absGla.c 68.2 KB
Newer Older
1 2
/**CFile****************************************************************

3
  FileName    [absGla2.c]
4 5 6

  SystemName  [ABC: Logic synthesis and verification system.]

7
  PackageName [Abstraction package.]
8 9 10 11 12 13 14 15 16

  Synopsis    [Scalable gate-level abstraction.]

  Author      [Alan Mishchenko]
  
  Affiliation [UC Berkeley]

  Date        [Ver. 1.0. Started - June 20, 2005.]

17
  Revision    [$Id: absGla2.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
18 19 20

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

21
#include "base/main/main.h"
22 23
#include "sat/cnf/cnf.h"
#include "sat/bsat/satSolver2.h"
24
#include "bool/kit/kit.h"
25 26 27
#include "abs.h"
#include "absRef.h"
//#include "absRef2.h"
28 29 30 31 32 33 34

ABC_NAMESPACE_IMPL_START

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

35
#define GA2_BIG_NUM 0x3FFFFFF0
36

37 38 39 40
typedef struct Ga2_Man_t_ Ga2_Man_t; // manager
struct Ga2_Man_t_
{
    // user data
41
    Gia_Man_t *    pGia;         // working AIG manager
42
    Abs_Par_t *    pPars;        // parameters
43
    // markings 
44
    Vec_Ptr_t *    vCnfs;        // for each object: CNF0, CNF1
45
    // abstraction
46
    Vec_Int_t *    vIds;         // abstraction ID for each GIA object
47
    Vec_Int_t *    vProofIds;    // mapping of GIA objects into their proof IDs
48
    Vec_Int_t *    vAbs;         // array of abstracted objects
49 50
    Vec_Int_t *    vValues;      // array of objects with abstraction ID assigned
    int            nProofIds;    // the counter of proof IDs
51 52
    int            LimAbs;       // limit value for starting abstraction objects
    int            LimPpi;       // limit value for starting PPI objects
53
    int            nMarked;      // total number of marked nodes and flops
54
    int            fUseNewLine;  // remember that you used new line
55
    // refinement
56
    Rnm_Man_t *    pRnm;         // refinement manager
57
//    Rf2_Man_t *    pRf2;         // refinement manager
58
    // SAT solver and variables
59 60 61
    Vec_Ptr_t *    vId2Lit;      // mapping, for each timeframe, of object ID into SAT literal
    sat_solver2 *  pSat;         // incremental SAT solver
    int            nSatVars;     // the number of SAT variables
62 63
    int            nCexes;       // the number of counter-examples
    int            nObjAdded;    // objs added during refinement
64
    int            nPdrCalls;    // count the number of concurrent calls
65 66 67 68 69 70
    // hash table
    int *          pTable;
    int            nTable;
    int            nHashHit;
    int            nHashMiss;
    int            nHashOver;
71 72 73
    // temporaries
    Vec_Int_t *    vLits;
    Vec_Int_t *    vIsopMem;
74
    char * pSopSizes, ** pSops;  // CNF representation
75
    // statistics  
76 77 78 79 80 81
    abctime        timeStart;
    abctime        timeInit;
    abctime        timeSat;
    abctime        timeUnsat;
    abctime        timeCex;
    abctime        timeOther;
82 83
};

84 85
static inline int         Ga2_ObjId( Ga2_Man_t * p, Gia_Obj_t * pObj )           { return Vec_IntEntry(p->vIds, Gia_ObjId(p->pGia, pObj));                                                  }
static inline void        Ga2_ObjSetId( Ga2_Man_t * p, Gia_Obj_t * pObj, int i ) { Vec_IntWriteEntry(p->vIds, Gia_ObjId(p->pGia, pObj), i);                                                 }
86

87 88
static inline Vec_Int_t * Ga2_ObjCnf0( Ga2_Man_t * p, Gia_Obj_t * pObj )         { assert(Ga2_ObjId(p,pObj) >= 0); return (Vec_Int_t *)Vec_PtrEntry( p->vCnfs, 2*Ga2_ObjId(p,pObj)   );                  }
static inline Vec_Int_t * Ga2_ObjCnf1( Ga2_Man_t * p, Gia_Obj_t * pObj )         { assert(Ga2_ObjId(p,pObj) >= 0); return (Vec_Int_t *)Vec_PtrEntry( p->vCnfs, 2*Ga2_ObjId(p,pObj)+1 );                  }
89

90 91 92 93
static inline int         Ga2_ObjIsAbs0( Ga2_Man_t * p, Gia_Obj_t * pObj )       { assert(Ga2_ObjId(p,pObj) >= 0); return Ga2_ObjId(p,pObj) >= 0         && Ga2_ObjId(p,pObj) < p->LimAbs;  }
static inline int         Ga2_ObjIsLeaf0( Ga2_Man_t * p, Gia_Obj_t * pObj )      { assert(Ga2_ObjId(p,pObj) >= 0); return Ga2_ObjId(p,pObj) >= p->LimAbs && Ga2_ObjId(p,pObj) < p->LimPpi;  }
static inline int         Ga2_ObjIsAbs( Ga2_Man_t * p, Gia_Obj_t * pObj )        { return Ga2_ObjId(p,pObj) >= 0 &&  Ga2_ObjCnf0(p,pObj);                                                   }
static inline int         Ga2_ObjIsLeaf( Ga2_Man_t * p, Gia_Obj_t * pObj )       { return Ga2_ObjId(p,pObj) >= 0 && !Ga2_ObjCnf0(p,pObj);                                                   }
94

95
static inline Vec_Int_t * Ga2_MapFrameMap( Ga2_Man_t * p, int f )                { return (Vec_Int_t *)Vec_PtrEntry( p->vId2Lit, f );                                                       }
96

97
// returns literal of this object, or -1 if SAT variable of the object is not assigned
98 99
static inline int Ga2_ObjFindLit( Ga2_Man_t * p, Gia_Obj_t * pObj, int f )  
{ 
100
//    int Id = Ga2_ObjId(p,pObj);
101
    assert( Ga2_ObjId(p,pObj) >= 0 && Ga2_ObjId(p,pObj) < Vec_IntSize(p->vValues) );
102
    return Vec_IntEntry( Ga2_MapFrameMap(p, f), Ga2_ObjId(p,pObj) );
103
}
104
// inserts literal of this object
105 106
static inline void Ga2_ObjAddLit( Ga2_Man_t * p, Gia_Obj_t * pObj, int f, int Lit )  
{ 
107
//    assert( Lit > 1 );
108
    assert( Ga2_ObjFindLit(p, pObj, f) == -1 );
109
    Vec_IntSetEntry( Ga2_MapFrameMap(p, f), Ga2_ObjId(p,pObj), Lit );
110
}
111
// returns or inserts-and-returns literal of this object
112 113 114 115 116 117 118 119
static inline int Ga2_ObjFindOrAddLit( Ga2_Man_t * p, Gia_Obj_t * pObj, int f )  
{ 
    int Lit = Ga2_ObjFindLit( p, pObj, f );
    if ( Lit == -1 )
    {
        Lit = toLitCond( p->nSatVars++, 0 );
        Ga2_ObjAddLit( p, pObj, f, Lit );
    }
120
//    assert( Lit > 1 );
121 122 123
    return Lit;
}

124

125 126 127 128 129 130
////////////////////////////////////////////////////////////////////////
///                     FUNCTION DEFINITIONS                         ///
////////////////////////////////////////////////////////////////////////

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

131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
  Synopsis    [Computes truth table for the marked node.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
unsigned Ga2_ObjComputeTruth_rec( Gia_Man_t * p, Gia_Obj_t * pObj, int fFirst )
{
    unsigned Val0, Val1;
    if ( pObj->fPhase && !fFirst )
        return pObj->Value;
    assert( Gia_ObjIsAnd(pObj) );
    Val0 = Ga2_ObjComputeTruth_rec( p, Gia_ObjFanin0(pObj), 0 );
    Val1 = Ga2_ObjComputeTruth_rec( p, Gia_ObjFanin1(pObj), 0 );
    return (Gia_ObjFaninC0(pObj) ? ~Val0 : Val0) & (Gia_ObjFaninC1(pObj) ? ~Val1 : Val1);
}
unsigned Ga2_ManComputeTruth( Gia_Man_t * p, Gia_Obj_t * pRoot, Vec_Int_t * vLeaves )
{
    static unsigned uTruth5[5] = { 0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000 };
    Gia_Obj_t * pObj;
154
    unsigned Res;
155 156 157
    int i;
    Gia_ManForEachObjVec( vLeaves, p, pObj, i )
        pObj->Value = uTruth5[i];
158 159 160 161
    Res = Ga2_ObjComputeTruth_rec( p, pRoot, 1 );
    Gia_ManForEachObjVec( vLeaves, p, pObj, i )
        pObj->Value = 0;
    return Res;
162 163 164 165
}

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

166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242
  Synopsis    [Returns AIG marked for CNF generation.]

  Description [The marking satisfies the following requirements:
  Each marked node has the number of marked fanins no more than N.]
               
  SideEffects [Uses pObj->fPhase to store the markings.]

  SeeAlso     []

***********************************************************************/
int Ga2_ManBreakTree_rec( Gia_Man_t * p, Gia_Obj_t * pObj, int fFirst, int N )
{   // breaks a tree rooted at the node into N-feasible subtrees
    int Val0, Val1;
    if ( pObj->fPhase && !fFirst )
        return 1;
    Val0 = Ga2_ManBreakTree_rec( p, Gia_ObjFanin0(pObj), 0, N );
    Val1 = Ga2_ManBreakTree_rec( p, Gia_ObjFanin1(pObj), 0, N );
    if ( Val0 + Val1 < N )
        return Val0 + Val1;
    if ( Val0 + Val1 == N )
    {
        pObj->fPhase = 1;
        return 1;
    }
    assert( Val0 + Val1 > N );
    assert( Val0 < N && Val1 < N );
    if ( Val0 >= Val1 )
    {
        Gia_ObjFanin0(pObj)->fPhase = 1;
        Val0 = 1;
    }
    else 
    {
        Gia_ObjFanin1(pObj)->fPhase = 1;
        Val1 = 1;
    }
    if ( Val0 + Val1 < N )
        return Val0 + Val1;
    if ( Val0 + Val1 == N )
    {
        pObj->fPhase = 1;
        return 1;
    }
    assert( 0 );
    return -1;
}
int Ga2_ManCheckNodesAnd( Gia_Man_t * p, Vec_Int_t * vNodes )
{
    Gia_Obj_t * pObj;
    int i;
    Gia_ManForEachObjVec( vNodes, p, pObj, i )
        if ( (!Gia_ObjFanin0(pObj)->fPhase && Gia_ObjFaninC0(pObj)) || 
             (!Gia_ObjFanin1(pObj)->fPhase && Gia_ObjFaninC1(pObj)) )
            return 0;
    return 1;
}
void Ga2_ManCollectNodes_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vNodes, int fFirst )
{
    if ( pObj->fPhase && !fFirst )
        return;
    assert( Gia_ObjIsAnd(pObj) );
    Ga2_ManCollectNodes_rec( p, Gia_ObjFanin0(pObj), vNodes, 0 );
    Ga2_ManCollectNodes_rec( p, Gia_ObjFanin1(pObj), vNodes, 0 );
    Vec_IntPush( vNodes, Gia_ObjId(p, pObj) );

}
void Ga2_ManCollectLeaves_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vLeaves, int fFirst )
{
    if ( pObj->fPhase && !fFirst )
    {
        Vec_IntPushUnique( vLeaves, Gia_ObjId(p, pObj) );
        return;
    }
    assert( Gia_ObjIsAnd(pObj) );
    Ga2_ManCollectLeaves_rec( p, Gia_ObjFanin0(pObj), vLeaves, 0 );
    Ga2_ManCollectLeaves_rec( p, Gia_ObjFanin1(pObj), vLeaves, 0 );
}
243
int Ga2_ManMarkup( Gia_Man_t * p, int N, int fSimple )
244
{
245
    static unsigned uTruth5[5] = { 0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000 };
246
//    abctime clk = Abc_Clock();
247 248
    Vec_Int_t * vLeaves;
    Gia_Obj_t * pObj;
249
    int i, k, Leaf, CountMarks;
250

251 252
    vLeaves = Vec_IntAlloc( 100 );

253
    if ( fSimple )
254
    {
255 256
        Gia_ManForEachObj( p, pObj, i )
            pObj->fPhase = !Gia_ObjIsCo(pObj);
257
    }
258
    else
259
    {
260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294
        // label nodes with multiple fanouts and inputs MUXes
        Gia_ManForEachObj( p, pObj, i )
        {
            pObj->Value = 0;
            if ( !Gia_ObjIsAnd(pObj) )
                continue;
            Gia_ObjFanin0(pObj)->Value++;
            Gia_ObjFanin1(pObj)->Value++;
            if ( !Gia_ObjIsMuxType(pObj) )
                continue;
            Gia_ObjFanin0(Gia_ObjFanin0(pObj))->Value++;
            Gia_ObjFanin1(Gia_ObjFanin0(pObj))->Value++;
            Gia_ObjFanin0(Gia_ObjFanin1(pObj))->Value++;
            Gia_ObjFanin1(Gia_ObjFanin1(pObj))->Value++;
        }
        Gia_ManForEachObj( p, pObj, i )
        {
            pObj->fPhase = 0;
            if ( Gia_ObjIsAnd(pObj) )
                pObj->fPhase = (pObj->Value > 1);
            else if ( Gia_ObjIsCo(pObj) )
                Gia_ObjFanin0(pObj)->fPhase = 1;
            else 
                pObj->fPhase = 1;
        } 
        // add marks when needed
        Gia_ManForEachAnd( p, pObj, i )
        {
            if ( !pObj->fPhase )
                continue;
            Vec_IntClear( vLeaves );
            Ga2_ManCollectLeaves_rec( p, pObj, vLeaves, 1 );
            if ( Vec_IntSize(vLeaves) > N )
                Ga2_ManBreakTree_rec( p, pObj, 1, N );
        }
295
    }
296

297
    // verify that the tree is split correctly
298 299
    Vec_IntFreeP( &p->vMapping );
    p->vMapping = Vec_IntStart( Gia_ManObjNum(p) );
300 301 302 303 304 305 306 307 308 309 310 311 312
    Gia_ManForEachRo( p, pObj, i )
    {
        Gia_Obj_t * pObjRi = Gia_ObjRoToRi(p, pObj);
        assert( pObj->fPhase );
        assert( Gia_ObjFanin0(pObjRi)->fPhase );
        // create map
        Vec_IntWriteEntry( p->vMapping, Gia_ObjId(p, pObj), Vec_IntSize(p->vMapping) );
        Vec_IntPush( p->vMapping, 1 );
        Vec_IntPush( p->vMapping, Gia_ObjFaninId0p(p, pObjRi) );
        Vec_IntPush( p->vMapping, Gia_ObjFaninC0(pObjRi) ? 0x55555555 : 0xAAAAAAAA );
        Vec_IntPush( p->vMapping, -1 );  // placeholder for ref counter
    }
    CountMarks = Gia_ManRegNum(p);
313 314 315 316 317 318
    Gia_ManForEachAnd( p, pObj, i )
    {
        if ( !pObj->fPhase )
            continue;
        Vec_IntClear( vLeaves );
        Ga2_ManCollectLeaves_rec( p, pObj, vLeaves, 1 );
319 320
        assert( Vec_IntSize(vLeaves) <= N );
        // create map
321 322
        Vec_IntWriteEntry( p->vMapping, i, Vec_IntSize(p->vMapping) );
        Vec_IntPush( p->vMapping, Vec_IntSize(vLeaves) );
323
        Vec_IntForEachEntry( vLeaves, Leaf, k )
324 325
        {            
            Vec_IntPush( p->vMapping, Leaf );
326
            Gia_ManObj(p, Leaf)->Value = uTruth5[k];
327
            assert( Gia_ManObj(p, Leaf)->fPhase );
328
        }
329 330
        Vec_IntPush( p->vMapping,  (int)Ga2_ObjComputeTruth_rec( p, pObj, 1 ) );
        Vec_IntPush( p->vMapping, -1 );  // placeholder for ref counter
331 332
        CountMarks++;
    }
333
//    Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
334
    Vec_IntFree( vLeaves );
335
    Gia_ManCleanValue( p );
336 337
    return CountMarks;
}
338 339
void Ga2_ManComputeTest( Gia_Man_t * p )
{
340
    abctime clk;
341
//    unsigned uTruth;
342
    Gia_Obj_t * pObj;
343
    int i, Counter = 0;
344
    clk = Abc_Clock();
345
    Ga2_ManMarkup( p, 5, 0 );
346
    Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
347 348 349 350
    Gia_ManForEachAnd( p, pObj, i )
    {
        if ( !pObj->fPhase )
            continue;
351 352 353 354 355
//        uTruth = Ga2_ObjTruth( p, pObj );
//        printf( "%6d : ", Counter );
//        Kit_DsdPrintFromTruth( &uTruth, Ga2_ObjLeaveNum(p, pObj) ); 
//        printf( "\n" );
        Counter++;
356
    }
357
    Abc_Print( 1, "Marked AND nodes = %6d.  ", Counter );
358
    Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
359
}
360 361 362 363 364 365 366 367 368 369 370 371

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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
372
Ga2_Man_t * Ga2_ManStart( Gia_Man_t * pGia, Abs_Par_t * pPars )
373
{
374 375
    Ga2_Man_t * p;
    p = ABC_CALLOC( Ga2_Man_t, 1 );
376
    p->timeStart = Abc_Clock();
377
    p->fUseNewLine = 1;
378
    // user data
379 380
    p->pGia      = pGia;
    p->pPars     = pPars;
381
    // markings 
382
    p->nMarked   = Ga2_ManMarkup( pGia, 5, pPars->fUseSimple );
383 384 385
    p->vCnfs     = Vec_PtrAlloc( 1000 );
    Vec_PtrPush( p->vCnfs, Vec_IntAlloc(0) );
    Vec_PtrPush( p->vCnfs, Vec_IntAlloc(0) );
386
    // abstraction
387
    p->vIds      = Vec_IntStartFull( Gia_ManObjNum(pGia) );
388
    p->vProofIds = Vec_IntAlloc( 0 );
389 390
    p->vAbs      = Vec_IntAlloc( 1000 );
    p->vValues   = Vec_IntAlloc( 1000 );
391
    // add constant node to abstraction
392 393
    Ga2_ObjSetId( p, Gia_ManConst0(pGia), 0 );
    Vec_IntPush( p->vValues, 0 );
394
    Vec_IntPush( p->vAbs, 0 );
395
    // refinement
396
    p->pRnm      = Rnm_ManStart( pGia );
397
//    p->pRf2      = Rf2_ManStart( pGia );
398
    // SAT solver and variables
399
    p->vId2Lit   = Vec_PtrAlloc( 1000 );
400
    // temporaries
401 402
    p->vLits     = Vec_IntAlloc( 100 );
    p->vIsopMem  = Vec_IntAlloc( 100 );
403
    Cnf_ReadMsops( &p->pSopSizes, &p->pSops );
404
    // hash table
405 406
    p->nTable = Abc_PrimeCudd(1<<18);
    p->pTable = ABC_CALLOC( int, 6 * p->nTable ); 
407 408
    return p;
}
409

410
void Ga2_ManDumpStats( Gia_Man_t * pGia, Abs_Par_t * pPars, sat_solver2 * pSat, int iFrame, int fUseN )
411 412 413 414 415
{
    FILE * pFile;
    char pFileName[32];
    sprintf( pFileName, "stats_gla%s%s.txt", fUseN ? "n":"", pPars->fUseFullProof ? "p":"" ); 

416
    pFile = fopen( pFileName, "a+" );
417 418 419 420 421 422 423 424 425 426 427 428 429 430 431

    fprintf( pFile, "%s pi=%d ff=%d and=%d mem=%d bmc=%d", 
        pGia->pName, 
        Gia_ManPiNum(pGia), Gia_ManRegNum(pGia), Gia_ManAndNum(pGia), 
        (int)(1 + sat_solver2_memory_proof(pSat)/(1<<20)),
        iFrame );

    if ( pGia->vGateClasses )
    fprintf( pFile, " ff=%d and=%d",                 
        Gia_GlaCountFlops( pGia, pGia->vGateClasses ),
        Gia_GlaCountNodes( pGia, pGia->vGateClasses )  );

    fprintf( pFile, "\n" );
    fclose( pFile );
}
432 433 434 435 436 437 438 439
void Ga2_ManReportMemory( Ga2_Man_t * p )
{
    double memTot = 0;
    double memAig = 1.0 * p->pGia->nObjsAlloc * sizeof(Gia_Obj_t) + Vec_IntMemory(p->pGia->vMapping);
    double memSat = sat_solver2_memory( p->pSat, 1 );
    double memPro = sat_solver2_memory_proof( p->pSat );
    double memMap = Vec_VecMemoryInt( (Vec_Vec_t *)p->vId2Lit );
    double memRef = Rnm_ManMemoryUsage( p->pRnm );
440
    double memHash= sizeof(int) * 6 * p->nTable;
441 442 443
    double memOth = sizeof(Ga2_Man_t);
    memOth += Vec_VecMemoryInt( (Vec_Vec_t *)p->vCnfs );
    memOth += Vec_IntMemory( p->vIds );
444
    memOth += Vec_IntMemory( p->vProofIds );
445 446 447 448 449
    memOth += Vec_IntMemory( p->vAbs );
    memOth += Vec_IntMemory( p->vValues );
    memOth += Vec_IntMemory( p->vLits );
    memOth += Vec_IntMemory( p->vIsopMem );
    memOth += 336450 + (sizeof(char) + sizeof(char*)) * 65536;
450
    memTot = memAig + memSat + memPro + memMap + memRef + memHash + memOth;
451 452 453 454 455
    ABC_PRMP( "Memory: AIG      ", memAig, memTot );
    ABC_PRMP( "Memory: SAT      ", memSat, memTot );
    ABC_PRMP( "Memory: Proof    ", memPro, memTot );
    ABC_PRMP( "Memory: Map      ", memMap, memTot );
    ABC_PRMP( "Memory: Refine   ", memRef, memTot );
456
    ABC_PRMP( "Memory: Hash     ", memHash,memTot );
457 458
    ABC_PRMP( "Memory: Other    ", memOth, memTot );
    ABC_PRMP( "Memory: TOTAL    ", memTot, memTot );
459
}
460
void Ga2_ManStop( Ga2_Man_t * p )
461
{
462 463
    Vec_IntFreeP( &p->pGia->vMapping );
    Gia_ManSetPhase( p->pGia );
464
    if ( p->pPars->fVerbose )
465 466 467 468
        Abc_Print( 1, "SAT solver:  Var = %d  Cla = %d  Conf = %d  Lrn = %d  Reduce = %d  Cex = %d  ObjsAdded = %d\n", 
            sat_solver2_nvars(p->pSat), sat_solver2_nclauses(p->pSat), 
            sat_solver2_nconflicts(p->pSat), sat_solver2_nlearnts(p->pSat), 
            p->pSat->nDBreduces, p->nCexes, p->nObjAdded );
469
    if ( p->pPars->fVerbose )
470 471
    Abc_Print( 1, "Hash hits = %d.  Hash misses = %d.  Hash overs = %d.  Concurrent calls = %d.\n", 
        p->nHashHit, p->nHashMiss, p->nHashOver, p->nPdrCalls );
472

473 474 475 476
    if( p->pSat ) sat_solver2_delete( p->pSat );
    Vec_VecFree( (Vec_Vec_t *)p->vCnfs );
    Vec_VecFree( (Vec_Vec_t *)p->vId2Lit );
    Vec_IntFree( p->vIds );
477
    Vec_IntFree( p->vProofIds );
478
    Vec_IntFree( p->vAbs );
479
    Vec_IntFree( p->vValues );
480 481
    Vec_IntFree( p->vLits );
    Vec_IntFree( p->vIsopMem );
482
    Rnm_ManStop( p->pRnm, 0 );
483
//    Rf2_ManStop( p->pRf2, p->pPars->fVerbose );
484
    ABC_FREE( p->pTable );
485 486 487
    ABC_FREE( p->pSopSizes );
    ABC_FREE( p->pSops[1] );
    ABC_FREE( p->pSops );
488 489 490 491 492 493
    ABC_FREE( p );
}


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

494
  Synopsis    [Computes a minimized truth table.]
495

496 497 498 499
  Description [Input literals can be 0/1 (const 0/1), non-trivial literals 
  (integers that are more than 1) and unassigned literals (large integers).
  This procedure computes the truth table that essentially depends on input
  variables ordered in the increasing order of their positive literals.]
500 501 502 503 504 505 506 507
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
static inline unsigned Ga2_ObjTruthDepends( unsigned t, int v )
{
508
    static unsigned uInvTruth5[5] = { 0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF, 0x0000FFFF };
509
    assert( v >= 0 && v <= 4 );
510
    return ((t ^ (t >> (1 << v))) & uInvTruth5[v]);
511 512 513
}
unsigned Ga2_ObjComputeTruthSpecial( Gia_Man_t * p, Gia_Obj_t * pRoot, Vec_Int_t * vLeaves, Vec_Int_t * vLits )
{
514
    int fVerbose = 0;
515
    static unsigned uTruth5[5] = { 0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000 };
516
    unsigned Res;
517
    Gia_Obj_t * pObj;
518
    int i, Entry;
519
//    int Id = Gia_ObjId(p, pRoot);
520 521 522 523 524
    assert( Gia_ObjIsAnd(pRoot) );

    if ( fVerbose )
    printf( "Object %d.\n", Gia_ObjId(p, pRoot) );

525 526 527 528
    // assign elementary truth tables
    Gia_ManForEachObjVec( vLeaves, p, pObj, i )
    {
        Entry = Vec_IntEntry( vLits, i );
529
        assert( Entry >= 0 );
530
        if ( Entry == 0 )
531
            pObj->Value = 0;
532
        else if ( Entry == 1 )
533
            pObj->Value = ~0;
534
        else // non-trivial literal
535
            pObj->Value = uTruth5[i];
536 537
        if ( fVerbose )
        printf( "%d ", Entry );
538
    }
539 540 541 542

    if ( fVerbose )
    {
    Res = Ga2_ObjTruth( p, pRoot );
543
//    Kit_DsdPrintFromTruth( &Res, Vec_IntSize(vLeaves) );
544 545 546
    printf( "\n" );
    }

547
    // compute truth table
548 549 550
    Res = Ga2_ObjComputeTruth_rec( p, pRoot, 1 );
    if ( Res != 0 && Res != ~0 )
    {
551 552 553 554 555 556
        // find essential variables
        int nUsed = 0, pUsed[5];
        for ( i = 0; i < Vec_IntSize(vLeaves); i++ )
            if ( Ga2_ObjTruthDepends( Res, i ) )
                pUsed[nUsed++] = i;
        assert( nUsed > 0 );
557
        // order positions by literal value
558 559 560
        Vec_IntSelectSortCost( pUsed, nUsed, vLits );
        assert( Vec_IntEntry(vLits, pUsed[0]) <= Vec_IntEntry(vLits, pUsed[nUsed-1]) );
        // assign elementary truth tables to the leaves
561
        Gia_ManForEachObjVec( vLeaves, p, pObj, i )
562 563 564 565 566 567 568 569 570 571
        {
            Entry = Vec_IntEntry( vLits, i );
            assert( Entry >= 0 );
            if ( Entry == 0 )
                pObj->Value = 0;
            else if ( Entry == 1 )
                pObj->Value = ~0;
            else // non-trivial literal
                pObj->Value = 0xDEADCAFE; // not important
        }
572
        for ( i = 0; i < nUsed; i++ )
573
        {
574 575 576 577
            Entry = Vec_IntEntry( vLits, pUsed[i] );
            assert( Entry > 1 );
            pObj = Gia_ManObj( p, Vec_IntEntry(vLeaves, pUsed[i]) );
            pObj->Value = Abc_LitIsCompl(Entry) ? ~uTruth5[i] : uTruth5[i];
578
//            pObj->Value = uTruth5[i];
579 580
            // remember this literal
            pUsed[i] = Abc_LitRegular(Entry);
581
//            pUsed[i] = Entry;
582
        }
583
        // compute truth table
584
        Res = Ga2_ObjComputeTruth_rec( p, pRoot, 1 );
585 586 587 588 589 590
        // reload the literals
        Vec_IntClear( vLits );
        for ( i = 0; i < nUsed; i++ )
        {
            Vec_IntPush( vLits, pUsed[i] );
            assert( Ga2_ObjTruthDepends(Res, i) );
591 592
            if ( fVerbose )
            printf( "%d ", pUsed[i] );
593
        }
594 595 596 597 598
        for ( ; i < 5; i++ )
            assert( !Ga2_ObjTruthDepends(Res, i) );

if ( fVerbose )
{
599
//    Kit_DsdPrintFromTruth( &Res, nUsed );
600 601 602
    printf( "\n" );
}

603
    }
604
    else
605 606 607 608 609 610 611 612 613
    {

if ( fVerbose )
{
    Vec_IntClear( vLits );
    printf( "Const %d\n", Res > 0 );
}

    }
614 615
    Gia_ManForEachObjVec( vLeaves, p, pObj, i )
        pObj->Value = 0;
616 617 618 619 620 621 622 623 624 625 626 627 628 629
    return Res;
}

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

  Synopsis    [Returns CNF of the function.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
630
Vec_Int_t * Ga2_ManCnfCompute( unsigned uTruth, int nVars, Vec_Int_t * vCover )
631
{
632 633
    int RetValue;
    assert( nVars <= 5 );
634
    // transform truth table into the SOP
635
    RetValue = Kit_TruthIsop( &uTruth, nVars, vCover, 0 );
636 637
    assert( RetValue == 0 );
    // check the case of constant cover
638
    return Vec_IntDup( vCover );
639 640 641 642 643 644 645 646 647 648 649 650 651
}

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

  Synopsis    [Derives CNF for one node.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
652
static inline void Ga2_ManCnfAddDynamic( Ga2_Man_t * p, int uTruth, int Lits[], int iLitOut, int ProofId )
653
{
654
    int i, k, b, Cube, nClaLits, ClaLits[6];
655
//    assert( uTruth > 0 && uTruth < 0xffff );
656 657 658 659 660 661
    for ( i = 0; i < 2; i++ )
    {
        if ( i )
            uTruth = 0xffff & ~uTruth;
//        Extra_PrintBinary( stdout, &uTruth, 16 ); printf( "\n" );
        for ( k = 0; k < p->pSopSizes[uTruth]; k++ )
662 663 664 665 666 667
        {
            nClaLits = 0;
            ClaLits[nClaLits++] = i ? lit_neg(iLitOut) : iLitOut;
            Cube = p->pSops[uTruth][k];
            for ( b = 3; b >= 0; b-- )
            {
668
                if ( Cube % 3 == 0 ) // value 0 --> add positive literal
669 670 671 672
                {
                    assert( Lits[b] > 1 );
                    ClaLits[nClaLits++] = Lits[b];
                }
673
                else if ( Cube % 3 == 1 ) // value 1 --> add negative literal
674 675 676 677 678 679
                {
                    assert( Lits[b] > 1 );
                    ClaLits[nClaLits++] = lit_neg(Lits[b]);
                }
                Cube = Cube / 3;
            }
680
            sat_solver2_addclause( p->pSat, ClaLits, ClaLits+nClaLits, ProofId );
681
        }
682 683
    }
}
684
void Ga2_ManCnfAddStatic( sat_solver2 * pSat, Vec_Int_t * vCnf0, Vec_Int_t * vCnf1, int Lits[], int iLitOut, int ProofId )
685
{
686 687 688 689 690 691 692 693 694 695 696 697
    Vec_Int_t * vCnf;
    int i, k, b, Cube, Literal, nClaLits, ClaLits[6];
    for ( i = 0; i < 2; i++ )
    {
        vCnf = i ? vCnf1 : vCnf0;
        Vec_IntForEachEntry( vCnf, Cube, k )
        {
            nClaLits = 0;
            ClaLits[nClaLits++] = i ? lit_neg(iLitOut) : iLitOut;
            for ( b = 0; b < 5; b++ )
            {
                Literal = 3 & (Cube >> (b << 1));
698
                if ( Literal == 1 ) // value 0 --> add positive literal
699
                {
700
//                    assert( Lits[b] > 1 );
701 702
                    ClaLits[nClaLits++] = Lits[b];
                }
703
                else if ( Literal == 2 ) // value 1 --> add negative literal
704
                {
705
//                    assert( Lits[b] > 1 );
706 707 708 709 710
                    ClaLits[nClaLits++] = lit_neg(Lits[b]);
                }
                else if ( Literal != 0 )
                    assert( 0 );
            }
711
            sat_solver2_addclause( pSat, ClaLits, ClaLits+nClaLits, ProofId );
712 713
        }
    }
714 715 716 717 718 719 720 721 722 723 724 725 726
}

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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763
static inline unsigned Saig_ManBmcHashKey( int * pArray )
{
    static int s_Primes[5] = { 12582917, 25165843, 50331653, 100663319, 201326611 };
    unsigned i, Key = 0;
    for ( i = 0; i < 5; i++ )
        Key += pArray[i] * s_Primes[i];
    return Key;
}
static inline int * Saig_ManBmcLookup( Ga2_Man_t * p, int * pArray )
{
    int * pTable = p->pTable + 6 * (Saig_ManBmcHashKey(pArray) % p->nTable);
    if ( memcmp( pTable, pArray, 20 ) )
    {
        if ( pTable[0] == 0 )
            p->nHashMiss++;
        else
            p->nHashOver++;
        memcpy( pTable, pArray, 20 );
        pTable[5] = 0;
    }
    else
        p->nHashHit++;
    assert( pTable + 5 < pTable + 6 * p->nTable );
    return pTable + 5;
}

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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
764
static inline void Ga2_ManSetupNode( Ga2_Man_t * p, Gia_Obj_t * pObj, int fAbs )
765 766
{
    unsigned uTruth;
767
    int nLeaves;
768
//    int Id = Gia_ObjId(p->pGia, pObj);
769
    assert( pObj->fPhase );
770 771
    assert( Vec_PtrSize(p->vCnfs) == 2 * Vec_IntSize(p->vValues) );
    // assign abstraction ID to the node
772
    if ( Ga2_ObjId(p,pObj) == -1 )
773
    {
774
        Ga2_ObjSetId( p, pObj, Vec_IntSize(p->vValues) );
775
        Vec_IntPush( p->vValues, Gia_ObjId(p->pGia, pObj) );
776 777
        Vec_PtrPush( p->vCnfs, NULL );
        Vec_PtrPush( p->vCnfs, NULL );
778 779
    }
    assert( Ga2_ObjCnf0(p, pObj) == NULL );
780 781 782
    if ( !fAbs )
        return;
    Vec_IntPush( p->vAbs, Gia_ObjId(p->pGia, pObj) );
783
    assert( Gia_ObjIsAnd(pObj) || Gia_ObjIsRo(p->pGia, pObj) );
784
    // compute parameters
785
    nLeaves = Ga2_ObjLeaveNum(p->pGia, pObj);
786
    uTruth = Ga2_ObjTruth( p->pGia, pObj );
787 788 789
    // create CNF for pos/neg phases
    Vec_PtrWriteEntry( p->vCnfs, 2 * Ga2_ObjId(p,pObj),     Ga2_ManCnfCompute( uTruth, nLeaves, p->vIsopMem) );    
    Vec_PtrWriteEntry( p->vCnfs, 2 * Ga2_ObjId(p,pObj) + 1, Ga2_ManCnfCompute(~uTruth, nLeaves, p->vIsopMem) );
790
}
791

792
static inline void Ga2_ManAddToAbsOneStatic( Ga2_Man_t * p, Gia_Obj_t * pObj, int f, int fUseId )
793 794
{
    Vec_Int_t * vLeaves;
795 796
    Gia_Obj_t * pLeaf;
    int k, Lit, iLitOut = Ga2_ObjFindOrAddLit( p, pObj, f );
797
    assert( iLitOut > 1 );
798 799
    assert( Gia_ObjIsConst0(pObj) || Gia_ObjIsRo(p->pGia, pObj) || Gia_ObjIsAnd(pObj) );
    if ( Gia_ObjIsConst0(pObj) || (f == 0 && Gia_ObjIsRo(p->pGia, pObj)) )
800 801
    {
        iLitOut = Abc_LitNot( iLitOut );
802
        sat_solver2_addclause( p->pSat, &iLitOut, &iLitOut + 1, fUseId ? Gia_ObjId(p->pGia, pObj) : -1 );
803 804 805
    }
    else
    {
806 807
        int fUseStatic = 1;
        Vec_IntClear( p->vLits );
808
        vLeaves = Ga2_ObjLeaves( p->pGia, pObj );
809 810 811 812 813 814 815 816
        Gia_ManForEachObjVec( vLeaves, p->pGia, pLeaf, k )
        {
            Lit = Ga2_ObjFindOrAddLit( p, pLeaf, f - Gia_ObjIsRo(p->pGia, pObj) );
            Vec_IntPush( p->vLits, Lit );
            if ( Lit < 2 )
                fUseStatic = 0;
        }
        if ( fUseStatic || Gia_ObjIsRo(p->pGia, pObj) )
817
            Ga2_ManCnfAddStatic( p->pSat, Ga2_ObjCnf0(p, pObj), Ga2_ObjCnf1(p, pObj), Vec_IntArray(p->vLits), iLitOut, fUseId ? Gia_ObjId(p->pGia, pObj) : -1 );
818 819 820 821 822 823 824 825 826
        else
        {
            unsigned uTruth = Ga2_ObjComputeTruthSpecial( p->pGia, pObj, vLeaves, p->vLits );
            Ga2_ManCnfAddDynamic( p, uTruth & 0xFFFF, Vec_IntArray(p->vLits), iLitOut, Gia_ObjId(p->pGia, pObj) );
        }
    }
}
static inline void Ga2_ManAddToAbsOneDynamic( Ga2_Man_t * p, Gia_Obj_t * pObj, int f )
{
827
//    int Id = Gia_ObjId(p->pGia, pObj);
828 829 830 831
    Vec_Int_t * vLeaves;
    Gia_Obj_t * pLeaf;
    unsigned uTruth;
    int i, Lit;
832

833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851
    assert( Ga2_ObjIsAbs0(p, pObj) );
    assert( Gia_ObjIsConst0(pObj) || Gia_ObjIsRo(p->pGia, pObj) || Gia_ObjIsAnd(pObj) );
    if ( Gia_ObjIsConst0(pObj) || (f == 0 && Gia_ObjIsRo(p->pGia, pObj)) )
    {
        Ga2_ObjAddLit( p, pObj, f, 0 );
    }
    else if ( Gia_ObjIsRo(p->pGia, pObj) )
    {
        // if flop is included in the abstraction, but its driver is not
        // flop input driver has no variable assigned -- we assign it here
        pLeaf = Gia_ObjRoToRi( p->pGia, pObj );
        Lit = Ga2_ObjFindOrAddLit( p, Gia_ObjFanin0(pLeaf), f-1 );
        assert( Lit >= 0 );
        Lit = Abc_LitNotCond( Lit, Gia_ObjFaninC0(pLeaf) );
        Ga2_ObjAddLit( p, pObj, f, Lit );
    }
    else
    {
        assert( Gia_ObjIsAnd(pObj) );
852
        Vec_IntClear( p->vLits );
853 854 855 856 857 858 859 860 861 862
        vLeaves = Ga2_ObjLeaves( p->pGia, pObj );
        Gia_ManForEachObjVec( vLeaves, p->pGia, pLeaf, i )
        {
            if ( Ga2_ObjIsAbs0(p, pLeaf) )      // belongs to original abstraction
            {
                Lit = Ga2_ObjFindLit( p, pLeaf, f );
                assert( Lit >= 0 );
            }
            else if ( Ga2_ObjIsLeaf0(p, pLeaf) ) // belongs to original PPIs
            {
863 864
                Lit = Ga2_ObjFindLit( p, pLeaf, f );
//                Lit = Ga2_ObjFindOrAddLit( p, pLeaf, f );
865 866
                if ( Lit == -1 )
                {
867 868
                    Lit = GA2_BIG_NUM + 2*i;
//                    assert( 0 );
869 870 871
                }
            }
            else assert( 0 );
872
            Vec_IntPush( p->vLits, Lit );
873 874 875 876 877 878 879 880 881 882 883 884 885 886
        }

        // minimize truth table
        uTruth = Ga2_ObjComputeTruthSpecial( p->pGia, pObj, vLeaves, p->vLits );
        if ( uTruth == 0 || uTruth == ~0 ) // const 0 / 1
        {
            Lit = (uTruth > 0);
            Ga2_ObjAddLit( p, pObj, f, Lit );
        }
        else if ( uTruth == 0xAAAAAAAA || uTruth == 0x55555555 )  // buffer / inverter
        {
            Lit = Vec_IntEntry( p->vLits, 0 );
            if ( Lit >= GA2_BIG_NUM )
            {
887
                pLeaf = Gia_ManObj( p->pGia, Vec_IntEntry(vLeaves, (Lit-GA2_BIG_NUM)/2) );
888 889 890 891 892 893 894
                Lit = Ga2_ObjFindLit( p, pLeaf, f );
                assert( Lit == -1 );
                Lit = Ga2_ObjFindOrAddLit( p, pLeaf, f );
            }
            assert( Lit >= 0 );
            Lit = Abc_LitNotCond( Lit, uTruth == 0x55555555 );
            Ga2_ObjAddLit( p, pObj, f, Lit );
895
            assert( Lit < 10000000 );
896 897 898 899 900 901 902 903 904
        }
        else
        {
            assert( Vec_IntSize(p->vLits) > 1 && Vec_IntSize(p->vLits) < 6 );
            // replace literals
            Vec_IntForEachEntry( p->vLits, Lit, i )
            {
                if ( Lit >= GA2_BIG_NUM )
                {
905
                    pLeaf = Gia_ManObj( p->pGia, Vec_IntEntry(vLeaves, (Lit-GA2_BIG_NUM)/2) );
906 907 908 909 910
                    Lit = Ga2_ObjFindLit( p, pLeaf, f );
                    assert( Lit == -1 );
                    Lit = Ga2_ObjFindOrAddLit( p, pLeaf, f );
                    Vec_IntWriteEntry( p->vLits, i, Lit );
                }
911
                assert( Lit < 10000000 );
912 913 914 915
            }

            // add new nodes
            if ( Vec_IntSize(p->vLits) == 5 )
916
            {
917 918 919
                Vec_IntClear( p->vLits );
                Gia_ManForEachObjVec( vLeaves, p->pGia, pLeaf, i )
                    Vec_IntPush( p->vLits, Ga2_ObjFindOrAddLit( p, pLeaf, f ) );
920
                Lit = Ga2_ObjFindOrAddLit(p, pObj, f);
921
                Ga2_ManCnfAddStatic( p->pSat, Ga2_ObjCnf0(p, pObj), Ga2_ObjCnf1(p, pObj), Vec_IntArray(p->vLits), Lit, -1 );
922
            }
923
            else
924
            {
925
//                int fUseHash = 1;
926
                if ( !p->pPars->fSkipHash )
927 928 929
                {
                    int * pLookup, nSize = Vec_IntSize(p->vLits);
                    assert( Vec_IntSize(p->vLits) < 5 );
930
                    assert( Vec_IntEntry(p->vLits, 0) <= Vec_IntEntryLast(p->vLits) );
931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954
                    assert( Ga2_ObjFindLit(p, pObj, f) == -1 );
                    for ( i = Vec_IntSize(p->vLits); i < 4; i++ )
                        Vec_IntPush( p->vLits, GA2_BIG_NUM );
                    Vec_IntPush( p->vLits, (int)uTruth );
                    assert( Vec_IntSize(p->vLits) == 5 );

                    // perform structural hashing here!!!
                    pLookup = Saig_ManBmcLookup( p, Vec_IntArray(p->vLits) );
                    if ( *pLookup == 0 )
                    {
                        *pLookup = Ga2_ObjFindOrAddLit(p, pObj, f);
                        Vec_IntShrink( p->vLits, nSize );
                        Ga2_ManCnfAddDynamic( p, uTruth & 0xFFFF, Vec_IntArray(p->vLits), *pLookup, -1 );
                    }
                    else
                        Ga2_ObjAddLit( p, pObj, f, *pLookup );

                }
                else
                {
                    Lit = Ga2_ObjFindOrAddLit(p, pObj, f);
                    Ga2_ManCnfAddDynamic( p, uTruth & 0xFFFF, Vec_IntArray(p->vLits), Lit, -1 );
                }
            }
955
        }
956 957 958 959 960
    }
}

void Ga2_ManAddAbsClauses( Ga2_Man_t * p, int f )
{
961
    int fSimple = 0;
962
    Gia_Obj_t * pObj;
963
    int i;
964 965 966 967
    Gia_ManForEachObjVec( p->vValues, p->pGia, pObj, i )
    {
        if ( i == p->LimAbs )
            break;
968
        if ( fSimple )
969
            Ga2_ManAddToAbsOneStatic( p, pObj, f, 0 );
970 971
        else
            Ga2_ManAddToAbsOneDynamic( p, pObj, f );
972
    }
973 974
    Gia_ManForEachObjVec( p->vAbs, p->pGia, pObj, i )
        if ( i >= p->LimAbs )
975
            Ga2_ManAddToAbsOneStatic( p, pObj, f, 1 );
976
//    sat_solver2_simplify( p->pSat );
977 978
}

979
void Ga2_ManAddToAbs( Ga2_Man_t * p, Vec_Int_t * vToAdd )
980
{
981
    Vec_Int_t * vLeaves;
982
    Gia_Obj_t * pObj, * pFanin;
983
    int f, i, k;
984
    // add abstraction objects
985 986
    Gia_ManForEachObjVec( vToAdd, p->pGia, pObj, i )
    {
987 988 989
        Ga2_ManSetupNode( p, pObj, 1 );
        if ( p->pSat->pPrf2 )
            Vec_IntWriteEntry( p->vProofIds, Gia_ObjId(p->pGia, pObj), p->nProofIds++ );
990
    }
991 992 993
    // add PPI objects
    Gia_ManForEachObjVec( vToAdd, p->pGia, pObj, i )
    {
994 995
        vLeaves = Ga2_ObjLeaves( p->pGia, pObj );
        Gia_ManForEachObjVec( vLeaves, p->pGia, pFanin, k )
996
            if ( Ga2_ObjId( p, pFanin ) == -1 )
997
                Ga2_ManSetupNode( p, pFanin, 0 );
998
    }
999
    // add new clauses to the timeframes
1000
    for ( f = 0; f <= p->pPars->iFrame; f++ )
1001 1002
    {
        Vec_IntFillExtra( Ga2_MapFrameMap(p, f), Vec_IntSize(p->vValues), -1 );
1003
        Gia_ManForEachObjVec( vToAdd, p->pGia, pObj, i )
1004
            Ga2_ManAddToAbsOneStatic( p, pObj, f, 1 );
1005
    }
1006
//    sat_solver2_simplify( p->pSat );
1007 1008
}

1009
void Ga2_ManShrinkAbs( Ga2_Man_t * p, int nAbs, int nValues, int nSatVars )
1010
{
1011
    Vec_Int_t * vMap;
1012
    Gia_Obj_t * pObj;
1013
    int i, k, Entry;
1014
    assert( nAbs > 0 );
1015
    assert( nValues > 0 );
1016
    assert( nSatVars > 0 );
1017
    // shrink abstraction
1018 1019
    Gia_ManForEachObjVec( p->vAbs, p->pGia, pObj, i )
    {
1020
        if ( !i ) continue;
1021 1022 1023 1024 1025 1026
        assert( Ga2_ObjCnf0(p, pObj) != NULL );
        assert( Ga2_ObjCnf1(p, pObj) != NULL );
        if ( i < nAbs )
            continue;
        Vec_IntFree( Ga2_ObjCnf0(p, pObj) );
        Vec_IntFree( Ga2_ObjCnf1(p, pObj) );
1027 1028
        Vec_PtrWriteEntry( p->vCnfs, 2 * Ga2_ObjId(p,pObj),     NULL );    
        Vec_PtrWriteEntry( p->vCnfs, 2 * Ga2_ObjId(p,pObj) + 1, NULL );
1029 1030 1031 1032 1033
    }
    Vec_IntShrink( p->vAbs, nAbs );
    // shrink values
    Gia_ManForEachObjVec( p->vValues, p->pGia, pObj, i )
    {
1034
        assert( Ga2_ObjId(p,pObj) >= 0 );
1035
        if ( i < nValues )
1036
            continue;
1037
        Ga2_ObjSetId( p, pObj, -1 );
1038
    }
1039
    Vec_IntShrink( p->vValues, nValues );
1040
    Vec_PtrShrink( p->vCnfs, 2 * nValues );
1041 1042 1043
    // hack to clear constant
    if ( nValues == 1 )
        nValues = 0;
1044
    // clean mapping for each timeframe
1045
    Vec_PtrForEachEntry( Vec_Int_t *, p->vId2Lit, vMap, i )
1046 1047
    {
        Vec_IntShrink( vMap, nValues );
1048
        Vec_IntForEachEntryStart( vMap, Entry, k, p->LimAbs )
1049 1050 1051
            if ( Entry >= 2*nSatVars )
                Vec_IntWriteEntry( vMap, k, -1 );
    }
1052 1053
    // shrink SAT variables
    p->nSatVars = nSatVars;
1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066
}

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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
1067 1068 1069 1070 1071 1072 1073 1074 1075
void Ga2_ManAbsTranslate_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vClasses, int fFirst )
{
    if ( pObj->fPhase && !fFirst )
        return;
    assert( Gia_ObjIsAnd(pObj) );
    Ga2_ManAbsTranslate_rec( p, Gia_ObjFanin0(pObj), vClasses, 0 );
    Ga2_ManAbsTranslate_rec( p, Gia_ObjFanin1(pObj), vClasses, 0 );
    Vec_IntWriteEntry( vClasses, Gia_ObjId(p, pObj), 1 );
}
1076

1077 1078 1079 1080 1081 1082
Vec_Int_t * Ga2_ManAbsTranslate( Ga2_Man_t * p )
{
    Vec_Int_t * vGateClasses;
    Gia_Obj_t * pObj;
    int i;
    vGateClasses = Vec_IntStart( Gia_ManObjNum(p->pGia) );
1083
    Vec_IntWriteEntry( vGateClasses, 0, 1 );
1084
    Gia_ManForEachObjVec( p->vAbs, p->pGia, pObj, i )
1085
    {
1086 1087 1088
        if ( Gia_ObjIsAnd(pObj) )
            Ga2_ManAbsTranslate_rec( p->pGia, pObj, vGateClasses, 1 );
        else if ( Gia_ObjIsRo(p->pGia, pObj) )
1089 1090 1091
            Vec_IntWriteEntry( vGateClasses, Gia_ObjId(p->pGia, pObj), 1 );
        else if ( !Gia_ObjIsConst0(pObj) )
            assert( 0 );
1092
//        Gia_ObjPrint( p->pGia, pObj );
1093
    }
1094 1095
    return vGateClasses;
}
1096

1097
Vec_Int_t * Ga2_ManAbsDerive( Gia_Man_t * p )
1098
{
1099
    Vec_Int_t * vToAdd;
1100
    Gia_Obj_t * pObj;
1101 1102
    int i;
    vToAdd = Vec_IntAlloc( 1000 );
1103
    Gia_ManForEachRo( p, pObj, i )
1104 1105
        if ( pObj->fPhase && Vec_IntEntry(p->vGateClasses, Gia_ObjId(p, pObj)) )
            Vec_IntPush( vToAdd, Gia_ObjId(p, pObj) );
1106
    Gia_ManForEachAnd( p, pObj, i )
1107 1108 1109 1110 1111 1112 1113 1114
        if ( pObj->fPhase && Vec_IntEntry(p->vGateClasses, i) )
            Vec_IntPush( vToAdd, i );
    return vToAdd;
}

void Ga2_ManRestart( Ga2_Man_t * p )
{
    Vec_Int_t * vToAdd;
1115
    int Lit = 1;
1116
    assert( p->pGia != NULL && p->pGia->vGateClasses != NULL );
1117 1118 1119 1120
    assert( Gia_ManPi(p->pGia, 0)->fPhase ); // marks are set
    // clear SAT variable numbers (begin with 1)
    if ( p->pSat ) sat_solver2_delete( p->pSat );
    p->pSat      = sat_solver2_new();
1121 1122 1123 1124
    p->pSat->nLearntStart = p->pPars->nLearnedStart;
    p->pSat->nLearntDelta = p->pPars->nLearnedDelta;
    p->pSat->nLearntRatio = p->pPars->nLearnedPerce;
    p->pSat->nLearntMax   = p->pSat->nLearntStart;
1125
    // add clause x0 = 0  (lit0 = 1; lit1 = 0)
1126
    sat_solver2_addclause( p->pSat, &Lit, &Lit + 1, -1 );
1127 1128 1129
    // remove previous abstraction
    Ga2_ManShrinkAbs( p, 1, 1, 1 );
    // start new abstraction
1130
    vToAdd = Ga2_ManAbsDerive( p->pGia );
1131 1132
    assert( p->pSat->pPrf2 == NULL );
    assert( p->pPars->iFrame < 0 );
1133
    Ga2_ManAddToAbs( p, vToAdd );
1134
    Vec_IntFree( vToAdd );
1135
    p->LimAbs = Vec_IntSize(p->vAbs);
1136
    p->LimPpi = Vec_IntSize(p->vValues);
1137 1138 1139
    // set runtime limit
    if ( p->pPars->nTimeOut )
        sat_solver2_set_runtime_limit( p->pSat, p->pPars->nTimeOut * CLOCKS_PER_SEC + p->timeStart );
1140 1141
    // clean the hash table
    memset( p->pTable, 0, 6 * sizeof(int) * p->nTable );
1142 1143
}

1144

1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155
/**Function*************************************************************

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
1156 1157 1158
static inline int Ga2_ObjSatValue( Ga2_Man_t * p, Gia_Obj_t * pObj, int f )
{
    int Lit = Ga2_ObjFindLit( p, pObj, f );
1159
    assert( !Gia_ObjIsConst0(pObj) );
1160 1161
    if ( Lit == -1 )
        return 0;
1162 1163
    if ( Abc_Lit2Var(Lit) >= p->pSat->size )
        return 0;
1164
    return Abc_LitIsCompl(Lit) ^ sat_solver2_var_value( p->pSat, Abc_Lit2Var(Lit) );
1165 1166
}
Abc_Cex_t * Ga2_ManDeriveCex( Ga2_Man_t * p, Vec_Int_t * vPis )
1167
{
1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183
    Abc_Cex_t * pCex;
    Gia_Obj_t * pObj;
    int i, f;
    pCex = Abc_CexAlloc( Gia_ManRegNum(p->pGia), Gia_ManPiNum(p->pGia), p->pPars->iFrame+1 );
    pCex->iPo = 0;
    pCex->iFrame = p->pPars->iFrame;
    Gia_ManForEachObjVec( vPis, p->pGia, pObj, i )
    {
        if ( !Gia_ObjIsPi(p->pGia, pObj) )
            continue;
        assert( Gia_ObjIsPi(p->pGia, pObj) );
        for ( f = 0; f <= pCex->iFrame; f++ )
            if ( Ga2_ObjSatValue( p, pObj, f ) )
                Abc_InfoSetBit( pCex->pData, pCex->nRegs + f * pCex->nPis + Gia_ObjCioId(pObj) );
    }
    return pCex;
1184
} 
1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246
void Ga2_ManRefinePrint( Ga2_Man_t * p, Vec_Int_t * vVec )
{
    Gia_Obj_t * pObj, * pFanin;
    int i, k;
    printf( "\n         Unsat core: \n" );
    Gia_ManForEachObjVec( vVec, p->pGia, pObj, i )
    {
        Vec_Int_t * vLeaves = Ga2_ObjLeaves( p->pGia, pObj );
        printf( "%12d : ", i );
        printf( "Obj =%6d ", Gia_ObjId(p->pGia, pObj) );
        if ( Gia_ObjIsRo(p->pGia, pObj) )
            printf( "ff " );
        else
            printf( "   " );
        if ( Ga2_ObjIsAbs0(p, pObj) )
            printf( "a " );
        else if ( Ga2_ObjIsLeaf0(p, pObj) )
            printf( "l " );
        else 
            printf( "  " );
        printf( "Fanins: " );
        Gia_ManForEachObjVec( vLeaves, p->pGia, pFanin, k )
        {
            printf( "%6d ", Gia_ObjId(p->pGia, pFanin) );
            if ( Gia_ObjIsRo(p->pGia, pFanin) )
                printf( "ff " );
            else
                printf( "   " );
            if ( Ga2_ObjIsAbs0(p, pFanin) )
                printf( "a " );
            else if ( Ga2_ObjIsLeaf0(p, pFanin) )
                printf( "l " );
            else
                printf( "  " );
        }
        printf( "\n" );
    }
}
void Ga2_ManRefinePrintPPis( Ga2_Man_t * p )
{
    Vec_Int_t * vVec = Vec_IntAlloc( 100 );
    Gia_Obj_t * pObj;
    int i;
    Gia_ManForEachObjVec( p->vValues, p->pGia, pObj, i )
    {
        if ( !i ) continue;
        if ( Ga2_ObjIsAbs(p, pObj) )
            continue;
        assert( pObj->fPhase );
        assert( Ga2_ObjIsLeaf(p, pObj) );
        assert( Gia_ObjIsAnd(pObj) || Gia_ObjIsCi(pObj) );
        Vec_IntPush( vVec, Gia_ObjId(p->pGia, pObj) );
    }
    printf( "        Current PPIs (%d): ", Vec_IntSize(vVec) );
    Vec_IntSort( vVec, 1 );
    Gia_ManForEachObjVec( vVec, p->pGia, pObj, i )
        printf( "%d ", Gia_ObjId(p->pGia, pObj) );
    printf( "\n" );
    Vec_IntFree( vVec );
}


1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279
void Ga2_GlaPrepareCexAndMap( Ga2_Man_t * p, Abc_Cex_t ** ppCex, Vec_Int_t ** pvMaps )
{
    Abc_Cex_t * pCex;
    Vec_Int_t * vMap;
    Gia_Obj_t * pObj;
    int f, i, k;
/*
    Gia_ManForEachObj( p->pGia, pObj, i )
        if ( Ga2_ObjId(p, pObj) >= 0 )
            assert( Vec_IntEntry(p->vValues, Ga2_ObjId(p, pObj)) == i );
*/
    // find PIs and PPIs
    vMap = Vec_IntAlloc( 1000 );
    Gia_ManForEachObjVec( p->vValues, p->pGia, pObj, i )
    {
        if ( !i ) continue;
        if ( Ga2_ObjIsAbs(p, pObj) )
            continue;
        assert( pObj->fPhase );
        assert( Ga2_ObjIsLeaf(p, pObj) );
        assert( Gia_ObjIsAnd(pObj) || Gia_ObjIsCi(pObj) );
        Vec_IntPush( vMap, Gia_ObjId(p->pGia, pObj) );
    }
    // derive counter-example
    pCex = Abc_CexAlloc( 0, Vec_IntSize(vMap), p->pPars->iFrame+1 );
    pCex->iFrame = p->pPars->iFrame;
    for ( f = 0; f <= p->pPars->iFrame; f++ )
        Gia_ManForEachObjVec( vMap, p->pGia, pObj, k )
            if ( Ga2_ObjSatValue( p, pObj, f ) )
                Abc_InfoSetBit( pCex->pData, f * Vec_IntSize(vMap) + k );
    *pvMaps = vMap;
    *ppCex = pCex;
}
1280 1281 1282 1283
Vec_Int_t * Ga2_ManRefine( Ga2_Man_t * p )
{
    Abc_Cex_t * pCex;
    Vec_Int_t * vMap, * vVec;
1284
    Gia_Obj_t * pObj;
1285
    int i, k;
1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304
    if ( p->pPars->fAddLayer )
    {
        // use simplified refinement strategy, which adds logic near at PPI without finding important ones
        vVec = Vec_IntAlloc( 100 );
        Gia_ManForEachObjVec( p->vValues, p->pGia, pObj, i )
        {
            if ( !i ) continue;
            if ( Ga2_ObjIsAbs(p, pObj) )
                continue;
            assert( pObj->fPhase );
            assert( Ga2_ObjIsLeaf(p, pObj) );
            assert( Gia_ObjIsAnd(pObj) || Gia_ObjIsCi(pObj) );
            if ( Gia_ObjIsPi(p->pGia, pObj) )
                continue;
            Vec_IntPush( vVec, Gia_ObjId(p->pGia, pObj) );
        }
        p->nObjAdded += Vec_IntSize(vVec);
        return vVec;
    }
1305
    Ga2_GlaPrepareCexAndMap( p, &pCex, &vMap );
1306
 //    Rf2_ManRefine( p->pRf2, pCex, vMap, p->pPars->fPropFanout, 1 );
1307
    vVec = Rnm_ManRefine( p->pRnm, pCex, vMap, p->pPars->fPropFanout, p->pPars->fNewRefine, 1 );
1308
//    printf( "Refinement %d\n", Vec_IntSize(vVec) );
1309 1310 1311 1312 1313 1314 1315 1316 1317 1318
    Abc_CexFree( pCex );
    if ( Vec_IntSize(vVec) == 0 )
    {
        Vec_IntFree( vVec );
        Abc_CexFreeP( &p->pGia->pCexSeq );
        p->pGia->pCexSeq = Ga2_ManDeriveCex( p, vMap );
        Vec_IntFree( vMap );
        return NULL;
    }
    Vec_IntFree( vMap );
1319 1320 1321 1322 1323 1324 1325
    // remove those already added
    k = 0;
    Gia_ManForEachObjVec( vVec, p->pGia, pObj, i )
        if ( !Ga2_ObjIsAbs(p, pObj) )
            Vec_IntWriteEntry( vVec, k++, Gia_ObjId(p->pGia, pObj) );
    Vec_IntShrink( vVec, k );

1326 1327
    // these objects should be PPIs that are not abstracted yet
    Gia_ManForEachObjVec( vVec, p->pGia, pObj, i )
1328
        assert( pObj->fPhase );//&& Ga2_ObjIsLeaf(p, pObj) );
1329 1330
    p->nObjAdded += Vec_IntSize(vVec);
    return vVec;
1331 1332 1333 1334
}

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

1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368
  Synopsis    [Creates a new manager.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Ga2_GlaAbsCount( Ga2_Man_t * p, int fRo, int fAnd )
{
    Gia_Obj_t * pObj;
    int i, Counter = 0;
    if ( fRo )
        Gia_ManForEachObjVec( p->vAbs, p->pGia, pObj, i )
            Counter += Gia_ObjIsRo(p->pGia, pObj);
    else if ( fAnd )
        Gia_ManForEachObjVec( p->vAbs, p->pGia, pObj, i )
            Counter += Gia_ObjIsAnd(pObj);
    else assert( 0 );
    return Counter;
}

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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
1369
void Ga2_ManAbsPrintFrame( Ga2_Man_t * p, int nFrames, int nConfls, int nCexes, abctime Time, int fFinal )
1370
{
1371 1372
    int fUseNewLine = ((fFinal && nCexes) || p->pPars->fVeryVerbose);
    if ( Abc_FrameIsBatchMode() && !fUseNewLine )
1373
        return;
1374
    p->fUseNewLine = fUseNewLine;
1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389
    Abc_Print( 1, "%4d :", nFrames );
    Abc_Print( 1, "%4d", Abc_MinInt(100, 100 * Vec_IntSize(p->vAbs) / p->nMarked) ); 
    Abc_Print( 1, "%6d", Vec_IntSize(p->vAbs) );
    Abc_Print( 1, "%5d", Vec_IntSize(p->vValues)-Vec_IntSize(p->vAbs)-1 );
    Abc_Print( 1, "%5d", Ga2_GlaAbsCount(p, 1, 0) );
    Abc_Print( 1, "%6d", Ga2_GlaAbsCount(p, 0, 1) );
    Abc_Print( 1, "%8d", nConfls );
    if ( nCexes == 0 )
        Abc_Print( 1, "%5c", '-' ); 
    else
        Abc_Print( 1, "%5d", nCexes ); 
    Abc_PrintInt( sat_solver2_nvars(p->pSat) );
    Abc_PrintInt( sat_solver2_nclauses(p->pSat) );
    Abc_PrintInt( sat_solver2_nlearnts(p->pSat) );
    Abc_Print( 1, "%9.2f sec", 1.0*Time/CLOCKS_PER_SEC );
1390
    Abc_Print( 1, "%5.0f MB", (sat_solver2_memory_proof(p->pSat) + sat_solver2_memory(p->pSat, 0)) / (1<<20) );
1391
    Abc_Print( 1, "%s", fUseNewLine ? "\n" : "\r" );
1392 1393 1394 1395 1396
    fflush( stdout );
}

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

1397 1398 1399 1400 1401 1402 1403 1404 1405
  Synopsis    [Send abstracted model or send cancel.]

  Description [Counter-example will be sent automatically when &vta terminates.]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420
char * Ga2_GlaGetFileName( Ga2_Man_t * p, int fAbs )
{
    static char * pFileNameDef = "glabs.aig";
    if ( p->pPars->pFileVabs )
        return p->pPars->pFileVabs;
    if ( p->pGia->pSpec )
    {
        if ( fAbs )
            return Extra_FileNameGenericAppend( p->pGia->pSpec, "_abs.aig");
        else
            return Extra_FileNameGenericAppend( p->pGia->pSpec, "_gla.aig");
    }
    return pFileNameDef;
}

1421 1422
void Ga2_GlaDumpAbsracted( Ga2_Man_t * p, int fVerbose )
{
1423
    char * pFileName;
1424
    assert( p->pPars->fDumpMabs || p->pPars->fDumpVabs );
1425
    if ( p->pPars->fDumpMabs )
1426
    {
1427
        pFileName = Ga2_GlaGetFileName(p, 0);
1428 1429
        if ( fVerbose )
            Abc_Print( 1, "Dumping miter with abstraction map into file \"%s\"...\n", pFileName );
1430 1431 1432
        // dump abstraction map
        Vec_IntFreeP( &p->pGia->vGateClasses );
        p->pGia->vGateClasses = Ga2_ManAbsTranslate( p );
1433
        Gia_AigerWrite( p->pGia, pFileName, 0, 0 );
1434
    }
1435
    else if ( p->pPars->fDumpVabs )
1436 1437 1438 1439
    {
        Vec_Int_t * vGateClasses;
        Gia_Man_t * pAbs;
        pFileName = Ga2_GlaGetFileName(p, 1);
1440 1441
        if ( fVerbose )
            Abc_Print( 1, "Dumping abstracted model into file \"%s\"...\n", pFileName );
1442
        // dump absracted model
1443 1444
        vGateClasses = Ga2_ManAbsTranslate( p );
        pAbs = Gia_ManDupAbsGates( p->pGia, vGateClasses );
1445
        Gia_ManCleanValue( p->pGia );
1446
        Gia_AigerWrite( pAbs, pFileName, 0, 0 );
1447 1448 1449
        Gia_ManStop( pAbs );
        Vec_IntFreeP( &vGateClasses );
    }
1450
    else assert( 0 );
1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474
}

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

  Synopsis    [Send abstracted model or send cancel.]

  Description [Counter-example will be sent automatically when &vta terminates.]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Gia_Ga2SendAbsracted( Ga2_Man_t * p, int fVerbose )
{
    Gia_Man_t * pAbs;
    Vec_Int_t * vGateClasses;
    assert( Abc_FrameIsBridgeMode() );
//    if ( fVerbose )
//        Abc_Print( 1, "Sending abstracted model...\n" );
    // create abstraction (value of p->pGia is not used here)
    vGateClasses = Ga2_ManAbsTranslate( p );
    pAbs = Gia_ManDupAbsGates( p->pGia, vGateClasses );
    Vec_IntFreeP( &vGateClasses );
1475
    Gia_ManCleanValue( p->pGia );
1476
    // send it out
1477
    Gia_ManToBridgeAbsNetlist( stdout, pAbs, BRIDGE_ABS_NETLIST );
1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490
    Gia_ManStop( pAbs );
}
void Gia_Ga2SendCancel( Ga2_Man_t * p, int fVerbose )
{
    extern int Gia_ManToBridgeBadAbs( FILE * pFile );
    assert( Abc_FrameIsBridgeMode() );
//    if ( fVerbose )
//        Abc_Print( 1, "Cancelling previously sent model...\n" );
    Gia_ManToBridgeBadAbs( stdout );
}

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

1491 1492 1493 1494 1495 1496 1497 1498 1499
  Synopsis    [Performs gate-level abstraction.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
1500
int Gia_ManPerformGla( Gia_Man_t * pAig, Abs_Par_t * pPars )
1501
{
1502
    int fUseSecondCore = 1;
1503
    Ga2_Man_t * p;
1504
    Vec_Int_t * vCore, * vPPis;
1505
    abctime clk2, clk = Abc_Clock();
1506
    int Status = l_Undef, RetValue = -1, iFrameTryToProve = -1, fOneIsSent = 0;
1507
    int i, c, f, Lit;
1508
    pPars->iFrame = -1;
1509
    // check trivial case 
1510
    assert( Gia_ManPoNum(pAig) == 1 ); 
1511 1512 1513 1514 1515
    ABC_FREE( pAig->pCexSeq );
    if ( Gia_ObjIsConst0(Gia_ObjFanin0(Gia_ManPo(pAig,0))) )
    {
        if ( !Gia_ObjFaninC0(Gia_ManPo(pAig,0)) )
        {
1516
            Abc_Print( 1, "Sequential miter is trivially UNSAT.\n" );
1517 1518 1519
            return 1;
        }
        pAig->pCexSeq = Abc_CexMakeTriv( Gia_ManRegNum(pAig), Gia_ManPiNum(pAig), 1, 0 );
1520
        Abc_Print( 1, "Sequential miter is trivially SAT.\n" );
1521 1522 1523 1524 1525 1526 1527 1528 1529 1530
        return 0;
    }
    // create gate classes if not given
    if ( pAig->vGateClasses == NULL )
    {
        pAig->vGateClasses = Vec_IntStart( Gia_ManObjNum(pAig) );
        Vec_IntWriteEntry( pAig->vGateClasses, 0, 1 );
        Vec_IntWriteEntry( pAig->vGateClasses, Gia_ObjFaninId0p(pAig, Gia_ManPo(pAig, 0)), 1 );
    }
    // start the manager
1531
    p = Ga2_ManStart( pAig, pPars );
1532
    p->timeInit = Abc_Clock() - clk;
1533 1534 1535 1536
    // perform initial abstraction
    if ( p->pPars->fVerbose )
    {
        Abc_Print( 1, "Running gate-level abstraction (GLA) with the following parameters:\n" );
1537 1538
        Abc_Print( 1, "FrameMax = %d  ConfMax = %d  Timeout = %d  Limit = %d %%  Limit2 = %d %%  RatioMax = %d %%\n", 
            pPars->nFramesMax, pPars->nConfLimit, pPars->nTimeOut, pPars->nRatioMin, pPars->nRatioMin2, pPars->nRatioMax );
1539
        Abc_Print( 1, "LrnStart = %d  LrnDelta = %d  LrnRatio = %d %%  Skip = %d  SimpleCNF = %d  Dump = %d\n", 
1540
            pPars->nLearnedStart, pPars->nLearnedDelta, pPars->nLearnedPerce, pPars->fUseSkip, pPars->fUseSimple, pPars->fDumpVabs|pPars->fDumpMabs );
1541 1542 1543 1544
        if ( pPars->fDumpVabs || pPars->fDumpMabs )
            Abc_Print( 1, "%s will be dumped into file \"%s\".\n", 
                pPars->fDumpVabs ? "Abstracted model" : "Miter with abstraction map",
                Ga2_GlaGetFileName(p, pPars->fDumpVabs) );
1545
        Abc_Print( 1, " Frame   %%   Abs  PPI   FF   LUT   Confl  Cex   Vars   Clas   Lrns     Time        Mem\n" );
1546 1547 1548 1549
    }
    // iterate unrolling
    for ( i = f = 0; !pPars->nFramesMax || f < pPars->nFramesMax; i++ )
    {
1550
        int nAbsOld;
1551 1552
        // remember the timeframe
        p->pPars->iFrame = -1;
1553 1554
        // create new SAT solver
        Ga2_ManRestart( p );
1555 1556
        // remember abstraction size after the last restart
        nAbsOld = Vec_IntSize(p->vAbs);
1557 1558 1559
        // unroll the circuit
        for ( f = 0; !pPars->nFramesMax || f < pPars->nFramesMax; f++ )
        {
1560
            // remember current limits
1561
            int nConflsBeg = sat_solver2_nconflicts(p->pSat);
1562 1563 1564
            int nAbs       = Vec_IntSize(p->vAbs);
            int nValues    = Vec_IntSize(p->vValues);
            int nVarsOld;
1565 1566
            // remember the timeframe
            p->pPars->iFrame = f;
1567 1568 1569 1570
            // extend and clear storage
            if ( f == Vec_PtrSize(p->vId2Lit) )
                Vec_PtrPush( p->vId2Lit, Vec_IntAlloc(0) );
            Vec_IntFillExtra( Ga2_MapFrameMap(p, f), Vec_IntSize(p->vValues), -1 );
1571
            // add static clauses to this timeframe
1572
            Ga2_ManAddAbsClauses( p, f );
1573
            // skip checking if skipcheck is enabled (&gla -s)
1574
            if ( p->pPars->fUseSkip && f <= p->pPars->iFrameProved )
1575 1576 1577 1578
                continue;
            // skip checking if we need to skip several starting frames (&gla -S <num>)
            if ( p->pPars->nFramesStart && f <= p->pPars->nFramesStart )
                continue;
1579
            // get the output literal
1580 1581 1582 1583
//            Lit = Ga2_ManUnroll_rec( p, Gia_ManPo(pAig,0), f );
            Lit = Ga2_ObjFindLit( p, Gia_ObjFanin0(Gia_ManPo(pAig,0)), f );
            assert( Lit >= 0 );
            Lit = Abc_LitNotCond( Lit, Gia_ObjFaninC0(Gia_ManPo(pAig,0)) );
1584 1585 1586
            if ( Lit == 0 )
                continue;
            assert( Lit > 1 );
1587
            // check for counter-examples
1588 1589
            if ( p->nSatVars > sat_solver2_nvars(p->pSat) )
                sat_solver2_setnvars( p->pSat, p->nSatVars );
1590
            nVarsOld = p->nSatVars;
1591 1592
            for ( c = 0; ; c++ )
            {
Alan Mishchenko committed
1593 1594 1595 1596 1597 1598 1599 1600 1601
                // consider the special case when the target literal is implied false
                // by implications which happened as a result of previous refinements
                // note that incremental UNSAT core cannot be computed because there is no learned clauses
                // in this case, we will assume that UNSAT core cannot reduce the problem
                if ( var_is_assigned(p->pSat, Abc_Lit2Var(Lit)) )
                {
                    Prf_ManStopP( &p->pSat->pPrf2 );
                    break;
                }
1602
                // perform SAT solving
1603
                clk2 = Abc_Clock();
1604
                Status = sat_solver2_solve( p->pSat, &Lit, &Lit+1, (ABC_INT64_T)pPars->nConfLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 );
1605 1606
                if ( Status == l_True ) // perform refinement
                {
1607
                    p->nCexes++;
1608
                    p->timeSat += Abc_Clock() - clk2;
1609

1610 1611 1612 1613 1614 1615
                    // cancel old one if it was sent
                    if ( Abc_FrameIsBridgeMode() && fOneIsSent )
                    {
                        Gia_Ga2SendCancel( p, pPars->fVerbose );
                        fOneIsSent = 0;
                    }
1616
                    if ( iFrameTryToProve >= 0 )
1617
                    {
1618
                        Gia_GlaProveCancel( pPars->fVerbose );
1619 1620 1621 1622
                        iFrameTryToProve = -1;
                    }

                    // perform refinement
1623
                    clk2 = Abc_Clock();
1624
                    Rnm_ManSetRefId( p->pRnm, c );
1625
                    vPPis = Ga2_ManRefine( p );
1626
                    p->timeCex += Abc_Clock() - clk2;
1627 1628 1629
                    if ( vPPis == NULL )
                    {
                        if ( pPars->fVerbose )
1630
                            Ga2_ManAbsPrintFrame( p, f, sat_solver2_nconflicts(p->pSat)-nConflsBeg, c, Abc_Clock() - clk, 1 );
1631
                        goto finish;
1632
                    }
1633

1634 1635
                    if ( c == 0 )
                    {
1636
//                        Ga2_ManRefinePrintPPis( p );
1637 1638 1639
                        // create bookmark to be used for rollback
                        assert( nVarsOld == p->pSat->size );
                        sat_solver2_bookmark( p->pSat );
1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657
                        // start incremental proof manager
                        assert( p->pSat->pPrf2 == NULL );
                        p->pSat->pPrf2 = Prf_ManAlloc();
                        if ( p->pSat->pPrf2 )
                        {
                            p->nProofIds = 0;
                            Vec_IntFill( p->vProofIds, Gia_ManObjNum(p->pGia), -1 );
                            Prf_ManRestart( p->pSat->pPrf2, p->vProofIds, sat_solver2_nlearnts(p->pSat), Vec_IntSize(vPPis) );
                        }
                    }
                    else
                    {
                        // resize the proof logger
                        if ( p->pSat->pPrf2 )
                            Prf_ManGrow( p->pSat->pPrf2, p->nProofIds + Vec_IntSize(vPPis) );
                    }

                    Ga2_ManAddToAbs( p, vPPis );
1658
                    Vec_IntFree( vPPis );
1659
                    if ( pPars->fVerbose )
1660
                        Ga2_ManAbsPrintFrame( p, f, sat_solver2_nconflicts(p->pSat)-nConflsBeg, c+1, Abc_Clock() - clk, 0 );
1661
                    // check if the number of objects is below limit
1662
                    if ( pPars->nRatioMin2 && Vec_IntSize(p->vAbs) >= p->nMarked * pPars->nRatioMin2 / 100 )
1663 1664 1665 1666
                    {
                        Status = l_Undef;
                        goto finish;
                    }
1667 1668
                    continue;
                }
1669
                p->timeUnsat += Abc_Clock() - clk2;
1670 1671
                if ( Status == l_Undef ) // ran out of resources
                    goto finish;
1672
                if ( p->pSat->nRuntimeLimit && Abc_Clock() > p->pSat->nRuntimeLimit ) // timeout
1673 1674
                    goto finish;
                if ( c == 0 )
1675
                {
1676
                    if ( f > p->pPars->iFrameProved )
1677
                        p->pPars->nFramesNoChange++;
1678
                    break;
1679
                }
1680
                if ( f > p->pPars->iFrameProved )
1681
                    p->pPars->nFramesNoChange = 0;
1682 1683 1684

                // derive the core
                assert( p->pSat->pPrf2 != NULL );
1685
                vCore = (Vec_Int_t *)Sat_ProofCore( p->pSat );
1686
                Prf_ManStopP( &p->pSat->pPrf2 );
1687 1688 1689 1690
                // update the SAT solver
                sat_solver2_rollback( p->pSat );
                // reduce abstraction
                Ga2_ManShrinkAbs( p, nAbs, nValues, nVarsOld );
1691 1692 1693 1694

                // purify UNSAT core
                if ( fUseSecondCore )
                {
1695 1696 1697
//                    int nOldCore = Vec_IntSize(vCore);
                    // reverse the order of objects in the core
//                    Vec_IntSort( vCore, 0 );
1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714
//                    Vec_IntPrint( vCore );
                    // create bookmark to be used for rollback
                    assert( nVarsOld == p->pSat->size );
                    sat_solver2_bookmark( p->pSat );
                    // start incremental proof manager
                    assert( p->pSat->pPrf2 == NULL );
                    p->pSat->pPrf2 = Prf_ManAlloc();
                    if ( p->pSat->pPrf2 )
                    {
                        p->nProofIds = 0;
                        Vec_IntFill( p->vProofIds, Gia_ManObjNum(p->pGia), -1 );
                        Prf_ManRestart( p->pSat->pPrf2, p->vProofIds, sat_solver2_nlearnts(p->pSat), Vec_IntSize(vCore) );

                        Ga2_ManAddToAbs( p, vCore );
                        Vec_IntFree( vCore );
                    }
                    // run SAT solver
1715
                    clk2 = Abc_Clock();
1716
                    Status = sat_solver2_solve( p->pSat, &Lit, &Lit+1, (ABC_INT64_T)pPars->nConfLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 );
1717 1718
                    if ( Status == l_Undef )
                        goto finish;
1719
                    assert( Status == l_False );
1720
                    p->timeUnsat += Abc_Clock() - clk2;
1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732

                    // derive the core
                    assert( p->pSat->pPrf2 != NULL );
                    vCore = (Vec_Int_t *)Sat_ProofCore( p->pSat );
                    Prf_ManStopP( &p->pSat->pPrf2 );
                    // update the SAT solver
                    sat_solver2_rollback( p->pSat );
                    // reduce abstraction
                    Ga2_ManShrinkAbs( p, nAbs, nValues, nVarsOld );
//                    printf( "\n%4d -> %4d\n", nOldCore, Vec_IntSize(vCore) );
                }

1733
                Ga2_ManAddToAbs( p, vCore );
1734
//                Ga2_ManRefinePrint( p, vCore );
1735 1736 1737
                Vec_IntFree( vCore );
                break;
            }
1738
            // remember the last proved frame
1739 1740
            if ( p->pPars->iFrameProved < f )
                p->pPars->iFrameProved = f;
1741
            // print statistics
1742
            if ( pPars->fVerbose )
1743
                Ga2_ManAbsPrintFrame( p, f, sat_solver2_nconflicts(p->pSat)-nConflsBeg, c, Abc_Clock() - clk, 1 );
1744
            // check if abstraction was proved
1745
            if ( Gia_GlaProveCheck( pPars->fVerbose ) )
1746 1747 1748 1749 1750
            {
                RetValue = 1;
                goto finish;
            }
            if ( c > 0 ) 
1751
            {
1752 1753
                if ( p->pPars->fVeryVerbose )
                    Abc_Print( 1, "\n" );
1754
                // recompute the abstraction
1755
                Vec_IntFreeP( &pAig->vGateClasses );
1756
                pAig->vGateClasses = Ga2_ManAbsTranslate( p );
1757
                // check if the number of objects is below limit
1758
                if ( pPars->nRatioMin && Vec_IntSize(p->vAbs) >= p->nMarked * pPars->nRatioMin / 100 )
1759 1760 1761 1762
                {
                    Status = l_Undef;
                    goto finish;
                }
1763 1764 1765 1766
            }
            // check the number of stable frames
            if ( p->pPars->nFramesNoChange == p->pPars->nFramesNoChangeLim )
            {
1767
                // dump the model into file
1768
                if ( p->pPars->fDumpVabs || p->pPars->fDumpMabs )
1769
                {
1770
                    char Command[1000];
1771
                    Abc_FrameSetStatus( -1 );
1772
                    Abc_FrameSetCex( NULL );
1773
                    Abc_FrameSetNFrames( f );
1774
                    sprintf( Command, "write_status %s", Extra_FileNameGenericAppend((char *)(p->pPars->pFileVabs ? p->pPars->pFileVabs : "glabs.aig"), ".status"));
1775
                    Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), Command );
1776 1777
                    Ga2_GlaDumpAbsracted( p, pPars->fVerbose );
                }
1778 1779
                // call the prover
                if ( p->pPars->fCallProver )
1780
                {
1781
                    // cancel old one if it is proving
1782
                    if ( iFrameTryToProve >= 0 )
1783
                        Gia_GlaProveCancel( pPars->fVerbose );
1784
                    // prove new one
1785
                    Gia_GlaProveAbsracted( pAig, pPars->fSimpProver, pPars->fVeryVerbose );
1786
                    iFrameTryToProve = f;
1787
                    p->nPdrCalls++;
1788 1789 1790 1791 1792 1793 1794 1795 1796 1797
                }
                // speak to the bridge
                if ( Abc_FrameIsBridgeMode() )
                {
                    // cancel old one if it was sent
                    if ( fOneIsSent )
                        Gia_Ga2SendCancel( p, pPars->fVerbose );
                    // send new one 
                    Gia_Ga2SendAbsracted( p, pPars->fVerbose );
                    fOneIsSent = 1;
1798
                }
1799
            }
1800 1801
            // if abstraction grew more than a certain percentage, force a restart
            if ( pPars->nRatioMax == 0 )
1802
                continue;
1803 1804 1805 1806 1807 1808 1809
            if ( c > 0 && (f > 20 || Vec_IntSize(p->vAbs) > 100) && Vec_IntSize(p->vAbs) - nAbsOld >= nAbsOld * pPars->nRatioMax / 100 )
            {
                if ( p->pPars->fVerbose )
                Abc_Print( 1, "Forcing restart because abstraction grew from %d to %d (more than %d %%).\n", 
                    nAbsOld, Vec_IntSize(p->vAbs), pPars->nRatioMax );
                break;
            }
1810 1811 1812
        }
    }
finish:
1813
    Prf_ManStopP( &p->pSat->pPrf2 );
1814
    // cancel old one if it is proving
1815
    if ( iFrameTryToProve >= 0 )
1816
        Gia_GlaProveCancel( pPars->fVerbose );
1817
    // analize the results
1818 1819
    if ( !p->fUseNewLine )
        Abc_Print( 1, "\n" );
1820
    if ( RetValue == 1 )
1821
        Abc_Print( 1, "GLA completed %d frames and proved abstraction derived in frame %d  ", p->pPars->iFrameProved+1, iFrameTryToProve );
1822
    else if ( pAig->pCexSeq == NULL )
1823 1824
    {
        Vec_IntFreeP( &pAig->vGateClasses );
1825
        pAig->vGateClasses = Ga2_ManAbsTranslate( p );
1826
        if ( p->pPars->nTimeOut && Abc_Clock() >= p->pSat->nRuntimeLimit ) 
1827 1828 1829
            Abc_Print( 1, "GLA reached timeout %d sec in frame %d with a %d-stable abstraction.    ", p->pPars->nTimeOut, p->pPars->iFrameProved+1, p->pPars->nFramesNoChange );
        else if ( pPars->nConfLimit && sat_solver2_nconflicts(p->pSat) >= pPars->nConfLimit )
            Abc_Print( 1, "GLA exceeded %d conflicts in frame %d with a %d-stable abstraction.  ", pPars->nConfLimit, p->pPars->iFrameProved+1, p->pPars->nFramesNoChange );
1830 1831 1832 1833
        else if ( pPars->nRatioMin2 && Vec_IntSize(p->vAbs) >= p->nMarked * pPars->nRatioMin2 / 100 )
            Abc_Print( 1, "GLA found that the size of abstraction exceeds %d %% in frame %d during refinement.  ", pPars->nRatioMin2, p->pPars->iFrameProved+1 );
        else if ( pPars->nRatioMin && Vec_IntSize(p->vAbs) >= p->nMarked * pPars->nRatioMin / 100 )
            Abc_Print( 1, "GLA found that the size of abstraction exceeds %d %% in frame %d.  ", pPars->nRatioMin, p->pPars->iFrameProved+1 );
1834
        else
1835
            Abc_Print( 1, "GLA finished %d frames and produced a %d-stable abstraction.  ", p->pPars->iFrameProved+1, p->pPars->nFramesNoChange );
1836
        p->pPars->iFrame = p->pPars->iFrameProved;
1837 1838 1839
    }
    else
    {
1840 1841
        if ( p->pPars->fVerbose )
            Abc_Print( 1, "\n" );
1842
        if ( !Gia_ManVerifyCex( pAig, pAig->pCexSeq, 0 ) )
1843
            Abc_Print( 1, "    Gia_ManPerformGlaOld(): CEX verification has failed!\n" );
1844
        Abc_Print( 1, "True counter-example detected in frame %d.  ", f );
1845
        p->pPars->iFrame = f - 1;
1846
        Vec_IntFreeP( &pAig->vGateClasses );
1847
        RetValue = 0;
1848
    }
1849
    Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
1850 1851
    if ( p->pPars->fVerbose )
    {
1852 1853 1854 1855 1856 1857 1858
        p->timeOther = (Abc_Clock() - clk) - p->timeUnsat - p->timeSat - p->timeCex - p->timeInit;
        ABC_PRTP( "Runtime: Initializing", p->timeInit,   Abc_Clock() - clk );
        ABC_PRTP( "Runtime: Solver UNSAT", p->timeUnsat,  Abc_Clock() - clk );
        ABC_PRTP( "Runtime: Solver SAT  ", p->timeSat,    Abc_Clock() - clk );
        ABC_PRTP( "Runtime: Refinement  ", p->timeCex,    Abc_Clock() - clk );
        ABC_PRTP( "Runtime: Other       ", p->timeOther,  Abc_Clock() - clk );
        ABC_PRTP( "Runtime: TOTAL       ", Abc_Clock() - clk, Abc_Clock() - clk );
1859
        Ga2_ManReportMemory( p );
1860
    }
1861
//    Ga2_ManDumpStats( p->pGia, p->pPars, p->pSat, p->pPars->iFrameProved, 0 );
1862
    Ga2_ManStop( p );
1863 1864
    fflush( stdout );
    return RetValue;
1865
}
1866 1867 1868 1869 1870 1871 1872 1873

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


ABC_NAMESPACE_IMPL_END