bmcBmc.c 11.2 KB
Newer Older
Alan Mishchenko committed
1 2
/**CFile****************************************************************

3
  FileName    [bmcBmc.c]
Alan Mishchenko committed
4 5 6

  SystemName  [ABC: Logic synthesis and verification system.]

7
  PackageName [SAT-based bounded model checking.]
Alan Mishchenko committed
8 9 10 11 12 13 14 15 16

  Synopsis    [Simple BMC package.]

  Author      [Alan Mishchenko]
  
  Affiliation [UC Berkeley]

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

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

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

21 22 23
#include "proof/fra/fra.h"
#include "sat/cnf/cnf.h"
#include "sat/bsat/satStore.h"
24
#include "bmc.h"
25 26

ABC_NAMESPACE_IMPL_START
Alan Mishchenko committed
27 28 29 30 31 32 33 34 35

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

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

Alan Mishchenko committed
36 37
/**Function*************************************************************

38
  Synopsis    [Create timeframes of the manager for BMC.]
Alan Mishchenko committed
39

40 41
  Description [The resulting manager is combinational. POs correspond to \
  the property outputs in each time-frame.]
Alan Mishchenko committed
42 43 44 45 46 47
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
48
Aig_Man_t * Saig_ManFramesBmc( Aig_Man_t * pAig, int nFrames )
Alan Mishchenko committed
49
{
50 51 52 53 54 55 56 57
    Aig_Man_t * pFrames;
    Aig_Obj_t * pObj, * pObjLi, * pObjLo;
    int i, f;
    assert( Saig_ManRegNum(pAig) > 0 );
    pFrames = Aig_ManStart( Aig_ManNodeNum(pAig) * nFrames );
    // map the constant node
    Aig_ManConst1(pAig)->pData = Aig_ManConst1( pFrames );
    // create variables for register outputs
Alan Mishchenko committed
58
    Saig_ManForEachLo( pAig, pObj, i )
59 60 61
        pObj->pData = Aig_ManConst0( pFrames );
    // add timeframes
    for ( f = 0; f < nFrames; f++ )
Alan Mishchenko committed
62
    {
63 64
        // create PI nodes for this frame
        Saig_ManForEachPi( pAig, pObj, i )
65
            pObj->pData = Aig_ObjCreateCi( pFrames );
66 67 68 69 70
        // add internal nodes of this frame
        Aig_ManForEachNode( pAig, pObj, i )
            pObj->pData = Aig_And( pFrames, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
        // create POs for this frame
        Saig_ManForEachPo( pAig, pObj, i )
71
            Aig_ObjCreateCo( pFrames, Aig_ObjChild0Copy(pObj) );
72 73 74 75 76 77 78 79
        if ( f == nFrames - 1 )
            break;
        // save register inputs
        Saig_ManForEachLi( pAig, pObj, i )
            pObj->pData = Aig_ObjChild0Copy(pObj);
        // transfer to register outputs
        Saig_ManForEachLiLo(  pAig, pObjLi, pObjLo, i )
            pObjLo->pData = pObjLi->pData;
Alan Mishchenko committed
80
    }
81 82
    Aig_ManCleanup( pFrames );
    return pFrames;
Alan Mishchenko committed
83 84 85 86
}

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

87
  Synopsis    [Returns the number of internal nodes that are not counted yet.]
Alan Mishchenko committed
88 89 90 91 92 93 94 95

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
96
int Saig_ManFramesCount_rec( Aig_Man_t * p, Aig_Obj_t * pObj )
Alan Mishchenko committed
97
{
98 99 100 101 102 103 104
    if ( !Aig_ObjIsNode(pObj) )
        return 0;
    if ( Aig_ObjIsTravIdCurrent(p, pObj) )
        return 0;
    Aig_ObjSetTravIdCurrent(p, pObj);
    return 1 + Saig_ManFramesCount_rec( p, Aig_ObjFanin0(pObj) ) + 
        Saig_ManFramesCount_rec( p, Aig_ObjFanin1(pObj) );
Alan Mishchenko committed
105 106 107 108
}

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

109
  Synopsis    [Create timeframes of the manager for BMC.]
Alan Mishchenko committed
110

111 112 113 114
  Description [The resulting manager is combinational. POs correspond to 
  the property outputs in each time-frame.
  The unrolling is stopped as soon as the number of nodes in the frames
  exceeds the given maximum size.]
Alan Mishchenko committed
115 116 117 118 119 120
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
121
Aig_Man_t * Saig_ManFramesBmcLimit( Aig_Man_t * pAig, int nFrames, int nSizeMax )
Alan Mishchenko committed
122
{
123 124 125 126 127 128 129 130 131 132 133 134 135 136
    Aig_Man_t * pFrames;
    Aig_Obj_t * pObj, * pObjLi, * pObjLo, * pObjPo;
    int i, f, Counter = 0;
    assert( Saig_ManRegNum(pAig) > 0 );
    pFrames = Aig_ManStart( nSizeMax );
    Aig_ManIncrementTravId( pFrames );
    // map the constant node
    Aig_ManConst1(pAig)->pData = Aig_ManConst1( pFrames );
    // create variables for register outputs
    Saig_ManForEachLo( pAig, pObj, i )
        pObj->pData = Aig_ManConst0( pFrames );
    // add timeframes
    Counter = 0;
    for ( f = 0; f < nFrames; f++ )
Alan Mishchenko committed
137
    {
138 139
        // create PI nodes for this frame
        Saig_ManForEachPi( pAig, pObj, i )
140
            pObj->pData = Aig_ObjCreateCi( pFrames );
141 142 143 144 145
        // add internal nodes of this frame
        Aig_ManForEachNode( pAig, pObj, i )
            pObj->pData = Aig_And( pFrames, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
        // create POs for this frame
        Saig_ManForEachPo( pAig, pObj, i )
Alan Mishchenko committed
146
        {
147
            pObjPo = Aig_ObjCreateCo( pFrames, Aig_ObjChild0Copy(pObj) );
148
            Counter += Saig_ManFramesCount_rec( pFrames, Aig_ObjFanin0(pObjPo) );
Alan Mishchenko committed
149
        }
150
        if ( Counter >= nSizeMax )
Alan Mishchenko committed
151
        {
152 153
            Aig_ManCleanup( pFrames );
            return pFrames;
Alan Mishchenko committed
154
        }
155
        if ( f == nFrames - 1 )
Alan Mishchenko committed
156
            break;
157 158 159 160 161 162
        // save register inputs
        Saig_ManForEachLi( pAig, pObj, i )
            pObj->pData = Aig_ObjChild0Copy(pObj);
        // transfer to register outputs
        Saig_ManForEachLiLo(  pAig, pObjLi, pObjLo, i )
            pObjLo->pData = pObjLi->pData;
Alan Mishchenko committed
163
    }
164 165
    Aig_ManCleanup( pFrames );
    return pFrames;
Alan Mishchenko committed
166 167
}

168
ABC_NAMESPACE_IMPL_END
Alan Mishchenko committed
169

170
#include "misc/util/utilMem.h"
Alan Mishchenko committed
171

172
ABC_NAMESPACE_IMPL_START
Alan Mishchenko committed
173

174
 
Alan Mishchenko committed
175 176
/**Function*************************************************************

177
  Synopsis    [Performs BMC for the given AIG.]
Alan Mishchenko committed
178 179 180 181 182 183 184 185

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
186
int Saig_ManBmcSimple( Aig_Man_t * pAig, int nFrames, int nSizeMax, int nConfLimit, int fRewrite, int fVerbose, int * piFrame, int nCofFanLit )
Alan Mishchenko committed
187
{
188 189 190 191
    extern Aig_Man_t * Gia_ManCofactorAig( Aig_Man_t * p, int nFrames, int nCofFanLit );
    sat_solver * pSat;
    Cnf_Dat_t * pCnf;
    Aig_Man_t * pFrames, * pAigTemp;
Alan Mishchenko committed
192
    Aig_Obj_t * pObj;
193
    int status, Lit, i, RetValue = -1;
194
    abctime clk;
195 196

    // derive the timeframes
197
    clk = Abc_Clock();
198
    if ( nCofFanLit )
Alan Mishchenko committed
199
    {
200 201 202
        pFrames = Gia_ManCofactorAig( pAig, nFrames, nCofFanLit );
        if ( pFrames == NULL )
            return -1;
Alan Mishchenko committed
203
    }
204
    else if ( nSizeMax > 0 )
Alan Mishchenko committed
205
    {
206
        pFrames = Saig_ManFramesBmcLimit( pAig, nFrames, nSizeMax );
207
        nFrames = Aig_ManCoNum(pFrames) / Saig_ManPoNum(pAig) + ((Aig_ManCoNum(pFrames) % Saig_ManPoNum(pAig)) > 0);
Alan Mishchenko committed
208
    }
209 210 211 212
    else
        pFrames = Saig_ManFramesBmc( pAig, nFrames );
    if ( piFrame )
        *piFrame = nFrames;
Alan Mishchenko committed
213 214
    if ( fVerbose )
    {
215
        printf( "Running \"bmc\". AIG:  PI/PO/Reg = %d/%d/%d.  Node = %6d. Lev = %5d.\n", 
Alan Mishchenko committed
216 217
            Saig_ManPiNum(pAig), Saig_ManPoNum(pAig), Saig_ManRegNum(pAig),
            Aig_ManNodeNum(pAig), Aig_ManLevelNum(pAig) );
218
        printf( "Time-frames (%d):  PI/PO = %d/%d.  Node = %6d. Lev = %5d.  ", 
219
            nFrames, Aig_ManCiNum(pFrames), Aig_ManCoNum(pFrames), 
220
            Aig_ManNodeNum(pFrames), Aig_ManLevelNum(pFrames) );
221
        ABC_PRT( "Time", Abc_Clock() - clk );
222 223 224 225
        fflush( stdout );
    }
    // rewrite the timeframes
    if ( fRewrite )
Alan Mishchenko committed
226
    {
227
        clk = Abc_Clock();
228 229 230
//        pFrames = Dar_ManBalance( pAigTemp = pFrames, 0 );
        pFrames = Dar_ManRwsat( pAigTemp = pFrames, 1, 0 );
        Aig_ManStop( pAigTemp );
Alan Mishchenko committed
231 232
        if ( fVerbose )
        {
233 234
            printf( "Time-frames after rewriting:  Node = %6d. Lev = %5d.  ", 
                Aig_ManNodeNum(pFrames), Aig_ManLevelNum(pFrames) );
235
            ABC_PRT( "Time", Abc_Clock() - clk );
236
            fflush( stdout );
Alan Mishchenko committed
237
        }
Alan Mishchenko committed
238
    }
239
    // create the SAT solver
240
    clk = Abc_Clock();
241
    pCnf = Cnf_Derive( pFrames, Aig_ManCoNum(pFrames) );  
242 243 244 245 246
//if ( s_fInterrupt )
//return -1;
    pSat = sat_solver_new();
    sat_solver_setnvars( pSat, pCnf->nVars );
    for ( i = 0; i < pCnf->nClauses; i++ )
Alan Mishchenko committed
247
    {
248 249
        if ( !sat_solver_addclause( pSat, pCnf->pClauses[i], pCnf->pClauses[i+1] ) )
            assert( 0 );
Alan Mishchenko committed
250
    }
251
    if ( fVerbose )
Alan Mishchenko committed
252
    {
253
        printf( "CNF: Variables = %6d. Clauses = %7d. Literals = %8d. ", pCnf->nVars, pCnf->nClauses, pCnf->nLiterals );
254
        ABC_PRT( "Time", Abc_Clock() - clk );
255
        fflush( stdout );
Alan Mishchenko committed
256
    }
257 258
    status = sat_solver_simplify(pSat);
    if ( status == 0 )
Alan Mishchenko committed
259
    {
260 261 262 263 264
        if ( fVerbose )
        {
            printf( "The BMC problem is trivially UNSAT\n" );
            fflush( stdout );
        }
Alan Mishchenko committed
265
    }
266
    else
Alan Mishchenko committed
267
    {
268
        abctime clkPart = Abc_Clock();
269
        Aig_ManForEachCo( pFrames, pObj, i )
270 271 272 273 274 275 276 277 278
        {
//if ( s_fInterrupt )
//return -1;
            Lit = toLitCond( pCnf->pVarNums[pObj->Id], 0 );
            if ( fVerbose )
            {
                printf( "Solving output %2d of frame %3d ... \r", 
                    i % Saig_ManPoNum(pAig), i / Saig_ManPoNum(pAig) );
            }
279
            clk = Abc_Clock();
280 281 282 283 284 285
            status = sat_solver_solve( pSat, &Lit, &Lit + 1, (ABC_INT64_T)nConfLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 );
            if ( fVerbose && (i % Saig_ManPoNum(pAig) == Saig_ManPoNum(pAig) - 1) )
            {
                printf( "Solved %2d outputs of frame %3d.  ", 
                    Saig_ManPoNum(pAig), i / Saig_ManPoNum(pAig) );
                printf( "Conf =%8.0f. Imp =%11.0f. ", (double)pSat->stats.conflicts, (double)pSat->stats.propagations );
286 287
                ABC_PRT( "T", Abc_Clock() - clkPart );
                clkPart = Abc_Clock();
288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306
                fflush( stdout );
            }
            if ( status == l_False )
            {
/*
                Lit = lit_neg( Lit );
                RetValue = sat_solver_addclause( pSat, &Lit, &Lit + 1 );
                assert( RetValue );
                if ( pSat->qtail != pSat->qhead )
                {
                    RetValue = sat_solver_simplify(pSat);
                    assert( RetValue );
                }
*/
            }
            else if ( status == l_True )
            {
                Vec_Int_t * vCiIds = Cnf_DataCollectPiSatNums( pCnf, pFrames );
                int * pModel = Sat_SolverGetModel( pSat, vCiIds->pArray, vCiIds->nSize );
307
                pModel[Aig_ManCiNum(pFrames)] = pObj->Id;
308
                pAig->pSeqModel = Fra_SmlCopyCounterExample( pAig, pFrames, pModel );
309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324
                ABC_FREE( pModel );
                Vec_IntFree( vCiIds );

                if ( piFrame )
                    *piFrame = i / Saig_ManPoNum(pAig);
                RetValue = 0;
                break;
            }
            else
            {
                if ( piFrame )
                    *piFrame = i / Saig_ManPoNum(pAig);
                RetValue = -1;
                break;
            }
        }
Alan Mishchenko committed
325
    }
326 327 328 329
    sat_solver_delete( pSat );
    Cnf_DataFree( pCnf );
    Aig_ManStop( pFrames );
    return RetValue;
Alan Mishchenko committed
330 331 332 333 334 335 336
}

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


337 338
ABC_NAMESPACE_IMPL_END