saigGlaCba.c 26.8 KB
Newer Older
Alan Mishchenko committed
1 2
/**CFile****************************************************************

3
  FileName    [saigGlaCba.c]
Alan Mishchenko committed
4 5 6 7 8 9 10 11 12 13 14 15 16

  SystemName  [ABC: Logic synthesis and verification system.]

  PackageName [Sequential AIG package.]

  Synopsis    [Gate level abstraction.]

  Author      [Alan Mishchenko]
  
  Affiliation [UC Berkeley]

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

17
  Revision    [$Id: saigGlaCba.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
Alan Mishchenko committed
18 19 20 21

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

#include "saig.h"
22 23
#include "sat/bsat/satSolver.h"
#include "sat/cnf/cnf.h"
Alan Mishchenko committed
24 25 26 27 28 29 30 31

ABC_NAMESPACE_IMPL_START


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

32 33
typedef struct Aig_Gla1Man_t_ Aig_Gla1Man_t;
struct Aig_Gla1Man_t_
Alan Mishchenko committed
34 35 36 37 38 39
{
    // user data
    Aig_Man_t *    pAig;
    int            nConfLimit;
    int            nFramesMax;
    int            fVerbose;
40 41 42 43 44
    // unrolling
    int            nFrames;
    Vec_Int_t *    vObj2Vec;   // maps obj ID into its vec ID
    Vec_Int_t *    vVec2Var;   // maps vec ID into its sat Var (nFrames per vec ID)
    Vec_Int_t *    vVar2Inf;   // maps sat Var into its frame and obj ID
Alan Mishchenko committed
45
    // abstraction
Alan Mishchenko committed
46 47 48
    Vec_Int_t *    vAssigned;  // collects objects whose SAT variables have been created
    Vec_Int_t *    vIncluded;  // maps obj ID into its status (0=unused; 1=included in abstraction)
    // components
Alan Mishchenko committed
49 50 51 52
    Vec_Int_t *    vPis;       // primary inputs
    Vec_Int_t *    vPPis;      // pseudo primary inputs
    Vec_Int_t *    vFlops;     // flops
    Vec_Int_t *    vNodes;     // nodes
Alan Mishchenko committed
53 54 55 56 57 58
    // CNF computation
    Vec_Ptr_t *    vLeaves;
    Vec_Ptr_t *    vVolume;
    Vec_Int_t *    vCover;
    Vec_Ptr_t *    vObj2Cnf;
    Vec_Int_t *    vLits;
Alan Mishchenko committed
59 60
    // SAT solver
    sat_solver *   pSat;
Alan Mishchenko committed
61
    // statistics
62 63 64
    clock_t        timeSat;
    clock_t        timeRef;
    clock_t        timeTotal;
Alan Mishchenko committed
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
};

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

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

  Synopsis    [Adds constant to the solver.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
82
static inline int Aig_Gla1AddConst( sat_solver * pSat, int iVar, int fCompl )
Alan Mishchenko committed
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
{
    lit Lit = toLitCond( iVar, fCompl );
    if ( !sat_solver_addclause( pSat, &Lit, &Lit + 1 ) )
        return 0;
    return 1;
}

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

  Synopsis    [Adds buffer to the solver.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
101
static inline int Aig_Gla1AddBuffer( sat_solver * pSat, int iVar0, int iVar1, int fCompl )
Alan Mishchenko committed
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
{
    lit Lits[2];

    Lits[0] = toLitCond( iVar0, 0 );
    Lits[1] = toLitCond( iVar1, !fCompl );
    if ( !sat_solver_addclause( pSat, Lits, Lits + 2 ) )
        return 0;

    Lits[0] = toLitCond( iVar0, 1 );
    Lits[1] = toLitCond( iVar1, fCompl );
    if ( !sat_solver_addclause( pSat, Lits, Lits + 2 ) )
        return 0;

    return 1;
}

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

  Synopsis    [Adds buffer to the solver.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
129
static inline int Aig_Gla1AddNode( sat_solver * pSat, int iVar, int iVar0, int iVar1, int fCompl0, int fCompl1 )
Alan Mishchenko committed
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
{
    lit Lits[3];

    Lits[0] = toLitCond( iVar, 1 );
    Lits[1] = toLitCond( iVar0, fCompl0 );
    if ( !sat_solver_addclause( pSat, Lits, Lits + 2 ) )
        return 0;

    Lits[0] = toLitCond( iVar, 1 );
    Lits[1] = toLitCond( iVar1, fCompl1 );
    if ( !sat_solver_addclause( pSat, Lits, Lits + 2 ) )
        return 0;

    Lits[0] = toLitCond( iVar, 0 );
    Lits[1] = toLitCond( iVar0, !fCompl0 );
    Lits[2] = toLitCond( iVar1, !fCompl1 );
    if ( !sat_solver_addclause( pSat, Lits, Lits + 3 ) )
        return 0;

    return 1;
}

Alan Mishchenko committed
152 153 154 155 156 157 158 159 160 161 162
/**Function*************************************************************

  Synopsis    [Derives abstraction components (PIs, PPIs, flops, nodes).]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
163
void Aig_Gla1CollectAbstr( Aig_Gla1Man_t * p )
Alan Mishchenko committed
164 165 166 167 168 169 170 171 172 173 174 175
{
    Aig_Obj_t * pObj;
    int i, Entry;
/*
    // make sure every neighbor of included objects is assigned a variable
    Vec_IntForEachEntry( p->vIncluded, Entry, i )
    {
        if ( Entry == 0 )
            continue;
        assert( Entry == 1 );
        pObj = Aig_ManObj( p->pAig, i );
        if ( Vec_IntFind( p->vAssigned, Aig_ObjId(pObj) ) == -1 )
176
            printf( "Aig_Gla1CollectAbstr(): Object not found\n" );
Alan Mishchenko committed
177 178 179
        if ( Aig_ObjIsNode(pObj) )
        {
            if ( Vec_IntFind( p->vAssigned, Aig_ObjFaninId0(pObj) ) == -1 )
180
                printf( "Aig_Gla1CollectAbstr(): Node's fanin is not found\n" );
Alan Mishchenko committed
181
            if ( Vec_IntFind( p->vAssigned, Aig_ObjFaninId1(pObj) ) == -1 )
182
                printf( "Aig_Gla1CollectAbstr(): Node's fanin is not found\n" );
Alan Mishchenko committed
183 184 185 186 187 188
        }
        else if ( Saig_ObjIsLo(p->pAig, pObj) ) 
        {
            Aig_Obj_t * pObjLi;
            pObjLi = Saig_ObjLoToLi(p->pAig, pObj);
            if ( Vec_IntFind( p->vAssigned, Aig_ObjFaninId0(pObjLi) ) == -1 )
189
                printf( "Aig_Gla1CollectAbstr(): Flop's fanin is not found\n" );
Alan Mishchenko committed
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
        }
        else assert( Aig_ObjIsConst1(pObj) );
    }
*/
    Vec_IntClear( p->vPis );
    Vec_IntClear( p->vPPis );
    Vec_IntClear( p->vFlops );
    Vec_IntClear( p->vNodes );
    Vec_IntForEachEntryReverse( p->vAssigned, Entry, i )
    {
        pObj = Aig_ManObj( p->pAig, Entry );
        if ( Saig_ObjIsPi(p->pAig, pObj) )
            Vec_IntPush( p->vPis, Aig_ObjId(pObj) );
        else if ( !Vec_IntEntry(p->vIncluded, Aig_ObjId(pObj)) )
            Vec_IntPush( p->vPPis, Aig_ObjId(pObj) );
        else if ( Aig_ObjIsNode(pObj) )
            Vec_IntPush( p->vNodes, Aig_ObjId(pObj) );
        else if ( Saig_ObjIsLo(p->pAig, pObj) )
            Vec_IntPush( p->vFlops, Aig_ObjId(pObj) );
        else assert( Aig_ObjIsConst1(pObj) );
    }
}

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

Alan Mishchenko committed
215 216 217 218 219 220 221 222 223
  Synopsis    [Duplicates the AIG manager recursively.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
224
void Aig_Gla1DeriveAbs_rec( Aig_Man_t * pNew, Aig_Obj_t * pObj )
Alan Mishchenko committed
225 226 227 228
{
    if ( pObj->pData )
        return;
    assert( Aig_ObjIsNode(pObj) );
229 230
    Aig_Gla1DeriveAbs_rec( pNew, Aig_ObjFanin0(pObj) );
    Aig_Gla1DeriveAbs_rec( pNew, Aig_ObjFanin1(pObj) );
Alan Mishchenko committed
231 232 233 234 235
    pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
}

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

Alan Mishchenko committed
236 237 238 239 240 241 242 243 244
  Synopsis    [Derives abstraction.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
245
Aig_Man_t * Aig_Gla1DeriveAbs( Aig_Gla1Man_t * p )
Alan Mishchenko committed
246 247 248
{ 
    Aig_Man_t * pNew;
    Aig_Obj_t * pObj;
249
    int i, RetValue;
Alan Mishchenko committed
250 251 252
    assert( Saig_ManPoNum(p->pAig) == 1 );
    // start the new manager
    pNew = Aig_ManStart( 5000 );
253
    pNew->pName = Abc_UtilStrsav( p->pAig->pName );
Alan Mishchenko committed
254 255 256 257 258
    // create constant
    Aig_ManCleanData( p->pAig );
    Aig_ManConst1(p->pAig)->pData = Aig_ManConst1(pNew);
    // create PIs
    Aig_ManForEachObjVec( p->vPis, p->pAig, pObj, i )
259
        pObj->pData = Aig_ObjCreateCi(pNew);
Alan Mishchenko committed
260 261
    // create additional PIs
    Aig_ManForEachObjVec( p->vPPis, p->pAig, pObj, i )
262
        pObj->pData = Aig_ObjCreateCi(pNew);
Alan Mishchenko committed
263 264
    // create ROs
    Aig_ManForEachObjVec( p->vFlops, p->pAig, pObj, i )
265
        pObj->pData = Aig_ObjCreateCi(pNew);
Alan Mishchenko committed
266 267
    // create internal nodes
    Aig_ManForEachObjVec( p->vNodes, p->pAig, pObj, i )
Alan Mishchenko committed
268
//        pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
269
        Aig_Gla1DeriveAbs_rec( pNew, pObj );
Alan Mishchenko committed
270 271
    // create PO
    Saig_ManForEachPo( p->pAig, pObj, i )
272
        pObj->pData = Aig_ObjCreateCo( pNew, Aig_ObjChild0Copy(pObj) );
Alan Mishchenko committed
273 274 275 276 277
    // create RIs
    Aig_ManForEachObjVec( p->vFlops, p->pAig, pObj, i )
    {
        assert( Saig_ObjIsLo(p->pAig, pObj) );
        pObj = Saig_ObjLoToLi( p->pAig, pObj );
278
        pObj->pData = Aig_ObjCreateCo( pNew, Aig_ObjChild0Copy(pObj) );
Alan Mishchenko committed
279 280 281 282
    }
    Aig_ManSetRegNum( pNew, Vec_IntSize(p->vFlops) );
    // clean up
    RetValue = Aig_ManCleanup( pNew );
Alan Mishchenko committed
283 284
    if ( RetValue > 0 )
        printf( "Aig_Gla1DeriveAbs(): Internal error! Object count mismatch.\n" );
Alan Mishchenko committed
285 286 287
    assert( RetValue == 0 );
    return pNew;
}
Alan Mishchenko committed
288 289 290 291 292 293 294 295 296 297 298 299

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

  Synopsis    [Finds existing SAT variable or creates a new one.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
300
static inline int Aig_Gla1FetchVecId( Aig_Gla1Man_t * p, Aig_Obj_t * pObj )
Alan Mishchenko committed
301
{
302
    int i, iVecId;
Alan Mishchenko committed
303 304 305 306 307 308
    iVecId = Vec_IntEntry( p->vObj2Vec, Aig_ObjId(pObj) );
    if ( iVecId == 0 )
    {
        iVecId = Vec_IntSize( p->vVec2Var ) / p->nFrames;
        for ( i = 0; i < p->nFrames; i++ )
            Vec_IntPush( p->vVec2Var, 0 );
Alan Mishchenko committed
309 310
        Vec_IntWriteEntry( p->vObj2Vec, Aig_ObjId(pObj), iVecId );
        Vec_IntPushOrderReverse( p->vAssigned, Aig_ObjId(pObj) );
Alan Mishchenko committed
311
    }
312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330
    return iVecId;
}

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

  Synopsis    [Finds existing SAT variable or creates a new one.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
static inline int Aig_Gla1FetchVar( Aig_Gla1Man_t * p, Aig_Obj_t * pObj, int k )
{
    int iVecId, iSatVar;
    assert( k < p->nFrames );
    iVecId  = Aig_Gla1FetchVecId( p, pObj );
Alan Mishchenko committed
331 332 333 334 335 336 337
    iSatVar = Vec_IntEntry( p->vVec2Var, iVecId * p->nFrames + k );
    if ( iSatVar == 0 )
    {
        iSatVar = Vec_IntSize( p->vVar2Inf ) / 2;
        Vec_IntPush( p->vVar2Inf, Aig_ObjId(pObj) );
        Vec_IntPush( p->vVar2Inf, k );
        Vec_IntWriteEntry( p->vVec2Var, iVecId * p->nFrames + k, iSatVar );
338
        sat_solver_setnvars( p->pSat, iSatVar + 1 );
Alan Mishchenko committed
339 340 341 342 343 344 345 346 347 348 349 350 351 352 353
    }
    return iSatVar;
}

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

  Synopsis    [Adds CNF for the given object in the given frame.]

  Description [Returns 0, if the solver becames UNSAT.]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
354
int Aig_Gla1ObjAddToSolver( Aig_Gla1Man_t * p, Aig_Obj_t * pObj, int k )
Alan Mishchenko committed
355
{
Alan Mishchenko committed
356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372
    if ( k == p->nFrames )
    {
        int i, j, nVecIds = Vec_IntSize( p->vVec2Var ) / p->nFrames;
        Vec_Int_t * vVec2VarNew = Vec_IntAlloc( 4 * nVecIds * p->nFrames );
        for ( i = 0; i < nVecIds; i++ )
        {
            for ( j = 0; j < p->nFrames; j++ )
                Vec_IntPush( vVec2VarNew, Vec_IntEntry( p->vVec2Var, i * p->nFrames + j ) );
            for ( j = 0; j < p->nFrames; j++ )
                Vec_IntPush( vVec2VarNew, i ? 0 : -1 );
        }
        Vec_IntFree( p->vVec2Var );
        p->vVec2Var = vVec2VarNew;
        p->nFrames *= 2;
    }
    assert( k < p->nFrames );
    assert( Vec_IntEntry(p->vIncluded, Aig_ObjId(pObj)) );
Alan Mishchenko committed
373
    if ( Aig_ObjIsConst1(pObj) )
374
        return Aig_Gla1AddConst( p->pSat, Aig_Gla1FetchVar(p, pObj, k), 0 );
Alan Mishchenko committed
375 376 377 378
    if ( Saig_ObjIsLo(p->pAig, pObj) )
    {
        Aig_Obj_t * pObjLi = Saig_ObjLoToLi(p->pAig, pObj);
        if ( k == 0 )
Alan Mishchenko committed
379
        {
380
            Aig_Gla1FetchVecId( p, Aig_ObjFanin0(pObjLi) );
381
            return Aig_Gla1AddConst( p->pSat, Aig_Gla1FetchVar(p, pObj, k), 1 );
Alan Mishchenko committed
382
        }
383
        return Aig_Gla1AddBuffer( p->pSat, Aig_Gla1FetchVar(p, pObj, k), 
384 385
                   Aig_Gla1FetchVar(p, Aig_ObjFanin0(pObjLi), k-1), 
                   Aig_ObjFaninC0(pObjLi) );
Alan Mishchenko committed
386
    }
Alan Mishchenko committed
387 388 389 390 391 392
    else
    { 
        Vec_Int_t * vClauses;
        int i, Entry;
        assert( Aig_ObjIsNode(pObj) );
        if ( p->vObj2Cnf == NULL )
393
            return Aig_Gla1AddNode( p->pSat, Aig_Gla1FetchVar(p, pObj, k), 
394 395 396
                       Aig_Gla1FetchVar(p, Aig_ObjFanin0(pObj), k), 
                       Aig_Gla1FetchVar(p, Aig_ObjFanin1(pObj), k), 
                       Aig_ObjFaninC0(pObj), Aig_ObjFaninC1(pObj) );
Alan Mishchenko committed
397 398
        // derive clauses
        assert( pObj->fMarkA );
399
        vClauses = (Vec_Int_t *)Vec_PtrEntry( p->vObj2Cnf, Aig_ObjId(pObj) );
Alan Mishchenko committed
400 401 402 403 404 405 406 407
        if ( vClauses == NULL )
        {
            Vec_PtrWriteEntry( p->vObj2Cnf, Aig_ObjId(pObj), (vClauses = Vec_IntAlloc(16)) );
            Cnf_ComputeClauses( p->pAig, pObj, p->vLeaves, p->vVolume, NULL, p->vCover, vClauses );
        }
        // derive variables
        Cnf_CollectLeaves( pObj, p->vLeaves, 0 );
        Vec_PtrForEachEntry( Aig_Obj_t *, p->vLeaves, pObj, i )
408
            Aig_Gla1FetchVar( p, pObj, k );
Alan Mishchenko committed
409 410 411 412 413 414 415 416 417 418
        // translate clauses
        assert( Vec_IntSize(vClauses) >= 2 );
        assert( Vec_IntEntry(vClauses, 0) == 0 );
        Vec_IntForEachEntry( vClauses, Entry, i )
        {
            if ( Entry == 0 )
            {
                Vec_IntClear( p->vLits );
                continue;
            }
419
            Vec_IntPush( p->vLits, (Entry & 1) ^ (2 * Aig_Gla1FetchVar(p, Aig_ManObj(p->pAig, Entry >> 1), k)) );
Alan Mishchenko committed
420 421 422 423 424 425 426 427
            if ( i == Vec_IntSize(vClauses) - 1 || Vec_IntEntry(vClauses, i+1) == 0 )
            {
                if ( !sat_solver_addclause( p->pSat, Vec_IntArray(p->vLits), Vec_IntArray(p->vLits)+Vec_IntSize(p->vLits) ) )
                    return 0;
            }
        }       
        return 1;
    }
Alan Mishchenko committed
428 429 430 431
}

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

432 433 434 435 436 437 438 439 440
  Synopsis    [Returns the array of neighbors.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
441
void Aig_Gla1CollectAssigned( Aig_Gla1Man_t * p, Vec_Int_t * vGateClasses )
442 443 444
{
    Aig_Obj_t * pObj;
    int i, Entry;
445
    Vec_IntForEachEntryReverse( vGateClasses, Entry, i )
446 447 448 449
    {
        if ( Entry == 0 )
            continue;
        assert( Entry == 1 );
450 451
        pObj = Aig_ManObj( p->pAig, i );
        Aig_Gla1FetchVecId( p, pObj );
452 453
        if ( Aig_ObjIsNode(pObj) )
        {
454 455
            Aig_Gla1FetchVecId( p, Aig_ObjFanin0(pObj) );
            Aig_Gla1FetchVecId( p, Aig_ObjFanin1(pObj) );
456
        }
457 458
        else if ( Saig_ObjIsLo(p->pAig, pObj) )
            Aig_Gla1FetchVecId( p, Aig_ObjFanin0(Saig_ObjLoToLi(p->pAig, pObj)) );
459 460 461 462 463 464
        else assert( Aig_ObjIsConst1(pObj) );
    }
}

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

Alan Mishchenko committed
465 466 467 468 469 470 471 472 473
  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
474
Aig_Gla1Man_t * Aig_Gla1ManStart( Aig_Man_t * pAig, Vec_Int_t * vGateClassesOld, int fNaiveCnf )
Alan Mishchenko committed
475
{
476
    Aig_Gla1Man_t * p;
Alan Mishchenko committed
477 478
    int i;

479
    p = ABC_CALLOC( Aig_Gla1Man_t, 1 );
Alan Mishchenko committed
480 481
    p->pAig      = pAig;
    p->nFrames   = 32;
482 483 484 485 486 487 488 489 490 491 492 493 494 495 496

    // unrolling
    p->vObj2Vec  = Vec_IntStart( Aig_ManObjNumMax(pAig) );
    p->vVec2Var  = Vec_IntAlloc( 1 << 20 );
    p->vVar2Inf  = Vec_IntAlloc( 1 << 20 );

    // skip first vector ID
    for ( i = 0; i < p->nFrames; i++ )
        Vec_IntPush( p->vVec2Var, -1 );
    // skip  first SAT variable
    Vec_IntPush( p->vVar2Inf, -1 );
    Vec_IntPush( p->vVar2Inf, -1 );

    // abstraction
    p->vAssigned = Vec_IntAlloc( 1000 );
497 498 499
    if ( vGateClassesOld )
    {
        p->vIncluded = Vec_IntDup( vGateClassesOld );
500
        Aig_Gla1CollectAssigned( p, vGateClassesOld );
501 502 503 504
        assert( fNaiveCnf );
    }
    else
        p->vIncluded = Vec_IntStart( Aig_ManObjNumMax(pAig) );
Alan Mishchenko committed
505

506
    // components
Alan Mishchenko committed
507 508 509 510
    p->vPis      = Vec_IntAlloc( 1000 );
    p->vPPis     = Vec_IntAlloc( 1000 );
    p->vFlops    = Vec_IntAlloc( 1000 );
    p->vNodes    = Vec_IntAlloc( 1000 );
Alan Mishchenko committed
511

Alan Mishchenko committed
512
    // CNF computation
Alan Mishchenko committed
513
    if ( !fNaiveCnf )
Alan Mishchenko committed
514 515 516 517 518 519 520 521 522
    {
        p->vLeaves   = Vec_PtrAlloc( 100 );
        p->vVolume   = Vec_PtrAlloc( 100 );
        p->vCover    = Vec_IntAlloc( 1 << 16 );
        p->vObj2Cnf  = Vec_PtrStart( Aig_ManObjNumMax(pAig) );
        p->vLits     = Vec_IntAlloc( 100 );
        Cnf_DeriveFastMark( pAig );
    }

Alan Mishchenko committed
523 524
    // start the SAT solver
    p->pSat = sat_solver_new();
Alan Mishchenko committed
525
    sat_solver_setnvars( p->pSat, 256 );
Alan Mishchenko committed
526 527 528 529 530 531 532 533 534 535 536 537 538 539 540
    return p;
}


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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
541
void Aig_Gla1ManStop( Aig_Gla1Man_t * p )
Alan Mishchenko committed
542
{
543 544 545 546
    Vec_IntFreeP( &p->vObj2Vec );
    Vec_IntFreeP( &p->vVec2Var );
    Vec_IntFreeP( &p->vVar2Inf );

Alan Mishchenko committed
547 548
    Vec_IntFreeP( &p->vAssigned );
    Vec_IntFreeP( &p->vIncluded );
Alan Mishchenko committed
549 550 551 552 553 554

    Vec_IntFreeP( &p->vPis );
    Vec_IntFreeP( &p->vPPis );
    Vec_IntFreeP( &p->vFlops );
    Vec_IntFreeP( &p->vNodes );

Alan Mishchenko committed
555 556 557 558 559 560 561 562 563 564
    if ( p->vObj2Cnf )
    {
        Vec_PtrFreeP( &p->vLeaves );
        Vec_PtrFreeP( &p->vVolume );
        Vec_IntFreeP( &p->vCover );
        Vec_VecFreeP( (Vec_Vec_t **)&p->vObj2Cnf );
        Vec_IntFreeP( &p->vLits );
        Aig_ManCleanMarkA( p->pAig );
    }

Alan Mishchenko committed
565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580
    if ( p->pSat )
        sat_solver_delete( p->pSat );
    ABC_FREE( p );
}

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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
581
Abc_Cex_t * Aig_Gla1DeriveCex( Aig_Gla1Man_t * p, int iFrame )
Alan Mishchenko committed
582
{
Alan Mishchenko committed
583 584 585 586 587 588 589 590 591 592
    Abc_Cex_t * pCex;
    Aig_Obj_t * pObj;
    int i, f, iVecId, iSatId;
    pCex = Abc_CexAlloc( Vec_IntSize(p->vFlops), Vec_IntSize(p->vPis) + Vec_IntSize(p->vPPis), iFrame+1 );
    pCex->iFrame = iFrame;
    Aig_ManForEachObjVec( p->vPis, p->pAig, pObj, i )
    {
        iVecId = Vec_IntEntry( p->vObj2Vec, Aig_ObjId(pObj) );
        assert( iVecId > 0 );
        for ( f = 0; f <= iFrame; f++ )
Alan Mishchenko committed
593
        {
Alan Mishchenko committed
594 595 596 597 598
            iSatId = Vec_IntEntry( p->vVec2Var, iVecId * p->nFrames + f );
            if ( iSatId == 0 )
                continue;
            assert( iSatId > 0 );
            if ( sat_solver_var_value(p->pSat, iSatId) )
599
                Abc_InfoSetBit( pCex->pData, pCex->nRegs + f * pCex->nPis + i );
Alan Mishchenko committed
600
        }
Alan Mishchenko committed
601 602 603 604 605 606
    }
    Aig_ManForEachObjVec( p->vPPis, p->pAig, pObj, i )
    {
        iVecId = Vec_IntEntry( p->vObj2Vec, Aig_ObjId(pObj) );
        assert( iVecId > 0 );
        for ( f = 0; f <= iFrame; f++ )
Alan Mishchenko committed
607
        {
Alan Mishchenko committed
608 609 610 611 612
            iSatId = Vec_IntEntry( p->vVec2Var, iVecId * p->nFrames + f );
            if ( iSatId == 0 )
                continue;
            assert( iSatId > 0 );
            if ( sat_solver_var_value(p->pSat, iSatId) )
613
                Abc_InfoSetBit( pCex->pData, pCex->nRegs + f * pCex->nPis + Vec_IntSize(p->vPis) + i );
Alan Mishchenko committed
614
        }
Alan Mishchenko committed
615 616
    }
    return pCex;
Alan Mishchenko committed
617 618 619 620
}

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

Alan Mishchenko committed
621
  Synopsis    [Prints current abstraction statistics.]
Alan Mishchenko committed
622 623 624 625 626 627 628 629

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
630
void Aig_Gla1PrintAbstr( Aig_Gla1Man_t * p, int f, int r, int v, int c )
Alan Mishchenko committed
631
{
Alan Mishchenko committed
632 633 634 635 636 637
    if ( r == 0 )
        printf( "== %3d ==", f );
    else
        printf( "         " );
    printf( " %4d  PI =%6d  PPI =%6d  FF =%6d  Node =%6d  Var =%7d  Conf =%6d\n", 
        r, Vec_IntSize(p->vPis), Vec_IntSize(p->vPPis), Vec_IntSize(p->vFlops), Vec_IntSize(p->vNodes), v, c );
Alan Mishchenko committed
638 639 640 641
}

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

Alan Mishchenko committed
642 643 644 645 646 647 648 649 650
  Synopsis    [Prints current abstraction statistics.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
651
void Aig_Gla1ExtendIncluded( Aig_Gla1Man_t * p )
Alan Mishchenko committed
652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669
{
    Aig_Obj_t * pObj;
    int i, k;
    Aig_ManForEachNode( p->pAig, pObj, i )
    {
        if ( !Vec_IntEntry( p->vIncluded, i ) )
            continue;
        Cnf_ComputeClauses( p->pAig, pObj, p->vLeaves, p->vVolume, NULL, p->vCover, p->vNodes );
        Vec_PtrForEachEntry( Aig_Obj_t *, p->vVolume, pObj, k )
        {
            assert( Aig_ObjId(pObj) <= i );
            Vec_IntWriteEntry( p->vIncluded, Aig_ObjId(pObj), 1 );
        }
    }
}

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

Alan Mishchenko committed
670
  Synopsis    [Performs gate-level localization abstraction.]
Alan Mishchenko committed
671

Alan Mishchenko committed
672 673 674
  Description [Returns array of objects included in the abstraction. This array
  may contain only const1, flop outputs, and internal nodes, that is, objects
  that should have clauses added to the SAT solver.]
Alan Mishchenko committed
675 676 677 678 679 680
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
681
Vec_Int_t * Aig_Gla1ManPerform( Aig_Man_t * pAig, Vec_Int_t * vGateClassesOld, int nStart, int nFramesMax, int nConfLimit, int TimeLimit, int fNaiveCnf, int fVerbose, int * piFrame )
Alan Mishchenko committed
682
{
Alan Mishchenko committed
683
    Vec_Int_t * vResult = NULL;
684
    Aig_Gla1Man_t * p;
Alan Mishchenko committed
685 686 687
    Aig_Man_t * pAbs;
    Aig_Obj_t * pObj;
    Abc_Cex_t * pCex;
Alan Mishchenko committed
688
    Vec_Int_t * vPPiRefine;
Alan Mishchenko committed
689
    int f, g, r, i, iSatVar, Lit, Entry, RetValue;
690 691 692
    int nConfBef, nConfAft;
    clock_t clk, clkTotal = clock();
    clock_t nTimeToStop = TimeLimit ? TimeLimit * CLOCKS_PER_SEC + clock(): 0;
Alan Mishchenko committed
693 694
    assert( Saig_ManPoNum(pAig) == 1 );

695 696 697
    if ( nFramesMax == 0 )
        nFramesMax = ABC_INFINITY;

Alan Mishchenko committed
698 699
    if ( fVerbose )
    {
Alan Mishchenko committed
700 701 702 703
        if ( TimeLimit )
            printf( "Abstracting from frame %d to frame %d with timeout %d sec.\n", nStart, nFramesMax, TimeLimit );
        else
            printf( "Abstracting from frame %d to frame %d with no timeout.\n", nStart, nFramesMax );
Alan Mishchenko committed
704 705
    }

Alan Mishchenko committed
706
    // start the solver
707
    p = Aig_Gla1ManStart( pAig, vGateClassesOld, fNaiveCnf );
Alan Mishchenko committed
708 709 710 711
    p->nFramesMax = nFramesMax;
    p->nConfLimit = nConfLimit;
    p->fVerbose   = fVerbose;

Alan Mishchenko committed
712 713
    // include constant node
    Vec_IntWriteEntry( p->vIncluded, 0, 1 );
714
    Aig_Gla1FetchVecId( p, Aig_ManConst1(pAig) );
Alan Mishchenko committed
715 716 717

    // set runtime limit
    if ( TimeLimit )
718
        sat_solver_set_runtime_limit( p->pSat, nTimeToStop );
Alan Mishchenko committed
719

Alan Mishchenko committed
720 721 722 723
    // iterate over the timeframes
    for ( f = 0; f < nFramesMax; f++ )
    {
        // initialize abstraction in this timeframe
Alan Mishchenko committed
724 725
        Aig_ManForEachObjVec( p->vAssigned, pAig, pObj, i )
            if ( Vec_IntEntry(p->vIncluded, Aig_ObjId(pObj)) )
726
                if ( !Aig_Gla1ObjAddToSolver( p, pObj, f ) )
Alan Mishchenko committed
727
                    printf( "Error!  SAT solver became UNSAT.\n" );
Alan Mishchenko committed
728

729 730 731 732
        // skip checking if we are not supposed to
        if ( f < nStart )
            continue;

Alan Mishchenko committed
733
        // create output literal to represent property failure
734
        pObj    = Aig_ManCo( pAig, 0 );
735
        iSatVar = Aig_Gla1FetchVar( p, Aig_ObjFanin0(pObj), f );
Alan Mishchenko committed
736 737 738
        Lit     = toLitCond( iSatVar, Aig_ObjFaninC0(pObj) );

        // try solving the abstraction
739
        Aig_Gla1CollectAbstr( p );
740
        for ( r = 0; r < ABC_INFINITY; r++ )
Alan Mishchenko committed
741
        {
Alan Mishchenko committed
742 743 744
            // try to find a counter-example
            clk = clock();
            nConfBef = p->pSat->stats.conflicts;
Alan Mishchenko committed
745 746
            RetValue = sat_solver_solve( p->pSat, &Lit, &Lit + 1, 
                (ABC_INT64_T)nConfLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 );
Alan Mishchenko committed
747 748
            nConfAft = p->pSat->stats.conflicts;
            p->timeSat += clock() - clk;
Alan Mishchenko committed
749
            if ( RetValue != l_True )
Alan Mishchenko committed
750 751 752 753 754 755 756
            {
                if ( fVerbose )
                {
                    if ( r == 0 )
                        printf( "== %3d ==", f );
                    else
                        printf( "         " );
757
                    if ( TimeLimit && clock() > nTimeToStop )
Alan Mishchenko committed
758 759 760 761
                        printf( "       SAT solver timed out after %d seconds.\n", TimeLimit );
                    else if ( RetValue != l_False )
                        printf( "       SAT solver returned UNDECIDED after %5d conflicts.\n", nConfAft - nConfBef );
                    else
762 763 764 765
                    {
                        printf( "       SAT solver returned UNSAT after %5d conflicts.  ", nConfAft - nConfBef );
                        Abc_PrintTime( 1, "Total time", clock() - clkTotal );
                    }
Alan Mishchenko committed
766
                }
Alan Mishchenko committed
767
                break;
Alan Mishchenko committed
768 769
            }
            clk = clock();
Alan Mishchenko committed
770
            // derive abstraction
771
            pAbs = Aig_Gla1DeriveAbs( p );
Alan Mishchenko committed
772
            // derive counter-example
773
            pCex = Aig_Gla1DeriveCex( p, f );
Alan Mishchenko committed
774 775 776 777
            // verify the counter-example
            RetValue = Saig_ManVerifyCex( pAbs, pCex );
            if ( RetValue == 0 )
                printf( "Error!  CEX is invalid.\n" );
Alan Mishchenko committed
778
            // perform refinement
Alan Mishchenko committed
779 780
            vPPiRefine = Saig_ManCbaFilterInputs( pAbs, Vec_IntSize(p->vPis), pCex, 0 );
            Vec_IntForEachEntry( vPPiRefine, Entry, i )
Alan Mishchenko committed
781
            {
Alan Mishchenko committed
782 783 784 785
                pObj = Aig_ManObj( pAig, Vec_IntEntry(p->vPPis, Entry) );
                assert( Aig_ObjIsNode(pObj) || Saig_ObjIsLo(p->pAig, pObj) );
                assert( Vec_IntEntry( p->vIncluded, Aig_ObjId(pObj) ) == 0 );
                Vec_IntWriteEntry( p->vIncluded, Aig_ObjId(pObj), 1 );
Alan Mishchenko committed
786
                for ( g = 0; g <= f; g++ )
787
                    if ( !Aig_Gla1ObjAddToSolver( p, pObj, g ) )
Alan Mishchenko committed
788
                        printf( "Error!  SAT solver became UNSAT.\n" );
Alan Mishchenko committed
789
            }
Alan Mishchenko committed
790 791 792 793 794 795 796 797
            if ( Vec_IntSize(vPPiRefine) == 0 )
            {
                Vec_IntFreeP( &p->vIncluded );
                Vec_IntFree( vPPiRefine );
                Aig_ManStop( pAbs );
                Abc_CexFree( pCex );
                break;
            }
Alan Mishchenko committed
798 799 800 801 802 803
            Vec_IntFree( vPPiRefine );
            Aig_ManStop( pAbs );
            Abc_CexFree( pCex );
            p->timeRef += clock() - clk;

            // prepare abstraction
804
            Aig_Gla1CollectAbstr( p );
Alan Mishchenko committed
805
            if ( fVerbose )
806
                Aig_Gla1PrintAbstr( p, f, r, p->pSat->size, nConfAft - nConfBef );
Alan Mishchenko committed
807 808 809 810
        }
        if ( RetValue != l_False )
            break;
    }
Alan Mishchenko committed
811
    p->timeTotal = clock() - clkTotal;
Alan Mishchenko committed
812 813
    if ( f == nFramesMax )
        printf( "Finished %d frames without exceeding conflict limit (%d).\n", f, nConfLimit );
Alan Mishchenko committed
814 815
    else if ( p->vIncluded == NULL )
        printf( "The problem is SAT in frame %d. The CEX is currently not produced.\n", f );
Alan Mishchenko committed
816 817
    else
        printf( "Ran out of conflict limit (%d) at frame %d.\n", nConfLimit, f );
818
    *piFrame = f;
Alan Mishchenko committed
819 820 821 822 823 824 825 826
    // print stats
    if ( fVerbose )
    {
        ABC_PRTP( "Sat   ", p->timeSat,   p->timeTotal );
        ABC_PRTP( "Ref   ", p->timeRef,   p->timeTotal );
        ABC_PRTP( "Total ", p->timeTotal, p->timeTotal );
    }
    // prepare return value
Alan Mishchenko committed
827
    if ( !fNaiveCnf && p->vIncluded )
828
        Aig_Gla1ExtendIncluded( p );
Alan Mishchenko committed
829
    vResult = p->vIncluded;  p->vIncluded = NULL;
830
    Aig_Gla1ManStop( p );
Alan Mishchenko committed
831
    return vResult;
Alan Mishchenko committed
832 833 834 835 836 837 838 839 840
}

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


ABC_NAMESPACE_IMPL_END