sswSweep.c 13.7 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 22 23
/**CFile****************************************************************

  FileName    [sswSweep.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: sswSweep.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]

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

#include "sswInt.h"
#include "bar.h"

24 25 26
ABC_NAMESPACE_IMPL_START


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

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

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

Alan Mishchenko committed
37 38 39 40 41 42 43 44 45
  Synopsis    [Retrives value of the PI in the original AIG.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
46
int Ssw_ManGetSatVarValue( Ssw_Man_t * p, Aig_Obj_t * pObj, int f )
Alan Mishchenko committed
47
{
Alan Mishchenko committed
48
    int fUseNoBoundary = 0;
Alan Mishchenko committed
49
    Aig_Obj_t * pObjFraig;
Alan Mishchenko committed
50
    int Value;
Alan Mishchenko committed
51
//    assert( Aig_ObjIsPi(pObj) );
Alan Mishchenko committed
52
    pObjFraig = Ssw_ObjFrame( p, pObj, f );
Alan Mishchenko committed
53 54 55 56 57 58 59 60 61 62 63
    if ( fUseNoBoundary )
    {
        Value = Ssw_CnfGetNodeValue( p->pMSat, Aig_Regular(pObjFraig) );
        Value ^= Aig_IsComplement(pObjFraig);
    }
    else
    {
        int nVarNum = Ssw_ObjSatNum( p->pMSat, Aig_Regular(pObjFraig) );
        Value = (!nVarNum)? 0 : (Aig_IsComplement(pObjFraig) ^ sat_solver_var_value( p->pMSat->pSat, nVarNum ));
    }

Alan Mishchenko committed
64
//    Value = (Aig_IsComplement(pObjFraig) ^ ((!nVarNum)? 0 : sat_solver_var_value( p->pSat, nVarNum )));
Alan Mishchenko committed
65 66 67 68 69 70 71 72 73 74
//    Value = (!nVarNum)? Aig_ManRandom(0) & 1 : (Aig_IsComplement(pObjFraig) ^ sat_solver_var_value( p->pSat, nVarNum ));
    if ( p->pPars->fPolarFlip )
    {
        if ( Aig_Regular(pObjFraig)->fPhase )  Value ^= 1;
    }
    return Value;
}

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

Alan Mishchenko committed
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
  Synopsis    [Performs fraiging for the internal nodes.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Ssw_CheckConstraints( Ssw_Man_t * p )
{
    Aig_Obj_t * pObj, * pObj2;
    int nConstrPairs, i;
    int Counter = 0;
    nConstrPairs = Aig_ManPoNum(p->pFrames)-Aig_ManRegNum(p->pAig);
    assert( (nConstrPairs & 1) == 0 );
    for ( i = 0; i < nConstrPairs; i += 2 )
    {
        pObj  = Aig_ManPo( p->pFrames, i   );
        pObj2 = Aig_ManPo( p->pFrames, i+1 );
        if ( Ssw_NodesAreEquiv( p, Aig_ObjFanin0(pObj), Aig_ObjFanin0(pObj2) ) != 1 )
        {
            Ssw_NodesAreConstrained( p, Aig_ObjChild0(pObj), Aig_ObjChild0(pObj2) );
            Counter++;
        }
    }
    printf( "Total constraints = %d. Added constraints = %d.\n", nConstrPairs/2, Counter );
}

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

Alan Mishchenko committed
106 107 108 109 110 111 112 113 114
  Synopsis    [Copy pattern from the solver into the internal storage.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
115
void Ssw_SmlSavePatternAigPhase( Ssw_Man_t * p, int f )
Alan Mishchenko committed
116 117 118 119 120
{
    Aig_Obj_t * pObj;
    int i;
    memset( p->pPatWords, 0, sizeof(unsigned) * p->nPatWords );
    Aig_ManForEachPi( p->pAig, pObj, i )
Alan Mishchenko committed
121
        if ( Aig_ObjPhaseReal( Ssw_ObjFrame(p, pObj, f) ) )
Alan Mishchenko committed
122 123 124 125 126 127 128 129 130 131 132 133 134 135
            Aig_InfoSetBit( p->pPatWords, i );
}

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

  Synopsis    [Copy pattern from the solver into the internal storage.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
136
void Ssw_SmlSavePatternAig( Ssw_Man_t * p, int f )
Alan Mishchenko committed
137 138 139 140 141
{
    Aig_Obj_t * pObj;
    int i;
    memset( p->pPatWords, 0, sizeof(unsigned) * p->nPatWords );
    Aig_ManForEachPi( p->pAig, pObj, i )
Alan Mishchenko committed
142
        if ( Ssw_ManGetSatVarValue( p, pObj, f ) )
Alan Mishchenko committed
143 144 145 146 147
            Aig_InfoSetBit( p->pPatWords, i );
}

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

Alan Mishchenko committed
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
  Synopsis    [Saves one counter-example into internal storage.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Ssw_SmlAddPatternDyn( Ssw_Man_t * p )
{
    Aig_Obj_t * pObj;
    unsigned * pInfo;
    int i, nVarNum;
    // iterate through the PIs of the frames
163
    Vec_PtrForEachEntry( Aig_Obj_t *, p->pMSat->vUsedPis, pObj, i )
Alan Mishchenko committed
164 165 166 167 168 169
    {
        assert( Aig_ObjIsPi(pObj) );
        nVarNum = Ssw_ObjSatNum( p->pMSat, pObj );
        assert( nVarNum > 0 );
        if ( sat_solver_var_value( p->pMSat->pSat, nVarNum ) )
        {
170
            pInfo = (unsigned *)Vec_PtrEntry( p->vSimInfo, Aig_ObjPioNum(pObj) );
Alan Mishchenko committed
171 172 173 174 175 176 177
            Aig_InfoSetBit( pInfo, p->nPatterns );
        }
    }
}

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

Alan Mishchenko committed
178 179 180 181 182 183 184 185 186
  Synopsis    [Performs fraiging for one node.]

  Description [Returns the fraiged node.]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
187
int Ssw_ManSweepNode( Ssw_Man_t * p, Aig_Obj_t * pObj, int f, int fBmc, Vec_Int_t * vPairs )
Alan Mishchenko committed
188 189
{ 
    Aig_Obj_t * pObjRepr, * pObjFraig, * pObjFraig2, * pObjReprFraig;
Alan Mishchenko committed
190
    int RetValue, clk;
Alan Mishchenko committed
191 192 193
    // get representative of this class
    pObjRepr = Aig_ObjRepr( p->pAig, pObj );
    if ( pObjRepr == NULL )
Alan Mishchenko committed
194
        return 0;
Alan Mishchenko committed
195
    // get the fraiged node
Alan Mishchenko committed
196
    pObjFraig = Ssw_ObjFrame( p, pObj, f );
Alan Mishchenko committed
197
    // get the fraiged representative
Alan Mishchenko committed
198
    pObjReprFraig = Ssw_ObjFrame( p, pObjRepr, f );
Alan Mishchenko committed
199
    // check if constant 0 pattern distinquishes these nodes
Alan Mishchenko committed
200
    assert( pObjFraig != NULL && pObjReprFraig != NULL );
Alan Mishchenko committed
201 202 203 204 205 206
    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) )
        return 0; 
    // add constraints on demand
    if ( !fBmc && p->pPars->fDynamic )
Alan Mishchenko committed
207
    {
Alan Mishchenko committed
208 209 210 211
clk = clock();
        Ssw_ManLoadSolver( p, pObjRepr, pObj );
        p->nRecycleCalls++;
p->timeMarkCones += clock() - clk;
Alan Mishchenko committed
212
    }
Alan Mishchenko committed
213 214 215
    // call equivalence checking
    if ( Aig_Regular(pObjFraig) != Aig_ManConst1(p->pFrames) )
        RetValue = Ssw_NodesAreEquiv( p, Aig_Regular(pObjReprFraig), Aig_Regular(pObjFraig) );
Alan Mishchenko committed
216
    else
Alan Mishchenko committed
217 218 219 220 221 222
        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;
Alan Mishchenko committed
223
    }
224 225 226 227 228
    if ( vPairs )
    {
        Vec_IntPush( vPairs, pObjRepr->Id );
        Vec_IntPush( vPairs, pObj->Id );
    }
Alan Mishchenko committed
229 230 231 232 233 234 235 236 237 238 239 240 241 242
    if ( RetValue == -1 ) // timed out
    {
        Ssw_ClassesRemoveNode( p->ppClasses, pObj );
        return 1;
    }
    // disproved the equivalence
    if ( !fBmc && p->pPars->fDynamic )
    {
        Ssw_SmlAddPatternDyn( p );
        p->nPatterns++;
        return 1;
    }
    else
        Ssw_SmlSavePatternAig( p, f );
243
    if ( !p->pPars->fConstrs )
Alan Mishchenko committed
244
        Ssw_ManResimulateWord( p, pObj, pObjRepr, f );
Alan Mishchenko committed
245
    else
Alan Mishchenko committed
246
        Ssw_ManResimulateBit( p, pObj, pObjRepr );
Alan Mishchenko committed
247
    assert( Aig_ObjRepr( p->pAig, pObj ) != pObjRepr );
Alan Mishchenko committed
248 249 250 251
    if ( Aig_ObjRepr( p->pAig, pObj ) == pObjRepr )
    {
        printf( "Ssw_ManSweepNode(): Failed to refine representative.\n" );
    }
Alan Mishchenko committed
252
    return 1;
Alan Mishchenko committed
253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268
}

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

  Synopsis    [Performs fraiging for the internal nodes.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Ssw_ManSweepBmc( Ssw_Man_t * p )
{
    Bar_Progress_t * pProgress = NULL;
Alan Mishchenko committed
269
    Aig_Obj_t * pObj, * pObjNew, * pObjLi, * pObjLo;
Alan Mishchenko committed
270 271 272 273 274 275
    int i, f, clk;
clk = clock();

    // start initialized timeframes
    p->pFrames = Aig_ManStart( Aig_ManObjNumMax(p->pAig) * p->pPars->nFramesK );
    Saig_ManForEachLo( p->pAig, pObj, i )
Alan Mishchenko committed
276
        Ssw_ObjSetFrame( p, pObj, 0, Aig_ManConst0(p->pFrames) );
Alan Mishchenko committed
277 278 279

    // sweep internal nodes
    p->fRefined = 0;
Alan Mishchenko committed
280 281
    if ( p->pPars->fVerbose )
        pProgress = Bar_ProgressStart( stdout, Aig_ManObjNumMax(p->pAig) * p->pPars->nFramesK );
Alan Mishchenko committed
282 283 284
    for ( f = 0; f < p->pPars->nFramesK; f++ )
    {
        // map constants and PIs
Alan Mishchenko committed
285
        Ssw_ObjSetFrame( p, Aig_ManConst1(p->pAig), f, Aig_ManConst1(p->pFrames) );
Alan Mishchenko committed
286
        Saig_ManForEachPi( p->pAig, pObj, i )
Alan Mishchenko committed
287
            Ssw_ObjSetFrame( p, pObj, f, Aig_ObjCreatePi(p->pFrames) );
Alan Mishchenko committed
288 289 290
        // sweep internal nodes
        Aig_ManForEachNode( p->pAig, pObj, i )
        {
Alan Mishchenko committed
291 292
            if ( p->pPars->fVerbose )
                Bar_ProgressUpdate( pProgress, Aig_ManObjNumMax(p->pAig) * f + i, NULL );
Alan Mishchenko committed
293
            pObjNew = Aig_And( p->pFrames, Ssw_ObjChild0Fra(p, pObj, f), Ssw_ObjChild1Fra(p, pObj, f) );
Alan Mishchenko committed
294
            Ssw_ObjSetFrame( p, pObj, f, pObjNew );
295
            p->fRefined |= Ssw_ManSweepNode( p, pObj, f, 1, NULL );
Alan Mishchenko committed
296
        }
Alan Mishchenko committed
297 298 299 300
        // quit if this is the last timeframe
        if ( f == p->pPars->nFramesK - 1 )
            break;
        // transfer latch input to the latch outputs 
301 302
        Aig_ManForEachPo( p->pAig, pObj, i )
            Ssw_ObjSetFrame( p, pObj, f, Ssw_ObjChild0Fra(p, pObj, f) );
Alan Mishchenko committed
303
        // build logic cones for register outputs
Alan Mishchenko committed
304
        Saig_ManForEachLiLo( p->pAig, pObjLi, pObjLo, i )
Alan Mishchenko committed
305
        {
306
            pObjNew = Ssw_ObjFrame( p, pObjLi, f );
Alan Mishchenko committed
307
            Ssw_ObjSetFrame( p, pObjLo, f+1, pObjNew );
Alan Mishchenko committed
308
            Ssw_CnfNodeAddToSolver( p->pMSat, Aig_Regular(pObjNew) );//
Alan Mishchenko committed
309
        }
Alan Mishchenko committed
310
    }
Alan Mishchenko committed
311 312
    if ( p->pPars->fVerbose )
        Bar_ProgressStop( pProgress );
Alan Mishchenko committed
313 314

    // cleanup
Alan Mishchenko committed
315
//    Ssw_ClassesCheck( p->ppClasses );
Alan Mishchenko committed
316 317 318 319
p->timeBmc += clock() - clk;
    return p->fRefined;
}

320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351

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

  Synopsis    [Generates AIG with the following nodes put into seq miters.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Ssw_ManDumpEquivMiter( Aig_Man_t * p, Vec_Int_t * vPairs, int Num )
{
    FILE * pFile;
    char pBuffer[16];
    Aig_Man_t * pNew;
    sprintf( pBuffer, "equiv%03d.aig", Num );
    pFile = fopen( pBuffer, "w" );
    if ( pFile == NULL )
    {
        printf( "Cannot open file %s for writing.\n", pBuffer );
        return;
    }
    fclose( pFile );
    pNew = Saig_ManCreateEquivMiter( p, vPairs );
    Ioa_WriteAiger( pNew, pBuffer, 0, 0 );
    Aig_ManStop( pNew );
    printf( "AIG with %4d disproved equivs is dumped into file \"%s\".\n", Vec_IntSize(vPairs)/2, pBuffer );
}


Alan Mishchenko committed
352 353 354 355 356 357 358 359 360 361 362
/**Function*************************************************************

  Synopsis    [Performs fraiging for the internal nodes.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
363 364
int Ssw_ManSweep( Ssw_Man_t * p )
{ 
365
    static int Counter;
Alan Mishchenko committed
366 367
    Bar_Progress_t * pProgress = NULL;
    Aig_Obj_t * pObj, * pObj2, * pObjNew;
368
    int nConstrPairs, clk, i, f;
369
    Vec_Int_t * vDisproved;
Alan Mishchenko committed
370 371 372 373 374

    // perform speculative reduction
clk = clock();
    // create timeframes
    p->pFrames = Ssw_FramesWithClasses( p );
Alan Mishchenko committed
375
    // add constants
Alan Mishchenko committed
376 377 378 379 380 381
    nConstrPairs = Aig_ManPoNum(p->pFrames)-Aig_ManRegNum(p->pAig);
    assert( (nConstrPairs & 1) == 0 );
    for ( i = 0; i < nConstrPairs; i += 2 )
    {
        pObj  = Aig_ManPo( p->pFrames, i   );
        pObj2 = Aig_ManPo( p->pFrames, i+1 );
Alan Mishchenko committed
382
        Ssw_NodesAreConstrained( p, Aig_ObjChild0(pObj), Aig_ObjChild0(pObj2) );
Alan Mishchenko committed
383 384 385 386 387
    }
    // build logic cones for register inputs
    for ( i = 0; i < Aig_ManRegNum(p->pAig); i++ )
    {
        pObj  = Aig_ManPo( p->pFrames, nConstrPairs + i );
Alan Mishchenko committed
388
        Ssw_CnfNodeAddToSolver( p->pMSat, Aig_ObjFanin0(pObj) );//
Alan Mishchenko committed
389
    }
Alan Mishchenko committed
390
    sat_solver_simplify( p->pMSat->pSat );
Alan Mishchenko committed
391

Alan Mishchenko committed
392 393
    // map constants and PIs of the last frame
    f = p->pPars->nFramesK;
Alan Mishchenko committed
394
    Ssw_ObjSetFrame( p, Aig_ManConst1(p->pAig), f, Aig_ManConst1(p->pFrames) );
Alan Mishchenko committed
395
    Saig_ManForEachPi( p->pAig, pObj, i )
Alan Mishchenko committed
396
        Ssw_ObjSetFrame( p, pObj, f, Aig_ObjCreatePi(p->pFrames) );
Alan Mishchenko committed
397 398
p->timeReduce += clock() - clk;

Alan Mishchenko committed
399 400
    // sweep internal nodes
    p->fRefined = 0;
Alan Mishchenko committed
401
    Ssw_ClassesClearRefined( p->ppClasses );
Alan Mishchenko committed
402 403
    if ( p->pPars->fVerbose )
        pProgress = Bar_ProgressStart( stdout, Aig_ManObjNumMax(p->pAig) );
404
    vDisproved = p->pPars->fEquivDump? Vec_IntAlloc(1000) : NULL;
Alan Mishchenko committed
405
    Aig_ManForEachObj( p->pAig, pObj, i )
Alan Mishchenko committed
406
    {
Alan Mishchenko committed
407 408 409
        if ( p->pPars->fVerbose )
            Bar_ProgressUpdate( pProgress, i, NULL );
        if ( Saig_ObjIsLo(p->pAig, pObj) )
410
            p->fRefined |= Ssw_ManSweepNode( p, pObj, f, 0, vDisproved );
Alan Mishchenko committed
411
        else if ( Aig_ObjIsNode(pObj) )
Alan Mishchenko committed
412
        { 
Alan Mishchenko committed
413
            pObjNew = Aig_And( p->pFrames, Ssw_ObjChild0Fra(p, pObj, f), Ssw_ObjChild1Fra(p, pObj, f) );
Alan Mishchenko committed
414
            Ssw_ObjSetFrame( p, pObj, f, pObjNew );
415
            p->fRefined |= Ssw_ManSweepNode( p, pObj, f, 0, vDisproved );
Alan Mishchenko committed
416
        }
Alan Mishchenko committed
417
    }
Alan Mishchenko committed
418 419
    if ( p->pPars->fVerbose )
        Bar_ProgressStop( pProgress );
Alan Mishchenko committed
420 421

    // cleanup
Alan Mishchenko committed
422
//    Ssw_ClassesCheck( p->ppClasses );
423 424 425
    if ( p->pPars->fEquivDump )
        Ssw_ManDumpEquivMiter( p->pAig, vDisproved, Counter++ );
    Vec_IntFreeP( &vDisproved );
Alan Mishchenko committed
426 427 428 429 430 431 432 433
    return p->fRefined;
}

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


434 435
ABC_NAMESPACE_IMPL_END