diff options
| author | Alan Mishchenko <alanmi@berkeley.edu> | 2008-10-04 08:01:00 -0700 | 
|---|---|---|
| committer | Alan Mishchenko <alanmi@berkeley.edu> | 2008-10-04 08:01:00 -0700 | 
| commit | eb75697fe00a8668f74b3c710dcbf5658e07d167 (patch) | |
| tree | 05b78ce8fb95fcc37b013f5bfd9da0dd3544b42a | |
| parent | 689cbe904e3a28d7502feb9931b748764f947aaf (diff) | |
| download | abc-eb75697fe00a8668f74b3c710dcbf5658e07d167.tar.gz abc-eb75697fe00a8668f74b3c710dcbf5658e07d167.tar.bz2 abc-eb75697fe00a8668f74b3c710dcbf5658e07d167.zip  | |
Version abc81004
39 files changed, 10024 insertions, 130 deletions
@@ -42,7 +42,7 @@ RSC=rc.exe  # PROP Ignore_Export_Lib 0  # PROP Target_Dir ""  # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /W3 /GX /O2 /I "src/base/abc" /I "src/base/abci" /I "src/base/cmd" /I "src/base/io" /I "src/base/main" /I "src/base/ver" /I "src/bdd/cudd" /I "src/bdd/dsd" /I "src/bdd/epd" /I "src/bdd/mtr" /I "src/bdd/parse" /I "src/bdd/reo" /I "src/bdd/cas" /I "src/map/fpga" /I "src/map/mapper" /I "src/map/mio" /I "src/map/super" /I "src/map/if" /I "src/map/pcm" /I "src/map/ply" /I "src/misc/extra" /I "src/misc/mvc" /I "src/misc/st" /I "src/misc/util" /I "src/misc/espresso" /I "src/misc/nm" /I "src/misc/vec" /I "src/misc/hash" /I "src/misc/bzlib" /I "src/misc/zlib" /I "src/opt/cut" /I "src/opt/dec" /I "src/opt/fxu" /I "src/opt/rwr" /I "src/opt/sim" /I "src/opt/ret" /I "src/opt/res" /I "src/opt/lpk" /I "src/sat/bsat" /I "src/sat/csat" /I "src/sat/msat" /I "src/sat/fraig" /I "src/sat/nsat" /I "src/sat/psat" /I "src/aig/ivy" /I "src/aig/hop" /I "src/aig/rwt" /I "src/aig/deco" /I "src/aig/mem" /I "src/aig/dar" /I "src/aig/fra" /I "src/aig/cnf" /I "src/aig/csw" /I "src/aig/ioa" /I "src/aig/aig" /I "src/aig/kit" /I "src/aig/bdc" /I "src/aig/bar" /I "src/aig/ntl" /I "src/aig/nwk" /I "src/aig/tim" /I "src/opt/mfs" /I "src/aig/mfx" /I "src/aig/saig" /I "src/aig/bbr" /I "src/aig/int" /I "src/aig/dch" /I "src/aig/ssw" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /D ABC_DLL=DLLEXPORT /D "_CRT_SECURE_NO_DEPRECATE" /D "ABC_USE_LIBRARIES" /FR /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "src/base/abc" /I "src/base/abci" /I "src/base/cmd" /I "src/base/io" /I "src/base/main" /I "src/base/ver" /I "src/bdd/cudd" /I "src/bdd/dsd" /I "src/bdd/epd" /I "src/bdd/mtr" /I "src/bdd/parse" /I "src/bdd/reo" /I "src/bdd/cas" /I "src/map/fpga" /I "src/map/mapper" /I "src/map/mio" /I "src/map/super" /I "src/map/if" /I "src/map/pcm" /I "src/map/ply" /I "src/misc/extra" /I "src/misc/mvc" /I "src/misc/st" /I "src/misc/util" /I "src/misc/espresso" /I "src/misc/nm" /I "src/misc/vec" /I "src/misc/hash" /I "src/misc/bzlib" /I "src/misc/zlib" /I "src/opt/cut" /I "src/opt/dec" /I "src/opt/fxu" /I "src/opt/rwr" /I "src/opt/sim" /I "src/opt/ret" /I "src/opt/res" /I "src/opt/lpk" /I "src/sat/bsat" /I "src/sat/csat" /I "src/sat/msat" /I "src/sat/fraig" /I "src/sat/nsat" /I "src/sat/psat" /I "src/aig/ivy" /I "src/aig/hop" /I "src/aig/rwt" /I "src/aig/deco" /I "src/aig/mem" /I "src/aig/dar" /I "src/aig/fra" /I "src/aig/cnf" /I "src/aig/csw" /I "src/aig/ioa" /I "src/aig/aig" /I "src/aig/kit" /I "src/aig/bdc" /I "src/aig/bar" /I "src/aig/ntl" /I "src/aig/nwk" /I "src/aig/tim" /I "src/opt/mfs" /I "src/aig/mfx" /I "src/aig/saig" /I "src/aig/bbr" /I "src/aig/int" /I "src/aig/dch" /I "src/aig/ssw" /I "src/sat/lsat" /I "src/aig/cec" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /D ABC_DLL=DLLEXPORT /D "_CRT_SECURE_NO_DEPRECATE" /D "ABC_USE_LIBRARIES" /FR /YX /FD /c  # ADD BASE RSC /l 0x409 /d "NDEBUG"  # ADD RSC /l 0x409 /d "NDEBUG"  BSC32=bscmake.exe @@ -66,7 +66,7 @@ LINK32=link.exe  # PROP Ignore_Export_Lib 0  # PROP Target_Dir ""  # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "src/base/abc" /I "src/base/abci" /I "src/base/cmd" /I "src/base/io" /I "src/base/main" /I "src/base/ver" /I "src/bdd/cudd" /I "src/bdd/dsd" /I "src/bdd/epd" /I "src/bdd/mtr" /I "src/bdd/parse" /I "src/bdd/reo" /I "src/bdd/cas" /I "src/map/fpga" /I "src/map/mapper" /I "src/map/mio" /I "src/map/super" /I "src/map/if" /I "src/map/pcm" /I "src/map/ply" /I "src/misc/extra" /I "src/misc/mvc" /I "src/misc/st" /I "src/misc/util" /I "src/misc/espresso" /I "src/misc/nm" /I "src/misc/vec" /I "src/misc/hash" /I "src/misc/bzlib" /I "src/misc/zlib" /I "src/opt/cut" /I "src/opt/dec" /I "src/opt/fxu" /I "src/opt/rwr" /I "src/opt/sim" /I "src/opt/ret" /I "src/opt/res" /I "src/opt/lpk" /I "src/sat/bsat" /I "src/sat/csat" /I "src/sat/msat" /I "src/sat/fraig" /I "src/sat/nsat" /I "src/sat/psat" /I "src/aig/ivy" /I "src/aig/hop" /I "src/aig/rwt" /I "src/aig/deco" /I "src/aig/mem" /I "src/aig/dar" /I "src/aig/fra" /I "src/aig/cnf" /I "src/aig/csw" /I "src/aig/ioa" /I "src/aig/aig" /I "src/aig/kit" /I "src/aig/bdc" /I "src/aig/bar" /I "src/aig/ntl" /I "src/aig/nwk" /I "src/aig/tim" /I "src/opt/mfs" /I "src/aig/mfx" /I "src/aig/saig" /I "src/aig/bbr" /I "src/aig/int" /I "src/aig/dch" /I "src/aig/ssw" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /D ABC_DLL=DLLEXPORT /D "_CRT_SECURE_NO_DEPRECATE" /D "ABC_USE_LIBRARIES" /FR /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "src/base/abc" /I "src/base/abci" /I "src/base/cmd" /I "src/base/io" /I "src/base/main" /I "src/base/ver" /I "src/bdd/cudd" /I "src/bdd/dsd" /I "src/bdd/epd" /I "src/bdd/mtr" /I "src/bdd/parse" /I "src/bdd/reo" /I "src/bdd/cas" /I "src/map/fpga" /I "src/map/mapper" /I "src/map/mio" /I "src/map/super" /I "src/map/if" /I "src/map/pcm" /I "src/map/ply" /I "src/misc/extra" /I "src/misc/mvc" /I "src/misc/st" /I "src/misc/util" /I "src/misc/espresso" /I "src/misc/nm" /I "src/misc/vec" /I "src/misc/hash" /I "src/misc/bzlib" /I "src/misc/zlib" /I "src/opt/cut" /I "src/opt/dec" /I "src/opt/fxu" /I "src/opt/rwr" /I "src/opt/sim" /I "src/opt/ret" /I "src/opt/res" /I "src/opt/lpk" /I "src/sat/bsat" /I "src/sat/csat" /I "src/sat/msat" /I "src/sat/fraig" /I "src/sat/nsat" /I "src/sat/psat" /I "src/aig/ivy" /I "src/aig/hop" /I "src/aig/rwt" /I "src/aig/deco" /I "src/aig/mem" /I "src/aig/dar" /I "src/aig/fra" /I "src/aig/cnf" /I "src/aig/csw" /I "src/aig/ioa" /I "src/aig/aig" /I "src/aig/kit" /I "src/aig/bdc" /I "src/aig/bar" /I "src/aig/ntl" /I "src/aig/nwk" /I "src/aig/tim" /I "src/opt/mfs" /I "src/aig/mfx" /I "src/aig/saig" /I "src/aig/bbr" /I "src/aig/int" /I "src/aig/dch" /I "src/aig/ssw" /I "src/sat/lsat" /I "src/aig/cec" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "__STDC__" /D ABC_DLL=DLLEXPORT /D "_CRT_SECURE_NO_DEPRECATE" /D "ABC_USE_LIBRARIES" /FR /YX /FD /GZ /c  # SUBTRACT CPP /X  # ADD BASE RSC /l 0x409 /d "_DEBUG"  # ADD RSC /l 0x409 /d "_DEBUG" @@ -1261,6 +1261,14 @@ SOURCE=.\src\sat\psat\m114p_types.h  # PROP Default_Filter ""  # End Group +# Begin Group "lsat" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\src\sat\lsat\solver.h +# End Source File +# End Group  # End Group  # Begin Group "opt" @@ -3501,6 +3509,10 @@ SOURCE=.\src\aig\ssw\sswSweep.c  SOURCE=.\src\aig\ssw\sswUnique.c  # End Source File  # End Group +# Begin Group "cec" + +# PROP Default_Filter "" +# End Group  # End Group  # End Group  # Begin Group "Header Files" diff --git a/src/aig/aig/aig.h b/src/aig/aig/aig.h index 503985b7..7480df78 100644 --- a/src/aig/aig/aig.h +++ b/src/aig/aig/aig.h @@ -194,6 +194,17 @@ struct Aig_ManCut_t_      unsigned *      puTemp[4];       // used for the truth table computation  }; +#ifdef WIN32 +#define DLLEXPORT __declspec(dllexport) +#define DLLIMPORT __declspec(dllimport) +#else  /* defined(WIN32) */ +#define DLLIMPORT +#endif /* defined(WIN32) */ + +#ifndef ABC_DLL +#define ABC_DLL DLLIMPORT +#endif +  static inline Aig_Cut_t *  Aig_ObjCuts( Aig_ManCut_t * p, Aig_Obj_t * pObj )                         { return p->pCuts[pObj->Id];  }  static inline void         Aig_ObjSetCuts( Aig_ManCut_t * p, Aig_Obj_t * pObj, Aig_Cut_t * pCuts )   { p->pCuts[pObj->Id] = pCuts; } @@ -452,7 +463,7 @@ static inline int     Aig_ObjFanoutNext( Aig_Man_t * p, int iFan )   { assert(iF  ////////////////////////////////////////////////////////////////////////  /*=== aigCheck.c ========================================================*/ -extern int             Aig_ManCheck( Aig_Man_t * p ); +extern ABC_DLL int     Aig_ManCheck( Aig_Man_t * p );  extern void            Aig_ManCheckMarkA( Aig_Man_t * p );  extern void            Aig_ManCheckPhase( Aig_Man_t * p );  /*=== aigCuts.c ========================================================*/ @@ -502,7 +513,7 @@ extern Aig_Man_t *     Aig_ManFrames( Aig_Man_t * pAig, int nFs, int fInit, int  extern Aig_Man_t *     Aig_ManStart( int nNodesMax );  extern Aig_Man_t *     Aig_ManStartFrom( Aig_Man_t * p );  extern Aig_Man_t *     Aig_ManExtractMiter( Aig_Man_t * p, Aig_Obj_t * pNode1, Aig_Obj_t * pNode2 ); -extern void            Aig_ManStop( Aig_Man_t * p ); +extern ABC_DLL void    Aig_ManStop( Aig_Man_t * p );  extern int             Aig_ManCleanup( Aig_Man_t * p );  extern int             Aig_ManAntiCleanup( Aig_Man_t * p );  extern int             Aig_ManPiCleanup( Aig_Man_t * p ); diff --git a/src/aig/cec/cecSat.c b/src/aig/cec/cecSat.c new file mode 100644 index 00000000..37f63f05 --- /dev/null +++ b/src/aig/cec/cecSat.c @@ -0,0 +1,284 @@ +/**CFile**************************************************************** + +  FileName    [cecSat.c] + +  SystemName  [ABC: Logic synthesis and verification system.] + +  PackageName [Combinational equivalence checking.] + +  Synopsis    [Backend calling the SAT solver.] + +  Author      [Alan Mishchenko] +   +  Affiliation [UC Berkeley] + +  Date        [Ver. 1.0. Started - June 30, 2007.] + +  Revision    [$Id: cecSat.c,v 1.00 2007/06/30 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "aig.h" +#include "cnf.h" +#include "solver.h" + +//////////////////////////////////////////////////////////////////////// +///                        DECLARATIONS                              /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +///                     FUNCTION DEFINITIONS                         /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + +  Synopsis    [Writes CNF into a file.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +solver * Cnf_WriteIntoSolverNew( Cnf_Dat_t * p ) +{ +    solver * pSat; +    int i, status; +    pSat = solver_new(); +    for ( i = 0; i < p->nVars; i++ ) +        solver_newVar( pSat ); +    for ( i = 0; i < p->nClauses; i++ ) +    { +        if ( !solver_addClause( pSat, p->pClauses[i+1]-p->pClauses[i], p->pClauses[i] ) ) +        { +            solver_delete( pSat ); +            return NULL; +        } +    } +    status = solver_simplify(pSat); +    if ( status == 0 ) +    { +        solver_delete( pSat ); +        return NULL; +    } +    return pSat; +} + +/**Function************************************************************* + +  Synopsis    [Adds the OR-clause.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Cnf_DataWriteAndClausesNew( void * p, Cnf_Dat_t * pCnf ) +{ +/* +    sat_solver * pSat = p; +    Aig_Obj_t * pObj; +    int i, Lit; +    Aig_ManForEachPo( pCnf->pMan, pObj, i ) +    { +        Lit = toLitCond( pCnf->pVarNums[pObj->Id], 0 ); +        if ( !sat_solver_addclause( pSat, &Lit, &Lit+1 ) ) +            return 0; +    } +*/ +    return 1; +} + +/**Function************************************************************* + +  Synopsis    [Adds the OR-clause.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Cnf_DataWriteOrClauseNew( solver * pSat, Cnf_Dat_t * pCnf ) +{ +    Aig_Obj_t * pObj; +    int i, * pLits; +    pLits = ALLOC( int, Aig_ManPoNum(pCnf->pMan) ); +    Aig_ManForEachPo( pCnf->pMan, pObj, i ) +        pLits[i] = solver_mkLit_args( pCnf->pVarNums[pObj->Id], 0 ); +    if ( !solver_addClause( pSat, Aig_ManPoNum(pCnf->pMan), pLits ) ) +    { +        free( pLits ); +        return 0; +    } +    free( pLits ); +    return 1; +} + +/**Function************************************************************* + +  Synopsis    [Writes the given clause in a file in DIMACS format.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Sat_SolverPrintStatsNew( FILE * pFile, solver * pSat ) +{ +//    printf( "starts        : %8d\n", solver_num_assigns(pSat) ); +    printf( "vars          : %8d\n", solver_num_vars(pSat) ); +    printf( "clauses       : %8d\n", solver_num_clauses(pSat) ); +    printf( "conflicts     : %8d\n", solver_num_learnts(pSat) ); +} + +/**Function************************************************************* + +  Synopsis    [Returns a counter-example.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int * Sat_SolverGetModelNew( solver * pSat, int * pVars, int nVars ) +{ +    int * pModel; +    int i; +    pModel = ALLOC( int, nVars+1 ); +    for ( i = 0; i < nVars; i++ ) +    { +        assert( pVars[i] >= 0 && pVars[i] < solver_num_vars(pSat) ); +        pModel[i] = (int)(solver_modelValue_Var( pSat, pVars[i] ) == solver_l_True); +    } +    return pModel;     +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Cec_RunSat( Aig_Man_t * pMan, sint64 nConfLimit, sint64 nInsLimit, int fFlipBits, int fAndOuts, int fVerbose ) +{ +    solver * pSat; +    Cnf_Dat_t * pCnf; +    int status, RetValue, clk = clock(); +    Vec_Int_t * vCiIds; + +    assert( Aig_ManRegNum(pMan) == 0 ); +    pMan->pData = NULL; + +    // derive CNF +    pCnf = Cnf_Derive( pMan, Aig_ManPoNum(pMan) ); +//    pCnf = Cnf_DeriveSimple( pMan, Aig_ManPoNum(pMan) ); + +    // convert into SAT solver +    pSat = Cnf_WriteIntoSolverNew( pCnf ); +    if ( pSat == NULL ) +    { +        Cnf_DataFree( pCnf ); +        return 1; +    } + + +    if ( fAndOuts ) +    { +        assert( 0 ); +        // assert each output independently +        if ( !Cnf_DataWriteAndClausesNew( pSat, pCnf ) ) +        { +            solver_delete( pSat ); +            Cnf_DataFree( pCnf ); +            return 1; +        } +    } +    else +    { +        // add the OR clause for the outputs +        if ( !Cnf_DataWriteOrClauseNew( pSat, pCnf ) ) +        { +            solver_delete( pSat ); +            Cnf_DataFree( pCnf ); +            return 1; +        } +    } +    vCiIds = Cnf_DataCollectPiSatNums( pCnf, pMan ); +    Cnf_DataFree( pCnf ); + + +//    printf( "Created SAT problem with %d variable and %d clauses. ", sat_solver_nvars(pSat), sat_solver_nclauses(pSat) ); +//    PRT( "Time", clock() - clk ); + +    // simplify the problem +    clk = clock(); +    status = solver_simplify(pSat); +//    printf( "Simplified the problem to %d variables and %d clauses. ", sat_solver_nvars(pSat), sat_solver_nclauses(pSat) ); +//    PRT( "Time", clock() - clk ); +    if ( status == 0 ) +    { +        Vec_IntFree( vCiIds ); +        solver_delete( pSat ); +//        printf( "The problem is UNSATISFIABLE after simplification.\n" ); +        return 1; +    } + +    // solve the miter +    clk = clock(); +    if ( fVerbose ) +        solver_set_verbosity( pSat, 1 ); +    status = solver_solve( pSat, 0, NULL ); +    if ( status == solver_l_Undef ) +    { +//        printf( "The problem timed out.\n" ); +        RetValue = -1; +    } +    else if ( status == solver_l_True ) +    { +//        printf( "The problem is SATISFIABLE.\n" ); +        RetValue = 0; +    } +    else if ( status == solver_l_False ) +    { +//        printf( "The problem is UNSATISFIABLE.\n" ); +        RetValue = 1; +    } +    else +        assert( 0 ); +//    PRT( "SAT sat_solver time", clock() - clk ); +//    printf( "The number of conflicts = %d.\n", (int)pSat->sat_solver_stats.conflicts ); +  +    // if the problem is SAT, get the counterexample +    if ( status == solver_l_True ) +    { +        pMan->pData = Sat_SolverGetModelNew( pSat, vCiIds->pArray, vCiIds->nSize ); +    } +    // free the sat_solver +    if ( fVerbose ) +        Sat_SolverPrintStatsNew( stdout, pSat ); +//sat_solver_store_write( pSat, "trace.cnf" ); +//sat_solver_store_free( pSat ); +    solver_delete( pSat ); +    Vec_IntFree( vCiIds ); +    return RetValue; +} + + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + diff --git a/src/aig/saig/saig.h b/src/aig/saig/saig.h index c7a40f96..ddae07e0 100644 --- a/src/aig/saig/saig.h +++ b/src/aig/saig/saig.h @@ -94,7 +94,9 @@ extern Aig_Man_t *       Saig_ManReadBlif( char * pFileName );  extern int               Saig_Interpolate( Aig_Man_t * pAig, Inter_ManParams_t * pPars, int * pDepth );  /*=== saigMiter.c ==========================================================*/  extern Aig_Man_t *       Saig_ManCreateMiter( Aig_Man_t * p1, Aig_Man_t * p2, int Oper ); -extern Aig_Man_t *       Saig_ManDupInitZero( Aig_Man_t * p ); +extern Aig_Man_t *       Saig_ManCreateMiterComb( Aig_Man_t * p1, Aig_Man_t * p2, int Oper ); +extern Aig_Man_t *       Saig_ManCreateMiterTwo( Aig_Man_t * pOld, Aig_Man_t * pNew, int nFrames ); +extern int               Saig_ManDemiterSimple( Aig_Man_t * p, Aig_Man_t ** ppAig0, Aig_Man_t ** ppAig1 );  /*=== saigPhase.c ==========================================================*/  extern Aig_Man_t *       Saig_ManPhaseAbstract( Aig_Man_t * p, Vec_Int_t * vInits, int nFrames, int fIgnore, int fPrint, int fVerbose );  /*=== saigRetFwd.c ==========================================================*/ @@ -107,6 +109,8 @@ extern Aig_Man_t *       Saig_ManRetimeMinArea( Aig_Man_t * p, int nMaxIters, in  extern int               Saig_ManRetimeSteps( Aig_Man_t * p, int nSteps, int fForward, int fAddBugs );  /*=== saigScl.c ==========================================================*/  extern void              Saig_ManReportUselessRegisters( Aig_Man_t * pAig ); +/*=== saigSynch.c ==========================================================*/ +extern Aig_Man_t *       Saig_ManDupInitZero( Aig_Man_t * p );  /*=== saigTrans.c ==========================================================*/  extern Aig_Man_t *       Saig_ManTimeframeSimplify( Aig_Man_t * pAig, int nFrames, int nFramesMax, int fInit, int fVerbose ); diff --git a/src/aig/saig/saigMiter.c b/src/aig/saig/saigMiter.c index 5b18db6e..5efcd24d 100644 --- a/src/aig/saig/saigMiter.c +++ b/src/aig/saig/saigMiter.c @@ -30,7 +30,7 @@  /**Function************************************************************* -  Synopsis    [] +  Synopsis    [Creates sequential miter.]    Description [] @@ -39,59 +39,59 @@    SeeAlso     []  ***********************************************************************/ -Aig_Man_t * Saig_ManCreateMiter( Aig_Man_t * p1, Aig_Man_t * p2, int Oper ) +Aig_Man_t * Saig_ManCreateMiter( Aig_Man_t * p0, Aig_Man_t * p1, int Oper )  {      Aig_Man_t * pNew;      Aig_Obj_t * pObj;      int i; -    assert( Saig_ManRegNum(p1) > 0 || Saig_ManRegNum(p2) > 0 ); -    assert( Saig_ManPiNum(p1) == Saig_ManPiNum(p2) ); -    assert( Saig_ManPoNum(p1) == Saig_ManPoNum(p2) ); -    pNew = Aig_ManStart( Aig_ManObjNumMax(p1) + Aig_ManObjNumMax(p2) ); +    assert( Saig_ManRegNum(p0) > 0 || Saig_ManRegNum(p1) > 0 ); +    assert( Saig_ManPiNum(p0) == Saig_ManPiNum(p1) ); +    assert( Saig_ManPoNum(p0) == Saig_ManPoNum(p1) ); +    pNew = Aig_ManStart( Aig_ManObjNumMax(p0) + Aig_ManObjNumMax(p1) );      pNew->pName = Aig_UtilStrsav( "miter" );      // map constant nodes +    Aig_ManConst1(p0)->pData = Aig_ManConst1(pNew);      Aig_ManConst1(p1)->pData = Aig_ManConst1(pNew); -    Aig_ManConst1(p2)->pData = Aig_ManConst1(pNew);      // map primary inputs -    Saig_ManForEachPi( p1, pObj, i ) +    Saig_ManForEachPi( p0, pObj, i )          pObj->pData = Aig_ObjCreatePi( pNew ); -    Saig_ManForEachPi( p2, pObj, i ) +    Saig_ManForEachPi( p1, pObj, i )          pObj->pData = Aig_ManPi( pNew, i );      // map register outputs -    Saig_ManForEachLo( p1, pObj, i ) +    Saig_ManForEachLo( p0, pObj, i )          pObj->pData = Aig_ObjCreatePi( pNew ); -    Saig_ManForEachLo( p2, pObj, i ) +    Saig_ManForEachLo( p1, pObj, i )          pObj->pData = Aig_ObjCreatePi( pNew );      // map internal nodes -    Aig_ManForEachNode( p1, pObj, i ) +    Aig_ManForEachNode( p0, pObj, i )          pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); -    Aig_ManForEachNode( p2, pObj, i ) +    Aig_ManForEachNode( p1, pObj, i )          pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );      // create primary outputs -    Saig_ManForEachPo( p1, pObj, i ) +    Saig_ManForEachPo( p0, pObj, i )      {          if ( Oper == 0 ) // XOR -            pObj = Aig_Exor( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild0Copy(Aig_ManPo(p2,i)) ); -        else if ( Oper == 1 ) // implication is PO(p1) -> PO(p2)  ...  complement is PO(p1) & !PO(p2)  -            pObj = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_Not(Aig_ObjChild0Copy(Aig_ManPo(p2,i))) ); +            pObj = Aig_Exor( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild0Copy(Aig_ManPo(p1,i)) ); +        else if ( Oper == 1 ) // implication is PO(p0) -> PO(p1)  ...  complement is PO(p0) & !PO(p1)  +            pObj = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_Not(Aig_ObjChild0Copy(Aig_ManPo(p1,i))) );          else              assert( 0 );          Aig_ObjCreatePo( pNew, pObj );      }      // create register inputs -    Saig_ManForEachLi( p1, pObj, i ) +    Saig_ManForEachLi( p0, pObj, i )          pObj->pData = Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) ); -    Saig_ManForEachLi( p2, pObj, i ) +    Saig_ManForEachLi( p1, pObj, i )          pObj->pData = Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) );      // cleanup -    Aig_ManSetRegNum( pNew, Saig_ManRegNum(p1) + Saig_ManRegNum(p2) ); +    Aig_ManSetRegNum( pNew, Saig_ManRegNum(p0) + Saig_ManRegNum(p1) );      Aig_ManCleanup( pNew );      return pNew;  }  /**Function************************************************************* -  Synopsis    [Duplicates the AIG to have constant-0 initial state.] +  Synopsis    [Creates combinational miter.]    Description [] @@ -100,30 +100,569 @@ Aig_Man_t * Saig_ManCreateMiter( Aig_Man_t * p1, Aig_Man_t * p2, int Oper )    SeeAlso     []  ***********************************************************************/ -Aig_Man_t * Saig_ManDupInitZero( Aig_Man_t * p ) +Aig_Man_t * Saig_ManCreateMiterComb( Aig_Man_t * p0, Aig_Man_t * p1, int Oper )  {      Aig_Man_t * pNew;      Aig_Obj_t * pObj;      int i; +    assert( Aig_ManPiNum(p0) == Aig_ManPiNum(p1) ); +    assert( Aig_ManPoNum(p0) == Aig_ManPoNum(p1) ); +    pNew = Aig_ManStart( Aig_ManObjNumMax(p0) + Aig_ManObjNumMax(p1) ); +    pNew->pName = Aig_UtilStrsav( "miter" ); +    // map constant nodes +    Aig_ManConst1(p0)->pData = Aig_ManConst1(pNew); +    Aig_ManConst1(p1)->pData = Aig_ManConst1(pNew); +    // map primary inputs and register outputs +    Aig_ManForEachPi( p0, pObj, i ) +        pObj->pData = Aig_ObjCreatePi( pNew ); +    Aig_ManForEachPi( p1, pObj, i ) +        pObj->pData = Aig_ManPi( pNew, i ); +    // map internal nodes +    Aig_ManForEachNode( p0, pObj, i ) +        pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); +    Aig_ManForEachNode( p1, pObj, i ) +        pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); +    // create primary outputs +    Aig_ManForEachPo( p0, pObj, i ) +    { +        if ( Oper == 0 ) // XOR +            pObj = Aig_Exor( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild0Copy(Aig_ManPo(p1,i)) ); +        else if ( Oper == 1 ) // implication is PO(p0) -> PO(p1)  ...  complement is PO(p0) & !PO(p1)  +            pObj = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_Not(Aig_ObjChild0Copy(Aig_ManPo(p1,i))) ); +        else +            assert( 0 ); +        Aig_ObjCreatePo( pNew, pObj ); +    } +    // cleanup +    Aig_ManSetRegNum( pNew, 0 ); +    Aig_ManCleanup( pNew ); +    return pNew; +} + +/**Function************************************************************* + +  Synopsis    [Create combinational timeframes by unrolling sequential circuits.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Aig_Man_t * Saig_ManUnrollTwo( Aig_Man_t * pBot, Aig_Man_t * pTop, int nFrames ) +{ +    Aig_Man_t * p, * pAig; +    Aig_Obj_t * pObj, * pObjLi, * pObjLo; +    int i, f; +    assert( nFrames > 1 ); +    assert( Saig_ManPiNum(pBot) == Saig_ManPiNum(pTop) ); +    assert( Saig_ManPoNum(pBot) == Saig_ManPoNum(pTop) ); +    assert( Saig_ManRegNum(pBot) == Saig_ManRegNum(pTop) ); +    assert( Saig_ManRegNum(pBot) > 0 || Saig_ManRegNum(pTop) > 0 ); +    // start timeframes +    p = Aig_ManStart( nFrames * AIG_MAX(Aig_ManObjNumMax(pBot), Aig_ManObjNumMax(pTop)) ); +    p->pName = Aig_UtilStrsav( "frames" ); +    // create variables for register outputs +    pAig = pBot; +    Saig_ManForEachLo( pAig, pObj, i ) +        pObj->pData = Aig_ObjCreatePi( p ); +    // add timeframes +    for ( f = 0; f < nFrames; f++ ) +    { +        // create PI nodes for this frame +        Aig_ManConst1(pAig)->pData = Aig_ManConst1( p ); +        Saig_ManForEachPi( pAig, pObj, i ) +            pObj->pData = Aig_ObjCreatePi( p ); +        // add internal nodes of this frame +        Aig_ManForEachNode( pAig, pObj, i ) +            pObj->pData = Aig_And( p, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); +        if ( f == nFrames - 1 ) +        { +            // create POs for this frame +            Aig_ManForEachPo( pAig, pObj, i ) +                Aig_ObjCreatePo( p, Aig_ObjChild0Copy(pObj) ); +            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; +        if ( f == 0 ) +        { +            // transfer from pOld to pNew +            Saig_ManForEachLo( pAig, pObj, i ) +                Saig_ManLo(pTop, i)->pData = pObj->pData; +            pAig = pTop; +        } +    } +    Aig_ManCleanup( p ); +    return p; +} + +/**Function************************************************************* + +  Synopsis    [Duplicates the AIG while creating POs from the set.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Aig_Man_t * Aig_ManDupNodes_old( Aig_Man_t * p, Vec_Ptr_t * vSet ) +{ +    Aig_Man_t * pNew, * pCopy; +    Aig_Obj_t * pObj; +    int i;      pNew = Aig_ManStart( Aig_ManObjNumMax(p) );      pNew->pName = Aig_UtilStrsav( p->pName );      Aig_ManConst1(p)->pData = Aig_ManConst1(pNew); -    Saig_ManForEachPi( p, pObj, i ) +    Aig_ManForEachPi( p, pObj, i )          pObj->pData = Aig_ObjCreatePi( pNew ); -    Saig_ManForEachLo( p, pObj, i ) -        pObj->pData = Aig_NotCond( Aig_ObjCreatePi( pNew ), pObj->fMarkA );      Aig_ManForEachNode( p, pObj, i )          pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); -    Saig_ManForEachPo( p, pObj, i ) -        pObj->pData = Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) ); +//    Saig_ManForEachPo( p, pObj, i ) +//        pObj->pData = Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) ); +    Vec_PtrForEachEntry( vSet, pObj, i ) +        Aig_ObjCreatePo( pNew, Aig_NotCond((Aig_Obj_t *)Aig_Regular(pObj)->pData, Aig_IsComplement(pObj)) );      Saig_ManForEachLi( p, pObj, i ) -        pObj->pData = Aig_ObjCreatePo( pNew, Aig_NotCond( Aig_ObjChild0Copy(pObj), pObj->fMarkA ) ); +        pObj->pData = Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) );      Aig_ManSetRegNum( pNew, Saig_ManRegNum(p) ); -    assert( Aig_ManNodeNum(pNew) == Aig_ManNodeNum(p) ); -    return pNew; +    // cleanup and return a copy +    Aig_ManSeqCleanup( pNew ); +    pCopy = Aig_ManDupSimpleDfs( pNew ); +    Aig_ManStop( pNew ); +    return pCopy; +} + +/**Function************************************************************* + +  Synopsis    [Duplicates the AIG while creating POs from the set.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Aig_Man_t * Aig_ManDupNodes( Aig_Man_t * p, Vec_Ptr_t * vSet, int iPart ) +{ +    Aig_Man_t * pNew, * pCopy; +    Aig_Obj_t * pObj; +    int i; +    Aig_ManCleanData( p ); +    pNew = Aig_ManStart( Aig_ManObjNumMax(p) ); +    pNew->pName = Aig_UtilStrsav( p->pName ); +    Aig_ManConst1(p)->pData = Aig_ManConst1(pNew); +    Saig_ManForEachPi( p, pObj, i ) +        pObj->pData = Aig_ObjCreatePi( pNew ); +    if ( iPart == 0 ) +    { +        Saig_ManForEachLo( p, pObj, i ) +            if ( i < Saig_ManRegNum(p)/2 ) +                pObj->pData = Aig_ObjCreatePi( pNew ); +    } +    else +    { +        Saig_ManForEachLo( p, pObj, i ) +            if ( i >= Saig_ManRegNum(p)/2 ) +                pObj->pData = Aig_ObjCreatePi( pNew ); +    } +    Aig_ManForEachNode( p, pObj, i ) +        if ( Aig_ObjFanin0(pObj)->pData && Aig_ObjFanin1(pObj)->pData ) +            pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); +//    Saig_ManForEachPo( p, pObj, i ) +//        pObj->pData = Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) ); +    Vec_PtrForEachEntry( vSet, pObj, i ) +        Aig_ObjCreatePo( pNew, Aig_NotCond((Aig_Obj_t *)Aig_Regular(pObj)->pData, Aig_IsComplement(pObj)) ); +    if ( iPart == 0 ) +    { +        Saig_ManForEachLi( p, pObj, i ) +            if ( i < Saig_ManRegNum(p)/2 ) +                pObj->pData = Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) ); +    } +    else +    { +        Saig_ManForEachLi( p, pObj, i ) +            if ( i >= Saig_ManRegNum(p)/2 ) +                pObj->pData = Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) ); +    } +    Aig_ManSetRegNum( pNew, Saig_ManRegNum(p)/2 ); +    // cleanup and return a copy +//    Aig_ManSeqCleanup( pNew ); +    Aig_ManCleanup( pNew ); +    pCopy = Aig_ManDupSimpleDfs( pNew ); +    Aig_ManStop( pNew ); +    return pCopy; +} + +/**Function************************************************************* + +  Synopsis    [Duplicates the AIG to have constant-0 initial state.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Saig_ManDemiterSimple( Aig_Man_t * p, Aig_Man_t ** ppAig0, Aig_Man_t ** ppAig1 ) +{ +    Vec_Ptr_t * vSet0, * vSet1; +    Aig_Obj_t * pObj, * pFanin, * pObj0, * pObj1; +    int i, Counter = 0; +    assert( Saig_ManRegNum(p) % 2 == 0 ); +    vSet0 = Vec_PtrAlloc( Saig_ManPoNum(p) ); +    vSet1 = Vec_PtrAlloc( Saig_ManPoNum(p) ); +    Saig_ManForEachPo( p, pObj, i ) +    { +        pFanin = Aig_ObjFanin0(pObj); +        if ( Aig_ObjIsConst1( pFanin ) ) +        { +            if ( !Aig_ObjFaninC0(pObj) ) +                printf( "The output number %d of the miter is constant 1.\n", i ); +            Counter++; +            continue; +        } +        if ( !Aig_ObjIsNode(pFanin) || !Aig_ObjRecognizeExor( pFanin, &pObj0, &pObj1 ) ) +        { +            printf( "The miter cannot be demitered.\n" ); +            Vec_PtrFree( vSet0 ); +            Vec_PtrFree( vSet1 ); +            return 0; +        } +//        printf( "%d %d  ", Aig_Regular(pObj0)->Id, Aig_Regular(pObj1)->Id ); +        if ( Aig_Regular(pObj0)->Id < Aig_Regular(pObj1)->Id ) +        { +            Vec_PtrPush( vSet0, pObj0 ); +            Vec_PtrPush( vSet1, pObj1 ); +        } +        else +        { +            Vec_PtrPush( vSet0, pObj1 ); +            Vec_PtrPush( vSet1, pObj0 ); +        } +    } +//    printf( "Miter has %d constant outputs.\n", Counter ); +//    printf( "\n" ); +    if ( ppAig0 ) +    { +        *ppAig0 = Aig_ManDupNodes( p, vSet0, 0 ); +        FREE( (*ppAig0)->pName ); +        (*ppAig0)->pName = Aig_UtilStrsav( "part0" ); +    } +    if ( ppAig1 ) +    { +        *ppAig1 = Aig_ManDupNodes( p, vSet1, 1 ); +        FREE( (*ppAig1)->pName ); +        (*ppAig1)->pName = Aig_UtilStrsav( "part1" ); +    } +    Vec_PtrFree( vSet0 ); +    Vec_PtrFree( vSet1 ); +    return 1; +} + +/**Function************************************************************* + +  Synopsis    [Labels logic reachable from the node.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Saig_ManDemiterLabel_rec( Aig_Man_t * p, Aig_Obj_t * pObj, int Value ) +{ +    if ( Aig_ObjIsTravIdCurrent(p, pObj) ) +        return; +    Aig_ObjSetTravIdCurrent(p, pObj); +    if ( Value )  +        pObj->fMarkB = 1; +    else +        pObj->fMarkA = 1; +    if ( Saig_ObjIsPi(p, pObj) ) +        return; +    if ( Saig_ObjIsLo(p, pObj) ) +    { +        Saig_ManDemiterLabel_rec( p, Aig_ObjFanin0( Saig_ObjLoToLi(p, pObj) ), Value ); +        return; +    } +    assert( Aig_ObjIsNode(pObj) ); +    Saig_ManDemiterLabel_rec( p, Aig_ObjFanin0(pObj), Value ); +    Saig_ManDemiterLabel_rec( p, Aig_ObjFanin1(pObj), Value ); +} + +/**Function************************************************************* + +  Synopsis    [Returns the first labeled register encountered during traversal.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Aig_Obj_t * Saig_ManGetLabeledRegister_rec( Aig_Man_t * p, Aig_Obj_t * pObj ) +{ +    Aig_Obj_t * pResult; +    if ( Aig_ObjIsTravIdCurrent(p, pObj) ) +        return NULL; +    Aig_ObjSetTravIdCurrent(p, pObj); +    if ( Saig_ObjIsPi(p, pObj) ) +        return NULL; +    if ( Saig_ObjIsLo(p, pObj) ) +    { +        if ( pObj->fMarkA || pObj->fMarkB ) +            return pObj; +        return Saig_ManGetLabeledRegister_rec( p, Aig_ObjFanin0( Saig_ObjLoToLi(p, pObj) ) ); +    } +    assert( Aig_ObjIsNode(pObj) ); +    pResult = Saig_ManGetLabeledRegister_rec( p, Aig_ObjFanin0(pObj) ); +    if ( pResult ) +        return pResult; +    return Saig_ManGetLabeledRegister_rec( p, Aig_ObjFanin1(pObj) ); +} + +/**Function************************************************************* + +  Synopsis    [Duplicates the AIG to have constant-0 initial state.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Saig_ManDemiter( Aig_Man_t * p, Aig_Man_t ** ppAig0, Aig_Man_t ** ppAig1 ) +{ +    Vec_Ptr_t * vPairs, * vSet0, * vSet1; +    Aig_Obj_t * pObj, * pObj0, * pObj1, * pFlop0, * pFlop1; +    int i, Counter; +    assert( Saig_ManRegNum(p) > 0 ); +    Aig_ManSetPioNumbers( p ); +    // check if demitering is possible +    vPairs = Vec_PtrAlloc( 2 * Saig_ManPoNum(p) ); +    Saig_ManForEachPo( p, pObj, i ) +    { +        if ( !Aig_ObjRecognizeExor( Aig_ObjFanin0(pObj), &pObj0, &pObj1 ) ) +        { +            Vec_PtrFree( vPairs ); +            return 0; +        } +        Vec_PtrPush( vPairs, pObj0 ); +        Vec_PtrPush( vPairs, pObj1 ); +    } +    // start array of outputs +    vSet0 = Vec_PtrAlloc( Saig_ManPoNum(p) ); +    vSet1 = Vec_PtrAlloc( Saig_ManPoNum(p) ); +    // get the first pair of outputs +    pObj0 = Vec_PtrEntry( vPairs, 0 ); +    pObj1 = Vec_PtrEntry( vPairs, 1 ); +    // label registers reachable from the outputs +    Aig_ManIncrementTravId( p ); +    Saig_ManDemiterLabel_rec( p, Aig_Regular(pObj0), 0 ); +    Vec_PtrPush( vSet0, pObj0 ); +    Aig_ManIncrementTravId( p ); +    Saig_ManDemiterLabel_rec( p, Aig_Regular(pObj1), 1 ); +    Vec_PtrPush( vSet1, pObj1 ); +    // find where each output belongs +    for ( i = 2; i < Vec_PtrSize(vPairs); i += 2 ) +    { +        pObj0 = Vec_PtrEntry( vPairs, i   ); +        pObj1 = Vec_PtrEntry( vPairs, i+1 ); + +        Aig_ManIncrementTravId( p ); +        pFlop0 = Saig_ManGetLabeledRegister_rec( p, Aig_Regular(pObj0) ); + +        Aig_ManIncrementTravId( p ); +        pFlop1 = Saig_ManGetLabeledRegister_rec( p, Aig_Regular(pObj1) ); + +        if ( (pFlop0->fMarkA && pFlop0->fMarkB) || (pFlop1->fMarkA && pFlop1->fMarkB) ||  +             (pFlop0->fMarkA && pFlop1->fMarkA) || (pFlop0->fMarkB && pFlop1->fMarkB)  ) +            printf( "Ouput pair %4d: Difficult case...\n", i/2 ); + +        if ( pFlop0->fMarkB ) +        { +            Saig_ManDemiterLabel_rec( p, pObj0, 1 ); +            Vec_PtrPush( vSet0, pObj0 ); +        } +        else // if ( pFlop0->fMarkA ) or none +        { +            Saig_ManDemiterLabel_rec( p, pObj0, 0 ); +            Vec_PtrPush( vSet1, pObj0 ); +        } + +        if ( pFlop1->fMarkB ) +        { +            Saig_ManDemiterLabel_rec( p, pObj1, 1 ); +            Vec_PtrPush( vSet0, pObj1 ); +        } +        else // if ( pFlop1->fMarkA ) or none +        { +            Saig_ManDemiterLabel_rec( p, pObj1, 0 ); +            Vec_PtrPush( vSet1, pObj1 ); +        } +    } +    // check if there are any flops in common +    Counter = 0; +    Saig_ManForEachLo( p, pObj, i ) +        if ( pObj->fMarkA && pObj->fMarkB ) +            Counter++; +    if ( Counter > 0 ) +        printf( "The miters contains %d flops reachable from both AIGs.\n", Counter ); + +    // produce two miters +    if ( ppAig0 ) +    { +        assert( 0 ); +        *ppAig0 = Aig_ManDupNodes( p, vSet0, 0 ); // not ready +        FREE( (*ppAig0)->pName ); +        (*ppAig0)->pName = Aig_UtilStrsav( "part0" ); +    } +    if ( ppAig1 ) +    { +        assert( 0 ); +        *ppAig1 = Aig_ManDupNodes( p, vSet1, 1 ); // not ready +        FREE( (*ppAig1)->pName ); +        (*ppAig1)->pName = Aig_UtilStrsav( "part1" ); +    } +    Vec_PtrFree( vSet0 ); +    Vec_PtrFree( vSet1 ); +    Vec_PtrFree( vPairs ); +    return 1;  } +/**Function************************************************************* + +  Synopsis    [Create specialized miter by unrolling two circuits.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Aig_Man_t * Saig_ManCreateMiterTwo( Aig_Man_t * pOld, Aig_Man_t * pNew, int nFrames ) +{ +    Aig_Man_t * pFrames0, * pFrames1, * pMiter; +    assert( Aig_ManNodeNum(pOld) <= Aig_ManNodeNum(pNew) ); +    pFrames0 = Saig_ManUnrollTwo( pOld, pOld, nFrames ); +    pFrames1 = Saig_ManUnrollTwo( pNew, pOld, nFrames ); +    pMiter = Saig_ManCreateMiterComb( pFrames0, pFrames1, 0 ); +    Aig_ManStop( pFrames0 ); +    Aig_ManStop( pFrames1 ); +    return pMiter; +} + +/**Function************************************************************* + +  Synopsis    [Reduces SEC to CEC for the special case of seq synthesis.] + +  Description [The first circuit (pPart0) should be circuit before synthesis. +  The second circuit (pPart1) should be circuit after synthesis.] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ssw_SecSpecial( Aig_Man_t * pPart0, Aig_Man_t * pPart1, int fVerbose ) +{ +    extern int Fra_FraigCec( Aig_Man_t ** ppAig, int nConfLimit, int fVerbose ); +    int nFrames = 2;   // modify to enable comparison over any number of frames +    Aig_Man_t * pMiterCec; +    int RetValue, clkTotal = clock(); +//    assert( Aig_ManNodeNum(pPart0) <= Aig_ManNodeNum(pPart1) ); +    if ( Aig_ManNodeNum(pPart0) >= Aig_ManNodeNum(pPart1) ) +    { +        printf( "Warning: The design after synthesis is smaller!\n" ); +        printf( "This warning may indicate that the order of designs is changed.\n" ); +        printf( "The solver expects the original disign as first argument and\n" ); +        printf( "the modified design as the second argument in Ssw_SecSpecial().\n" ); +    } +    // create two-level miter +    pMiterCec = Saig_ManCreateMiterTwo( pPart0, pPart1, nFrames ); +    if ( fVerbose ) +    { +        Aig_ManPrintStats( pMiterCec ); +//        Aig_ManDumpBlif( pMiterCec, "miter01.blif", NULL, NULL ); +//        printf( "The new miter is written into file \"%s\".\n", "miter01.blif" ); +    } +    // run CEC on this miter +    RetValue = Fra_FraigCec( &pMiterCec, 100000, fVerbose ); +    // transfer model if given +//    if ( pNtk2 == NULL ) +//        pNtk1->pModel = pMiterCec->pData, pMiterCec->pData = NULL; +    Aig_ManStop( pMiterCec ); +    // report the miter +    if ( RetValue == 1 ) +    { +        printf( "Networks are equivalent.   " ); +PRT( "Time", clock() - clkTotal ); +    } +    else if ( RetValue == 0 ) +    { +        printf( "Networks are NOT EQUIVALENT.   " ); +PRT( "Time", clock() - clkTotal ); +    } +    else +    { +        printf( "Networks are UNDECIDED.   " ); +PRT( "Time", clock() - clkTotal ); +    } +    fflush( stdout ); +    return RetValue; +} + +/**Function************************************************************* + +  Synopsis    [Reduces SEC to CEC for the special case of seq synthesis.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ssw_SecSpecialMiter( Aig_Man_t * pMiter, int fVerbose ) +{ +    Aig_Man_t * pPart0, * pPart1; +    int RetValue; +    if ( fVerbose ) +        Aig_ManPrintStats( pMiter ); +    // demiter the miter +    if ( !Saig_ManDemiterSimple( pMiter, &pPart0, &pPart1 ) ) +    { +        printf( "Demitering has failed.\n" ); +        return -1; +    } +    if ( fVerbose ) +    { +        Aig_ManPrintStats( pPart0 ); +        Aig_ManPrintStats( pPart1 ); +//        Aig_ManDumpBlif( pPart0, "part0.blif", NULL, NULL ); +//        Aig_ManDumpBlif( pPart1, "part1.blif", NULL, NULL ); +//        printf( "The result of demitering is written into files \"%s\" and \"%s\".\n", "part0.blif", "part1.blif" ); +    } +    RetValue = Ssw_SecSpecial( pPart0, pPart1, fVerbose ); +    Aig_ManStop( pPart0 ); +    Aig_ManStop( pPart1 ); +    return RetValue; +} +  ////////////////////////////////////////////////////////////////////////  ///                       END OF FILE                                ///  //////////////////////////////////////////////////////////////////////// diff --git a/src/aig/saig/saigSynch.c b/src/aig/saig/saigSynch.c index 9dbbb420..eb0fefc9 100644 --- a/src/aig/saig/saigSynch.c +++ b/src/aig/saig/saigSynch.c @@ -453,6 +453,40 @@ Vec_Str_t * Saig_SynchSequence( Aig_Man_t * pAig, int nWords )  /**Function************************************************************* +  Synopsis    [Duplicates the AIG to have constant-0 initial state.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Aig_Man_t * Saig_ManDupInitZero( Aig_Man_t * p ) +{ +    Aig_Man_t * pNew; +    Aig_Obj_t * pObj; +    int i; +    pNew = Aig_ManStart( Aig_ManObjNumMax(p) ); +    pNew->pName = Aig_UtilStrsav( p->pName ); +    Aig_ManConst1(p)->pData = Aig_ManConst1(pNew); +    Saig_ManForEachPi( p, pObj, i ) +        pObj->pData = Aig_ObjCreatePi( pNew ); +    Saig_ManForEachLo( p, pObj, i ) +        pObj->pData = Aig_NotCond( Aig_ObjCreatePi( pNew ), pObj->fMarkA ); +    Aig_ManForEachNode( p, pObj, i ) +        pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); +    Saig_ManForEachPo( p, pObj, i ) +        pObj->pData = Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) ); +    Saig_ManForEachLi( p, pObj, i ) +        pObj->pData = Aig_ObjCreatePo( pNew, Aig_NotCond( Aig_ObjChild0Copy(pObj), pObj->fMarkA ) ); +    Aig_ManSetRegNum( pNew, Saig_ManRegNum(p) ); +    assert( Aig_ManNodeNum(pNew) == Aig_ManNodeNum(p) ); +    return pNew; +} + +/**Function************************************************************* +    Synopsis    [Determines synchronizing sequence using ternary simulation.]    Description [] diff --git a/src/aig/ssw/ssw.h b/src/aig/ssw/ssw.h index 766407d4..e6e3a1b4 100644 --- a/src/aig/ssw/ssw.h +++ b/src/aig/ssw/ssw.h @@ -55,6 +55,7 @@ struct Ssw_Pars_t_      int              fSemiFormal;   // enable semiformal filtering      int              fUniqueness;   // enable uniqueness constraints      int              fVerbose;      // verbose stats +    int              fFlopVerbose;  // verbose printout of redundant flops      // optimized latch correspondence      int              fLatchCorrOpt; // perform register correspondence (optimized)      int              nSatVarMax;    // max number of SAT vars before recycling SAT solver (optimized latch corr only) @@ -92,6 +93,8 @@ extern Aig_Man_t *   Ssw_SignalCorrespondence( Aig_Man_t * pAig, Ssw_Pars_t * pP  extern Aig_Man_t *   Ssw_LatchCorrespondence( Aig_Man_t * pAig, Ssw_Pars_t * pPars );  /*=== sswLoc.c ==========================================================*/  extern int           Saig_ManLocalization( Aig_Man_t * p, int nFramesMax, int nConfMax, int fVerbose ); +/*=== sswMiter.c ===================================================*/ +extern int           Ssw_SecSpecialMiter( Aig_Man_t * pMiter, int fVerbose );  /*=== sswPart.c ==========================================================*/  extern Aig_Man_t *   Ssw_SignalCorrespondencePart( Aig_Man_t * pAig, Ssw_Pars_t * pPars );  /*=== sswPairs.c ===================================================*/ diff --git a/src/aig/ssw/sswPart.c b/src/aig/ssw/sswPart.c index 7eb6b8fe..983a2022 100644 --- a/src/aig/ssw/sswPart.c +++ b/src/aig/ssw/sswPart.c @@ -97,12 +97,14 @@ Aig_Man_t * Ssw_SignalCorrespondencePart( Aig_Man_t * pAig, Ssw_Pars_t * pPars )          if ( pAig->vOnehots )              pTemp->vOnehots = Aig_ManRegProjectOnehots( pAig, pTemp, pAig->vOnehots, fVerbose );          // run SSW -        pNew = Ssw_SignalCorrespondence( pTemp, pPars ); -        nClasses = Aig_TransferMappedClasses( pAig, pTemp, pMapBack ); -        if ( fVerbose ) -            printf( "%3d : Reg = %4d. PI = %4d. (True = %4d. Regs = %4d.) And = %5d. It = %3d. Cl = %5d.\n",  -                i, Vec_IntSize(vPart), Aig_ManPiNum(pTemp)-Vec_IntSize(vPart), nCountPis, nCountRegs, Aig_ManNodeNum(pTemp), pPars->nIters, nClasses ); -        Aig_ManStop( pNew ); +        if (nCountPis>0) { +            pNew = Ssw_SignalCorrespondence( pTemp, pPars ); +            nClasses = Aig_TransferMappedClasses( pAig, pTemp, pMapBack ); +            if ( fVerbose ) +                printf( "%3d : Reg = %4d. PI = %4d. (True = %4d. Regs = %4d.) And = %5d. It = %3d. Cl = %5d.\n",  +                    i, Vec_IntSize(vPart), Aig_ManPiNum(pTemp)-Vec_IntSize(vPart), nCountPis, nCountRegs, Aig_ManNodeNum(pTemp), pPars->nIters, nClasses ); +            Aig_ManStop( pNew ); +        }          Aig_ManStop( pTemp );          free( pMapBack );      } diff --git a/src/aig/ssw_old/module.make b/src/aig/ssw_old/module.make new file mode 100644 index 00000000..625d72d1 --- /dev/null +++ b/src/aig/ssw_old/module.make @@ -0,0 +1,14 @@ +SRC +=    src/aig/ssw/sswAig.c \ +    src/aig/ssw/sswBmc.c \ +    src/aig/ssw/sswClass.c \ +    src/aig/ssw/sswCnf.c \ +    src/aig/ssw/sswCore.c \ +    src/aig/ssw/sswLcorr.c \ +    src/aig/ssw/sswMan.c \ +    src/aig/ssw/sswPart.c \ +    src/aig/ssw/sswPairs.c \ +    src/aig/ssw/sswSat.c \ +    src/aig/ssw/sswSim.c \ +    src/aig/ssw/sswSimSat.c \ +    src/aig/ssw/sswSweep.c \ +    src/aig/ssw/sswUnique.c diff --git a/src/aig/ssw_old/ssw.h b/src/aig/ssw_old/ssw.h new file mode 100644 index 00000000..766407d4 --- /dev/null +++ b/src/aig/ssw_old/ssw.h @@ -0,0 +1,117 @@ +/**CFile**************************************************************** + +  FileName    [ssw.h]  + +  SystemName  [ABC: Logic synthesis and verification system.] + +  PackageName [Inductive prover with constraints.] + +  Synopsis    [External declarations.] + +  Author      [Alan Mishchenko] +   +  Affiliation [UC Berkeley] + +  Date        [Ver. 1.0. Started - September 1, 2008.] + +  Revision    [$Id: ssw.h,v 1.00 2008/09/01 00:00:00 alanmi Exp $] + +***********************************************************************/ +  +#ifndef __SSW_H__ +#define __SSW_H__ + +#ifdef __cplusplus +extern "C" {  +#endif + +//////////////////////////////////////////////////////////////////////// +///                          INCLUDES                                /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +///                         PARAMETERS                               /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +///                         BASIC TYPES                              /// +//////////////////////////////////////////////////////////////////////// + +// choicing parameters +typedef struct Ssw_Pars_t_ Ssw_Pars_t; +struct Ssw_Pars_t_ +{ +    int              nPartSize;     // size of the partition +    int              nOverSize;     // size of the overlap between partitions +    int              nFramesK;      // the induction depth +    int              nFramesAddSim; // the number of additional frames to simulate +    int              nConstrs;      // treat the last nConstrs POs as seq constraints +    int              nMaxLevs;      // the max number of levels of nodes to consider +    int              nBTLimit;      // conflict limit at a node +    int              nMinDomSize;   // min clock domain considered for optimization +    int              fPolarFlip;    // uses polarity adjustment +    int              fSkipCheck;    // do not run equivalence check for unaffected cones +    int              fLatchCorr;    // perform register correspondence +    int              fSemiFormal;   // enable semiformal filtering +    int              fUniqueness;   // enable uniqueness constraints +    int              fVerbose;      // verbose stats +    // optimized latch correspondence +    int              fLatchCorrOpt; // perform register correspondence (optimized) +    int              nSatVarMax;    // max number of SAT vars before recycling SAT solver (optimized latch corr only) +    int              nRecycleCalls; // calls to perform before recycling SAT solver (optimized latch corr only) +    // internal parameters +    int              nIters;        // the number of iterations performed +}; + +// sequential counter-example +typedef struct Ssw_Cex_t_   Ssw_Cex_t; +struct Ssw_Cex_t_ +{ +    int              iPo;               // the zero-based number of PO, for which verification failed +    int              iFrame;            // the zero-based number of the time-frame, for which verificaiton failed +    int              nRegs;             // the number of registers in the miter  +    int              nPis;              // the number of primary inputs in the miter +    int              nBits;             // the number of words of bit data used +    unsigned         pData[0];          // the cex bit data (the number of bits: nRegs + (iFrame+1) * nPis) +}; + +//////////////////////////////////////////////////////////////////////// +///                      MACRO DEFINITIONS                           /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +///                    FUNCTION DECLARATIONS                         /// +//////////////////////////////////////////////////////////////////////// + +/*=== sswAbs.c ==========================================================*/ +extern Aig_Man_t *   Saig_ManProofAbstraction( Aig_Man_t * p, int nFrames, int nConfMax, int fVerbose ); +/*=== sswCore.c ==========================================================*/ +extern void          Ssw_ManSetDefaultParams( Ssw_Pars_t * p ); +extern void          Ssw_ManSetDefaultParamsLcorr( Ssw_Pars_t * p ); +extern Aig_Man_t *   Ssw_SignalCorrespondence( Aig_Man_t * pAig, Ssw_Pars_t * pPars ); +extern Aig_Man_t *   Ssw_LatchCorrespondence( Aig_Man_t * pAig, Ssw_Pars_t * pPars ); +/*=== sswLoc.c ==========================================================*/ +extern int           Saig_ManLocalization( Aig_Man_t * p, int nFramesMax, int nConfMax, int fVerbose ); +/*=== sswPart.c ==========================================================*/ +extern Aig_Man_t *   Ssw_SignalCorrespondencePart( Aig_Man_t * pAig, Ssw_Pars_t * pPars ); +/*=== sswPairs.c ===================================================*/ +extern int           Ssw_SecWithPairs( Aig_Man_t * pAig1, Aig_Man_t * pAig2, Vec_Int_t * vIds1, Vec_Int_t * vIds2, Ssw_Pars_t * pPars ); +extern int           Ssw_SecGeneral( Aig_Man_t * pAig1, Aig_Man_t * pAig2, Ssw_Pars_t * pPars ); +extern int           Ssw_SecGeneralMiter( Aig_Man_t * pMiter, Ssw_Pars_t * pPars ); +/*=== sswSim.c ===================================================*/ +extern Ssw_Cex_t *   Ssw_SmlAllocCounterExample( int nRegs, int nRealPis, int nFrames ); +extern void          Ssw_SmlFreeCounterExample( Ssw_Cex_t * pCex ); +extern int           Ssw_SmlRunCounterExample( Aig_Man_t * pAig, Ssw_Cex_t * p ); +extern int           Ssw_SmlFindOutputCounterExample( Aig_Man_t * pAig, Ssw_Cex_t * p ); +extern Ssw_Cex_t *   Ssw_SmlDupCounterExample( Ssw_Cex_t * p, int nRegsNew ); + +#ifdef __cplusplus +} +#endif + +#endif + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + diff --git a/src/aig/ssw_old/sswAig.c b/src/aig/ssw_old/sswAig.c new file mode 100644 index 00000000..7b6d1bb0 --- /dev/null +++ b/src/aig/ssw_old/sswAig.c @@ -0,0 +1,205 @@ +/**CFile**************************************************************** + +  FileName    [sswAig.c] + +  SystemName  [ABC: Logic synthesis and verification system.] + +  PackageName [Inductive prover with constraints.] + +  Synopsis    [AIG manipulation.] + +  Author      [Alan Mishchenko] +   +  Affiliation [UC Berkeley] + +  Date        [Ver. 1.0. Started - September 1, 2008.] + +  Revision    [$Id: sswAig.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "sswInt.h" + +//////////////////////////////////////////////////////////////////////// +///                        DECLARATIONS                              /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +///                     FUNCTION DEFINITIONS                         /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + +  Synopsis    [Performs speculative reduction for one node.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Ssw_FramesConstrainNode( Ssw_Man_t * p, Aig_Man_t * pFrames, Aig_Man_t * pAig, Aig_Obj_t * pObj, int iFrame, int fTwoPos ) +{ +    Aig_Obj_t * pObjNew, * pObjNew2, * pObjRepr, * pObjReprNew, * pMiter; +    // skip nodes without representative +    pObjRepr = Aig_ObjRepr(pAig, pObj); +    if ( pObjRepr == NULL ) +        return; +    p->nConstrTotal++; +    assert( pObjRepr->Id < pObj->Id ); +    // get the new node  +    pObjNew = Ssw_ObjFrame( p, pObj, iFrame ); +    // get the new node of the representative +    pObjReprNew = Ssw_ObjFrame( p, pObjRepr, iFrame ); +    // if this is the same node, no need to add constraints +    if ( pObj->fPhase == pObjRepr->fPhase ) +    { +        assert( pObjNew != Aig_Not(pObjReprNew) ); +        if ( pObjNew == pObjReprNew ) +            return; +    } +    else +    { +        assert( pObjNew != pObjReprNew ); +        if ( pObjNew == Aig_Not(pObjReprNew) ) +            return; +    } +    p->nConstrReduced++; +    // these are different nodes - perform speculative reduction +    pObjNew2 = Aig_NotCond( pObjReprNew, pObj->fPhase ^ pObjRepr->fPhase ); +    // set the new node +    Ssw_ObjSetFrame( p, pObj, iFrame, pObjNew2 ); +    // add the constraint +    if ( fTwoPos ) +    { +        Aig_ObjCreatePo( pFrames, pObjNew2 ); +        Aig_ObjCreatePo( pFrames, pObjNew ); +    } +    else +    { +        pMiter = Aig_Exor( pFrames, pObjNew, pObjNew2 ); +        Aig_ObjCreatePo( pFrames, Aig_NotCond(pMiter, Aig_ObjPhaseReal(pMiter)) ); +    } +} + +/**Function************************************************************* + +  Synopsis    [Prepares the inductive case with speculative reduction.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Aig_Man_t * Ssw_FramesWithClasses( Ssw_Man_t * p ) +{ +    Aig_Man_t * pFrames; +    Aig_Obj_t * pObj, * pObjLi, * pObjLo, * pObjNew; +    int i, f; +    assert( p->pFrames == NULL ); +    assert( Aig_ManRegNum(p->pAig) > 0 ); +    assert( Aig_ManRegNum(p->pAig) < Aig_ManPiNum(p->pAig) ); +    p->nConstrTotal = p->nConstrReduced = 0; + +    // start the fraig package +    pFrames = Aig_ManStart( Aig_ManObjNumMax(p->pAig) * p->nFrames ); +    // create latches for the first frame +    Saig_ManForEachLo( p->pAig, pObj, i ) +        Ssw_ObjSetFrame( p, pObj, 0, Aig_ObjCreatePi(pFrames) ); +    // add timeframes +    for ( f = 0; f < p->pPars->nFramesK; f++ ) +    { +        // map constants and PIs +        Ssw_ObjSetFrame( p, Aig_ManConst1(p->pAig), f, Aig_ManConst1(pFrames) ); +        Saig_ManForEachPi( p->pAig, pObj, i ) +            Ssw_ObjSetFrame( p, pObj, f, Aig_ObjCreatePi(pFrames) ); +        // set the constraints on the latch outputs +        Saig_ManForEachLo( p->pAig, pObj, i ) +            Ssw_FramesConstrainNode( p, pFrames, p->pAig, pObj, f, 1 ); +        // add internal nodes of this frame +        Aig_ManForEachNode( p->pAig, pObj, i ) +        { +            pObjNew = Aig_And( pFrames, Ssw_ObjChild0Fra(p, pObj, f), Ssw_ObjChild1Fra(p, pObj, f) ); +            Ssw_ObjSetFrame( p, pObj, f, pObjNew ); +            Ssw_FramesConstrainNode( p, pFrames, p->pAig, pObj, f, 1 ); +        } +        // transfer latch input to the latch outputs  +        Saig_ManForEachLiLo( p->pAig, pObjLi, pObjLo, i ) +            Ssw_ObjSetFrame( p, pObjLo, f+1, Ssw_ObjChild0Fra(p, pObjLi,f) ); +    } +    // add the POs for the latch outputs of the last frame +//    Saig_ManForEachLo( p->pAig, pObj, i ) +//        Aig_ObjCreatePo( pFrames, Ssw_ObjFrame( p, pObj, p->pPars->nFramesK ) ); +    for ( f = 0; f <= p->pPars->nFramesK; f++ ) +        Saig_ManForEachLo( p->pAig, pObj, i ) +            Aig_ObjCreatePo( pFrames, Ssw_ObjFrame( p, pObj, f ) ); + +    // remove dangling nodes +    Aig_ManCleanup( pFrames ); +    // make sure the satisfying assignment is node assigned +    assert( pFrames->pData == NULL ); +//Aig_ManShow( pFrames, 0, NULL ); +    return pFrames; +} + + + +/**Function************************************************************* + +  Synopsis    [Prepares the inductive case with speculative reduction.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Aig_Man_t * Ssw_SpeculativeReduction( Ssw_Man_t * p ) +{ +    Aig_Man_t * pFrames; +    Aig_Obj_t * pObj, * pObjNew; +    int i; +    assert( p->pFrames == NULL ); +    assert( Aig_ManRegNum(p->pAig) > 0 ); +    assert( Aig_ManRegNum(p->pAig) < Aig_ManPiNum(p->pAig) ); +    p->nConstrTotal = p->nConstrReduced = 0; + +    // start the fraig package +    pFrames = Aig_ManStart( Aig_ManObjNumMax(p->pAig) * p->nFrames ); +    // map constants and PIs +    Ssw_ObjSetFrame( p, Aig_ManConst1(p->pAig), 0, Aig_ManConst1(pFrames) ); +    Saig_ManForEachPi( p->pAig, pObj, i ) +        Ssw_ObjSetFrame( p, pObj, 0, Aig_ObjCreatePi(pFrames) ); +    // create latches for the first frame +    Saig_ManForEachLo( p->pAig, pObj, i ) +        Ssw_ObjSetFrame( p, pObj, 0, Aig_ObjCreatePi(pFrames) ); +    // set the constraints on the latch outputs +    Saig_ManForEachLo( p->pAig, pObj, i ) +        Ssw_FramesConstrainNode( p, pFrames, p->pAig, pObj, 0, 0 ); +    // add internal nodes of this frame +    Aig_ManForEachNode( p->pAig, pObj, i ) +    { +        pObjNew = Aig_And( pFrames, Ssw_ObjChild0Fra(p, pObj, 0), Ssw_ObjChild1Fra(p, pObj, 0) ); +        Ssw_ObjSetFrame( p, pObj, 0, pObjNew ); +        Ssw_FramesConstrainNode( p, pFrames, p->pAig, pObj, 0, 0 ); +    } +    // add the POs for the latch outputs of the last frame +    Saig_ManForEachLi( p->pAig, pObj, i ) +        Aig_ObjCreatePo( pFrames, Ssw_ObjChild0Fra(p, pObj,0) ); +    // remove dangling nodes +    Aig_ManCleanup( pFrames ); +    Aig_ManSetRegNum( pFrames, Aig_ManRegNum(p->pAig) ); +    printf( "SpecRed: Total constraints = %d. Reduced constraints = %d.\n",  +        p->nConstrTotal, p->nConstrReduced ); +    return pFrames; +} + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/ssw_old/sswBmc.c b/src/aig/ssw_old/sswBmc.c new file mode 100644 index 00000000..e2d47440 --- /dev/null +++ b/src/aig/ssw_old/sswBmc.c @@ -0,0 +1,315 @@ +/**CFile**************************************************************** + +  FileName    [sswBmc.c] + +  SystemName  [ABC: Logic synthesis and verification system.] + +  PackageName [Inductive prover with constraints.] + +  Synopsis    [Bounded model checker for equivalence clases.] + +  Author      [Alan Mishchenko] +   +  Affiliation [UC Berkeley] + +  Date        [Ver. 1.0. Started - September 1, 2008.] + +  Revision    [$Id: sswBmc.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "sswInt.h" + +//////////////////////////////////////////////////////////////////////// +///                        DECLARATIONS                              /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Ssw_Bmc_t_ Ssw_Bmc_t; // BMC manager + +struct Ssw_Bmc_t_ +{ +    // parameters +    int              nConfMaxStart;  // the starting conflict limit +    int              nConfMax;       // the intermediate conflict limit +    int              nFramesSweep;   // the number of frames to sweep +    int              fVerbose;       // prints output statistics +    // equivalences considered +    Ssw_Man_t *      pMan;           // SAT sweeping manager +    Vec_Ptr_t *      vTargets;       // the nodes that are watched +    // storage for patterns +    int              nPatternsAlloc; // the max number of interesting states +    int              nPatterns;      // the number of patterns +    Vec_Ptr_t *      vPatterns;      // storage for the interesting states +    Vec_Int_t *      vHistory;       // what state and how many steps +}; + +//////////////////////////////////////////////////////////////////////// +///                     FUNCTION DEFINITIONS                         /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Ssw_Bmc_t * Ssw_BmcManStart( Ssw_Man_t * pMan, int nConfMax, int fVerbose ) +{ +    Ssw_Bmc_t * p; +    Aig_Obj_t * pObj; +    int i; +    // create interpolation manager +    p = ALLOC( Ssw_Bmc_t, 1 );  +    memset( p, 0, sizeof(Ssw_Bmc_t) ); +    p->nConfMaxStart  = nConfMax; +    p->nConfMax       = nConfMax; +    p->nFramesSweep   = AIG_MAX( (1<<21)/Aig_ManNodeNum(pMan->pAig), pMan->nFrames ); +    p->fVerbose       = fVerbose; +    // equivalences considered +    p->pMan           = pMan; +    p->vTargets       = Vec_PtrAlloc( Saig_ManPoNum(p->pMan->pAig) ); +    Saig_ManForEachPo( p->pMan->pAig, pObj, i ) +        Vec_PtrPush( p->vTargets, Aig_ObjFanin0(pObj) ); +    // storage for patterns +    p->nPatternsAlloc = 512; +    p->nPatterns      = 1; +    p->vPatterns      = Vec_PtrAllocSimInfo( Aig_ManRegNum(p->pMan->pAig), Aig_BitWordNum(p->nPatternsAlloc) ); +    Vec_PtrCleanSimInfo( p->vPatterns, 0, Aig_BitWordNum(p->nPatternsAlloc) ); +    p->vHistory       = Vec_IntAlloc( 100 ); +    Vec_IntPush( p->vHistory, 0 ); +    // update arrays of the manager +    free( p->pMan->pNodeToFrames ); +    Vec_IntFree( p->pMan->vSatVars ); +    p->pMan->pNodeToFrames = CALLOC( Aig_Obj_t *, Aig_ManObjNumMax(p->pMan->pAig) * p->nFramesSweep ); +    p->pMan->vSatVars      = Vec_IntStart( Aig_ManObjNumMax(p->pMan->pAig) * (p->nFramesSweep+1) ); +    return p; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_BmcManStop( Ssw_Bmc_t * p ) +{ +    Vec_PtrFree( p->vTargets ); +    Vec_PtrFree( p->vPatterns ); +    Vec_IntFree( p->vHistory ); +    free( p ); +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ssw_BmcCheckTargets( Ssw_Bmc_t * p ) +{ +    Aig_Obj_t * pObj; +    int i; +    Vec_PtrForEachEntry( p->vTargets, pObj, i ) +        if ( !Ssw_ObjIsConst1Cand(p->pMan->pAig, pObj) ) +            return 1; +    return 0; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_ManFilterBmcSavePattern( Ssw_Bmc_t * p ) +{ +    unsigned * pInfo; +    Aig_Obj_t * pObj; +    int i; +    if ( p->nPatterns >= p->nPatternsAlloc ) +        return; +    Saig_ManForEachLo( p->pMan->pAig, pObj, i ) +    { +        pInfo = Vec_PtrEntry( p->vPatterns, i ); +        if ( Aig_InfoHasBit( p->pMan->pPatWords, Saig_ManPiNum(p->pMan->pAig) + i ) ) +            Aig_InfoSetBit( pInfo, p->nPatterns ); +    } +    p->nPatterns++; +} + +/**Function************************************************************* + +  Synopsis    [Performs fraiging for the internal nodes.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ssw_ManFilterBmc( Ssw_Bmc_t * pBmc, int iPat, int fCheckTargets ) +{ +    Ssw_Man_t * p = pBmc->pMan; +    Aig_Obj_t * pObj, * pObjNew, * pObjLi, * pObjLo; +    unsigned * pInfo; +    int i, f, clk, RetValue, fFirst = 0; +clk = clock(); + +    // start initialized timeframes +    p->pFrames = Aig_ManStart( Aig_ManObjNumMax(p->pAig) * 3 ); +    Saig_ManForEachLo( p->pAig, pObj, i ) +    { +        pInfo = Vec_PtrEntry( pBmc->vPatterns, i ); +        pObjNew = Aig_NotCond( Aig_ManConst1(p->pFrames), !Aig_InfoHasBit(pInfo, iPat) ); +        Ssw_ObjSetFrame( p, pObj, 0, pObjNew ); +    } + +    // sweep internal nodes +    Ssw_ManStartSolver( p ); +    RetValue = pBmc->nFramesSweep; +    for ( f = 0; f < pBmc->nFramesSweep; f++ ) +    { +        // map constants and PIs +        Ssw_ObjSetFrame( p, Aig_ManConst1(p->pAig), f, Aig_ManConst1(p->pFrames) ); +        Saig_ManForEachPi( p->pAig, pObj, i ) +            Ssw_ObjSetFrame( p, pObj, f, Aig_ObjCreatePi(p->pFrames) ); +        // 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_ManSweepNode( p, pObj, f, 1 ) ) +            { +                Ssw_ManFilterBmcSavePattern( pBmc ); +                if ( fFirst == 0 ) +                { +                    fFirst = 1; +                    pBmc->nConfMax *= 10; +                }  +            } +            if ( f > 0 && p->pSat->stats.conflicts >= pBmc->nConfMax ) +            { +                RetValue = -1; +                break; +            } +        } +        // quit if this is the last timeframe +        if ( p->pSat->stats.conflicts >= pBmc->nConfMax ) +        { +            RetValue += f + 1; +            break; +        } +        if ( fCheckTargets && Ssw_BmcCheckTargets( pBmc ) ) +            break; +        // transfer latch input to the latch outputs  +        // build logic cones for register outputs +        Saig_ManForEachLiLo( p->pAig, pObjLi, pObjLo, i ) +        { +            pObjNew = Ssw_ObjChild0Fra(p, pObjLi,f); +            Ssw_ObjSetFrame( p, pObjLo, f+1, pObjNew ); +            Ssw_CnfNodeAddToSolver( p, Aig_Regular(pObjNew) ); +        } +//printf( "Frame %2d : Conflicts = %6d. \n", f, p->pSat->stats.conflicts ); +    } +    if ( fFirst ) +        pBmc->nConfMax /= 10; + +    // cleanup +    Ssw_ClassesCheck( p->ppClasses ); +p->timeBmc += clock() - clk; +    return RetValue; +} + +/**Function************************************************************* + +  Synopsis    [Returns 1 if one of the targets has failed.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ssw_FilterUsingBmc( Ssw_Man_t * pMan, int fCheckTargets, int nConfMax, int fVerbose ) +{ +    Ssw_Bmc_t * p; +    int RetValue, Frames, Iter, clk = clock(); +    p = Ssw_BmcManStart( pMan, nConfMax, fVerbose ); +    if ( fCheckTargets && Ssw_BmcCheckTargets( p ) ) +    { +        assert( 0 ); +        Ssw_BmcManStop( p ); +        return 1; +    } +    if ( fVerbose ) +    { +        printf( "AIG : Const = %6d. Cl = %6d. Nodes = %6d.  ConfMax = %6d. FramesMax = %6d.\n",  +            Ssw_ClassesCand1Num(p->pMan->ppClasses), Ssw_ClassesClassNum(p->pMan->ppClasses),  +            Aig_ManNodeNum(p->pMan->pAig), p->nConfMax, p->nFramesSweep ); +    }  +    RetValue = 0; +    for ( Iter = 0; Iter < p->nPatterns; Iter++ ) +    { +clk = clock(); +        Frames = Ssw_ManFilterBmc( p, Iter, fCheckTargets ); +        if ( fVerbose ) +        { +            printf( "%3d : Const = %6d. Cl = %6d. NR = %6d. F = %3d. C = %5d. P = %3d. %s ",  +                Iter, Ssw_ClassesCand1Num(p->pMan->ppClasses), Ssw_ClassesClassNum(p->pMan->ppClasses),  +                Aig_ManNodeNum(p->pMan->pFrames), Frames, (int)p->pMan->pSat->stats.conflicts, p->nPatterns,  +                p->pMan->nSatFailsReal? "f" : " " ); +            PRT( "T", clock() - clk ); +        }  +        Ssw_ManCleanup( p->pMan ); +        if ( fCheckTargets && Ssw_BmcCheckTargets( p ) ) +        { +            printf( "Target is hit!!!\n" ); +            RetValue = 1; +        } +        if ( p->nPatterns >= p->nPatternsAlloc ) +            break; +    } +    Ssw_BmcManStop( p ); + +    pMan->nStrangers = 0; +    pMan->nSatCalls = 0; +    pMan->nSatProof = 0; +    pMan->nSatFailsReal = 0;  +    pMan->nSatFailsTotal = 0; +    pMan->nSatCallsUnsat = 0; +    pMan->nSatCallsSat = 0;   +    pMan->timeSimSat = 0;     +    pMan->timeSat = 0;        +    pMan->timeSatSat = 0;     +    pMan->timeSatUnsat = 0;   +    pMan->timeSatUndec = 0;   +    return RetValue; +} + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/ssw_old/sswClass.c b/src/aig/ssw_old/sswClass.c new file mode 100644 index 00000000..cfbb138c --- /dev/null +++ b/src/aig/ssw_old/sswClass.c @@ -0,0 +1,941 @@ +/**CFile**************************************************************** + +  FileName    [sswClass.c] + +  SystemName  [ABC: Logic synthesis and verification system.] + +  PackageName [Inductive prover with constraints.] + +  Synopsis    [Representation of candidate equivalence classes.] + +  Author      [Alan Mishchenko] +   +  Affiliation [UC Berkeley] + +  Date        [Ver. 1.0. Started - September 1, 2008.] + +  Revision    [$Id: sswClass.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "sswInt.h" + +/* +    The candidate equivalence classes are stored as a vector of pointers  +    to the array of pointers to the nodes in each class. +    The first node of the class is its representative node. +    The representative has the smallest topological order among the class nodes. +    The nodes inside each class are ordered according to their topological order. +    The classes are ordered according to the topo order of their representatives. +*/ + +// internal representation of candidate equivalence classes +struct Ssw_Cla_t_ +{ +    // class information +    Aig_Man_t *      pAig;             // original AIG manager +    Aig_Obj_t ***    pId2Class;        // non-const classes by ID of repr node +    int *            pClassSizes;      // sizes of each equivalence class +    // statistics +    int              nClasses;         // the total number of non-const classes +    int              nCands1;          // the total number of const candidates +    int              nLits;            // the number of literals in all classes +    // memory +    Aig_Obj_t **     pMemClasses;      // memory allocated for equivalence classes +    Aig_Obj_t **     pMemClassesFree;  // memory allocated for equivalence classes to be used +    // temporary data +    Vec_Ptr_t *      vClassOld;        // old equivalence class after splitting +    Vec_Ptr_t *      vClassNew;        // new equivalence class(es) after splitting +    Vec_Ptr_t *      vRefined;         // the nodes refined since the last iteration +    // procedures used for class refinement +    void *           pManData; +    unsigned (*pFuncNodeHash) (void *,Aig_Obj_t *);              // returns hash key of the node +    int (*pFuncNodeIsConst)   (void *,Aig_Obj_t *);              // returns 1 if the node is a constant +    int (*pFuncNodesAreEqual) (void *,Aig_Obj_t *, Aig_Obj_t *); // returns 1 if nodes are equal up to a complement +}; + +//////////////////////////////////////////////////////////////////////// +///                        DECLARATIONS                              /// +//////////////////////////////////////////////////////////////////////// + +static inline Aig_Obj_t *  Ssw_ObjNext( Aig_Obj_t ** ppNexts, Aig_Obj_t * pObj )                       { return ppNexts[pObj->Id];  } +static inline void         Ssw_ObjSetNext( Aig_Obj_t ** ppNexts, Aig_Obj_t * pObj, Aig_Obj_t * pNext ) { ppNexts[pObj->Id] = pNext; } + +// iterator through the equivalence classes +#define Ssw_ManForEachClass( p, ppClass, i )                 \ +    for ( i = 0; i < Aig_ManObjNumMax(p->pAig); i++ )        \ +        if ( ((ppClass) = p->pId2Class[i]) == NULL ) {} else +// iterator through the nodes in one class +#define Ssw_ClassForEachNode( p, pRepr, pNode, i )           \ +    for ( i = 0; i < p->pClassSizes[pRepr->Id]; i++ )        \ +        if ( ((pNode) = p->pId2Class[pRepr->Id][i]) == NULL ) {} else + +//////////////////////////////////////////////////////////////////////// +///                     FUNCTION DEFINITIONS                         /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + +  Synopsis    [Creates one equivalence class.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Ssw_ObjAddClass( Ssw_Cla_t * p, Aig_Obj_t * pRepr, Aig_Obj_t ** pClass, int nSize )  +{ +    assert( p->pId2Class[pRepr->Id] == NULL ); +    assert( pClass[0] == pRepr ); +    p->pId2Class[pRepr->Id] = pClass;  +    assert( p->pClassSizes[pRepr->Id] == 0 ); +    assert( nSize > 1 ); +    p->pClassSizes[pRepr->Id] = nSize; +    p->nClasses++; +    p->nLits += nSize - 1; +} + +/**Function************************************************************* + +  Synopsis    [Removes one equivalence class.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline Aig_Obj_t ** Ssw_ObjRemoveClass( Ssw_Cla_t * p, Aig_Obj_t * pRepr )  +{ +    Aig_Obj_t ** pClass = p->pId2Class[pRepr->Id]; +    int nSize; +    assert( pClass != NULL ); +    p->pId2Class[pRepr->Id] = NULL;  +    nSize = p->pClassSizes[pRepr->Id]; +    assert( nSize > 1 ); +    p->nClasses--; +    p->nLits -= nSize - 1; +    p->pClassSizes[pRepr->Id] = 0; +    return pClass; +} + +/**Function************************************************************* + +  Synopsis    [Starts representation of equivalence classes.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Ssw_Cla_t * Ssw_ClassesStart( Aig_Man_t * pAig ) +{ +    Ssw_Cla_t * p; +    p = ALLOC( Ssw_Cla_t, 1 ); +    memset( p, 0, sizeof(Ssw_Cla_t) ); +    p->pAig         = pAig; +    p->pId2Class    = CALLOC( Aig_Obj_t **, Aig_ManObjNumMax(pAig) ); +    p->pClassSizes  = CALLOC( int, Aig_ManObjNumMax(pAig) ); +    p->vClassOld    = Vec_PtrAlloc( 100 ); +    p->vClassNew    = Vec_PtrAlloc( 100 ); +    p->vRefined     = Vec_PtrAlloc( 1000 ); +    assert( pAig->pReprs == NULL ); +    Aig_ManReprStart( pAig, Aig_ManObjNumMax(pAig) ); +    return p; +} + +/**Function************************************************************* + +  Synopsis    [Starts representation of equivalence classes.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_ClassesSetData( Ssw_Cla_t * p, void * pManData,  +    unsigned (*pFuncNodeHash)(void *,Aig_Obj_t *),               // returns hash key of the node +    int (*pFuncNodeIsConst)(void *,Aig_Obj_t *),                 // returns 1 if the node is a constant +    int (*pFuncNodesAreEqual)(void *,Aig_Obj_t *, Aig_Obj_t *) ) // returns 1 if nodes are equal up to a complement +{ +    p->pManData           = pManData; +    p->pFuncNodeHash      = pFuncNodeHash; +    p->pFuncNodeIsConst   = pFuncNodeIsConst; +    p->pFuncNodesAreEqual = pFuncNodesAreEqual; +} + +/**Function************************************************************* + +  Synopsis    [Stop representation of equivalence classes.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_ClassesStop( Ssw_Cla_t * p ) +{ +    if ( p->vClassNew )    Vec_PtrFree( p->vClassNew ); +    if ( p->vClassOld )    Vec_PtrFree( p->vClassOld ); +    Vec_PtrFree( p->vRefined ); +    FREE( p->pId2Class ); +    FREE( p->pClassSizes ); +    FREE( p->pMemClasses ); +    free( p ); +} + +/**Function************************************************************* + +  Synopsis    [Stop representation of equivalence classes.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Aig_Man_t * Ssw_ClassesReadAig( Ssw_Cla_t * p ) +{ +    return p->pAig; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Vec_Ptr_t * Ssw_ClassesGetRefined( Ssw_Cla_t * p ) +{ +    return p->vRefined; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_ClassesClearRefined( Ssw_Cla_t * p ) +{ +    Vec_PtrClear( p->vRefined ); +} + +/**Function************************************************************* + +  Synopsis    [Stop representation of equivalence classes.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ssw_ClassesCand1Num( Ssw_Cla_t * p ) +{ +    return p->nCands1; +} + +/**Function************************************************************* + +  Synopsis    [Stop representation of equivalence classes.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ssw_ClassesClassNum( Ssw_Cla_t * p ) +{ +    return p->nClasses; +} + +/**Function************************************************************* + +  Synopsis    [Stop representation of equivalence classes.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ssw_ClassesLitNum( Ssw_Cla_t * p ) +{ +    return p->nLits; +} + +/**Function************************************************************* + +  Synopsis    [Stop representation of equivalence classes.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Aig_Obj_t ** Ssw_ClassesReadClass( Ssw_Cla_t * p, Aig_Obj_t * pRepr, int * pnSize ) +{ +    if ( p->pId2Class[pRepr->Id] == NULL ) +        return NULL; +    assert( p->pId2Class[pRepr->Id] != NULL ); +    assert( p->pClassSizes[pRepr->Id] > 1 ); +    *pnSize = p->pClassSizes[pRepr->Id]; +    return p->pId2Class[pRepr->Id]; +} + +/**Function************************************************************* + +  Synopsis    [Stop representation of equivalence classes.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_ClassesCollectClass( Ssw_Cla_t * p, Aig_Obj_t * pRepr, Vec_Ptr_t * vClass ) +{ +    int i; +    Vec_PtrClear( vClass ); +    if ( p->pId2Class[pRepr->Id] == NULL ) +        return; +    assert( p->pClassSizes[pRepr->Id] > 1 ); +    for ( i = 1; i < p->pClassSizes[pRepr->Id]; i++ ) +        Vec_PtrPush( vClass, p->pId2Class[pRepr->Id][i] ); +} + +/**Function************************************************************* + +  Synopsis    [Checks candidate equivalence classes.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_ClassesCheck( Ssw_Cla_t * p ) +{ +    Aig_Obj_t * pObj, * pPrev, ** ppClass; +    int i, k, nLits, nClasses, nCands1; +    nClasses = nLits = 0; +    Ssw_ManForEachClass( p, ppClass, k ) +    { +        pPrev = NULL; +        assert( p->pClassSizes[ppClass[0]->Id] >= 2 ); +        Ssw_ClassForEachNode( p, ppClass[0], pObj, i ) +        { +            if ( i == 0 ) +                assert( Aig_ObjRepr(p->pAig, pObj) == NULL ); +            else +            { +                assert( Aig_ObjRepr(p->pAig, pObj) == ppClass[0] ); +                assert( pPrev->Id < pObj->Id ); +                nLits++; +            } +            pPrev = pObj; +        } +        nClasses++; +    } +    nCands1 = 0; +    Aig_ManForEachObj( p->pAig, pObj, i ) +        nCands1 += Ssw_ObjIsConst1Cand( p->pAig, pObj ); +    assert( p->nLits == nLits ); +    assert( p->nCands1 == nCands1 ); +    assert( p->nClasses == nClasses ); +} + +/**Function************************************************************* + +  Synopsis    [Prints simulation classes.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_ClassesPrintOne( Ssw_Cla_t * p, Aig_Obj_t * pRepr ) +{ +    Aig_Obj_t * pObj; +    int i; +    printf( "{ " ); +    Ssw_ClassForEachNode( p, pRepr, pObj, i ) +        printf( "%d(%d,%d) ", pObj->Id, pObj->Level, Aig_SupportSize(p->pAig,pObj) ); +    printf( "}\n" ); +} + +/**Function************************************************************* + +  Synopsis    [Prints simulation classes.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_ClassesPrint( Ssw_Cla_t * p, int fVeryVerbose ) +{ +    Aig_Obj_t ** ppClass; +    Aig_Obj_t * pObj; +    int i; +    printf( "Equivalence classes: Const1 = %5d. Class = %5d. Lit = %5d.\n",  +        p->nCands1, p->nClasses, p->nCands1+p->nLits ); +    if ( !fVeryVerbose ) +        return; +    printf( "Constants { " ); +    Aig_ManForEachObj( p->pAig, pObj, i ) +        if ( Ssw_ObjIsConst1Cand( p->pAig, pObj ) ) +            printf( "%d(%d,%d) ", pObj->Id, pObj->Level, Aig_SupportSize(p->pAig,pObj) ); +    printf( "}\n" ); +    Ssw_ManForEachClass( p, ppClass, i ) +    { +        printf( "%3d (%3d) : ", i, p->pClassSizes[i] ); +        Ssw_ClassesPrintOne( p, ppClass[0] ); +    } +    printf( "\n" ); +} + +/**Function************************************************************* + +  Synopsis    [Prints simulation classes.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_ClassesRemoveNode( Ssw_Cla_t * p, Aig_Obj_t * pObj ) +{ +    Aig_Obj_t * pRepr, * pTemp; +    assert( p->pClassSizes[pObj->Id] == 0 ); +    assert( p->pId2Class[pObj->Id] == NULL ); +    pRepr = Aig_ObjRepr( p->pAig, pObj ); +    assert( pRepr != NULL ); +    Vec_PtrPush( p->vRefined, pObj ); +    if ( Ssw_ObjIsConst1Cand( p->pAig, pObj ) ) +    { +        assert( p->pClassSizes[pRepr->Id] == 0 ); +        assert( p->pId2Class[pRepr->Id] == NULL ); +        Aig_ObjSetRepr( p->pAig, pObj, NULL ); +        p->nCands1--; +        return; +    } +    Vec_PtrPush( p->vRefined, pRepr ); +    Aig_ObjSetRepr( p->pAig, pObj, NULL ); +    assert( p->pId2Class[pRepr->Id][0] == pRepr ); +    assert( p->pClassSizes[pRepr->Id] >= 2 ); +    if ( p->pClassSizes[pRepr->Id] == 2 ) +    { +        p->pId2Class[pRepr->Id] = NULL; +        p->nClasses--; +        p->pClassSizes[pRepr->Id] = 0; +        p->nLits--; +    } +    else +    { +        int i, k = 0; +        // remove the entry from the class +        Ssw_ClassForEachNode( p, pRepr, pTemp, i ) +            if ( pTemp != pObj ) +                p->pId2Class[pRepr->Id][k++] = pTemp; +        assert( k + 1 == p->pClassSizes[pRepr->Id] ); +        // reduce the class +        p->pClassSizes[pRepr->Id]--; +        p->nLits--; +    } +} + +/**Function************************************************************* + +  Synopsis    [Creates initial simulation classes.] + +  Description [Assumes that simulation info is assigned.] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Ssw_Cla_t * Ssw_ClassesPrepare( Aig_Man_t * pAig, int fLatchCorr, int nMaxLevs, int fVerbose ) +{ +    Ssw_Cla_t * p; +    Ssw_Sml_t * pSml; +    Aig_Obj_t ** ppTable, ** ppNexts, ** ppClassNew; +    Aig_Obj_t * pObj, * pTemp, * pRepr; +    int i, k, nTableSize, nNodes, iEntry, nEntries, nEntries2; +    int clk; + +    // start the classes +    p = Ssw_ClassesStart( pAig ); + +    // perform sequential simulation +clk = clock(); +    pSml = Ssw_SmlSimulateSeq( pAig, 0, 32, 4 ); +if ( fVerbose ) +{ +PRT( "Simulation of 32 frames with 4 words", clock() - clk ); +} + +    // set comparison procedures +clk = clock(); +    Ssw_ClassesSetData( p, pSml, Ssw_SmlObjHashWord, Ssw_SmlObjIsConstWord, Ssw_SmlObjsAreEqualWord ); + +    // allocate the hash table hashing simulation info into nodes +    nTableSize = Aig_PrimeCudd( Aig_ManObjNumMax(p->pAig)/4 ); +    ppTable = CALLOC( Aig_Obj_t *, nTableSize );  +    ppNexts = CALLOC( Aig_Obj_t *, Aig_ManObjNumMax(p->pAig) );  + +    // add all the nodes to the hash table +    nEntries = 0; +    Aig_ManForEachObj( p->pAig, pObj, i ) +    { +        if ( fLatchCorr ) +        { +            if ( !Saig_ObjIsLo(p->pAig, pObj) ) +                continue; +        } +        else +        { +            if ( !Aig_ObjIsNode(pObj) && !Aig_ObjIsPi(pObj) ) +                continue; +            // skip the node with more that the given number of levels +            if ( nMaxLevs && (int)pObj->Level > nMaxLevs ) +                continue; +        } +        // check if the node belongs to the class of constant 1 +        if ( p->pFuncNodeIsConst( p->pManData, pObj ) ) +        { +            Ssw_ObjSetConst1Cand( p->pAig, pObj ); +            p->nCands1++; +            continue; +        } +        // hash the node by its simulation info +        iEntry = p->pFuncNodeHash( p->pManData, pObj ) % nTableSize; +        // add the node to the class +        if ( ppTable[iEntry] == NULL ) +            ppTable[iEntry] = pObj; +        else +        { +            // set the representative of this node +            pRepr = ppTable[iEntry]; +            Aig_ObjSetRepr( p->pAig, pObj, pRepr ); +            // add node to the table +            if ( Ssw_ObjNext( ppNexts, pRepr ) == NULL ) +            { // this will be the second entry +                p->pClassSizes[pRepr->Id]++; +                nEntries++; +            } +            // add the entry to the list +            Ssw_ObjSetNext( ppNexts, pObj, Ssw_ObjNext( ppNexts, pRepr ) ); +            Ssw_ObjSetNext( ppNexts, pRepr, pObj ); +            p->pClassSizes[pRepr->Id]++; +            nEntries++; +        } +    } + +    // allocate room for classes +    p->pMemClasses = ALLOC( Aig_Obj_t *, nEntries + p->nCands1 ); +    p->pMemClassesFree = p->pMemClasses + nEntries; +  +    // copy the entries into storage in the topological order +    nEntries2 = 0; +    Aig_ManForEachObj( p->pAig, pObj, i ) +    { +        if ( !Aig_ObjIsNode(pObj) && !Aig_ObjIsPi(pObj) ) +            continue; +        nNodes = p->pClassSizes[pObj->Id]; +        // skip the nodes that are not representatives of non-trivial classes +        if ( nNodes == 0 ) +            continue; +        assert( nNodes > 1 ); +        // add the nodes to the class in the topological order +        ppClassNew = p->pMemClasses + nEntries2; +        ppClassNew[0] = pObj; +        for ( pTemp = Ssw_ObjNext(ppNexts, pObj), k = 1; pTemp;  +              pTemp = Ssw_ObjNext(ppNexts, pTemp), k++ ) +        { +            ppClassNew[nNodes-k] = pTemp; +        } +        // add the class of nodes +        p->pClassSizes[pObj->Id] = 0; +        Ssw_ObjAddClass( p, pObj, ppClassNew, nNodes ); +        // increment the number of entries +        nEntries2 += nNodes; +    } +    assert( nEntries == nEntries2 ); +    free( ppTable ); +    free( ppNexts ); + +    // now it is time to refine the classes +    Ssw_ClassesRefine( p, 1 ); +    Ssw_ClassesCheck( p ); +    Ssw_SmlStop( pSml ); +//    Ssw_ClassesPrint( p, 0 ); +if ( fVerbose ) +{ +PRT( "Collecting candidate equival classes", clock() - clk ); +} +    return p; +} + +/**Function************************************************************* + +  Synopsis    [Creates initial simulation classes.] + +  Description [Assumes that simulation info is assigned.] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Ssw_Cla_t * Ssw_ClassesPrepareSimple( Aig_Man_t * pAig, int fLatchCorr, int nMaxLevs ) +{ +    Ssw_Cla_t * p; +    Aig_Obj_t * pObj; +    int i; +    // start the classes +    p = Ssw_ClassesStart( pAig ); +    // go through the nodes +    p->nCands1 = 0; +    Aig_ManForEachObj( pAig, pObj, i ) +    { +        if ( fLatchCorr ) +        { +            if ( !Saig_ObjIsLo(pAig, pObj) ) +                continue; +        } +        else +        { +            if ( !Aig_ObjIsNode(pObj) && !Saig_ObjIsLo(pAig, pObj) ) +                continue; +            // skip the node with more that the given number of levels +            if ( nMaxLevs && (int)pObj->Level > nMaxLevs ) +                continue; +        } +        Ssw_ObjSetConst1Cand( pAig, pObj ); +        p->nCands1++; +    } +    // allocate room for classes +    p->pMemClassesFree = p->pMemClasses = ALLOC( Aig_Obj_t *, p->nCands1 ); +//    Ssw_ClassesPrint( p, 0 ); +    return p; +} + +/**Function************************************************************* + +  Synopsis    [Creates initial simulation classes.] + +  Description [Assumes that simulation info is assigned.] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Ssw_Cla_t * Ssw_ClassesPrepareTargets( Aig_Man_t * pAig ) +{ +    Ssw_Cla_t * p; +    Aig_Obj_t * pObj; +    int i; +    // start the classes +    p = Ssw_ClassesStart( pAig ); +    // go through the nodes +    p->nCands1 = 0; +    Saig_ManForEachPo( pAig, pObj, i ) +    { +        Ssw_ObjSetConst1Cand( pAig, Aig_ObjFanin0(pObj) ); +        p->nCands1++; +    } +    // allocate room for classes +    p->pMemClassesFree = p->pMemClasses = ALLOC( Aig_Obj_t *, p->nCands1 ); +//    Ssw_ClassesPrint( p, 0 ); +    return p; +} + +/**Function************************************************************* + +  Synopsis    [Creates classes from the temporary representation.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Ssw_Cla_t * Ssw_ClassesPreparePairs( Aig_Man_t * pAig, Vec_Int_t ** pvClasses ) +{ +    Ssw_Cla_t * p; +    Aig_Obj_t ** ppClassNew; +    Aig_Obj_t * pObj, * pRepr, * pPrev; +    int i, k, nTotalObjs, nEntries, Entry; +    // start the classes +    p = Ssw_ClassesStart( pAig ); +    // count the number of entries in the classes +    nTotalObjs = 0; +    for ( i = 0; i < Aig_ManObjNumMax(pAig); i++ ) +        nTotalObjs += pvClasses[i] ? Vec_IntSize(pvClasses[i]) : 0;  +    // allocate memory for classes +    p->pMemClasses = ALLOC( Aig_Obj_t *, nTotalObjs ); +    // create constant-1 class +    if ( pvClasses[0] ) +    Vec_IntForEachEntry( pvClasses[0], Entry, i ) +    { +        assert( (i == 0) == (Entry == 0) ); +        if ( i == 0 ) +            continue; +        pObj = Aig_ManObj( pAig, Entry ); +        Ssw_ObjSetConst1Cand( pAig, pObj ); +        p->nCands1++; +    } +    // create classes +    nEntries = 0; +    for ( i = 1; i < Aig_ManObjNumMax(pAig); i++ ) +    { +        if ( pvClasses[i] == NULL ) +            continue; +        // get room for storing the class +        ppClassNew = p->pMemClasses + nEntries; +        nEntries  += Vec_IntSize( pvClasses[i] ); +        // store the nodes of the class +        pPrev = pRepr = Aig_ManObj( pAig, Vec_IntEntry(pvClasses[i],0) ); +        ppClassNew[0] = pRepr; +        Vec_IntForEachEntryStart( pvClasses[i], Entry, k, 1 ) +        { +            pObj = Aig_ManObj( pAig, Entry ); +            assert( pPrev->Id < pObj->Id ); +            pPrev = pObj; +            ppClassNew[k] = pObj; +            Aig_ObjSetRepr( pAig, pObj, pRepr ); +        } +        // create new class +        Ssw_ObjAddClass( p, pRepr, ppClassNew, Vec_IntSize(pvClasses[i]) ); +    } +    // prepare room for new classes +    p->pMemClassesFree = p->pMemClasses + nEntries; +    Ssw_ClassesCheck( p ); +//    Ssw_ClassesPrint( p, 0 ); +    return p; +} + +/**Function************************************************************* + +  Synopsis    [Iteratively refines the classes after simulation.] + +  Description [Returns the number of refinements performed.] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ssw_ClassesRefineOneClass( Ssw_Cla_t * p, Aig_Obj_t * pReprOld, int fRecursive ) +{ +    Aig_Obj_t ** pClassOld, ** pClassNew; +    Aig_Obj_t * pObj, * pReprNew; +    int i; + +    // split the class +    Vec_PtrClear( p->vClassOld ); +    Vec_PtrClear( p->vClassNew ); +    Ssw_ClassForEachNode( p, pReprOld, pObj, i ) +        if ( p->pFuncNodesAreEqual(p->pManData, pReprOld, pObj) ) +            Vec_PtrPush( p->vClassOld, pObj ); +        else +            Vec_PtrPush( p->vClassNew, pObj ); +    // check if splitting happened +    if ( Vec_PtrSize(p->vClassNew) == 0 ) +        return 0; +    // remember that this class is refined +    Ssw_ClassForEachNode( p, pReprOld, pObj, i ) +        Vec_PtrPush( p->vRefined, pObj ); + +    // get the new representative +    pReprNew = Vec_PtrEntry( p->vClassNew, 0 ); +    assert( Vec_PtrSize(p->vClassOld) > 0 ); +    assert( Vec_PtrSize(p->vClassNew) > 0 ); + +    // create old class +    pClassOld = Ssw_ObjRemoveClass( p, pReprOld ); +    Vec_PtrForEachEntry( p->vClassOld, pObj, i ) +    { +        pClassOld[i] = pObj; +        Aig_ObjSetRepr( p->pAig, pObj, i? pReprOld : NULL ); +    } +    // create new class +    pClassNew = pClassOld + i; +    Vec_PtrForEachEntry( p->vClassNew, pObj, i ) +    { +        pClassNew[i] = pObj; +        Aig_ObjSetRepr( p->pAig, pObj, i? pReprNew : NULL ); +    } + +    // put classes back +    if ( Vec_PtrSize(p->vClassOld) > 1 ) +        Ssw_ObjAddClass( p, pReprOld, pClassOld, Vec_PtrSize(p->vClassOld) ); +    if ( Vec_PtrSize(p->vClassNew) > 1 ) +        Ssw_ObjAddClass( p, pReprNew, pClassNew, Vec_PtrSize(p->vClassNew) ); + +    // check if the class should be recursively refined +    if ( fRecursive && Vec_PtrSize(p->vClassNew) > 1 ) +        return 1 + Ssw_ClassesRefineOneClass( p, pReprNew, 1 ); +    return 1; +} + +/**Function************************************************************* + +  Synopsis    [Refines the classes after simulation.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ssw_ClassesRefine( Ssw_Cla_t * p, int fRecursive ) +{ +    Aig_Obj_t ** ppClass; +    int i, nRefis = 0; +    Ssw_ManForEachClass( p, ppClass, i ) +        nRefis += Ssw_ClassesRefineOneClass( p, ppClass[0], fRecursive ); +    return nRefis; +} + +/**Function************************************************************* + +  Synopsis    [Refine the group of constant 1 nodes.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ssw_ClassesRefineConst1Group( Ssw_Cla_t * p, Vec_Ptr_t * vRoots, int fRecursive ) +{ +    Aig_Obj_t * pObj, * pReprNew, ** ppClassNew; +    int i; +    if ( Vec_PtrSize(vRoots) == 0 ) +        return 0; +    // collect the nodes to be refined +    Vec_PtrClear( p->vClassNew ); +    Vec_PtrForEachEntry( vRoots, pObj, i ) +        if ( !p->pFuncNodeIsConst( p->pManData, pObj ) ) +            Vec_PtrPush( p->vClassNew, pObj ); +    // check if there is a new class +    if ( Vec_PtrSize(p->vClassNew) == 0 ) +        return 0; +    p->nCands1 -= Vec_PtrSize(p->vClassNew); +    pReprNew = Vec_PtrEntry( p->vClassNew, 0 ); +    Aig_ObjSetRepr( p->pAig, pReprNew, NULL ); +    if ( Vec_PtrSize(p->vClassNew) == 1 ) +        return 1; +    // create a new class composed of these nodes +    ppClassNew = p->pMemClassesFree; +    p->pMemClassesFree += Vec_PtrSize(p->vClassNew); +    Vec_PtrForEachEntry( p->vClassNew, pObj, i ) +    { +        ppClassNew[i] = pObj; +        Aig_ObjSetRepr( p->pAig, pObj, i? pReprNew : NULL ); +    } +    Ssw_ObjAddClass( p, pReprNew, ppClassNew, Vec_PtrSize(p->vClassNew) ); +    // refine them recursively +    if ( fRecursive ) +        return 1 + Ssw_ClassesRefineOneClass( p, pReprNew, 1 ); +    return 1; +} + +/**Function************************************************************* + +  Synopsis    [Refine the group of constant 1 nodes.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ssw_ClassesRefineConst1( Ssw_Cla_t * p, int fRecursive ) +{ +    Aig_Obj_t * pObj, * pReprNew, ** ppClassNew; +    int i; +    // collect the nodes to be refined +    Vec_PtrClear( p->vClassNew ); +    for ( i = 0; i < Vec_PtrSize(p->pAig->vObjs); i++ ) +        if ( p->pAig->pReprs[i] == Aig_ManConst1(p->pAig) ) +        { +            pObj = Aig_ManObj( p->pAig, i ); +            if ( !p->pFuncNodeIsConst( p->pManData, pObj ) ) +            { +                Vec_PtrPush( p->vClassNew, pObj ); +                Vec_PtrPush( p->vRefined, pObj ); +            } +        } +    // check if there is a new class +    if ( Vec_PtrSize(p->vClassNew) == 0 ) +        return 0; +    p->nCands1 -= Vec_PtrSize(p->vClassNew); +    pReprNew = Vec_PtrEntry( p->vClassNew, 0 ); +    Aig_ObjSetRepr( p->pAig, pReprNew, NULL ); +    if ( Vec_PtrSize(p->vClassNew) == 1 ) +        return 1; +    // create a new class composed of these nodes +    ppClassNew = p->pMemClassesFree; +    p->pMemClassesFree += Vec_PtrSize(p->vClassNew); +    Vec_PtrForEachEntry( p->vClassNew, pObj, i ) +    { +        ppClassNew[i] = pObj; +        Aig_ObjSetRepr( p->pAig, pObj, i? pReprNew : NULL ); +    } +    Ssw_ObjAddClass( p, pReprNew, ppClassNew, Vec_PtrSize(p->vClassNew) ); +    // refine them recursively +    if ( fRecursive ) +        return 1 + Ssw_ClassesRefineOneClass( p, pReprNew, 1 ); +    return 1; +} + + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/ssw_old/sswCnf.c b/src/aig/ssw_old/sswCnf.c new file mode 100644 index 00000000..e4b8f9f6 --- /dev/null +++ b/src/aig/ssw_old/sswCnf.c @@ -0,0 +1,335 @@ +/**CFile**************************************************************** + +  FileName    [sswCnf.c] + +  SystemName  [ABC: Logic synthesis and verification system.] + +  PackageName [Inductive prover with constraints.] + +  Synopsis    [Computation of CNF.] + +  Author      [Alan Mishchenko] +   +  Affiliation [UC Berkeley] + +  Date        [Ver. 1.0. Started - September 1, 2008.] + +  Revision    [$Id: sswCnf.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "sswInt.h" + +//////////////////////////////////////////////////////////////////////// +///                        DECLARATIONS                              /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +///                     FUNCTION DEFINITIONS                         /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + +  Synopsis    [Addes clauses to the solver.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_AddClausesMux( Ssw_Man_t * p, Aig_Obj_t * pNode ) +{ +    Aig_Obj_t * pNodeI, * pNodeT, * pNodeE; +    int pLits[4], RetValue, VarF, VarI, VarT, VarE, fCompT, fCompE; + +    assert( !Aig_IsComplement( pNode ) ); +    assert( Aig_ObjIsMuxType( pNode ) ); +    // get nodes (I = if, T = then, E = else) +    pNodeI = Aig_ObjRecognizeMux( pNode, &pNodeT, &pNodeE ); +    // get the variable numbers +    VarF = Ssw_ObjSatNum(p,pNode); +    VarI = Ssw_ObjSatNum(p,pNodeI); +    VarT = Ssw_ObjSatNum(p,Aig_Regular(pNodeT)); +    VarE = Ssw_ObjSatNum(p,Aig_Regular(pNodeE)); +    // get the complementation flags +    fCompT = Aig_IsComplement(pNodeT); +    fCompE = Aig_IsComplement(pNodeE); + +    // f = ITE(i, t, e) + +    // i' + t' + f +    // i' + t  + f' +    // i  + e' + f +    // i  + e  + f' + +    // create four clauses +    pLits[0] = toLitCond(VarI, 1); +    pLits[1] = toLitCond(VarT, 1^fCompT); +    pLits[2] = toLitCond(VarF, 0); +    if ( p->pPars->fPolarFlip ) +    { +        if ( pNodeI->fPhase )               pLits[0] = lit_neg( pLits[0] ); +        if ( Aig_Regular(pNodeT)->fPhase )  pLits[1] = lit_neg( pLits[1] ); +        if ( pNode->fPhase )                pLits[2] = lit_neg( pLits[2] ); +    } +    RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 ); +    assert( RetValue ); +    pLits[0] = toLitCond(VarI, 1); +    pLits[1] = toLitCond(VarT, 0^fCompT); +    pLits[2] = toLitCond(VarF, 1); +    if ( p->pPars->fPolarFlip ) +    { +        if ( pNodeI->fPhase )               pLits[0] = lit_neg( pLits[0] ); +        if ( Aig_Regular(pNodeT)->fPhase )  pLits[1] = lit_neg( pLits[1] ); +        if ( pNode->fPhase )                pLits[2] = lit_neg( pLits[2] ); +    } +    RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 ); +    assert( RetValue ); +    pLits[0] = toLitCond(VarI, 0); +    pLits[1] = toLitCond(VarE, 1^fCompE); +    pLits[2] = toLitCond(VarF, 0); +    if ( p->pPars->fPolarFlip ) +    { +        if ( pNodeI->fPhase )               pLits[0] = lit_neg( pLits[0] ); +        if ( Aig_Regular(pNodeE)->fPhase )  pLits[1] = lit_neg( pLits[1] ); +        if ( pNode->fPhase )                pLits[2] = lit_neg( pLits[2] ); +    } +    RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 ); +    assert( RetValue ); +    pLits[0] = toLitCond(VarI, 0); +    pLits[1] = toLitCond(VarE, 0^fCompE); +    pLits[2] = toLitCond(VarF, 1); +    if ( p->pPars->fPolarFlip ) +    { +        if ( pNodeI->fPhase )               pLits[0] = lit_neg( pLits[0] ); +        if ( Aig_Regular(pNodeE)->fPhase )  pLits[1] = lit_neg( pLits[1] ); +        if ( pNode->fPhase )                pLits[2] = lit_neg( pLits[2] ); +    } +    RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 ); +    assert( RetValue ); + +    // two additional clauses +    // t' & e' -> f' +    // t  & e  -> f  + +    // t  + e   + f' +    // t' + e'  + f  + +    if ( VarT == VarE ) +    { +//        assert( fCompT == !fCompE ); +        return; +    } + +    pLits[0] = toLitCond(VarT, 0^fCompT); +    pLits[1] = toLitCond(VarE, 0^fCompE); +    pLits[2] = toLitCond(VarF, 1); +    if ( p->pPars->fPolarFlip ) +    { +        if ( Aig_Regular(pNodeT)->fPhase )  pLits[0] = lit_neg( pLits[0] ); +        if ( Aig_Regular(pNodeE)->fPhase )  pLits[1] = lit_neg( pLits[1] ); +        if ( pNode->fPhase )                pLits[2] = lit_neg( pLits[2] ); +    } +    RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 ); +    assert( RetValue ); +    pLits[0] = toLitCond(VarT, 1^fCompT); +    pLits[1] = toLitCond(VarE, 1^fCompE); +    pLits[2] = toLitCond(VarF, 0); +    if ( p->pPars->fPolarFlip ) +    { +        if ( Aig_Regular(pNodeT)->fPhase )  pLits[0] = lit_neg( pLits[0] ); +        if ( Aig_Regular(pNodeE)->fPhase )  pLits[1] = lit_neg( pLits[1] ); +        if ( pNode->fPhase )                pLits[2] = lit_neg( pLits[2] ); +    } +    RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 ); +    assert( RetValue ); +} + +/**Function************************************************************* + +  Synopsis    [Addes clauses to the solver.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_AddClausesSuper( Ssw_Man_t * p, Aig_Obj_t * pNode, Vec_Ptr_t * vSuper ) +{ +    Aig_Obj_t * pFanin; +    int * pLits, nLits, RetValue, i; +    assert( !Aig_IsComplement(pNode) ); +    assert( Aig_ObjIsNode( pNode ) ); +    // create storage for literals +    nLits = Vec_PtrSize(vSuper) + 1; +    pLits = ALLOC( int, nLits ); +    // suppose AND-gate is A & B = C +    // add !A => !C   or   A + !C +    Vec_PtrForEachEntry( vSuper, pFanin, i ) +    { +        pLits[0] = toLitCond(Ssw_ObjSatNum(p,Aig_Regular(pFanin)), Aig_IsComplement(pFanin)); +        pLits[1] = toLitCond(Ssw_ObjSatNum(p,pNode), 1); +        if ( p->pPars->fPolarFlip ) +        { +            if ( Aig_Regular(pFanin)->fPhase )  pLits[0] = lit_neg( pLits[0] ); +            if ( pNode->fPhase )                pLits[1] = lit_neg( pLits[1] ); +        } +        RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 2 ); +        assert( RetValue ); +    } +    // add A & B => C   or   !A + !B + C +    Vec_PtrForEachEntry( vSuper, pFanin, i ) +    { +        pLits[i] = toLitCond(Ssw_ObjSatNum(p,Aig_Regular(pFanin)), !Aig_IsComplement(pFanin)); +        if ( p->pPars->fPolarFlip ) +        { +            if ( Aig_Regular(pFanin)->fPhase )  pLits[i] = lit_neg( pLits[i] ); +        } +    } +    pLits[nLits-1] = toLitCond(Ssw_ObjSatNum(p,pNode), 0); +    if ( p->pPars->fPolarFlip ) +    { +        if ( pNode->fPhase )  pLits[nLits-1] = lit_neg( pLits[nLits-1] ); +    } +    RetValue = sat_solver_addclause( p->pSat, pLits, pLits + nLits ); +    assert( RetValue ); +    free( pLits ); +} + +/**Function************************************************************* + +  Synopsis    [Collects the supergate.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_CollectSuper_rec( Aig_Obj_t * pObj, Vec_Ptr_t * vSuper, int fFirst, int fUseMuxes ) +{ +    // if the new node is complemented or a PI, another gate begins +    if ( Aig_IsComplement(pObj) || Aig_ObjIsPi(pObj) ||  +         (!fFirst && Aig_ObjRefs(pObj) > 1) ||  +         (fUseMuxes && Aig_ObjIsMuxType(pObj)) ) +    { +        Vec_PtrPushUnique( vSuper, pObj ); +        return; +    } +    // go through the branches +    Ssw_CollectSuper_rec( Aig_ObjChild0(pObj), vSuper, 0, fUseMuxes ); +    Ssw_CollectSuper_rec( Aig_ObjChild1(pObj), vSuper, 0, fUseMuxes ); +} + +/**Function************************************************************* + +  Synopsis    [Collects the supergate.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_CollectSuper( Aig_Obj_t * pObj, int fUseMuxes, Vec_Ptr_t * vSuper ) +{ +    assert( !Aig_IsComplement(pObj) ); +    assert( !Aig_ObjIsPi(pObj) ); +    Vec_PtrClear( vSuper ); +    Ssw_CollectSuper_rec( pObj, vSuper, 1, fUseMuxes ); +} + +/**Function************************************************************* + +  Synopsis    [Updates the solver clause database.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_ObjAddToFrontier( Ssw_Man_t * p, Aig_Obj_t * pObj, Vec_Ptr_t * vFrontier ) +{ +    assert( !Aig_IsComplement(pObj) ); +    if ( Ssw_ObjSatNum(p,pObj) ) +        return; +    assert( Ssw_ObjSatNum(p,pObj) == 0 ); +    if ( Aig_ObjIsConst1(pObj) ) +        return; +    if ( p->pPars->fLatchCorrOpt ) +    { +        Vec_PtrPush( p->vUsedNodes, pObj ); +        if ( Aig_ObjIsPi(pObj) ) +            Vec_PtrPush( p->vUsedPis, pObj ); +    } +    Ssw_ObjSetSatNum( p, pObj, p->nSatVars++ ); +    sat_solver_setnvars( p->pSat, 100 * (1 + p->nSatVars / 100) ); +    if ( Aig_ObjIsNode(pObj) ) +        Vec_PtrPush( vFrontier, pObj ); +} + +/**Function************************************************************* + +  Synopsis    [Updates the solver clause database.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_CnfNodeAddToSolver( Ssw_Man_t * p, Aig_Obj_t * pObj ) +{  +    Vec_Ptr_t * vFrontier; +    Aig_Obj_t * pNode, * pFanin; +    int i, k, fUseMuxes = 1; +    // quit if CNF is ready +    if ( Ssw_ObjSatNum(p,pObj) ) +        return; +    // start the frontier +    vFrontier = Vec_PtrAlloc( 100 ); +    Ssw_ObjAddToFrontier( p, pObj, vFrontier ); +    // explore nodes in the frontier +    Vec_PtrForEachEntry( vFrontier, pNode, i ) +    { +        // create the supergate +        assert( Ssw_ObjSatNum(p,pNode) ); +        if ( fUseMuxes && Aig_ObjIsMuxType(pNode) ) +        { +            Vec_PtrClear( p->vFanins ); +            Vec_PtrPushUnique( p->vFanins, Aig_ObjFanin0( Aig_ObjFanin0(pNode) ) ); +            Vec_PtrPushUnique( p->vFanins, Aig_ObjFanin0( Aig_ObjFanin1(pNode) ) ); +            Vec_PtrPushUnique( p->vFanins, Aig_ObjFanin1( Aig_ObjFanin0(pNode) ) ); +            Vec_PtrPushUnique( p->vFanins, Aig_ObjFanin1( Aig_ObjFanin1(pNode) ) ); +            Vec_PtrForEachEntry( p->vFanins, pFanin, k ) +                Ssw_ObjAddToFrontier( p, Aig_Regular(pFanin), vFrontier ); +            Ssw_AddClausesMux( p, pNode ); +        } +        else +        { +            Ssw_CollectSuper( pNode, fUseMuxes, p->vFanins ); +            Vec_PtrForEachEntry( p->vFanins, pFanin, k ) +                Ssw_ObjAddToFrontier( p, Aig_Regular(pFanin), vFrontier ); +            Ssw_AddClausesSuper( p, pNode, p->vFanins ); +        } +        assert( Vec_PtrSize(p->vFanins) > 1 ); +    } +    Vec_PtrFree( vFrontier ); +} + + + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/ssw_old/sswCore.c b/src/aig/ssw_old/sswCore.c new file mode 100644 index 00000000..5b33d96c --- /dev/null +++ b/src/aig/ssw_old/sswCore.c @@ -0,0 +1,293 @@ +/**CFile**************************************************************** + +  FileName    [sswCore.c] + +  SystemName  [ABC: Logic synthesis and verification system.] + +  PackageName [Inductive prover with constraints.] + +  Synopsis    [The core procedures.] + +  Author      [Alan Mishchenko] +   +  Affiliation [UC Berkeley] + +  Date        [Ver. 1.0. Started - September 1, 2008.] + +  Revision    [$Id: sswCore.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "sswInt.h" + +//////////////////////////////////////////////////////////////////////// +///                        DECLARATIONS                              /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +///                     FUNCTION DEFINITIONS                         /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + +  Synopsis    [This procedure sets default parameters.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_ManSetDefaultParams( Ssw_Pars_t * p ) +{ +    memset( p, 0, sizeof(Ssw_Pars_t) ); +    p->nPartSize      =     0;  // size of the partition +    p->nOverSize      =     0;  // size of the overlap between partitions +    p->nFramesK       =     1;  // the induction depth +    p->nFramesAddSim  =     0;  // additional frames to simulate +    p->nConstrs       =     0;  // treat the last nConstrs POs as seq constraints +    p->nBTLimit       =  1000;  // conflict limit at a node +    p->nMinDomSize    =   100;  // min clock domain considered for optimization +    p->fPolarFlip     =     0;  // uses polarity adjustment +    p->fSkipCheck     =     0;  // do not run equivalence check for unaffected cones +    p->fLatchCorr     =     0;  // performs register correspondence +    p->fSemiFormal    =     0;  // enable semiformal filtering +    p->fUniqueness    =     0;  // enable uniqueness constraints +    p->fVerbose       =     0;  // verbose stats +    // latch correspondence +    p->fLatchCorrOpt  =     0;  // performs optimized register correspondence +    p->nSatVarMax     =  1000;  // the max number of SAT variables +    p->nRecycleCalls  =    50;  // calls to perform before recycling SAT solver +    // return values +    p->nIters         =     0;  // the number of iterations performed +} + +/**Function************************************************************* + +  Synopsis    [This procedure sets default parameters.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_ManSetDefaultParamsLcorr( Ssw_Pars_t * p ) +{ +    Ssw_ManSetDefaultParams( p ); +    p->fLatchCorrOpt = 1; +    p->nBTLimit      = 10000; +} + +/**Function************************************************************* + +  Synopsis    [Performs computation of signal correspondence with constraints.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Aig_Man_t * Ssw_SignalCorrespondenceRefine( Ssw_Man_t * p ) +{ +    int nSatProof, nSatCallsSat, nRecycles, nSatFailsReal; +    Aig_Man_t * pAigNew; +    int RetValue, nIter; +    int clk, clkTotal = clock(); +    // get the starting stats +    p->nLitsBeg  = Ssw_ClassesLitNum( p->ppClasses ); +    p->nNodesBeg = Aig_ManNodeNum(p->pAig); +    p->nRegsBeg  = Aig_ManRegNum(p->pAig); +    // refine classes using BMC +    if ( p->pPars->fVerbose ) +    { +        printf( "Before BMC: " ); +        Ssw_ClassesPrint( p->ppClasses, 0 ); +    } +    if ( !p->pPars->fLatchCorr ) +    {  +        Ssw_ManSweepBmc( p ); +        Ssw_ManCleanup( p ); +    } +    if ( p->pPars->fVerbose ) +    { +        printf( "After  BMC: " ); +        Ssw_ClassesPrint( p->ppClasses, 0 ); +    } +    // apply semi-formal filtering +    if ( p->pPars->fSemiFormal ) +    { +        Aig_Man_t * pSRed; +        Ssw_FilterUsingBmc( p, 0, 2000, p->pPars->fVerbose ); +//        Ssw_FilterUsingBmc( p, 1, 100000, p->pPars->fVerbose ); +        pSRed = Ssw_SpeculativeReduction( p ); +        Aig_ManDumpBlif( pSRed, "srm.blif", NULL, NULL ); +        Aig_ManStop( pSRed ); +    } +    // refine classes using induction +    nSatProof = nSatCallsSat = nRecycles = nSatFailsReal = 0; +    for ( nIter = 0; ; nIter++ ) +    { +clk = clock(); +        if ( p->pPars->fLatchCorrOpt ) +        { +            RetValue = Ssw_ManSweepLatch( p ); +            if ( p->pPars->fVerbose ) +            { +                printf( "%3d : Const = %6d. Cl = %6d. Pr = %5d. Cex = %5d. Rcl = %3d. F = %3d. ",  +                    nIter, Ssw_ClassesCand1Num(p->ppClasses), Ssw_ClassesClassNum(p->ppClasses),  +                    p->nSatProof-nSatProof, p->nSatCallsSat-nSatCallsSat,  +                    p->nRecycles-nRecycles, p->nSatFailsReal-nSatFailsReal ); +                PRT( "T", clock() - clk ); +                nSatProof     = p->nSatProof; +                nSatCallsSat  = p->nSatCallsSat; +                nRecycles     = p->nRecycles; +                nSatFailsReal = p->nSatFailsReal; +            }  +        } +        else +        { +//            if ( nIter == 6 ) +//                p->pPars->fUniqueness = 0; + +            RetValue = Ssw_ManSweep( p ); +            if ( p->pPars->fVerbose ) +            { +                printf( "%3d : Const = %6d. Cl = %6d. LR = %6d. NR = %6d. U = %3d. F = %2d. ",  +                    nIter, Ssw_ClassesCand1Num(p->ppClasses), Ssw_ClassesClassNum(p->ppClasses),  +                    p->nConstrReduced, Aig_ManNodeNum(p->pFrames), p->nUniques, p->nSatFailsReal ); +                if ( p->pPars->fSkipCheck ) +                    printf( "Use = %5d. Skip = %5d. ",  +                        p->nRefUse, p->nRefSkip ); +                PRT( "T", clock() - clk ); +            }  +        } +        Ssw_ManCleanup( p ); +        if ( !RetValue ) +            break; +/* +        { +            static int Flag = 0; +            if ( Flag++ == 4 && nIter == 4 ) +            { +                Aig_Man_t * pSRed; +                pSRed = Ssw_SpeculativeReduction( p ); +                Aig_ManDumpBlif( pSRed, "srm.blif", NULL, NULL ); +                Aig_ManStop( pSRed ); +            } +        } +*/ + +    }  +    p->pPars->nIters = nIter + 1; +p->timeTotal = clock() - clkTotal; +    pAigNew = Aig_ManDupRepr( p->pAig, 0 ); +    Aig_ManSeqCleanup( pAigNew ); +    // get the final stats +    p->nLitsEnd  = Ssw_ClassesLitNum( p->ppClasses ); +    p->nNodesEnd = Aig_ManNodeNum(pAigNew); +    p->nRegsEnd  = Aig_ManRegNum(pAigNew); +    return pAigNew; +} + +/**Function************************************************************* + +  Synopsis    [Performs computation of signal correspondence with constraints.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Aig_Man_t * Ssw_SignalCorrespondence( Aig_Man_t * pAig, Ssw_Pars_t * pPars ) +{ +    Ssw_Pars_t Pars; +    Aig_Man_t * pAigNew; +    Ssw_Man_t * p; +    assert( Aig_ManRegNum(pAig) > 0 ); +    // reset random numbers +    Aig_ManRandom( 1 ); +    // if parameters are not given, create them +    if ( pPars == NULL ) +        Ssw_ManSetDefaultParams( pPars = &Pars ); +    // consider the case of empty AIG +    if ( Aig_ManNodeNum(pAig) == 0 ) +    { +        pPars->nIters = 0; +        // Ntl_ManFinalize() needs the following to satisfy an assertion +        Aig_ManReprStart( pAig,Aig_ManObjNumMax(pAig) ); +        return Aig_ManDupOrdered(pAig); +    } +    // check and update parameters +    if ( pPars->fLatchCorrOpt ) +    { +        pPars->fLatchCorr = 1; +        pPars->nFramesAddSim = 0; +    } +    else +    { +        assert( pPars->nFramesK > 0 ); +        if ( pPars->nFramesK > 1 ) +            pPars->fSkipCheck = 0; +        // perform partitioning +        if ( (pPars->nPartSize > 0 && pPars->nPartSize < Aig_ManRegNum(pAig)) +             || (pAig->vClockDoms && Vec_VecSize(pAig->vClockDoms) > 0)  ) +            return Ssw_SignalCorrespondencePart( pAig, pPars ); +    } +    // start the induction manager +    p = Ssw_ManCreate( pAig, pPars ); +    // compute candidate equivalence classes +//    p->pPars->nConstrs = 1; +    if ( p->pPars->nConstrs == 0 ) +    { +        // perform one round of seq simulation and generate candidate equivalence classes +        p->ppClasses = Ssw_ClassesPrepare( pAig, pPars->fLatchCorr, pPars->nMaxLevs, pPars->fVerbose ); +//        p->ppClasses = Ssw_ClassesPrepareTargets( pAig ); +//        p->pSml = Ssw_SmlStart( pAig, 0, p->nFrames + p->pPars->nFramesAddSim, 1 ); +        p->pSml = Ssw_SmlStart( pAig, 0, 1, 1 ); +        Ssw_ClassesSetData( p->ppClasses, p->pSml, Ssw_SmlObjHashWord, Ssw_SmlObjIsConstWord, Ssw_SmlObjsAreEqualWord ); +    } +    else +    { +        // create trivial equivalence classes with all nodes being candidates for constant 1 +        p->ppClasses = Ssw_ClassesPrepareSimple( pAig, pPars->fLatchCorr, pPars->nMaxLevs ); +        Ssw_ClassesSetData( p->ppClasses, NULL, NULL, Ssw_SmlObjIsConstBit, Ssw_SmlObjsAreEqualBit ); +    } +    // perform refinement of classes +    pAigNew = Ssw_SignalCorrespondenceRefine( p );     +    // cleanup +    Ssw_ManStop( p ); +    return pAigNew; +} + +/**Function************************************************************* + +  Synopsis    [Performs computation of latch correspondence.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Aig_Man_t * Ssw_LatchCorrespondence( Aig_Man_t * pAig, Ssw_Pars_t * pPars ) +{ +    Ssw_Pars_t Pars; +    if ( pPars == NULL ) +        Ssw_ManSetDefaultParamsLcorr( pPars = &Pars ); +    return Ssw_SignalCorrespondence( pAig, pPars ); +} + + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/ssw_old/sswInt.h b/src/aig/ssw_old/sswInt.h new file mode 100644 index 00000000..d7bf46a8 --- /dev/null +++ b/src/aig/ssw_old/sswInt.h @@ -0,0 +1,232 @@ +/**CFile**************************************************************** + +  FileName    [sswInt.h] + +  SystemName  [ABC: Logic synthesis and verification system.] + +  PackageName [Inductive prover with constraints.] + +  Synopsis    [External declarations.] + +  Author      [Alan Mishchenko] +   +  Affiliation [UC Berkeley] + +  Date        [Ver. 1.0. Started - September 1, 2008.] + +  Revision    [$Id: sswInt.h,v 1.00 2008/09/01 00:00:00 alanmi Exp $] + +***********************************************************************/ +  +#ifndef __SSW_INT_H__ +#define __SSW_INT_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +//////////////////////////////////////////////////////////////////////// +///                          INCLUDES                                /// +//////////////////////////////////////////////////////////////////////// + +#include "saig.h" +#include "satSolver.h" +#include "ssw.h" + +//////////////////////////////////////////////////////////////////////// +///                         PARAMETERS                               /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +///                         BASIC TYPES                              /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Ssw_Man_t_ Ssw_Man_t; // signal correspondence manager +typedef struct Ssw_Cla_t_ Ssw_Cla_t; // equivalence classe manager +typedef struct Ssw_Sml_t_ Ssw_Sml_t; // sequential simulation manager + +struct Ssw_Man_t_ +{ +    // parameters +    Ssw_Pars_t *     pPars;          // parameters +    int              nFrames;        // for quick lookup +    // AIGs used in the package +    Aig_Man_t *      pAig;           // user-given AIG +    Aig_Man_t *      pFrames;        // final AIG +    Aig_Obj_t **     pNodeToFrames;  // mapping of AIG nodes into FRAIG nodes +    // equivalence classes +    Ssw_Cla_t *      ppClasses;      // equivalence classes of nodes +    int              fRefined;       // is set to 1 when refinement happens +    int              nRefUse;        // the number of equivalences used +    int              nRefSkip;       // the number of equivalences skipped   +    // SAT solving +    sat_solver *     pSat;           // recyclable SAT solver +    int              nSatVars;       // the counter of SAT variables +    Vec_Int_t *      vSatVars;       // mapping of each node into its SAT var +    int              nSatVarsTotal;  // the total number of SAT vars created +    Vec_Ptr_t *      vFanins;        // fanins of the CNF node +    // SAT solving (latch corr only) +    Vec_Ptr_t *      vUsedNodes;     // the nodes with SAT variables +    Vec_Ptr_t *      vUsedPis;       // the PIs with SAT variables +    Vec_Ptr_t *      vSimInfo;       // simulation information for the framed PIs +    int              nPatterns;      // the number of patterns saved +    int              nSimRounds;     // the number of simulation rounds performed +    int              nCallsCount;    // the number of calls in this round +    int              nCallsDelta;    // the number of calls to skip +    int              nCallsSat;      // the number of SAT calls in this round +    int              nCallsUnsat;    // the number of UNSAT calls in this round +    int              nRecycleCalls;  // the number of calls since last recycling +    int              nRecycles;      // the number of time SAT solver was recycled +    int              nConeMax;       // the maximum cone size +    // uniqueness +    Vec_Ptr_t *      vCommon;        // the set of common variables in the logic cones +    int              iOutputLit;     // the output literal of the uniqueness constaint +    int              nUniques;       // the number of uniqueness constaints used  +    // sequential simulator +    Ssw_Sml_t *      pSml; +    // counter example storage +    int              nPatWords;      // the number of words in the counter example +    unsigned *       pPatWords;      // the counter example +    unsigned *       pPatWords2;      // the counter example +    // constraints +    int              nConstrTotal;   // the number of total constraints +    int              nConstrReduced; // the number of reduced constraints +    int              nStrangers;     // the number of strange situations +    // SAT calls statistics +    int              nSatCalls;      // the number of SAT calls +    int              nSatProof;      // the number of proofs +    int              nSatFailsReal;  // the number of timeouts +    int              nSatFailsTotal; // the number of timeouts +    int              nSatCallsUnsat; // the number of unsat SAT calls +    int              nSatCallsSat;   // the number of sat SAT calls +    // node/register/lit statistics +    int              nLitsBeg; +    int              nLitsEnd; +    int              nNodesBeg; +    int              nNodesEnd; +    int              nRegsBeg; +    int              nRegsEnd; +    // runtime stats +    int              timeBmc;        // bounded model checking +    int              timeReduce;     // speculative reduction +    int              timeMarkCones;  // marking the cones not to be refined +    int              timeSimSat;     // simulation of the counter-examples +    int              timeSat;        // solving SAT +    int              timeSatSat;     // sat +    int              timeSatUnsat;   // unsat +    int              timeSatUndec;   // undecided +    int              timeOther;      // other runtime +    int              timeTotal;      // total runtime +}; + +//////////////////////////////////////////////////////////////////////// +///                      MACRO DEFINITIONS                           /// +//////////////////////////////////////////////////////////////////////// + +static inline int  Ssw_ObjSatNum( Ssw_Man_t * p, Aig_Obj_t * pObj )             { return Vec_IntEntry( p->vSatVars, pObj->Id );         } +static inline void Ssw_ObjSetSatNum( Ssw_Man_t * p, Aig_Obj_t * pObj, int Num ) { Vec_IntWriteEntryFill( p->vSatVars, pObj->Id, Num );  } + +static inline int  Ssw_ObjIsConst1Cand( Aig_Man_t * pAig, Aig_Obj_t * pObj )  +{ +    return Aig_ObjRepr(pAig, pObj) == Aig_ManConst1(pAig); +} +static inline void Ssw_ObjSetConst1Cand( Aig_Man_t * pAig, Aig_Obj_t * pObj )  +{ +    assert( !Ssw_ObjIsConst1Cand( pAig, pObj ) ); +    Aig_ObjSetRepr( pAig, pObj, Aig_ManConst1(pAig) ); +} + +static inline Aig_Obj_t * Ssw_ObjFrame( Ssw_Man_t * p, Aig_Obj_t * pObj, int i )                       { return p->pNodeToFrames[p->nFrames*pObj->Id + i];  } +static inline void        Ssw_ObjSetFrame( Ssw_Man_t * p, Aig_Obj_t * pObj, int i, Aig_Obj_t * pNode ) { p->pNodeToFrames[p->nFrames*pObj->Id + i] = pNode; } + +static inline Aig_Obj_t * Ssw_ObjChild0Fra( Ssw_Man_t * p, Aig_Obj_t * pObj, int i ) { assert( !Aig_IsComplement(pObj) ); return Aig_ObjFanin0(pObj)? Aig_NotCond(Ssw_ObjFrame(p, Aig_ObjFanin0(pObj), i), Aig_ObjFaninC0(pObj)) : NULL;  } +static inline Aig_Obj_t * Ssw_ObjChild1Fra( Ssw_Man_t * p, Aig_Obj_t * pObj, int i ) { assert( !Aig_IsComplement(pObj) ); return Aig_ObjFanin1(pObj)? Aig_NotCond(Ssw_ObjFrame(p, Aig_ObjFanin1(pObj), i), Aig_ObjFaninC1(pObj)) : NULL;  } + +//////////////////////////////////////////////////////////////////////// +///                    FUNCTION DECLARATIONS                         /// +//////////////////////////////////////////////////////////////////////// + +/*=== sswAig.c ===================================================*/ +extern Aig_Man_t *   Ssw_FramesWithClasses( Ssw_Man_t * p ); +extern Aig_Man_t *   Ssw_SpeculativeReduction( Ssw_Man_t * p ); +/*=== sswBmc.c ===================================================*/ +extern int           Ssw_FilterUsingBmc( Ssw_Man_t * pMan, int fCheckTargets, int nConfMax, int fVerbose ); +/*=== sswClass.c =================================================*/ +extern Ssw_Cla_t *   Ssw_ClassesStart( Aig_Man_t * pAig ); +extern void          Ssw_ClassesSetData( Ssw_Cla_t * p, void * pManData, +                         unsigned (*pFuncNodeHash)(void *,Aig_Obj_t *), +                         int (*pFuncNodeIsConst)(void *,Aig_Obj_t *), +                         int (*pFuncNodesAreEqual)(void *,Aig_Obj_t *, Aig_Obj_t *) ); +extern void          Ssw_ClassesStop( Ssw_Cla_t * p ); +extern Aig_Man_t *   Ssw_ClassesReadAig( Ssw_Cla_t * p ); +extern Vec_Ptr_t *   Ssw_ClassesGetRefined( Ssw_Cla_t * p ); +extern void          Ssw_ClassesClearRefined( Ssw_Cla_t * p ); +extern int           Ssw_ClassesCand1Num( Ssw_Cla_t * p ); +extern int           Ssw_ClassesClassNum( Ssw_Cla_t * p ); +extern int           Ssw_ClassesLitNum( Ssw_Cla_t * p ); +extern Aig_Obj_t **  Ssw_ClassesReadClass( Ssw_Cla_t * p, Aig_Obj_t * pRepr, int * pnSize ); +extern void          Ssw_ClassesCollectClass( Ssw_Cla_t * p, Aig_Obj_t * pRepr, Vec_Ptr_t * vClass ); +extern void          Ssw_ClassesCheck( Ssw_Cla_t * p ); +extern void          Ssw_ClassesPrint( Ssw_Cla_t * p, int fVeryVerbose ); +extern void          Ssw_ClassesRemoveNode( Ssw_Cla_t * p, Aig_Obj_t * pObj ); +extern Ssw_Cla_t *   Ssw_ClassesPrepare( Aig_Man_t * pAig, int fLatchCorr, int nMaxLevs, int fVerbose ); +extern Ssw_Cla_t *   Ssw_ClassesPrepareSimple( Aig_Man_t * pAig, int fLatchCorr, int nMaxLevs ); +extern Ssw_Cla_t *   Ssw_ClassesPrepareTargets( Aig_Man_t * pAig ); +extern Ssw_Cla_t *   Ssw_ClassesPreparePairs( Aig_Man_t * pAig, Vec_Int_t ** pvClasses ); +extern int           Ssw_ClassesRefine( Ssw_Cla_t * p, int fRecursive ); +extern int           Ssw_ClassesRefineOneClass( Ssw_Cla_t * p, Aig_Obj_t * pRepr, int fRecursive ); +extern int           Ssw_ClassesRefineConst1Group( Ssw_Cla_t * p, Vec_Ptr_t * vRoots, int fRecursive ); +extern int           Ssw_ClassesRefineConst1( Ssw_Cla_t * p, int fRecursive ); +/*=== sswCnf.c ===================================================*/ +extern void          Ssw_CnfNodeAddToSolver( Ssw_Man_t * p, Aig_Obj_t * pObj ); +/*=== sswCore.c ===================================================*/ +extern Aig_Man_t *   Ssw_SignalCorrespondenceRefine( Ssw_Man_t * p ); +/*=== sswLcorr.c ==========================================================*/ +extern int           Ssw_ManSweepLatch( Ssw_Man_t * p ); +/*=== sswMan.c ===================================================*/ +extern Ssw_Man_t *   Ssw_ManCreate( Aig_Man_t * pAig, Ssw_Pars_t * pPars ); +extern void          Ssw_ManCleanup( Ssw_Man_t * p ); +extern void          Ssw_ManStop( Ssw_Man_t * p ); +extern void          Ssw_ManStartSolver( Ssw_Man_t * p ); +/*=== sswSat.c ===================================================*/ +extern int           Ssw_NodesAreEquiv( Ssw_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew ); +extern int           Ssw_NodesAreConstrained( Ssw_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew ); +/*=== sswSim.c ===================================================*/ +extern unsigned      Ssw_SmlObjHashWord( Ssw_Sml_t * p, Aig_Obj_t * pObj ); +extern int           Ssw_SmlObjIsConstWord( Ssw_Sml_t * p, Aig_Obj_t * pObj ); +extern int           Ssw_SmlObjsAreEqualWord( Ssw_Sml_t * p, Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 ); +extern int           Ssw_SmlObjIsConstBit( void * p, Aig_Obj_t * pObj ); +extern int           Ssw_SmlObjsAreEqualBit( void * p, Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 ); +extern Ssw_Sml_t *   Ssw_SmlStart( Aig_Man_t * pAig, int nPref, int nFrames, int nWordsFrame ); +extern void          Ssw_SmlClean( Ssw_Sml_t * p ); +extern void          Ssw_SmlStop( Ssw_Sml_t * p ); +extern void          Ssw_SmlObjAssignConst( Ssw_Sml_t * p, Aig_Obj_t * pObj, int fConst1, int iFrame ); +extern unsigned      Ssw_SmlObjGetWord( Ssw_Sml_t * p, Aig_Obj_t * pObj, int iWord, int iFrame ); +extern void          Ssw_SmlObjSetWord( Ssw_Sml_t * p, Aig_Obj_t * pObj, unsigned Word, int iWord, int iFrame ); +extern void          Ssw_SmlAssignDist1Plus( Ssw_Sml_t * p, unsigned * pPat ); +extern void          Ssw_SmlSimulateOne( Ssw_Sml_t * p ); +extern void          Ssw_SmlSimulateOneFrame( Ssw_Sml_t * p ); +extern Ssw_Sml_t *   Ssw_SmlSimulateSeq( Aig_Man_t * pAig, int nPref, int nFrames, int nWords ); +/*=== sswSimSat.c ===================================================*/ +extern void          Ssw_ManResimulateBit( Ssw_Man_t * p, Aig_Obj_t * pObj, Aig_Obj_t * pRepr ); +extern void          Ssw_ManResimulateWord( Ssw_Man_t * p, Aig_Obj_t * pCand, Aig_Obj_t * pRepr, int f ); +extern void          Ssw_ManResimulateWord2( Ssw_Man_t * p, Aig_Obj_t * pCand, Aig_Obj_t * pRepr, int f ); +/*=== sswSweep.c ===================================================*/ +extern int           Ssw_ManGetSatVarValue( Ssw_Man_t * p, Aig_Obj_t * pObj, int f ); +extern int           Ssw_ManSweepNode( Ssw_Man_t * p, Aig_Obj_t * pObj, int f, int fBmc ); +extern int           Ssw_ManSweepBmc( Ssw_Man_t * p ); +extern int           Ssw_ManSweep( Ssw_Man_t * p ); +/*=== sswUnique.c ===================================================*/ +extern int           Ssw_ManUniqueOne( Ssw_Man_t * p, Aig_Obj_t * pRepr, Aig_Obj_t * pObj ); +extern int           Ssw_ManUniqueAddConstraint( Ssw_Man_t * p, Vec_Ptr_t * vCommon, int f1, int f2 ); + +#ifdef __cplusplus +} +#endif + +#endif + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + diff --git a/src/aig/ssw_old/sswLcorr.c b/src/aig/ssw_old/sswLcorr.c new file mode 100644 index 00000000..cde9b0c9 --- /dev/null +++ b/src/aig/ssw_old/sswLcorr.c @@ -0,0 +1,364 @@ +/**CFile**************************************************************** + +  FileName    [sswLcorr.c] + +  SystemName  [ABC: Logic synthesis and verification system.] + +  PackageName [Inductive prover with constraints.] + +  Synopsis    [Latch correspondence.] + +  Author      [Alan Mishchenko] +   +  Affiliation [UC Berkeley] + +  Date        [Ver. 1.0. Started - September 1, 2008.] + +  Revision    [$Id: sswLcorr.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "sswInt.h" +//#include "bar.h" + +//////////////////////////////////////////////////////////////////////// +///                        DECLARATIONS                              /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +///                     FUNCTION DEFINITIONS                         /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + +  Synopsis    [Recycles the SAT solver.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_ManSatSolverRecycle( Ssw_Man_t * p ) +{ +    int Lit; +    if ( p->pSat ) +    { +        Aig_Obj_t * pObj; +        int i; +        Vec_PtrForEachEntry( p->vUsedNodes, pObj, i ) +            Ssw_ObjSetSatNum( p, pObj, 0 ); +        Vec_PtrClear( p->vUsedNodes ); +        Vec_PtrClear( p->vUsedPis ); +//        memset( p->pSatVars, 0, sizeof(int) * Aig_ManObjNumMax(p->pAigTotal) ); +        sat_solver_delete( p->pSat ); +    } +    p->pSat = sat_solver_new(); +    sat_solver_setnvars( p->pSat, 1000 ); +    // var 0 is not used +    // var 1 is reserved for const1 node - add the clause +    p->nSatVars = 1; +//    p->nSatVars = 0; +    Lit = toLit( p->nSatVars ); +    if ( p->pPars->fPolarFlip ) +        Lit = lit_neg( Lit ); +    sat_solver_addclause( p->pSat, &Lit, &Lit + 1 ); +    Ssw_ObjSetSatNum( p, Aig_ManConst1(p->pFrames), p->nSatVars++ ); + +    p->nRecycles++; +    p->nRecycleCalls = 0; +} + + +/**Function************************************************************* + +  Synopsis    [Tranfers simulation information from FRAIG to AIG.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_ManSweepTransfer( Ssw_Man_t * p ) +{ +    Aig_Obj_t * pObj, * pObjFraig; +    unsigned * pInfo; +    int i; +    // transfer simulation information +    Aig_ManForEachPi( p->pAig, pObj, i ) +    { +        pObjFraig = Ssw_ObjFrame( p, pObj, 0 ); +        if ( pObjFraig == Aig_ManConst0(p->pFrames) ) +        { +            Ssw_SmlObjAssignConst( p->pSml, pObj, 0, 0 ); +            continue; +        } +        assert( !Aig_IsComplement(pObjFraig) ); +        assert( Aig_ObjIsPi(pObjFraig) ); +        pInfo = Vec_PtrEntry( p->vSimInfo, Aig_ObjPioNum(pObjFraig) ); +        Ssw_SmlObjSetWord( p->pSml, pObj, pInfo[0], 0, 0 ); +    } +} + +/**Function************************************************************* + +  Synopsis    [Performs one round of simulation with counter-examples.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ssw_ManSweepResimulate( Ssw_Man_t * p ) +{ +    int RetValue1, RetValue2, clk = clock(); +    // transfer PI simulation information from storage +    Ssw_ManSweepTransfer( p ); +    // simulate internal nodes +    Ssw_SmlSimulateOneFrame( p->pSml ); +    // check equivalence classes +    RetValue1 = Ssw_ClassesRefineConst1( p->ppClasses, 1 ); +    RetValue2 = Ssw_ClassesRefine( p->ppClasses, 1 ); +    // prepare simulation info for the next round +    Vec_PtrCleanSimInfo( p->vSimInfo, 0, 1 ); +    p->nPatterns = 0; +    p->nSimRounds++; +p->timeSimSat += clock() - clk; +    return RetValue1 > 0 || RetValue2 > 0; +} + +/**Function************************************************************* + +  Synopsis    [Saves one counter-example into internal storage.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_SmlAddPattern( Ssw_Man_t * p, Aig_Obj_t * pRepr, Aig_Obj_t * pCand ) +{ +    Aig_Obj_t * pObj; +    unsigned * pInfo; +    int i, nVarNum, Value; +    Vec_PtrForEachEntry( p->vUsedPis, pObj, i ) +    { +        nVarNum = Ssw_ObjSatNum( p, pObj ); +        assert( nVarNum > 0 ); +        Value = sat_solver_var_value( p->pSat, nVarNum ); +        if ( Value == 0 ) +            continue; +        pInfo = Vec_PtrEntry( p->vSimInfo, Aig_ObjPioNum(pObj) ); +        Aig_InfoSetBit( pInfo, p->nPatterns ); +    } +} + +/**Function************************************************************* + +  Synopsis    [Builds fraiged logic cone of the node.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_ManBuildCone_rec( Ssw_Man_t * p, Aig_Obj_t * pObj ) +{ +    Aig_Obj_t * pObjNew; +    assert( !Aig_IsComplement(pObj) ); +    if ( Ssw_ObjFrame( p, pObj, 0 ) ) +        return; +    assert( Aig_ObjIsNode(pObj) ); +    Ssw_ManBuildCone_rec( p, Aig_ObjFanin0(pObj) ); +    Ssw_ManBuildCone_rec( p, Aig_ObjFanin1(pObj) ); +    pObjNew = Aig_And( p->pFrames, Ssw_ObjChild0Fra(p, pObj, 0), Ssw_ObjChild1Fra(p, pObj, 0) ); +    Ssw_ObjSetFrame( p, pObj, 0, pObjNew ); +} + +/**Function************************************************************* + +  Synopsis    [Recycles the SAT solver.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_ManSweepLatchOne( Ssw_Man_t * p, Aig_Obj_t * pObjRepr, Aig_Obj_t * pObj ) +{ +    Aig_Obj_t * pObjFraig, * pObjReprFraig, * pObjLi; +    int RetValue, clk; +    assert( Aig_ObjIsPi(pObj) ); +    assert( Aig_ObjIsPi(pObjRepr) || Aig_ObjIsConst1(pObjRepr) ); +    // check if it makes sense to skip some calls +    if ( p->nCallsCount > 100 && p->nCallsUnsat < p->nCallsSat ) +    { +        if ( ++p->nCallsDelta < 0 ) +            return; +    } +    p->nCallsDelta = 0; +clk = clock(); +    // get the fraiged node +    pObjLi = Saig_ObjLoToLi( p->pAig, pObj );  +    Ssw_ManBuildCone_rec( p, Aig_ObjFanin0(pObjLi) ); +    pObjFraig = Ssw_ObjChild0Fra( p, pObjLi, 0 ); +    // get the fraiged representative +    if ( Aig_ObjIsPi(pObjRepr) ) +    { +        pObjLi = Saig_ObjLoToLi( p->pAig, pObjRepr );  +        Ssw_ManBuildCone_rec( p, Aig_ObjFanin0(pObjLi) ); +        pObjReprFraig = Ssw_ObjChild0Fra( p, pObjLi, 0 ); +    } +    else  +        pObjReprFraig = Ssw_ObjFrame( p, pObjRepr, 0 ); +p->timeReduce += clock() - clk; +    // if the fraiged nodes are the same, return +    if ( Aig_Regular(pObjFraig) == Aig_Regular(pObjReprFraig) ) +        return; +    p->nRecycleCalls++; +    p->nCallsCount++; + +    // check equivalence of the two nodes +    if ( (pObj->fPhase == pObjRepr->fPhase) != (Aig_ObjPhaseReal(pObjFraig) == Aig_ObjPhaseReal(pObjReprFraig)) ) +    { +        p->nPatterns++; +        p->nStrangers++; +        p->fRefined = 1; +    } +    else +    {  +        RetValue = Ssw_NodesAreEquiv( p, Aig_Regular(pObjReprFraig), Aig_Regular(pObjFraig) ); +        if ( RetValue == 1 )  // proved equivalence +        { +            p->nCallsUnsat++; +            return; +        } +        if ( RetValue == -1 ) // timed out +        { +            Ssw_ClassesRemoveNode( p->ppClasses, pObj ); +            p->nCallsUnsat++; +            p->fRefined = 1; +            return; +        } +        else // disproved equivalence +        {        +            Ssw_SmlAddPattern( p, pObjRepr, pObj ); +            p->nPatterns++; +            p->nCallsSat++; +            p->fRefined = 1; +        } +    } +} + +/**Function************************************************************* + +  Synopsis    [Performs one iteration of sweeping latches.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ssw_ManSweepLatch( Ssw_Man_t * p ) +{ +//    Bar_Progress_t * pProgress = NULL; +    Vec_Ptr_t * vClass; +    Aig_Obj_t * pObj, * pRepr, * pTemp; +    int i, k; + +    // start the timeframe +    p->pFrames = Aig_ManStart( Aig_ManObjNumMax(p->pAig) ); +    // map constants and PIs +    Ssw_ObjSetFrame( p, Aig_ManConst1(p->pAig), 0, Aig_ManConst1(p->pFrames) ); +    Saig_ManForEachPi( p->pAig, pObj, i ) +        Ssw_ObjSetFrame( p, pObj, 0, Aig_ObjCreatePi(p->pFrames) ); + +    // implement equivalence classes +    Saig_ManForEachLo( p->pAig, pObj, i ) +    { +        pRepr = Aig_ObjRepr( p->pAig, pObj ); +        if ( pRepr == NULL ) +        { +            pTemp = Aig_ObjCreatePi(p->pFrames); +            pTemp->pData = pObj; +        } +        else +            pTemp = Aig_NotCond( Ssw_ObjFrame(p, pRepr, 0), pRepr->fPhase ^ pObj->fPhase ); +        Ssw_ObjSetFrame( p, pObj, 0, pTemp ); +    } +    Aig_ManSetPioNumbers( p->pFrames ); + +    // prepare simulation info +    assert( p->vSimInfo == NULL ); +    p->vSimInfo = Vec_PtrAllocSimInfo( Aig_ManPiNum(p->pFrames), 1 ); +    Vec_PtrCleanSimInfo( p->vSimInfo, 0, 1 ); + +    // go through the registers +//    if ( p->pPars->fVerbose ) +//        pProgress = Bar_ProgressStart( stdout, Aig_ManRegNum(p->pAig) ); +    vClass = Vec_PtrAlloc( 100 ); +    p->fRefined = 0; +    p->nCallsCount = p->nCallsSat = p->nCallsUnsat = 0; +    Saig_ManForEachLo( p->pAig, pObj, i ) +    { +//        if ( p->pPars->fVerbose ) +//            Bar_ProgressUpdate( pProgress, i, NULL ); +        // consider the case of constant candidate +        if ( Ssw_ObjIsConst1Cand( p->pAig, pObj ) ) +            Ssw_ManSweepLatchOne( p, Aig_ManConst1(p->pAig), pObj ); +        else +        { +            // consider the case of equivalence class +            Ssw_ClassesCollectClass( p->ppClasses, pObj, vClass ); +            if ( Vec_PtrSize(vClass) == 0 ) +                continue; +            // try to prove equivalences in this class +            Vec_PtrForEachEntry( vClass, pTemp, k ) +                if ( Aig_ObjRepr(p->pAig, pTemp) == pObj ) +                { +                    Ssw_ManSweepLatchOne( p, pObj, pTemp ); +                    if ( p->nPatterns == 32 ) +                        break; +                } +        } +        // resimulate +        if ( p->nPatterns == 32 ) +            Ssw_ManSweepResimulate( p ); +        // attempt recycling the SAT solver +        if ( p->pPars->nSatVarMax &&  +             p->nSatVars > p->pPars->nSatVarMax && +             p->nRecycleCalls > p->pPars->nRecycleCalls ) +             Ssw_ManSatSolverRecycle( p ); +    } +    // resimulate +    if ( p->nPatterns > 0 ) +        Ssw_ManSweepResimulate( p ); +    // cleanup +    Vec_PtrFree( vClass ); +    p->nSatFailsTotal += p->nSatFailsReal; +//    if ( p->pPars->fVerbose ) +//        Bar_ProgressStop( pProgress ); + +    // cleanup +//    Ssw_ClassesCheck( p->ppClasses ); +    return p->fRefined; +} + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/ssw_old/sswMan.c b/src/aig/ssw_old/sswMan.c new file mode 100644 index 00000000..84b041b4 --- /dev/null +++ b/src/aig/ssw_old/sswMan.c @@ -0,0 +1,237 @@ +/**CFile**************************************************************** + +  FileName    [sswMan.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: sswMan.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "sswInt.h" + +//////////////////////////////////////////////////////////////////////// +///                        DECLARATIONS                              /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +///                     FUNCTION DEFINITIONS                         /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + +  Synopsis    [Creates the manager.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Ssw_Man_t * Ssw_ManCreate( Aig_Man_t * pAig, Ssw_Pars_t * pPars ) +{ +    Ssw_Man_t * p; +    // prepare the sequential AIG +    assert( Saig_ManRegNum(pAig) > 0 ); +    Aig_ManFanoutStart( pAig ); +    Aig_ManSetPioNumbers( pAig ); +    // create interpolation manager +    p = ALLOC( Ssw_Man_t, 1 );  +    memset( p, 0, sizeof(Ssw_Man_t) ); +    p->pPars         = pPars; +    p->pAig          = pAig; +    p->nFrames       = pPars->nFramesK + 1; +    p->pNodeToFrames = CALLOC( Aig_Obj_t *, Aig_ManObjNumMax(p->pAig) * p->nFrames ); +    // SAT solving +    p->vSatVars      = Vec_IntStart( Aig_ManObjNumMax(p->pAig) * (p->nFrames+1) ); +    p->vFanins       = Vec_PtrAlloc( 100 ); +    // SAT solving (latch corr only) +    p->vUsedNodes    = Vec_PtrAlloc( 1000 ); +    p->vUsedPis      = Vec_PtrAlloc( 1000 ); +    p->vCommon       = Vec_PtrAlloc( 100 ); +    p->iOutputLit    = -1; +    // allocate storage for sim pattern +    p->nPatWords     = Aig_BitWordNum( Saig_ManPiNum(pAig) * p->nFrames + Saig_ManRegNum(pAig) ); +    p->pPatWords     = ALLOC( unsigned, p->nPatWords );  +    p->pPatWords2     = ALLOC( unsigned, p->nPatWords );  +    return p; +} + +/**Function************************************************************* + +  Synopsis    [Prints stats of the manager.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ssw_ManCountEquivs( Ssw_Man_t * p ) +{ +    Aig_Obj_t * pObj; +    int i, nEquivs = 0; +    Aig_ManForEachObj( p->pAig, pObj, i ) +        nEquivs += ( Aig_ObjRepr(p->pAig, pObj) != NULL ); +    return nEquivs; +} + +/**Function************************************************************* + +  Synopsis    [Prints stats of the manager.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_ManPrintStats( Ssw_Man_t * p ) +{ +    double nMemory = 1.0*Aig_ManObjNumMax(p->pAig)*p->nFrames*(2*sizeof(int)+2*sizeof(void*))/(1<<20); + +    printf( "Parameters: F = %d. AddF = %d. C-lim = %d. Constr = %d. MaxLev = %d. Mem = %0.2f Mb.\n",  +        p->pPars->nFramesK, p->pPars->nFramesAddSim, p->pPars->nBTLimit, p->pPars->nConstrs, p->pPars->nMaxLevs, nMemory ); +    printf( "AIG       : PI = %d. PO = %d. Latch = %d. Node = %d.  Ave SAT vars = %d.\n",  +        Saig_ManPiNum(p->pAig), Saig_ManPoNum(p->pAig), Saig_ManRegNum(p->pAig), Aig_ManNodeNum(p->pAig),  +        p->nSatVarsTotal/p->pPars->nIters ); +    printf( "SAT calls : Proof = %d. Cex = %d. Fail = %d. Equivs = %d. Str = %d.\n",  +        p->nSatProof, p->nSatCallsSat, p->nSatFailsTotal, Ssw_ManCountEquivs(p), p->nStrangers ); +    printf( "SAT solver: Vars = %d. Max cone = %d. Recycles = %d. Rounds = %d.\n",  +        p->nSatVars, p->nConeMax, p->nRecycles, p->nSimRounds ); +    printf( "NBeg = %d. NEnd = %d. (Gain = %6.2f %%).  RBeg = %d. REnd = %d. (Gain = %6.2f %%).\n",  +        p->nNodesBeg, p->nNodesEnd, 100.0*(p->nNodesBeg-p->nNodesEnd)/(p->nNodesBeg?p->nNodesBeg:1),  +        p->nRegsBeg, p->nRegsEnd, 100.0*(p->nRegsBeg-p->nRegsEnd)/(p->nRegsBeg?p->nRegsBeg:1) ); + +    p->timeOther = p->timeTotal-p->timeBmc-p->timeReduce-p->timeMarkCones-p->timeSimSat-p->timeSat; +    PRTP( "BMC        ", p->timeBmc,       p->timeTotal ); +    PRTP( "Spec reduce", p->timeReduce,    p->timeTotal ); +    PRTP( "Mark cones ", p->timeMarkCones, p->timeTotal ); +    PRTP( "Sim SAT    ", p->timeSimSat,    p->timeTotal ); +    PRTP( "SAT solving", p->timeSat,       p->timeTotal ); +    PRTP( "  unsat    ", p->timeSatUnsat,  p->timeTotal ); +    PRTP( "  sat      ", p->timeSatSat,    p->timeTotal ); +    PRTP( "  undecided", p->timeSatUndec,  p->timeTotal ); +    PRTP( "Other      ", p->timeOther,     p->timeTotal ); +    PRTP( "TOTAL      ", p->timeTotal,     p->timeTotal ); +} + +/**Function************************************************************* + +  Synopsis    [Frees the manager.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_ManCleanup( Ssw_Man_t * p ) +{ +    if ( p->pFrames ) +    { +        Aig_ManStop( p->pFrames ); +        p->pFrames = NULL; +        memset( p->pNodeToFrames, 0, sizeof(Aig_Obj_t *) * Aig_ManObjNumMax(p->pAig) * p->nFrames ); +    } +    if ( p->pSat ) +    { +        int i; +//        printf( "Vars = %d. Clauses = %d. Learnts = %d.\n", p->pSat->size, p->pSat->clauses.size, p->pSat->learnts.size ); +        p->nSatVarsTotal += p->pSat->size; +        sat_solver_delete( p->pSat ); +        p->pSat = NULL; +//        memset( p->pSatVars, 0, sizeof(int) * Aig_ManObjNumMax(p->pAig) * (p->nFrames+1) ); +        for ( i = 0; i < Vec_IntSize(p->vSatVars); i++ ) +            p->vSatVars->pArray[i] = 0; +    } +    if ( p->vSimInfo )   +    { +        Vec_PtrFree( p->vSimInfo ); +        p->vSimInfo = NULL; +    } +    p->nConstrTotal = 0; +    p->nConstrReduced = 0; +} + +/**Function************************************************************* + +  Synopsis    [Frees the manager.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_ManStop( Ssw_Man_t * p ) +{ +    Aig_ManCleanMarkA( p->pAig ); +    Aig_ManCleanMarkB( p->pAig ); +    if ( p->pPars->fVerbose ) +        Ssw_ManPrintStats( p ); +    if ( p->ppClasses ) +        Ssw_ClassesStop( p->ppClasses ); +    if ( p->pSml )       +        Ssw_SmlStop( p->pSml ); +    Vec_PtrFree( p->vFanins ); +    Vec_PtrFree( p->vUsedNodes ); +    Vec_PtrFree( p->vUsedPis ); +    Vec_IntFree( p->vSatVars ); +    Vec_PtrFree( p->vCommon ); +    FREE( p->pNodeToFrames ); +    FREE( p->pPatWords ); +    FREE( p->pPatWords2 ); +    free( p ); +} + +/**Function************************************************************* + +  Synopsis    [Starts the SAT solver.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_ManStartSolver( Ssw_Man_t * p ) +{ +    int Lit; +    assert( p->pSat == NULL ); +    p->pSat = sat_solver_new(); +    sat_solver_setnvars( p->pSat, 1000 ); +    // var 0 is not used +    // var 1 is reserved for const1 node - add the clause +    p->nSatVars = 1; +    Lit = toLit( p->nSatVars ); +    if ( p->pPars->fPolarFlip ) +        Lit = lit_neg( Lit ); +    sat_solver_addclause( p->pSat, &Lit, &Lit + 1 ); +    Ssw_ObjSetSatNum( p, Aig_ManConst1(p->pAig), p->nSatVars++ ); + +    Vec_PtrClear( p->vUsedNodes ); +    Vec_PtrClear( p->vUsedPis ); +} + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/ssw_old/sswPairs.c b/src/aig/ssw_old/sswPairs.c new file mode 100644 index 00000000..c77ad30d --- /dev/null +++ b/src/aig/ssw_old/sswPairs.c @@ -0,0 +1,470 @@ +/**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" + +//////////////////////////////////////////////////////////////////////// +///                        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 +        if ( p->nRegs == 0 && Aig_ObjIsPi(Aig_Regular(pChild)) ) +        { +            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 ) +    { +        printf( "Miter has %d outputs. ", Saig_ManPoNum(p) ); +        printf( "Const0 = %d.  ", CountConst0 ); +        printf( "NonConst0 = %d.  ", CountNonConst0 ); +        printf( "Undecided = %d.  ", CountUndecided ); +        printf( "\n" ); +    } + +    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) ); +        pObj1m = Aig_Regular(pObj1->pData); +        pObj2m = Aig_Regular(pObj2->pData); +        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 [] +                +  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 +    pvClasses = CALLOC( Vec_Int_t *, nObjNumMax ); +    pReprs    = ALLOC( int, nObjNumMax ); +    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 ); +            if ( idReprObj < idRepr )  +            { // add idRepr to the same class +                Vec_IntPushUniqueOrder( pvClasses[idReprObj], idRepr ); +                pReprs[ idRepr ] = idReprObj; +            } +            else // if ( idReprObj > idRepr )  +            { // 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; +                } +            } +        } +    } +    free( pReprs ); +    return pvClasses; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_FreeTempClasses( Vec_Int_t ** pvClasses, int nObjNumMax ) +{ +    int i; +    for ( i = 0; i < nObjNumMax; i++ ) +        if ( pvClasses[i] )  +            Vec_IntFree( pvClasses[i] ); +    free( pvClasses ); +} + +/**Function************************************************************* + +  Synopsis    [Performs signal correspondence for the miter of two AIGs with node pairs defined.] + +  Description [] +                +  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 ) +{ +    Ssw_Man_t * p;  +    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 ); +    // 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 ); +    Ssw_ClassesSetData( p->ppClasses, p->pSml, Ssw_SmlObjHashWord, Ssw_SmlObjIsConstWord, Ssw_SmlObjsAreEqualWord ); +    // 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 [] +                +  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; +    int RetValue, i, clk = clock(); +    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 ) +    { +        pRepr = Aig_Regular(pObj->pData); +        if ( pRepr == NULL ) +            continue; +        if ( Aig_ManObj(pAigNew, pRepr->Id) == NULL ) +            continue; +/* +        if ( Aig_ObjIsNode(pObj) ) +            printf( "n " ); +        else if ( Saig_ObjIsPi(pAig, pObj) ) +            printf( "pi " ); +        else if ( Saig_ObjIsLo(pAig, pObj) ) +            printf( "lo " ); +*/ +        Vec_IntPush( vIds1, Aig_ObjId(pObj) ); +        Vec_IntPush( vIds2, Aig_ObjId(pRepr) ); +    } +    printf( "Recorded %d pairs (before: %d  after: %d).\n", Vec_IntSize(vIds1), Aig_ManObjNumMax(pAig), Aig_ManObjNumMax(pAigNew) ); +    // 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 ) +        printf( "Verification successful.  " ); +    else if ( RetValue == 0 ) +        printf( "Verification failed with the counter-example.  " ); +    else +        printf( "Verification UNDECIDED. Remaining registers %d (total %d).  ",  +            Aig_ManRegNum(pAigRes), Aig_ManRegNum(pAig) + Aig_ManRegNum(pAigNew) ); +    PRT( "Time", clock() - clk ); +    // 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; +    int RetValue, clk = clock(); +    assert( vIds1 != NULL && vIds2 != NULL ); +    // try the new AIGs +    printf( "Performing specialized verification with node pairs.\n" ); +    pAigRes = Ssw_SignalCorrespondenceWithPairs( pAig1, pAig2, vIds1, vIds2, pPars ); +    // report the results +    RetValue = Ssw_MiterStatus( pAigRes, 1 ); +    if ( RetValue == 1 ) +        printf( "Verification successful.  " ); +    else if ( RetValue == 0 ) +        printf( "Verification failed with a counter-example.  " ); +    else +        printf( "Verification UNDECIDED. The number of remaining regs = %d (total = %d).  ",  +            Aig_ManRegNum(pAigRes), Aig_ManRegNum(pAig1) + Aig_ManRegNum(pAig2) ); +    PRT( "Time", clock() - clk ); +    // 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; +    int RetValue, clk = clock(); +    // try the new AIGs +    printf( "Performing general verification without node pairs.\n" ); +    pMiter = Saig_ManCreateMiter( pAig1, pAig2, 0 ); +    pAigRes = Ssw_SignalCorrespondence( pMiter, pPars ); +    Aig_ManStop( pMiter ); +    // report the results +    RetValue = Ssw_MiterStatus( pAigRes, 1 ); +    if ( RetValue == 1 ) +        printf( "Verification successful.  " ); +    else if ( RetValue == 0 ) +        printf( "Verification failed with a counter-example.  " ); +    else +        printf( "Verification UNDECIDED. The number of remaining regs = %d (total = %d).  ",  +            Aig_ManRegNum(pAigRes), Aig_ManRegNum(pAig1) + Aig_ManRegNum(pAig2) ); +    PRT( "Time", clock() - clk ); +    // cleanup +    Aig_ManStop( pAigRes ); +    return RetValue; +} + +/**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; +    int RetValue, clk = clock(); +    // try the new AIGs +//    printf( "Performing general verification without node pairs.\n" ); +    pAigRes = Ssw_SignalCorrespondence( pMiter, pPars ); +    // report the results +    RetValue = Ssw_MiterStatus( pAigRes, 1 ); +    if ( RetValue == 1 ) +        printf( "Verification successful.  " ); +    else if ( RetValue == 0 ) +        printf( "Verification failed with a counter-example.  " ); +    else +        printf( "Verification UNDECIDED. The number of remaining regs = %d (total = %d).  ",  +            Aig_ManRegNum(pAigRes), Aig_ManRegNum(pMiter) ); +    PRT( "Time", clock() - clk ); +    // cleanup +    Aig_ManStop( pAigRes ); +    return RetValue; +} + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/ssw_old/sswPart.c b/src/aig/ssw_old/sswPart.c new file mode 100644 index 00000000..7eb6b8fe --- /dev/null +++ b/src/aig/ssw_old/sswPart.c @@ -0,0 +1,129 @@ +/**CFile**************************************************************** + +  FileName    [sswPart.c] + +  SystemName  [ABC: Logic synthesis and verification system.] + +  PackageName [Inductive prover with constraints.] + +  Synopsis    [Partitioned signal correspondence.] + +  Author      [Alan Mishchenko] +   +  Affiliation [UC Berkeley] + +  Date        [Ver. 1.0. Started - September 1, 2008.] + +  Revision    [$Id: sswPart.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "sswInt.h" + +//////////////////////////////////////////////////////////////////////// +///                        DECLARATIONS                              /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +///                     FUNCTION DEFINITIONS                         /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + +  Synopsis    [Performs partitioned sequential SAT sweepingG.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Aig_Man_t * Ssw_SignalCorrespondencePart( Aig_Man_t * pAig, Ssw_Pars_t * pPars ) +{ +    int fPrintParts = 0; +    char Buffer[100]; +    Aig_Man_t * pTemp, * pNew; +    Vec_Ptr_t * vResult; +    Vec_Int_t * vPart; +    int * pMapBack; +    int i, nCountPis, nCountRegs; +    int nClasses, nPartSize, fVerbose; +    int clk = clock(); + +    // save parameters +    nPartSize = pPars->nPartSize; pPars->nPartSize = 0; +    fVerbose  = pPars->fVerbose;  pPars->fVerbose = 0; +    // generate partitions +    if ( pAig->vClockDoms ) +    { +        // divide large clock domains into separate partitions +        vResult = Vec_PtrAlloc( 100 ); +        Vec_PtrForEachEntry( (Vec_Ptr_t *)pAig->vClockDoms, vPart, i ) +        { +            if ( nPartSize && Vec_IntSize(vPart) > nPartSize ) +                Aig_ManPartDivide( vResult, vPart, nPartSize, pPars->nOverSize ); +            else +                Vec_PtrPush( vResult, Vec_IntDup(vPart) ); +        } +    } +    else +        vResult = Aig_ManRegPartitionSimple( pAig, nPartSize, pPars->nOverSize ); +//    vResult = Aig_ManPartitionSmartRegisters( pAig, nPartSize, 0 );  +//    vResult = Aig_ManRegPartitionSmart( pAig, nPartSize ); +    if ( fPrintParts ) +    { +        // print partitions +        printf( "Simple partitioning. %d partitions are saved:\n", Vec_PtrSize(vResult) ); +        Vec_PtrForEachEntry( vResult, vPart, i ) +        { +            extern void Ioa_WriteAiger( Aig_Man_t * pMan, char * pFileName, int fWriteSymbols, int fCompact ); +            sprintf( Buffer, "part%03d.aig", i ); +            pTemp = Aig_ManRegCreatePart( pAig, vPart, &nCountPis, &nCountRegs, NULL ); +            Ioa_WriteAiger( pTemp, Buffer, 0, 0 ); +            printf( "part%03d.aig : Reg = %4d. PI = %4d. (True = %4d. Regs = %4d.) And = %5d.\n",  +                i, Vec_IntSize(vPart), Aig_ManPiNum(pTemp)-Vec_IntSize(vPart), nCountPis, nCountRegs, Aig_ManNodeNum(pTemp) ); +            Aig_ManStop( pTemp ); +        } +    } + +    // perform SSW with partitions +    Aig_ManReprStart( pAig, Aig_ManObjNumMax(pAig) ); +    Vec_PtrForEachEntry( vResult, vPart, i ) +    { +        pTemp = Aig_ManRegCreatePart( pAig, vPart, &nCountPis, &nCountRegs, &pMapBack ); +        Aig_ManSetRegNum( pTemp, pTemp->nRegs ); +        // create the projection of 1-hot registers +        if ( pAig->vOnehots ) +            pTemp->vOnehots = Aig_ManRegProjectOnehots( pAig, pTemp, pAig->vOnehots, fVerbose ); +        // run SSW +        pNew = Ssw_SignalCorrespondence( pTemp, pPars ); +        nClasses = Aig_TransferMappedClasses( pAig, pTemp, pMapBack ); +        if ( fVerbose ) +            printf( "%3d : Reg = %4d. PI = %4d. (True = %4d. Regs = %4d.) And = %5d. It = %3d. Cl = %5d.\n",  +                i, Vec_IntSize(vPart), Aig_ManPiNum(pTemp)-Vec_IntSize(vPart), nCountPis, nCountRegs, Aig_ManNodeNum(pTemp), pPars->nIters, nClasses ); +        Aig_ManStop( pNew ); +        Aig_ManStop( pTemp ); +        free( pMapBack ); +    } +    // remap the AIG +    pNew = Aig_ManDupRepr( pAig, 0 ); +    Aig_ManSeqCleanup( pNew ); +//    Aig_ManPrintStats( pAig ); +//    Aig_ManPrintStats( pNew ); +    Vec_VecFree( (Vec_Vec_t *)vResult ); +    pPars->nPartSize = nPartSize; +    pPars->fVerbose = fVerbose; +    if ( fVerbose ) +    { +        PRT( "Total time", clock() - clk ); +    } +    return pNew; +} + + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/ssw_old/sswSat.c b/src/aig/ssw_old/sswSat.c new file mode 100644 index 00000000..85d3b8c1 --- /dev/null +++ b/src/aig/ssw_old/sswSat.c @@ -0,0 +1,264 @@ +/**CFile**************************************************************** + +  FileName    [sswSat.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: sswSat.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "sswInt.h" + +//////////////////////////////////////////////////////////////////////// +///                        DECLARATIONS                              /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +///                     FUNCTION DEFINITIONS                         /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + +  Synopsis    [Runs equivalence test for the two nodes.] + +  Description [Both nodes should be regular and different from each other.] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ssw_NodesAreEquiv( Ssw_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew ) +{ +    int nBTLimit = p->pPars->nBTLimit; +    int pLits[3], nLits, RetValue, RetValue1, clk;//, status; +    p->nSatCalls++; + +    // sanity checks +    assert( !Aig_IsComplement(pOld) ); +    assert( !Aig_IsComplement(pNew) ); +    assert( pOld != pNew ); + +    if ( p->pSat == NULL ) +        Ssw_ManStartSolver( p ); + +    // if the nodes do not have SAT variables, allocate them +    Ssw_CnfNodeAddToSolver( p, pOld ); +    Ssw_CnfNodeAddToSolver( p, pNew ); + +    if ( p->pSat->qtail != p->pSat->qhead ) +    { +        RetValue = sat_solver_simplify(p->pSat); +        assert( RetValue != 0 ); +    } + +    // solve under assumptions +    // A = 1; B = 0     OR     A = 1; B = 1  +    nLits = 2; +    pLits[0] = toLitCond( Ssw_ObjSatNum(p,pOld), 0 ); +    pLits[1] = toLitCond( Ssw_ObjSatNum(p,pNew), pOld->fPhase == pNew->fPhase ); +    if ( p->iOutputLit > -1 ) +        pLits[nLits++] = p->iOutputLit; +    if ( p->pPars->fPolarFlip ) +    { +        if ( pOld->fPhase )  pLits[0] = lit_neg( pLits[0] ); +        if ( pNew->fPhase )  pLits[1] = lit_neg( pLits[1] ); +    } +//Sat_SolverWriteDimacs( p->pSat, "temp.cnf", pLits, pLits + 2, 1 ); + +clk = clock(); +    RetValue1 = sat_solver_solve( p->pSat, pLits, pLits + nLits,  +        (sint64)nBTLimit, (sint64)0, (sint64)0, (sint64)0 ); +p->timeSat += clock() - clk; +    if ( RetValue1 == l_False ) +    { +p->timeSatUnsat += clock() - clk; +        if ( nLits == 2 ) +        { +            pLits[0] = lit_neg( pLits[0] ); +            pLits[1] = lit_neg( pLits[1] ); +            RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 2 ); +            assert( RetValue ); +        } +        p->nSatCallsUnsat++; +    } +    else if ( RetValue1 == l_True ) +    { +p->timeSatSat += clock() - clk; +        p->nSatCallsSat++; +        return 0; +    } +    else // if ( RetValue1 == l_Undef ) +    { +p->timeSatUndec += clock() - clk; +        p->nSatFailsReal++; +        return -1; +    } + +    // if the old node was constant 0, we already know the answer +    if ( pOld == Aig_ManConst1(p->pFrames) ) +    { +        p->nSatProof++; +        return 1; +    } + +    // solve under assumptions +    // A = 0; B = 1     OR     A = 0; B = 0  +    nLits = 2; +    pLits[0] = toLitCond( Ssw_ObjSatNum(p,pOld), 1 ); +    pLits[1] = toLitCond( Ssw_ObjSatNum(p,pNew), pOld->fPhase ^ pNew->fPhase ); +    if ( p->iOutputLit > -1 ) +        pLits[nLits++] = p->iOutputLit; +    if ( p->pPars->fPolarFlip ) +    { +        if ( pOld->fPhase )  pLits[0] = lit_neg( pLits[0] ); +        if ( pNew->fPhase )  pLits[1] = lit_neg( pLits[1] ); +    } +/* +    if ( p->pSat->qtail != p->pSat->qhead ) +    { +        RetValue = sat_solver_simplify(p->pSat); +        assert( RetValue != 0 ); +    } +*/ +clk = clock(); +    RetValue1 = sat_solver_solve( p->pSat, pLits, pLits + nLits,  +        (sint64)nBTLimit, (sint64)0, (sint64)0, (sint64)0 ); +p->timeSat += clock() - clk; +    if ( RetValue1 == l_False ) +    { +p->timeSatUnsat += clock() - clk; +        if ( nLits == 2 ) +        { +            pLits[0] = lit_neg( pLits[0] ); +            pLits[1] = lit_neg( pLits[1] ); +            RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 2 ); +            assert( RetValue ); +        } +        p->nSatCallsUnsat++; +    } +    else if ( RetValue1 == l_True ) +    { +p->timeSatSat += clock() - clk; +        p->nSatCallsSat++; +        return 0; +    } +    else // if ( RetValue1 == l_Undef ) +    { +p->timeSatUndec += clock() - clk; +        p->nSatFailsReal++; +        return -1; +    } +    // return SAT proof +    p->nSatProof++; +    return 1; +} + +/**Function************************************************************* + +  Synopsis    [Constrains two nodes to be equivalent in the SAT solver.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ssw_NodesAreConstrained( Ssw_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew ) +{ +    int pLits[2], RetValue, fComplNew; +    Aig_Obj_t * pTemp; + +    // sanity checks +    assert( Aig_Regular(pOld) != Aig_Regular(pNew) ); + +    // move constant to the old node +    if ( Aig_Regular(pNew) == Aig_ManConst1(p->pFrames) ) +    { +        assert( Aig_Regular(pOld) != Aig_ManConst1(p->pFrames) ); +        pTemp = pOld; +        pOld  = pNew; +        pNew  = pTemp; +    } + +    // move complement to the new node +    if ( Aig_IsComplement(pOld) ) +    { +        pOld = Aig_Regular(pOld); +        pNew = Aig_Not(pNew); +    } + +    // start the solver +    if ( p->pSat == NULL ) +        Ssw_ManStartSolver( p ); + +    // if the nodes do not have SAT variables, allocate them +    Ssw_CnfNodeAddToSolver( p, pOld ); +    Ssw_CnfNodeAddToSolver( p, Aig_Regular(pNew) ); + +    // transform the new node +    fComplNew = Aig_IsComplement( pNew ); +    pNew = Aig_Regular( pNew ); + +    // consider the constant 1 case +    if ( pOld == Aig_ManConst1(p->pFrames) ) +    { +        // add constaint A = 1  ---->  A +        pLits[0] = toLitCond( Ssw_ObjSatNum(p,pNew), fComplNew ); +        if ( p->pPars->fPolarFlip ) +        { +            if ( pNew->fPhase )  pLits[0] = lit_neg( pLits[0] ); +        } +        RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 1 ); +        assert( RetValue ); +    } +    else +    { +        // add constaint A = B  ---->  (A v !B)(!A v B) + +        // (A v !B) +        pLits[0] = toLitCond( Ssw_ObjSatNum(p,pOld), 0 ); +        pLits[1] = toLitCond( Ssw_ObjSatNum(p,pNew), !fComplNew ); +        if ( p->pPars->fPolarFlip ) +        { +            if ( pOld->fPhase )  pLits[0] = lit_neg( pLits[0] ); +            if ( pNew->fPhase )  pLits[1] = lit_neg( pLits[1] ); +        } +        pLits[0] = lit_neg( pLits[0] ); +        pLits[1] = lit_neg( pLits[1] ); +        RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 2 ); +        assert( RetValue ); + +        // (!A v B) +        pLits[0] = toLitCond( Ssw_ObjSatNum(p,pOld), 1 ); +        pLits[1] = toLitCond( Ssw_ObjSatNum(p,pNew), fComplNew); +        if ( p->pPars->fPolarFlip ) +        { +            if ( pOld->fPhase )  pLits[0] = lit_neg( pLits[0] ); +            if ( pNew->fPhase )  pLits[1] = lit_neg( pLits[1] ); +        } +        pLits[0] = lit_neg( pLits[0] ); +        pLits[1] = lit_neg( pLits[1] ); +        RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 2 ); +        assert( RetValue ); +    } +    return 1; +} + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/ssw_old/sswSim.c b/src/aig/ssw_old/sswSim.c new file mode 100644 index 00000000..3fdb5cbc --- /dev/null +++ b/src/aig/ssw_old/sswSim.c @@ -0,0 +1,1334 @@ +/**CFile**************************************************************** + +  FileName    [sswSim.c] + +  SystemName  [ABC: Logic synthesis and verification system.] + +  PackageName [Inductive prover with constraints.] + +  Synopsis    [Sequential simulator used by the inductive prover.] + +  Author      [Alan Mishchenko] +   +  Affiliation [UC Berkeley] + +  Date        [Ver. 1.0. Started - September 1, 2008.] + +  Revision    [$Id: sswSim.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "sswInt.h" + +//////////////////////////////////////////////////////////////////////// +///                        DECLARATIONS                              /// +//////////////////////////////////////////////////////////////////////// + +// simulation manager +struct Ssw_Sml_t_ +{ +    Aig_Man_t *      pAig;              // the original AIG manager +    int              nPref;             // the number of timeframes in the prefix +    int              nFrames;           // the number of timeframes  +    int              nWordsFrame;       // the number of words in each timeframe +    int              nWordsTotal;       // the total number of words at a node +    int              nWordsPref;        // the number of word in the prefix +    int              fNonConstOut;      // have seen a non-const-0 output during simulation +    int              nSimRounds;        // statistics +    int              timeSim;           // statistics +    unsigned         pData[0];          // simulation data for the nodes +}; + +static inline unsigned * Ssw_ObjSim( Ssw_Sml_t * p, int Id )  { return p->pData + p->nWordsTotal * Id; } +static inline unsigned   Ssw_ObjRandomSim()                   { return Aig_ManRandom(0);               } + +//////////////////////////////////////////////////////////////////////// +///                     FUNCTION DEFINITIONS                         /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + +  Synopsis    [Computes hash value of the node using its simulation info.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +unsigned Ssw_SmlObjHashWord( Ssw_Sml_t * p, Aig_Obj_t * pObj ) +{ +    static int s_SPrimes[128] = {  +        1009, 1049, 1093, 1151, 1201, 1249, 1297, 1361, 1427, 1459,  +        1499, 1559, 1607, 1657, 1709, 1759, 1823, 1877, 1933, 1997,  +        2039, 2089, 2141, 2213, 2269, 2311, 2371, 2411, 2467, 2543,  +        2609, 2663, 2699, 2741, 2797, 2851, 2909, 2969, 3037, 3089,  +        3169, 3221, 3299, 3331, 3389, 3461, 3517, 3557, 3613, 3671,  +        3719, 3779, 3847, 3907, 3943, 4013, 4073, 4129, 4201, 4243,  +        4289, 4363, 4441, 4493, 4549, 4621, 4663, 4729, 4793, 4871,  +        4933, 4973, 5021, 5087, 5153, 5227, 5281, 5351, 5417, 5471,  +        5519, 5573, 5651, 5693, 5749, 5821, 5861, 5923, 6011, 6073,  +        6131, 6199, 6257, 6301, 6353, 6397, 6481, 6563, 6619, 6689,  +        6737, 6803, 6863, 6917, 6977, 7027, 7109, 7187, 7237, 7309,  +        7393, 7477, 7523, 7561, 7607, 7681, 7727, 7817, 7877, 7933,  +        8011, 8039, 8059, 8081, 8093, 8111, 8123, 8147 +    }; +    unsigned * pSims; +    unsigned uHash; +    int i; +    assert( p->nWordsTotal <= 128 ); +    uHash = 0; +    pSims = Ssw_ObjSim(p, pObj->Id); +    for ( i = p->nWordsPref; i < p->nWordsTotal; i++ ) +        uHash ^= pSims[i] * s_SPrimes[i & 0x7F]; +    return uHash; +} + +/**Function************************************************************* + +  Synopsis    [Returns 1 if simulation info is composed of all zeros.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ssw_SmlObjIsConstWord( Ssw_Sml_t * p, Aig_Obj_t * pObj ) +{ +    unsigned * pSims; +    int i; +    pSims = Ssw_ObjSim(p, pObj->Id); +    for ( i = p->nWordsPref; i < p->nWordsTotal; i++ ) +        if ( pSims[i] ) +            return 0; +    return 1; +} + +/**Function************************************************************* + +  Synopsis    [Returns 1 if simulation infos are equal.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ssw_SmlObjsAreEqualWord( Ssw_Sml_t * p, Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 ) +{ +    unsigned * pSims0, * pSims1; +    int i; +    pSims0 = Ssw_ObjSim(p, pObj0->Id); +    pSims1 = Ssw_ObjSim(p, pObj1->Id); +    for ( i = p->nWordsPref; i < p->nWordsTotal; i++ ) +        if ( pSims0[i] != pSims1[i] ) +            return 0; +    return 1; +} + +/**Function************************************************************* + +  Synopsis    [Returns 1 if the node appears to be constant 1 candidate.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ssw_SmlObjIsConstBit( void * p, Aig_Obj_t * pObj ) +{ +    return pObj->fPhase == pObj->fMarkB; +} + +/**Function************************************************************* + +  Synopsis    [Returns 1 if the nodes appear equal.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ssw_SmlObjsAreEqualBit( void * p, Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 ) +{ +    return (pObj0->fPhase == pObj1->fPhase) == (pObj0->fMarkB == pObj1->fMarkB); +} + + +/**Function************************************************************* + +  Synopsis    [Counts the number of 1s in the XOR of simulation data.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ssw_SmlNodeNotEquWeight( Ssw_Sml_t * p, int Left, int Right ) +{ +    unsigned * pSimL, * pSimR; +    int k, Counter = 0; +    pSimL = Ssw_ObjSim( p, Left ); +    pSimR = Ssw_ObjSim( p, Right ); +    for ( k = p->nWordsPref; k < p->nWordsTotal; k++ ) +        Counter += Aig_WordCountOnes( pSimL[k] ^ pSimR[k] ); +    return Counter; +} + +/**Function************************************************************* + +  Synopsis    [Returns 1 if simulation info is composed of all zeros.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ssw_SmlNodeIsZero( Ssw_Sml_t * p, Aig_Obj_t * pObj ) +{ +    unsigned * pSims; +    int i; +    pSims = Ssw_ObjSim(p, pObj->Id); +    for ( i = p->nWordsPref; i < p->nWordsTotal; i++ ) +        if ( pSims[i] ) +            return 0; +    return 1; +} + +/**Function************************************************************* + +  Synopsis    [Counts the number of one's in the patten of the output.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ssw_SmlNodeCountOnes( Ssw_Sml_t * p, Aig_Obj_t * pObj ) +{ +    unsigned * pSims; +    int i, Counter = 0; +    pSims = Ssw_ObjSim(p, pObj->Id); +    for ( i = 0; i < p->nWordsTotal; i++ ) +        Counter += Aig_WordCountOnes( pSims[i] ); +    return Counter; +} + + + +/**Function************************************************************* + +  Synopsis    [Generated const 0 pattern.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_SmlSavePattern0( Ssw_Man_t * p, int fInit ) +{ +    memset( p->pPatWords, 0, sizeof(unsigned) * p->nPatWords ); +} + +/**Function************************************************************* + +  Synopsis    [[Generated const 1 pattern.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_SmlSavePattern1( Ssw_Man_t * p, int fInit ) +{ +    Aig_Obj_t * pObj; +    int i, k, nTruePis; +    memset( p->pPatWords, 0xff, sizeof(unsigned) * p->nPatWords ); +    if ( !fInit ) +        return; +    // clear the state bits to correspond to all-0 initial state +    nTruePis = Saig_ManPiNum(p->pAig); +    k = 0; +    Saig_ManForEachLo( p->pAig, pObj, i ) +        Aig_InfoXorBit( p->pPatWords, nTruePis * p->nFrames + k++ ); +} + +/**Function************************************************************* + +  Synopsis    [Copy pattern from the solver into the internal storage.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_SmlSavePattern( Ssw_Man_t * p ) +{ +    Aig_Obj_t * pObj; +    int i; +    memset( p->pPatWords, 0, sizeof(unsigned) * p->nPatWords ); +    Aig_ManForEachPi( p->pFrames, pObj, i ) +        if ( p->pSat->model.ptr[Ssw_ObjSatNum(p, pObj)] == l_True ) +            Aig_InfoSetBit( p->pPatWords, i ); +/* +    if ( p->vCex ) +    { +        Vec_IntClear( p->vCex ); +        for ( i = 0; i < Saig_ManPiNum(p->pAig); i++ ) +            Vec_IntPush( p->vCex, Aig_InfoHasBit( p->pPatWords, i ) ); +        for ( i = Saig_ManPiNum(p->pFrames); i < Aig_ManPiNum(p->pFrames); i++ ) +            Vec_IntPush( p->vCex, Aig_InfoHasBit( p->pPatWords, i ) ); +    } +*/ + +/* +    printf( "Pattern: " ); +    Aig_ManForEachPi( p->pFrames, pObj, i ) +        printf( "%d", Aig_InfoHasBit( p->pPatWords, i ) ); +    printf( "\n" ); +*/ +} + + + +/**Function************************************************************* + +  Synopsis    [Creates the counter-example from the successful pattern.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int * Ssw_SmlCheckOutputSavePattern( Ssw_Sml_t * p, Aig_Obj_t * pObjPo ) +{  +    Aig_Obj_t * pFanin, * pObjPi; +    unsigned * pSims; +    int i, k, BestPat, * pModel; +    // find the word of the pattern +    pFanin = Aig_ObjFanin0(pObjPo); +    pSims = Ssw_ObjSim(p, pFanin->Id); +    for ( i = 0; i < p->nWordsTotal; i++ ) +        if ( pSims[i] ) +            break; +    assert( i < p->nWordsTotal ); +    // find the bit of the pattern +    for ( k = 0; k < 32; k++ ) +        if ( pSims[i] & (1 << k) ) +            break; +    assert( k < 32 ); +    // determine the best pattern +    BestPat = i * 32 + k; +    // fill in the counter-example data +    pModel = ALLOC( int, Aig_ManPiNum(p->pAig)+1 ); +    Aig_ManForEachPi( p->pAig, pObjPi, i ) +    { +        pModel[i] = Aig_InfoHasBit(Ssw_ObjSim(p, pObjPi->Id), BestPat); +//        printf( "%d", pModel[i] ); +    } +    pModel[Aig_ManPiNum(p->pAig)] = pObjPo->Id; +//    printf( "\n" ); +    return pModel; +} + +/**Function************************************************************* + +  Synopsis    [Returns 1 if the one of the output is already non-constant 0.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int * Ssw_SmlCheckOutput( Ssw_Sml_t * p ) +{ +    Aig_Obj_t * pObj; +    int i; +    // make sure the reference simulation pattern does not detect the bug +    pObj = Aig_ManPo( p->pAig, 0 ); +    assert( Aig_ObjFanin0(pObj)->fPhase == (unsigned)Aig_ObjFaninC0(pObj) );  +    Aig_ManForEachPo( p->pAig, pObj, i ) +    { +        if ( !Ssw_SmlObjIsConstWord( p, Aig_ObjFanin0(pObj) ) ) +        { +            // create the counter-example from this pattern +            return Ssw_SmlCheckOutputSavePattern( p, pObj ); +        } +    } +    return NULL; +} + + + +/**Function************************************************************* + +  Synopsis    [Assigns random patterns to the PI node.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_SmlAssignRandom( Ssw_Sml_t * p, Aig_Obj_t * pObj ) +{ +    unsigned * pSims; +    int i; +    assert( Aig_ObjIsPi(pObj) ); +    pSims = Ssw_ObjSim( p, pObj->Id ); +    for ( i = 0; i < p->nWordsTotal; i++ ) +        pSims[i] = Ssw_ObjRandomSim(); +} + +/**Function************************************************************* + +  Synopsis    [Assigns random patterns to the PI node.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_SmlAssignRandomFrame( Ssw_Sml_t * p, Aig_Obj_t * pObj, int iFrame ) +{ +    unsigned * pSims; +    int i; +    assert( Aig_ObjIsPi(pObj) ); +    pSims = Ssw_ObjSim( p, pObj->Id ) + p->nWordsFrame * iFrame; +    for ( i = 0; i < p->nWordsFrame; i++ ) +        pSims[i] = Ssw_ObjRandomSim(); +} + +/**Function************************************************************* + +  Synopsis    [Assigns constant patterns to the PI node.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_SmlObjAssignConst( Ssw_Sml_t * p, Aig_Obj_t * pObj, int fConst1, int iFrame ) +{ +    unsigned * pSims; +    int i; +    assert( Aig_ObjIsPi(pObj) ); +    pSims = Ssw_ObjSim( p, pObj->Id ) + p->nWordsFrame * iFrame; +    for ( i = 0; i < p->nWordsFrame; i++ ) +        pSims[i] = fConst1? ~(unsigned)0 : 0; +}  + +/**Function************************************************************* + +  Synopsis    [Assigns constant patterns to the PI node.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +unsigned Ssw_SmlObjGetWord( Ssw_Sml_t * p, Aig_Obj_t * pObj, int iWord, int iFrame ) +{ +    unsigned * pSims; +//    assert( Aig_ObjIsPi(pObj) ); +    pSims = Ssw_ObjSim( p, pObj->Id ) + p->nWordsFrame * iFrame; +    return pSims[iWord]; +}  + +/**Function************************************************************* + +  Synopsis    [Assigns constant patterns to the PI node.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_SmlObjSetWord( Ssw_Sml_t * p, Aig_Obj_t * pObj, unsigned Word, int iWord, int iFrame ) +{ +    unsigned * pSims; +    assert( Aig_ObjIsPi(pObj) ); +    pSims = Ssw_ObjSim( p, pObj->Id ) + p->nWordsFrame * iFrame; +    pSims[iWord] = Word; +}  + +/**Function************************************************************* + +  Synopsis    [Assings random simulation info for the PIs.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_SmlInitialize( Ssw_Sml_t * p, int fInit ) +{ +    Aig_Obj_t * pObj; +    int i; +    if ( fInit ) +    { +        assert( Aig_ManRegNum(p->pAig) > 0 ); +        assert( Aig_ManRegNum(p->pAig) < Aig_ManPiNum(p->pAig) ); +        // assign random info for primary inputs +        Saig_ManForEachPi( p->pAig, pObj, i ) +            Ssw_SmlAssignRandom( p, pObj ); +        // assign the initial state for the latches +        Saig_ManForEachLo( p->pAig, pObj, i ) +            Ssw_SmlObjAssignConst( p, pObj, 0, 0 ); +    } +    else +    { +        Aig_ManForEachPi( p->pAig, pObj, i ) +            Ssw_SmlAssignRandom( p, pObj ); +    } +} + +/**Function************************************************************* + +  Synopsis    [Assings distance-1 simulation info for the PIs.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_SmlAssignDist1( Ssw_Sml_t * p, unsigned * pPat ) +{ +    Aig_Obj_t * pObj; +    int f, i, k, Limit, nTruePis; +    assert( p->nFrames > 0 ); +    if ( p->nFrames == 1 ) +    { +        // copy the PI info  +        Aig_ManForEachPi( p->pAig, pObj, i ) +            Ssw_SmlObjAssignConst( p, pObj, Aig_InfoHasBit(pPat, i), 0 ); +        // flip one bit +        Limit = AIG_MIN( Aig_ManPiNum(p->pAig), p->nWordsTotal * 32 - 1 ); +        for ( i = 0; i < Limit; i++ ) +            Aig_InfoXorBit( Ssw_ObjSim( p, Aig_ManPi(p->pAig,i)->Id ), i+1 ); +    } +    else +    { +        int fUseDist1 = 0; + +        // copy the PI info for each frame +        nTruePis = Aig_ManPiNum(p->pAig) - Aig_ManRegNum(p->pAig); +        for ( f = 0; f < p->nFrames; f++ ) +            Saig_ManForEachPi( p->pAig, pObj, i ) +                Ssw_SmlObjAssignConst( p, pObj, Aig_InfoHasBit(pPat, nTruePis * f + i), f ); +        // copy the latch info  +        k = 0; +        Saig_ManForEachLo( p->pAig, pObj, i ) +            Ssw_SmlObjAssignConst( p, pObj, Aig_InfoHasBit(pPat, nTruePis * p->nFrames + k++), 0 ); +//        assert( p->pFrames == NULL || nTruePis * p->nFrames + k == Aig_ManPiNum(p->pFrames) ); + +        // flip one bit of the last frame +        if ( fUseDist1 ) //&& p->nFrames == 2 ) +        { +            Limit = AIG_MIN( nTruePis, p->nWordsFrame * 32 - 1 ); +            for ( i = 0; i < Limit; i++ ) +                Aig_InfoXorBit( Ssw_ObjSim( p, Aig_ManPi(p->pAig, i)->Id ) + p->nWordsFrame*(p->nFrames-1), i+1 ); +        } +    } +} + +/**Function************************************************************* + +  Synopsis    [Assings distance-1 simulation info for the PIs.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_SmlAssignDist1Plus( Ssw_Sml_t * p, unsigned * pPat ) +{ +    Aig_Obj_t * pObj; +    int f, i, Limit; +    assert( p->nFrames > 0 ); + +    // copy the pattern into the primary inputs +    Aig_ManForEachPi( p->pAig, pObj, i ) +        Ssw_SmlObjAssignConst( p, pObj, Aig_InfoHasBit(pPat, i), 0 ); +/* +    // set distance one PIs for the first frame +    Limit = AIG_MIN( Saig_ManPiNum(p->pAig), p->nWordsFrame * 32 - 1 ); +    for ( i = 0; i < Limit; i++ ) +        Aig_InfoXorBit( Ssw_ObjSim( p, Aig_ManPi(p->pAig, i)->Id ), i+1 ); +*/ +    // create random info for the remaining timeframes +    for ( f = 1; f < p->nFrames; f++ ) +        Saig_ManForEachPi( p->pAig, pObj, i ) +            Ssw_SmlAssignRandomFrame( p, pObj, f ); +} + +/**Function************************************************************* + +  Synopsis    [Simulates one node.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_SmlNodeSimulate( Ssw_Sml_t * p, Aig_Obj_t * pObj, int iFrame ) +{ +    unsigned * pSims, * pSims0, * pSims1; +    int fCompl, fCompl0, fCompl1, i; +    assert( !Aig_IsComplement(pObj) ); +    assert( Aig_ObjIsNode(pObj) ); +    assert( iFrame == 0 || p->nWordsFrame < p->nWordsTotal ); +    // get hold of the simulation information +    pSims  = Ssw_ObjSim(p, pObj->Id) + p->nWordsFrame * iFrame; +    pSims0 = Ssw_ObjSim(p, Aig_ObjFanin0(pObj)->Id) + p->nWordsFrame * iFrame; +    pSims1 = Ssw_ObjSim(p, Aig_ObjFanin1(pObj)->Id) + p->nWordsFrame * iFrame; +    // get complemented attributes of the children using their random info +    fCompl  = pObj->fPhase; +    fCompl0 = Aig_ObjPhaseReal(Aig_ObjChild0(pObj)); +    fCompl1 = Aig_ObjPhaseReal(Aig_ObjChild1(pObj)); +    // simulate +    if ( fCompl0 && fCompl1 ) +    { +        if ( fCompl ) +            for ( i = 0; i < p->nWordsFrame; i++ ) +                pSims[i] = (pSims0[i] | pSims1[i]); +        else +            for ( i = 0; i < p->nWordsFrame; i++ ) +                pSims[i] = ~(pSims0[i] | pSims1[i]); +    } +    else if ( fCompl0 && !fCompl1 ) +    { +        if ( fCompl ) +            for ( i = 0; i < p->nWordsFrame; i++ ) +                pSims[i] = (pSims0[i] | ~pSims1[i]); +        else +            for ( i = 0; i < p->nWordsFrame; i++ ) +                pSims[i] = (~pSims0[i] & pSims1[i]); +    } +    else if ( !fCompl0 && fCompl1 ) +    { +        if ( fCompl ) +            for ( i = 0; i < p->nWordsFrame; i++ ) +                pSims[i] = (~pSims0[i] | pSims1[i]); +        else +            for ( i = 0; i < p->nWordsFrame; i++ ) +                pSims[i] = (pSims0[i] & ~pSims1[i]); +    } +    else // if ( !fCompl0 && !fCompl1 ) +    { +        if ( fCompl ) +            for ( i = 0; i < p->nWordsFrame; i++ ) +                pSims[i] = ~(pSims0[i] & pSims1[i]); +        else +            for ( i = 0; i < p->nWordsFrame; i++ ) +                pSims[i] = (pSims0[i] & pSims1[i]); +    } +} + +/**Function************************************************************* + +  Synopsis    [Simulates one node.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ssw_SmlNodesCompareInFrame( Ssw_Sml_t * p, Aig_Obj_t * pObj0, Aig_Obj_t * pObj1, int iFrame0, int iFrame1 ) +{ +    unsigned * pSims0, * pSims1; +    int i; +    assert( !Aig_IsComplement(pObj0) ); +    assert( !Aig_IsComplement(pObj1) ); +    assert( iFrame0 == 0 || p->nWordsFrame < p->nWordsTotal ); +    assert( iFrame1 == 0 || p->nWordsFrame < p->nWordsTotal ); +    // get hold of the simulation information +    pSims0  = Ssw_ObjSim(p, pObj0->Id) + p->nWordsFrame * iFrame0; +    pSims1  = Ssw_ObjSim(p, pObj1->Id) + p->nWordsFrame * iFrame1; +    // compare +    for ( i = 0; i < p->nWordsFrame; i++ ) +        if ( pSims0[i] != pSims1[i] ) +            return 0; +    return 1; +} + +/**Function************************************************************* + +  Synopsis    [Simulates one node.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_SmlNodeCopyFanin( Ssw_Sml_t * p, Aig_Obj_t * pObj, int iFrame ) +{ +    unsigned * pSims, * pSims0; +    int fCompl, fCompl0, i; +    assert( !Aig_IsComplement(pObj) ); +    assert( Aig_ObjIsPo(pObj) ); +    assert( iFrame == 0 || p->nWordsFrame < p->nWordsTotal ); +    // get hold of the simulation information +    pSims  = Ssw_ObjSim(p, pObj->Id) + p->nWordsFrame * iFrame; +    pSims0 = Ssw_ObjSim(p, Aig_ObjFanin0(pObj)->Id) + p->nWordsFrame * iFrame; +    // get complemented attributes of the children using their random info +    fCompl  = pObj->fPhase; +    fCompl0 = Aig_ObjPhaseReal(Aig_ObjChild0(pObj)); +    // copy information as it is +    if ( fCompl0 ) +        for ( i = 0; i < p->nWordsFrame; i++ ) +            pSims[i] = ~pSims0[i]; +    else +        for ( i = 0; i < p->nWordsFrame; i++ ) +            pSims[i] = pSims0[i]; +} + +/**Function************************************************************* + +  Synopsis    [Simulates one node.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_SmlNodeTransferNext( Ssw_Sml_t * p, Aig_Obj_t * pOut, Aig_Obj_t * pIn, int iFrame ) +{ +    unsigned * pSims0, * pSims1; +    int i; +    assert( !Aig_IsComplement(pOut) ); +    assert( !Aig_IsComplement(pIn) ); +    assert( Aig_ObjIsPo(pOut) ); +    assert( Aig_ObjIsPi(pIn) ); +    assert( iFrame == 0 || p->nWordsFrame < p->nWordsTotal ); +    // get hold of the simulation information +    pSims0 = Ssw_ObjSim(p, pOut->Id) + p->nWordsFrame * iFrame; +    pSims1 = Ssw_ObjSim(p, pIn->Id) + p->nWordsFrame * (iFrame+1); +    // copy information as it is +    for ( i = 0; i < p->nWordsFrame; i++ ) +        pSims1[i] = pSims0[i]; +} + + +/**Function************************************************************* + +  Synopsis    [Check if any of the POs becomes non-constant.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ssw_SmlCheckNonConstOutputs( Ssw_Sml_t * p ) +{ +    Aig_Obj_t * pObj; +    int i; +    Saig_ManForEachPo( p->pAig, pObj, i ) +        if ( !Ssw_SmlNodeIsZero(p, pObj) ) +            return 1; +    return 0; +} + +/**Function************************************************************* + +  Synopsis    [Simulates AIG manager.] + +  Description [Assumes that the PI simulation info is attached.] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_SmlSimulateOne( Ssw_Sml_t * p ) +{ +    Aig_Obj_t * pObj, * pObjLi, * pObjLo; +    int f, i, clk; +clk = clock(); +    for ( f = 0; f < p->nFrames; f++ ) +    { +        // simulate the nodes +        Aig_ManForEachNode( p->pAig, pObj, i ) +            Ssw_SmlNodeSimulate( p, pObj, f ); +        // copy simulation info into outputs +        Saig_ManForEachPo( p->pAig, pObj, i ) +            Ssw_SmlNodeCopyFanin( p, pObj, f ); +        // quit if this is the last timeframe +        if ( f == p->nFrames - 1 ) +            break; +        // copy simulation info into outputs +        Saig_ManForEachLi( p->pAig, pObj, i ) +            Ssw_SmlNodeCopyFanin( p, pObj, f ); +        // copy simulation info into the inputs +        Saig_ManForEachLiLo( p->pAig, pObjLi, pObjLo, i ) +            Ssw_SmlNodeTransferNext( p, pObjLi, pObjLo, f ); +    } +p->timeSim += clock() - clk; +p->nSimRounds++; +} + +/**Function************************************************************* + +  Synopsis    [Simulates AIG manager.] + +  Description [Assumes that the PI simulation info is attached.] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_SmlSimulateOneFrame( Ssw_Sml_t * p ) +{ +    Aig_Obj_t * pObj, * pObjLi, * pObjLo; +    int i, clk; +clk = clock(); +    // simulate the nodes +    Aig_ManForEachNode( p->pAig, pObj, i ) +        Ssw_SmlNodeSimulate( p, pObj, 0 ); +    // copy simulation info into outputs +    Saig_ManForEachLi( p->pAig, pObj, i ) +        Ssw_SmlNodeCopyFanin( p, pObj, 0 ); +    // copy simulation info into the inputs +    Saig_ManForEachLiLo( p->pAig, pObjLi, pObjLo, i ) +        Ssw_SmlNodeTransferNext( p, pObjLi, pObjLo, 0 ); +p->timeSim += clock() - clk; +p->nSimRounds++; +} + + +/**Function************************************************************* + +  Synopsis    [Allocates simulation manager.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Ssw_Sml_t * Ssw_SmlStart( Aig_Man_t * pAig, int nPref, int nFrames, int nWordsFrame ) +{ +    Ssw_Sml_t * p; +    p = (Ssw_Sml_t *)malloc( sizeof(Ssw_Sml_t) + sizeof(unsigned) * Aig_ManObjNumMax(pAig) * (nPref + nFrames) * nWordsFrame ); +    memset( p, 0, sizeof(Ssw_Sml_t) + sizeof(unsigned) * (nPref + nFrames) * nWordsFrame ); +    p->pAig        = pAig; +    p->nPref       = nPref; +    p->nFrames     = nPref + nFrames; +    p->nWordsFrame = nWordsFrame; +    p->nWordsTotal = (nPref + nFrames) * nWordsFrame; +    p->nWordsPref  = nPref * nWordsFrame; +    return p; +} + +/**Function************************************************************* + +  Synopsis    [Allocates simulation manager.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_SmlClean( Ssw_Sml_t * p ) +{ +    memset( p->pData, 0, sizeof(unsigned) * Aig_ManObjNumMax(p->pAig) * p->nWordsTotal ); +} + +/**Function************************************************************* + +  Synopsis    [Deallocates simulation manager.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_SmlStop( Ssw_Sml_t * p ) +{ +    free( p ); +} + + +/**Function************************************************************* + +  Synopsis    [Performs simulation of the uninitialized circuit.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Ssw_Sml_t * Ssw_SmlSimulateComb( Aig_Man_t * pAig, int nWords ) +{ +    Ssw_Sml_t * p; +    p = Ssw_SmlStart( pAig, 0, 1, nWords ); +    Ssw_SmlInitialize( p, 0 ); +    Ssw_SmlSimulateOne( p ); +    return p; +} + +/**Function************************************************************* + +  Synopsis    [Performs simulation of the initialized circuit.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Ssw_Sml_t * Ssw_SmlSimulateSeq( Aig_Man_t * pAig, int nPref, int nFrames, int nWords ) +{ +    Ssw_Sml_t * p; +    p = Ssw_SmlStart( pAig, nPref, nFrames, nWords ); +    Ssw_SmlInitialize( p, 1 ); +    Ssw_SmlSimulateOne( p ); +    p->fNonConstOut = Ssw_SmlCheckNonConstOutputs( p ); +    return p; +} + + + +/**Function************************************************************* + +  Synopsis    [Allocates a counter-example.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Ssw_Cex_t * Ssw_SmlAllocCounterExample( int nRegs, int nRealPis, int nFrames ) +{ +    Ssw_Cex_t * pCex; +    int nWords = Aig_BitWordNum( nRegs + nRealPis * nFrames ); +    pCex = (Ssw_Cex_t *)malloc( sizeof(Ssw_Cex_t) + sizeof(unsigned) * nWords ); +    memset( pCex, 0, sizeof(Ssw_Cex_t) + sizeof(unsigned) * nWords ); +    pCex->nRegs  = nRegs; +    pCex->nPis   = nRealPis; +    pCex->nBits  = nRegs + nRealPis * nFrames; +    return pCex; +} + +/**Function************************************************************* + +  Synopsis    [Frees the counter-example.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_SmlFreeCounterExample( Ssw_Cex_t * pCex ) +{ +    free( pCex ); +} + +/**Function************************************************************* + +  Synopsis    [Resimulates the counter-example.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ssw_SmlRunCounterExample( Aig_Man_t * pAig, Ssw_Cex_t * p ) +{ +    Ssw_Sml_t * pSml; +    Aig_Obj_t * pObj; +    int RetValue, i, k, iBit; +    assert( Aig_ManRegNum(pAig) > 0 ); +    assert( Aig_ManRegNum(pAig) < Aig_ManPiNum(pAig) ); +    // start a new sequential simulator +    pSml = Ssw_SmlStart( pAig, 0, p->iFrame+1, 1 ); +    // assign simulation info for the registers +    iBit = 0; +    Saig_ManForEachLo( pAig, pObj, i ) +        Ssw_SmlObjAssignConst( pSml, pObj, Aig_InfoHasBit(p->pData, iBit++), 0 ); +    // assign simulation info for the primary inputs +    for ( i = 0; i <= p->iFrame; i++ ) +        Saig_ManForEachPi( pAig, pObj, k ) +            Ssw_SmlObjAssignConst( pSml, pObj, Aig_InfoHasBit(p->pData, iBit++), i ); +    assert( iBit == p->nBits ); +    // run random simulation +    Ssw_SmlSimulateOne( pSml ); +    // check if the given output has failed +    RetValue = !Ssw_SmlNodeIsZero( pSml, Aig_ManPo(pAig, p->iPo) ); +    Ssw_SmlStop( pSml ); +    return RetValue; +} + +/**Function************************************************************* + +  Synopsis    [Resimulates the counter-example.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ssw_SmlFindOutputCounterExample( Aig_Man_t * pAig, Ssw_Cex_t * p ) +{ +    Ssw_Sml_t * pSml; +    Aig_Obj_t * pObj; +    int i, k, iBit, iOut; +    assert( Aig_ManRegNum(pAig) > 0 ); +    assert( Aig_ManRegNum(pAig) < Aig_ManPiNum(pAig) ); +    // start a new sequential simulator +    pSml = Ssw_SmlStart( pAig, 0, p->iFrame+1, 1 ); +    // assign simulation info for the registers +    iBit = 0; +    Saig_ManForEachLo( pAig, pObj, i ) +        Ssw_SmlObjAssignConst( pSml, pObj, Aig_InfoHasBit(p->pData, iBit++), 0 ); +    // assign simulation info for the primary inputs +    for ( i = 0; i <= p->iFrame; i++ ) +        Saig_ManForEachPi( pAig, pObj, k ) +            Ssw_SmlObjAssignConst( pSml, pObj, Aig_InfoHasBit(p->pData, iBit++), i ); +    assert( iBit == p->nBits ); +    // run random simulation +    Ssw_SmlSimulateOne( pSml ); +    // check if the given output has failed +    iOut = -1; +    Saig_ManForEachPo( pAig, pObj, k ) +        if ( !Ssw_SmlNodeIsZero( pSml, Aig_ManPo(pAig, k) ) ) +        { +            iOut = k; +            break; +        } +    Ssw_SmlStop( pSml ); +    return iOut; +} + +/**Function************************************************************* + +  Synopsis    [Creates sequential counter-example from the simulation info.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Ssw_Cex_t * Ssw_SmlGetCounterExample( Ssw_Sml_t * p ) +{ +    Ssw_Cex_t * pCex; +    Aig_Obj_t * pObj; +    unsigned * pSims; +    int iPo, iFrame, iBit, i, k; + +    // make sure the simulation manager has it +    assert( p->fNonConstOut ); + +    // find the first output that failed +    iPo = -1; +    iBit = -1; +    iFrame = -1; +    Saig_ManForEachPo( p->pAig, pObj, iPo ) +    { +        if ( Ssw_SmlNodeIsZero(p, pObj) ) +            continue; +        pSims = Ssw_ObjSim( p, pObj->Id ); +        for ( i = p->nWordsPref; i < p->nWordsTotal; i++ ) +            if ( pSims[i] ) +            { +                iFrame = i / p->nWordsFrame; +                iBit = 32 * (i % p->nWordsFrame) + Aig_WordFindFirstBit( pSims[i] ); +                break; +            } +        break; +    } +    assert( iPo < Aig_ManPoNum(p->pAig)-Aig_ManRegNum(p->pAig) ); +    assert( iFrame < p->nFrames ); +    assert( iBit < 32 * p->nWordsFrame ); + +    // allocate the counter example +    pCex = Ssw_SmlAllocCounterExample( Aig_ManRegNum(p->pAig), Aig_ManPiNum(p->pAig) - Aig_ManRegNum(p->pAig), iFrame + 1 ); +    pCex->iPo    = iPo; +    pCex->iFrame = iFrame; + +    // copy the bit data +    Saig_ManForEachLo( p->pAig, pObj, k ) +    { +        pSims = Ssw_ObjSim( p, pObj->Id ); +        if ( Aig_InfoHasBit( pSims, iBit ) ) +            Aig_InfoSetBit( pCex->pData, k ); +    } +    for ( i = 0; i <= iFrame; i++ ) +    { +        Saig_ManForEachPi( p->pAig, pObj, k ) +        { +            pSims = Ssw_ObjSim( p, pObj->Id ); +            if ( Aig_InfoHasBit( pSims, 32 * p->nWordsFrame * i + iBit ) ) +                Aig_InfoSetBit( pCex->pData, pCex->nRegs + pCex->nPis * i + k ); +        } +    } +    // verify the counter example +    if ( !Ssw_SmlRunCounterExample( p->pAig, pCex ) ) +    { +        printf( "Ssw_SmlGetCounterExample(): Counter-example is invalid.\n" ); +        Ssw_SmlFreeCounterExample( pCex ); +        pCex = NULL; +    } +    return pCex; +} +  +/**Function************************************************************* + +  Synopsis    [Generates seq counter-example from the combinational one.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Ssw_Cex_t * Ssw_SmlCopyCounterExample( Aig_Man_t * pAig, Aig_Man_t * pFrames, int * pModel ) +{ +    Ssw_Cex_t * pCex; +    Aig_Obj_t * pObj; +    int i, nFrames, nTruePis, nTruePos, iPo, iFrame; +    // get the number of frames +    assert( Aig_ManRegNum(pAig) > 0 ); +    assert( Aig_ManRegNum(pFrames) == 0 ); +    nTruePis = Aig_ManPiNum(pAig)-Aig_ManRegNum(pAig); +    nTruePos = Aig_ManPoNum(pAig)-Aig_ManRegNum(pAig); +    nFrames = Aig_ManPiNum(pFrames) / nTruePis; +    assert( nTruePis * nFrames == Aig_ManPiNum(pFrames) ); +    assert( nTruePos * nFrames == Aig_ManPoNum(pFrames) ); +    // find the PO that failed +    iPo = -1; +    iFrame = -1; +    Aig_ManForEachPo( pFrames, pObj, i ) +        if ( pObj->Id == pModel[Aig_ManPiNum(pFrames)] ) +        { +            iPo = i % nTruePos; +            iFrame = i / nTruePos; +            break; +        } +    assert( iPo >= 0 ); +    // allocate the counter example +    pCex = Ssw_SmlAllocCounterExample( Aig_ManRegNum(pAig), nTruePis, iFrame + 1 ); +    pCex->iPo    = iPo; +    pCex->iFrame = iFrame; + +    // copy the bit data +    for ( i = 0; i < Aig_ManPiNum(pFrames); i++ ) +    { +        if ( pModel[i] ) +            Aig_InfoSetBit( pCex->pData, pCex->nRegs + i ); +        if ( pCex->nRegs + i == pCex->nBits - 1 ) +            break; +    } + +    // verify the counter example +    if ( !Ssw_SmlRunCounterExample( pAig, pCex ) ) +    { +        printf( "Ssw_SmlGetCounterExample(): Counter-example is invalid.\n" ); +        Ssw_SmlFreeCounterExample( pCex ); +        pCex = NULL; +    } +    return pCex; + +} + +/**Function************************************************************* + +  Synopsis    [Make the trivial counter-example for the trivially asserted output.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Ssw_Cex_t * Ssw_SmlTrivCounterExample( Aig_Man_t * pAig, int iFrameOut ) +{ +    Ssw_Cex_t * pCex; +    int nTruePis, nTruePos, iPo, iFrame; +    assert( Aig_ManRegNum(pAig) > 0 ); +    nTruePis = Aig_ManPiNum(pAig)-Aig_ManRegNum(pAig); +    nTruePos = Aig_ManPoNum(pAig)-Aig_ManRegNum(pAig); +    iPo = iFrameOut % nTruePos; +    iFrame = iFrameOut / nTruePos; +    // allocate the counter example +    pCex = Ssw_SmlAllocCounterExample( Aig_ManRegNum(pAig), nTruePis, iFrame + 1 ); +    pCex->iPo    = iPo; +    pCex->iFrame = iFrame; +    return pCex; +} + +/**Function************************************************************* + +  Synopsis    [Make the trivial counter-example for the trivially asserted output.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Ssw_Cex_t * Ssw_SmlDupCounterExample( Ssw_Cex_t * p, int nRegsNew ) +{ +    Ssw_Cex_t * pCex; +    int i; +    pCex = Ssw_SmlAllocCounterExample( nRegsNew, p->nPis, p->iFrame+1 ); +    pCex->iPo    = p->iPo; +    pCex->iFrame = p->iFrame; +    for ( i = p->nRegs; i < p->nBits; i++ ) +        if ( Aig_InfoHasBit(p->pData, i) ) +            Aig_InfoSetBit( pCex->pData, pCex->nRegs + i - p->nRegs ); +    return pCex; +} + +/**Function************************************************************* + +  Synopsis    [Resimulates the counter-example.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ssw_SmlWriteCounterExample( FILE * pFile, Aig_Man_t * pAig, Ssw_Cex_t * p ) +{ +    Ssw_Sml_t * pSml; +    Aig_Obj_t * pObj; +    int RetValue, i, k, iBit; +    unsigned * pSims; +    assert( Aig_ManRegNum(pAig) > 0 ); +    assert( Aig_ManRegNum(pAig) < Aig_ManPiNum(pAig) ); +    // start a new sequential simulator +    pSml = Ssw_SmlStart( pAig, 0, p->iFrame+1, 1 ); +    // assign simulation info for the registers +    iBit = 0; +    Saig_ManForEachLo( pAig, pObj, i ) +//        Ssw_SmlObjAssignConst( pSml, pObj, Aig_InfoHasBit(p->pData, iBit++), 0 ); +        Ssw_SmlObjAssignConst( pSml, pObj, 0, 0 ); +    // assign simulation info for the primary inputs +    iBit = p->nRegs; +    for ( i = 0; i <= p->iFrame; i++ ) +        Saig_ManForEachPi( pAig, pObj, k ) +            Ssw_SmlObjAssignConst( pSml, pObj, Aig_InfoHasBit(p->pData, iBit++), i ); +    assert( iBit == p->nBits ); +    // run random simulation +    Ssw_SmlSimulateOne( pSml ); +    // check if the given output has failed +    RetValue = !Ssw_SmlNodeIsZero( pSml, Aig_ManPo(pAig, p->iPo) ); + +    // write the output file +    for ( i = 0; i <= p->iFrame; i++ ) +    { +/* +        Saig_ManForEachLo( pAig, pObj, k ) +        { +            pSims = Ssw_ObjSim(pSml, pObj->Id); +            fprintf( pFile, "%d", (int)(pSims[i] != 0) ); +        } +        fprintf( pFile, " " ); +*/ +        Saig_ManForEachPi( pAig, pObj, k ) +        { +            pSims = Ssw_ObjSim(pSml, pObj->Id); +            fprintf( pFile, "%d", (int)(pSims[i] != 0) ); +        } +/* +        fprintf( pFile, " " ); +        Saig_ManForEachPo( pAig, pObj, k ) +        { +            pSims = Ssw_ObjSim(pSml, pObj->Id); +            fprintf( pFile, "%d", (int)(pSims[i] != 0) ); +        } +        fprintf( pFile, " " ); +        Saig_ManForEachLi( pAig, pObj, k ) +        { +            pSims = Ssw_ObjSim(pSml, pObj->Id); +            fprintf( pFile, "%d", (int)(pSims[i] != 0) ); +        } +*/ +        fprintf( pFile, "\n" ); +    } + +    Ssw_SmlStop( pSml ); +    return RetValue; +} + + + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/ssw_old/sswSimSat.c b/src/aig/ssw_old/sswSimSat.c new file mode 100644 index 00000000..cbb6d0c1 --- /dev/null +++ b/src/aig/ssw_old/sswSimSat.c @@ -0,0 +1,199 @@ +/**CFile**************************************************************** + +  FileName    [sswSimSat.c] + +  SystemName  [ABC: Logic synthesis and verification system.] + +  PackageName [Inductive prover with constraints.] + +  Synopsis    [Performs resimulation using counter-examples.] + +  Author      [Alan Mishchenko] +   +  Affiliation [UC Berkeley] + +  Date        [Ver. 1.0. Started - September 1, 2008.] + +  Revision    [$Id: sswSimSat.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "sswInt.h" + +//////////////////////////////////////////////////////////////////////// +///                        DECLARATIONS                              /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +///                     FUNCTION DEFINITIONS                         /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + +  Synopsis    [Handle the counter-example.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_ManResimulateBit( Ssw_Man_t * p, Aig_Obj_t * pCand, Aig_Obj_t * pRepr ) +{ +    Aig_Obj_t * pObj; +    int i, RetValue1, RetValue2, clk = clock(); +    // set the PI simulation information +    Aig_ManConst1(p->pAig)->fMarkB = 1; +    Aig_ManForEachPi( p->pAig, pObj, i ) +        pObj->fMarkB = Aig_InfoHasBit( p->pPatWords, i ); +    // 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) ); +    // check equivalence classes +    RetValue1 = Ssw_ClassesRefineConst1( p->ppClasses, 0 ); +    RetValue2 = Ssw_ClassesRefine( p->ppClasses, 0 ); +    // make sure refinement happened +    if ( Aig_ObjIsConst1(pRepr) )  +    { +        assert( RetValue1 ); +        if ( RetValue1 == 0 ) +            printf( "\nSsw_ManResimulateBit() Error: RetValue1 does not hold.\n" ); +    } +    else +    { +        assert( RetValue2 ); +        if ( RetValue2 == 0 ) +            printf( "\nSsw_ManResimulateBit() Error: RetValue2 does not hold.\n" ); +    } +p->timeSimSat += clock() - clk; +} + +/**Function************************************************************* + +  Synopsis    [Verifies the result of simulation.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_ManResimulateWordVerify( Ssw_Man_t * p, int f ) +{ +    Aig_Obj_t * pObj, * pObjFraig; +    unsigned uWord; +    int Value1, Value2; +    int i, nVarNum, Counter = 0; +    Aig_ManForEachObj( p->pAig, pObj, i ) +    { +        pObjFraig = Ssw_ObjFrame( p, pObj, f ); +        if ( pObjFraig == NULL ) +            continue; +        nVarNum = Ssw_ObjSatNum( p, Aig_Regular(pObjFraig) ); +        if ( nVarNum == 0 ) +            continue; +        Value1 = Ssw_ManGetSatVarValue( p, pObj, f ); +        uWord  = Ssw_SmlObjGetWord( p->pSml, pObj, 0, 0 ); +        Value2 = ((uWord != 0) ^ pObj->fPhase); +        Counter += (Value1 != Value2); +        if ( Value1 != Value2 ) +        { +/* +            int Value1f = Ssw_ManGetSatVarValue( p, Aig_ObjFanin0(pObj), f ); +            int Value2f = Ssw_ManGetSatVarValue( p, Aig_ObjFanin1(pObj), f ); +*/ +            int x = 0; +            int Value3 = Ssw_ManGetSatVarValue( p, pObj, f ); +        } +    } +    if ( Counter ) +        printf( "Counter = %d.\n", Counter ); +} + +/**Function************************************************************* + +  Synopsis    [Handle the counter-example.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_ManResimulateWord( Ssw_Man_t * p, Aig_Obj_t * pCand, Aig_Obj_t * pRepr, int f ) +{ +    int RetValue1, RetValue2, clk = clock(); +    // set the PI simulation information +    Ssw_SmlAssignDist1Plus( p->pSml, p->pPatWords ); +    // simulate internal nodes +    Ssw_SmlSimulateOne( p->pSml ); +    Ssw_ManResimulateWordVerify( p, f ); + +    // check equivalence classes +    RetValue1 = Ssw_ClassesRefineConst1( p->ppClasses, 1 ); +    RetValue2 = Ssw_ClassesRefine( p->ppClasses, 1 ); +    // make sure refinement happened +    if ( Aig_ObjIsConst1(pRepr) ) +    { +        assert( RetValue1 ); +        if ( RetValue1 == 0 ) +            printf( "\nSsw_ManResimulateWord() Error: RetValue1 does not hold.\n" ); +    } +    else +    { +        assert( RetValue2 ); +        if ( RetValue2 == 0 ) +            printf( "\nSsw_ManResimulateWord() Error: RetValue2 does not hold.\n" ); +    } +p->timeSimSat += clock() - clk; +} + +/**Function************************************************************* + +  Synopsis    [Handle the counter-example.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_ManResimulateWord2( Ssw_Man_t * p, Aig_Obj_t * pCand, Aig_Obj_t * pRepr, int f ) +{ +    int RetValue1, RetValue2, clk = clock(); +    // set the PI simulation information +    Ssw_SmlAssignDist1Plus( p->pSml, p->pPatWords2 ); +    // simulate internal nodes +    Ssw_SmlSimulateOne( p->pSml ); +    Ssw_ManResimulateWordVerify( p, f ); + +    // check equivalence classes +    RetValue1 = Ssw_ClassesRefineConst1( p->ppClasses, 1 ); +    RetValue2 = Ssw_ClassesRefine( p->ppClasses, 1 ); +    // make sure refinement happened +    if ( Aig_ObjIsConst1(pRepr) ) +    { +        assert( RetValue1 ); +        if ( RetValue1 == 0 ) +            printf( "\nSsw_ManResimulateWord() Error: RetValue1 does not hold.\n" ); +    } +    else +    { +        assert( RetValue2 ); +        if ( RetValue2 == 0 ) +            printf( "\nSsw_ManResimulateWord() Error: RetValue2 does not hold.\n" ); +    } +p->timeSimSat += clock() - clk; + +} + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/ssw_old/sswSweep.c b/src/aig/ssw_old/sswSweep.c new file mode 100644 index 00000000..b9d4ad63 --- /dev/null +++ b/src/aig/ssw_old/sswSweep.c @@ -0,0 +1,473 @@ +/**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" + +//////////////////////////////////////////////////////////////////////// +///                        DECLARATIONS                              /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +///                     FUNCTION DEFINITIONS                         /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + +  Synopsis    [Mark nodes affected by sweep in the previous iteration.] + +  Description [Assumes that affected nodes are in p->ppClasses->vRefined.] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_ManSweepMarkRefinement( Ssw_Man_t * p ) +{ +    Vec_Ptr_t * vRefined, * vSupp; +    Aig_Obj_t * pObj, * pObjLo, * pObjLi; +    int i, k; +    vRefined = Ssw_ClassesGetRefined( p->ppClasses ); +    if ( Vec_PtrSize(vRefined) == 0 ) +    { +        Aig_ManForEachObj( p->pAig, pObj, i ) +            pObj->fMarkA = 1; +        return; +    } +    // mark the nodes to be refined +    Aig_ManCleanMarkA( p->pAig ); +    Vec_PtrForEachEntry( vRefined, pObj, i ) +    { +        if ( Aig_ObjIsPi(pObj) ) +        { +            pObj->fMarkA = 1; +            continue; +        } +        assert( Aig_ObjIsNode(pObj) ); +        vSupp = Aig_Support( p->pAig, pObj ); +        Vec_PtrForEachEntry( vSupp, pObjLo, k ) +            pObjLo->fMarkA = 1; +        Vec_PtrFree( vSupp ); +    } +    // mark refinement +    Aig_ManForEachNode( p->pAig, pObj, i ) +        pObj->fMarkA = Aig_ObjFanin0(pObj)->fMarkA | Aig_ObjFanin1(pObj)->fMarkA; +    Saig_ManForEachLi( p->pAig, pObj, i ) +        pObj->fMarkA |= Aig_ObjFanin0(pObj)->fMarkA; +    Saig_ManForEachLiLo( p->pAig, pObjLi, pObjLo, i ) +        pObjLo->fMarkA |= pObjLi->fMarkA; +} + +/**Function************************************************************* + +  Synopsis    [Retrives value of the PI in the original AIG.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ssw_ManGetSatVarValue( Ssw_Man_t * p, Aig_Obj_t * pObj, int f ) +{ +    Aig_Obj_t * pObjFraig; +    int nVarNum, Value; +//    assert( Aig_ObjIsPi(pObj) ); +    pObjFraig = Ssw_ObjFrame( p, pObj, f ); +    nVarNum = Ssw_ObjSatNum( p, Aig_Regular(pObjFraig) ); +    assert( nVarNum > 0 ); +    if ( nVarNum == 0 ) +        printf( "Variable is not assigned.\n" ); +    Value = (!nVarNum)? 0 : (Aig_IsComplement(pObjFraig) ^ sat_solver_var_value( p->pSat, nVarNum )); +//    Value = (Aig_IsComplement(pObjFraig) ^ ((!nVarNum)? 0 : sat_solver_var_value( p->pSat, nVarNum ))); +//    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************************************************************* + +  Synopsis    [Copy pattern from the solver into the internal storage.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_SmlSavePatternAig( Ssw_Man_t * p, int f ) +{ +    Aig_Obj_t * pObj; +    int i; +    memset( p->pPatWords, 0, sizeof(unsigned) * p->nPatWords ); +    Aig_ManForEachPi( p->pAig, pObj, i ) +        if ( Ssw_ManGetSatVarValue( p, pObj, f ) ) +            Aig_InfoSetBit( p->pPatWords, i ); +} + +/**Function************************************************************* + +  Synopsis    [Copy pattern from the solver into the internal storage.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_SmlSavePatternAig2( Ssw_Man_t * p, int f ) +{ +    Aig_Obj_t * pObj; +    int i; +    memset( p->pPatWords2, 0, sizeof(unsigned) * p->nPatWords ); +    Aig_ManForEachPi( p->pAig, pObj, i ) +        if ( Ssw_ManGetSatVarValue( p, pObj, f ) ) +            Aig_InfoSetBit( p->pPatWords2, i ); +} + +/**Function************************************************************* + +  Synopsis    [Copy pattern from the solver into the internal storage.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ssw_SmlSavePatternAigPhase( Ssw_Man_t * p, int f ) +{ +    Aig_Obj_t * pObj; +    int i; +    memset( p->pPatWords, 0, sizeof(unsigned) * p->nPatWords ); +    Aig_ManForEachPi( p->pAig, pObj, i ) +        if ( Aig_ObjPhaseReal( Ssw_ObjFrame(p, pObj, f) ) ) +            Aig_InfoSetBit( p->pPatWords, i ); +} + +/**Function************************************************************* + +  Synopsis    [Performs fraiging for one node.] + +  Description [Returns the fraiged node.] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ssw_ManSweepNode( Ssw_Man_t * p, Aig_Obj_t * pObj, int f, int fBmc ) +{  +    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 ); +    if ( (pObj->fPhase == pObjRepr->fPhase) != (Aig_ObjPhaseReal(pObjFraig) == Aig_ObjPhaseReal(pObjReprFraig)) ) +    { +        p->nStrangers++; +        Ssw_SmlSavePatternAigPhase( p, f ); +    } +    else +    {  +        // if the fraiged nodes are the same, return +        if ( Aig_Regular(pObjFraig) == Aig_Regular(pObjReprFraig) ) +            return 0;  +        // count the number of skipped calls +        if ( !pObj->fMarkA && !pObjRepr->fMarkA ) +            p->nRefSkip++; +        else +            p->nRefUse++; +        // call equivalence checking +        if ( p->pPars->fSkipCheck && !fBmc && !pObj->fMarkA && !pObjRepr->fMarkA ) +            RetValue = 1; +        else 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; +        } +        // check if skipping calls works correctly +        if ( p->pPars->fSkipCheck && !fBmc && !pObj->fMarkA && !pObjRepr->fMarkA ) +        { +            assert( 0 ); +            printf( "\nSsw_ManSweepNode(): Error!\n" ); +        } +        // disproved the equivalence +        Ssw_SmlSavePatternAig( p, f ); +    }  +    if ( !fBmc && p->pPars->fUniqueness && p->pPars->nFramesK > 1 &&  +        Ssw_ManUniqueOne( p, pObjRepr, pObj ) && p->iOutputLit == -1 ) +    {  +        if ( Ssw_ManUniqueAddConstraint( p, p->vCommon, 0, 1 ) ) +        { +            int RetValue2 = Ssw_NodesAreEquiv( p, Aig_Regular(pObjReprFraig), Aig_Regular(pObjFraig) ); +            p->iOutputLit = -1; + +            { +                int Flag = 0; +                if ( Flag ) +                { +                    Aig_Obj_t * pFan0 = Aig_ObjFanin0(pObj); +                    Aig_Obj_t * pFan1 = Aig_ObjFanin1(pObj); +                    Aig_Obj_t * pFan00 = Aig_ObjFanin0(pFan0); +                    Aig_Obj_t * pFan01 = Aig_ObjFanin1(pFan0); +                    Aig_Obj_t * pFan10 = Aig_ObjFanin0(pFan1); +                    Aig_Obj_t * pFan11 = Aig_ObjFanin1(pFan1); +                } +            } + +            if ( RetValue2 == 0 ) +            { +                int x = Ssw_ManUniqueOne( p, pObjRepr, pObj ); +//                Ssw_SmlSavePatternAig2( p, f ); +//                Ssw_ManResimulateWord2( p, pObj, pObjRepr, f ); +                Ssw_SmlSavePatternAig( p, f ); +                Ssw_ManResimulateWord( p, pObj, pObjRepr, f ); +                if ( Aig_ObjRepr( p->pAig, pObj ) == pObjRepr ) +                    printf( "Ssw_ManSweepNode(): Refinement did not happen!!!!!!!!!!!!!!!!!!!!.\n" ); +                return 1; +            } +            return 0; + + +/* +            int RetValue; +            assert( p->iOutputLit > -1 ); +            RetValue = Ssw_ManSweepNode( p, pObj, f, 0 ); +            p->iOutputLit = -1; +            return RetValue; +*/ +        } +    } +    if ( p->pPars->nConstrs == 0 ) +        Ssw_ManResimulateWord( p, pObj, pObjRepr, f ); +    else +        Ssw_ManResimulateBit( p, pObj, pObjRepr ); +    assert( Aig_ObjRepr( p->pAig, pObj ) != pObjRepr ); +    if ( Aig_ObjRepr( p->pAig, pObj ) == pObjRepr ) +        printf( "Ssw_ManSweepNode(): Refinement did not happen.\n" ); +    return 1; +} + +/**Function************************************************************* + +  Synopsis    [Performs fraiging for the internal nodes.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ssw_ManSweepBmc( Ssw_Man_t * p ) +{ +    Bar_Progress_t * pProgress = NULL; +    Aig_Obj_t * pObj, * pObjNew, * pObjLi, * pObjLo; +    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 ) +        Ssw_ObjSetFrame( p, pObj, 0, Aig_ManConst0(p->pFrames) ); + +    // sweep internal nodes +    p->fRefined = 0; +    if ( p->pPars->fVerbose ) +        pProgress = Bar_ProgressStart( stdout, Aig_ManObjNumMax(p->pAig) * p->pPars->nFramesK ); +    Ssw_ManStartSolver( p ); +    for ( f = 0; f < p->pPars->nFramesK; f++ ) +    { +        // map constants and PIs +        Ssw_ObjSetFrame( p, Aig_ManConst1(p->pAig), f, Aig_ManConst1(p->pFrames) ); +        Saig_ManForEachPi( p->pAig, pObj, i ) +        {  +            pObjNew = Aig_ObjCreatePi(p->pFrames); +            Ssw_ObjSetFrame( p, pObj, f, pObjNew ); +            Ssw_CnfNodeAddToSolver( p, Aig_Regular(pObjNew) ); +        } +        // sweep internal nodes +        Aig_ManForEachNode( p->pAig, pObj, i ) +        { +            if ( p->pPars->fVerbose ) +                Bar_ProgressUpdate( pProgress, Aig_ManObjNumMax(p->pAig) * f + i, NULL ); +            pObjNew = Aig_And( p->pFrames, Ssw_ObjChild0Fra(p, pObj, f), Ssw_ObjChild1Fra(p, pObj, f) ); +            Ssw_ObjSetFrame( p, pObj, f, pObjNew ); +            p->fRefined |= Ssw_ManSweepNode( p, pObj, f, 1 ); +        } +        // quit if this is the last timeframe +        if ( f == p->pPars->nFramesK - 1 ) +            break; +        // transfer latch input to the latch outputs  +        // build logic cones for register outputs +        Saig_ManForEachLiLo( p->pAig, pObjLi, pObjLo, i ) +        { +            pObjNew = Ssw_ObjChild0Fra(p, pObjLi,f); +            Ssw_ObjSetFrame( p, pObjLo, f+1, pObjNew ); +            Ssw_CnfNodeAddToSolver( p, Aig_Regular(pObjNew) ); +        } +    } +    if ( p->pPars->fVerbose ) +        Bar_ProgressStop( pProgress ); + +    // cleanup +//    Ssw_ClassesCheck( p->ppClasses ); +p->timeBmc += clock() - clk; +    return p->fRefined; +} + +/**Function************************************************************* + +  Synopsis    [Performs fraiging for the internal nodes.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ssw_ManSweep( Ssw_Man_t * p ) +{ +    Bar_Progress_t * pProgress = NULL; +    Aig_Obj_t * pObj, * pObj2, * pObjNew; +    int nConstrPairs, clk, i, f; +    int v; + +    // perform speculative reduction +clk = clock(); +    // create timeframes +    p->pFrames = Ssw_FramesWithClasses( p ); +    // add constraints +    Ssw_ManStartSolver( p ); +//    nConstrPairs = Aig_ManPoNum(p->pFrames)-Aig_ManRegNum(p->pAig); +    nConstrPairs = Aig_ManPoNum(p->pFrames)-p->nFrames*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 ); +        Ssw_NodesAreConstrained( p, Aig_ObjChild0(pObj), Aig_ObjChild0(pObj2) ); +    } +/* +    // build logic cones for register inputs +    for ( i = 0; i < Aig_ManRegNum(p->pAig); i++ ) +    { +        pObj  = Aig_ManPo( p->pFrames, nConstrPairs + i ); +        Ssw_CnfNodeAddToSolver( p, Aig_ObjFanin0(pObj) ); +    } +*/ +p->timeReduce += clock() - clk; + +    // mark nodes that do not have to be refined +clk = clock(); +    if ( p->pPars->fSkipCheck ) +        Ssw_ManSweepMarkRefinement( p ); +p->timeMarkCones += clock() - clk; + +//Ssw_ManUnique( p ); + +    // map constants and PIs of the last frame +    f = p->pPars->nFramesK; +    Ssw_ObjSetFrame( p, Aig_ManConst1(p->pAig), f, Aig_ManConst1(p->pFrames) ); +    Saig_ManForEachPi( p->pAig, pObj, i ) +        Ssw_ObjSetFrame( p, pObj, f, Aig_ObjCreatePi(p->pFrames) ); +////     +    // bring up the previous frames +//    if ( p->pPars->fUniqueness ) +        for ( v = 0; v <= f; v++ ) +//            Saig_ManForEachLo( p->pAig, pObj, i ) +            Aig_ManForEachPi( p->pAig, pObj, i ) +        { +/* +            if ( i == 53 && v == 1 ) +            { +                int x = 0; +            } +*/ +                Ssw_CnfNodeAddToSolver( p, Aig_Regular(Ssw_ObjFrame(p, pObj, v)) ); +        } +//// +    sat_solver_simplify( p->pSat ); +    // make sure LOs are assigned +    Saig_ManForEachLo( p->pAig, pObj, i ) +        assert( Ssw_ObjFrame( p, pObj, f ) != NULL ); +    // sweep internal nodes +    p->fRefined = 0; +    p->nSatFailsReal = 0; +    p->nRefUse = p->nRefSkip = 0; +    p->nUniques = 0; +    Ssw_ClassesClearRefined( p->ppClasses ); +    if ( p->pPars->fVerbose ) +        pProgress = Bar_ProgressStart( stdout, Aig_ManObjNumMax(p->pAig) ); +    Aig_ManForEachObj( p->pAig, pObj, i ) +    { +        if ( p->pPars->fVerbose ) +            Bar_ProgressUpdate( pProgress, i, NULL ); +        if ( Saig_ObjIsLo(p->pAig, pObj) ) +            p->fRefined |= Ssw_ManSweepNode( p, pObj, f, 0 ); +        else if ( Aig_ObjIsNode(pObj) ) +        {  +            pObj->fMarkA = Aig_ObjFanin0(pObj)->fMarkA | Aig_ObjFanin1(pObj)->fMarkA; +            pObjNew = Aig_And( p->pFrames, Ssw_ObjChild0Fra(p, pObj, f), Ssw_ObjChild1Fra(p, pObj, f) ); +            Ssw_ObjSetFrame( p, pObj, f, pObjNew ); +            p->fRefined |= Ssw_ManSweepNode( p, pObj, f, 0 ); +        } +    } +    p->nSatFailsTotal += p->nSatFailsReal; +    if ( p->pPars->fVerbose ) +        Bar_ProgressStop( pProgress ); + +    // cleanup +//    Ssw_ClassesCheck( p->ppClasses ); +    return p->fRefined; +} + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/ssw_old/sswUnique.c b/src/aig/ssw_old/sswUnique.c new file mode 100644 index 00000000..2beeed09 --- /dev/null +++ b/src/aig/ssw_old/sswUnique.c @@ -0,0 +1,290 @@ +/**CFile**************************************************************** + +  FileName    [sswSat.c] + +  SystemName  [ABC: Logic synthesis and verification system.] + +  PackageName [Inductive prover with constraints.] + +  Synopsis    [On-demand uniqueness constraints.] + +  Author      [Alan Mishchenko] +   +  Affiliation [UC Berkeley] + +  Date        [Ver. 1.0. Started - September 1, 2008.] + +  Revision    [$Id: sswSat.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "sswInt.h" + +//////////////////////////////////////////////////////////////////////// +///                        DECLARATIONS                              /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +///                     FUNCTION DEFINITIONS                         /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + +  Synopsis    [Returns the result of merging the two vectors.] + +  Description [Assumes that the vectors are sorted in the increasing order.] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Vec_PtrTwoMerge( Vec_Ptr_t * vArr1, Vec_Ptr_t * vArr2, Vec_Ptr_t * vArr ) +{ +    Aig_Obj_t ** pBeg  = (Aig_Obj_t **)vArr->pArray; +    Aig_Obj_t ** pBeg1 = (Aig_Obj_t **)vArr1->pArray; +    Aig_Obj_t ** pBeg2 = (Aig_Obj_t **)vArr2->pArray; +    Aig_Obj_t ** pEnd1 = (Aig_Obj_t **)vArr1->pArray + vArr1->nSize; +    Aig_Obj_t ** pEnd2 = (Aig_Obj_t **)vArr2->pArray + vArr2->nSize; +    Vec_PtrGrow( vArr, Vec_PtrSize(vArr1) + Vec_PtrSize(vArr2) ); +    pBeg  = (Aig_Obj_t **)vArr->pArray; +    while ( pBeg1 < pEnd1 && pBeg2 < pEnd2 ) +    { +        if ( (*pBeg1)->Id == (*pBeg2)->Id ) +            *pBeg++ = *pBeg1++, pBeg2++; +        else if ( (*pBeg1)->Id < (*pBeg2)->Id ) +            *pBeg++ = *pBeg1++; +        else  +            *pBeg++ = *pBeg2++; +    } +    while ( pBeg1 < pEnd1 ) +        *pBeg++ = *pBeg1++; +    while ( pBeg2 < pEnd2 ) +        *pBeg++ = *pBeg2++; +    vArr->nSize = pBeg - (Aig_Obj_t **)vArr->pArray; +    assert( vArr->nSize <= vArr->nCap ); +    assert( vArr->nSize >= vArr1->nSize ); +    assert( vArr->nSize >= vArr2->nSize ); +} + +/**Function************************************************************* + +  Synopsis    [Returns the result of merging the two vectors.] + +  Description [Assumes that the vectors are sorted in the increasing order.] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Vec_PtrTwoCommon( Vec_Ptr_t * vArr1, Vec_Ptr_t * vArr2, Vec_Ptr_t * vArr ) +{ +    Aig_Obj_t ** pBeg  = (Aig_Obj_t **)vArr->pArray; +    Aig_Obj_t ** pBeg1 = (Aig_Obj_t **)vArr1->pArray; +    Aig_Obj_t ** pBeg2 = (Aig_Obj_t **)vArr2->pArray; +    Aig_Obj_t ** pEnd1 = (Aig_Obj_t **)vArr1->pArray + vArr1->nSize; +    Aig_Obj_t ** pEnd2 = (Aig_Obj_t **)vArr2->pArray + vArr2->nSize; +    Vec_PtrGrow( vArr, AIG_MIN( Vec_PtrSize(vArr1), Vec_PtrSize(vArr2) ) ); +    pBeg  = (Aig_Obj_t **)vArr->pArray; +    while ( pBeg1 < pEnd1 && pBeg2 < pEnd2 ) +    { +        if ( (*pBeg1)->Id == (*pBeg2)->Id ) +            *pBeg++ = *pBeg1++, pBeg2++; +        else if ( (*pBeg1)->Id < (*pBeg2)->Id ) +//            *pBeg++ = *pBeg1++; +            pBeg1++; +        else  +//            *pBeg++ = *pBeg2++; +            pBeg2++; +    } +//    while ( pBeg1 < pEnd1 ) +//        *pBeg++ = *pBeg1++; +//    while ( pBeg2 < pEnd2 ) +//        *pBeg++ = *pBeg2++; +    vArr->nSize = pBeg - (Aig_Obj_t **)vArr->pArray; +    assert( vArr->nSize <= vArr->nCap ); +    assert( vArr->nSize <= vArr1->nSize ); +    assert( vArr->nSize <= vArr2->nSize ); +} + +/**Function************************************************************* + +  Synopsis    [Returns 1 if uniqueness constraints can be added.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ssw_ManUniqueOne( Ssw_Man_t * p, Aig_Obj_t * pRepr, Aig_Obj_t * pObj ) +{ +    int fVerbose = 1; +    Aig_Obj_t * ppObjs[2], * pTemp; +    Vec_Ptr_t * vSupp, * vSupp2; +    int i, k, Value0, Value1, RetValue; +    assert( p->pPars->nFramesK > 1 ); + +    vSupp  = Vec_PtrAlloc( 100 ); +    vSupp2 = Vec_PtrAlloc( 100 ); +    Vec_PtrClear( p->vCommon ); + +    // compute the first support in terms of LOs +    ppObjs[0] = pRepr;  +    ppObjs[1] = pObj; +    Aig_SupportNodes( p->pAig, ppObjs, 2, vSupp ); +    // modify support to be in terms of LIs +    k = 0; +    Vec_PtrForEachEntry( vSupp, pTemp, i ) +        if ( Saig_ObjIsLo(p->pAig, pTemp) ) +            Vec_PtrWriteEntry( vSupp, k++, Saig_ObjLoToLi(p->pAig, pTemp) ); +    Vec_PtrShrink( vSupp, k ); +    // compute the support of support +    Aig_SupportNodes( p->pAig, (Aig_Obj_t **)Vec_PtrArray(vSupp), Vec_PtrSize(vSupp), vSupp2 ); +    // return support to LO +    Vec_PtrForEachEntry( vSupp, pTemp, i ) +        Vec_PtrWriteEntry( vSupp, i, Saig_ObjLiToLo(p->pAig, pTemp) ); +    // find the number of common vars +    Vec_PtrSort( vSupp, Aig_ObjCompareIdIncrease ); +    Vec_PtrSort( vSupp2, Aig_ObjCompareIdIncrease ); +    Vec_PtrTwoCommon( vSupp, vSupp2, p->vCommon ); +//    Vec_PtrTwoMerge( vSupp, vSupp2, p->vCommon ); + +/* +    { +        Vec_Ptr_t * vNew = Vec_PtrDup(vSupp); +        Vec_PtrUniqify( vNew, Aig_ObjCompareIdIncrease ); +        if ( Vec_PtrSize(vNew) != Vec_PtrSize(vSupp) ) +            printf( "Not unique!\n" ); +        Vec_PtrFree( vNew ); +        Vec_PtrForEachEntry( vSupp, pTemp, i ) +            printf( "%d ", pTemp->Id ); +        printf( "\n" ); +    } +    { +        Vec_Ptr_t * vNew = Vec_PtrDup(vSupp2); +        Vec_PtrUniqify( vNew, Aig_ObjCompareIdIncrease ); +        if ( Vec_PtrSize(vNew) != Vec_PtrSize(vSupp2) ) +            printf( "Not unique!\n" ); +        Vec_PtrFree( vNew ); +        Vec_PtrForEachEntry( vSupp2, pTemp, i ) +            printf( "%d ", pTemp->Id ); +        printf( "\n" ); +    } +    { +        Vec_Ptr_t * vNew = Vec_PtrDup(p->vCommon); +        Vec_PtrUniqify( vNew, Aig_ObjCompareIdIncrease ); +        if ( Vec_PtrSize(vNew) != Vec_PtrSize(p->vCommon) ) +            printf( "Not unique!\n" ); +        Vec_PtrFree( vNew ); +        Vec_PtrForEachEntry( p->vCommon, pTemp, i ) +            printf( "%d ", pTemp->Id ); +        printf( "\n" ); +    } +*/ + +    if ( fVerbose ) +        printf( "Node = %5d : One = %3d. Two = %3d. Common = %3d.  ", +            Aig_ObjId(pObj), Vec_PtrSize(vSupp), Vec_PtrSize(vSupp2), Vec_PtrSize(p->vCommon) ); + +//    Vec_PtrClear( vSupp ); +//    Vec_PtrForEachEntry( vSupp2, pTemp, i ) +//        Vec_PtrPush( vSupp, pTemp ); + +    // check the current values +    RetValue = 1; +//    Vec_PtrForEachEntry( p->vCommon, pTemp, i ) +    Vec_PtrForEachEntry( vSupp, pTemp, i ) +    { +        Value0 = Ssw_ManGetSatVarValue( p, pTemp, 0 ); +        Value1 = Ssw_ManGetSatVarValue( p, pTemp, 1 ); +        if ( Value0 != Value1 ) +            RetValue = 0; +        if ( fVerbose ) +            printf( "%d", Value0 ^ Value1 ); +    } +    if ( Vec_PtrSize(p->vCommon) == 0 ) +        RetValue = 0; + +    Vec_PtrForEachEntry( vSupp, pTemp, i ) +        printf( " %d", pTemp->Id ); + +    if ( fVerbose ) +        printf( "\n" ); + + +    Vec_PtrClear( p->vCommon ); +    Vec_PtrForEachEntry( vSupp, pTemp, i ) +        Vec_PtrPush( p->vCommon, pTemp ); + +    Vec_PtrFree( vSupp ); +    Vec_PtrFree( vSupp2 ); +    return RetValue; +} + +/**Function************************************************************* + +  Synopsis    [Returns the output of the uniqueness constraint.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ssw_ManUniqueAddConstraint( Ssw_Man_t * p, Vec_Ptr_t * vCommon, int f1, int f2 ) +{ +    Aig_Obj_t * pObj, * pObj1New, * pObj2New, * pMiter, * pTotal; +    int i, pLits[2]; +//    int RetValue; +    assert( Vec_PtrSize(vCommon) > 0 ); +    // generate the constraint +    pTotal = Aig_ManConst0(p->pFrames); +    Vec_PtrForEachEntry( vCommon, pObj, i ) +    { +        assert( Saig_ObjIsLo(p->pAig, pObj) ); +        pObj1New = Ssw_ObjFrame( p, pObj, f1 ); +        pObj2New = Ssw_ObjFrame( p, pObj, f2 ); +        pMiter = Aig_Exor( p->pFrames, pObj1New, pObj2New ); +        pTotal = Aig_Or( p->pFrames, pTotal, pMiter ); +    } +/* +    if ( Aig_ObjIsConst1(Aig_Regular(pTotal)) ) +    { +//        printf( "Skipped\n" ); +        return 0; +    } +*/ +    p->nUniques++; +    // create CNF +//    { +//        int Num1 = p->nSatVars; +    Ssw_CnfNodeAddToSolver( p, Aig_Regular(pTotal) ); +//    printf( "Created variable %d while vars are %d. (diff = %d)\n",  +//        Ssw_ObjSatNum( p, Aig_Regular(pTotal) ), p->nSatVars, p->nSatVars - Num1 ); +//    } +    // add output constraint +    pLits[0] = toLitCond( Ssw_ObjSatNum(p,Aig_Regular(pTotal)), Aig_IsComplement(pTotal) ); +/* +    RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 1 ); +    assert( RetValue ); +    // simplify the solver +    if ( p->pSat->qtail != p->pSat->qhead ) +    { +        RetValue = sat_solver_simplify(p->pSat); +        assert( RetValue != 0 ); +    } +*/ +    assert( p->iOutputLit == -1 ); +    p->iOutputLit = pLits[0]; +    return 1; +} + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 4f46f3a2..50fb11ac 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -254,6 +254,7 @@ static int Abc_CommandAbc8Zero       ( Abc_Frame_t * pAbc, int argc, char ** arg  static int Abc_CommandAbc8Cec        ( Abc_Frame_t * pAbc, int argc, char ** argv );  static int Abc_CommandAbc8DSec       ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbcTestNew     ( Abc_Frame_t * pAbc, int argc, char ** argv );  ////////////////////////////////////////////////////////////////////////  ///                     FUNCTION DEFINITIONS                         /// @@ -518,6 +519,7 @@ void Abc_Init( Abc_Frame_t * pAbc )      Cmd_CommandAdd( pAbc, "ABC8",         "*cec",          Abc_CommandAbc8Cec,          0 );      Cmd_CommandAdd( pAbc, "ABC8",         "*dsec",         Abc_CommandAbc8DSec,         0 ); +    Cmd_CommandAdd( pAbc, "Various",      "testnew",         Abc_CommandAbcTestNew,     0 );  //    Cmd_CommandAdd( pAbc, "Verification", "trace_start",   Abc_CommandTraceStart,       0 );  //    Cmd_CommandAdd( pAbc, "Verification", "trace_check",   Abc_CommandTraceCheck,       0 ); @@ -4919,22 +4921,24 @@ int Abc_CommandDemiter( Abc_Frame_t * pAbc, int argc, char ** argv )  {      FILE * pOut, * pErr;      Abc_Ntk_t * pNtk;//, * pNtkRes; -    int fComb; +    int fSeq;      int c;      extern int Abc_NtkDemiter( Abc_Ntk_t * pNtk ); +    extern int Abc_NtkDarDemiter( Abc_Ntk_t * pNtk );      pNtk = Abc_FrameReadNtk(pAbc);      pOut = Abc_FrameReadOut(pAbc);      pErr = Abc_FrameReadErr(pAbc);      // set defaults +    fSeq = 1;      Extra_UtilGetoptReset(); -    while ( ( c = Extra_UtilGetopt( argc, argv, "ch" ) ) != EOF ) +    while ( ( c = Extra_UtilGetopt( argc, argv, "sh" ) ) != EOF )      {          switch ( c )          { -        case 'c': -            fComb ^= 1; +        case 's': +            fSeq ^= 1;              break;          default:              goto usage; @@ -4947,12 +4951,6 @@ int Abc_CommandDemiter( Abc_Frame_t * pAbc, int argc, char ** argv )          return 1;      } -    if ( Abc_NtkPoNum(pNtk) != 1 ) -    { -        fprintf( pErr, "The network is not a miter.\n" ); -        return 1; -    } -      if ( !Abc_NodeIsExorType(Abc_ObjFanin0(Abc_NtkPo(pNtk,0))) )      {          fprintf( pErr, "The miter's PO is not an EXOR.\n" ); @@ -4960,19 +4958,35 @@ int Abc_CommandDemiter( Abc_Frame_t * pAbc, int argc, char ** argv )      }      // get the new network -    if ( !Abc_NtkDemiter( pNtk ) ) +    if ( fSeq )      { -        fprintf( pErr, "Demitering has failed.\n" ); -        return 1; +        if ( !Abc_NtkDarDemiter( pNtk ) ) +        { +            fprintf( pErr, "Demitering has failed.\n" ); +            return 1; +        } +    } +    else +    { +        if ( Abc_NtkPoNum(pNtk) != 1 ) +        { +            fprintf( pErr, "The network is not a single-output miter.\n" ); +            return 1; +        } +        if ( !Abc_NtkDemiter( pNtk ) ) +        { +            fprintf( pErr, "Demitering has failed.\n" ); +            return 1; +        }      }      // replace the current network  //    Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );      return 0;  usage: -    fprintf( pErr, "usage: demiter [-h]\n" ); +    fprintf( pErr, "usage: demiter [-sh]\n" );      fprintf( pErr, "\t        removes topmost EXOR from the miter to create two POs\n" ); -//    fprintf( pErr, "\t-c    : computes combinational miter (latches as POs) [default = %s]\n", fComb? "yes": "no" ); +    fprintf( pErr, "\t-s    : applied multi-output algorithm [default = %s]\n", fSeq? "yes": "no" );      fprintf( pErr, "\t-h    : print the command usage\n");      return 1;  } @@ -7720,7 +7734,7 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )  //    extern void Aig_ProcedureTest();      extern void Abc_NtkDarTest( Abc_Ntk_t * pNtk );      extern Abc_Ntk_t * Abc_NtkDarTestNtk( Abc_Ntk_t * pNtk ); - +    extern int Ssw_SecSpecialMiter( Aig_Man_t * pMiter, int fVerbose );      pNtk = Abc_FrameReadNtk(pAbc);      pOut = Abc_FrameReadOut(pAbc); @@ -7922,6 +7936,7 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )      Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );  */ +/*      pNtkRes = Abc_NtkDarTestNtk( pNtk );      if ( pNtkRes == NULL )      { @@ -7930,6 +7945,9 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )      }      // replace the current network      Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); +*/ + +    Abc_NtkDarTest( pNtk );      return 0;  usage: @@ -13541,7 +13559,7 @@ int Abc_CommandSeqSweep2( Abc_Frame_t * pAbc, int argc, char ** argv )      // set defaults      Ssw_ManSetDefaultParams( pPars );      Extra_UtilGetoptReset(); -    while ( ( c = Extra_UtilGetopt( argc, argv, "PQFCLNSplsfuvh" ) ) != EOF ) +    while ( ( c = Extra_UtilGetopt( argc, argv, "PQFCLNSplsfuvwh" ) ) != EOF )      {          switch ( c )          { @@ -13640,6 +13658,9 @@ int Abc_CommandSeqSweep2( Abc_Frame_t * pAbc, int argc, char ** argv )          case 'v':              pPars->fVerbose ^= 1;              break; +        case 'w': +            pPars->fFlopVerbose ^= 1; +            break;          case 'h':              goto usage;          default: @@ -13689,7 +13710,7 @@ int Abc_CommandSeqSweep2( Abc_Frame_t * pAbc, int argc, char ** argv )      return 0;  usage: -    fprintf( pErr, "usage: scorr [-PQFCLNS <num>] [-plsfuvh]\n" ); +    fprintf( pErr, "usage: scorr [-PQFCLNS <num>] [-plsfuvwh]\n" );      fprintf( pErr, "\t         performs sequential sweep using K-step induction\n" );      fprintf( pErr, "\t-P num : max partition size (0 = no partitioning) [default = %d]\n", pPars->nPartSize );      fprintf( pErr, "\t-Q num : partition overlap (0 = no overlap) [default = %d]\n", pPars->nOverSize ); @@ -13704,6 +13725,7 @@ usage:      fprintf( pErr, "\t-f     : toggle filtering using interative BMC [default = %s]\n", pPars->fSemiFormal? "yes": "no" );      fprintf( pErr, "\t-u     : toggle using uniqueness constraints [default = %s]\n", pPars->fUniqueness? "yes": "no" );      fprintf( pErr, "\t-v     : toggle verbose output [default = %s]\n", pPars->fVerbose? "yes": "no" ); +    fprintf( pErr, "\t-w     : toggle printout of flop equivalences [default = %s]\n", pPars->fFlopVerbose? "yes": "no" );      fprintf( pErr, "\t-h     : print the command usage\n");      return 1;  } @@ -19634,6 +19656,64 @@ usage:  } + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Abc_CommandAbcTestNew( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ +    extern int Abc_NtkTestProcedure( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2 ); + +    Abc_Ntk_t * pNtk; +    int c; + +    pNtk = Abc_FrameReadNtk(pAbc); + +    // set defaults +    Extra_UtilGetoptReset(); +    while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF ) +    { +        switch ( c ) +        { +        case 'h': +            goto usage; +        default: +            goto usage; +        } +    } + +    if ( pNtk == NULL ) +    { +        fprintf( stdout, "Empty network.\n" ); +        return 1; +    } + +    if ( !Abc_NtkIsStrash( pNtk) ) +    { +        fprintf( stdout, "The current network is not an AIG. Cannot continue.\n" ); +        return 1; +    } + +//    Abc_NtkTestProcedure( pNtk, NULL ); + +    return 0; + +usage: +    fprintf( stdout, "usage: testnew [-h]\n" ); +    fprintf( stdout, "\t        new testing procedure\n" ); +    fprintf( stdout, "\t-h    : print the command usage\n"); +    return 1; +} + +  ////////////////////////////////////////////////////////////////////////  ///                       END OF FILE                                ///  //////////////////////////////////////////////////////////////////////// diff --git a/src/base/abci/abc.zip b/src/base/abci/abc.zip Binary files differnew file mode 100644 index 00000000..34df9a63 --- /dev/null +++ b/src/base/abci/abc.zip diff --git a/src/base/abci/abcDar.c b/src/base/abci/abcDar.c index 98228c56..c64fb0f5 100644 --- a/src/base/abci/abcDar.c +++ b/src/base/abci/abcDar.c @@ -1240,6 +1240,96 @@ PRT( "Initial fraiging time", clock() - clk );  /**Function************************************************************* +  Synopsis    [Print Latch Equivalence Classes.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Abc_NtkPrintLatchEquivClasses( Abc_Ntk_t * pNtk, Aig_Man_t * pAig ) +{ +    bool header_dumped = false; +    int num_orig_latches = Abc_NtkLatchNum(pNtk); +    char **pNames = ALLOC( char *, num_orig_latches ); +    bool *p_irrelevant = ALLOC( bool, num_orig_latches ); +    char * pFlopName, * pReprName; +    Aig_Obj_t * pFlop, * pRepr; +    Abc_Obj_t * pNtkFlop;  +    int repr_idx; +    int i; + +    Abc_NtkForEachLatch( pNtk, pNtkFlop, i ) +    { +        char *temp_name = Abc_ObjName( Abc_ObjFanout0(pNtkFlop) ); +        pNames[i] = ALLOC( char , strlen(temp_name)+1); +        strcpy(pNames[i], temp_name); +    } +    i = 0; +     +    Aig_ManSetPioNumbers( pAig ); +    Saig_ManForEachLo( pAig, pFlop, i ) +    { +        p_irrelevant[i] = false; +         +        pFlopName = pNames[i]; + +        pRepr = Aig_ObjRepr(pAig, pFlop); + +        if ( pRepr == NULL ) +        { +            // printf("Nothing equivalent to flop %s\n", pFlopName); +            p_irrelevant[i] = true; +            continue; +        } + +        if (!header_dumped) +        { +            printf("Here are the flop equivalences:\n"); +            header_dumped = true; +        } + +        // pRepr is representative of the equivalence class, to which pFlop belongs +        if ( Aig_ObjIsConst1(pRepr) ) +        { +            printf( "Original flop %s is proved equivalent to constant.\n", pFlopName ); +            // printf( "Original flop # %d is proved equivalent to constant.\n", i ); +            continue; +        } + +        assert( Saig_ObjIsLo( pAig, pRepr ) ); +        repr_idx = Aig_ObjPioNum(pRepr) - Saig_ManPiNum(pAig); +        pReprName = pNames[repr_idx]; +        printf( "Original flop %s is proved equivalent to flop %s.\n",  pFlopName, pReprName ); +        // printf( "Original flop # %d is proved equivalent to flop # %d.\n",  i, repr_idx ); +    } + +    header_dumped = false; +    for (i=0; i<num_orig_latches; ++i) +    { +        if (p_irrelevant[i]) +        { +            if (!header_dumped) +            { +                printf("The following flops have been deemed irrelevant:\n"); +                header_dumped = true; +            } +            printf("%s ", pNames[i]); +        } +         +        FREE(pNames[i]); +    } +    if (header_dumped) +        printf("\n"); +     +    FREE(pNames); +    FREE(p_irrelevant); +} + +/**Function************************************************************* +    Synopsis    [Gives the current ABC network to AIG manager for processing.]    Description [] @@ -1259,7 +1349,11 @@ Abc_Ntk_t * Abc_NtkDarSeqSweep2( Abc_Ntk_t * pNtk, Ssw_Pars_t * pPars )          return NULL;      pMan = Ssw_SignalCorrespondence( pTemp = pMan, pPars ); -    Aig_ManStop( pTemp ); + +    if ( pPars->fFlopVerbose ) +        Abc_NtkPrintLatchEquivClasses(pNtk, pTemp); + +        Aig_ManStop( pTemp );      if ( pMan == NULL )          return NULL; @@ -1474,6 +1568,47 @@ PRT( "Time", clock() - clk );    SeeAlso     []  ***********************************************************************/ +int Abc_NtkDarDemiter( Abc_Ntk_t * pNtk ) +{  +    Aig_Man_t * pMan, * pPart0, * pPart1, * pMiter; +    // derive the AIG manager +    pMan = Abc_NtkToDar( pNtk, 0, 1 ); +    if ( pMan == NULL ) +    { +        printf( "Converting network into AIG has failed.\n" ); +        return 0; +    } +    if ( !Saig_ManDemiterSimple( pMan, &pPart0, &pPart1 ) ) +    { +        printf( "Demitering has failed.\n" ); +        return 0; +    } +    Aig_ManDumpBlif( pPart0, "part0.blif", NULL, NULL ); +    Aig_ManDumpBlif( pPart1, "part1.blif", NULL, NULL ); +    printf( "The result of demitering is written into files \"%s\" and \"%s\".\n", "part0.blif", "part1.blif" ); +    // create two-level miter +    pMiter = Saig_ManCreateMiterTwo( pPart0, pPart1, 2 ); +    Aig_ManDumpBlif( pMiter, "miter01.blif", NULL, NULL ); +    Aig_ManStop( pMiter ); +    printf( "The new miter is written into file \"%s\".\n", "miter01.blif" ); + +    Aig_ManStop( pPart0 ); +    Aig_ManStop( pPart1 ); +    Aig_ManStop( pMan ); +    return 1; +} + +/**Function************************************************************* + +  Synopsis    [Gives the current ABC network to AIG manager for processing.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/  int Abc_NtkDarProve( Abc_Ntk_t * pNtk, Fra_Sec_t * pSecPar )  {      Aig_Man_t * pMan; @@ -2457,9 +2592,9 @@ void Abc_NtkDarReach( Abc_Ntk_t * pNtk, int nBddMax, int nIterMax, int fPartitio  ***********************************************************************/  void Abc_NtkDarTest( Abc_Ntk_t * pNtk )  { -    extern Aig_Man_t * Ssw_SignalCorrespondeceTestPairs( Aig_Man_t * pAig ); +//    extern Aig_Man_t * Ssw_SignalCorrespondeceTestPairs( Aig_Man_t * pAig ); -    Aig_Man_t * pMan, * pTemp; +    Aig_Man_t * pMan;//, * pTemp;      assert( Abc_NtkIsStrash(pNtk) );      pMan = Abc_NtkToDar( pNtk, 0, 1 );      if ( pMan == NULL ) @@ -2472,9 +2607,13 @@ Aig_ManStop( pMan );  pMan = Saig_ManReadBlif( "_temp_.blif" );  Aig_ManPrintStats( pMan );  */ +/*      Aig_ManSetRegNum( pMan, pMan->nRegs );      pTemp = Ssw_SignalCorrespondeceTestPairs( pMan );      Aig_ManStop( pTemp ); +*/ +    Ssw_SecSpecialMiter( pMan, 0 ); +      Aig_ManStop( pMan );  } diff --git a/src/base/cmd/cmd.c b/src/base/cmd/cmd.c index 75aa0064..4e0a4c95 100644 --- a/src/base/cmd/cmd.c +++ b/src/base/cmd/cmd.c @@ -50,6 +50,7 @@ static int CmdCommandEmpty         ( Abc_Frame_t * pAbc, int argc, char ** argv  static int CmdCommandLs            ( Abc_Frame_t * pAbc, int argc, char ** argv );  static int CmdCommandScrGen        ( Abc_Frame_t * pAbc, int argc, char ** argv );  #endif +static int CmdCommandVersion       ( Abc_Frame_t * pAbc, int argc, char ** argv );  static int CmdCommandSis           ( Abc_Frame_t * pAbc, int argc, char ** argv );  static int CmdCommandMvsis         ( Abc_Frame_t * pAbc, int argc, char ** argv );  static int CmdCommandCapo          ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -68,7 +69,7 @@ static int CmdCommandCapo          ( Abc_Frame_t * pAbc, int argc, char ** argv  ******************************************************************************/  void Cmd_Init( Abc_Frame_t * pAbc ) -{ +{       pAbc->tCommands = st_init_table(strcmp, st_strhash);      pAbc->tAliases  = st_init_table(strcmp, st_strhash);      pAbc->tFlags    = st_init_table(strcmp, st_strhash); @@ -91,6 +92,7 @@ void Cmd_Init( Abc_Frame_t * pAbc )      Cmd_CommandAdd( pAbc, "Basic", "ls",        CmdCommandLs,             0 );      Cmd_CommandAdd( pAbc, "Basic", "scrgen",    CmdCommandScrGen,         0 );  #endif +    Cmd_CommandAdd( pAbc, "Basic", "version",   CmdCommandVersion,        0);       Cmd_CommandAdd( pAbc, "Various", "sis",     CmdCommandSis,            1);       Cmd_CommandAdd( pAbc, "Various", "mvsis",   CmdCommandMvsis,          1);  @@ -1910,6 +1912,22 @@ usage:      return 1;                    // error exit   } +/**Function******************************************************************** + +  Synopsis    [Print the version string.] + +  Description [] + +  SideEffects [] + +  SeeAlso     [] + +******************************************************************************/ +int CmdCommandVersion( Abc_Frame_t * pAbc, int argc, char **argv ) +{ +    printf("%s\n", Abc_UtilsGetVersion(pAbc)); +    return 0; +}  //////////////////////////////////////////////////////////////////////// diff --git a/src/base/cmd/cmd.h b/src/base/cmd/cmd.h index 030b77e8..9d0b8703 100644 --- a/src/base/cmd/cmd.h +++ b/src/base/cmd/cmd.h @@ -40,6 +40,17 @@ extern "C" {  typedef struct MvCommand    Abc_Command;  // one command  typedef struct MvAlias      Abc_Alias;    // one alias +#ifdef WIN32 +#define DLLEXPORT __declspec(dllexport) +#define DLLIMPORT __declspec(dllimport) +#else  /* defined(WIN32) */ +#define DLLIMPORT +#endif /* defined(WIN32) */ + +#ifndef ABC_DLL +#define ABC_DLL DLLIMPORT +#endif +  ////////////////////////////////////////////////////////////////////////  ///                       MACRO DEFINITIONS                          ///  //////////////////////////////////////////////////////////////////////// @@ -53,7 +64,7 @@ extern void        Cmd_Init();  extern void        Cmd_End();  /*=== cmdApi.c ========================================================*/  extern void        Cmd_CommandAdd( Abc_Frame_t * pAbc, char * sGroup, char * sName, void * pFunc, int fChanges ); -extern int         Cmd_CommandExecute( Abc_Frame_t * pAbc, char * sCommand ); +extern ABC_DLL int Cmd_CommandExecute( Abc_Frame_t * pAbc, char * sCommand );  /*=== cmdFlag.c ========================================================*/  extern char *      Cmd_FlagReadByName( Abc_Frame_t * pAbc, char * flag );  extern void        Cmd_FlagDeleteByName( Abc_Frame_t * pAbc, char * key ); diff --git a/src/base/io/io.c b/src/base/io/io.c index 6d7948ab..6f326a27 100644 --- a/src/base/io/io.c +++ b/src/base/io/io.c @@ -1710,30 +1710,7 @@ int IoCommandWriteCounter( Abc_Frame_t * pAbc, int argc, char **argv )      }      // write the counter-example into the file -    if ( pNtk->pModel ) -    { -        Abc_Obj_t * pObj; -        FILE * pFile = fopen( pFileName, "w" ); -        int i; -        if ( pFile == NULL ) -        { -            fprintf( stdout, "IoCommandWriteCounter(): Cannot open the output file \"%s\".\n", pFileName ); -            return 1; -        } -        if ( fNames ) -        { -            Abc_NtkForEachPi( pNtk, pObj, i ) -                fprintf( pFile, "%s=%c ", Abc_ObjName(pObj), '0'+(pNtk->pModel[i]==1) ); -        } -        else -        { -            Abc_NtkForEachPi( pNtk, pObj, i ) -                fprintf( pFile, "%c", '0'+(pNtk->pModel[i]==1) ); -        } -        fprintf( pFile, "\n" ); -        fclose( pFile ); -    } -    else +    if ( pNtk->pSeqModel )      {           Fra_Cex_t * pCex = pNtk->pSeqModel;          Abc_Obj_t * pObj; @@ -1771,6 +1748,29 @@ int IoCommandWriteCounter( Abc_Frame_t * pAbc, int argc, char **argv )          fprintf( pFile, "\n" );          fclose( pFile );      } +    else +    { +        Abc_Obj_t * pObj; +        FILE * pFile = fopen( pFileName, "w" ); +        int i; +        if ( pFile == NULL ) +        { +            fprintf( stdout, "IoCommandWriteCounter(): Cannot open the output file \"%s\".\n", pFileName ); +            return 1; +        } +        if ( fNames ) +        { +            Abc_NtkForEachPi( pNtk, pObj, i ) +                fprintf( pFile, "%s=%c ", Abc_ObjName(pObj), '0'+(pNtk->pModel[i]==1) ); +        } +        else +        { +            Abc_NtkForEachPi( pNtk, pObj, i ) +                fprintf( pFile, "%c", '0'+(pNtk->pModel[i]==1) ); +        } +        fprintf( pFile, "\n" ); +        fclose( pFile ); +    }      return 0; diff --git a/src/base/main/mainUtils.c b/src/base/main/mainUtils.c index d69055a4..46469490 100644 --- a/src/base/main/mainUtils.c +++ b/src/base/main/mainUtils.c @@ -200,14 +200,26 @@ void Abc_UtilsSource( Abc_Frame_t * pAbc )          if ( sPath1 && sPath2 ) {              /* ~/.rc == .rc : Source the file only once */ -            (void) Cmd_CommandExecute(pAbc, "source -s ~/.abc.rc"); +            char *tmp_cmd = ALLOC(char, strlen(sPath1)+12); +            (void) sprintf(tmp_cmd, "source -s %s", sPath1); +            // (void) Cmd_CommandExecute(pAbc, "source -s ~/.abc.rc"); +            (void) Cmd_CommandExecute(pAbc, tmp_cmd); +            FREE(tmp_cmd);          }          else {              if (sPath1) { -                (void) Cmd_CommandExecute(pAbc, "source -s ~/.abc.rc"); +                char *tmp_cmd = ALLOC(char, strlen(sPath1)+12); +                (void) sprintf(tmp_cmd, "source -s %s", sPath1); +                // (void) Cmd_CommandExecute(pAbc, "source -s ~/.abc.rc"); +                (void) Cmd_CommandExecute(pAbc, tmp_cmd); +                FREE(tmp_cmd);              }              if (sPath2) { -                (void) Cmd_CommandExecute(pAbc, "source -s .abc.rc"); +                char *tmp_cmd = ALLOC(char, strlen(sPath2)+12); +                (void) sprintf(tmp_cmd, "source -s %s", sPath2); +                // (void) Cmd_CommandExecute(pAbc, "source -s .abc.rc"); +                (void) Cmd_CommandExecute(pAbc, tmp_cmd); +                FREE(tmp_cmd);              }          }          if ( sPath1 ) FREE(sPath1); diff --git a/src/misc/extra/extra.h b/src/misc/extra/extra.h index d63ed5d3..beb5a4d0 100644 --- a/src/misc/extra/extra.h +++ b/src/misc/extra/extra.h @@ -76,6 +76,18 @@ extern "C" {  /* Macro declarations                                                        */  /*---------------------------------------------------------------------------*/ +#ifdef WIN32 +#define DLLEXPORT __declspec(dllexport) +#define DLLIMPORT __declspec(dllimport) +#else  /* defined(WIN32) */ +#define DLLIMPORT +#endif /* defined(WIN32) */ + +#ifndef ABC_DLL +#define ABC_DLL DLLIMPORT +#endif + +  typedef unsigned char      uint8;  typedef unsigned short     uint16;  typedef unsigned int       uint32; @@ -633,19 +645,19 @@ extern unsigned    Extra_TruthSemiCanonicize( unsigned * pInOut, unsigned * pAux  #endif -extern long        Extra_CpuTime(); -extern double      Extra_CpuTimeDouble(); -extern int         Extra_GetSoftDataLimit(); -extern void        Extra_UtilGetoptReset(); -extern int         Extra_UtilGetopt( int argc, char *argv[], char *optstring ); -extern char *      Extra_UtilPrintTime( long t ); -extern char *      Extra_UtilStrsav( char *s ); -extern char *      Extra_UtilTildeExpand( char *fname ); -extern char *      Extra_UtilFileSearch( char *file, char *path, char *mode ); -extern void        (*Extra_UtilMMoutOfMemory)(); +extern long          Extra_CpuTime(); +extern double        Extra_CpuTimeDouble(); +extern int           Extra_GetSoftDataLimit(); +extern ABC_DLL void  Extra_UtilGetoptReset(); +extern int           Extra_UtilGetopt( int argc, char *argv[], char *optstring ); +extern char *        Extra_UtilPrintTime( long t ); +extern char *        Extra_UtilStrsav( char *s ); +extern char *        Extra_UtilTildeExpand( char *fname ); +extern char *        Extra_UtilFileSearch( char *file, char *path, char *mode ); +extern void          (*Extra_UtilMMoutOfMemory)(); -extern char *      globalUtilOptarg; -extern int         globalUtilOptind; +extern char *        globalUtilOptarg; +extern int           globalUtilOptind;  /**AutomaticEnd***************************************************************/ diff --git a/src/sat/bsat/satChecker.c b/src/sat/bsat/satChecker.c new file mode 100644 index 00000000..1488fe2f --- /dev/null +++ b/src/sat/bsat/satChecker.c @@ -0,0 +1,187 @@ +/**CFile**************************************************************** + +  FileName    [satChecker.c] + +  SystemName  [ABC: Logic synthesis and verification system.] + +  PackageName [SAT sat_solver.] + +  Synopsis    [Resolution proof checker.] + +  Author      [Alan Mishchenko] +   +  Affiliation [UC Berkeley] + +  Date        [Ver. 1.0. Started - June 20, 2005.] + +  Revision    [$Id: satChecker.c,v 1.4 2005/09/16 22:55:03 casem Exp $] + +***********************************************************************/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <time.h> +#include "vec.h" + +//////////////////////////////////////////////////////////////////////// +///                        DECLARATIONS                              /// +//////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////// +///                     FUNCTION DEFINITIONS                         /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Sat_PrintClause( Vec_Vec_t * vClauses, int Clause ) +{ +    Vec_Int_t * vClause; +    int i, Entry; +    printf( "Clause %d:  {", Clause ); +    vClause = Vec_VecEntry( vClauses, Clause ); +    Vec_IntForEachEntry( vClause, Entry, i ) +        printf( " %d", Entry ); +    printf( " }\n" ); +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Sat_ProofResolve( Vec_Vec_t * vClauses, int Result, int Clause1, int Clause2 ) +{ +    Vec_Int_t * vResult  = Vec_VecEntry( vClauses, Result ); +    Vec_Int_t * vClause1 = Vec_VecEntry( vClauses, Clause1 ); +    Vec_Int_t * vClause2 = Vec_VecEntry( vClauses, Clause2 ); +    int Entry1, Entry2, ResVar; +    int i, j, Counter = 0; + +    Vec_IntForEachEntry( vClause1, Entry1, i ) +    Vec_IntForEachEntry( vClause2, Entry2, j ) +    if ( Entry1 == -Entry2 ) +    { +        ResVar = Entry1; +        Counter++; +    } +    if ( Counter != 1 ) +    { +        printf( "Error: Clause %d = Resolve(%d, %d): The number of pivot vars is %d.\n",  +            Result, Clause1, Clause2, Counter ); +        Sat_PrintClause( vClauses, Clause1 ); +        Sat_PrintClause( vClauses, Clause2 ); +        return 0; +    } +    // create new clause +    assert( Vec_IntSize(vResult) == 0 ); +    Vec_IntForEachEntry( vClause1, Entry1, i ) +        if ( Entry1 != ResVar && Entry1 != -ResVar ) +            Vec_IntPushUnique( vResult, Entry1 ); +    assert( Vec_IntSize(vResult) + 1 == Vec_IntSize(vClause1) ); +    Vec_IntForEachEntry( vClause2, Entry2, i ) +        if ( Entry2 != ResVar && Entry2 != -ResVar ) +            Vec_IntPushUnique( vResult, Entry2 ); +    return 1; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Sat_ProofChecker( char * pFileName ) +{ +    FILE * pFile; +    Vec_Vec_t * vClauses; +    int c, i, Num, RetValue, Counter, Counter2, Clause1, Clause2; +    // open the file +    pFile = fopen( pFileName, "r" ); +    if ( pFile == NULL ) +        return; +    // count the number of clauses +    Counter = Counter2 = 0; +    while ( (c = fgetc(pFile)) != EOF ) +    { +        Counter += (c == '\n'); +        Counter2 += (c == '*'); +    } +    vClauses = Vec_VecStart( Counter+1 ); +    printf( "The proof contains %d roots and %d resolution steps.\n", Counter-Counter2, Counter2 ); +    // read the clauses +    rewind( pFile ); +    for ( i = 1 ; ; i++ ) +    { +        RetValue = fscanf( pFile, "%d", &Num ); +        if ( RetValue != 1 ) +            break; +        assert( Num == i ); +        while ( (c = fgetc( pFile )) == ' ' ); +        if ( c == '*' ) +        { +            RetValue = fscanf( pFile, "%d %d", &Clause1, &Clause2 ); +            assert( RetValue == 2 ); +            RetValue = fscanf( pFile, "%d", &Num ); +            assert( RetValue == 1 ); +            assert( Num == 0 ); +            if ( !Sat_ProofResolve( vClauses, i, Clause1, Clause2 ) ) +            { +                printf( "Error detected in the resolution proof.\n" ); +                Vec_VecFree( vClauses ); +                fclose( pFile ); +                return; +            } +        } +        else +        { +            ungetc( c, pFile ); +            while ( 1 ) +            { +                RetValue = fscanf( pFile, "%d", &Num ); +                assert( RetValue == 1 ); +                if ( Num == 0 ) +                    break; +                Vec_VecPush( vClauses, i, (void *)Num ); +            } +            RetValue = fscanf( pFile, "%d", &Num ); +            assert( RetValue == 1 ); +            assert( Num == 0 ); +        } +    } +    assert( i-1 == Counter ); +    if ( Vec_IntSize( Vec_VecEntry(vClauses, Counter) ) != 0 ) +        printf( "The last clause is not empty.\n" ); +    else +        printf( "The empty clause is derived.\n" ); +    Vec_VecFree( vClauses ); +    fclose( pFile ); +} + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/sat/bsat/satInterA.c b/src/sat/bsat/satInterA.c index 57628989..5edc5b67 100644 --- a/src/sat/bsat/satInterA.c +++ b/src/sat/bsat/satInterA.c @@ -701,6 +701,10 @@ p->timeTrace += clock() - clk;  //        Inta_ManPrintInterOne( p, pFinal );      }      Inta_ManProofSet( p, pFinal, p->Counter ); +    // make sure the same proof ID is not asssigned to two consecutive clauses +    assert( p->pProofNums[pFinal->Id-1] != p->Counter ); +//    if ( p->pProofNums[pFinal->Id] == p->pProofNums[pFinal->Id-1] ) +//        p->pProofNums[pFinal->Id] = p->pProofNums[pConflict->Id];      return p->Counter;  } @@ -748,6 +752,27 @@ int Inta_ManProofRecordOne( Inta_Man_t * p, Sto_Cls_t * pClause )      {          assert( 0 ); // cannot prove          return 0; +    }  + +    // skip the clause if it is weaker or the same as the conflict clause +    if ( pClause->nLits >= pConflict->nLits ) +    { +        // check if every literal of conflict clause can be found in the given clause +        int j; +        for ( i = 0; i < (int)pConflict->nLits; i++ ) +        { +            for ( j = 0; j < (int)pClause->nLits; j++ ) +                if ( pConflict->pLits[i] == pClause->pLits[j] ) +                    break; +            if ( j == (int)pClause->nLits ) // literal pConflict->pLits[i] is not found +                break; +        } +        if ( i == (int)pConflict->nLits ) // all lits are found +        { +            // undo to the root level +            Inta_ManCancelUntil( p, p->nRootSize ); +            return 1; +        }      }      // construct the proof @@ -973,6 +998,7 @@ void * Inta_ManInterpolate( Inta_Man_t * p, Sto_Man_t * pCnf, void * vVarsAB, in      if ( p->fProofWrite )      {           fclose( p->pFile ); +//        Sat_ProofChecker( "proof.cnf_" );          p->pFile = NULL;          } diff --git a/src/sat/bsat/satInterA_mod.c b/src/sat/bsat/satInterA_mod.c new file mode 100644 index 00000000..faf396a6 --- /dev/null +++ b/src/sat/bsat/satInterA_mod.c @@ -0,0 +1,1104 @@ +/**CFile**************************************************************** + +  FileName    [satInter.c] + +  SystemName  [ABC: Logic synthesis and verification system.] + +  PackageName [SAT sat_solver.] + +  Synopsis    [Interpolation package.] + +  Author      [Alan Mishchenko] +   +  Affiliation [UC Berkeley] + +  Date        [Ver. 1.0. Started - June 20, 2005.] + +  Revision    [$Id: satInter.c,v 1.4 2005/09/16 22:55:03 casem Exp $] + +***********************************************************************/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <time.h> +#include "satStore.h" +#include "aig.h" + +//////////////////////////////////////////////////////////////////////// +///                        DECLARATIONS                              /// +//////////////////////////////////////////////////////////////////////// + +// variable assignments  +static const lit    LIT_UNDEF = 0xffffffff; + +// interpolation manager +struct Inta_Man_t_ +{ +    // clauses of the problems +    Sto_Man_t *     pCnf;         // the set of CNF clauses for A and B +    Vec_Int_t *     vVarsAB;      // the array of global variables +    // various parameters +    int             fVerbose;     // verbosiness flag +    int             fProofVerif;  // verifies the proof +    int             fProofWrite;  // writes the proof file +    int             nVarsAlloc;   // the allocated size of var arrays +    int             nClosAlloc;   // the allocated size of clause arrays +    // internal BCP +    int             nRootSize;    // the number of root level assignments +    int             nTrailSize;   // the number of assignments made  +    lit *           pTrail;       // chronological order of assignments (size nVars) +    lit *           pAssigns;     // assignments by variable (size nVars)  +    char *          pSeens;       // temporary mark (size nVars) +    Sto_Cls_t **    pReasons;     // reasons for each assignment (size nVars)           +    Sto_Cls_t **    pWatches;     // watched clauses for each literal (size 2*nVars)           +    // interpolation data +    Aig_Man_t *     pAig;         // the AIG manager for recording the interpolant +    int *           pVarTypes;    // variable type (size nVars) [1=A, 0=B, <0=AB] +    Aig_Obj_t **    pInters;      // storage for interpolants as truth tables (size nClauses) +    int             nIntersAlloc; // the allocated size of truth table array +    // proof recording +    int             Counter;      // counter of resolved clauses +    int *           pProofNums;   // the proof numbers for each clause (size nClauses) +    FILE *          pFile;        // the file for proof recording +    // internal verification +    lit *           pResLits;     // the literals of the resolvent    +    int             nResLits;     // the number of literals of the resolvent +    int             nResLitsAlloc;// the number of literals of the resolvent +    // runtime stats +    int             timeBcp;      // the runtime for BCP +    int             timeTrace;    // the runtime of trace construction +    int             timeTotal;    // the total runtime of interpolation +}; + +// procedure to get hold of the clauses' truth table  +static inline Aig_Obj_t ** Inta_ManAigRead( Inta_Man_t * pMan, Sto_Cls_t * pCls )                   { return pMan->pInters + pCls->Id;          } +static inline void         Inta_ManAigClear( Inta_Man_t * pMan, Aig_Obj_t ** p )                    { *p = Aig_ManConst0(pMan->pAig);           } +static inline void         Inta_ManAigFill( Inta_Man_t * pMan, Aig_Obj_t ** p )                     { *p = Aig_ManConst1(pMan->pAig);           } +static inline void         Inta_ManAigCopy( Inta_Man_t * pMan, Aig_Obj_t ** p, Aig_Obj_t ** q )     { *p = *q;                                  } +static inline void         Inta_ManAigAnd( Inta_Man_t * pMan, Aig_Obj_t ** p, Aig_Obj_t ** q )      { *p = Aig_And(pMan->pAig, *p, *q);         } +static inline void         Inta_ManAigOr( Inta_Man_t * pMan, Aig_Obj_t ** p, Aig_Obj_t ** q )       { *p = Aig_Or(pMan->pAig, *p, *q);          } +static inline void         Inta_ManAigOrNot( Inta_Man_t * pMan, Aig_Obj_t ** p, Aig_Obj_t ** q )    { *p = Aig_Or(pMan->pAig, *p, Aig_Not(*q)); } +static inline void         Inta_ManAigOrVar( Inta_Man_t * pMan, Aig_Obj_t ** p, int v )             { *p = Aig_Or(pMan->pAig, *p, Aig_IthVar(pMan->pAig, v));          } +static inline void         Inta_ManAigOrNotVar( Inta_Man_t * pMan, Aig_Obj_t ** p, int v )          { *p = Aig_Or(pMan->pAig, *p, Aig_Not(Aig_IthVar(pMan->pAig, v))); } + +// reading/writing the proof for a clause +static inline int          Inta_ManProofGet( Inta_Man_t * p, Sto_Cls_t * pCls )                  { return p->pProofNums[pCls->Id];           } +static inline void         Inta_ManProofSet( Inta_Man_t * p, Sto_Cls_t * pCls, int n )           {  +    p->pProofNums[pCls->Id] = n;               +    if ( pCls->Id == 5552 || pCls->Id == 5553 ) +    { +        int x = 0; +    } +} + +//////////////////////////////////////////////////////////////////////// +///                     FUNCTION DEFINITIONS                         /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + +  Synopsis    [Allocate proof manager.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Inta_Man_t * Inta_ManAlloc() +{ +    Inta_Man_t * p; +    // allocate the manager +    p = (Inta_Man_t *)malloc( sizeof(Inta_Man_t) ); +    memset( p, 0, sizeof(Inta_Man_t) ); +    // verification +    p->nResLitsAlloc = (1<<16); +    p->pResLits = malloc( sizeof(lit) * p->nResLitsAlloc ); +    // parameters +    p->fProofWrite = 1; +    p->fProofVerif = 1; + +    return p;     +} + +/**Function************************************************************* + +  Synopsis    [Count common variables in the clauses of A and B.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Inta_ManGlobalVars( Inta_Man_t * p ) +{ +    Sto_Cls_t * pClause; +    int LargeNum = -100000000; +    int Var, nVarsAB, v; + +    // mark the variable encountered in the clauses of A +    Sto_ManForEachClauseRoot( p->pCnf, pClause ) +    { +        if ( !pClause->fA ) +            break; +        for ( v = 0; v < (int)pClause->nLits; v++ ) +            p->pVarTypes[lit_var(pClause->pLits[v])] = 1; +    } + +    // check variables that appear in clauses of B +    nVarsAB = 0; +    Sto_ManForEachClauseRoot( p->pCnf, pClause ) +    { +        if ( pClause->fA ) +            continue; +        for ( v = 0; v < (int)pClause->nLits; v++ ) +        { +            Var = lit_var(pClause->pLits[v]); +            if ( p->pVarTypes[Var] == 1 ) // var of A +            { +                // change it into a global variable +                nVarsAB++; +                p->pVarTypes[Var] = LargeNum; +            } +        } +    } +    assert( nVarsAB <= Vec_IntSize(p->vVarsAB) ); + +    // order global variables +    nVarsAB = 0; +    Vec_IntForEachEntry( p->vVarsAB, Var, v ) +        p->pVarTypes[Var] = -(1+nVarsAB++); + +    // check that there is no extra global variables +    for ( v = 0; v < p->pCnf->nVars; v++ ) +        assert( p->pVarTypes[v] != LargeNum ); +    return nVarsAB; +} + +/**Function************************************************************* + +  Synopsis    [Resize proof manager.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Inta_ManResize( Inta_Man_t * p ) +{ +    // check if resizing is needed +    if ( p->nVarsAlloc < p->pCnf->nVars ) +    { +        // find the new size +        if ( p->nVarsAlloc == 0 ) +            p->nVarsAlloc = 1; +        while ( p->nVarsAlloc < p->pCnf->nVars )  +            p->nVarsAlloc *= 2; +        // resize the arrays +        p->pTrail    = (lit *)       realloc( p->pTrail,    sizeof(lit) * p->nVarsAlloc ); +        p->pAssigns  = (lit *)       realloc( p->pAssigns,  sizeof(lit) * p->nVarsAlloc ); +        p->pSeens    = (char *)      realloc( p->pSeens,    sizeof(char) * p->nVarsAlloc ); +        p->pVarTypes = (int *)       realloc( p->pVarTypes, sizeof(int) * p->nVarsAlloc ); +        p->pReasons  = (Sto_Cls_t **)realloc( p->pReasons,  sizeof(Sto_Cls_t *) * p->nVarsAlloc ); +        p->pWatches  = (Sto_Cls_t **)realloc( p->pWatches,  sizeof(Sto_Cls_t *) * p->nVarsAlloc*2 ); +    } + +    // clean the free space +    memset( p->pAssigns , 0xff, sizeof(lit) * p->pCnf->nVars ); +    memset( p->pSeens   , 0,    sizeof(char) * p->pCnf->nVars ); +    memset( p->pVarTypes, 0,    sizeof(int) * p->pCnf->nVars ); +    memset( p->pReasons , 0,    sizeof(Sto_Cls_t *) * p->pCnf->nVars ); +    memset( p->pWatches , 0,    sizeof(Sto_Cls_t *) * p->pCnf->nVars*2 ); + +    // compute the number of common variables +    Inta_ManGlobalVars( p ); + +    // check if resizing of clauses is needed +    if ( p->nClosAlloc < p->pCnf->nClauses ) +    { +        // find the new size +        if ( p->nClosAlloc == 0 ) +            p->nClosAlloc = 1; +        while ( p->nClosAlloc < p->pCnf->nClauses )  +            p->nClosAlloc *= 2; +        // resize the arrays +        p->pProofNums = (int *) realloc( p->pProofNums,  sizeof(int) * p->nClosAlloc ); +    } +    memset( p->pProofNums, 0, sizeof(int) * p->pCnf->nClauses ); + +    // check if resizing of truth tables is needed +    if ( p->nIntersAlloc < p->pCnf->nClauses ) +    { +        p->nIntersAlloc = p->pCnf->nClauses; +        p->pInters = (Aig_Obj_t **) realloc( p->pInters, sizeof(Aig_Obj_t *) * p->nIntersAlloc ); +    } +    memset( p->pInters, 0, sizeof(Aig_Obj_t *) * p->pCnf->nClauses ); +} + +/**Function************************************************************* + +  Synopsis    [Deallocate proof manager.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Inta_ManFree( Inta_Man_t * p ) +{ +/* +    printf( "Runtime stats:\n" ); +PRT( "BCP     ", p->timeBcp   ); +PRT( "Trace   ", p->timeTrace ); +PRT( "TOTAL   ", p->timeTotal ); +*/ +    free( p->pInters ); +    free( p->pProofNums ); +    free( p->pTrail ); +    free( p->pAssigns ); +    free( p->pSeens ); +    free( p->pVarTypes ); +    free( p->pReasons ); +    free( p->pWatches ); +    free( p->pResLits ); +    free( p ); +} + + + + +/**Function************************************************************* + +  Synopsis    [Prints the clause.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Inta_ManPrintClause( Inta_Man_t * p, Sto_Cls_t * pClause ) +{ +    int i; +    printf( "Clause ID = %d. Proof = %d. {", pClause->Id, Inta_ManProofGet(p, pClause) ); +    for ( i = 0; i < (int)pClause->nLits; i++ ) +        printf( " %d", pClause->pLits[i] ); +    printf( " }\n" ); +} + +/**Function************************************************************* + +  Synopsis    [Prints the resolvent.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Inta_ManPrintResolvent( lit * pResLits, int nResLits ) +{ +    int i; +    printf( "Resolvent: {" ); +    for ( i = 0; i < nResLits; i++ ) +        // Yu Hu +        // printf( " %d", pResLits[i] ); +        printf( " %d", lit_print(pResLits[i]) ); +    printf( " }\n" ); +} + +/**Function************************************************************* + +  Synopsis    [Prints the interpolant for one clause.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Inta_ManPrintInterOne( Inta_Man_t * p, Sto_Cls_t * pClause ) +{ +    printf( "Clause %2d :  ", pClause->Id ); +//    Extra_PrintBinary___( stdout, Inta_ManAigRead(p, pClause), (1 << p->nVarsAB) ); +    printf( "\n" ); +} + + + +/**Function************************************************************* + +  Synopsis    [Adds one clause to the watcher list.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Inta_ManWatchClause( Inta_Man_t * p, Sto_Cls_t * pClause, lit Lit ) +{ +    assert( lit_check(Lit, p->pCnf->nVars) ); +    if ( pClause->pLits[0] == Lit ) +        pClause->pNext0 = p->pWatches[lit_neg(Lit)];   +    else +    { +        assert( pClause->pLits[1] == Lit ); +        pClause->pNext1 = p->pWatches[lit_neg(Lit)];   +    } +    p->pWatches[lit_neg(Lit)] = pClause; +} + + +/**Function************************************************************* + +  Synopsis    [Records implication.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline int Inta_ManEnqueue( Inta_Man_t * p, lit Lit, Sto_Cls_t * pReason ) +{ +    int Var = lit_var(Lit); +    if ( p->pAssigns[Var] != LIT_UNDEF ) +        return p->pAssigns[Var] == Lit; +    p->pAssigns[Var] = Lit; +    p->pReasons[Var] = pReason; +    p->pTrail[p->nTrailSize++] = Lit; +//printf( "assigning var %d value %d\n", Var, !lit_sign(Lit) ); +    return 1; +} + +/**Function************************************************************* + +  Synopsis    [Records implication.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Inta_ManCancelUntil( Inta_Man_t * p, int Level ) +{ +    lit Lit; +    int i, Var; +    for ( i = p->nTrailSize - 1; i >= Level; i-- ) +    { +        Lit = p->pTrail[i]; +        Var = lit_var( Lit ); +        p->pReasons[Var] = NULL; +        p->pAssigns[Var] = LIT_UNDEF; +//printf( "cancelling var %d\n", Var ); +    } +    p->nTrailSize = Level; +} + +/**Function************************************************************* + +  Synopsis    [Propagate one assignment.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline Sto_Cls_t * Inta_ManPropagateOne( Inta_Man_t * p, lit Lit ) +{ +    Sto_Cls_t ** ppPrev, * pCur, * pTemp; +    lit LitF = lit_neg(Lit); +    int i; +    // iterate through the literals +    ppPrev = p->pWatches + Lit; +    for ( pCur = p->pWatches[Lit]; pCur; pCur = *ppPrev ) +    { +        // make sure the false literal is in the second literal of the clause +        if ( pCur->pLits[0] == LitF ) +        { +            pCur->pLits[0] = pCur->pLits[1]; +            pCur->pLits[1] = LitF; +            pTemp = pCur->pNext0; +            pCur->pNext0 = pCur->pNext1; +            pCur->pNext1 = pTemp; +        } +        assert( pCur->pLits[1] == LitF ); + +        // if the first literal is true, the clause is satisfied +        if ( pCur->pLits[0] == p->pAssigns[lit_var(pCur->pLits[0])] ) +        { +            ppPrev = &pCur->pNext1; +            continue; +        } + +        // look for a new literal to watch +        for ( i = 2; i < (int)pCur->nLits; i++ ) +        { +            // skip the case when the literal is false +            if ( lit_neg(pCur->pLits[i]) == p->pAssigns[lit_var(pCur->pLits[i])] ) +                continue; +            // the literal is either true or unassigned - watch it +            pCur->pLits[1] = pCur->pLits[i]; +            pCur->pLits[i] = LitF; +            // remove this clause from the watch list of Lit +            *ppPrev = pCur->pNext1; +            // add this clause to the watch list of pCur->pLits[i] (now it is pCur->pLits[1]) +            Inta_ManWatchClause( p, pCur, pCur->pLits[1] ); +            break; +        } +        if ( i < (int)pCur->nLits ) // found new watch +            continue; + +        // clause is unit - enqueue new implication +        if ( Inta_ManEnqueue(p, pCur->pLits[0], pCur) ) +        { +            ppPrev = &pCur->pNext1; +            continue; +        } + +        // conflict detected - return the conflict clause +        return pCur; +    } +    return NULL; +} + +/**Function************************************************************* + +  Synopsis    [Propagate the current assignments.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Sto_Cls_t * Inta_ManPropagate( Inta_Man_t * p, int Start ) +{ +    Sto_Cls_t * pClause; +    int i; +    int clk = clock(); +    for ( i = Start; i < p->nTrailSize; i++ ) +    { +        pClause = Inta_ManPropagateOne( p, p->pTrail[i] ); +        if ( pClause ) +        { +p->timeBcp += clock() - clk; +            return pClause; +        } +    } +p->timeBcp += clock() - clk; +    return NULL; +} + + +/**Function************************************************************* + +  Synopsis    [Writes one root clause into a file.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Inta_ManProofWriteOne( Inta_Man_t * p, Sto_Cls_t * pClause ) +{ +    Inta_ManProofSet( p, pClause, ++p->Counter ); + +    if ( p->fProofWrite ) +    { +        int v; +        fprintf( p->pFile, "%d", Inta_ManProofGet(p, pClause) ); +        for ( v = 0; v < (int)pClause->nLits; v++ ) +            fprintf( p->pFile, " %d", lit_print(pClause->pLits[v]) ); +        fprintf( p->pFile, " 0 0\n" ); +    } +} + +// Yu Hu +void Inta_ManPrintClauseEx( lit * pResLits, int nResLits ) +{ +    int i; +    printf( " {" ); +    for ( i = 0; i < nResLits; i++ ) +        printf( " %d", lit_print(pResLits[i]) ); +    printf( " }\n" ); +} + + +/**Function************************************************************* + +  Synopsis    [Traces the proof for one clause.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Inta_ManProofTraceOne( Inta_Man_t * p, Sto_Cls_t * pConflict, Sto_Cls_t * pFinal ) +{ +    Sto_Cls_t * pReason; +    int i, v, Var, PrevId; +    int fPrint = 1; // Yu Hu +    int clk = clock(); + +    // collect resolvent literals +    if ( p->fProofVerif ) +    { +        assert( (int)pConflict->nLits <= p->nResLitsAlloc ); +        memcpy( p->pResLits, pConflict->pLits, sizeof(lit) * pConflict->nLits ); +        p->nResLits = pConflict->nLits; +    } + +    // mark all the variables in the conflict as seen +    for ( v = 0; v < (int)pConflict->nLits; v++ ) +        p->pSeens[lit_var(pConflict->pLits[v])] = 1; + +    // start the anticedents +//    pFinal->pAntis = Vec_PtrAlloc( 32 ); +//    Vec_PtrPush( pFinal->pAntis, pConflict ); + +    if ( p->pCnf->nClausesA ) +        Inta_ManAigCopy( p, Inta_ManAigRead(p, pFinal), Inta_ManAigRead(p, pConflict) ); + +    // follow the trail backwards +    PrevId = Inta_ManProofGet(p, pConflict); +    for ( i = p->nTrailSize - 1; i >= 0; i-- ) +    { +        // skip literals that are not involved +        Var = lit_var(p->pTrail[i]); +        if ( !p->pSeens[Var] ) +            continue; +        p->pSeens[Var] = 0; + +        // skip literals of the resulting clause +        pReason = p->pReasons[Var]; +        if ( pReason == NULL ) +            continue; +        assert( p->pTrail[i] == pReason->pLits[0] ); + +        // add the variables to seen +        for ( v = 1; v < (int)pReason->nLits; v++ ) +            p->pSeens[lit_var(pReason->pLits[v])] = 1; + +        // record the reason clause +        assert( Inta_ManProofGet(p, pReason) > 0 ); +        p->Counter++; +        if ( p->fProofWrite && p->Counter >= 8370 &&  p->Counter <= 8380 ) { +            fprintf( p->pFile, "%d * %d %d 0\n", p->Counter, PrevId, Inta_ManProofGet(p, pReason) ); +            // Yu Hu +            printf( "%d * %d %d 0\n", p->Counter, PrevId, Inta_ManProofGet(p, pReason) ); + +            if ( p->Counter == 8371 ) +            { +                int s = 0; +            } +        } +        PrevId = p->Counter; + +        if ( p->pCnf->nClausesA ) +        { +            if ( p->pVarTypes[Var] == 1 ) // var of A +                Inta_ManAigOr( p, Inta_ManAigRead(p, pFinal), Inta_ManAigRead(p, pReason) ); +            else +                Inta_ManAigAnd( p, Inta_ManAigRead(p, pFinal), Inta_ManAigRead(p, pReason) ); +        } +  +        // resolve the temporary resolvent with the reason clause +        if ( p->fProofVerif ) +        { +            int v1, v2;  + +            // Yu Hu +            // if ( fPrint ) +            //     Inta_ManPrintResolvent( p->pResLits, p->nResLits ); +            if ( fPrint && p->Counter >= 8370 &&  p->Counter <= 8380 ) {                                                                                                 +                printf("pivot = %d,\n", lit_print(p->pTrail[i]));                                                           +                Inta_ManPrintClauseEx( p->pResLits, p->nResLits);                                                           +            }                                                           + +            // check that the var is present in the resolvent +            for ( v1 = 0; v1 < p->nResLits; v1++ ) +                if ( lit_var(p->pResLits[v1]) == Var ) +                    break; +            if ( v1 == p->nResLits ) +                printf( "Recording clause %d: Cannot find variable %d in the temporary resolvent.\n", pFinal->Id, Var ); +            if ( p->pResLits[v1] != lit_neg(pReason->pLits[0]) ) +                printf( "Recording clause %d: The resolved variable %d is in the wrong polarity.\n", pFinal->Id, Var ); +            // remove this variable from the resolvent +            assert( lit_var(p->pResLits[v1]) == Var ); +            p->nResLits--; +            for ( ; v1 < p->nResLits; v1++ ) +                p->pResLits[v1] = p->pResLits[v1+1]; +            // add variables of the reason clause +            for ( v2 = 1; v2 < (int)pReason->nLits; v2++ ) +            { +                for ( v1 = 0; v1 < p->nResLits; v1++ ) +                    if ( lit_var(p->pResLits[v1]) == lit_var(pReason->pLits[v2]) ) +                        break; +                // if it is a new variable, add it to the resolvent +                if ( v1 == p->nResLits )  +                { +                    if ( p->nResLits == p->nResLitsAlloc ) +                        printf( "Recording clause %d: Ran out of space for intermediate resolvent.\n", pFinal->Id ); +                    p->pResLits[ p->nResLits++ ] = pReason->pLits[v2]; +                    continue; +                } +                // if the variable is the same, the literal should be the same too +                if ( p->pResLits[v1] == pReason->pLits[v2] ) +                    continue; +                // the literal is different +                printf( "Recording clause %d: Trying to resolve the clause with more than one opposite literal.\n", pFinal->Id ); +            } + +            // Yu Hu +            if ( fPrint && p->Counter >= 8370 &&  p->Counter <= 8380 ) {                                                                                                 +                Inta_ManPrintClauseEx( pReason->pLits, pReason->nLits);                                                     +                Inta_ManPrintResolvent( p->pResLits, p->nResLits);                                                         +            }             + +        } +//        Vec_PtrPush( pFinal->pAntis, pReason ); +    } + +    // unmark all seen variables +//    for ( i = p->nTrailSize - 1; i >= 0; i-- ) +//        p->pSeens[lit_var(p->pTrail[i])] = 0; +    // check that the literals are unmarked +//    for ( i = p->nTrailSize - 1; i >= 0; i-- ) +//        assert( p->pSeens[lit_var(p->pTrail[i])] == 0 ); + +    // use the resulting clause to check the correctness of resolution +    if ( p->fProofVerif ) +    { +        int v1, v2;  + +        // Yu Hu +//        if ( fPrint ) +//            Inta_ManPrintResolvent( p->pResLits, p->nResLits ); + +        for ( v1 = 0; v1 < p->nResLits; v1++ ) +        { +            for ( v2 = 0; v2 < (int)pFinal->nLits; v2++ ) +                if ( pFinal->pLits[v2] == p->pResLits[v1] ) +                    break; +            if ( v2 < (int)pFinal->nLits ) +                continue; +            break; +        } +        if ( v1 < p->nResLits ) +        { +            printf( "Recording clause %d: The final resolvent is wrong.\n", pFinal->Id ); +            Inta_ManPrintClause( p, pConflict ); +            Inta_ManPrintResolvent( p->pResLits, p->nResLits ); +            Inta_ManPrintClause( p, pFinal ); +        } + +        // if there are literals in the clause that are not in the resolvent +        // it means that the derived resolvent is stronger than the clause +        // we can replace the clause with the resolvent by removing these literals +        if ( p->nResLits != (int)pFinal->nLits ) +        { +            for ( v1 = 0; v1 < (int)pFinal->nLits; v1++ ) +            { +                for ( v2 = 0; v2 < p->nResLits; v2++ ) +                    if ( pFinal->pLits[v1] == p->pResLits[v2] ) +                        break; +                if ( v2 < p->nResLits ) +                    continue; +                // remove literal v1 from the final clause +                pFinal->nLits--; +                for ( v2 = v1; v2 < (int)pFinal->nLits; v2++ ) +                    pFinal->pLits[v2] = pFinal->pLits[v2+1]; +                v1--; +            } +            assert( p->nResLits == (int)pFinal->nLits ); +        } +    } +p->timeTrace += clock() - clk;   + +    // return the proof pointer  +    if ( p->pCnf->nClausesA ) +    { +//        Inta_ManPrintInterOne( p, pFinal ); +    } +    Inta_ManProofSet( p, pFinal, p->Counter ); +    if ( pFinal->Id == 5552 || pFinal->Id == 5553 ) +    { +        int x = 0; +    } + +    if ( p->pProofNums[pFinal->Id] == p->pProofNums[pFinal->Id-1] ) +        p->pProofNums[pFinal->Id] = p->pProofNums[pConflict->Id]; + +    return p->Counter; +} + +/**Function************************************************************* + +  Synopsis    [Records the proof for one clause.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Inta_ManProofRecordOne( Inta_Man_t * p, Sto_Cls_t * pClause ) +{ +    Sto_Cls_t * pConflict; +    int i; + +    // empty clause never ends up there +    assert( pClause->nLits > 0 ); +    if ( pClause->nLits == 0 ) +        printf( "Error: Empty clause is attempted.\n" ); + +    assert( !pClause->fRoot ); +    assert( p->nTrailSize == p->nRootSize ); + +    // if any of the clause literals are already assumed +    // it means that the clause is redundant and can be skipped +    for ( i = 0; i < (int)pClause->nLits; i++ ) +        if ( p->pAssigns[lit_var(pClause->pLits[i])] == pClause->pLits[i] ) +            return 1; + +    // add assumptions to the trail +    for ( i = 0; i < (int)pClause->nLits; i++ ) +        if ( !Inta_ManEnqueue( p, lit_neg(pClause->pLits[i]), NULL ) ) +        { +            assert( 0 ); // impossible +            return 0; +        } + +    // propagate the assumptions +    pConflict = Inta_ManPropagate( p, p->nRootSize ); +    if ( pConflict == NULL ) +    { +        assert( 0 ); // cannot prove +        return 0; +    } + +    // construct the proof +    Inta_ManProofTraceOne( p, pConflict, pClause ); + +    // undo to the root level +    Inta_ManCancelUntil( p, p->nRootSize ); + +    // add large clauses to the watched lists +    if ( pClause->nLits > 1 ) +    { +        Inta_ManWatchClause( p, pClause, pClause->pLits[0] ); +        Inta_ManWatchClause( p, pClause, pClause->pLits[1] ); +        return 1; +    } +    assert( pClause->nLits == 1 ); + +    // if the clause proved is unit, add it and propagate +    if ( !Inta_ManEnqueue( p, pClause->pLits[0], pClause ) ) +    { +        assert( 0 ); // impossible +        return 0; +    } + +    // propagate the assumption +    pConflict = Inta_ManPropagate( p, p->nRootSize ); +    if ( pConflict ) +    { +        // construct the proof +        Inta_ManProofTraceOne( p, pConflict, p->pCnf->pEmpty ); +//        if ( p->fVerbose ) +//            printf( "Found last conflict after adding unit clause number %d!\n", pClause->Id ); +        return 0; +    } + +    // update the root level +    p->nRootSize = p->nTrailSize; +    return 1; +} + +/**Function************************************************************* + +  Synopsis    [Propagate the root clauses.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Inta_ManProcessRoots( Inta_Man_t * p ) +{ +    Sto_Cls_t * pClause; +    int Counter; + +    // make sure the root clauses are preceeding the learnt clauses +    Counter = 0; +    Sto_ManForEachClause( p->pCnf, pClause ) +    { +        assert( (int)pClause->fA    == (Counter < (int)p->pCnf->nClausesA) ); +        assert( (int)pClause->fRoot == (Counter < (int)p->pCnf->nRoots)    ); +        Counter++; +    } +    assert( p->pCnf->nClauses == Counter ); + +    // make sure the last clause if empty +    assert( p->pCnf->pTail->nLits == 0 ); + +    // go through the root unit clauses +    p->nTrailSize = 0; +    Sto_ManForEachClauseRoot( p->pCnf, pClause ) +    { +        // create watcher lists for the root clauses +        if ( pClause->nLits > 1 ) +        { +            Inta_ManWatchClause( p, pClause, pClause->pLits[0] ); +            Inta_ManWatchClause( p, pClause, pClause->pLits[1] ); +        } +        // empty clause and large clauses +        if ( pClause->nLits != 1 ) +            continue; +        // unit clause +        assert( lit_check(pClause->pLits[0], p->pCnf->nVars) ); +        if ( !Inta_ManEnqueue( p, pClause->pLits[0], pClause ) ) +        { +            // detected root level conflict +//            printf( "Error in Inta_ManProcessRoots(): Detected a root-level conflict too early!\n" ); +//            assert( 0 ); +            // detected root level conflict +            Inta_ManProofTraceOne( p, pClause, p->pCnf->pEmpty ); +            if ( p->fVerbose ) +                printf( "Found root level conflict!\n" ); +            return 0; +        } +    } + +    // propagate the root unit clauses +    pClause = Inta_ManPropagate( p, 0 ); +    if ( pClause ) +    { +        // detected root level conflict +        Inta_ManProofTraceOne( p, pClause, p->pCnf->pEmpty ); +        if ( p->fVerbose ) +            printf( "Found root level conflict!\n" ); +        return 0; +    } + +    // set the root level +    p->nRootSize = p->nTrailSize; +    return 1; +} + +/**Function************************************************************* + +  Synopsis    [Records the proof.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Inta_ManPrepareInter( Inta_Man_t * p ) +{ +    Sto_Cls_t * pClause; +    int Var, VarAB, v; + +    // set interpolants for root clauses +    Sto_ManForEachClauseRoot( p->pCnf, pClause ) +    { +        if ( !pClause->fA ) // clause of B +        { +            Inta_ManAigFill( p, Inta_ManAigRead(p, pClause) ); +//            Inta_ManPrintInterOne( p, pClause ); +            continue; +        } +        // clause of A +        Inta_ManAigClear( p, Inta_ManAigRead(p, pClause) ); +        for ( v = 0; v < (int)pClause->nLits; v++ ) +        { +            Var = lit_var(pClause->pLits[v]); +            if ( p->pVarTypes[Var] < 0 ) // global var +            { +                VarAB = -p->pVarTypes[Var]-1; +                assert( VarAB >= 0 && VarAB < Vec_IntSize(p->vVarsAB) ); +                if ( lit_sign(pClause->pLits[v]) ) // negative var +                    Inta_ManAigOrNotVar( p, Inta_ManAigRead(p, pClause), VarAB ); +                else +                    Inta_ManAigOrVar( p, Inta_ManAigRead(p, pClause), VarAB ); +            } +        } +//        Inta_ManPrintInterOne( p, pClause ); +    } +} + +/**Function************************************************************* + +  Synopsis    [Computes interpolant for the given CNF.] + +  Description [Takes the interpolation manager, the CNF deriving by the SAT +  solver, which includes ClausesA, ClausesB, and learned clauses. Additional +  arguments are the vector of variables common to AB and the verbosiness flag. +  Returns the AIG manager with a single output, containing the interpolant.] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void * Inta_ManInterpolate( Inta_Man_t * p, Sto_Man_t * pCnf, void * vVarsAB, int fVerbose ) +{ +    Aig_Man_t * pRes; +    Aig_Obj_t * pObj; +    Sto_Cls_t * pClause; +    int RetValue = 1; +    int clkTotal = clock(); + +    // check that the CNF makes sense +    assert( pCnf->nVars > 0 && pCnf->nClauses > 0 ); +    p->pCnf = pCnf; +    p->fVerbose = fVerbose; +    p->vVarsAB = vVarsAB; +    p->pAig = pRes = Aig_ManStart( 10000 ); +    Aig_IthVar( p->pAig, Vec_IntSize(p->vVarsAB) - 1 ); + +    // adjust the manager +    Inta_ManResize( p ); + +    // prepare the interpolant computation +    Inta_ManPrepareInter( p ); + +    // construct proof for each clause +    // start the proof +    if ( p->fProofWrite ) +    { +        p->pFile = fopen( "proof.cnf_", "w" ); +        p->Counter = 0; +    } + +    // write the root clauses +    Sto_ManForEachClauseRoot( p->pCnf, pClause ) +        Inta_ManProofWriteOne( p, pClause ); + +    // propagate root level assignments +    if ( Inta_ManProcessRoots( p ) ) +    { +        // if there is no conflict, consider learned clauses +        Sto_ManForEachClause( p->pCnf, pClause ) +        { +            if ( pClause->Id == 5552 ) +            { +                int s = 0; +            } +            if ( pClause->fRoot ) +                continue; +            if ( !Inta_ManProofRecordOne( p, pClause ) ) +            { +                RetValue = 0; +                break; +            } +        } +    } + +    // stop the proof +    if ( p->fProofWrite ) +    {  +        fclose( p->pFile ); +        p->pFile = NULL;     +    } + +    if ( fVerbose ) +    { +//        PRT( "Interpo", clock() - clkTotal ); +    printf( "Vars = %d. Roots = %d. Learned = %d. Resol steps = %d.  Ave = %.2f.  Mem = %.2f Mb\n",  +        p->pCnf->nVars, p->pCnf->nRoots, p->pCnf->nClauses-p->pCnf->nRoots, p->Counter,   +        1.0*(p->Counter-p->pCnf->nRoots)/(p->pCnf->nClauses-p->pCnf->nRoots),  +        1.0*Sto_ManMemoryReport(p->pCnf)/(1<<20) ); +p->timeTotal += clock() - clkTotal; +    } + +    pObj = *Inta_ManAigRead( p, p->pCnf->pTail ); +    Aig_ObjCreatePo( pRes, pObj ); +    Aig_ManCleanup( pRes ); + +    p->pAig = NULL; +    return pRes; +     +} + + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Aig_Man_t * Inta_ManDeriveClauses( Inta_Man_t * pMan, Sto_Man_t * pCnf, int fClausesA ) +{ +    Aig_Man_t * p; +    Aig_Obj_t * pMiter, * pSum, * pLit; +    Sto_Cls_t * pClause; +    int Var, VarAB, v; +    p = Aig_ManStart( 10000 ); +    pMiter = Aig_ManConst1(p); +    Sto_ManForEachClauseRoot( pCnf, pClause ) +    { +        if ( fClausesA ^ pClause->fA ) // clause of B +            continue; +        // clause of A +        pSum = Aig_ManConst0(p); +        for ( v = 0; v < (int)pClause->nLits; v++ ) +        { +            Var = lit_var(pClause->pLits[v]); +            if ( pMan->pVarTypes[Var] < 0 ) // global var +            { +                VarAB = -pMan->pVarTypes[Var]-1; +                assert( VarAB >= 0 && VarAB < Vec_IntSize(pMan->vVarsAB) ); +                pLit = Aig_NotCond( Aig_IthVar(p, VarAB), lit_sign(pClause->pLits[v]) ); +            } +            else +                pLit = Aig_NotCond( Aig_IthVar(p, Vec_IntSize(pMan->vVarsAB)+1+Var), lit_sign(pClause->pLits[v]) ); +            pSum = Aig_Or( p, pSum, pLit ); +        } +        pMiter = Aig_And( p, pMiter, pSum ); +    } +    Aig_ObjCreatePo( p, pMiter ); +    return p; +} + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/sat/bsat/satInterA_old.c b/src/sat/bsat/satInterA_old.c new file mode 100644 index 00000000..57628989 --- /dev/null +++ b/src/sat/bsat/satInterA_old.c @@ -0,0 +1,1047 @@ +/**CFile**************************************************************** + +  FileName    [satInter.c] + +  SystemName  [ABC: Logic synthesis and verification system.] + +  PackageName [SAT sat_solver.] + +  Synopsis    [Interpolation package.] + +  Author      [Alan Mishchenko] +   +  Affiliation [UC Berkeley] + +  Date        [Ver. 1.0. Started - June 20, 2005.] + +  Revision    [$Id: satInter.c,v 1.4 2005/09/16 22:55:03 casem Exp $] + +***********************************************************************/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <time.h> +#include "satStore.h" +#include "aig.h" + +//////////////////////////////////////////////////////////////////////// +///                        DECLARATIONS                              /// +//////////////////////////////////////////////////////////////////////// + +// variable assignments  +static const lit    LIT_UNDEF = 0xffffffff; + +// interpolation manager +struct Inta_Man_t_ +{ +    // clauses of the problems +    Sto_Man_t *     pCnf;         // the set of CNF clauses for A and B +    Vec_Int_t *     vVarsAB;      // the array of global variables +    // various parameters +    int             fVerbose;     // verbosiness flag +    int             fProofVerif;  // verifies the proof +    int             fProofWrite;  // writes the proof file +    int             nVarsAlloc;   // the allocated size of var arrays +    int             nClosAlloc;   // the allocated size of clause arrays +    // internal BCP +    int             nRootSize;    // the number of root level assignments +    int             nTrailSize;   // the number of assignments made  +    lit *           pTrail;       // chronological order of assignments (size nVars) +    lit *           pAssigns;     // assignments by variable (size nVars)  +    char *          pSeens;       // temporary mark (size nVars) +    Sto_Cls_t **    pReasons;     // reasons for each assignment (size nVars)           +    Sto_Cls_t **    pWatches;     // watched clauses for each literal (size 2*nVars)           +    // interpolation data +    Aig_Man_t *     pAig;         // the AIG manager for recording the interpolant +    int *           pVarTypes;    // variable type (size nVars) [1=A, 0=B, <0=AB] +    Aig_Obj_t **    pInters;      // storage for interpolants as truth tables (size nClauses) +    int             nIntersAlloc; // the allocated size of truth table array +    // proof recording +    int             Counter;      // counter of resolved clauses +    int *           pProofNums;   // the proof numbers for each clause (size nClauses) +    FILE *          pFile;        // the file for proof recording +    // internal verification +    lit *           pResLits;     // the literals of the resolvent    +    int             nResLits;     // the number of literals of the resolvent +    int             nResLitsAlloc;// the number of literals of the resolvent +    // runtime stats +    int             timeBcp;      // the runtime for BCP +    int             timeTrace;    // the runtime of trace construction +    int             timeTotal;    // the total runtime of interpolation +}; + +// procedure to get hold of the clauses' truth table  +static inline Aig_Obj_t ** Inta_ManAigRead( Inta_Man_t * pMan, Sto_Cls_t * pCls )                   { return pMan->pInters + pCls->Id;          } +static inline void         Inta_ManAigClear( Inta_Man_t * pMan, Aig_Obj_t ** p )                    { *p = Aig_ManConst0(pMan->pAig);           } +static inline void         Inta_ManAigFill( Inta_Man_t * pMan, Aig_Obj_t ** p )                     { *p = Aig_ManConst1(pMan->pAig);           } +static inline void         Inta_ManAigCopy( Inta_Man_t * pMan, Aig_Obj_t ** p, Aig_Obj_t ** q )     { *p = *q;                                  } +static inline void         Inta_ManAigAnd( Inta_Man_t * pMan, Aig_Obj_t ** p, Aig_Obj_t ** q )      { *p = Aig_And(pMan->pAig, *p, *q);         } +static inline void         Inta_ManAigOr( Inta_Man_t * pMan, Aig_Obj_t ** p, Aig_Obj_t ** q )       { *p = Aig_Or(pMan->pAig, *p, *q);          } +static inline void         Inta_ManAigOrNot( Inta_Man_t * pMan, Aig_Obj_t ** p, Aig_Obj_t ** q )    { *p = Aig_Or(pMan->pAig, *p, Aig_Not(*q)); } +static inline void         Inta_ManAigOrVar( Inta_Man_t * pMan, Aig_Obj_t ** p, int v )             { *p = Aig_Or(pMan->pAig, *p, Aig_IthVar(pMan->pAig, v));          } +static inline void         Inta_ManAigOrNotVar( Inta_Man_t * pMan, Aig_Obj_t ** p, int v )          { *p = Aig_Or(pMan->pAig, *p, Aig_Not(Aig_IthVar(pMan->pAig, v))); } + +// reading/writing the proof for a clause +static inline int          Inta_ManProofGet( Inta_Man_t * p, Sto_Cls_t * pCls )                  { return p->pProofNums[pCls->Id];           } +static inline void         Inta_ManProofSet( Inta_Man_t * p, Sto_Cls_t * pCls, int n )           { p->pProofNums[pCls->Id] = n;              } + +//////////////////////////////////////////////////////////////////////// +///                     FUNCTION DEFINITIONS                         /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + +  Synopsis    [Allocate proof manager.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Inta_Man_t * Inta_ManAlloc() +{ +    Inta_Man_t * p; +    // allocate the manager +    p = (Inta_Man_t *)malloc( sizeof(Inta_Man_t) ); +    memset( p, 0, sizeof(Inta_Man_t) ); +    // verification +    p->nResLitsAlloc = (1<<16); +    p->pResLits = malloc( sizeof(lit) * p->nResLitsAlloc ); +    // parameters +    p->fProofWrite = 0; +    p->fProofVerif = 1; +    return p;     +} + +/**Function************************************************************* + +  Synopsis    [Count common variables in the clauses of A and B.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Inta_ManGlobalVars( Inta_Man_t * p ) +{ +    Sto_Cls_t * pClause; +    int LargeNum = -100000000; +    int Var, nVarsAB, v; + +    // mark the variable encountered in the clauses of A +    Sto_ManForEachClauseRoot( p->pCnf, pClause ) +    { +        if ( !pClause->fA ) +            break; +        for ( v = 0; v < (int)pClause->nLits; v++ ) +            p->pVarTypes[lit_var(pClause->pLits[v])] = 1; +    } + +    // check variables that appear in clauses of B +    nVarsAB = 0; +    Sto_ManForEachClauseRoot( p->pCnf, pClause ) +    { +        if ( pClause->fA ) +            continue; +        for ( v = 0; v < (int)pClause->nLits; v++ ) +        { +            Var = lit_var(pClause->pLits[v]); +            if ( p->pVarTypes[Var] == 1 ) // var of A +            { +                // change it into a global variable +                nVarsAB++; +                p->pVarTypes[Var] = LargeNum; +            } +        } +    } +    assert( nVarsAB <= Vec_IntSize(p->vVarsAB) ); + +    // order global variables +    nVarsAB = 0; +    Vec_IntForEachEntry( p->vVarsAB, Var, v ) +        p->pVarTypes[Var] = -(1+nVarsAB++); + +    // check that there is no extra global variables +    for ( v = 0; v < p->pCnf->nVars; v++ ) +        assert( p->pVarTypes[v] != LargeNum ); +    return nVarsAB; +} + +/**Function************************************************************* + +  Synopsis    [Resize proof manager.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Inta_ManResize( Inta_Man_t * p ) +{ +    // check if resizing is needed +    if ( p->nVarsAlloc < p->pCnf->nVars ) +    { +        // find the new size +        if ( p->nVarsAlloc == 0 ) +            p->nVarsAlloc = 1; +        while ( p->nVarsAlloc < p->pCnf->nVars )  +            p->nVarsAlloc *= 2; +        // resize the arrays +        p->pTrail    = (lit *)       realloc( p->pTrail,    sizeof(lit) * p->nVarsAlloc ); +        p->pAssigns  = (lit *)       realloc( p->pAssigns,  sizeof(lit) * p->nVarsAlloc ); +        p->pSeens    = (char *)      realloc( p->pSeens,    sizeof(char) * p->nVarsAlloc ); +        p->pVarTypes = (int *)       realloc( p->pVarTypes, sizeof(int) * p->nVarsAlloc ); +        p->pReasons  = (Sto_Cls_t **)realloc( p->pReasons,  sizeof(Sto_Cls_t *) * p->nVarsAlloc ); +        p->pWatches  = (Sto_Cls_t **)realloc( p->pWatches,  sizeof(Sto_Cls_t *) * p->nVarsAlloc*2 ); +    } + +    // clean the free space +    memset( p->pAssigns , 0xff, sizeof(lit) * p->pCnf->nVars ); +    memset( p->pSeens   , 0,    sizeof(char) * p->pCnf->nVars ); +    memset( p->pVarTypes, 0,    sizeof(int) * p->pCnf->nVars ); +    memset( p->pReasons , 0,    sizeof(Sto_Cls_t *) * p->pCnf->nVars ); +    memset( p->pWatches , 0,    sizeof(Sto_Cls_t *) * p->pCnf->nVars*2 ); + +    // compute the number of common variables +    Inta_ManGlobalVars( p ); + +    // check if resizing of clauses is needed +    if ( p->nClosAlloc < p->pCnf->nClauses ) +    { +        // find the new size +        if ( p->nClosAlloc == 0 ) +            p->nClosAlloc = 1; +        while ( p->nClosAlloc < p->pCnf->nClauses )  +            p->nClosAlloc *= 2; +        // resize the arrays +        p->pProofNums = (int *) realloc( p->pProofNums,  sizeof(int) * p->nClosAlloc ); +    } +    memset( p->pProofNums, 0, sizeof(int) * p->pCnf->nClauses ); + +    // check if resizing of truth tables is needed +    if ( p->nIntersAlloc < p->pCnf->nClauses ) +    { +        p->nIntersAlloc = p->pCnf->nClauses; +        p->pInters = (Aig_Obj_t **) realloc( p->pInters, sizeof(Aig_Obj_t *) * p->nIntersAlloc ); +    } +    memset( p->pInters, 0, sizeof(Aig_Obj_t *) * p->pCnf->nClauses ); +} + +/**Function************************************************************* + +  Synopsis    [Deallocate proof manager.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Inta_ManFree( Inta_Man_t * p ) +{ +/* +    printf( "Runtime stats:\n" ); +PRT( "BCP     ", p->timeBcp   ); +PRT( "Trace   ", p->timeTrace ); +PRT( "TOTAL   ", p->timeTotal ); +*/ +    free( p->pInters ); +    free( p->pProofNums ); +    free( p->pTrail ); +    free( p->pAssigns ); +    free( p->pSeens ); +    free( p->pVarTypes ); +    free( p->pReasons ); +    free( p->pWatches ); +    free( p->pResLits ); +    free( p ); +} + + + + +/**Function************************************************************* + +  Synopsis    [Prints the clause.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Inta_ManPrintClause( Inta_Man_t * p, Sto_Cls_t * pClause ) +{ +    int i; +    printf( "Clause ID = %d. Proof = %d. {", pClause->Id, Inta_ManProofGet(p, pClause) ); +    for ( i = 0; i < (int)pClause->nLits; i++ ) +        printf( " %d", pClause->pLits[i] ); +    printf( " }\n" ); +} + +/**Function************************************************************* + +  Synopsis    [Prints the resolvent.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Inta_ManPrintResolvent( lit * pResLits, int nResLits ) +{ +    int i; +    printf( "Resolvent: {" ); +    for ( i = 0; i < nResLits; i++ ) +        printf( " %d", pResLits[i] ); +    printf( " }\n" ); +} + +/**Function************************************************************* + +  Synopsis    [Prints the interpolant for one clause.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Inta_ManPrintInterOne( Inta_Man_t * p, Sto_Cls_t * pClause ) +{ +    printf( "Clause %2d :  ", pClause->Id ); +//    Extra_PrintBinary___( stdout, Inta_ManAigRead(p, pClause), (1 << p->nVarsAB) ); +    printf( "\n" ); +} + + + +/**Function************************************************************* + +  Synopsis    [Adds one clause to the watcher list.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Inta_ManWatchClause( Inta_Man_t * p, Sto_Cls_t * pClause, lit Lit ) +{ +    assert( lit_check(Lit, p->pCnf->nVars) ); +    if ( pClause->pLits[0] == Lit ) +        pClause->pNext0 = p->pWatches[lit_neg(Lit)];   +    else +    { +        assert( pClause->pLits[1] == Lit ); +        pClause->pNext1 = p->pWatches[lit_neg(Lit)];   +    } +    p->pWatches[lit_neg(Lit)] = pClause; +} + + +/**Function************************************************************* + +  Synopsis    [Records implication.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline int Inta_ManEnqueue( Inta_Man_t * p, lit Lit, Sto_Cls_t * pReason ) +{ +    int Var = lit_var(Lit); +    if ( p->pAssigns[Var] != LIT_UNDEF ) +        return p->pAssigns[Var] == Lit; +    p->pAssigns[Var] = Lit; +    p->pReasons[Var] = pReason; +    p->pTrail[p->nTrailSize++] = Lit; +//printf( "assigning var %d value %d\n", Var, !lit_sign(Lit) ); +    return 1; +} + +/**Function************************************************************* + +  Synopsis    [Records implication.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Inta_ManCancelUntil( Inta_Man_t * p, int Level ) +{ +    lit Lit; +    int i, Var; +    for ( i = p->nTrailSize - 1; i >= Level; i-- ) +    { +        Lit = p->pTrail[i]; +        Var = lit_var( Lit ); +        p->pReasons[Var] = NULL; +        p->pAssigns[Var] = LIT_UNDEF; +//printf( "cancelling var %d\n", Var ); +    } +    p->nTrailSize = Level; +} + +/**Function************************************************************* + +  Synopsis    [Propagate one assignment.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline Sto_Cls_t * Inta_ManPropagateOne( Inta_Man_t * p, lit Lit ) +{ +    Sto_Cls_t ** ppPrev, * pCur, * pTemp; +    lit LitF = lit_neg(Lit); +    int i; +    // iterate through the literals +    ppPrev = p->pWatches + Lit; +    for ( pCur = p->pWatches[Lit]; pCur; pCur = *ppPrev ) +    { +        // make sure the false literal is in the second literal of the clause +        if ( pCur->pLits[0] == LitF ) +        { +            pCur->pLits[0] = pCur->pLits[1]; +            pCur->pLits[1] = LitF; +            pTemp = pCur->pNext0; +            pCur->pNext0 = pCur->pNext1; +            pCur->pNext1 = pTemp; +        } +        assert( pCur->pLits[1] == LitF ); + +        // if the first literal is true, the clause is satisfied +        if ( pCur->pLits[0] == p->pAssigns[lit_var(pCur->pLits[0])] ) +        { +            ppPrev = &pCur->pNext1; +            continue; +        } + +        // look for a new literal to watch +        for ( i = 2; i < (int)pCur->nLits; i++ ) +        { +            // skip the case when the literal is false +            if ( lit_neg(pCur->pLits[i]) == p->pAssigns[lit_var(pCur->pLits[i])] ) +                continue; +            // the literal is either true or unassigned - watch it +            pCur->pLits[1] = pCur->pLits[i]; +            pCur->pLits[i] = LitF; +            // remove this clause from the watch list of Lit +            *ppPrev = pCur->pNext1; +            // add this clause to the watch list of pCur->pLits[i] (now it is pCur->pLits[1]) +            Inta_ManWatchClause( p, pCur, pCur->pLits[1] ); +            break; +        } +        if ( i < (int)pCur->nLits ) // found new watch +            continue; + +        // clause is unit - enqueue new implication +        if ( Inta_ManEnqueue(p, pCur->pLits[0], pCur) ) +        { +            ppPrev = &pCur->pNext1; +            continue; +        } + +        // conflict detected - return the conflict clause +        return pCur; +    } +    return NULL; +} + +/**Function************************************************************* + +  Synopsis    [Propagate the current assignments.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Sto_Cls_t * Inta_ManPropagate( Inta_Man_t * p, int Start ) +{ +    Sto_Cls_t * pClause; +    int i; +    int clk = clock(); +    for ( i = Start; i < p->nTrailSize; i++ ) +    { +        pClause = Inta_ManPropagateOne( p, p->pTrail[i] ); +        if ( pClause ) +        { +p->timeBcp += clock() - clk; +            return pClause; +        } +    } +p->timeBcp += clock() - clk; +    return NULL; +} + + +/**Function************************************************************* + +  Synopsis    [Writes one root clause into a file.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Inta_ManProofWriteOne( Inta_Man_t * p, Sto_Cls_t * pClause ) +{ +    Inta_ManProofSet( p, pClause, ++p->Counter ); + +    if ( p->fProofWrite ) +    { +        int v; +        fprintf( p->pFile, "%d", Inta_ManProofGet(p, pClause) ); +        for ( v = 0; v < (int)pClause->nLits; v++ ) +            fprintf( p->pFile, " %d", lit_print(pClause->pLits[v]) ); +        fprintf( p->pFile, " 0 0\n" ); +    } +} + +/**Function************************************************************* + +  Synopsis    [Traces the proof for one clause.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Inta_ManProofTraceOne( Inta_Man_t * p, Sto_Cls_t * pConflict, Sto_Cls_t * pFinal ) +{ +    Sto_Cls_t * pReason; +    int i, v, Var, PrevId; +    int fPrint = 0; +    int clk = clock(); + +    // collect resolvent literals +    if ( p->fProofVerif ) +    { +        assert( (int)pConflict->nLits <= p->nResLitsAlloc ); +        memcpy( p->pResLits, pConflict->pLits, sizeof(lit) * pConflict->nLits ); +        p->nResLits = pConflict->nLits; +    } + +    // mark all the variables in the conflict as seen +    for ( v = 0; v < (int)pConflict->nLits; v++ ) +        p->pSeens[lit_var(pConflict->pLits[v])] = 1; + +    // start the anticedents +//    pFinal->pAntis = Vec_PtrAlloc( 32 ); +//    Vec_PtrPush( pFinal->pAntis, pConflict ); + +    if ( p->pCnf->nClausesA ) +        Inta_ManAigCopy( p, Inta_ManAigRead(p, pFinal), Inta_ManAigRead(p, pConflict) ); + +    // follow the trail backwards +    PrevId = Inta_ManProofGet(p, pConflict); +    for ( i = p->nTrailSize - 1; i >= 0; i-- ) +    { +        // skip literals that are not involved +        Var = lit_var(p->pTrail[i]); +        if ( !p->pSeens[Var] ) +            continue; +        p->pSeens[Var] = 0; + +        // skip literals of the resulting clause +        pReason = p->pReasons[Var]; +        if ( pReason == NULL ) +            continue; +        assert( p->pTrail[i] == pReason->pLits[0] ); + +        // add the variables to seen +        for ( v = 1; v < (int)pReason->nLits; v++ ) +            p->pSeens[lit_var(pReason->pLits[v])] = 1; + +        // record the reason clause +        assert( Inta_ManProofGet(p, pReason) > 0 ); +        p->Counter++; +        if ( p->fProofWrite ) +            fprintf( p->pFile, "%d * %d %d 0\n", p->Counter, PrevId, Inta_ManProofGet(p, pReason) ); +        PrevId = p->Counter; + +        if ( p->pCnf->nClausesA ) +        { +            if ( p->pVarTypes[Var] == 1 ) // var of A +                Inta_ManAigOr( p, Inta_ManAigRead(p, pFinal), Inta_ManAigRead(p, pReason) ); +            else +                Inta_ManAigAnd( p, Inta_ManAigRead(p, pFinal), Inta_ManAigRead(p, pReason) ); +        } +  +        // resolve the temporary resolvent with the reason clause +        if ( p->fProofVerif ) +        { +            int v1, v2;  +            if ( fPrint ) +                Inta_ManPrintResolvent( p->pResLits, p->nResLits ); +            // check that the var is present in the resolvent +            for ( v1 = 0; v1 < p->nResLits; v1++ ) +                if ( lit_var(p->pResLits[v1]) == Var ) +                    break; +            if ( v1 == p->nResLits ) +                printf( "Recording clause %d: Cannot find variable %d in the temporary resolvent.\n", pFinal->Id, Var ); +            if ( p->pResLits[v1] != lit_neg(pReason->pLits[0]) ) +                printf( "Recording clause %d: The resolved variable %d is in the wrong polarity.\n", pFinal->Id, Var ); +            // remove this variable from the resolvent +            assert( lit_var(p->pResLits[v1]) == Var ); +            p->nResLits--; +            for ( ; v1 < p->nResLits; v1++ ) +                p->pResLits[v1] = p->pResLits[v1+1]; +            // add variables of the reason clause +            for ( v2 = 1; v2 < (int)pReason->nLits; v2++ ) +            { +                for ( v1 = 0; v1 < p->nResLits; v1++ ) +                    if ( lit_var(p->pResLits[v1]) == lit_var(pReason->pLits[v2]) ) +                        break; +                // if it is a new variable, add it to the resolvent +                if ( v1 == p->nResLits )  +                { +                    if ( p->nResLits == p->nResLitsAlloc ) +                        printf( "Recording clause %d: Ran out of space for intermediate resolvent.\n", pFinal->Id ); +                    p->pResLits[ p->nResLits++ ] = pReason->pLits[v2]; +                    continue; +                } +                // if the variable is the same, the literal should be the same too +                if ( p->pResLits[v1] == pReason->pLits[v2] ) +                    continue; +                // the literal is different +                printf( "Recording clause %d: Trying to resolve the clause with more than one opposite literal.\n", pFinal->Id ); +            } +        } +//        Vec_PtrPush( pFinal->pAntis, pReason ); +    } + +    // unmark all seen variables +//    for ( i = p->nTrailSize - 1; i >= 0; i-- ) +//        p->pSeens[lit_var(p->pTrail[i])] = 0; +    // check that the literals are unmarked +//    for ( i = p->nTrailSize - 1; i >= 0; i-- ) +//        assert( p->pSeens[lit_var(p->pTrail[i])] == 0 ); + +    // use the resulting clause to check the correctness of resolution +    if ( p->fProofVerif ) +    { +        int v1, v2;  +        if ( fPrint ) +            Inta_ManPrintResolvent( p->pResLits, p->nResLits ); +        for ( v1 = 0; v1 < p->nResLits; v1++ ) +        { +            for ( v2 = 0; v2 < (int)pFinal->nLits; v2++ ) +                if ( pFinal->pLits[v2] == p->pResLits[v1] ) +                    break; +            if ( v2 < (int)pFinal->nLits ) +                continue; +            break; +        } +        if ( v1 < p->nResLits ) +        { +            printf( "Recording clause %d: The final resolvent is wrong.\n", pFinal->Id ); +            Inta_ManPrintClause( p, pConflict ); +            Inta_ManPrintResolvent( p->pResLits, p->nResLits ); +            Inta_ManPrintClause( p, pFinal ); +        } + +        // if there are literals in the clause that are not in the resolvent +        // it means that the derived resolvent is stronger than the clause +        // we can replace the clause with the resolvent by removing these literals +        if ( p->nResLits != (int)pFinal->nLits ) +        { +            for ( v1 = 0; v1 < (int)pFinal->nLits; v1++ ) +            { +                for ( v2 = 0; v2 < p->nResLits; v2++ ) +                    if ( pFinal->pLits[v1] == p->pResLits[v2] ) +                        break; +                if ( v2 < p->nResLits ) +                    continue; +                // remove literal v1 from the final clause +                pFinal->nLits--; +                for ( v2 = v1; v2 < (int)pFinal->nLits; v2++ ) +                    pFinal->pLits[v2] = pFinal->pLits[v2+1]; +                v1--; +            } +            assert( p->nResLits == (int)pFinal->nLits ); +        } +    } +p->timeTrace += clock() - clk; + +    // return the proof pointer  +    if ( p->pCnf->nClausesA ) +    { +//        Inta_ManPrintInterOne( p, pFinal ); +    } +    Inta_ManProofSet( p, pFinal, p->Counter ); +    return p->Counter; +} + +/**Function************************************************************* + +  Synopsis    [Records the proof for one clause.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Inta_ManProofRecordOne( Inta_Man_t * p, Sto_Cls_t * pClause ) +{ +    Sto_Cls_t * pConflict; +    int i; + +    // empty clause never ends up there +    assert( pClause->nLits > 0 ); +    if ( pClause->nLits == 0 ) +        printf( "Error: Empty clause is attempted.\n" ); + +    assert( !pClause->fRoot ); +    assert( p->nTrailSize == p->nRootSize ); + +    // if any of the clause literals are already assumed +    // it means that the clause is redundant and can be skipped +    for ( i = 0; i < (int)pClause->nLits; i++ ) +        if ( p->pAssigns[lit_var(pClause->pLits[i])] == pClause->pLits[i] ) +            return 1; + +    // add assumptions to the trail +    for ( i = 0; i < (int)pClause->nLits; i++ ) +        if ( !Inta_ManEnqueue( p, lit_neg(pClause->pLits[i]), NULL ) ) +        { +            assert( 0 ); // impossible +            return 0; +        } + +    // propagate the assumptions +    pConflict = Inta_ManPropagate( p, p->nRootSize ); +    if ( pConflict == NULL ) +    { +        assert( 0 ); // cannot prove +        return 0; +    } + +    // construct the proof +    Inta_ManProofTraceOne( p, pConflict, pClause ); + +    // undo to the root level +    Inta_ManCancelUntil( p, p->nRootSize ); + +    // add large clauses to the watched lists +    if ( pClause->nLits > 1 ) +    { +        Inta_ManWatchClause( p, pClause, pClause->pLits[0] ); +        Inta_ManWatchClause( p, pClause, pClause->pLits[1] ); +        return 1; +    } +    assert( pClause->nLits == 1 ); + +    // if the clause proved is unit, add it and propagate +    if ( !Inta_ManEnqueue( p, pClause->pLits[0], pClause ) ) +    { +        assert( 0 ); // impossible +        return 0; +    } + +    // propagate the assumption +    pConflict = Inta_ManPropagate( p, p->nRootSize ); +    if ( pConflict ) +    { +        // construct the proof +        Inta_ManProofTraceOne( p, pConflict, p->pCnf->pEmpty ); +//        if ( p->fVerbose ) +//            printf( "Found last conflict after adding unit clause number %d!\n", pClause->Id ); +        return 0; +    } + +    // update the root level +    p->nRootSize = p->nTrailSize; +    return 1; +} + +/**Function************************************************************* + +  Synopsis    [Propagate the root clauses.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Inta_ManProcessRoots( Inta_Man_t * p ) +{ +    Sto_Cls_t * pClause; +    int Counter; + +    // make sure the root clauses are preceeding the learnt clauses +    Counter = 0; +    Sto_ManForEachClause( p->pCnf, pClause ) +    { +        assert( (int)pClause->fA    == (Counter < (int)p->pCnf->nClausesA) ); +        assert( (int)pClause->fRoot == (Counter < (int)p->pCnf->nRoots)    ); +        Counter++; +    } +    assert( p->pCnf->nClauses == Counter ); + +    // make sure the last clause if empty +    assert( p->pCnf->pTail->nLits == 0 ); + +    // go through the root unit clauses +    p->nTrailSize = 0; +    Sto_ManForEachClauseRoot( p->pCnf, pClause ) +    { +        // create watcher lists for the root clauses +        if ( pClause->nLits > 1 ) +        { +            Inta_ManWatchClause( p, pClause, pClause->pLits[0] ); +            Inta_ManWatchClause( p, pClause, pClause->pLits[1] ); +        } +        // empty clause and large clauses +        if ( pClause->nLits != 1 ) +            continue; +        // unit clause +        assert( lit_check(pClause->pLits[0], p->pCnf->nVars) ); +        if ( !Inta_ManEnqueue( p, pClause->pLits[0], pClause ) ) +        { +            // detected root level conflict +//            printf( "Error in Inta_ManProcessRoots(): Detected a root-level conflict too early!\n" ); +//            assert( 0 ); +            // detected root level conflict +            Inta_ManProofTraceOne( p, pClause, p->pCnf->pEmpty ); +            if ( p->fVerbose ) +                printf( "Found root level conflict!\n" ); +            return 0; +        } +    } + +    // propagate the root unit clauses +    pClause = Inta_ManPropagate( p, 0 ); +    if ( pClause ) +    { +        // detected root level conflict +        Inta_ManProofTraceOne( p, pClause, p->pCnf->pEmpty ); +        if ( p->fVerbose ) +            printf( "Found root level conflict!\n" ); +        return 0; +    } + +    // set the root level +    p->nRootSize = p->nTrailSize; +    return 1; +} + +/**Function************************************************************* + +  Synopsis    [Records the proof.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Inta_ManPrepareInter( Inta_Man_t * p ) +{ +    Sto_Cls_t * pClause; +    int Var, VarAB, v; + +    // set interpolants for root clauses +    Sto_ManForEachClauseRoot( p->pCnf, pClause ) +    { +        if ( !pClause->fA ) // clause of B +        { +            Inta_ManAigFill( p, Inta_ManAigRead(p, pClause) ); +//            Inta_ManPrintInterOne( p, pClause ); +            continue; +        } +        // clause of A +        Inta_ManAigClear( p, Inta_ManAigRead(p, pClause) ); +        for ( v = 0; v < (int)pClause->nLits; v++ ) +        { +            Var = lit_var(pClause->pLits[v]); +            if ( p->pVarTypes[Var] < 0 ) // global var +            { +                VarAB = -p->pVarTypes[Var]-1; +                assert( VarAB >= 0 && VarAB < Vec_IntSize(p->vVarsAB) ); +                if ( lit_sign(pClause->pLits[v]) ) // negative var +                    Inta_ManAigOrNotVar( p, Inta_ManAigRead(p, pClause), VarAB ); +                else +                    Inta_ManAigOrVar( p, Inta_ManAigRead(p, pClause), VarAB ); +            } +        } +//        Inta_ManPrintInterOne( p, pClause ); +    } +} + +/**Function************************************************************* + +  Synopsis    [Computes interpolant for the given CNF.] + +  Description [Takes the interpolation manager, the CNF deriving by the SAT +  solver, which includes ClausesA, ClausesB, and learned clauses. Additional +  arguments are the vector of variables common to AB and the verbosiness flag. +  Returns the AIG manager with a single output, containing the interpolant.] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void * Inta_ManInterpolate( Inta_Man_t * p, Sto_Man_t * pCnf, void * vVarsAB, int fVerbose ) +{ +    Aig_Man_t * pRes; +    Aig_Obj_t * pObj; +    Sto_Cls_t * pClause; +    int RetValue = 1; +    int clkTotal = clock(); + +    // check that the CNF makes sense +    assert( pCnf->nVars > 0 && pCnf->nClauses > 0 ); +    p->pCnf = pCnf; +    p->fVerbose = fVerbose; +    p->vVarsAB = vVarsAB; +    p->pAig = pRes = Aig_ManStart( 10000 ); +    Aig_IthVar( p->pAig, Vec_IntSize(p->vVarsAB) - 1 ); + +    // adjust the manager +    Inta_ManResize( p ); + +    // prepare the interpolant computation +    Inta_ManPrepareInter( p ); + +    // construct proof for each clause +    // start the proof +    if ( p->fProofWrite ) +    { +        p->pFile = fopen( "proof.cnf_", "w" ); +        p->Counter = 0; +    } + +    // write the root clauses +    Sto_ManForEachClauseRoot( p->pCnf, pClause ) +        Inta_ManProofWriteOne( p, pClause ); + +    // propagate root level assignments +    if ( Inta_ManProcessRoots( p ) ) +    { +        // if there is no conflict, consider learned clauses +        Sto_ManForEachClause( p->pCnf, pClause ) +        { +            if ( pClause->fRoot ) +                continue; +            if ( !Inta_ManProofRecordOne( p, pClause ) ) +            { +                RetValue = 0; +                break; +            } +        } +    } + +    // stop the proof +    if ( p->fProofWrite ) +    {  +        fclose( p->pFile ); +        p->pFile = NULL;     +    } + +    if ( fVerbose ) +    { +//        PRT( "Interpo", clock() - clkTotal ); +    printf( "Vars = %d. Roots = %d. Learned = %d. Resol steps = %d.  Ave = %.2f.  Mem = %.2f Mb\n",  +        p->pCnf->nVars, p->pCnf->nRoots, p->pCnf->nClauses-p->pCnf->nRoots, p->Counter,   +        1.0*(p->Counter-p->pCnf->nRoots)/(p->pCnf->nClauses-p->pCnf->nRoots),  +        1.0*Sto_ManMemoryReport(p->pCnf)/(1<<20) ); +p->timeTotal += clock() - clkTotal; +    } + +    pObj = *Inta_ManAigRead( p, p->pCnf->pTail ); +    Aig_ObjCreatePo( pRes, pObj ); +    Aig_ManCleanup( pRes ); + +    p->pAig = NULL; +    return pRes; +     +} + + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Aig_Man_t * Inta_ManDeriveClauses( Inta_Man_t * pMan, Sto_Man_t * pCnf, int fClausesA ) +{ +    Aig_Man_t * p; +    Aig_Obj_t * pMiter, * pSum, * pLit; +    Sto_Cls_t * pClause; +    int Var, VarAB, v; +    p = Aig_ManStart( 10000 ); +    pMiter = Aig_ManConst1(p); +    Sto_ManForEachClauseRoot( pCnf, pClause ) +    { +        if ( fClausesA ^ pClause->fA ) // clause of B +            continue; +        // clause of A +        pSum = Aig_ManConst0(p); +        for ( v = 0; v < (int)pClause->nLits; v++ ) +        { +            Var = lit_var(pClause->pLits[v]); +            if ( pMan->pVarTypes[Var] < 0 ) // global var +            { +                VarAB = -pMan->pVarTypes[Var]-1; +                assert( VarAB >= 0 && VarAB < Vec_IntSize(pMan->vVarsAB) ); +                pLit = Aig_NotCond( Aig_IthVar(p, VarAB), lit_sign(pClause->pLits[v]) ); +            } +            else +                pLit = Aig_NotCond( Aig_IthVar(p, Vec_IntSize(pMan->vVarsAB)+1+Var), lit_sign(pClause->pLits[v]) ); +            pSum = Aig_Or( p, pSum, pLit ); +        } +        pMiter = Aig_And( p, pMiter, pSum ); +    } +    Aig_ObjCreatePo( p, pMiter ); +    return p; +} + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/sat/bsat/satInterA_yu_hu.c b/src/sat/bsat/satInterA_yu_hu.c index 2005e558..aa2289f2 100644 --- a/src/sat/bsat/satInterA_yu_hu.c +++ b/src/sat/bsat/satInterA_yu_hu.c @@ -114,6 +114,7 @@ Inta_Man_t * Inta_ManAlloc()      // parameters      p->fProofWrite = 1;      p->fProofVerif = 1; +      return p;      } @@ -289,16 +290,6 @@ void Inta_ManPrintClause( Inta_Man_t * p, Sto_Cls_t * pClause )      printf( " }\n" );  } -// Yu Hu -void Inta_ManPrintClauseEx( lit * pResLits, int nResLits ) -{ -    int i; -    printf( " {" ); -    for ( i = 0; i < nResLits; i++ ) -        printf( " %d", lit_print(pResLits[i]) ); -    printf( " }\n" ); -} -  /**Function*************************************************************    Synopsis    [Prints the resolvent.] @@ -315,6 +306,8 @@ void Inta_ManPrintResolvent( lit * pResLits, int nResLits )      int i;      printf( "Resolvent: {" );      for ( i = 0; i < nResLits; i++ ) +        // Yu Hu +        // printf( " %d", pResLits[i] );          printf( " %d", lit_print(pResLits[i]) );      printf( " }\n" );  } @@ -537,6 +530,17 @@ void Inta_ManProofWriteOne( Inta_Man_t * p, Sto_Cls_t * pClause )      }  } +// Yu Hu +void Inta_ManPrintClauseEx( lit * pResLits, int nResLits ) +{ +    int i; +    printf( " {" ); +    for ( i = 0; i < nResLits; i++ ) +        printf( " %d", lit_print(pResLits[i]) ); +    printf( " }\n" ); +} + +  /**Function*************************************************************    Synopsis    [Traces the proof for one clause.] @@ -594,7 +598,6 @@ int Inta_ManProofTraceOne( Inta_Man_t * p, Sto_Cls_t * pConflict, Sto_Cls_t * pF          for ( v = 1; v < (int)pReason->nLits; v++ )              p->pSeens[lit_var(pReason->pLits[v])] = 1; -          // record the reason clause          assert( Inta_ManProofGet(p, pReason) > 0 );          p->Counter++; @@ -617,14 +620,15 @@ int Inta_ManProofTraceOne( Inta_Man_t * p, Sto_Cls_t * pConflict, Sto_Cls_t * pF          if ( p->fProofVerif )          {              int v1, v2;  +              // Yu Hu -//            if ( fPrint ) -//                Inta_ManPrintResolvent( p->pResLits, p->nResLits ); -            if ( fPrint ) { -                printf("pivot = %d,\n", lit_print(p->pTrail[i])); -                Inta_ManPrintClauseEx( p->pResLits, p->nResLits); -            } -  +            // if ( fPrint ) +            //     Inta_ManPrintResolvent( p->pResLits, p->nResLits ); +            if ( fPrint ) {                                                                                                 +                printf("pivot = %d,\n", lit_print(p->pTrail[i]));                                                           +                Inta_ManPrintClauseEx( p->pResLits, p->nResLits);                                                           +            }                                                           +              // check that the var is present in the resolvent              for ( v1 = 0; v1 < p->nResLits; v1++ )                  if ( lit_var(p->pResLits[v1]) == Var ) @@ -660,12 +664,12 @@ int Inta_ManProofTraceOne( Inta_Man_t * p, Sto_Cls_t * pConflict, Sto_Cls_t * pF              }              // Yu Hu -            if ( fPrint ) { -                Inta_ManPrintClauseEx( pReason->pLits, pReason->nLits); -                Inta_ManPrintResolvent( p->pResLits, p->nResLits ); -            } -        } +            if ( fPrint ) {                                                                                                 +                Inta_ManPrintClauseEx( pReason->pLits, pReason->nLits);                                                     +                Inta_ManPrintResolvent( p->pResLits, p->nResLits);                                                         +            }             +        }  //        Vec_PtrPush( pFinal->pAntis, pReason );      } @@ -680,10 +684,11 @@ int Inta_ManProofTraceOne( Inta_Man_t * p, Sto_Cls_t * pConflict, Sto_Cls_t * pF      if ( p->fProofVerif )      {          int v1, v2;  -        if ( fPrint ){ -            // Yu Hu + +        // Yu Hu +//        if ( fPrint )  //            Inta_ManPrintResolvent( p->pResLits, p->nResLits ); -        } +          for ( v1 = 0; v1 < p->nResLits; v1++ )          {              for ( v2 = 0; v2 < (int)pFinal->nLits; v2++ ) @@ -700,6 +705,27 @@ int Inta_ManProofTraceOne( Inta_Man_t * p, Sto_Cls_t * pConflict, Sto_Cls_t * pF              Inta_ManPrintResolvent( p->pResLits, p->nResLits );              Inta_ManPrintClause( p, pFinal );          } + +        // if there are literals in the clause that are not in the resolvent +        // it means that the derived resolvent is stronger than the clause +        // we can replace the clause with the resolvent by removing these literals +        if ( p->nResLits != (int)pFinal->nLits ) +        { +            for ( v1 = 0; v1 < (int)pFinal->nLits; v1++ ) +            { +                for ( v2 = 0; v2 < p->nResLits; v2++ ) +                    if ( pFinal->pLits[v1] == p->pResLits[v2] ) +                        break; +                if ( v2 < p->nResLits ) +                    continue; +                // remove literal v1 from the final clause +                pFinal->nLits--; +                for ( v2 = v1; v2 < (int)pFinal->nLits; v2++ ) +                    pFinal->pLits[v2] = pFinal->pLits[v2+1]; +                v1--; +            } +            assert( p->nResLits == (int)pFinal->nLits ); +        }      }  p->timeTrace += clock() - clk; @@ -733,9 +759,16 @@ int Inta_ManProofRecordOne( Inta_Man_t * p, Sto_Cls_t * pClause )      if ( pClause->nLits == 0 )          printf( "Error: Empty clause is attempted.\n" ); -    // add assumptions to the trail      assert( !pClause->fRoot );      assert( p->nTrailSize == p->nRootSize ); + +    // if any of the clause literals are already assumed +    // it means that the clause is redundant and can be skipped +    for ( i = 0; i < (int)pClause->nLits; i++ ) +        if ( p->pAssigns[lit_var(pClause->pLits[i])] == pClause->pLits[i] ) +            return 1; + +    // add assumptions to the trail      for ( i = 0; i < (int)pClause->nLits; i++ )          if ( !Inta_ManEnqueue( p, lit_neg(pClause->pLits[i]), NULL ) )          { diff --git a/src/sat/lsat/solver.h b/src/sat/lsat/solver.h new file mode 100644 index 00000000..a15e42d6 --- /dev/null +++ b/src/sat/lsat/solver.h @@ -0,0 +1,124 @@ +/****************************************************************************************[solver.h] +Copyright (c) 2008, Niklas Sorensson +              2008, Koen Claessen + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +associated documentation files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, +sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT +NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +**************************************************************************************************/ + +#ifndef Minisat_solver_h +#define Minisat_solver_h + +// SolverTypes: +// +typedef struct solver_t solver; +typedef int solver_Var; +typedef int solver_Lit; +typedef int solver_lbool; + +// Constants: (can these be made inline-able?) +// + +extern const solver_lbool solver_l_True; +extern const solver_lbool solver_l_False; +extern const solver_lbool solver_l_Undef; + + +solver*      solver_new             (void); +void         solver_delete          (solver* s); +              +solver_Var   solver_newVar          (solver *s); +solver_Lit   solver_newLit          (solver *s); +              +solver_Lit   solver_mkLit           (solver_Var x); +solver_Lit   solver_mkLit_args      (solver_Var x, int sign); +solver_Lit   solver_negate          (solver_Lit p); +                                     +solver_Var   solver_var             (solver_Lit p); +int          solver_sign            (solver_Lit p); +              +int          solver_addClause       (solver *s, int len, solver_Lit *ps); +void         solver_addClause_begin (solver *s); +void         solver_addClause_addLit(solver *s, solver_Lit p); +int          solver_addClause_commit(solver *s); +              +int          solver_simplify        (solver *s); +              +int          solver_solve           (solver *s, int len, solver_Lit *ps); +void         solver_solve_begin     (solver *s); +void         solver_solve_addLit    (solver *s, solver_Lit p); +int          solver_solve_commit    (solver *s); +              +int          solver_okay            (solver *s); +              +void         solver_setPolarity     (solver *s, solver_Var v, int b); +void         solver_setDecisionVar  (solver *s, solver_Var v, int b); + +solver_lbool solver_get_l_True      (void); +solver_lbool solver_get_l_False     (void); +solver_lbool solver_get_l_Undef     (void); + +solver_lbool solver_value_Var       (solver *s, solver_Var x); +solver_lbool solver_value_Lit       (solver *s, solver_Lit p); + +solver_lbool solver_modelValue_Var  (solver *s, solver_Var x); +solver_lbool solver_modelValue_Lit  (solver *s, solver_Lit p); + +int          solver_num_assigns     (solver *s); +int          solver_num_clauses     (solver *s);      +int          solver_num_learnts     (solver *s);      +int          solver_num_vars        (solver *s);   +int          solver_num_freeVars    (solver *s); + +int          solver_conflict_len    (solver *s); +solver_Lit   solver_conflict_nthLit (solver *s, int i); + +// Setters: + +void         solver_set_verbosity   (solver *s, int v); + +// Getters: + +int          solver_num_conflicts   (solver *s); + +/* TODO + +    // Mode of operation: +    // +    int       verbosity; +    double    var_decay; +    double    clause_decay; +    double    random_var_freq; +    double    random_seed; +    double    restart_luby_start; // The factor with which the values of the luby sequence is multiplied to get the restart    (default 100) +    double    restart_luby_inc;   // The constant that the luby sequence uses powers of                                        (default 2) +    bool      expensive_ccmin;    // FIXME: describe. +    bool      rnd_pol;            // FIXME: describe. + +    int       restart_first;      // The initial restart limit.                                                                (default 100) +    double    restart_inc;        // The factor with which the restart limit is multiplied in each restart.                    (default 1.5) +    double    learntsize_factor;  // The intitial limit for learnt clauses is a factor of the original clauses.                (default 1 / 3) +    double    learntsize_inc;     // The limit for learnt clauses is multiplied with this factor each restart.                 (default 1.1) + +    int       learntsize_adjust_start_confl; +    double    learntsize_adjust_inc; + +    // Statistics: (read-only member variable) +    // +    uint64_t starts, decisions, rnd_decisions, propagations, conflicts; +    uint64_t dec_vars, clauses_literals, learnts_literals, max_literals, tot_literals; +*/ + +#endif  | 
