sswPairs.c 16 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
/**CFile****************************************************************

  FileName    [sswPairs.c]

  SystemName  [ABC: Logic synthesis and verification system.]

  PackageName [Inductive prover with constraints.]

  Synopsis    [Calls to the SAT solver.]

  Author      [Alan Mishchenko]
  
  Affiliation [UC Berkeley]

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

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

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

#include "sswInt.h"

23 24 25
ABC_NAMESPACE_IMPL_START


Alan Mishchenko committed
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
////////////////////////////////////////////////////////////////////////
///                        DECLARATIONS                              ///
////////////////////////////////////////////////////////////////////////

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

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

  Synopsis    [Reports the status of the miter.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Ssw_MiterStatus( Aig_Man_t * p, int fVerbose )
{
    Aig_Obj_t * pObj, * pChild;
    int i, CountConst0 = 0, CountNonConst0 = 0, CountUndecided = 0;
//    if ( p->pData )
//        return 0;
    Saig_ManForEachPo( p, pObj, i )
    {
        pChild = Aig_ObjChild0(pObj);
        // check if the output is constant 0
        if ( pChild == Aig_ManConst0(p) )
        {
            CountConst0++;
            continue;
        }
        // check if the output is constant 1
        if ( pChild == Aig_ManConst1(p) )
        {
            CountNonConst0++;
            continue;
        }
        // check if the output is a primary input
67
        if ( p->nRegs == 0 && Aig_ObjIsCi(Aig_Regular(pChild)) )
Alan Mishchenko committed
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
        {
            CountNonConst0++;
            continue;
        }
        // check if the output can be not constant 0
        if ( Aig_Regular(pChild)->fPhase != (unsigned)Aig_IsComplement(pChild) )
        {
            CountNonConst0++;
            continue;
        }
        CountUndecided++;
    }

    if ( fVerbose )
    {
83 84 85 86 87
        Abc_Print( 1, "Miter has %d outputs. ", Saig_ManPoNum(p) );
        Abc_Print( 1, "Const0 = %d.  ", CountConst0 );
        Abc_Print( 1, "NonConst0 = %d.  ", CountNonConst0 );
        Abc_Print( 1, "Undecided = %d.  ", CountUndecided );
        Abc_Print( 1, "\n" );
Alan Mishchenko committed
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
    }

    if ( CountNonConst0 )
        return 0;
    if ( CountUndecided )
        return -1;
    return 1;
}

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

  Synopsis    [Transfer equivalent pairs to the miter.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Vec_Int_t * Ssw_TransferSignalPairs( Aig_Man_t * pMiter, Aig_Man_t * pAig1, Aig_Man_t * pAig2, Vec_Int_t * vIds1, Vec_Int_t * vIds2 )
{
    Vec_Int_t * vIds;
    Aig_Obj_t * pObj1, * pObj2;
    Aig_Obj_t * pObj1m, * pObj2m;
    int i;
    vIds = Vec_IntAlloc( 2 * Vec_IntSize(vIds1) );
    for ( i = 0; i < Vec_IntSize(vIds1); i++ )
    {
        pObj1 = Aig_ManObj( pAig1, Vec_IntEntry(vIds1, i) );
        pObj2 = Aig_ManObj( pAig2, Vec_IntEntry(vIds2, i) );
119 120
        pObj1m = Aig_Regular((Aig_Obj_t *)pObj1->pData);
        pObj2m = Aig_Regular((Aig_Obj_t *)pObj2->pData);
Alan Mishchenko committed
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
        assert( pObj1m && pObj2m );
        if ( pObj1m == pObj2m )
            continue;
        if ( pObj1m->Id < pObj2m->Id )
        {
            Vec_IntPush( vIds, pObj1m->Id );
            Vec_IntPush( vIds, pObj2m->Id );
        }
        else
        {
            Vec_IntPush( vIds, pObj2m->Id );
            Vec_IntPush( vIds, pObj1m->Id );
        }
    }
    return vIds;
}

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

  Synopsis    [Transform pairs into class representation.]

  Description []
143

Alan Mishchenko committed
144 145 146 147 148 149 150 151 152 153 154
  SideEffects []

  SeeAlso     []

***********************************************************************/
Vec_Int_t ** Ssw_TransformPairsIntoTempClasses( Vec_Int_t * vPairs, int nObjNumMax )
{
    Vec_Int_t ** pvClasses;   // vector of classes
    int * pReprs;             // mapping nodes into their representatives
    int Entry, idObj, idRepr, idReprObj, idReprRepr, i;
    // allocate data-structures
Alan Mishchenko committed
155 156
    pvClasses = ABC_CALLOC( Vec_Int_t *, nObjNumMax );
    pReprs    = ABC_ALLOC( int, nObjNumMax );
Alan Mishchenko committed
157 158 159 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
    for ( i = 0; i < nObjNumMax; i++ )
        pReprs[i] = -1;
    // consider pairs
    for ( i = 0; i < Vec_IntSize(vPairs); i += 2 )
    {
        // get both objects
        idRepr = Vec_IntEntry( vPairs, i   );
        idObj  = Vec_IntEntry( vPairs, i+1 );
        assert( idObj > 0 );
        assert( (pReprs[idRepr] == -1) || (pvClasses[pReprs[idRepr]] != NULL) );
        assert( (pReprs[idObj]  == -1) || (pvClasses[pReprs[idObj] ] != NULL) );
        // get representatives of both objects
        idReprRepr = pReprs[idRepr];
        idReprObj  = pReprs[idObj];
        // check different situations
        if ( idReprRepr == -1 && idReprObj == -1 )
        {   // they do not have classes
            // create a class
            pvClasses[idRepr] = Vec_IntAlloc( 4 );
            Vec_IntPush( pvClasses[idRepr], idRepr );
            Vec_IntPush( pvClasses[idRepr], idObj );
            pReprs[ idRepr ] = idRepr;
            pReprs[ idObj  ] = idRepr;
        }
        else if ( idReprRepr >= 0 && idReprObj == -1 )
        {   // representative has a class
            // add iObj to the same class
            Vec_IntPushUniqueOrder( pvClasses[idReprRepr], idObj );
            pReprs[ idObj ] = idReprRepr;
        }
        else if ( idReprRepr == -1 && idReprObj >= 0 )
        {   // object has a class
            assert( idReprObj != idRepr );
190
            if ( idReprObj < idRepr )
Alan Mishchenko committed
191 192 193 194
            { // add idRepr to the same class
                Vec_IntPushUniqueOrder( pvClasses[idReprObj], idRepr );
                pReprs[ idRepr ] = idReprObj;
            }
195
            else // if ( idReprObj > idRepr )
Alan Mishchenko committed
196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236
            { // make idRepr new representative
                Vec_IntPushFirst( pvClasses[idReprObj], idRepr );
                pvClasses[idRepr] = pvClasses[idReprObj];
                pvClasses[idReprObj] = NULL;
                // set correct representatives of each node
                Vec_IntForEachEntry( pvClasses[idRepr], Entry, i )
                    pReprs[ Entry ] = idRepr;
            }
        }
        else // if ( idReprRepr >= 0 && idReprObj >= 0 )
        {   // both have classes
            if ( idReprRepr == idReprObj )
            {  // the classes are the same
                // nothing to do
            }
            else
            {  // the classes are different
                // find the repr of the new class
                if ( idReprRepr < idReprObj )
                {
                    Vec_IntForEachEntry( pvClasses[idReprObj], Entry, i )
                    {
                        Vec_IntPushUniqueOrder( pvClasses[idReprRepr], Entry );
                        pReprs[ Entry ] = idReprRepr;
                    }
                    Vec_IntFree( pvClasses[idReprObj] );
                    pvClasses[idReprObj] = NULL;
                }
                else // if ( idReprRepr > idReprObj )
                {
                    Vec_IntForEachEntry( pvClasses[idReprRepr], Entry, i )
                    {
                        Vec_IntPushUniqueOrder( pvClasses[idReprObj], Entry );
                        pReprs[ Entry ] = idReprObj;
                    }
                    Vec_IntFree( pvClasses[idReprRepr] );
                    pvClasses[idReprRepr] = NULL;
                }
            }
        }
    }
Alan Mishchenko committed
237
    ABC_FREE( pReprs );
Alan Mishchenko committed
238 239 240 241 242 243 244 245
    return pvClasses;
}

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

  Synopsis    []

  Description []
246

Alan Mishchenko committed
247 248 249 250 251 252 253 254 255
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Ssw_FreeTempClasses( Vec_Int_t ** pvClasses, int nObjNumMax )
{
    int i;
    for ( i = 0; i < nObjNumMax; i++ )
256
        if ( pvClasses[i] )
Alan Mishchenko committed
257
            Vec_IntFree( pvClasses[i] );
Alan Mishchenko committed
258
    ABC_FREE( pvClasses );
Alan Mishchenko committed
259 260 261 262 263 264 265
}

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

  Synopsis    [Performs signal correspondence for the miter of two AIGs with node pairs defined.]

  Description []
266

Alan Mishchenko committed
267 268 269 270 271 272 273
  SideEffects []

  SeeAlso     []

***********************************************************************/
Aig_Man_t * Ssw_SignalCorrespondenceWithPairs( Aig_Man_t * pAig1, Aig_Man_t * pAig2, Vec_Int_t * vIds1, Vec_Int_t * vIds2, Ssw_Pars_t * pPars )
{
274
    Ssw_Man_t * p;
Alan Mishchenko committed
275 276 277 278 279 280 281
    Aig_Man_t * pAigNew, * pMiter;
    Ssw_Pars_t Pars;
    Vec_Int_t * vPairs;
    Vec_Int_t ** pvClasses;
    assert( Vec_IntSize(vIds1) == Vec_IntSize(vIds2) );
    // create sequential miter
    pMiter = Saig_ManCreateMiter( pAig1, pAig2, 0 );
Alan Mishchenko committed
282
    Aig_ManCleanup( pMiter );
Alan Mishchenko committed
283 284 285 286 287 288 289 290 291 292 293 294 295
    // transfer information to the miter
    vPairs = Ssw_TransferSignalPairs( pMiter, pAig1, pAig2, vIds1, vIds2 );
    // create representation of the classes
    pvClasses = Ssw_TransformPairsIntoTempClasses( vPairs, Aig_ManObjNumMax(pMiter) );
    Vec_IntFree( vPairs );
    // if parameters are not given, create them
    if ( pPars == NULL )
        Ssw_ManSetDefaultParams( pPars = &Pars );
    // start the induction manager
    p = Ssw_ManCreate( pMiter, pPars );
    // create equivalence classes using these IDs
    p->ppClasses = Ssw_ClassesPreparePairs( pMiter, pvClasses );
    p->pSml = Ssw_SmlStart( pMiter, 0, p->nFrames + p->pPars->nFramesAddSim, 1 );
296
    Ssw_ClassesSetData( p->ppClasses, p->pSml, (unsigned(*)(void *,Aig_Obj_t *))Ssw_SmlObjHashWord, (int(*)(void *,Aig_Obj_t *))Ssw_SmlObjIsConstWord, (int(*)(void *,Aig_Obj_t *,Aig_Obj_t *))Ssw_SmlObjsAreEqualWord );
Alan Mishchenko committed
297 298 299 300 301 302 303 304 305 306 307 308 309 310
    // perform refinement of classes
    pAigNew = Ssw_SignalCorrespondenceRefine( p );
    // cleanup
    Ssw_FreeTempClasses( pvClasses, Aig_ManObjNumMax(pMiter) );
    Ssw_ManStop( p );
    Aig_ManStop( pMiter );
    return pAigNew;
}

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

  Synopsis    [Runs inductive SEC for the miter of two AIGs with node pairs defined.]

  Description []
311

Alan Mishchenko committed
312 313 314 315 316 317 318 319 320 321 322
  SideEffects []

  SeeAlso     []

***********************************************************************/
Aig_Man_t * Ssw_SignalCorrespondeceTestPairs( Aig_Man_t * pAig )
{
    Aig_Man_t * pAigNew, * pAigRes;
    Ssw_Pars_t Pars, * pPars = &Pars;
    Vec_Int_t * vIds1, * vIds2;
    Aig_Obj_t * pObj, * pRepr;
323
    int RetValue, i;
324
    abctime clk = Abc_Clock();
Alan Mishchenko committed
325 326 327 328 329 330 331 332
    Ssw_ManSetDefaultParams( pPars );
    pPars->fVerbose = 1;
    pAigNew = Ssw_SignalCorrespondence( pAig, pPars );
    // record pairs of equivalent nodes
    vIds1 = Vec_IntAlloc( Aig_ManObjNumMax(pAig) );
    vIds2 = Vec_IntAlloc( Aig_ManObjNumMax(pAig) );
    Aig_ManForEachObj( pAig, pObj, i )
    {
333
        pRepr = Aig_Regular((Aig_Obj_t *)pObj->pData);
Alan Mishchenko committed
334 335 336 337 338 339
        if ( pRepr == NULL )
            continue;
        if ( Aig_ManObj(pAigNew, pRepr->Id) == NULL )
            continue;
/*
        if ( Aig_ObjIsNode(pObj) )
340
            Abc_Print( 1, "n " );
Alan Mishchenko committed
341
        else if ( Saig_ObjIsPi(pAig, pObj) )
342
            Abc_Print( 1, "pi " );
Alan Mishchenko committed
343
        else if ( Saig_ObjIsLo(pAig, pObj) )
344
            Abc_Print( 1, "lo " );
Alan Mishchenko committed
345 346 347 348
*/
        Vec_IntPush( vIds1, Aig_ObjId(pObj) );
        Vec_IntPush( vIds2, Aig_ObjId(pRepr) );
    }
349
    Abc_Print( 1, "Recorded %d pairs (before: %d  after: %d).\n", Vec_IntSize(vIds1), Aig_ManObjNumMax(pAig), Aig_ManObjNumMax(pAigNew) );
Alan Mishchenko committed
350 351 352 353 354 355 356
    // try the new AIGs
    pAigRes = Ssw_SignalCorrespondenceWithPairs( pAig, pAigNew, vIds1, vIds2, pPars );
    Vec_IntFree( vIds1 );
    Vec_IntFree( vIds2 );
    // report the results
    RetValue = Ssw_MiterStatus( pAigRes, 1 );
    if ( RetValue == 1 )
357
        Abc_Print( 1, "Verification successful.  " );
Alan Mishchenko committed
358
    else if ( RetValue == 0 )
359
        Abc_Print( 1, "Verification failed with the counter-example.  " );
Alan Mishchenko committed
360
    else
361
        Abc_Print( 1, "Verification UNDECIDED. Remaining registers %d (total %d).  ",
Alan Mishchenko committed
362
            Aig_ManRegNum(pAigRes), Aig_ManRegNum(pAig) + Aig_ManRegNum(pAigNew) );
363
    ABC_PRT( "Time", Abc_Clock() - clk );
Alan Mishchenko committed
364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382
    // cleanup
    Aig_ManStop( pAigNew );
    return pAigRes;
}

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

  Synopsis    [Runs inductive SEC for the miter of two AIGs with node pairs defined.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Ssw_SecWithPairs( Aig_Man_t * pAig1, Aig_Man_t * pAig2, Vec_Int_t * vIds1, Vec_Int_t * vIds2, Ssw_Pars_t * pPars )
{
    Aig_Man_t * pAigRes;
383
    int RetValue;
384
    abctime clk = Abc_Clock();
Alan Mishchenko committed
385 386
    assert( vIds1 != NULL && vIds2 != NULL );
    // try the new AIGs
387
    Abc_Print( 1, "Performing specialized verification with node pairs.\n" );
Alan Mishchenko committed
388 389 390 391
    pAigRes = Ssw_SignalCorrespondenceWithPairs( pAig1, pAig2, vIds1, vIds2, pPars );
    // report the results
    RetValue = Ssw_MiterStatus( pAigRes, 1 );
    if ( RetValue == 1 )
392
        Abc_Print( 1, "Verification successful.  " );
Alan Mishchenko committed
393
    else if ( RetValue == 0 )
394
        Abc_Print( 1, "Verification failed with a counter-example.  " );
Alan Mishchenko committed
395
    else
396
        Abc_Print( 1, "Verification UNDECIDED. The number of remaining regs = %d (total = %d).  ",
Alan Mishchenko committed
397
            Aig_ManRegNum(pAigRes), Aig_ManRegNum(pAig1) + Aig_ManRegNum(pAig2) );
398
    ABC_PRT( "Time", Abc_Clock() - clk );
Alan Mishchenko committed
399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417
    // cleanup
    Aig_ManStop( pAigRes );
    return RetValue;
}

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

  Synopsis    [Runs inductive SEC for the miter of two AIGs.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Ssw_SecGeneral( Aig_Man_t * pAig1, Aig_Man_t * pAig2, Ssw_Pars_t * pPars )
{
    Aig_Man_t * pAigRes, * pMiter;
418
    int RetValue;
419
    abctime clk = Abc_Clock();
Alan Mishchenko committed
420
    // try the new AIGs
421
    Abc_Print( 1, "Performing general verification without node pairs.\n" );
Alan Mishchenko committed
422
    pMiter = Saig_ManCreateMiter( pAig1, pAig2, 0 );
Alan Mishchenko committed
423
    Aig_ManCleanup( pMiter );
Alan Mishchenko committed
424 425 426 427 428
    pAigRes = Ssw_SignalCorrespondence( pMiter, pPars );
    Aig_ManStop( pMiter );
    // report the results
    RetValue = Ssw_MiterStatus( pAigRes, 1 );
    if ( RetValue == 1 )
429
        Abc_Print( 1, "Verification successful.  " );
Alan Mishchenko committed
430
    else if ( RetValue == 0 )
431
        Abc_Print( 1, "Verification failed with a counter-example.  " );
Alan Mishchenko committed
432
    else
433
        Abc_Print( 1, "Verification UNDECIDED. The number of remaining regs = %d (total = %d).  ",
Alan Mishchenko committed
434
            Aig_ManRegNum(pAigRes), Aig_ManRegNum(pAig1) + Aig_ManRegNum(pAig2) );
435
    ABC_PRT( "Time", Abc_Clock() - clk );
Alan Mishchenko committed
436 437 438 439 440
    // cleanup
    Aig_ManStop( pAigRes );
    return RetValue;
}

Alan Mishchenko committed
441 442 443 444 445 446 447 448 449 450 451 452 453 454
/**Function*************************************************************

  Synopsis    [Runs inductive SEC for the miter of two AIGs.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Ssw_SecGeneralMiter( Aig_Man_t * pMiter, Ssw_Pars_t * pPars )
{
    Aig_Man_t * pAigRes;
455
    int RetValue;
456
    abctime clk = Abc_Clock();
Alan Mishchenko committed
457
    // try the new AIGs
458
//    Abc_Print( 1, "Performing general verification without node pairs.\n" );
Alan Mishchenko committed
459 460 461 462
    pAigRes = Ssw_SignalCorrespondence( pMiter, pPars );
    // report the results
    RetValue = Ssw_MiterStatus( pAigRes, 1 );
    if ( RetValue == 1 )
463
        Abc_Print( 1, "Verification successful.  " );
Alan Mishchenko committed
464
    else if ( RetValue == 0 )
465
        Abc_Print( 1, "Verification failed with a counter-example.  " );
Alan Mishchenko committed
466
    else
467
        Abc_Print( 1, "Verification UNDECIDED. The number of remaining regs = %d (total = %d).  ",
Alan Mishchenko committed
468
            Aig_ManRegNum(pAigRes), Aig_ManRegNum(pMiter) );
469
    ABC_PRT( "Time", Abc_Clock() - clk );
Alan Mishchenko committed
470 471 472 473 474
    // cleanup
    Aig_ManStop( pAigRes );
    return RetValue;
}

Alan Mishchenko committed
475 476 477 478 479
////////////////////////////////////////////////////////////////////////
///                       END OF FILE                                ///
////////////////////////////////////////////////////////////////////////


480
ABC_NAMESPACE_IMPL_END