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

  FileName    [sswConstr.c]

  SystemName  [ABC: Logic synthesis and verification system.]

  PackageName [Inductive prover with constraints.]

  Synopsis    [One round of SAT sweeping.]

  Author      [Alan Mishchenko]
  
  Affiliation [UC Berkeley]

  Date        [Ver. 1.0. Started - September 1, 2008.]

  Revision    [$Id: sswConstr.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]

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

#include "sswInt.h"
22
#include "aig/gia/giaAig.h"
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46

ABC_NAMESPACE_IMPL_START


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

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

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

  Synopsis    [Performs fraiging for one node.]

  Description [Returns the fraiged node.]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Ssw_ManRefineByFilterSim( Ssw_Man_t * p, int nFrames )
47
{
48 49 50 51 52
    Aig_Obj_t * pObj, * pObjLi;
    int f, i, RetValue1, RetValue2;
    assert( nFrames > 0 );
    // assign register outputs
    Saig_ManForEachLi( p->pAig, pObj, i )
53
        pObj->fMarkB = Abc_InfoHasBit( p->pPatWords, Saig_ManPiNum(p->pAig) + i );
54 55 56 57 58 59 60 61 62 63 64 65 66 67
    // simulate the timeframes
    for ( f = 0; f < nFrames; f++ )
    {
        // set the PI simulation information
        Aig_ManConst1(p->pAig)->fMarkB = 1;
        Saig_ManForEachPi( p->pAig, pObj, i )
            pObj->fMarkB = 0;
        Saig_ManForEachLiLo( p->pAig, pObjLi, pObj, i )
            pObj->fMarkB = pObjLi->fMarkB;
        // simulate internal nodes
        Aig_ManForEachNode( p->pAig, pObj, i )
            pObj->fMarkB = ( Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj) )
                         & ( Aig_ObjFanin1(pObj)->fMarkB ^ Aig_ObjFaninC1(pObj) );
        // assign the COs
68
        Aig_ManForEachCo( p->pAig, pObj, i )
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
            pObj->fMarkB = ( Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj) );
        // transfer
        if ( f == 0 )
        { // copy markB into phase
            Aig_ManForEachObj( p->pAig, pObj, i )
                pObj->fPhase = pObj->fMarkB;
        }
        else
        { // refine classes
            RetValue1 = Ssw_ClassesRefineConst1( p->ppClasses, 0 );
            RetValue2 = Ssw_ClassesRefine( p->ppClasses, 0 );
        }
    }
}


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

  Synopsis    [Performs fraiging for one node.]

  Description [Returns the fraiged node.]
90

91 92 93 94 95 96
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Ssw_ManRollForward( Ssw_Man_t * p, int nFrames )
97
{
98 99 100 101 102
    Aig_Obj_t * pObj, * pObjLi;
    int f, i;
    assert( nFrames > 0 );
    // assign register outputs
    Saig_ManForEachLi( p->pAig, pObj, i )
103
        pObj->fMarkB = Abc_InfoHasBit( p->pPatWords, Saig_ManPiNum(p->pAig) + i );
104 105 106 107 108 109 110 111 112 113 114 115 116 117
    // simulate the timeframes
    for ( f = 0; f < nFrames; f++ )
    {
        // set the PI simulation information
        Aig_ManConst1(p->pAig)->fMarkB = 1;
        Saig_ManForEachPi( p->pAig, pObj, i )
            pObj->fMarkB = Aig_ManRandom(0) & 1;
        Saig_ManForEachLiLo( p->pAig, pObjLi, pObj, i )
            pObj->fMarkB = pObjLi->fMarkB;
        // simulate internal nodes
        Aig_ManForEachNode( p->pAig, pObj, i )
            pObj->fMarkB = ( Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj) )
                         & ( Aig_ObjFanin1(pObj)->fMarkB ^ Aig_ObjFaninC1(pObj) );
        // assign the COs
118
        Aig_ManForEachCo( p->pAig, pObj, i )
119 120 121 122
            pObj->fMarkB = ( Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj) );
    }
    // record the new pattern
    Saig_ManForEachLi( p->pAig, pObj, i )
123 124
        if ( pObj->fMarkB ^ Abc_InfoHasBit(p->pPatWords, Saig_ManPiNum(p->pAig) + i) )
            Abc_InfoXorBit( p->pPatWords, Saig_ManPiNum(p->pAig) + i );
125 126 127 128 129 130 131
}

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

  Synopsis    [Performs fraiging for one node.]

  Description [Returns the fraiged node.]
132

133 134 135 136 137 138
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Ssw_ManFindStartingState( Ssw_Man_t * p, Abc_Cex_t * pCex )
139
{
140 141 142 143 144 145 146 147 148 149 150 151
    Aig_Obj_t * pObj, * pObjLi;
    int f, i, iBit;
    // assign register outputs
    Saig_ManForEachLi( p->pAig, pObj, i )
        pObj->fMarkB = 0;
    // simulate the timeframes
    iBit = pCex->nRegs;
    for ( f = 0; f <= pCex->iFrame; f++ )
    {
        // set the PI simulation information
        Aig_ManConst1(p->pAig)->fMarkB = 1;
        Saig_ManForEachPi( p->pAig, pObj, i )
152
            pObj->fMarkB = Abc_InfoHasBit( pCex->pData, iBit++ );
153 154 155 156 157 158 159
        Saig_ManForEachLiLo( p->pAig, pObjLi, pObj, i )
            pObj->fMarkB = pObjLi->fMarkB;
        // simulate internal nodes
        Aig_ManForEachNode( p->pAig, pObj, i )
            pObj->fMarkB = ( Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj) )
                         & ( Aig_ObjFanin1(pObj)->fMarkB ^ Aig_ObjFaninC1(pObj) );
        // assign the COs
160
        Aig_ManForEachCo( p->pAig, pObj, i )
161 162 163 164
            pObj->fMarkB = ( Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj) );
    }
    assert( iBit == pCex->nBits );
    // check that the output failed as expected -- cannot check because it is not an SRM!
165
//    pObj = Aig_ManCo( p->pAig, pCex->iPo );
166
//    if ( pObj->fMarkB != 1 )
167
//        Abc_Print( 1, "The counter-example does not refine the output.\n" );
168 169
    // record the new pattern
    Saig_ManForEachLo( p->pAig, pObj, i )
170 171
        if ( pObj->fMarkB ^ Abc_InfoHasBit(p->pPatWords, Saig_ManPiNum(p->pAig) + i) )
            Abc_InfoXorBit( p->pPatWords, Saig_ManPiNum(p->pAig) + i );
172 173 174 175 176 177 178 179 180 181 182 183 184 185
}

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

  Synopsis    [Performs fraiging for one node.]

  Description [Returns the fraiged node.]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Ssw_ManSweepNodeFilter( Ssw_Man_t * p, Aig_Obj_t * pObj, int f )
186
{
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
    Aig_Obj_t * pObjRepr, * pObjFraig, * pObjFraig2, * pObjReprFraig;
    int RetValue;
    // get representative of this class
    pObjRepr = Aig_ObjRepr( p->pAig, pObj );
    if ( pObjRepr == NULL )
        return 0;
    // get the fraiged node
    pObjFraig = Ssw_ObjFrame( p, pObj, f );
    // get the fraiged representative
    pObjReprFraig = Ssw_ObjFrame( p, pObjRepr, f );
    // check if constant 0 pattern distinquishes these nodes
    assert( pObjFraig != NULL && pObjReprFraig != NULL );
    assert( (pObj->fPhase == pObjRepr->fPhase) == (Aig_ObjPhaseReal(pObjFraig) == Aig_ObjPhaseReal(pObjReprFraig)) );
    // if the fraiged nodes are the same, return
    if ( Aig_Regular(pObjFraig) == Aig_Regular(pObjReprFraig) )
202
        return 0;
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224
    // call equivalence checking
    if ( Aig_Regular(pObjFraig) != Aig_ManConst1(p->pFrames) )
        RetValue = Ssw_NodesAreEquiv( p, Aig_Regular(pObjReprFraig), Aig_Regular(pObjFraig) );
    else
        RetValue = Ssw_NodesAreEquiv( p, Aig_Regular(pObjFraig), Aig_Regular(pObjReprFraig) );
    if ( RetValue == 1 )  // proved equivalent
    {
        pObjFraig2 = Aig_NotCond( pObjReprFraig, pObj->fPhase ^ pObjRepr->fPhase );
        Ssw_ObjSetFrame( p, pObj, f, pObjFraig2 );
        return 0;
    }
    if ( RetValue == -1 ) // timed out
    {
//        Ssw_ClassesRemoveNode( p->ppClasses, pObj );
        return 1;
    }
    // disproved equivalence
    Ssw_SmlSavePatternAig( p, f );
    Ssw_ManResimulateBit( p, pObj, pObjRepr );
    assert( Aig_ObjRepr( p->pAig, pObj ) != pObjRepr );
    if ( Aig_ObjRepr( p->pAig, pObj ) == pObjRepr )
    {
225
        Abc_Print( 1, "Ssw_ManSweepNodeFilter(): Failed to refine representative.\n" );
226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280
    }
    return 0;
}

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

  Synopsis    [Performs fraiging for the internal nodes.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Aig_Obj_t * Ssw_ManSweepBmcFilter_rec( Ssw_Man_t * p, Aig_Obj_t * pObj, int f )
{
    Aig_Obj_t * pObjNew, * pObjLi;
    pObjNew = Ssw_ObjFrame( p, pObj, f );
    if ( pObjNew )
        return pObjNew;
    assert( !Saig_ObjIsPi(p->pAig, pObj) );
    if ( Saig_ObjIsLo(p->pAig, pObj) )
    {
        assert( f > 0 );
        pObjLi  = Saig_ObjLoToLi( p->pAig, pObj );
        pObjNew = Ssw_ManSweepBmcFilter_rec( p, Aig_ObjFanin0(pObjLi), f-1 );
        pObjNew = Aig_NotCond( pObjNew, Aig_ObjFaninC0(pObjLi) );
    }
    else
    {
        assert( Aig_ObjIsNode(pObj) );
        Ssw_ManSweepBmcFilter_rec( p, Aig_ObjFanin0(pObj), f );
        Ssw_ManSweepBmcFilter_rec( p, Aig_ObjFanin1(pObj), f );
        pObjNew = Aig_And( p->pFrames, Ssw_ObjChild0Fra(p, pObj, f), Ssw_ObjChild1Fra(p, pObj, f) );
    }
    Ssw_ObjSetFrame( p, pObj, f, pObjNew );
    assert( pObjNew != NULL );
    return pObjNew;
}

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

  Synopsis    [Filter equivalence classes of nodes.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Ssw_ManSweepBmcFilter( Ssw_Man_t * p, int TimeLimit )
{
    Aig_Obj_t * pObj, * pObjNew, * pObjLi, * pObjLo;
281
    int f, f1, i;
282
    abctime clkTotal = Abc_Clock();
283 284 285 286
    // start initialized timeframes
    p->pFrames = Aig_ManStart( Aig_ManObjNumMax(p->pAig) * p->pPars->nFramesK );
    Saig_ManForEachLo( p->pAig, pObj, i )
    {
287
        if ( Abc_InfoHasBit( p->pPatWords, Saig_ManPiNum(p->pAig) + i ) )
288 289
        {
            Ssw_ObjSetFrame( p, pObj, 0, Aig_ManConst1(p->pFrames) );
290
//Abc_Print( 1, "1" );
291 292 293 294
        }
        else
        {
            Ssw_ObjSetFrame( p, pObj, 0, Aig_ManConst0(p->pFrames) );
295
//Abc_Print( 1, "0" );
296 297
        }
    }
298
//Abc_Print( 1, "\n" );
299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320

    // sweep internal nodes
    for ( f = 0; f < p->pPars->nFramesK; f++ )
    {
        // realloc mapping of timeframes
        if ( f == p->nFrames-1 )
        {
            Aig_Obj_t ** pNodeToFrames;
            pNodeToFrames = ABC_CALLOC( Aig_Obj_t *, Aig_ManObjNumMax(p->pAig) * 2 * p->nFrames );
            for ( f1 = 0; f1 < p->nFrames; f1++ )
            {
                Aig_ManForEachObj( p->pAig, pObj, i )
                    pNodeToFrames[2*p->nFrames*pObj->Id + f1] = Ssw_ObjFrame( p, pObj, f1 );
            }
            ABC_FREE( p->pNodeToFrames );
            p->pNodeToFrames = pNodeToFrames;
            p->nFrames *= 2;
        }
        // map constants and PIs
        Ssw_ObjSetFrame( p, Aig_ManConst1(p->pAig), f, Aig_ManConst1(p->pFrames) );
        Saig_ManForEachPi( p->pAig, pObj, i )
        {
321
            pObjNew = Aig_ObjCreateCi(p->pFrames);
322 323 324 325 326 327 328 329 330 331 332 333 334
            Ssw_ObjSetFrame( p, pObj, f, pObjNew );
        }
        // sweep internal nodes
        Aig_ManForEachNode( p->pAig, pObj, i )
        {
            pObjNew = Aig_And( p->pFrames, Ssw_ObjChild0Fra(p, pObj, f), Ssw_ObjChild1Fra(p, pObj, f) );
            Ssw_ObjSetFrame( p, pObj, f, pObjNew );
            if ( Ssw_ManSweepNodeFilter( p, pObj, f ) )
                break;
        }
        // printout
        if ( p->pPars->fVerbose )
        {
335
            Abc_Print( 1, "Frame %4d : ", f );
336 337 338 339 340
            Ssw_ClassesPrint( p->ppClasses, 0 );
        }
        if ( i < Vec_PtrSize(p->pAig->vObjs) )
        {
            if ( p->pPars->fVerbose )
341
                Abc_Print( 1, "Exceeded the resource limits (%d conflicts). Quitting...\n", p->pPars->nBTLimit );
342
            break;
343
        }
344 345 346 347
        // quit if this is the last timeframe
        if ( f == p->pPars->nFramesK - 1 )
        {
            if ( p->pPars->fVerbose )
348
                Abc_Print( 1, "Exceeded the time frame limit (%d time frames). Quitting...\n", p->pPars->nFramesK );
349 350 351
            break;
        }
        // check timeout
352
        if ( TimeLimit && ((float)TimeLimit <= (float)(Abc_Clock()-clkTotal)/(float)(CLOCKS_PER_SEC)) )
353 354
            break;
        // transfer latch input to the latch outputs 
355
        Aig_ManForEachCo( p->pAig, pObj, i )
356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373
            Ssw_ObjSetFrame( p, pObj, f, Ssw_ObjChild0Fra(p, pObj, f) );
        // build logic cones for register outputs
        Saig_ManForEachLiLo( p->pAig, pObjLi, pObjLo, i )
        {
            pObjNew = Ssw_ObjFrame( p, pObjLi, f );
            Ssw_ObjSetFrame( p, pObjLo, f+1, pObjNew );
            Ssw_CnfNodeAddToSolver( p->pMSat, Aig_Regular(pObjNew) );//
        }
    }
    // verify
//    Ssw_ClassesCheck( p->ppClasses );
    return 1;
}

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

  Synopsis    [Filter equivalence classes of nodes.]

374
  Description [Unrolls at most nFramesMax frames. Works with nConfMax
375
  conflicts until the first undefined SAT call. Verbose prints the message.]
376

377 378 379 380 381
  SideEffects []

  SeeAlso     []

***********************************************************************/
382
void Ssw_SignalFilter( Aig_Man_t * pAig, int nFramesMax, int nConfMax, int nRounds, int TimeLimit, int TimeLimit2, Abc_Cex_t * pCex, int fLatchOnly, int fVerbose )
383 384 385
{
    Ssw_Pars_t Pars, * pPars = &Pars;
    Ssw_Man_t * p;
386 387
    int r, TimeLimitPart;//, clkTotal = Abc_Clock();
    abctime nTimeToStop = TimeLimit ? TimeLimit * CLOCKS_PER_SEC + Abc_Clock(): 0;
388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405
    assert( Aig_ManRegNum(pAig) > 0 );
    assert( Aig_ManConstrNum(pAig) == 0 );
    // consider the case of empty AIG
    if ( Aig_ManNodeNum(pAig) == 0 )
        return;
    // reset random numbers
    Aig_ManRandom( 1 );
    // if parameters are not given, create them
    Ssw_ManSetDefaultParams( pPars = &Pars );
    pPars->nFramesK  = 3; //nFramesMax;
    pPars->nBTLimit  = nConfMax;
    pPars->TimeLimit = TimeLimit;
    pPars->fVerbose  = fVerbose;
    // start the induction manager
    p = Ssw_ManCreate( pAig, pPars );
    pPars->nFramesK  = nFramesMax;
    // create trivial equivalence classes with all nodes being candidates for constant 1
    if ( pAig->pReprs == NULL )
406
        p->ppClasses = Ssw_ClassesPrepareSimple( pAig, fLatchOnly, 0 );
407 408 409 410 411 412 413 414 415 416 417
    else
        p->ppClasses = Ssw_ClassesPrepareFromReprs( pAig );
    Ssw_ClassesSetData( p->ppClasses, NULL, NULL, Ssw_SmlObjIsConstBit, Ssw_SmlObjsAreEqualBit );
    assert( p->vInits == NULL );
    // compute starting state if needed
    if ( pCex )
        Ssw_ManFindStartingState( p, pCex );
    // refine classes using BMC
    for ( r = 0; r < nRounds; r++ )
    {
        if ( p->pPars->fVerbose )
418
            Abc_Print( 1, "Round %3d:\n", r );
419 420 421 422
        // start filtering equivalence classes
        Ssw_ManRefineByFilterSim( p, p->pPars->nFramesK );
        if ( Ssw_ClassesCand1Num(p->ppClasses) == 0 && Ssw_ClassesClassNum(p->ppClasses) == 0 )
        {
423
            Abc_Print( 1, "All equivalences are refined away.\n" );
424 425 426 427 428
            break;
        }
        // printout
        if ( p->pPars->fVerbose )
        {
429
            Abc_Print( 1, "Initial    : " );
430 431 432
            Ssw_ClassesPrint( p->ppClasses, 0 );
        }
        p->pMSat = Ssw_SatStart( 0 );
433
        TimeLimitPart = TimeLimit ? (nTimeToStop - Abc_Clock()) / CLOCKS_PER_SEC : 0;
434 435 436
        if ( TimeLimit2 )
        {
            if ( TimeLimitPart )
437
                TimeLimitPart = Abc_MinInt( TimeLimitPart, TimeLimit2 );
438 439 440 441 442 443 444 445 446 447
            else
                TimeLimitPart = TimeLimit2;
        }
        Ssw_ManSweepBmcFilter( p, TimeLimitPart );
        Ssw_SatStop( p->pMSat );
        p->pMSat = NULL;
        Ssw_ManCleanup( p );
        // simulate pattern forward
        Ssw_ManRollForward( p, p->pPars->nFramesK );
        // check timeout
448
        if ( TimeLimit && Abc_Clock() > nTimeToStop )
449
        {
450
            Abc_Print( 1, "Reached timeout (%d seconds).\n",  TimeLimit );
451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472
            break;
        }
    }
    // cleanup
    Aig_ManSetPhase( p->pAig );
    Aig_ManCleanMarkB( p->pAig );
    // cleanup
    pPars->fVerbose = 0;
    Ssw_ManStop( p );
}

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

  Synopsis    [Filter equivalence classes of nodes.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
473
void Ssw_SignalFilterGia( Gia_Man_t * p, int nFramesMax, int nConfMax, int nRounds, int TimeLimit, int TimeLimit2, Abc_Cex_t * pCex, int fLatchOnly, int fVerbose )
474
{
475 476 477 478 479 480 481 482
    Aig_Man_t * pAig;
    pAig = Gia_ManToAigSimple( p );
    if ( p->pReprs != NULL )
    {
        Gia_ManReprToAigRepr2( pAig, p );
        ABC_FREE( p->pReprs );
        ABC_FREE( p->pNexts );
    }
483
    Ssw_SignalFilter( pAig, nFramesMax, nConfMax, nRounds, TimeLimit, TimeLimit2, pCex, fLatchOnly, fVerbose );
484 485 486 487 488 489 490 491 492 493
    Gia_ManReprFromAigRepr( pAig, p );
    Aig_ManStop( pAig );
}

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


ABC_NAMESPACE_IMPL_END