fraClaus.c 56.4 KB
Newer Older
Alan Mishchenko committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/**CFile****************************************************************

  FileName    [fraClaus.c]

  SystemName  [ABC: Logic synthesis and verification system.]

  PackageName [New FRAIG package.]

  Synopsis    [Induction with clause strengthening.]

  Author      [Alan Mishchenko]
  
  Affiliation [UC Berkeley]

  Date        [Ver. 1.0. Started - June 30, 2007.]

  Revision    [$Id: fraClau.c,v 1.00 2007/06/30 00:00:00 alanmi Exp $]

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

#include "fra.h"
22 23
#include "sat/cnf/cnf.h"
#include "sat/bsat/satSolver.h"
Alan Mishchenko committed
24

25 26 27
ABC_NAMESPACE_IMPL_START


Alan Mishchenko committed
28 29 30 31 32 33 34 35
////////////////////////////////////////////////////////////////////////
///                        DECLARATIONS                              ///
////////////////////////////////////////////////////////////////////////

typedef struct Clu_Man_t_    Clu_Man_t;
struct Clu_Man_t_
{
    // parameters
Alan Mishchenko committed
36 37 38
    int              nFrames;        // the K of the K-step induction
    int              nPref;          // the number of timeframes to skip  
    int              nClausesMax;    // the max number of 4-clauses to consider
Alan Mishchenko committed
39 40 41 42 43
    int              nLutSize;       // the max cut size
    int              nLevels;        // the number of levels for cut computation
    int              nCutsMax;       // the maximum number of cuts to compute at a node
    int              nBatches;       // the number of clause batches to use
    int              fStepUp;        // increase cut size for each batch
Alan Mishchenko committed
44
    int              fTarget;        // tries to prove the property
Alan Mishchenko committed
45
    int              fVerbose;       
Alan Mishchenko committed
46
    int              fVeryVerbose;
Alan Mishchenko committed
47 48 49 50 51
    // internal parameters
    int              nSimWords;      // the number of simulation words
    int              nSimWordsPref;  // the number of simulation words in the prefix
    int              nSimFrames;     // the number of frames to simulate 
    int              nBTLimit;       // the largest number of backtracks (0 = infinite)
Alan Mishchenko committed
52
    // the network 
Alan Mishchenko committed
53 54 55 56 57 58
    Aig_Man_t *      pAig;
    // SAT solvers
    sat_solver *     pSatMain;
    sat_solver *     pSatBmc;
    // CNF for the test solver
    Cnf_Dat_t *      pCnf;
Alan Mishchenko committed
59 60 61
    int              fFail;
    int              fFiltering; 
    int              fNothingNew;
Alan Mishchenko committed
62 63 64 65 66
    // clauses
    Vec_Int_t *      vLits;
    Vec_Int_t *      vClauses;
    Vec_Int_t *      vCosts;
    int              nClauses;
Alan Mishchenko committed
67 68 69
    int              nCuts;
    int              nOneHots;
    int              nOneHotsProven;
Alan Mishchenko committed
70 71 72
    // clauses proven
    Vec_Int_t *      vLitsProven;
    Vec_Int_t *      vClausesProven;
Alan Mishchenko committed
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
    // counter-examples
    Vec_Ptr_t *      vCexes;
    int              nCexes;
    int              nCexesAlloc;
};

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

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

  Synopsis    [Runs the SAT solver on the problem.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Fra_ClausRunBmc( Clu_Man_t * p )
{
    Aig_Obj_t * pObj;
Alan Mishchenko committed
97
    int Lits[2], nLitsTot, RetValue, i;
Alan Mishchenko committed
98
    // set the output literals
Alan Mishchenko committed
99
    nLitsTot = 2 * p->pCnf->nVars;
100
    pObj = Aig_ManCo(p->pAig, 0);
Alan Mishchenko committed
101
    for ( i = 0; i < p->nPref + p->nFrames; i++ )
Alan Mishchenko committed
102
    {
Alan Mishchenko committed
103
        Lits[0] = i * nLitsTot + toLitCond( p->pCnf->pVarNums[pObj->Id], 0 ); 
Alan Mishchenko committed
104
        RetValue = sat_solver_solve( p->pSatBmc, Lits, Lits + 1, (ABC_INT64_T)p->nBTLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 );
Alan Mishchenko committed
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
        if ( RetValue != l_False )
            return 0;
    }
    return 1;
}

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

  Synopsis    [Runs the SAT solver on the problem.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Fra_ClausRunSat( Clu_Man_t * p )
{
    Aig_Obj_t * pObj;
    int * pLits;
Alan Mishchenko committed
126
    int i, RetValue;
Alan Mishchenko committed
127
    pLits = ABC_ALLOC( int, p->nFrames + 1 );
Alan Mishchenko committed
128
    // set the output literals
129
    pObj = Aig_ManCo(p->pAig, 0);
Alan Mishchenko committed
130 131 132
    for ( i = 0; i <= p->nFrames; i++ )
        pLits[i] = i * 2 * p->pCnf->nVars + toLitCond( p->pCnf->pVarNums[pObj->Id], i != p->nFrames ); 
    // try to solve the problem
Alan Mishchenko committed
133 134
    RetValue = sat_solver_solve( p->pSatMain, pLits, pLits + p->nFrames + 1, (ABC_INT64_T)p->nBTLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 );
    ABC_FREE( pLits );
Alan Mishchenko committed
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
    if ( RetValue == l_False )
        return 1;
    // get the counter-example
    assert( RetValue == l_True );
    return 0;
}

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

  Synopsis    [Runs the SAT solver on the problem.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Fra_ClausRunSat0( Clu_Man_t * p )
{
    Aig_Obj_t * pObj;
    int Lits[2], RetValue;
157
    pObj = Aig_ManCo(p->pAig, 0);
Alan Mishchenko committed
158
    Lits[0] = toLitCond( p->pCnf->pVarNums[pObj->Id], 0 ); 
Alan Mishchenko committed
159
    RetValue = sat_solver_solve( p->pSatMain, Lits, Lits + 1, (ABC_INT64_T)p->nBTLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 );
Alan Mishchenko committed
160 161 162 163 164 165 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
    if ( RetValue == l_False )
        return 1;
    return 0;
}

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

  Synopsis    [Return combinations appearing in the cut.]

  Description [This procedure is taken from "Hacker's Delight" by H.S.Warren.]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void transpose32a( unsigned a[32] ) 
{
    int j, k;
    unsigned long m, t;
    for ( j = 16, m = 0x0000FFFF; j; j >>= 1, m ^= m << j ) 
    {
        for ( k = 0; k < 32; k = ((k | j) + 1) & ~j ) 
        {
            t = (a[k] ^ (a[k|j] >> j)) & m;
            a[k] ^= t;
            a[k|j] ^= (t << j);
        }
    }
}

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

  Synopsis    [Return combinations appearing in the cut.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Fra_ClausProcessClausesCut( Clu_Man_t * p, Fra_Sml_t * pSimMan, Dar_Cut_t * pCut, int * pScores )
{
    unsigned Matrix[32];
Alan Mishchenko committed
205
    unsigned * pSims[16], uWord;
Alan Mishchenko committed
206
    int nSeries, i, k, j;
Alan Mishchenko committed
207
    int nWordsForSim = pSimMan->nWordsTotal - p->nSimWordsPref;
Alan Mishchenko committed
208 209
    // compute parameters
    assert( pCut->nLeaves > 1 && pCut->nLeaves < 5 );
Alan Mishchenko committed
210
    assert( nWordsForSim % 8 == 0 );
Alan Mishchenko committed
211 212
    // get parameters
    for ( i = 0; i < (int)pCut->nLeaves; i++ )
Alan Mishchenko committed
213
        pSims[i] = Fra_ObjSim( pSimMan, pCut->pLeaves[i] ) + p->nSimWordsPref;
Alan Mishchenko committed
214 215
    // add combinational patterns
    memset( pScores, 0, sizeof(int) * 16 );
Alan Mishchenko committed
216
    nSeries = nWordsForSim / 8;
Alan Mishchenko committed
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 243 244 245 246 247 248 249
    for ( i = 0; i < nSeries; i++ )
    {
        memset( Matrix, 0, sizeof(unsigned) * 32 );
        for ( k = 0; k < 8; k++ )
            for ( j = 0; j < (int)pCut->nLeaves; j++ )
                Matrix[31-(k*4+j)] = pSims[j][i*8+k];
        transpose32a( Matrix );
        for ( k = 0; k < 32; k++ )
            for ( j = 0, uWord = Matrix[k]; j < 8; j++, uWord >>= 4 )
                pScores[uWord & 0xF]++;
    }
    // collect patterns
    uWord = 0;
    for ( i = 0; i < 16; i++ )
        if ( pScores[i] )
            uWord |= (1 << i);
//    Extra_PrintBinary( stdout, &uWord, 16 ); printf( "\n" );
    return (int)uWord;
}

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

  Synopsis    [Return combinations appearing in the cut.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Fra_ClausProcessClausesCut2( Clu_Man_t * p, Fra_Sml_t * pSimMan, Dar_Cut_t * pCut, int * pScores )
{
Alan Mishchenko committed
250
    unsigned * pSims[16], uWord;
Alan Mishchenko committed
251
    int iMint, i, k, b;
Alan Mishchenko committed
252
    int nWordsForSim = pSimMan->nWordsTotal - p->nSimWordsPref;
Alan Mishchenko committed
253 254
    // compute parameters
    assert( pCut->nLeaves > 1 && pCut->nLeaves < 5 );
Alan Mishchenko committed
255
    assert( nWordsForSim % 8 == 0 );
Alan Mishchenko committed
256 257
    // get parameters
    for ( i = 0; i < (int)pCut->nLeaves; i++ )
Alan Mishchenko committed
258
        pSims[i] = Fra_ObjSim( pSimMan, pCut->pLeaves[i] ) + p->nSimWordsPref;
Alan Mishchenko committed
259 260
    // add combinational patterns
    memset( pScores, 0, sizeof(int) * 16 );
Alan Mishchenko committed
261
    for ( i = 0; i < nWordsForSim; i++ )
Alan Mishchenko committed
262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278
        for ( k = 0; k < 32; k++ )
        {
            iMint = 0;
            for ( b = 0; b < (int)pCut->nLeaves; b++ )
                if ( pSims[b][i] & (1 << k) )
                    iMint |= (1 << b);
            pScores[iMint]++;
        }
    // collect patterns
    uWord = 0;
    for ( i = 0; i < 16; i++ )
        if ( pScores[i] )
            uWord |= (1 << i);
//    Extra_PrintBinary( stdout, &uWord, 16 ); printf( "\n" );
    return (int)uWord;
}

Alan Mishchenko committed
279 280 281 282 283 284 285 286 287 288 289 290 291
/**Function*************************************************************

  Synopsis    [Return the number of combinations appearing in the cut.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Fra_ClausProcessClausesCut3( Clu_Man_t * p, Fra_Sml_t * pSimMan, Aig_Cut_t * pCut, int * pScores )
{
Alan Mishchenko committed
292 293 294
    unsigned Matrix[32];
    unsigned * pSims[16], uWord;
    int iMint, i, j, k, b, nMints, nSeries;
Alan Mishchenko committed
295
    int nWordsForSim = pSimMan->nWordsTotal - p->nSimWordsPref;
Alan Mishchenko committed
296

Alan Mishchenko committed
297 298 299 300 301 302 303 304 305
    // compute parameters
    assert( pCut->nFanins > 1 && pCut->nFanins < 17 );
    assert( nWordsForSim % 8 == 0 );
    // get parameters
    for ( i = 0; i < (int)pCut->nFanins; i++ )
        pSims[i] = Fra_ObjSim( pSimMan, pCut->pFanins[i] ) + p->nSimWordsPref;
    // add combinational patterns
    nMints = (1 << pCut->nFanins);
    memset( pScores, 0, sizeof(int) * nMints );
Alan Mishchenko committed
306 307 308 309 310 311

    if ( pCut->nLeafMax == 4 )
    {
        // convert the simulation patterns
        nSeries = nWordsForSim / 8;
        for ( i = 0; i < nSeries; i++ )
Alan Mishchenko committed
312
        {
Alan Mishchenko committed
313 314 315 316 317 318 319 320
            memset( Matrix, 0, sizeof(unsigned) * 32 );
            for ( k = 0; k < 8; k++ )
                for ( j = 0; j < (int)pCut->nFanins; j++ )
                    Matrix[31-(k*4+j)] = pSims[j][i*8+k];
            transpose32a( Matrix );
            for ( k = 0; k < 32; k++ )
                for ( j = 0, uWord = Matrix[k]; j < 8; j++, uWord >>= 4 )
                    pScores[uWord & 0xF]++;
Alan Mishchenko committed
321
        }
Alan Mishchenko committed
322 323 324 325 326 327 328 329 330 331 332 333 334 335
    }
    else
    {
        // go through the simulation patterns
        for ( i = 0; i < nWordsForSim; i++ )
            for ( k = 0; k < 32; k++ )
            {
                iMint = 0;
                for ( b = 0; b < (int)pCut->nFanins; b++ )
                    if ( pSims[b][i] & (1 << k) )
                        iMint |= (1 << b);
                pScores[iMint]++;
            }
    }
Alan Mishchenko committed
336 337
}

Alan Mishchenko committed
338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355

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

  Synopsis    [Returns the cut-off cost.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Fra_ClausSelectClauses( Clu_Man_t * p )
{
    int * pCostCount, nClauCount, Cost, CostMax, i, c;
    assert( Vec_IntSize(p->vClauses) > p->nClausesMax );   
    // count how many implications have each cost
    CostMax = p->nSimWords * 32 + 1;
Alan Mishchenko committed
356
    pCostCount = ABC_ALLOC( int, CostMax );
Alan Mishchenko committed
357 358 359
    memset( pCostCount, 0, sizeof(int) * CostMax );
    Vec_IntForEachEntry( p->vCosts, Cost, i )
    {
Alan Mishchenko committed
360 361
        if ( Cost == -1 )
            continue;
Alan Mishchenko committed
362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385
        assert( Cost < CostMax );
        pCostCount[ Cost ]++;
    }
    assert( pCostCount[0] == 0 );
    // select the bound on the cost (above this bound, implication will be included)
    nClauCount = 0;
    for ( c = CostMax - 1; c > 0; c-- )
    {
        assert( pCostCount[c] >= 0 );
        nClauCount += pCostCount[c];
        if ( nClauCount >= p->nClausesMax )
            break;
    }
    // collect implications with the given costs
    nClauCount = 0;
    Vec_IntForEachEntry( p->vCosts, Cost, i )
    {
        if ( Cost >= c && nClauCount < p->nClausesMax )
        {
            nClauCount++;
            continue;
        }
        Vec_IntWriteEntry( p->vCosts, i, -1 );
    }
Alan Mishchenko committed
386
    ABC_FREE( pCostCount );
Alan Mishchenko committed
387 388 389 390 391 392 393
    p->nClauses = nClauCount;
if ( p->fVerbose )
printf( "Selected %d clauses. Cost range: [%d < %d < %d]\n", nClauCount, 1, c, CostMax );
    return c;
}


Alan Mishchenko committed
394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415
/**Function*************************************************************

  Synopsis    [Processes the clauses.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Fra_ClausRecordClause( Clu_Man_t * p, Dar_Cut_t * pCut, int iMint, int Cost )
{
    int i;
    for ( i = 0; i < (int)pCut->nLeaves; i++ )
        Vec_IntPush( p->vLits, toLitCond( p->pCnf->pVarNums[pCut->pLeaves[i]], (iMint&(1<<i)) ) );
    Vec_IntPush( p->vClauses, Vec_IntSize(p->vLits) );
    Vec_IntPush( p->vCosts, Cost );
}

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

Alan Mishchenko committed
416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435
  Synopsis    [Processes the clauses.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Fra_ClausRecordClause2( Clu_Man_t * p, Aig_Cut_t * pCut, int iMint, int Cost )
{
    int i;
    for ( i = 0; i < (int)pCut->nFanins; i++ )
        Vec_IntPush( p->vLits, toLitCond( p->pCnf->pVarNums[pCut->pFanins[i]], (iMint&(1<<i)) ) );
    Vec_IntPush( p->vClauses, Vec_IntSize(p->vLits) );
    Vec_IntPush( p->vCosts, Cost );
}

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

Alan Mishchenko committed
436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520
  Synopsis    [Returns 1 if simulation info is composed of all zeros.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Fra_ClausSmlNodeIsConst( Fra_Sml_t * pSeq, Aig_Obj_t * pObj )
{
    unsigned * pSims;
    int i;
    pSims = Fra_ObjSim(pSeq, pObj->Id);
    for ( i = pSeq->nWordsPref; i < pSeq->nWordsTotal; i++ )
        if ( pSims[i] )
            return 0;
    return 1;
}

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

  Synopsis    [Returns 1 if implications holds.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Fra_ClausSmlNodesAreImp( Fra_Sml_t * pSeq, Aig_Obj_t * pObj1, Aig_Obj_t * pObj2 )
{
    unsigned * pSimL, * pSimR;
    int k;
    pSimL = Fra_ObjSim(pSeq, pObj1->Id);
    pSimR = Fra_ObjSim(pSeq, pObj2->Id);
    for ( k = pSeq->nWordsPref; k < pSeq->nWordsTotal; k++ )
        if ( pSimL[k] & ~pSimR[k] ) // !(Obj1 -> Obj2)
            return 0;
    return 1;
}

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

  Synopsis    [Returns 1 if implications holds.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Fra_ClausSmlNodesAreImpC( Fra_Sml_t * pSeq, Aig_Obj_t * pObj1, Aig_Obj_t * pObj2 )
{
    unsigned * pSimL, * pSimR;
    int k;
    pSimL = Fra_ObjSim(pSeq, pObj1->Id);
    pSimR = Fra_ObjSim(pSeq, pObj2->Id);
    for ( k = pSeq->nWordsPref; k < pSeq->nWordsTotal; k++ )
        if ( pSimL[k] & pSimR[k] )
            return 0;
    return 1;
}

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

  Synopsis    [Processes the clauses.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Fra_ClausCollectLatchClauses( Clu_Man_t * p, Fra_Sml_t * pSeq )
{
    Aig_Obj_t * pObj1, * pObj2;
    unsigned * pSims1, * pSims2;
    int CostMax, i, k, nCountConst, nCountImps;

    nCountConst = nCountImps = 0;
    CostMax = p->nSimWords * 32;
Alan Mishchenko committed
521
/*
Alan Mishchenko committed
522 523 524 525
    // add the property
    {
        Aig_Obj_t * pObj;
        int Lits[1];
526
        pObj = Aig_ManCo( p->pAig, 0 );
Alan Mishchenko committed
527 528 529 530 531 532 533
        Lits[0] = toLitCond( p->pCnf->pVarNums[pObj->Id], 1 ); 
        Vec_IntPush( p->vLits, Lits[0] );
        Vec_IntPush( p->vClauses, Vec_IntSize(p->vLits) );
        Vec_IntPush( p->vCosts, CostMax );
        nCountConst++;
//        printf( "Added the target property to the set of clauses to be inductively checked.\n" );
    }
Alan Mishchenko committed
534
*/
Alan Mishchenko committed
535

Alan Mishchenko committed
536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583
    pSeq->nWordsPref = p->nSimWordsPref;
    Aig_ManForEachLoSeq( p->pAig, pObj1, i )
    {
        pSims1 = Fra_ObjSim( pSeq, pObj1->Id );
        if ( Fra_ClausSmlNodeIsConst( pSeq, pObj1 ) )
        {
            Vec_IntPush( p->vLits, toLitCond( p->pCnf->pVarNums[pObj1->Id], 1 ) );
            Vec_IntPush( p->vClauses, Vec_IntSize(p->vLits) );
            Vec_IntPush( p->vCosts, CostMax );
            nCountConst++;
            continue;
        }
        Aig_ManForEachLoSeq( p->pAig, pObj2, k )
        {
            pSims2 = Fra_ObjSim( pSeq, pObj2->Id );
            if ( Fra_ClausSmlNodesAreImp( pSeq, pObj1, pObj2 ) )
            {
                Vec_IntPush( p->vLits, toLitCond( p->pCnf->pVarNums[pObj1->Id], 1 ) );
                Vec_IntPush( p->vLits, toLitCond( p->pCnf->pVarNums[pObj2->Id], 0 ) );
                Vec_IntPush( p->vClauses, Vec_IntSize(p->vLits) );
                Vec_IntPush( p->vCosts, CostMax );
                nCountImps++;
                continue;
            }
            if ( Fra_ClausSmlNodesAreImp( pSeq, pObj2, pObj1 ) )
            {
                Vec_IntPush( p->vLits, toLitCond( p->pCnf->pVarNums[pObj2->Id], 1 ) );
                Vec_IntPush( p->vLits, toLitCond( p->pCnf->pVarNums[pObj1->Id], 0 ) );
                Vec_IntPush( p->vClauses, Vec_IntSize(p->vLits) );
                Vec_IntPush( p->vCosts, CostMax );
                nCountImps++;
                continue;
            }
            if ( Fra_ClausSmlNodesAreImpC( pSeq, pObj1, pObj2 ) )
            {
                Vec_IntPush( p->vLits, toLitCond( p->pCnf->pVarNums[pObj1->Id], 1 ) );
                Vec_IntPush( p->vLits, toLitCond( p->pCnf->pVarNums[pObj2->Id], 1 ) );
                Vec_IntPush( p->vClauses, Vec_IntSize(p->vLits) );
                Vec_IntPush( p->vCosts, CostMax );
                nCountImps++;
                continue;
            }
        }
        if ( nCountConst + nCountImps > p->nClausesMax / 2 )
            break;
    }
    pSeq->nWordsPref = 0;
    if ( p->fVerbose )
Alan Mishchenko committed
584 585 586
    printf( "Collected %d register constants and %d one-hotness implications.\n", nCountConst, nCountImps );
    p->nOneHots = nCountConst + nCountImps;
    p->nOneHotsProven = 0;
Alan Mishchenko committed
587 588 589 590 591
    return 0;
}

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

Alan Mishchenko committed
592 593 594 595 596 597 598 599 600
  Synopsis    [Processes the clauses.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
601
int Fra_ClausProcessClauses( Clu_Man_t * p, int fRefs )
Alan Mishchenko committed
602 603
{
    Aig_MmFixed_t * pMemCuts;
Alan Mishchenko committed
604
//    Aig_ManCut_t * pManCut;
Alan Mishchenko committed
605 606 607
    Fra_Sml_t * pComb, * pSeq;
    Aig_Obj_t * pObj;
    Dar_Cut_t * pCut;
608 609
    int Scores[16], uScores, i, k, j, nCuts = 0;
    clock_t clk;
Alan Mishchenko committed
610 611 612

    // simulate the AIG
clk = clock();
Alan Mishchenko committed
613 614
//    srand( 0xAABBAABB );
    Aig_ManRandom(1);
Alan Mishchenko committed
615
    pSeq = Fra_SmlSimulateSeq( p->pAig, 0, p->nPref + p->nSimFrames, p->nSimWords/p->nSimFrames, 1 );
Alan Mishchenko committed
616
    if ( p->fTarget && pSeq->fNonConstOut )
Alan Mishchenko committed
617 618 619 620 621
    {
        printf( "Property failed after sequential simulation!\n" );
        Fra_SmlStop( pSeq );
        return 0;
    }
Alan Mishchenko committed
622 623
if ( p->fVerbose )
{
Alan Mishchenko committed
624
ABC_PRT( "Sim-seq", clock() - clk );
Alan Mishchenko committed
625 626 627 628 629 630 631 632 633
}


clk = clock();
    if ( fRefs )
    {
    Fra_ClausCollectLatchClauses( p, pSeq );
if ( p->fVerbose )
{
Alan Mishchenko committed
634
ABC_PRT( "Lat-cla", clock() - clk );
Alan Mishchenko committed
635 636 637
}
    }

Alan Mishchenko committed
638 639 640

    // generate cuts for all nodes, assign cost, and find best cuts
clk = clock();
641
    pMemCuts = Dar_ManComputeCuts( p->pAig, 10, 0, 1 );
Alan Mishchenko committed
642
//    pManCut = Aig_ComputeCuts( p->pAig, 10, 4, 0, 1 );
Alan Mishchenko committed
643 644
if ( p->fVerbose )
{
Alan Mishchenko committed
645
ABC_PRT( "Cuts   ", clock() - clk );
Alan Mishchenko committed
646
}
Alan Mishchenko committed
647 648 649 650 651 652 653 654 655 656 657 658 659 660

    // collect sequential info for each cut
clk = clock();
    Aig_ManForEachNode( p->pAig, pObj, i )
        Dar_ObjForEachCut( pObj, pCut, k )
            if ( pCut->nLeaves > 1 )
            {
                pCut->uTruth = Fra_ClausProcessClausesCut( p, pSeq, pCut, Scores );
//                uScores = Fra_ClausProcessClausesCut2( p, pSeq, pCut, Scores );
//                if ( uScores != pCut->uTruth )
//                {
//                    int x = 0;
//                }
            }
Alan Mishchenko committed
661 662
if ( p->fVerbose )
{
Alan Mishchenko committed
663
ABC_PRT( "Infoseq", clock() - clk );
Alan Mishchenko committed
664
}
Alan Mishchenko committed
665 666 667 668
    Fra_SmlStop( pSeq );

    // perform combinational simulation
clk = clock();
Alan Mishchenko committed
669 670
//    srand( 0xAABBAABB );
    Aig_ManRandom(1);
671
    pComb = Fra_SmlSimulateComb( p->pAig, p->nSimWords + p->nSimWordsPref, 0 );
Alan Mishchenko committed
672 673
if ( p->fVerbose )
{
Alan Mishchenko committed
674
ABC_PRT( "Sim-cmb", clock() - clk );
Alan Mishchenko committed
675
}
Alan Mishchenko committed
676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695

    // collect combinational info for each cut
clk = clock();
    Aig_ManForEachNode( p->pAig, pObj, i )
        Dar_ObjForEachCut( pObj, pCut, k )
            if ( pCut->nLeaves > 1 )
            {
                nCuts++;
                uScores = Fra_ClausProcessClausesCut( p, pComb, pCut, Scores );
                uScores &= ~pCut->uTruth; pCut->uTruth = 0;
                if ( uScores == 0 )
                    continue;
                // write the clauses
                for ( j = 0; j < (1<<pCut->nLeaves); j++ )
                    if ( uScores & (1 << j) )
                        Fra_ClausRecordClause( p, pCut, j, Scores[j] );

            }
    Fra_SmlStop( pComb );
    Aig_MmFixedStop( pMemCuts, 0 );
Alan Mishchenko committed
696
//    Aig_ManCutStop( pManCut );
Alan Mishchenko committed
697 698
if ( p->fVerbose )
{
Alan Mishchenko committed
699
ABC_PRT( "Infocmb", clock() - clk );
Alan Mishchenko committed
700
}
Alan Mishchenko committed
701

Alan Mishchenko committed
702
    if ( p->fVerbose )
Alan Mishchenko committed
703 704
    printf( "Node = %5d. Non-triv cuts = %7d. Clauses = %6d. Clause per cut = %6.2f.\n", 
        Aig_ManNodeNum(p->pAig), nCuts, Vec_IntSize(p->vClauses), 1.0*Vec_IntSize(p->vClauses)/nCuts );
Alan Mishchenko committed
705 706 707 708 709

    if ( Vec_IntSize(p->vClauses) > p->nClausesMax )
        Fra_ClausSelectClauses( p );
    else
        p->nClauses = Vec_IntSize( p->vClauses );
Alan Mishchenko committed
710 711 712 713 714
    return 1;
}

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

Alan Mishchenko committed
715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730
  Synopsis    [Processes the clauses.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Fra_ClausProcessClauses2( Clu_Man_t * p, int fRefs )
{
//    Aig_MmFixed_t * pMemCuts;
    Aig_ManCut_t * pManCut;
    Fra_Sml_t * pComb, * pSeq;
    Aig_Obj_t * pObj;
    Aig_Cut_t * pCut;
731 732
    int i, k, j, nCuts = 0;
    clock_t clk;
Alan Mishchenko committed
733 734 735 736 737
    int ScoresSeq[1<<12], ScoresComb[1<<12];
    assert( p->nLutSize < 13 );

    // simulate the AIG
clk = clock();
Alan Mishchenko committed
738 739
//    srand( 0xAABBAABB );
    Aig_ManRandom(1);
Alan Mishchenko committed
740
    pSeq = Fra_SmlSimulateSeq( p->pAig, 0, p->nPref + p->nSimFrames, p->nSimWords/p->nSimFrames, 1  );
Alan Mishchenko committed
741
    if ( p->fTarget && pSeq->fNonConstOut )
Alan Mishchenko committed
742 743 744 745 746 747 748
    {
        printf( "Property failed after sequential simulation!\n" );
        Fra_SmlStop( pSeq );
        return 0;
    }
if ( p->fVerbose )
{
Alan Mishchenko committed
749
//ABC_PRT( "Sim-seq", clock() - clk );
Alan Mishchenko committed
750 751 752 753
}

    // perform combinational simulation
clk = clock();
Alan Mishchenko committed
754 755
//    srand( 0xAABBAABB );
    Aig_ManRandom(1);
756
    pComb = Fra_SmlSimulateComb( p->pAig, p->nSimWords + p->nSimWordsPref, 0 );
Alan Mishchenko committed
757 758
if ( p->fVerbose )
{
Alan Mishchenko committed
759
//ABC_PRT( "Sim-cmb", clock() - clk );
Alan Mishchenko committed
760 761 762 763 764 765 766 767 768
}


clk = clock();
    if ( fRefs )
    {
    Fra_ClausCollectLatchClauses( p, pSeq );
if ( p->fVerbose )
{
Alan Mishchenko committed
769
//ABC_PRT( "Lat-cla", clock() - clk );
Alan Mishchenko committed
770 771 772 773 774 775
}
    }


    // generate cuts for all nodes, assign cost, and find best cuts
clk = clock();
776
//    pMemCuts = Dar_ManComputeCuts( p->pAig, 10, 0, 1 );
Alan Mishchenko committed
777 778 779
    pManCut = Aig_ComputeCuts( p->pAig, p->nCutsMax, p->nLutSize, 0, p->fVerbose );
if ( p->fVerbose )
{
Alan Mishchenko committed
780
//ABC_PRT( "Cuts   ", clock() - clk );
Alan Mishchenko committed
781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803
}

    // collect combinational info for each cut
clk = clock();
    Aig_ManForEachNode( p->pAig, pObj, i )
    {
        if ( pObj->Level > (unsigned)p->nLevels )
            continue;
        Aig_ObjForEachCut( pManCut, pObj, pCut, k )
            if ( pCut->nFanins > 1 )
            {
                nCuts++;
                Fra_ClausProcessClausesCut3( p, pSeq, pCut, ScoresSeq );
                Fra_ClausProcessClausesCut3( p, pComb, pCut, ScoresComb );
                // write the clauses
                for ( j = 0; j < (1<<pCut->nFanins); j++ )
                    if ( ScoresComb[j] != 0 && ScoresSeq[j] == 0 )
                        Fra_ClausRecordClause2( p, pCut, j, ScoresComb[j] );

            }
    }
    Fra_SmlStop( pSeq );
    Fra_SmlStop( pComb );
Alan Mishchenko committed
804
    p->nCuts = nCuts;
Alan Mishchenko committed
805 806 807 808 809
//    Aig_MmFixedStop( pMemCuts, 0 );
    Aig_ManCutStop( pManCut );
    p->pAig->pManCuts = NULL;

    if ( p->fVerbose )
Alan Mishchenko committed
810 811
    {
    printf( "Node = %5d. Cuts = %7d. Clauses = %6d. Clause/cut = %6.2f.\n", 
Alan Mishchenko committed
812
        Aig_ManNodeNum(p->pAig), nCuts, Vec_IntSize(p->vClauses), 1.0*Vec_IntSize(p->vClauses)/nCuts );
Alan Mishchenko committed
813
    ABC_PRT( "Processing sim-info to find candidate clauses (unoptimized)", clock() - clk );
Alan Mishchenko committed
814
    }
Alan Mishchenko committed
815 816 817 818 819 820

    // filter out clauses that are contained in the already proven clauses
    assert( p->nClauses == 0 );
    p->nClauses = Vec_IntSize( p->vClauses );
    if ( Vec_IntSize( p->vClausesProven ) > 0 )
    {
Alan Mishchenko committed
821 822 823
        int RetValue, k, Beg;
        int End = -1; // Suppress "might be used uninitialized"
        int * pStart;
Alan Mishchenko committed
824 825
        // reset the solver
        if ( p->pSatMain )  sat_solver_delete( p->pSatMain );
826
        p->pSatMain = (sat_solver *)Cnf_DataWriteIntoSolver( p->pCnf, 1, 0 );
Alan Mishchenko committed
827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859
        if ( p->pSatMain == NULL )
        {
            printf( "Error: Main solver is unsat.\n" );
            return -1;
        }  

        // add the proven clauses
        Beg = 0;
        pStart = Vec_IntArray(p->vLitsProven);
        Vec_IntForEachEntry( p->vClausesProven, End, i )
        {
            assert( End - Beg <= p->nLutSize );
            // add the clause to all timeframes
            RetValue = sat_solver_addclause( p->pSatMain, pStart + Beg, pStart + End );
            if ( RetValue == 0 )
            {
                printf( "Error: Solver is UNSAT after adding assumption clauses.\n" );
                return -1;
            }
            Beg = End;
        }
        assert( End == Vec_IntSize(p->vLitsProven) );

        // check the clauses
        Beg = 0;
        pStart = Vec_IntArray(p->vLits);
        Vec_IntForEachEntry( p->vClauses, End, i )
        {
            assert( Vec_IntEntry( p->vCosts, i ) >= 0 );
            assert( End - Beg <= p->nLutSize );
            // check the clause
            for ( k = Beg; k < End; k++ )
                pStart[k] = lit_neg( pStart[k] );
Alan Mishchenko committed
860
            RetValue = sat_solver_solve( p->pSatMain, pStart + Beg, pStart + End, (ABC_INT64_T)p->nBTLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 );
Alan Mishchenko committed
861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887
            for ( k = Beg; k < End; k++ )
                pStart[k] = lit_neg( pStart[k] );
            // the clause holds
            if ( RetValue == l_False )
            {
                Vec_IntWriteEntry( p->vCosts, i, -1 );
                p->nClauses--;
            }
            Beg = End;
        }
        assert( End == Vec_IntSize(p->vLits) );
        if ( p->fVerbose )
        printf( "Already proved clauses filtered out %d candidate clauses (out of %d).\n", 
            Vec_IntSize(p->vClauses) - p->nClauses, Vec_IntSize(p->vClauses) );
    }

    p->fFiltering = 0;
    if ( p->nClauses > p->nClausesMax )
    {
        Fra_ClausSelectClauses( p );
        p->fFiltering = 1;
    }
    return 1;
}

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

Alan Mishchenko committed
888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906
  Synopsis    [Converts AIG into the SAT solver.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Fra_ClausBmcClauses( Clu_Man_t * p )
{
    int * pStart, nLitsTot, RetValue, Beg, End, Counter, i, k, f;
/*
    for ( i = 0; i < Vec_IntSize(p->vLits); i++ )
        printf( "%d ", p->vLits->pArray[i] );
    printf( "\n" );
*/
    // add the clauses
    Counter = 0;
Alan Mishchenko committed
907 908 909 910 911 912 913 914
    // skip through the prefix variables
    if ( p->nPref )
    {
        nLitsTot = p->nPref * 2 * p->pCnf->nVars;
        for ( i = 0; i < Vec_IntSize(p->vLits); i++ )
            p->vLits->pArray[i] += nLitsTot;
    }
    // go through the timeframes
Alan Mishchenko committed
915
    nLitsTot = 2 * p->pCnf->nVars;
Alan Mishchenko committed
916
    pStart = Vec_IntArray(p->vLits);
Alan Mishchenko committed
917 918 919 920 921 922 923 924 925 926 927
    for ( f = 0; f < p->nFrames; f++ )
    {
        Beg = 0;
        Vec_IntForEachEntry( p->vClauses, End, i )
        {
            if ( Vec_IntEntry( p->vCosts, i ) == -1 )
            {
                Beg = End;
                continue;
            }
            assert( Vec_IntEntry( p->vCosts, i ) > 0 );
Alan Mishchenko committed
928
            assert( End - Beg <= p->nLutSize );
Alan Mishchenko committed
929

Alan Mishchenko committed
930 931
            for ( k = Beg; k < End; k++ )
                pStart[k] = lit_neg( pStart[k] );
Alan Mishchenko committed
932
            RetValue = sat_solver_solve( p->pSatBmc, pStart + Beg, pStart + End, (ABC_INT64_T)p->nBTLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 );
Alan Mishchenko committed
933 934
            for ( k = Beg; k < End; k++ )
                pStart[k] = lit_neg( pStart[k] );
Alan Mishchenko committed
935

Alan Mishchenko committed
936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968
            if ( RetValue != l_False )
            {
                Beg = End;
                Vec_IntWriteEntry( p->vCosts, i, -1 );
                Counter++;
                continue;
            }
/*
            // add the clause
            RetValue = sat_solver_addclause( p->pSatBmc, pStart + Beg, pStart + End );
    //        assert( RetValue == 1 );
            if ( RetValue == 0 )
            {
                printf( "Error: Solver is UNSAT after adding BMC clauses.\n" );
                return -1;
            }
*/
            Beg = End;

            // simplify the solver
            if ( p->pSatBmc->qtail != p->pSatBmc->qhead )
            {
                RetValue = sat_solver_simplify(p->pSatBmc);
                assert( RetValue != 0 );
                assert( p->pSatBmc->qtail == p->pSatBmc->qhead );
            }
        }
        // increment literals
        for ( i = 0; i < Vec_IntSize(p->vLits); i++ )
            p->vLits->pArray[i] += nLitsTot;
    }

    // return clauses back to normal
Alan Mishchenko committed
969
    nLitsTot = (p->nPref + p->nFrames) * nLitsTot;
Alan Mishchenko committed
970 971 972 973 974 975 976 977 978 979 980 981
    for ( i = 0; i < Vec_IntSize(p->vLits); i++ )
        p->vLits->pArray[i] -= nLitsTot;
/*
    for ( i = 0; i < Vec_IntSize(p->vLits); i++ )
        printf( "%d ", p->vLits->pArray[i] );
    printf( "\n" );
*/
    return Counter;
}

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

Alan Mishchenko committed
982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037
  Synopsis    [Cleans simulation info.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Fra_ClausSimInfoClean( Clu_Man_t * p )
{
    assert( p->pCnf->nVars <= Vec_PtrSize(p->vCexes) );
    Vec_PtrCleanSimInfo( p->vCexes, 0, p->nCexesAlloc/32 );
    p->nCexes = 0;
}

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

  Synopsis    [Reallocs simulation info.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Fra_ClausSimInfoRealloc( Clu_Man_t * p )
{
    assert( p->nCexes == p->nCexesAlloc );
    Vec_PtrReallocSimInfo( p->vCexes );
    Vec_PtrCleanSimInfo( p->vCexes, p->nCexesAlloc/32, 2 * p->nCexesAlloc/32 );
    p->nCexesAlloc *= 2;
}

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

  Synopsis    [Records simulation info.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Fra_ClausSimInfoRecord( Clu_Man_t * p, int * pModel )
{
    int i;
    if ( p->nCexes == p->nCexesAlloc )
        Fra_ClausSimInfoRealloc( p );
    assert( p->nCexes < p->nCexesAlloc );
    for ( i = 0; i < p->pCnf->nVars; i++ )
    {
        if ( pModel[i] == l_True )
        {
1038 1039
            assert( Abc_InfoHasBit( (unsigned *)Vec_PtrEntry(p->vCexes, i), p->nCexes ) == 0 );
            Abc_InfoSetBit( (unsigned *)Vec_PtrEntry(p->vCexes, i), p->nCexes );
Alan Mishchenko committed
1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057
        }
    }
    p->nCexes++;
}

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

  Synopsis    [Uses the simulation info.]

  Description [Returns 1 if the simulation info disproved the clause.]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Fra_ClausSimInfoCheck( Clu_Man_t * p, int * pLits, int nLits )
{
Alan Mishchenko committed
1058
    unsigned * pSims[16], uWord;
Alan Mishchenko committed
1059 1060 1061 1062 1063
    int nWords, iVar, i, w;
    for ( i = 0; i < nLits; i++ )
    {
        iVar = lit_var(pLits[i]) - p->nFrames * p->pCnf->nVars;
        assert( iVar > 0 && iVar < p->pCnf->nVars );
1064
        pSims[i] = (unsigned *)Vec_PtrEntry( p->vCexes, iVar );
Alan Mishchenko committed
1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079
    }
    nWords = p->nCexes / 32;
    for ( w = 0; w < nWords; w++ )
    {
        uWord = ~(unsigned)0;
        for ( i = 0; i < nLits; i++ )
            uWord &= (lit_sign(pLits[i])? pSims[i][w] : ~pSims[i][w]);
        if ( uWord )
            return 1;
    }
    if ( p->nCexes % 32 )
    {
        uWord = ~(unsigned)0;
        for ( i = 0; i < nLits; i++ )
            uWord &= (lit_sign(pLits[i])? pSims[i][w] : ~pSims[i][w]);
1080
        if ( uWord & Abc_InfoMask( p->nCexes % 32 ) )
Alan Mishchenko committed
1081 1082 1083 1084 1085 1086 1087 1088
            return 1;
    }
    return 0;
}


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

Alan Mishchenko committed
1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099
  Synopsis    [Converts AIG into the SAT solver.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Fra_ClausInductiveClauses( Clu_Man_t * p )
{
Alan Mishchenko committed
1100
//    Aig_Obj_t * pObjLi, * pObjLo;
Alan Mishchenko committed
1101 1102
    int * pStart, nLitsTot, RetValue, Beg, End, Counter, i, k, f, fFlag;//, Lits[2];
    p->fFail = 0;
Alan Mishchenko committed
1103 1104 1105

    // reset the solver
    if ( p->pSatMain )  sat_solver_delete( p->pSatMain );
1106
    p->pSatMain = (sat_solver *)Cnf_DataWriteIntoSolver( p->pCnf, p->nFrames+1, 0 );
Alan Mishchenko committed
1107 1108 1109 1110
    if ( p->pSatMain == NULL )
    {
        printf( "Error: Main solver is unsat.\n" );
        return -1;
Alan Mishchenko committed
1111 1112 1113
    }  
    Fra_ClausSimInfoClean( p );

Alan Mishchenko committed
1114 1115 1116 1117 1118 1119 1120
/*
    // check if the property holds
    if ( Fra_ClausRunSat0( p ) )
        printf( "Property holds without strengthening.\n" );
    else
        printf( "Property does not hold without strengthening.\n" );
*/
Alan Mishchenko committed
1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137
/*
    // add constant registers
    Aig_ManForEachLiLoSeq( p->pAig, pObjLi, pObjLo, i )  
        if ( Aig_ObjFanin0(pObjLi) == Aig_ManConst1(p->pAig) )
        {
            for ( k = 0; k < p->nFrames; k++ )
            {
                Lits[0] = k * 2 * p->pCnf->nVars + toLitCond( p->pCnf->pVarNums[pObjLo->Id], Aig_ObjFaninC0(pObjLi) ); 
                RetValue = sat_solver_addclause( p->pSatMain, Lits, Lits + 1 );
                if ( RetValue == 0 )
                {
                    printf( "Error: Solver is UNSAT after adding constant-register clauses.\n" );
                    return -1;
                }
            }
        }
*/
Alan Mishchenko committed
1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185


    // add the proven clauses
    nLitsTot = 2 * p->pCnf->nVars;
    pStart = Vec_IntArray(p->vLitsProven);
    for ( f = 0; f < p->nFrames; f++ )
    {
        Beg = 0;
        Vec_IntForEachEntry( p->vClausesProven, End, i )
        {
            assert( End - Beg <= p->nLutSize );
            // add the clause to all timeframes
            RetValue = sat_solver_addclause( p->pSatMain, pStart + Beg, pStart + End );
            if ( RetValue == 0 )
            {
                printf( "Error: Solver is UNSAT after adding assumption clauses.\n" );
                return -1;
            }
            Beg = End;
        }
        // increment literals
        for ( i = 0; i < Vec_IntSize(p->vLitsProven); i++ )
            p->vLitsProven->pArray[i] += nLitsTot;
    }
    // return clauses back to normal
    nLitsTot = (p->nFrames) * nLitsTot;
    for ( i = 0; i < Vec_IntSize(p->vLitsProven); i++ )
        p->vLitsProven->pArray[i] -= nLitsTot;

/*
    // add the proven clauses
    nLitsTot = 2 * p->pCnf->nVars;
    pStart = Vec_IntArray(p->vLitsProven);
    Beg = 0;
    Vec_IntForEachEntry( p->vClausesProven, End, i )
    {
        assert( End - Beg <= p->nLutSize );
        // add the clause to all timeframes
        RetValue = sat_solver_addclause( p->pSatMain, pStart + Beg, pStart + End );
        if ( RetValue == 0 )
        {
            printf( "Error: Solver is UNSAT after adding assumption clauses.\n" );
            return -1;
        }
        Beg = End;
    }
*/
    
Alan Mishchenko committed
1186 1187
    // add the clauses
    nLitsTot = 2 * p->pCnf->nVars;
Alan Mishchenko committed
1188
    pStart = Vec_IntArray(p->vLits);
Alan Mishchenko committed
1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199
    for ( f = 0; f < p->nFrames; f++ )
    {
        Beg = 0;
        Vec_IntForEachEntry( p->vClauses, End, i )
        {
            if ( Vec_IntEntry( p->vCosts, i ) == -1 )
            {
                Beg = End;
                continue;
            }
            assert( Vec_IntEntry( p->vCosts, i ) > 0 );
Alan Mishchenko committed
1200
            assert( End - Beg <= p->nLutSize );
Alan Mishchenko committed
1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223
            // add the clause to all timeframes
            RetValue = sat_solver_addclause( p->pSatMain, pStart + Beg, pStart + End );
            if ( RetValue == 0 )
            {
                printf( "Error: Solver is UNSAT after adding assumption clauses.\n" );
                return -1;
            }
            Beg = End;
        }
        // increment literals
        for ( i = 0; i < Vec_IntSize(p->vLits); i++ )
            p->vLits->pArray[i] += nLitsTot;
    }

    // simplify the solver
    if ( p->pSatMain->qtail != p->pSatMain->qhead )
    {
        RetValue = sat_solver_simplify(p->pSatMain);
        assert( RetValue != 0 );
        assert( p->pSatMain->qtail == p->pSatMain->qhead );
    }
  
    // check if the property holds
Alan Mishchenko committed
1224
    if ( p->fTarget )
Alan Mishchenko committed
1225
    {
Alan Mishchenko committed
1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237
        if ( Fra_ClausRunSat0( p ) )
        {
            if ( p->fVerbose )
            printf( " Property holds.  " );
        }
        else
        {
            if ( p->fVerbose )
            printf( " Property fails.  " );
    //        return -2;
            p->fFail = 1;
        }
Alan Mishchenko committed
1238 1239 1240 1241 1242 1243 1244 1245 1246
    }

/*
    // add the property for the first K frames
    for ( i = 0; i < p->nFrames; i++ )
    {
        Aig_Obj_t * pObj;
        int Lits[2];
        // set the output literals
1247
        pObj = Aig_ManCo(p->pAig, 0);
Alan Mishchenko committed
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
        Lits[0] = i * nLitsTot + toLitCond( p->pCnf->pVarNums[pObj->Id], 1 ); 
        // add the clause
        RetValue = sat_solver_addclause( p->pSatMain, Lits, Lits + 1 );
//        assert( RetValue == 1 );
        if ( RetValue == 0 )
        {
            printf( "Error: Solver is UNSAT after adding property for the first K frames.\n" );
            return -1;
        }
    }
*/

    // simplify the solver
    if ( p->pSatMain->qtail != p->pSatMain->qhead )
    {
        RetValue = sat_solver_simplify(p->pSatMain);
        assert( RetValue != 0 );
        assert( p->pSatMain->qtail == p->pSatMain->qhead );
    }


    // check the clause in the last timeframe
    Beg = 0;
    Counter = 0;
    Vec_IntForEachEntry( p->vClauses, End, i )
    {
        if ( Vec_IntEntry( p->vCosts, i ) == -1 )
        {
            Beg = End;
            continue;
        }
        assert( Vec_IntEntry( p->vCosts, i ) > 0 );
Alan Mishchenko committed
1280
        assert( End - Beg <= p->nLutSize );
Alan Mishchenko committed
1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296

        if ( Fra_ClausSimInfoCheck(p, pStart + Beg, End - Beg) )
        {
            fFlag = 1;
//            printf( "s-" );

            Beg = End;
            Vec_IntWriteEntry( p->vCosts, i, -1 );
            Counter++;
            continue;
        }
        else
        {
            fFlag = 0;
//            printf( "s?" );
        }
Alan Mishchenko committed
1297 1298 1299

        for ( k = Beg; k < End; k++ )
            pStart[k] = lit_neg( pStart[k] );
Alan Mishchenko committed
1300
        RetValue = sat_solver_solve( p->pSatMain, pStart + Beg, pStart + End, (ABC_INT64_T)p->nBTLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 );
Alan Mishchenko committed
1301 1302 1303 1304 1305 1306
        for ( k = Beg; k < End; k++ )
            pStart[k] = lit_neg( pStart[k] );

        // the problem is not solved
        if ( RetValue != l_False )
        {
Alan Mishchenko committed
1307
//            printf( "S- " );
1308 1309
//            Fra_ClausSimInfoRecord( p, (int*)p->pSatMain->model.ptr + p->nFrames * p->pCnf->nVars );
            Fra_ClausSimInfoRecord( p, (int*)p->pSatMain->model + p->nFrames * p->pCnf->nVars );
Alan Mishchenko committed
1310 1311 1312
//            RetValue = Fra_ClausSimInfoCheck(p, pStart + Beg, End - Beg);
//            assert( RetValue );

Alan Mishchenko committed
1313 1314 1315 1316 1317
            Beg = End;
            Vec_IntWriteEntry( p->vCosts, i, -1 );
            Counter++;
            continue;
        }
Alan Mishchenko committed
1318 1319 1320 1321
//        printf( "S+ " );
//        assert( !fFlag );

/*
Alan Mishchenko committed
1322 1323 1324 1325 1326
        // add the clause
        RetValue = sat_solver_addclause( p->pSatMain, pStart + Beg, pStart + End );
//        assert( RetValue == 1 );
        if ( RetValue == 0 )
        {
Alan Mishchenko committed
1327
            printf( "Error: Solver is UNSAT after adding proved clauses.\n" );
Alan Mishchenko committed
1328 1329
            return -1;
        }
Alan Mishchenko committed
1330
*/
Alan Mishchenko committed
1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346
        Beg = End;

        // simplify the solver
        if ( p->pSatMain->qtail != p->pSatMain->qhead )
        {
            RetValue = sat_solver_simplify(p->pSatMain);
            assert( RetValue != 0 );
            assert( p->pSatMain->qtail == p->pSatMain->qhead );
        }
    }

    // return clauses back to normal
    nLitsTot = p->nFrames * nLitsTot;
    for ( i = 0; i < Vec_IntSize(p->vLits); i++ )
        p->vLits->pArray[i] -= nLitsTot;

Alan Mishchenko committed
1347 1348
//    if ( fFail )
//        return -2;
Alan Mishchenko committed
1349 1350 1351 1352
    return Counter;
}


Alan Mishchenko committed
1353

Alan Mishchenko committed
1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364
/**Function*************************************************************

  Synopsis    [Converts AIG into the SAT solver.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
1365
Clu_Man_t * Fra_ClausAlloc( Aig_Man_t * pAig, int nFrames, int nPref, int nClausesMax, int nLutSize, int nLevels, int nCutsMax, int nBatches, int fStepUp, int fTarget, int fVerbose, int fVeryVerbose )
Alan Mishchenko committed
1366 1367
{
    Clu_Man_t * p;
Alan Mishchenko committed
1368
    p = ABC_ALLOC( Clu_Man_t, 1 );
Alan Mishchenko committed
1369
    memset( p, 0, sizeof(Clu_Man_t) );
Alan Mishchenko committed
1370 1371 1372 1373
    p->pAig          = pAig;
    p->nFrames       = nFrames;
    p->nPref         = nPref;
    p->nClausesMax   = nClausesMax;
Alan Mishchenko committed
1374 1375 1376 1377 1378
    p->nLutSize      = nLutSize;
    p->nLevels       = nLevels;
    p->nCutsMax      = nCutsMax;
    p->nBatches      = nBatches;
    p->fStepUp       = fStepUp;
Alan Mishchenko committed
1379
    p->fTarget       = fTarget;
Alan Mishchenko committed
1380 1381 1382 1383 1384 1385 1386 1387 1388 1389
    p->fVerbose      = fVerbose;
    p->fVeryVerbose  = fVeryVerbose;
    p->nSimWords     = 512;//1024;//64;
    p->nSimFrames    = 32;//8;//32;
    p->nSimWordsPref = p->nPref*p->nSimWords/p->nSimFrames;

    p->vLits         = Vec_IntAlloc( 1<<14 );
    p->vClauses      = Vec_IntAlloc( 1<<12 );
    p->vCosts        = Vec_IntAlloc( 1<<12 );

Alan Mishchenko committed
1390 1391 1392
    p->vLitsProven   = Vec_IntAlloc( 1<<14 );
    p->vClausesProven= Vec_IntAlloc( 1<<12 );

Alan Mishchenko committed
1393 1394
    p->nCexesAlloc   = 1024;
    p->vCexes        = Vec_PtrAllocSimInfo( Aig_ManObjNumMax(p->pAig)+1, p->nCexesAlloc/32 );
Alan Mishchenko committed
1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414
    Vec_PtrCleanSimInfo( p->vCexes, 0, p->nCexesAlloc/32 );
    return p;
}

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

  Synopsis    [Converts AIG into the SAT solver.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Fra_ClausFree( Clu_Man_t * p )
{
    if ( p->vCexes )    Vec_PtrFree( p->vCexes );
    if ( p->vLits )     Vec_IntFree( p->vLits );
    if ( p->vClauses )  Vec_IntFree( p->vClauses );
Alan Mishchenko committed
1415 1416
    if ( p->vLitsProven )     Vec_IntFree( p->vLitsProven );
    if ( p->vClausesProven )  Vec_IntFree( p->vClausesProven );
Alan Mishchenko committed
1417 1418 1419 1420
    if ( p->vCosts )    Vec_IntFree( p->vCosts );
    if ( p->pCnf )      Cnf_DataFree( p->pCnf );
    if ( p->pSatMain )  sat_solver_delete( p->pSatMain );
    if ( p->pSatBmc )   sat_solver_delete( p->pSatBmc );
Alan Mishchenko committed
1421
    ABC_FREE( p );
Alan Mishchenko committed
1422 1423
}

Alan Mishchenko committed
1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456

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

  Synopsis    [Converts AIG into the SAT solver.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Fra_ClausAddToStorage( Clu_Man_t * p )
{
    int * pStart; 
    int Beg, End, Counter, i, k;
    Beg = 0;
    Counter = 0;
    pStart = Vec_IntArray( p->vLits );
    Vec_IntForEachEntry( p->vClauses, End, i )
    {
        if ( Vec_IntEntry( p->vCosts, i ) == -1 )
        {
            Beg = End;
            continue;
        }
        assert( Vec_IntEntry( p->vCosts, i ) > 0 );
        assert( End - Beg <= p->nLutSize );
        for ( k = Beg; k < End; k++ )
            Vec_IntPush( p->vLitsProven, pStart[k] );
        Vec_IntPush( p->vClausesProven, Vec_IntSize(p->vLitsProven) );
        Beg = End;
        Counter++;
Alan Mishchenko committed
1457 1458 1459

        if ( i < p->nOneHots )
            p->nOneHotsProven++;
Alan Mishchenko committed
1460 1461
    }
    if ( p->fVerbose )
Alan Mishchenko committed
1462
    printf( "Added to storage %d proved clauses (including %d one-hot clauses)\n", Counter, p->nOneHotsProven );
Alan Mishchenko committed
1463 1464 1465 1466 1467 1468 1469 1470 1471

    Vec_IntClear( p->vClauses );
    Vec_IntClear( p->vLits );
    Vec_IntClear( p->vCosts );
    p->nClauses = 0;

    p->fNothingNew = (int)(Counter == 0);
}

Alan Mishchenko committed
1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482
/**Function*************************************************************

  Synopsis    [Converts AIG into the SAT solver.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510
void Fra_ClausPrintIndClauses( Clu_Man_t * p )
{
    int Counters[9] = {0};
    int * pStart; 
    int Beg, End, i;
    Beg = 0;
    pStart = Vec_IntArray( p->vLitsProven );
    Vec_IntForEachEntry( p->vClausesProven, End, i )
    {
        if ( End - Beg >= 8 )
            Counters[8]++;
        else
            Counters[End - Beg]++;
//printf( "%d ", End-Beg );
        Beg = End;
    }
    printf( "SUMMARY: Total proved clauses = %d. ", Vec_IntSize(p->vClausesProven) );
    printf( "Clause per lit: " );
    for ( i = 0; i < 8; i++ )
        if ( Counters[i] )
            printf( "%d=%d ", i, Counters[i] );
    if ( Counters[8] )
            printf( ">7=%d ", Counters[8] );
    printf( "\n" );
}

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

Alan Mishchenko committed
1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524
  Synopsis    [Writes the clauses into an AIGER file.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Aig_Obj_t * Fra_ClausGetLiteral( Clu_Man_t * p, int * pVar2Id, int Lit )
{
    Aig_Obj_t * pLiteral;
    int NodeId = pVar2Id[ lit_var(Lit) ];
    assert( NodeId >= 0 );
1525
    pLiteral = (Aig_Obj_t *)Aig_ManObj( p->pAig, NodeId )->pData;
Alan Mishchenko committed
1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540
    return Aig_NotCond( pLiteral, lit_sign(Lit) );
}

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

  Synopsis    [Writes the clauses into an AIGER file.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Fra_ClausWriteIndClauses( Clu_Man_t * p )
Alan Mishchenko committed
1541
{ 
Alan Mishchenko committed
1542 1543 1544
    extern void Ioa_WriteAiger( Aig_Man_t * pMan, char * pFileName, int fWriteSymbols, int fCompact );
    Aig_Man_t * pNew;
    Aig_Obj_t * pClause, * pLiteral;
Alan Mishchenko committed
1545
    char * pName;
Alan Mishchenko committed
1546 1547 1548
    int * pStart, * pVar2Id; 
    int Beg, End, i, k;
    // create mapping from SAT vars to node IDs
Alan Mishchenko committed
1549
    pVar2Id = ABC_ALLOC( int, p->pCnf->nVars );
Alan Mishchenko committed
1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569
    memset( pVar2Id, 0xFF, sizeof(int) * p->pCnf->nVars );
    for ( i = 0; i < Aig_ManObjNumMax(p->pAig); i++ )
        if ( p->pCnf->pVarNums[i] >= 0 )
        {
            assert( p->pCnf->pVarNums[i] < p->pCnf->nVars );
            pVar2Id[ p->pCnf->pVarNums[i] ] = i;
        }
    // start the manager
    pNew = Aig_ManDupWithoutPos( p->pAig );
    // add the clauses
    Beg = 0;
    pStart = Vec_IntArray( p->vLitsProven );
    Vec_IntForEachEntry( p->vClausesProven, End, i )
    {
        pClause = Fra_ClausGetLiteral( p, pVar2Id, pStart[Beg] );
        for ( k = Beg + 1; k < End; k++ )
        {
            pLiteral = Fra_ClausGetLiteral( p, pVar2Id, pStart[k] );
            pClause = Aig_Or( pNew, pClause, pLiteral );
        }
1570
        Aig_ObjCreateCo( pNew, pClause );
Alan Mishchenko committed
1571 1572
        Beg = End;
    }
Alan Mishchenko committed
1573
    ABC_FREE( pVar2Id );
Alan Mishchenko committed
1574
    Aig_ManCleanup( pNew );
Alan Mishchenko committed
1575 1576 1577
    pName = Ioa_FileNameGenericAppend( p->pAig->pName, "_care.aig" );
    printf( "Care one-hotness clauses will be written into file \"%s\".\n", pName );
    Ioa_WriteAiger( pNew, pName, 0, 1 );
Alan Mishchenko committed
1578 1579 1580 1581 1582
    Aig_ManStop( pNew );
}

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

Alan Mishchenko committed
1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626
  Synopsis    [Checks if the clause holds using the given simulation info.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Fra_ClausEstimateCoverageOne( Fra_Sml_t * pSim, int * pLits, int nLits, int * pVar2Id, unsigned * pResult )
{
    unsigned * pSims[16];
    int iVar, i, w;
    for ( i = 0; i < nLits; i++ )
    {
        iVar = lit_var(pLits[i]);
        pSims[i] = Fra_ObjSim( pSim, pVar2Id[iVar] );
    }
    for ( w = 0; w < pSim->nWordsTotal; w++ )
    {
        pResult[w] = ~(unsigned)0;
        for ( i = 0; i < nLits; i++ )
            pResult[w] &= (lit_sign(pLits[i])? pSims[i][w] : ~pSims[i][w]);
    }
}

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

  Synopsis    [Estimates the coverage of state space by clauses.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Fra_ClausEstimateCoverage( Clu_Man_t * p )
{
    int nCombSimWords = (1<<11);
    Fra_Sml_t * pComb;
    unsigned * pResultTot, * pResultOne;
    int nCovered, Beg, End, i, w;
    int * pStart, * pVar2Id; 
1627
    clock_t clk = clock();
Alan Mishchenko committed
1628
    // simulate the circuit with nCombSimWords * 32 = 64K patterns
Alan Mishchenko committed
1629 1630
//    srand( 0xAABBAABB );
    Aig_ManRandom(1);
1631
    pComb = Fra_SmlSimulateComb( p->pAig, nCombSimWords, 0 );
Alan Mishchenko committed
1632
    // create mapping from SAT vars to node IDs
Alan Mishchenko committed
1633
    pVar2Id = ABC_ALLOC( int, p->pCnf->nVars );
Alan Mishchenko committed
1634 1635 1636 1637 1638 1639 1640 1641
    memset( pVar2Id, 0, sizeof(int) * p->pCnf->nVars );
    for ( i = 0; i < Aig_ManObjNumMax(p->pAig); i++ )
        if ( p->pCnf->pVarNums[i] >= 0 )
        {
            assert( p->pCnf->pVarNums[i] < p->pCnf->nVars );
            pVar2Id[ p->pCnf->pVarNums[i] ] = i;
        }
    // get storage for one assignment and all assignments
1642 1643 1644
    assert( Aig_ManCoNum(p->pAig) > 2 );
    pResultOne = Fra_ObjSim( pComb, Aig_ManCo(p->pAig, 0)->Id );
    pResultTot = Fra_ObjSim( pComb, Aig_ManCo(p->pAig, 1)->Id );
Alan Mishchenko committed
1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662
    // start the OR of don't-cares
    for ( w = 0; w < nCombSimWords; w++ )
        pResultTot[w] = 0;
    // check clauses
    Beg = 0;
    pStart = Vec_IntArray( p->vLitsProven );
    Vec_IntForEachEntry( p->vClausesProven, End, i )
    {
        Fra_ClausEstimateCoverageOne( pComb, pStart + Beg, End-Beg, pVar2Id, pResultOne );
        Beg = End;
        for ( w = 0; w < nCombSimWords; w++ )
            pResultTot[w] |= pResultOne[w];
    }
    // count the total number of patterns contained in the don't-care
    nCovered = 0;
    for ( w = 0; w < nCombSimWords; w++ )
        nCovered += Aig_WordCountOnes( pResultTot[w] );
    Fra_SmlStop( pComb );
Alan Mishchenko committed
1663
    ABC_FREE( pVar2Id );
Alan Mishchenko committed
1664 1665 1666
    // print the result
    printf( "Care states ratio = %f. ", 1.0 * (nCombSimWords * 32 - nCovered) / (nCombSimWords * 32) );
    printf( "(%d out of %d patterns)  ", nCombSimWords * 32 - nCovered, nCombSimWords * 32 );
Alan Mishchenko committed
1667
    ABC_PRT( "Time", clock() - clk );
Alan Mishchenko committed
1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682
}


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

  Synopsis    [Converts AIG into the SAT solver.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Fra_Claus( Aig_Man_t * pAig, int nFrames, int nPref, int nClausesMax, int nLutSize, int nLevels, int nCutsMax, int nBatches, int fStepUp, int fBmc, int fRefs, int fTarget, int fVerbose, int fVeryVerbose )
Alan Mishchenko committed
1683 1684
{
    Clu_Man_t * p;
1685
    clock_t clk, clkTotal = clock(), clkInd;
Alan Mishchenko committed
1686
    int b, Iter, Counter, nPrefOld;
Alan Mishchenko committed
1687
    int nClausesBeg = 0;
Alan Mishchenko committed
1688 1689

    // create the manager
Alan Mishchenko committed
1690 1691 1692 1693 1694
    p = Fra_ClausAlloc( pAig, nFrames, nPref, nClausesMax, nLutSize, nLevels, nCutsMax, nBatches, fStepUp, fTarget, fVerbose, fVeryVerbose );
if ( p->fVerbose )
{
    printf( "PARAMETERS: Frames = %d. Pref = %d. Clauses max = %d. Cut size = %d.\n", nFrames, nPref, nClausesMax, nLutSize );
    printf( "Level max = %d. Cuts max = %d. Batches = %d. Increment cut size = %s.\n", nLevels, nCutsMax, nBatches, fStepUp? "yes":"no" );
Alan Mishchenko committed
1695
//ABC_PRT( "Sim-seq", clock() - clk );
Alan Mishchenko committed
1696 1697
}

1698
    assert( !p->fTarget || Aig_ManCoNum(pAig) - Aig_ManRegNum(pAig) == 1 );
Alan Mishchenko committed
1699 1700 1701

clk = clock();
    // derive CNF
Alan Mishchenko committed
1702 1703
//    if ( p->fTarget )
//        p->pAig->nRegs++;
1704
    p->pCnf = Cnf_DeriveSimple( p->pAig, Aig_ManCoNum(p->pAig) );
Alan Mishchenko committed
1705 1706
//    if ( p->fTarget )
//        p->pAig->nRegs--;
Alan Mishchenko committed
1707 1708
if ( fVerbose )
{
Alan Mishchenko committed
1709
//ABC_PRT( "CNF    ", clock() - clk );
Alan Mishchenko committed
1710
}
Alan Mishchenko committed
1711 1712 1713

    // check BMC
clk = clock();
1714
    p->pSatBmc = (sat_solver *)Cnf_DataWriteIntoSolver( p->pCnf, p->nPref + p->nFrames, 1 );
Alan Mishchenko committed
1715 1716 1717 1718 1719
    if ( p->pSatBmc == NULL )
    {
        printf( "Error: BMC solver is unsat.\n" );
        Fra_ClausFree( p );
        return 1;
Alan Mishchenko committed
1720
    } 
Alan Mishchenko committed
1721
    if ( p->fTarget && !Fra_ClausRunBmc( p ) )
Alan Mishchenko committed
1722
    {
Alan Mishchenko committed
1723
        printf( "Problem fails the base case after %d frame expansion.\n", p->nPref + p->nFrames );
Alan Mishchenko committed
1724 1725 1726
        Fra_ClausFree( p );
        return 1;
    }
Alan Mishchenko committed
1727 1728
if ( fVerbose )
{
Alan Mishchenko committed
1729
//ABC_PRT( "SAT-bmc", clock() - clk );
Alan Mishchenko committed
1730
}
Alan Mishchenko committed
1731 1732 1733

    // start the SAT solver
clk = clock();
1734
    p->pSatMain = (sat_solver *)Cnf_DataWriteIntoSolver( p->pCnf, p->nFrames+1, 0 );
Alan Mishchenko committed
1735 1736 1737 1738 1739 1740
    if ( p->pSatMain == NULL )
    {
        printf( "Error: Main solver is unsat.\n" );
        Fra_ClausFree( p );
        return 1;
    } 
Alan Mishchenko committed
1741 1742 1743


    for ( b = 0; b < p->nBatches; b++ )
Alan Mishchenko committed
1744
    {
Alan Mishchenko committed
1745 1746
//        if ( fVerbose )
        printf( "*** BATCH %d:  ", b+1 );
Alan Mishchenko committed
1747
        if ( b && p->nLutSize < 12 && (!p->fFiltering || p->fNothingNew || p->fStepUp) )
Alan Mishchenko committed
1748 1749 1750 1751
            p->nLutSize++;
        printf( "Using %d-cuts.\n", p->nLutSize );

        // try solving without additional clauses
Alan Mishchenko committed
1752
        if ( p->fTarget && Fra_ClausRunSat( p ) )
Alan Mishchenko committed
1753 1754 1755 1756 1757 1758 1759
        {
            printf( "Problem is inductive without strengthening.\n" );
            Fra_ClausFree( p );
            return 1;
        }
        if ( fVerbose )
        {
Alan Mishchenko committed
1760
//        ABC_PRT( "SAT-ind", clock() - clk );
Alan Mishchenko committed
1761
        }
Alan Mishchenko committed
1762
 
Alan Mishchenko committed
1763 1764 1765 1766 1767 1768 1769
        // collect the candidate inductive clauses using 4-cuts
        clk = clock();
        nPrefOld = p->nPref; p->nPref = 0; p->nSimWordsPref = 0;
    //    Fra_ClausProcessClauses( p, fRefs );
        Fra_ClausProcessClauses2( p, fRefs );
        p->nPref = nPrefOld;
        p->nSimWordsPref = p->nPref*p->nSimWords/p->nSimFrames;
Alan Mishchenko committed
1770
        nClausesBeg = p->nClauses;
Alan Mishchenko committed
1771

Alan Mishchenko committed
1772
    //ABC_PRT( "Clauses", clock() - clk );
Alan Mishchenko committed
1773 1774


Alan Mishchenko committed
1775 1776 1777 1778 1779 1780 1781 1782
        // check clauses using BMC
        if ( fBmc ) 
        {
            clk = clock();
            Counter = Fra_ClausBmcClauses( p );
            p->nClauses -= Counter;
            if ( fVerbose )
            {
Alan Mishchenko committed
1783
                printf( "BMC disproved %d clauses.  ", Counter );
Alan Mishchenko committed
1784
                ABC_PRT( "Time", clock() - clk );
Alan Mishchenko committed
1785 1786
            }
        }
Alan Mishchenko committed
1787 1788


Alan Mishchenko committed
1789
        // prove clauses inductively
Alan Mishchenko committed
1790
        clkInd = clk = clock();
Alan Mishchenko committed
1791 1792
        Counter = 1;
        for ( Iter = 0; Counter > 0; Iter++ )
Alan Mishchenko committed
1793
        {
Alan Mishchenko committed
1794 1795 1796 1797 1798 1799 1800 1801 1802
            if ( fVerbose )
            printf( "Iter %3d : Begin = %5d. ", Iter, p->nClauses );
            Counter = Fra_ClausInductiveClauses( p );
            if ( Counter > 0 )
               p->nClauses -= Counter;
            if ( fVerbose )
            {
            printf( "End = %5d. Exs = %5d.  ", p->nClauses, p->nCexes );
    //        printf( "\n" );
Alan Mishchenko committed
1803
            ABC_PRT( "Time", clock() - clk );
Alan Mishchenko committed
1804 1805
            }
            clk = clock();
Alan Mishchenko committed
1806
        }
Alan Mishchenko committed
1807 1808 1809
        // add proved clauses to storage
        Fra_ClausAddToStorage( p );
        // report the results
Alan Mishchenko committed
1810 1811 1812 1813 1814 1815 1816 1817
        if ( p->fTarget )
        {
            if ( Counter == -1 )
                printf( "Fra_Claus(): Internal error.  " );
            else if ( p->fFail )
                printf( "Property FAILS during refinement.  " );
            else
                printf( "Property HOLDS inductively after strengthening.  " );
Alan Mishchenko committed
1818
            ABC_PRT( "Time  ", clock() - clkTotal );
Alan Mishchenko committed
1819 1820 1821
            if ( !p->fFail )
                break;
        }
Alan Mishchenko committed
1822
        else
Alan Mishchenko committed
1823 1824
        {
            printf( "Finished proving inductive clauses. " );
Alan Mishchenko committed
1825
            ABC_PRT( "Time  ", clock() - clkTotal );
Alan Mishchenko committed
1826
        }
Alan Mishchenko committed
1827 1828
    }

Alan Mishchenko committed
1829 1830 1831 1832 1833 1834
    // verify the computed interpolant
    Fra_InvariantVerify( pAig, nFrames, p->vClausesProven, p->vLitsProven );
//    printf( "THIS COMMAND IS KNOWN TO HAVE A BUG!\n" );

//    if ( !p->fTarget && p->fVerbose )
    if ( p->fVerbose )
Alan Mishchenko committed
1835 1836 1837 1838
    {
        Fra_ClausPrintIndClauses( p );
        Fra_ClausEstimateCoverage( p );
    }
Alan Mishchenko committed
1839 1840 1841 1842 1843

    if ( !p->fTarget )
    {
        Fra_ClausWriteIndClauses( p );
    }
Alan Mishchenko committed
1844 1845 1846 1847 1848 1849 1850
/*
    // print the statistic into a file
    {
        FILE * pTable;
        assert( p->nBatches == 1 );
        pTable = fopen( "stats.txt", "a+" );
        fprintf( pTable, "%s ",  pAig->pName );
1851 1852
        fprintf( pTable, "%d ",  Aig_ManCiNum(pAig)-Aig_ManRegNum(pAig) );
        fprintf( pTable, "%d ",  Aig_ManCoNum(pAig)-Aig_ManRegNum(pAig) );
Alan Mishchenko committed
1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865
        fprintf( pTable, "%d ",  Aig_ManRegNum(pAig) );
        fprintf( pTable, "%d ",  Aig_ManNodeNum(pAig) );
        fprintf( pTable, "%d ",  p->nCuts );
        fprintf( pTable, "%d ",  nClausesBeg );
        fprintf( pTable, "%d ",  p->nClauses );
        fprintf( pTable, "%d ",  Iter );
        fprintf( pTable, "%.2f ", (float)(clkInd-clkTotal)/(float)(CLOCKS_PER_SEC) );
        fprintf( pTable, "%.2f ", (float)(clock()-clkInd)/(float)(CLOCKS_PER_SEC) );
        fprintf( pTable, "%.2f ", (float)(clock()-clkTotal)/(float)(CLOCKS_PER_SEC) );
        fprintf( pTable, "\n" );
        fclose( pTable );
    }
*/
Alan Mishchenko committed
1866 1867 1868 1869 1870 1871 1872 1873 1874 1875
    // clean the manager
    Fra_ClausFree( p );
    return 1;
}

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


1876 1877
ABC_NAMESPACE_IMPL_END