diff options
| author | Alan Mishchenko <alanmi@berkeley.edu> | 2017-02-18 14:20:10 -0800 | 
|---|---|---|
| committer | Alan Mishchenko <alanmi@berkeley.edu> | 2017-02-18 14:20:10 -0800 | 
| commit | 429f52ce15d1c10e71d98d8c1388b93809a425e1 (patch) | |
| tree | 9c9a388ba80ec97abbc2afcfb1c966e50cccfbc7 | |
| parent | bc010af4be920199d7f1e0bfe4a6d70dcbca042b (diff) | |
| download | abc-429f52ce15d1c10e71d98d8c1388b93809a425e1.tar.gz abc-429f52ce15d1c10e71d98d8c1388b93809a425e1.tar.bz2 abc-429f52ce15d1c10e71d98d8c1388b93809a425e1.zip | |
Experiments with SAT sweeping.
| -rw-r--r-- | abclib.dsp | 4 | ||||
| -rw-r--r-- | src/aig/gia/gia.h | 14 | ||||
| -rw-r--r-- | src/aig/gia/giaEquiv.c | 2 | ||||
| -rw-r--r-- | src/aig/gia/giaUtil.c | 19 | ||||
| -rw-r--r-- | src/base/wlc/wlcSim.c | 22 | ||||
| -rw-r--r-- | src/misc/util/utilTruth.h | 16 | ||||
| -rw-r--r-- | src/proof/cec/cecSat.c | 862 | ||||
| -rw-r--r-- | src/proof/cec/module.make | 1 | ||||
| -rw-r--r-- | src/sat/bmc/bmcGen.c | 18 | ||||
| -rw-r--r-- | src/sat/satoko/satoko.h | 2 | ||||
| -rw-r--r-- | src/sat/satoko/solver_api.c | 4 | 
11 files changed, 936 insertions, 28 deletions
| @@ -5027,6 +5027,10 @@ SOURCE=.\src\proof\cec\cecPat.c  # End Source File  # Begin Source File +SOURCE=.\src\proof\cec\cecSat.c +# End Source File +# Begin Source File +  SOURCE=.\src\proof\cec\cecSeq.c  # End Source File  # Begin Source File diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index c183432a..10804850 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -194,6 +194,7 @@ struct Gia_Man_t_      int            MappedDelay;   // delay after mapping      // bit-parallel simulation      int            iPatsPi; +    int            nSimWords;      Vec_Wrd_t *    vSims;      Vec_Wrd_t *    vSimsPi;      Vec_Int_t *    vClassOld; @@ -982,24 +983,26 @@ static inline void        Gia_ObjSetNext( Gia_Man_t * p, int Id, int Num )   { p  static inline int         Gia_ObjIsConst( Gia_Man_t * p, int Id )            { return Gia_ObjRepr(p, Id) == 0;                                   }  static inline int         Gia_ObjIsHead( Gia_Man_t * p, int Id )             { return Gia_ObjRepr(p, Id) == GIA_VOID && Gia_ObjNext(p, Id) > 0;  } -static inline int         Gia_ObjIsNone( Gia_Man_t * p, int Id )             { return Gia_ObjRepr(p, Id) == GIA_VOID && Gia_ObjNext(p, Id) == 0; } -static inline int         Gia_ObjIsTail( Gia_Man_t * p, int Id )             { return (Gia_ObjRepr(p, Id) > 0 && Gia_ObjRepr(p, Id) != GIA_VOID) && Gia_ObjNext(p, Id) == 0;                  } +static inline int         Gia_ObjIsNone( Gia_Man_t * p, int Id )             { return Gia_ObjRepr(p, Id) == GIA_VOID && Gia_ObjNext(p, Id) <= 0; } +static inline int         Gia_ObjIsTail( Gia_Man_t * p, int Id )             { return (Gia_ObjRepr(p, Id) > 0 && Gia_ObjRepr(p, Id) != GIA_VOID) && Gia_ObjNext(p, Id) <= 0;                  }  static inline int         Gia_ObjIsClass( Gia_Man_t * p, int Id )            { return (Gia_ObjRepr(p, Id) > 0 && Gia_ObjRepr(p, Id) != GIA_VOID) || Gia_ObjNext(p, Id) > 0;                   }  static inline int         Gia_ObjHasSameRepr( Gia_Man_t * p, int i, int k )  { assert( k ); return i? (Gia_ObjRepr(p, i) == Gia_ObjRepr(p, k) && Gia_ObjRepr(p, i) != GIA_VOID) : Gia_ObjRepr(p, k) == 0;  }  static inline int         Gia_ObjIsFailedPair( Gia_Man_t * p, int i, int k ) { assert( k ); return i? (Gia_ObjFailed(p, i) || Gia_ObjFailed(p, k)) : Gia_ObjFailed(p, k);                     } -static inline int         Gia_ClassIsPair( Gia_Man_t * p, int i )            { assert( Gia_ObjIsHead(p, i) ); assert( Gia_ObjNext(p, i) ); return Gia_ObjNext(p, Gia_ObjNext(p, i)) == 0;     } +static inline int         Gia_ClassIsPair( Gia_Man_t * p, int i )            { assert( Gia_ObjIsHead(p, i) ); assert( Gia_ObjNext(p, i) ); return Gia_ObjNext(p, Gia_ObjNext(p, i)) <= 0;     }  static inline void        Gia_ClassUndoPair( Gia_Man_t * p, int i )          { assert( Gia_ClassIsPair(p,i) ); Gia_ObjSetRepr(p, Gia_ObjNext(p, i), GIA_VOID); Gia_ObjSetNext(p, i, 0);       }  #define Gia_ManForEachConst( p, i )                            \      for ( i = 1; i < Gia_ManObjNum(p); i++ ) if ( !Gia_ObjIsConst(p, i) ) {} else  #define Gia_ManForEachClass( p, i )                            \      for ( i = 1; i < Gia_ManObjNum(p); i++ ) if ( !Gia_ObjIsHead(p, i) ) {} else +#define Gia_ManForEachClass0( p, i )                            \ +    for ( i = 0; i < Gia_ManObjNum(p); i++ ) if ( !Gia_ObjIsHead(p, i) ) {} else  #define Gia_ManForEachClassReverse( p, i )                     \      for ( i = Gia_ManObjNum(p) - 1; i > 0; i-- ) if ( !Gia_ObjIsHead(p, i) ) {} else  #define Gia_ClassForEachObj( p, i, iObj )                      \ -    for ( assert(Gia_ObjIsHead(p, i)), iObj = i; iObj; iObj = Gia_ObjNext(p, iObj) ) +    for ( assert(Gia_ObjIsHead(p, i)), iObj = i; iObj > 0; iObj = Gia_ObjNext(p, iObj) )  #define Gia_ClassForEachObj1( p, i, iObj )                     \ -    for ( assert(Gia_ObjIsHead(p, i)), iObj = Gia_ObjNext(p, i); iObj; iObj = Gia_ObjNext(p, iObj) ) +    for ( assert(Gia_ObjIsHead(p, i)), iObj = Gia_ObjNext(p, i); iObj > 0; iObj = Gia_ObjNext(p, iObj) )  static inline int         Gia_ObjFoffsetId( Gia_Man_t * p, int Id )                { return Vec_IntEntry( p->vFanout, Id );                                 } @@ -1585,6 +1588,7 @@ extern void                Gia_ManSwapPos( Gia_Man_t * p, int i );  extern Vec_Int_t *         Gia_ManSaveValue( Gia_Man_t * p );  extern void                Gia_ManLoadValue( Gia_Man_t * p, Vec_Int_t * vValues );  extern Vec_Int_t *         Gia_ManFirstFanouts( Gia_Man_t * p ); +extern void                Gia_ManDetectMuxes( Gia_Man_t * p );  /*=== giaCTas.c ===========================================================*/  typedef struct Tas_Man_t_  Tas_Man_t; diff --git a/src/aig/gia/giaEquiv.c b/src/aig/gia/giaEquiv.c index 1b0bce07..f41db898 100644 --- a/src/aig/gia/giaEquiv.c +++ b/src/aig/gia/giaEquiv.c @@ -485,7 +485,7 @@ void Gia_ManEquivPrintClasses( Gia_Man_t * p, int fVerbose, float Mem )      if ( fVerbose )      {  //        int Ent; -        Abc_Print( 1, "Const0 = " ); +        Abc_Print( 1, "Const0 (%d) = ", Counter0 );          Gia_ManForEachConst( p, i )              Abc_Print( 1, "%d ", i );          Abc_Print( 1, "\n" ); diff --git a/src/aig/gia/giaUtil.c b/src/aig/gia/giaUtil.c index c7af642e..d64c53fa 100644 --- a/src/aig/gia/giaUtil.c +++ b/src/aig/gia/giaUtil.c @@ -2050,6 +2050,25 @@ void Gia_AigerWriteLut( Gia_Man_t * p, char * pFileName )      Vec_WrdFree( vTruths );  } +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Gia_ManDetectMuxes( Gia_Man_t * p ) +{ +    Gia_Obj_t * pObj, * pNodeT, * pNodeE; int i; +    Gia_ManForEachObj( p, pObj, i ); +        if ( Gia_ObjIsAnd(pObj) && Gia_ObjRecognizeMux(pObj, &pNodeT, &pNodeE) ) +            pObj->fMark0 = 1; +} +  ////////////////////////////////////////////////////////////////////////  ///                       END OF FILE                                ///  //////////////////////////////////////////////////////////////////////// diff --git a/src/base/wlc/wlcSim.c b/src/base/wlc/wlcSim.c index 20ac8c61..e2fcd1f8 100644 --- a/src/base/wlc/wlcSim.c +++ b/src/base/wlc/wlcSim.c @@ -43,13 +43,13 @@ ABC_NAMESPACE_IMPL_START  ***********************************************************************/  static inline word * Wlc_ObjSim( Gia_Man_t * p, int iObj )  { -    return Vec_WrdEntryP( p->vSims, p->iPatsPi * iObj ); +    return Vec_WrdEntryP( p->vSims, p->nSimWords * iObj );  }  static inline void Wlc_ObjSimPi( Gia_Man_t * p, int iObj )  {      int w;      word * pSim = Wlc_ObjSim( p, iObj ); -    for ( w = 0; w < p->iPatsPi; w++ ) +    for ( w = 0; w < p->nSimWords; w++ )          pSim[w] = Gia_ManRandomW( 0 );  }  static inline void Wlc_ObjSimRo( Gia_Man_t * p, int iObj ) @@ -57,7 +57,7 @@ static inline void Wlc_ObjSimRo( Gia_Man_t * p, int iObj )      int w;      word * pSimRo = Wlc_ObjSim( p, iObj );      word * pSimRi = Wlc_ObjSim( p, Gia_ObjRoToRiId(p, iObj) ); -    for ( w = 0; w < p->iPatsPi; w++ ) +    for ( w = 0; w < p->nSimWords; w++ )          pSimRo[w] = pSimRi[w];  }  static inline void Wlc_ObjSimCo( Gia_Man_t * p, int iObj ) @@ -67,10 +67,10 @@ static inline void Wlc_ObjSimCo( Gia_Man_t * p, int iObj )      word * pSimCo  = Wlc_ObjSim( p, iObj );      word * pSimDri = Wlc_ObjSim( p, Gia_ObjFaninId0(pObj, iObj) );      if ( Gia_ObjFaninC0(pObj) ) -        for ( w = 0; w < p->iPatsPi; w++ ) +        for ( w = 0; w < p->nSimWords; w++ )              pSimCo[w] = ~pSimDri[w];      else -        for ( w = 0; w < p->iPatsPi; w++ ) +        for ( w = 0; w < p->nSimWords; w++ )              pSimCo[w] =  pSimDri[w];  }  static inline void Wlc_ObjSimAnd( Gia_Man_t * p, int iObj ) @@ -81,16 +81,16 @@ static inline void Wlc_ObjSimAnd( Gia_Man_t * p, int iObj )      word * pSim0 = Wlc_ObjSim( p, Gia_ObjFaninId0(pObj, iObj) );      word * pSim1 = Wlc_ObjSim( p, Gia_ObjFaninId1(pObj, iObj) );      if ( Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) ) -        for ( w = 0; w < p->iPatsPi; w++ ) +        for ( w = 0; w < p->nSimWords; w++ )              pSim[w] = ~pSim0[w] & ~pSim1[w];      else if ( Gia_ObjFaninC0(pObj) && !Gia_ObjFaninC1(pObj) ) -        for ( w = 0; w < p->iPatsPi; w++ ) +        for ( w = 0; w < p->nSimWords; w++ )              pSim[w] = ~pSim0[w] & pSim1[w];      else if ( !Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) ) -        for ( w = 0; w < p->iPatsPi; w++ ) +        for ( w = 0; w < p->nSimWords; w++ )              pSim[w] = pSim0[w] & ~pSim1[w];      else -        for ( w = 0; w < p->iPatsPi; w++ ) +        for ( w = 0; w < p->nSimWords; w++ )              pSim[w] = pSim0[w] & pSim1[w];  } @@ -135,7 +135,7 @@ Vec_Ptr_t * Wlc_NtkSimulate( Wlc_Ntk_t * p, Vec_Int_t * vNodes, int nWords, int      // allocate simulation info for one timeframe      Vec_WrdFreeP( &pGia->vSims );      pGia->vSims = Vec_WrdStart( Gia_ManObjNum(pGia) * nWords ); -    pGia->iPatsPi = nWords; +    pGia->nSimWords = nWords;      // allocate resulting simulation info      vRes = Vec_PtrAlloc( Vec_IntSize(vNodes) );      Wlc_NtkForEachObjVec( vNodes, p, pWlcObj, i ) @@ -188,7 +188,7 @@ Vec_Ptr_t * Wlc_NtkSimulate( Wlc_Ntk_t * p, Vec_Int_t * vNodes, int nWords, int              printf( "Replaced %d dangling internal bits with constant 0.\n", Counter );      }      Vec_WrdFreeP( &pGia->vSims ); -    pGia->iPatsPi = 0; +    pGia->nSimWords = 0;      Gia_ManStop( pGia );      return vRes;  } diff --git a/src/misc/util/utilTruth.h b/src/misc/util/utilTruth.h index d77ed64d..e04ffbc9 100644 --- a/src/misc/util/utilTruth.h +++ b/src/misc/util/utilTruth.h @@ -1631,6 +1631,14 @@ static inline int Abc_TtFindFirstBit( word * pIn, int nVars )              return 64*w + Abc_Tt6FirstBit(pIn[w]);      return -1;  } +static inline int Abc_TtFindFirstBit2( word * pIn, int nWords ) +{ +    int w; +    for ( w = 0; w < nWords; w++ ) +        if ( pIn[w] ) +            return 64*w + Abc_Tt6FirstBit(pIn[w]); +    return -1; +}  static inline int Abc_TtFindFirstDiffBit( word * pIn1, word * pIn2, int nVars )  {      int w, nWords = Abc_TtWordNum(nVars); @@ -1639,6 +1647,14 @@ static inline int Abc_TtFindFirstDiffBit( word * pIn1, word * pIn2, int nVars )              return 64*w + Abc_Tt6FirstBit(pIn1[w] ^ pIn2[w]);      return -1;  } +static inline int Abc_TtFindFirstDiffBit2( word * pIn1, word * pIn2, int nWords ) +{ +    int w; +    for ( w = 0; w < nWords; w++ ) +        if ( pIn1[w] ^ pIn2[w] ) +            return 64*w + Abc_Tt6FirstBit(pIn1[w] ^ pIn2[w]); +    return -1; +}  static inline int Abc_TtFindFirstZero( word * pIn, int nVars )  {      int w, nWords = Abc_TtWordNum(nVars); diff --git a/src/proof/cec/cecSat.c b/src/proof/cec/cecSat.c new file mode 100644 index 00000000..9e85e49d --- /dev/null +++ b/src/proof/cec/cecSat.c @@ -0,0 +1,862 @@ +/**CFile**************************************************************** + +  FileName    [cecSat.c] + +  SystemName  [ABC: Logic synthesis and verification system.] + +  PackageName [Combinational equivalence checking.] + +  Synopsis    [Detection of structural isomorphism.] + +  Author      [Alan Mishchenko] +   +  Affiliation [UC Berkeley] + +  Date        [Ver. 1.0. Started - June 20, 2005.] + +  Revision    [$Id: cecSat.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "aig/gia/gia.h" +#include "misc/util/utilTruth.h" +#include "sat/satoko/satoko.h" +#include "sat/satoko/solver.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +///                        DECLARATIONS                              /// +//////////////////////////////////////////////////////////////////////// + +// sweeping manager +typedef struct Cec2_Par_t_ Cec2_Par_t; +struct Cec2_Par_t_ +{ +    int              nSimWords;     // simulation words +    int              nSimRounds;    // simulation rounds +    int              nConfLimit;    // SAT solver conflict limit +    int              fIsMiter;      // this is a miter +    int              fVeryVerbose;  // verbose stats +    int              fVerbose;      // verbose stats +}; + +// SAT solving manager +typedef struct Cec2_Man_t_ Cec2_Man_t; +struct Cec2_Man_t_ +{ +    Cec2_Par_t *     pPars;          // parameters +    Gia_Man_t *      pAig;           // user's AIG +    Gia_Man_t *      pNew;           // internal AIG +    // SAT solving +    satoko_t *       pSat;           // SAT solver +    Vec_Ptr_t *      vFrontier;      // CNF construction +    Vec_Ptr_t *      vFanins;        // CNF construction +    Vec_Wrd_t *      vSims;          // CI simulation info +    Vec_Int_t *      vNodesNew;      // nodes +    Vec_Int_t *      vObjSatPairs;   // nodes +}; + +static inline int    Cec2_ObjSatId( Gia_Man_t * p, Gia_Obj_t * pObj )             { return Gia_ObjCopyArray(p, Gia_ObjId(p, pObj));                                                     } +static inline int    Cec2_ObjSetSatId( Gia_Man_t * p, Gia_Obj_t * pObj, int Num ) { assert(Cec2_ObjSatId(p, pObj) == -1); Gia_ObjSetCopyArray(p, Gia_ObjId(p, pObj), Num); return Num;  } +static inline void   Cec2_ObjCleanSatId( Gia_Man_t * p, Gia_Obj_t * pObj )        { assert(Cec2_ObjSatId(p, pObj) != -1); Gia_ObjSetCopyArray(p, Gia_ObjId(p, pObj), -1);               } + +//////////////////////////////////////////////////////////////////////// +///                     FUNCTION DEFINITIONS                         /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + +  Synopsis    [Sets parameter defaults.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Cec2_SetDefaultParams( Cec2_Par_t * p ) +{ +    memset( p, 0, sizeof(Cec2_Par_t) ); +    p->nSimWords      =       8;    // simulation words +    p->nSimRounds     =       4;    // simulation rounds +    p->nConfLimit     =    1000;    // conflict limit at a node +    p->fIsMiter       =       0;    // this is a miter +    p->fVeryVerbose   =       0;    // verbose stats +    p->fVerbose       =       1;    // verbose stats +}   + +/**Function************************************************************* + +  Synopsis    [Adds clauses to the solver.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Cec2_AddClausesMux( Gia_Man_t * p, Gia_Obj_t * pNode, satoko_t * pSat ) +{ +    int fPolarFlip = 0; +    Gia_Obj_t * pNodeI, * pNodeT, * pNodeE; +    int pLits[4], RetValue, VarF, VarI, VarT, VarE, fCompT, fCompE; + +    assert( !Gia_IsComplement( pNode ) ); +    assert( pNode->fMark0 ); +    // get nodes (I = if, T = then, E = else) +    pNodeI = Gia_ObjRecognizeMux( pNode, &pNodeT, &pNodeE ); +    // get the variable numbers +    VarF = Cec2_ObjSatId(p, pNode); +    VarI = Cec2_ObjSatId(p, pNodeI); +    VarT = Cec2_ObjSatId(p, Gia_Regular(pNodeT)); +    VarE = Cec2_ObjSatId(p, Gia_Regular(pNodeE)); +    // get the complementation flags +    fCompT = Gia_IsComplement(pNodeT); +    fCompE = Gia_IsComplement(pNodeE); + +    // f = ITE(i, t, e) + +    // i' + t' + f +    // i' + t  + f' +    // i  + e' + f +    // i  + e  + f' + +    // create four clauses +    pLits[0] = Abc_Var2Lit(VarI, 1); +    pLits[1] = Abc_Var2Lit(VarT, 1^fCompT); +    pLits[2] = Abc_Var2Lit(VarF, 0); +    if ( fPolarFlip ) +    { +        if ( pNodeI->fPhase )               pLits[0] = Abc_LitNot( pLits[0] ); +        if ( Gia_Regular(pNodeT)->fPhase )  pLits[1] = Abc_LitNot( pLits[1] ); +        if ( pNode->fPhase )                pLits[2] = Abc_LitNot( pLits[2] ); +    } +    RetValue = satoko_add_clause( pSat, pLits, 3 ); +    assert( RetValue ); +    pLits[0] = Abc_Var2Lit(VarI, 1); +    pLits[1] = Abc_Var2Lit(VarT, 0^fCompT); +    pLits[2] = Abc_Var2Lit(VarF, 1); +    if ( fPolarFlip ) +    { +        if ( pNodeI->fPhase )               pLits[0] = Abc_LitNot( pLits[0] ); +        if ( Gia_Regular(pNodeT)->fPhase )  pLits[1] = Abc_LitNot( pLits[1] ); +        if ( pNode->fPhase )                pLits[2] = Abc_LitNot( pLits[2] ); +    } +    RetValue = satoko_add_clause( pSat, pLits, 3 ); +    assert( RetValue ); +    pLits[0] = Abc_Var2Lit(VarI, 0); +    pLits[1] = Abc_Var2Lit(VarE, 1^fCompE); +    pLits[2] = Abc_Var2Lit(VarF, 0); +    if ( fPolarFlip ) +    { +        if ( pNodeI->fPhase )               pLits[0] = Abc_LitNot( pLits[0] ); +        if ( Gia_Regular(pNodeE)->fPhase )  pLits[1] = Abc_LitNot( pLits[1] ); +        if ( pNode->fPhase )                pLits[2] = Abc_LitNot( pLits[2] ); +    } +    RetValue = satoko_add_clause( pSat, pLits, 3 ); +    assert( RetValue ); +    pLits[0] = Abc_Var2Lit(VarI, 0); +    pLits[1] = Abc_Var2Lit(VarE, 0^fCompE); +    pLits[2] = Abc_Var2Lit(VarF, 1); +    if ( fPolarFlip ) +    { +        if ( pNodeI->fPhase )               pLits[0] = Abc_LitNot( pLits[0] ); +        if ( Gia_Regular(pNodeE)->fPhase )  pLits[1] = Abc_LitNot( pLits[1] ); +        if ( pNode->fPhase )                pLits[2] = Abc_LitNot( pLits[2] ); +    } +    RetValue = satoko_add_clause( pSat, 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] = Abc_Var2Lit(VarT, 0^fCompT); +    pLits[1] = Abc_Var2Lit(VarE, 0^fCompE); +    pLits[2] = Abc_Var2Lit(VarF, 1); +    if ( fPolarFlip ) +    { +        if ( Gia_Regular(pNodeT)->fPhase )  pLits[0] = Abc_LitNot( pLits[0] ); +        if ( Gia_Regular(pNodeE)->fPhase )  pLits[1] = Abc_LitNot( pLits[1] ); +        if ( pNode->fPhase )                pLits[2] = Abc_LitNot( pLits[2] ); +    } +    RetValue = satoko_add_clause( pSat, pLits, 3 ); +    assert( RetValue ); +    pLits[0] = Abc_Var2Lit(VarT, 1^fCompT); +    pLits[1] = Abc_Var2Lit(VarE, 1^fCompE); +    pLits[2] = Abc_Var2Lit(VarF, 0); +    if ( fPolarFlip ) +    { +        if ( Gia_Regular(pNodeT)->fPhase )  pLits[0] = Abc_LitNot( pLits[0] ); +        if ( Gia_Regular(pNodeE)->fPhase )  pLits[1] = Abc_LitNot( pLits[1] ); +        if ( pNode->fPhase )                pLits[2] = Abc_LitNot( pLits[2] ); +    } +    RetValue = satoko_add_clause( pSat, pLits, 3 ); +    assert( RetValue ); +} +void Cec2_AddClausesSuper( Gia_Man_t * p, Gia_Obj_t * pNode, Vec_Ptr_t * vSuper, satoko_t * pSat ) +{ +    int fPolarFlip = 0; +    Gia_Obj_t * pFanin; +    int * pLits, nLits, RetValue, i; +    assert( !Gia_IsComplement(pNode) ); +    assert( Gia_ObjIsAnd( pNode ) ); +    // create storage for literals +    nLits = Vec_PtrSize(vSuper) + 1; +    pLits = ABC_ALLOC( int, nLits ); +    // suppose AND-gate is A & B = C +    // add !A => !C   or   A + !C +    Vec_PtrForEachEntry( Gia_Obj_t *, vSuper, pFanin, i ) +    { +        pLits[0] = Abc_Var2Lit(Cec2_ObjSatId(p, Gia_Regular(pFanin)), Gia_IsComplement(pFanin)); +        pLits[1] = Abc_Var2Lit(Cec2_ObjSatId(p, pNode), 1); +        if ( fPolarFlip ) +        { +            if ( Gia_Regular(pFanin)->fPhase )  pLits[0] = Abc_LitNot( pLits[0] ); +            if ( pNode->fPhase )                pLits[1] = Abc_LitNot( pLits[1] ); +        } +        RetValue = satoko_add_clause( pSat, pLits, 2 ); +        assert( RetValue ); +    } +    // add A & B => C   or   !A + !B + C +    Vec_PtrForEachEntry( Gia_Obj_t *, vSuper, pFanin, i ) +    { +        pLits[i] = Abc_Var2Lit(Cec2_ObjSatId(p, Gia_Regular(pFanin)), !Gia_IsComplement(pFanin)); +        if ( fPolarFlip ) +        { +            if ( Gia_Regular(pFanin)->fPhase )  pLits[i] = Abc_LitNot( pLits[i] ); +        } +    } +    pLits[nLits-1] = Abc_Var2Lit(Cec2_ObjSatId(p, pNode), 0); +    if ( fPolarFlip ) +    { +        if ( pNode->fPhase )  pLits[nLits-1] = Abc_LitNot( pLits[nLits-1] ); +    } +    RetValue = satoko_add_clause( pSat, pLits, nLits ); +    assert( RetValue ); +    ABC_FREE( pLits ); +} + +/**Function************************************************************* + +  Synopsis    [Adds clauses and returns CNF variable of the node.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Cec2_CollectSuper_rec( Gia_Obj_t * pObj, Vec_Ptr_t * vSuper, int fFirst, int fUseMuxes ) +{ +    // if the new node is complemented or a PI, another gate begins +    if ( Gia_IsComplement(pObj) || Gia_ObjIsCi(pObj) ||  +         (!fFirst && Gia_ObjValue(pObj) > 1) ||  +         (fUseMuxes && pObj->fMark0) ) +    { +        Vec_PtrPushUnique( vSuper, pObj ); +        return; +    } +    // go through the branches +    Cec2_CollectSuper_rec( Gia_ObjChild0(pObj), vSuper, 0, fUseMuxes ); +    Cec2_CollectSuper_rec( Gia_ObjChild1(pObj), vSuper, 0, fUseMuxes ); +} +void Cec2_CollectSuper( Gia_Obj_t * pObj, int fUseMuxes, Vec_Ptr_t * vSuper ) +{ +    assert( !Gia_IsComplement(pObj) ); +    assert( !Gia_ObjIsCi(pObj) ); +    Vec_PtrClear( vSuper ); +    Cec2_CollectSuper_rec( pObj, vSuper, 1, fUseMuxes ); +} +void Cec2_ObjAddToFrontier( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Ptr_t * vFrontier, satoko_t * pSat ) +{ +    assert( !Gia_IsComplement(pObj) ); +    assert( !Gia_ObjIsConst0(pObj) ); +    if ( Cec2_ObjSatId(p, pObj) >= 0 ) +        return; +    assert( Cec2_ObjSatId(p, pObj) == -1 ); +    Cec2_ObjSetSatId( p, pObj, satoko_add_variable(pSat, 0) ); +    if ( Gia_ObjIsAnd(pObj) ) +        Vec_PtrPush( vFrontier, pObj ); +} +int Cec2_ObjGetCnfVar( Cec2_Man_t * p, int iObj ) +{  +    Gia_Obj_t * pNode, * pFanin; +    Gia_Obj_t * pObj = Gia_ManObj(p->pNew, iObj); +    int i, k, fUseMuxes = 1; +    // quit if CNF is ready +    if ( Cec2_ObjSatId(p->pNew,pObj) >= 0 ) +        return Cec2_ObjSatId(p->pNew,pObj); +    assert( iObj > 0 ); +    if ( Gia_ObjIsCi(pObj) ) +        return Cec2_ObjSetSatId( p->pNew, pObj, satoko_add_variable(p->pSat, 0) ); +    assert( Gia_ObjIsAnd(pObj) ); +    // start the frontier +    Vec_PtrClear( p->vFrontier ); +    Cec2_ObjAddToFrontier( p->pNew, pObj, p->vFrontier, p->pSat ); +    // explore nodes in the frontier +    Vec_PtrForEachEntry( Gia_Obj_t *, p->vFrontier, pNode, i ) +    { +        // create the supergate +        assert( Cec2_ObjSatId(p->pNew,pNode) >= 0 ); +        if ( fUseMuxes && pNode->fMark0 ) +        { +            Vec_PtrClear( p->vFanins ); +            Vec_PtrPushUnique( p->vFanins, Gia_ObjFanin0( Gia_ObjFanin0(pNode) ) ); +            Vec_PtrPushUnique( p->vFanins, Gia_ObjFanin0( Gia_ObjFanin1(pNode) ) ); +            Vec_PtrPushUnique( p->vFanins, Gia_ObjFanin1( Gia_ObjFanin0(pNode) ) ); +            Vec_PtrPushUnique( p->vFanins, Gia_ObjFanin1( Gia_ObjFanin1(pNode) ) ); +            Vec_PtrForEachEntry( Gia_Obj_t *, p->vFanins, pFanin, k ) +                Cec2_ObjAddToFrontier( p->pNew, Gia_Regular(pFanin), p->vFrontier, p->pSat ); +            Cec2_AddClausesMux( p->pNew, pNode, p->pSat ); +        } +        else +        { +            Cec2_CollectSuper( pNode, fUseMuxes, p->vFanins ); +            Vec_PtrForEachEntry( Gia_Obj_t *, p->vFanins, pFanin, k ) +                Cec2_ObjAddToFrontier( p->pNew, Gia_Regular(pFanin), p->vFrontier, p->pSat ); +            Cec2_AddClausesSuper( p->pNew, pNode, p->vFanins, p->pSat ); +        } +        assert( Vec_PtrSize(p->vFanins) > 1 ); +    } +    return Cec2_ObjSatId(p->pNew,pObj); +} + + + +/**Function************************************************************* + +  Synopsis    [Internal simulation APIs.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline word * Cec2_ObjSim( Gia_Man_t * p, int iObj ) +{ +    return Vec_WrdEntryP( p->vSims, p->nSimWords * iObj ); +} +static inline void Cec2_ObjSimSetPiBit( Gia_Man_t * p, int iObj, int Bit ) +{ +    word * pSim = Cec2_ObjSim( p, iObj ); +    p->iPatsPi = (p->iPatsPi == 64 * p->nSimWords - 1) ? 1 : p->iPatsPi + 1; +    assert( p->iPatsPi > 0 && p->iPatsPi < 64 * p->nSimWords ); +    if ( Abc_InfoHasBit( (unsigned*)pSim, p->iPatsPi ) != Bit ) +        Abc_InfoXorBit( (unsigned*)pSim, p->iPatsPi ); +} +static inline void Cec2_ObjSimRo( Gia_Man_t * p, int iObj ) +{ +    int w; +    word * pSimRo = Cec2_ObjSim( p, iObj ); +    word * pSimRi = Cec2_ObjSim( p, Gia_ObjRoToRiId(p, iObj) ); +    for ( w = 0; w < p->nSimWords; w++ ) +        pSimRo[w] = pSimRi[w]; +} +static inline void Cec2_ObjSimCo( Gia_Man_t * p, int iObj ) +{ +    int w; +    Gia_Obj_t * pObj = Gia_ManObj( p, iObj ); +    word * pSimCo  = Cec2_ObjSim( p, iObj ); +    word * pSimDri = Cec2_ObjSim( p, Gia_ObjFaninId0(pObj, iObj) ); +    if ( Gia_ObjFaninC0(pObj) ) +        for ( w = 0; w < p->nSimWords; w++ ) +            pSimCo[w] = ~pSimDri[w]; +    else +        for ( w = 0; w < p->nSimWords; w++ ) +            pSimCo[w] =  pSimDri[w]; +} +static inline void Cec2_ObjSimAnd( Gia_Man_t * p, int iObj ) +{ +    int w; +    Gia_Obj_t * pObj = Gia_ManObj( p, iObj ); +    word * pSim  = Cec2_ObjSim( p, iObj ); +    word * pSim0 = Cec2_ObjSim( p, Gia_ObjFaninId0(pObj, iObj) ); +    word * pSim1 = Cec2_ObjSim( p, Gia_ObjFaninId1(pObj, iObj) ); +    if ( Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) ) +        for ( w = 0; w < p->nSimWords; w++ ) +            pSim[w] = ~pSim0[w] & ~pSim1[w]; +    else if ( Gia_ObjFaninC0(pObj) && !Gia_ObjFaninC1(pObj) ) +        for ( w = 0; w < p->nSimWords; w++ ) +            pSim[w] = ~pSim0[w] & pSim1[w]; +    else if ( !Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) ) +        for ( w = 0; w < p->nSimWords; w++ ) +            pSim[w] = pSim0[w] & ~pSim1[w]; +    else +        for ( w = 0; w < p->nSimWords; w++ ) +            pSim[w] = pSim0[w] & pSim1[w]; +} +static inline int Cec2_ObjSimEqual( Gia_Man_t * p, int iObj0, int iObj1 ) +{ +    int w; +    word * pSim0 = Cec2_ObjSim( p, iObj0 ); +    word * pSim1 = Cec2_ObjSim( p, iObj1 ); +    if ( (pSim0[0] & 1) == (pSim1[0] & 1) ) +    { +        for ( w = 0; w < p->nSimWords; w++ ) +            if ( pSim0[w] != pSim1[w] ) +                return 0; +        return 1; +    } +    else +    { +        for ( w = 0; w < p->nSimWords; w++ ) +            if ( pSim0[w] != ~pSim1[w] ) +                return 0; +        return 1; +    } +} +static inline void Cec2_ObjSimPi( Gia_Man_t * p, int iObj ) +{ +    int w; +    word * pSim = Cec2_ObjSim( p, iObj ); +    for ( w = 0; w < p->nSimWords; w++ ) +        pSim[w] = Gia_ManRandomW( 0 ); +    pSim[0] <<= 1; +} +void Cec2_ManSimulateCis( Gia_Man_t * p ) +{ +    int i, Id; +    Gia_ManForEachCiId( p, Id, i ) +        Cec2_ObjSimPi( p, Id ); +    p->iPatsPi = 1; +} +Abc_Cex_t * Cec2_ManDeriveCex( Gia_Man_t * p, int iOut, int iPat ) +{ +    Abc_Cex_t * pCex; +    int i, Id; +    pCex = Abc_CexAlloc( 0, Gia_ManCiNum(p), 1 ); +    pCex->iPo = iOut; +    if ( iPat == -1 ) +        return pCex; +    Gia_ManForEachCiId( p, Id, i ) +        if ( Abc_InfoHasBit((unsigned *)Cec2_ObjSim(p, Id), iPat) ) +            Abc_InfoSetBit( pCex->pData, i ); +    return pCex; +} +int Cec2_ManSimulateCos( Gia_Man_t * p ) +{ +    int i, Id; +    // check outputs and generate CEX if they fail +    Gia_ManForEachCoId( p, Id, i ) +    { +        Cec2_ObjSimCo( p, Id ); +        if ( Cec2_ObjSimEqual(p, Id, 0) ) +            continue; +        p->pCexSeq = Cec2_ManDeriveCex( p, i, Abc_TtFindFirstBit2(Cec2_ObjSim(p, Id), p->nSimWords) ); +        return 0; +    } +    return 1; +} +void Cec2_ManSaveCis( Gia_Man_t * p ) +{ +    int w, i, Id; +    assert( p->vSimsPi != NULL ); +    for ( w = 0; w < p->nSimWords; w++ ) +        Gia_ManForEachCiId( p, Id, i ) +            Vec_WrdPush( p->vSimsPi, Cec2_ObjSim(p, Id)[w] ); +} +void Cec2_ManSimulate( Gia_Man_t * p ) +{ +    extern void Cec2_ManSimClassRefineOne( Gia_Man_t * p, int iRepr ); +    Gia_Obj_t * pObj; int i; +    Cec2_ManSaveCis( p ); +    Gia_ManForEachAnd( p, pObj, i ) +        Cec2_ObjSimAnd( p, i ); +    if ( p->pReprs == NULL ) +        return; +    Gia_ManForEachClass0( p, i ) +        Cec2_ManSimClassRefineOne( p, i ); +} +void Cec2_ManSimAlloc( Gia_Man_t * p, int nWords ) +{ +    Vec_WrdFreeP( &p->vSims ); +    Vec_WrdFreeP( &p->vSimsPi ); +    p->vSims   = Vec_WrdStart( Gia_ManObjNum(p) * nWords ); +    p->vSimsPi = Vec_WrdAlloc( Gia_ManCiNum(p) * nWords * 4 ); // storage for CI patterns +    p->nSimWords = nWords; +} + + +/**Function************************************************************* + +  Synopsis    [Computes hash key of the simulation info.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Cec2_ManSimHashKey( word * pSim, int nSims, int nTableSize ) +{ +    static int s_Primes[16] = {  +        1291, 1699, 1999, 2357, 2953, 3313, 3907, 4177,  +        4831, 5147, 5647, 6343, 6899, 7103, 7873, 8147 }; +    unsigned uHash = 0, * pSimU = (unsigned *)pSim; +    int i, nSimsU = 2 * nSims; +    if ( pSimU[0] & 1 ) +        for ( i = 0; i < nSimsU; i++ ) +            uHash ^= ~pSimU[i] * s_Primes[i & 0xf]; +    else +        for ( i = 0; i < nSimsU; i++ ) +            uHash ^= pSimU[i] * s_Primes[i & 0xf]; +    return (int)(uHash % nTableSize); + +} + +/**Function************************************************************* + +  Synopsis    [Creating initial equivalence classes.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Cec2_ManSimClassRefineOne( Gia_Man_t * p, int iRepr ) +{ +    int iObj, iPrev = iRepr, iPrev2, iRepr2; +    Gia_ClassForEachObj1( p, iRepr, iRepr2 ) +        if ( Cec2_ObjSimEqual(p, iRepr, iRepr2) ) +            iPrev = iRepr2; +        else +            break; +    if ( iRepr2 <= 0 ) // no refinement +        return; +    // relink remaining nodes of the class +    // nodes that are equal to iRepr, remain in the class of iRepr +    // nodes that are not equal to iRepr, move to the class of iRepr2 +    Gia_ObjSetRepr( p, iRepr2, GIA_VOID ); +    iPrev2 = iRepr2; +    for ( iObj = Gia_ObjNext(p, iRepr2); iObj > 0; iObj = Gia_ObjNext(p, iObj) ) +    { +        if ( Cec2_ObjSimEqual(p, iRepr, iObj) ) // remains with iRepr +        { +            Gia_ObjSetNext( p, iPrev, iObj ); +            iPrev = iObj; +        } +        else // moves to iRepr2 +        { +            Gia_ObjSetRepr( p, iObj, iRepr2 ); +            Gia_ObjSetNext( p, iPrev2, iObj ); +            iPrev2 = iObj; +        } +    } +    Gia_ObjSetNext( p, iPrev, -1 ); +    Gia_ObjSetNext( p, iPrev2, -1 ); +} +void Cec2_ManCreateClasses( Gia_Man_t * p ) +{ +    Gia_Obj_t * pObj; +    int nWords = p->nSimWords; +    int * pTable, nTableSize, i, Key; +    // allocate representation +    assert( p->pReprs == NULL ); +    p->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(p) ); +    p->pNexts = ABC_FALLOC( int, Gia_ManObjNum(p) ); +    // hash each node by its simulation info +    nTableSize = Abc_PrimeCudd( Gia_ManObjNum(p) ); +    pTable = ABC_FALLOC( int, nTableSize ); +    Gia_ManForEachObj( p, pObj, i ) +    { +        p->pReprs[i].iRepr = GIA_VOID; +        if ( Gia_ObjIsCo(pObj) ) +            continue; +        Key = Cec2_ManSimHashKey( Cec2_ObjSim(p, i), nWords, nTableSize ); +        assert( Key >= 0 && Key < nTableSize ); +        if ( pTable[Key] == -1 ) +            pTable[Key] = i; +        else +            Gia_ObjSetRepr( p, i, pTable[Key] ); +    } +    // create classes +    for ( i = Gia_ManObjNum(p) - 1; i >= 0; i-- ) +    { +        int iRepr = Gia_ObjRepr(p, i); +        if ( iRepr == GIA_VOID ) +            continue; +        Gia_ObjSetNext( p, i, Gia_ObjNext(p, iRepr) ); +        Gia_ObjSetNext( p, iRepr, i ); +    } +    ABC_FREE( pTable ); +    Gia_ManForEachClass0( p, i ) +        Cec2_ManSimClassRefineOne( p, i ); +} + + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Cec2_Man_t * Cec2_ManCreate( Gia_Man_t * pAig, Cec2_Par_t * pPars ) +{ +    Cec2_Man_t * p; +    Gia_Obj_t * pObj; int i; +    assert( Gia_ManRegNum(pAig) == 0 ); +    p = ABC_CALLOC( Cec2_Man_t, 1 ); +    memset( p, 0, sizeof(Cec2_Man_t) ); +    p->pPars        = pPars; +    p->pAig         = pAig; +    // create new manager +    p->pNew         = Gia_ManStart( Gia_ManObjNum(pAig) ); +    Gia_ManFillValue( pAig ); +    Gia_ManConst0(pAig)->Value = 0; +    Gia_ManForEachCi( pAig, pObj, i ) +        pObj->Value = Gia_ManAppendCi( p->pNew ); +    Gia_ManHashAlloc( p->pNew ); +    Vec_IntFill( &p->pNew->vCopies, Gia_ManObjNum(p->pNew), -1 ); +    // SAT solving +    p->pSat         = satoko_create(); +    p->vFrontier    = Vec_PtrAlloc( 1000 ); +    p->vFanins      = Vec_PtrAlloc( 100 ); +    p->vNodesNew    = Vec_IntAlloc( 100 ); +    p->vObjSatPairs = Vec_IntAlloc( 100 ); +    // remember pointer to the solver in the AIG manager +    pAig->pData     = p->pSat; +    return p; +} +void Cec2_ManDestroy( Cec2_Man_t * p ) +{ +    Vec_WrdFreeP( &p->pAig->vSims ); +    //Vec_WrdFreeP( &p->pAig->vSimsPi ); +    Gia_ManCleanMark01( p->pAig ); +    satoko_destroy( p->pSat ); +    Gia_ManStopP( &p->pNew ); +    Vec_PtrFreeP( &p->vFrontier ); +    Vec_PtrFreeP( &p->vFanins ); +    Vec_IntFreeP( &p->vNodesNew ); +    Vec_IntFreeP( &p->vObjSatPairs ); +    ABC_FREE( p ); +} + + +/**Function************************************************************* + +  Synopsis    [Internal simulation APIs.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Cec2_ManCollect_rec( Cec2_Man_t * p, int iObj ) +{ +    Gia_Obj_t * pObj; +    if ( Gia_ObjIsTravIdCurrentId(p->pNew, iObj) ) +        return; +    Gia_ObjSetTravIdCurrentId(p->pNew, iObj); +    pObj = Gia_ManObj( p->pNew, iObj ); +    if ( Cec2_ObjSatId(p->pNew, pObj) >= 0 ) +        Vec_IntPush( p->vNodesNew, iObj ); +    if ( !iObj ) +        return; +    if ( Gia_ObjIsAnd(pObj) ) +    { +        Cec2_ManCollect_rec( p, Gia_ObjFaninId0(pObj, iObj) ); +        Cec2_ManCollect_rec( p, Gia_ObjFaninId1(pObj, iObj) ); +    } +    else +    { +        assert( Cec2_ObjSatId(p->pNew, pObj) >= 0 ); +        Vec_IntPushTwo( p->vObjSatPairs, Gia_ManCiIdToId(p->pAig, Gia_ObjCioId(pObj)), Cec2_ObjSatId(p->pNew, pObj) ); // SAT var +    } +} +int Cec2_ManSolveTwo( Cec2_Man_t * p, int iObj0, int iObj1, int fPhase ) +{ +    Gia_Obj_t * pObj; +    int status, i, iVar0, iVar1; +    if (iObj1 < iObj0)  +        iObj1 ^= iObj0, iObj0 ^= iObj1, iObj1 ^= iObj0; +    assert( iObj0 < iObj1 ); +    assert( solver_varnum(p->pSat) == 0 ); +    if ( !iObj0 ) +        Cec2_ObjSetSatId( p->pNew, Gia_ManConst0(p->pNew), satoko_add_variable(p->pSat, 0) ); +    iVar0 = Cec2_ObjGetCnfVar( p, iObj0 ); +    iVar1 = Cec2_ObjGetCnfVar( p, iObj1 ); +    // collect inputs and internal nodes +    Vec_IntClear( p->vNodesNew ); +    Vec_IntClear( p->vObjSatPairs ); +    Gia_ManIncrementTravId( p->pNew ); +    Cec2_ManCollect_rec( p, iObj0 ); +    Cec2_ManCollect_rec( p, iObj1 ); +    // solve direct +    satoko_assump_push( p->pSat, Abc_Var2Lit(iVar0, 1) ); +    satoko_assump_push( p->pSat, Abc_Var2Lit(iVar1, fPhase) ); +    status = satoko_solve( p->pSat ); +    satoko_assump_pop( p->pSat ); +    satoko_assump_pop( p->pSat ); +    if ( status == SATOKO_UNSAT && iObj0 > 0 ) +    { +        // solve reverse +        satoko_assump_push( p->pSat, Abc_Var2Lit(iVar0, 0) ); +        satoko_assump_push( p->pSat, Abc_Var2Lit(iVar1, !fPhase) ); +        status = satoko_solve( p->pSat ); +        satoko_assump_pop( p->pSat ); +        satoko_assump_pop( p->pSat ); +    } +    Gia_ManForEachObjVec( p->vNodesNew, p->pNew, pObj, i ) +        Cec2_ObjCleanSatId( p->pNew, pObj ); +    return status; +} +int Cec2_ManSweepNode( Cec2_Man_t * p, int iObj ) +{ +    int i, IdAig, IdSat, status, RetValue = 1; +    Gia_Obj_t * pObj = Gia_ManObj( p->pAig, iObj ); +    Gia_Obj_t * pRepr = Gia_ObjReprObj( p->pAig, iObj ); +    int fCompl = Abc_LitIsCompl(pObj->Value) ^ Abc_LitIsCompl(pRepr->Value) ^ pObj->fPhase ^ pRepr->fPhase; +    status = Cec2_ManSolveTwo( p, Abc_Lit2Var(pRepr->Value), Abc_Lit2Var(pObj->Value), fCompl ); +    if ( status == SATOKO_SAT ) +    { +        Vec_IntForEachEntryDouble( p->vObjSatPairs, IdAig, IdSat, i ) +            Cec2_ObjSimSetPiBit( p->pAig, IdAig, var_value(p->pSat, IdSat) == LIT_TRUE ); +        RetValue = 0; +    } +    else if ( status == SATOKO_UNSAT ) +    { +        pObj->Value = Abc_LitNotCond( pRepr->Value, fCompl ); +        Gia_ObjSetProved( p->pAig, iObj ); +    } +    else  +    { +        assert( status == SATOKO_UNDEC ); +        Gia_ObjSetFailed( p->pAig, iObj ); +        assert( 0 ); +    } +    satoko_rollback( p->pSat ); +    return RetValue; +} +int Cec2_ManPerformSweeping( Gia_Man_t * p, Cec2_Par_t * pPars ) +{ +    Cec2_Man_t * pMan;  +    Gia_Obj_t * pObj, * pRepr, * pObjNew;  +    int i, fDisproved = 1; + +    // check if any output trivially fails under all-0 pattern +    Gia_ManSetPhase( p ); +    if ( pPars->fIsMiter )  +    { +        Gia_ManForEachCo( p, pObj, i ) +            if ( pObj->fPhase ) +            { +                p->pCexSeq = Cec2_ManDeriveCex( p, i, -1 ); +                return 0; +            } +    } +    // simulate one round and create classes +    Cec2_ManSimAlloc( p, pPars->nSimWords ); +    Cec2_ManSimulateCis( p ); +    Cec2_ManSimulate( p ); +    if ( pPars->fIsMiter && !Cec2_ManSimulateCos(p) ) // cex detected +        return 0; +    Cec2_ManCreateClasses( p ); +    if ( pPars->fVerbose ) +        Gia_ManEquivPrintClasses( p, pPars->fVeryVerbose, 0 ); + +    // perform additinal simulation +    for ( i = 0; i < pPars->nSimRounds; i++ ) +    { +        Cec2_ManSimulateCis( p ); +        Cec2_ManSimulate( p ); +        if ( pPars->fIsMiter && !Cec2_ManSimulateCos(p) ) // cex detected +            return 0; +        if ( pPars->fVerbose ) +            Gia_ManEquivPrintClasses( p, pPars->fVeryVerbose, 0 ); +    } +    // perform sweeping +    pMan = Cec2_ManCreate( p, pPars ); +    while ( fDisproved ) +    { +        fDisproved = 0; +        Cec2_ManSimulateCis( p ); +        Gia_ManForEachAnd( p, pObj, i ) +        { +            pObj->fMark1 = 0; +            if ( ~pObj->Value ) // skip swept nodes +                continue; +            assert( !Gia_ObjProved(p, i) && !Gia_ObjFailed(p, i) ); +            pObj->fMark1 = Gia_ObjFanin0(pObj)->fMark1 || Gia_ObjFanin1(pObj)->fMark1; +            if ( pObj->fMark1 ) // skip nodes in the TFO of a disproved one +                continue; +            // duplicate the node +            pObj->Value = Gia_ManHashAnd( pMan->pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); +            if ( Vec_IntSize(&pMan->pNew->vCopies) == Abc_Lit2Var(pObj->Value) ) +            { +                pObjNew = Gia_ManObj( pMan->pNew, Abc_Lit2Var(pObj->Value) ); +                pObjNew->fMark0 = Gia_ObjIsMuxType( pObjNew ); +                Vec_IntPush( &pMan->pNew->vCopies, -1 ); +            } +            assert( Vec_IntSize(&pMan->pNew->vCopies) == Gia_ManObjNum(pMan->pNew) ); +            pRepr = Gia_ObjReprObj( p, i ); +            if ( pRepr == NULL || pRepr->fMark1 ) +                continue; +            //if ( Gia_ObjIsConst0(pRepr) ) +            //    continue; +            if ( Abc_Lit2Var(pObj->Value) == Abc_Lit2Var(pRepr->Value) ) +            { +                assert( (pObj->Value ^ pRepr->Value) == (pObj->fPhase ^ pRepr->fPhase) ); +                Gia_ObjSetProved( p, i ); +                continue; +            } +            if ( Cec2_ManSweepNode(pMan, i) ) +                continue; +            // mark nodes as disproved +            pRepr->fMark1 = pObj->fMark1 = 1; +            fDisproved = 1; +        } +        if ( fDisproved ) +        { +            Cec2_ManSimulate( p ); +            if ( pPars->fIsMiter && !Cec2_ManSimulateCos(p) ) // cex detected +                break; +        } +        if ( pPars->fVerbose ) +            Gia_ManEquivPrintClasses( p, pPars->fVeryVerbose, 0 ); +    } +    Cec2_ManDestroy( pMan ); +    return p->pCexSeq ? 0 : 1; +} +void Cec2_ManSimulateTest( Gia_Man_t * p ) +{ +    abctime clk = Abc_Clock(); +    Cec2_Par_t Pars, * pPars = &Pars; +    Cec2_SetDefaultParams( pPars ); +    Cec2_ManPerformSweeping( p, pPars ); +    Abc_PrintTime( 1, "SAT sweeping time", Abc_Clock() - clk ); +} + + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/cec/module.make b/src/proof/cec/module.make index 82e0de74..38106e5e 100644 --- a/src/proof/cec/module.make +++ b/src/proof/cec/module.make @@ -6,6 +6,7 @@ SRC +=    src/proof/cec/cecCec.c \      src/proof/cec/cecIso.c \      src/proof/cec/cecMan.c \      src/proof/cec/cecPat.c \ +    src/proof/cec/cecSat.c \      src/proof/cec/cecSeq.c \      src/proof/cec/cecSolve.c \      src/proof/cec/cecSplit.c \ diff --git a/src/sat/bmc/bmcGen.c b/src/sat/bmc/bmcGen.c index 5d84ce87..460c9fec 100644 --- a/src/sat/bmc/bmcGen.c +++ b/src/sat/bmc/bmcGen.c @@ -46,13 +46,13 @@ ABC_NAMESPACE_IMPL_START  ***********************************************************************/  static inline word * Gia_ManMoObj( Gia_Man_t * p, int iObj )  { -    return Vec_WrdEntryP( p->vSims, iObj * p->iPatsPi ); +    return Vec_WrdEntryP( p->vSims, iObj * p->nSimWords );  }  static inline void Gia_ManMoSetCi( Gia_Man_t * p, int iObj )  {      int w;      word * pSims = Gia_ManMoObj( p, iObj ); -    for ( w = 0; w < p->iPatsPi; w++ ) +    for ( w = 0; w < p->nSimWords; w++ )          pSims[w] = Gia_ManRandomW( 0 );  }  static inline void Gia_ManMoSimAnd( Gia_Man_t * p, int iObj ) @@ -65,19 +65,19 @@ static inline void Gia_ManMoSimAnd( Gia_Man_t * p, int iObj )      if ( Gia_ObjFaninC0(pObj) )      {          if (  Gia_ObjFaninC1(pObj) ) -            for ( w = 0; w < p->iPatsPi; w++ ) +            for ( w = 0; w < p->nSimWords; w++ )                  pSims[w] = ~(pSims0[w] | pSims1[w]);          else  -            for ( w = 0; w < p->iPatsPi; w++ ) +            for ( w = 0; w < p->nSimWords; w++ )                  pSims[w] = ~pSims0[w] & pSims1[w];      }      else       {          if (  Gia_ObjFaninC1(pObj) ) -            for ( w = 0; w < p->iPatsPi; w++ ) +            for ( w = 0; w < p->nSimWords; w++ )                  pSims[w] = pSims0[w] & ~pSims1[w];          else  -            for ( w = 0; w < p->iPatsPi; w++ ) +            for ( w = 0; w < p->nSimWords; w++ )                  pSims[w] = pSims0[w] & pSims1[w];      }  } @@ -89,12 +89,12 @@ static inline void Gia_ManMoSetCo( Gia_Man_t * p, int iObj )      word * pSims0 = Gia_ManMoObj( p, Gia_ObjFaninId0(pObj, iObj) );      if ( Gia_ObjFaninC0(pObj) )      { -        for ( w = 0; w < p->iPatsPi; w++ ) +        for ( w = 0; w < p->nSimWords; w++ )              pSims[w] = ~pSims0[w];      }      else       { -        for ( w = 0; w < p->iPatsPi; w++ ) +        for ( w = 0; w < p->nSimWords; w++ )              pSims[w] = pSims0[w];      }  } @@ -102,7 +102,7 @@ void Gia_ManMoFindSimulate( Gia_Man_t * p, int nWords )  {      int i, iObj;      Gia_ManRandomW( 1 ); -    p->iPatsPi = nWords; +    p->nSimWords = nWords;      if ( p->vSims )          Vec_WrdFill( p->vSims, nWords * Gia_ManObjNum(p), 0 );      else diff --git a/src/sat/satoko/satoko.h b/src/sat/satoko/satoko.h index 88070eac..7c2f3720 100644 --- a/src/sat/satoko/satoko.h +++ b/src/sat/satoko/satoko.h @@ -83,7 +83,7 @@ extern void satoko_destroy(satoko_t *);  extern void satoko_default_opts(satoko_opts_t *);  extern void satoko_configure(satoko_t *, satoko_opts_t *);  extern int  satoko_parse_dimacs(char *, satoko_t **); -extern void satoko_add_variable(satoko_t *, char); +extern int  satoko_add_variable(satoko_t *, char);  extern int  satoko_add_clause(satoko_t *, unsigned *, unsigned);  extern void satoko_assump_push(satoko_t *s, unsigned);  extern void satoko_assump_pop(satoko_t *s); diff --git a/src/sat/satoko/solver_api.c b/src/sat/satoko/solver_api.c index 9cad0a14..e03cc084 100644 --- a/src/sat/satoko/solver_api.c +++ b/src/sat/satoko/solver_api.c @@ -216,7 +216,7 @@ int satoko_simplify(solver_t * s)      return SATOKO_OK;  } -void satoko_add_variable(solver_t *s, char sign) +int satoko_add_variable(solver_t *s, char sign)  {      unsigned var = vec_act_size(s->activity);      vec_wl_push(s->watches); @@ -231,6 +231,7 @@ void satoko_add_variable(solver_t *s, char sign)      heap_insert(s->var_order, var);      if (s->marks)          vec_char_push_back(s->marks, 0); +    return var;  }  int satoko_add_clause(solver_t *s, unsigned *lits, unsigned size) @@ -351,6 +352,7 @@ void satoko_rollback(satoko_t *s)          clause_unwatch(s, cdb_cref(s->all_clauses, (unsigned *)cl_to_remove[i]));          cl_to_remove[i]->f_mark = 1;      } +    satoko_free(cl_to_remove);      vec_uint_shrink(s->originals, s->book_cl_orig);      vec_uint_shrink(s->learnts, s->book_cl_lrnt);      /* Shrink variable related vectors */ | 
