summaryrefslogtreecommitdiffstats
path: root/src/sat
diff options
context:
space:
mode:
Diffstat (limited to 'src/sat')
-rw-r--r--src/sat/bmc/bmc.h5
-rw-r--r--src/sat/bmc/bmcBmcAnd.c3
-rw-r--r--src/sat/bmc/bmcCexCare.c266
-rw-r--r--src/sat/bmc/bmcCexTools.c6
-rw-r--r--src/sat/bmc/bmcChain.c3
-rw-r--r--src/sat/bmc/bmcClp.c10
-rw-r--r--src/sat/bmc/bmcEnum.c223
-rw-r--r--src/sat/bmc/bmcExpand.c4
-rw-r--r--src/sat/bmc/bmcFault.c2
-rw-r--r--src/sat/bmc/bmcFx.c6
-rw-r--r--src/sat/bmc/bmcGen.c22
-rw-r--r--src/sat/bmc/bmcICheck.c3
-rw-r--r--src/sat/bsat/satSolver.c510
-rw-r--r--src/sat/bsat/satSolver.h61
-rw-r--r--src/sat/cnf/cnfUtil.c2
-rw-r--r--src/sat/satoko/LICENSE22
-rw-r--r--src/sat/satoko/act_clause.h43
-rw-r--r--src/sat/satoko/act_var.h53
-rw-r--r--src/sat/satoko/cdb.h106
-rw-r--r--src/sat/satoko/clause.h63
-rw-r--r--src/sat/satoko/cnf_reader.c156
-rw-r--r--src/sat/satoko/module.make3
-rw-r--r--src/sat/satoko/satoko.h114
-rw-r--r--src/sat/satoko/solver.c718
-rw-r--r--src/sat/satoko/solver.h254
-rw-r--r--src/sat/satoko/solver_api.c445
-rw-r--r--src/sat/satoko/types.h39
-rw-r--r--src/sat/satoko/utils/b_queue.h81
-rw-r--r--src/sat/satoko/utils/heap.h178
-rwxr-xr-xsrc/sat/satoko/utils/mem.h23
-rwxr-xr-xsrc/sat/satoko/utils/misc.h35
-rw-r--r--src/sat/satoko/utils/sdbl.h133
-rw-r--r--src/sat/satoko/utils/sort.h65
-rw-r--r--src/sat/satoko/utils/vec/vec_char.h260
-rw-r--r--src/sat/satoko/utils/vec/vec_flt.h246
-rwxr-xr-xsrc/sat/satoko/utils/vec/vec_int.h240
-rwxr-xr-xsrc/sat/satoko/utils/vec/vec_sdbl.h253
-rwxr-xr-xsrc/sat/satoko/utils/vec/vec_uint.h268
-rw-r--r--src/sat/satoko/watch_list.h203
-rw-r--r--src/sat/xsat/license39
-rw-r--r--src/sat/xsat/module.make3
-rw-r--r--src/sat/xsat/xsat.h59
-rw-r--r--src/sat/xsat/xsatBQueue.h190
-rw-r--r--src/sat/xsat/xsatClause.h109
-rw-r--r--src/sat/xsat/xsatCnfReader.c236
-rw-r--r--src/sat/xsat/xsatHeap.h330
-rw-r--r--src/sat/xsat/xsatMemory.h222
-rw-r--r--src/sat/xsat/xsatSolver.c1003
-rw-r--r--src/sat/xsat/xsatSolver.h248
-rw-r--r--src/sat/xsat/xsatSolverAPI.c346
-rw-r--r--src/sat/xsat/xsatUtils.h106
-rw-r--r--src/sat/xsat/xsatWatchList.h269
52 files changed, 7999 insertions, 288 deletions
diff --git a/src/sat/bmc/bmc.h b/src/sat/bmc/bmc.h
index 30538253..a3f353c2 100644
--- a/src/sat/bmc/bmc.h
+++ b/src/sat/bmc/bmc.h
@@ -164,7 +164,8 @@ extern int Saig_ManBmcScalable( Aig_Man_t * pAig, Saig_ParBmc_t *
extern int Gia_ManBmcPerform( Gia_Man_t * p, Bmc_AndPar_t * pPars );
/*=== bmcCexCare.c ==========================================================*/
extern Abc_Cex_t * Bmc_CexCareExtendToObjects( Gia_Man_t * p, Abc_Cex_t * pCex, Abc_Cex_t * pCexCare );
-extern Abc_Cex_t * Bmc_CexCareMinimize( Aig_Man_t * p, Abc_Cex_t * pCex, int fCheck, int fVerbose );
+extern Abc_Cex_t * Bmc_CexCareMinimize( Aig_Man_t * p, int nRealPis, Abc_Cex_t * pCex, int nTryCexes, int fCheck, int fVerbose );
+extern Abc_Cex_t * Bmc_CexCareMinimizeAig( Gia_Man_t * p, int nRealPis, Abc_Cex_t * pCex, int nTryCexes, int fCheck, int fVerbose );
extern void Bmc_CexCareVerify( Aig_Man_t * p, Abc_Cex_t * pCex, Abc_Cex_t * pCexMin, int fVerbose );
/*=== bmcCexCut.c ==========================================================*/
extern Gia_Man_t * Bmc_GiaTargetStates( Gia_Man_t * p, Abc_Cex_t * pCex, int iFrBeg, int iFrEnd, int fCombOnly, int fGenAll, int fAllFrames, int fVerbose );
@@ -172,7 +173,7 @@ extern Aig_Man_t * Bmc_AigTargetStates( Aig_Man_t * p, Abc_Cex_t * pCex, i
/*=== bmcCexMin.c ==========================================================*/
extern Abc_Cex_t * Saig_ManCexMinPerform( Aig_Man_t * pAig, Abc_Cex_t * pCex );
/*=== bmcCexTool.c ==========================================================*/
-extern void Bmc_CexPrint( Abc_Cex_t * pCex, int nInputs, int fVerbose );
+extern void Bmc_CexPrint( Abc_Cex_t * pCex, int nRealPis, int fVerbose );
extern int Bmc_CexVerify( Gia_Man_t * p, Abc_Cex_t * pCex, Abc_Cex_t * pCexCare );
/*=== bmcICheck.c ==========================================================*/
extern void Bmc_PerformICheck( Gia_Man_t * p, int nFramesMax, int nTimeOut, int fEmpty, int fVerbose );
diff --git a/src/sat/bmc/bmcBmcAnd.c b/src/sat/bmc/bmcBmcAnd.c
index 8087046a..3490d34f 100644
--- a/src/sat/bmc/bmcBmcAnd.c
+++ b/src/sat/bmc/bmcBmcAnd.c
@@ -986,8 +986,7 @@ int Gia_ManBmcPerformInt( Gia_Man_t * pGia, Bmc_AndPar_t * pPars )
{
// p->pFrames = Jf_ManDeriveCnf( pTemp = p->pFrames, 1 ); Gia_ManStop( pTemp );
// p->pCnf = (Cnf_Dat_t *)p->pFrames->pData; p->pFrames->pData = NULL;
- extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose );
- p->pCnf = Mf_ManGenerateCnf( p->pFrames, pPars->nLutSize, 1, 0, pPars->fVerbose );
+ p->pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p->pFrames, pPars->nLutSize, 1, 0, 0, pPars->fVerbose );
}
Vec_IntFillExtra( p->vId2Var, Gia_ManObjNum(p->pFrames), 0 );
// create clauses for constant node
diff --git a/src/sat/bmc/bmcCexCare.c b/src/sat/bmc/bmcCexCare.c
index 21fea429..cc3e85ea 100644
--- a/src/sat/bmc/bmcCexCare.c
+++ b/src/sat/bmc/bmcCexCare.c
@@ -88,7 +88,7 @@ Abc_Cex_t * Bmc_CexCareExtendToObjects( Gia_Man_t * p, Abc_Cex_t * pCex, Abc_Cex
/**Function*************************************************************
- Synopsis [Backward propagation.]
+ Synopsis [Forward propagation.]
Description []
@@ -97,21 +97,14 @@ Abc_Cex_t * Bmc_CexCareExtendToObjects( Gia_Man_t * p, Abc_Cex_t * pCex, Abc_Cex
SeeAlso []
***********************************************************************/
-void Bmc_CexCarePropagateFwdOne( Gia_Man_t * p, Abc_Cex_t * pCex, int f, int fGrow )
+void Bmc_CexCarePropagateFwdOne( Gia_Man_t * p, Abc_Cex_t * pCex, int f, Vec_Int_t * vPriosIn )
{
Gia_Obj_t * pObj;
int Prio, Prio0, Prio1;
int i, Phase0, Phase1;
- if ( (fGrow & 2) )
- {
- Gia_ManForEachPi( p, pObj, i )
- pObj->Value = Abc_Var2Lit( f * pCex->nPis + (pCex->nPis-1-i) + 1, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i) );
- }
- else
- {
- Gia_ManForEachPi( p, pObj, i )
- pObj->Value = Abc_Var2Lit( f * pCex->nPis + i + 1, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i) );
- }
+ assert( Vec_IntSize(vPriosIn) == pCex->nPis * (pCex->iFrame + 1) );
+ Gia_ManForEachPi( p, pObj, i )
+ pObj->Value = Vec_IntEntry( vPriosIn, f * pCex->nPis + i );
Gia_ManForEachAnd( p, pObj, i )
{
Prio0 = Abc_Lit2Var(Gia_ObjFanin0(pObj)->Value);
@@ -119,37 +112,38 @@ void Bmc_CexCarePropagateFwdOne( Gia_Man_t * p, Abc_Cex_t * pCex, int f, int fGr
Phase0 = Abc_LitIsCompl(Gia_ObjFanin0(pObj)->Value) ^ Gia_ObjFaninC0(pObj);
Phase1 = Abc_LitIsCompl(Gia_ObjFanin1(pObj)->Value) ^ Gia_ObjFaninC1(pObj);
if ( Phase0 && Phase1 )
- Prio = (fGrow & 1) ? Abc_MinInt(Prio0, Prio1) : Abc_MaxInt(Prio0, Prio1);
- else if ( Phase0 && !Phase1 )
+ Prio = Abc_MinInt(Prio0, Prio1);
+ else if ( Phase0 )
Prio = Prio1;
- else if ( !Phase0 && Phase1 )
+ else if ( Phase1 )
Prio = Prio0;
else // if ( !Phase0 && !Phase1 )
- Prio = (fGrow & 1) ? Abc_MaxInt(Prio0, Prio1) : Abc_MinInt(Prio0, Prio1);
- pObj->Value = Abc_Var2Lit( Prio, Phase0 & Phase1 );
+ Prio = Abc_MaxInt(Prio0, Prio1);
+ pObj->Value = Abc_Var2Lit( Prio, Phase0 && Phase1 );
+ pObj->fPhase = 0;
}
Gia_ManForEachCo( p, pObj, i )
pObj->Value = Abc_LitNotCond( Gia_ObjFanin0(pObj)->Value, Gia_ObjFaninC0(pObj) );
}
-void Bmc_CexCarePropagateFwd( Gia_Man_t * p, Abc_Cex_t * pCex, int fGrow, Vec_Int_t * vPrios )
+void Bmc_CexCarePropagateFwd( Gia_Man_t * p, Abc_Cex_t * pCex, Vec_Int_t * vPriosIn, Vec_Int_t * vPriosFf )
{
- Gia_Obj_t * pObj, * pObjRo, * pObjRi;
- int f, i;
- Gia_ManConst0( p )->Value = 0;
- Gia_ManForEachRi( p, pObj, i )
- pObj->Value = 0;
- Vec_IntClear( vPrios );
+ Gia_Obj_t * pObjRo, * pObjRi;
+ int i, f, ValueMax = Abc_Var2Lit( pCex->nPis * (pCex->iFrame + 1), 0 );
+ Gia_ManConst0( p )->Value = ValueMax;
+ Gia_ManForEachRi( p, pObjRi, i )
+ pObjRi->Value = ValueMax;
+ Vec_IntClear( vPriosFf );
for ( f = 0; f <= pCex->iFrame; f++ )
{
Gia_ManForEachRiRo( p, pObjRi, pObjRo, i )
- Vec_IntPush( vPrios, (pObjRo->Value = pObjRi->Value) );
- Bmc_CexCarePropagateFwdOne( p, pCex, f, fGrow );
+ Vec_IntPush( vPriosFf, (pObjRo->Value = pObjRi->Value) );
+ Bmc_CexCarePropagateFwdOne( p, pCex, f, vPriosIn );
}
}
/**Function*************************************************************
- Synopsis [Forward propagation.]
+ Synopsis [Backward propagation.]
Description []
@@ -160,9 +154,9 @@ void Bmc_CexCarePropagateFwd( Gia_Man_t * p, Abc_Cex_t * pCex, int fGrow, Vec_In
***********************************************************************/
void Bmc_CexCarePropagateBwdOne( Gia_Man_t * p, Abc_Cex_t * pCex, int f, Abc_Cex_t * pCexMin )
{
- Gia_Obj_t * pObj;
+ Gia_Obj_t * pObj, * pFan0, * pFan1;
int i, Phase0, Phase1;
- Gia_ManForEachCand( p, pObj, i )
+ Gia_ManForEachCi( p, pObj, i )
pObj->fPhase = 0;
Gia_ManForEachCo( p, pObj, i )
if ( pObj->fPhase )
@@ -171,45 +165,60 @@ void Bmc_CexCarePropagateBwdOne( Gia_Man_t * p, Abc_Cex_t * pCex, int f, Abc_Cex
{
if ( !pObj->fPhase )
continue;
- Phase0 = Abc_LitIsCompl(Gia_ObjFanin0(pObj)->Value) ^ Gia_ObjFaninC0(pObj);
- Phase1 = Abc_LitIsCompl(Gia_ObjFanin1(pObj)->Value) ^ Gia_ObjFaninC1(pObj);
+ pFan0 = Gia_ObjFanin0(pObj);
+ pFan1 = Gia_ObjFanin1(pObj);
+ Phase0 = Abc_LitIsCompl(pFan0->Value) ^ Gia_ObjFaninC0(pObj);
+ Phase1 = Abc_LitIsCompl(pFan1->Value) ^ Gia_ObjFaninC1(pObj);
if ( Phase0 && Phase1 )
{
- Gia_ObjFanin0(pObj)->fPhase = 1;
- Gia_ObjFanin1(pObj)->fPhase = 1;
+ pFan0->fPhase = 1;
+ pFan1->fPhase = 1;
}
- else if ( Phase0 && !Phase1 )
- Gia_ObjFanin1(pObj)->fPhase = 1;
- else if ( !Phase0 && Phase1 )
- Gia_ObjFanin0(pObj)->fPhase = 1;
+ else if ( Phase0 )
+ pFan1->fPhase = 1;
+ else if ( Phase1 )
+ pFan0->fPhase = 1;
else // if ( !Phase0 && !Phase1 )
{
- if ( Abc_Lit2Var(Gia_ObjFanin0(pObj)->Value) <= Abc_Lit2Var(Gia_ObjFanin1(pObj)->Value) )
- Gia_ObjFanin0(pObj)->fPhase = 1;
+ if ( pFan0->fPhase || pFan1->fPhase )
+ continue;
+ if ( Gia_ObjIsPi(p, pFan0) )
+ pFan0->fPhase = 1;
+ else if ( Gia_ObjIsPi(p, pFan1) )
+ pFan1->fPhase = 1;
+// else if ( Gia_ObjIsAnd(pFan0) && Txs_ObjIsJust(p, pFan0) )
+// pFan0->fPhase = 1;
+// else if ( Gia_ObjIsAnd(pFan1) && Txs_ObjIsJust(p, pFan1) )
+// pFan1->fPhase = 1;
else
- Gia_ObjFanin1(pObj)->fPhase = 1;
+ {
+ if ( Abc_Lit2Var(pFan0->Value) > Abc_Lit2Var(pFan1->Value) )
+ pFan0->fPhase = 1;
+ else
+ pFan1->fPhase = 1;
+ }
}
}
Gia_ManForEachPi( p, pObj, i )
if ( pObj->fPhase )
Abc_InfoSetBit( pCexMin->pData, pCexMin->nRegs + pCexMin->nPis * f + i );
}
-Abc_Cex_t * Bmc_CexCarePropagateBwd( Gia_Man_t * p, Abc_Cex_t * pCex, Vec_Int_t * vPrios, int fGrow )
+Abc_Cex_t * Bmc_CexCarePropagateBwd( Gia_Man_t * p, Abc_Cex_t * pCex, Vec_Int_t * vPriosIn, Vec_Int_t * vPriosFf )
{
Abc_Cex_t * pCexMin;
- Gia_Obj_t * pObj, * pObjRo, * pObjRi;
+ Gia_Obj_t * pObjRo, * pObjRi;
int f, i;
pCexMin = Abc_CexAlloc( pCex->nRegs, pCex->nPis, pCex->iFrame + 1 );
pCexMin->iPo = pCex->iPo;
pCexMin->iFrame = pCex->iFrame;
- Gia_ManForEachCo( p, pObj, i )
- pObj->fPhase = 0;
+ Gia_ManForEachCo( p, pObjRi, i )
+ pObjRi->fPhase = 0;
for ( f = pCex->iFrame; f >= 0; f-- )
{
Gia_ManPo(p, pCex->iPo)->fPhase = (int)(f == pCex->iFrame);
- Gia_ManForEachRo( p, pObj, i )
- pObj->Value = Vec_IntEntry( vPrios, f * pCex->nRegs + i );
- Bmc_CexCarePropagateFwdOne( p, pCex, f, fGrow );
+ Gia_ManForEachRo( p, pObjRo, i )
+ pObjRo->Value = Vec_IntEntry( vPriosFf, f * pCex->nRegs + i );
+ Bmc_CexCarePropagateFwdOne( p, pCex, f, vPriosIn );
Bmc_CexCarePropagateBwdOne( p, pCex, f, pCexMin );
Gia_ManForEachRiRo( p, pObjRi, pObjRo, i )
pObjRi->fPhase = pObjRo->fPhase;
@@ -228,12 +237,26 @@ Abc_Cex_t * Bmc_CexCarePropagateBwd( Gia_Man_t * p, Abc_Cex_t * pCex, Vec_Int_t
SeeAlso []
***********************************************************************/
-Abc_Cex_t * Bmc_CexCareMinimizeAig( Gia_Man_t * p, Abc_Cex_t * pCex, int fCheck, int fVerbose )
+Abc_Cex_t * Bmc_CexCareTotal( Abc_Cex_t ** pCexes, int nCexes )
{
- int nTryCexes = 4; // belongs to range [1;4]
+ int i, k, nWords = Abc_BitWordNum( pCexes[0]->nBits );
+ Abc_Cex_t * pCexMin = Abc_CexAlloc( pCexes[0]->nRegs, pCexes[0]->nPis, pCexes[0]->iFrame + 1 );
+ pCexMin->iPo = pCexes[0]->iPo;
+ pCexMin->iFrame = pCexes[0]->iFrame;
+ for ( i = 0; i < nWords; i++ )
+ {
+ pCexMin->pData[i] = pCexes[0]->pData[i];
+ for ( k = 1; k < nCexes; k++ )
+ pCexMin->pData[i] &= pCexes[k]->pData[i];
+ }
+ return pCexMin;
+}
+Abc_Cex_t * Bmc_CexCareMinimizeAig( Gia_Man_t * p, int nRealPis, Abc_Cex_t * pCex, int nTryCexes, int fCheck, int fVerbose )
+{
+ //int nTryCexes = 4; // belongs to range [1;4]
Abc_Cex_t * pCexBest, * pCexMin[4] = {NULL};
- int k, nOnesBest, nOnesCur;
- Vec_Int_t * vPrios;
+ int k, f, i, nOnesBest, nOnesCur, Counter = 0;
+ Vec_Int_t * vPriosIn, * vPriosFf;
if ( pCex->nPis != Gia_ManPiNum(p) )
{
printf( "Given CEX does to have same number of inputs as the AIG.\n" );
@@ -255,35 +278,125 @@ Abc_Cex_t * Bmc_CexCareMinimizeAig( Gia_Man_t * p, Abc_Cex_t * pCex, int fCheck,
if ( fVerbose )
{
printf( "Original : " );
- Bmc_CexPrint( pCex, Gia_ManPiNum(p), 0 );
+ Bmc_CexPrint( pCex, nRealPis, 0 );
}
- vPrios = Vec_IntAlloc( pCex->nRegs * (pCex->iFrame + 1) );
+ vPriosIn = Vec_IntAlloc( pCex->nPis * (pCex->iFrame + 1) );
+ vPriosFf = Vec_IntAlloc( pCex->nRegs * (pCex->iFrame + 1) );
for ( k = 0; k < nTryCexes; k++ )
{
- Bmc_CexCarePropagateFwd(p, pCex, k, vPrios );
- assert( Vec_IntSize(vPrios) == pCex->nRegs * (pCex->iFrame + 1) );
+ Counter = 0;
+ Vec_IntFill( vPriosIn, pCex->nPis * (pCex->iFrame + 1), 0 );
+/*
+ if ( k == 0 )
+ {
+ for ( f = 0; f <= pCex->iFrame; f++ )
+ for ( i = nRealPis; i < Gia_ManPiNum(p); i++ )
+ Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) );
+ for ( f = 0; f <= pCex->iFrame; f++ )
+ for ( i = 0; i < nRealPis; i++ )
+ Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) );
+ }
+ else if ( k == 1 )
+ {
+ for ( f = pCex->iFrame; f >= 0; f-- )
+ for ( i = nRealPis; i < Gia_ManPiNum(p); i++ )
+ Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) );
+ for ( f = pCex->iFrame; f >= 0; f-- )
+ for ( i = 0; i < nRealPis; i++ )
+ Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) );
+ }
+ else if ( k == 2 )
+ {
+ for ( f = 0; f <= pCex->iFrame; f++ )
+ for ( i = Gia_ManPiNum(p) - 1; i >= nRealPis; i-- )
+ Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) );
+ for ( f = 0; f <= pCex->iFrame; f++ )
+ for ( i = nRealPis - 1; i >= 0; i-- )
+ Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) );
+ }
+ else if ( k == 3 )
+ {
+ for ( f = pCex->iFrame; f >= 0; f-- )
+ for ( i = Gia_ManPiNum(p) - 1; i >= nRealPis; i-- )
+ Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) );
+ for ( f = pCex->iFrame; f >= 0; f-- )
+ for ( i = nRealPis - 1; i >= 0; i-- )
+ Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) );
+ }
+ else assert( 0 );
+*/
+ if ( k == 0 )
+ {
+ for ( f = pCex->iFrame; f >= 0; f-- )
+ for ( i = Gia_ManPiNum(p) - 1; i >= nRealPis; i-- )
+ Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) );
+ for ( f = pCex->iFrame; f >= 0; f-- )
+ for ( i = nRealPis - 1; i >= 0; i-- )
+ Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) );
+ }
+ else if ( k == 1 )
+ {
+ for ( f = pCex->iFrame; f >= 0; f-- )
+ for ( i = Gia_ManPiNum(p) - 1; i >= nRealPis; i-- )
+ Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) );
+ for ( f = pCex->iFrame; f >= 0; f-- )
+ for ( i = 0; i < nRealPis; i++ )
+ Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) );
+ }
+ else if ( k == 2 )
+ {
+ for ( f = pCex->iFrame; f >= 0; f-- )
+ for ( i = nRealPis; i < Gia_ManPiNum(p); i++ )
+ Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) );
+ for ( f = pCex->iFrame; f >= 0; f-- )
+ for ( i = nRealPis - 1; i >= 0; i-- )
+ Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) );
+ }
+ else if ( k == 3 )
+ {
+ for ( f = pCex->iFrame; f >= 0; f-- )
+ for ( i = nRealPis; i < Gia_ManPiNum(p); i++ )
+ Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) );
+ for ( f = pCex->iFrame; f >= 0; f-- )
+ for ( i = 0; i < nRealPis; i++ )
+ Vec_IntWriteEntry( vPriosIn, f * pCex->nPis + i, Abc_Var2Lit(Counter++, Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i)) );
+ }
+ else assert( 0 );
+
+ assert( Counter == pCex->nPis * (pCex->iFrame + 1) );
+ Bmc_CexCarePropagateFwd( p, pCex, vPriosIn, vPriosFf );
+ assert( Vec_IntSize(vPriosFf) == pCex->nRegs * (pCex->iFrame + 1) );
if ( !Abc_LitIsCompl(Gia_ManPo(p, pCex->iPo)->Value) )
{
printf( "Counter-example is invalid.\n" );
- Vec_IntFree( vPrios );
+ Vec_IntFree( vPriosIn );
+ Vec_IntFree( vPriosFf );
return NULL;
}
- pCexMin[k] = Bmc_CexCarePropagateBwd( p, pCex, vPrios, k );
+ pCexMin[k] = Bmc_CexCarePropagateBwd( p, pCex, vPriosIn, vPriosFf );
if ( fVerbose )
{
- if ( (k & 1) )
- printf( "Decrease : " );
- else
- printf( "Increase : " );
- Bmc_CexPrint( pCexMin[k], Gia_ManPiNum(p), 0 );
+ if ( k == 0 )
+ printf( "PI- PPI-: " );
+ else if ( k == 1 )
+ printf( "PI+ PPI-: " );
+ else if ( k == 2 )
+ printf( "PI- PPI+: " );
+ else if ( k == 3 )
+ printf( "PI+ PPI+: " );
+ else assert( 0 );
+ Bmc_CexPrint( pCexMin[k], nRealPis, 0 );
}
}
- Vec_IntFree( vPrios );
+ Vec_IntFree( vPriosIn );
+ Vec_IntFree( vPriosFf );
// select the best one
pCexBest = pCexMin[0];
nOnesBest = Abc_CexCountOnes(pCexMin[0]);
for ( k = 1; k < nTryCexes; k++ )
{
+ if ( pCexMin[k] == NULL )
+ continue;
nOnesCur = Abc_CexCountOnes(pCexMin[k]);
if ( nOnesBest > nOnesCur )
{
@@ -291,25 +404,29 @@ Abc_Cex_t * Bmc_CexCareMinimizeAig( Gia_Man_t * p, Abc_Cex_t * pCex, int fCheck,
pCexBest = pCexMin[k];
}
}
- for ( k = 0; k < nTryCexes; k++ )
- if ( pCexBest != pCexMin[k] )
- Abc_CexFreeP( &pCexMin[k] );
- // verify and return
if ( fVerbose )
{
+ //Abc_Cex_t * pTotal = Bmc_CexCareTotal( pCexMin, nTryCexes );
printf( "Final : " );
- Bmc_CexPrint( pCexBest, Gia_ManPiNum(p), 0 );
+ Bmc_CexPrint( pCexBest, nRealPis, 0 );
+ //printf( "Total : " );
+ //Bmc_CexPrint( pTotal, nRealPis, 0 );
+ //Abc_CexFreeP( &pTotal );
}
+ for ( k = 0; k < nTryCexes; k++ )
+ if ( pCexMin[k] && pCexBest != pCexMin[k] )
+ Abc_CexFreeP( &pCexMin[k] );
+ // verify and return
if ( !Bmc_CexVerify( p, pCex, pCexBest ) )
printf( "Counter-example verification has failed.\n" );
else if ( fCheck )
printf( "Counter-example verification succeeded.\n" );
return pCexBest;
}
-Abc_Cex_t * Bmc_CexCareMinimize( Aig_Man_t * p, Abc_Cex_t * pCex, int fCheck, int fVerbose )
+Abc_Cex_t * Bmc_CexCareMinimize( Aig_Man_t * p, int nRealPis, Abc_Cex_t * pCex, int nTryCexes, int fCheck, int fVerbose )
{
Gia_Man_t * pGia = Gia_ManFromAigSimple( p );
- Abc_Cex_t * pCexMin = Bmc_CexCareMinimizeAig( pGia, pCex, fCheck, fVerbose );
+ Abc_Cex_t * pCexMin = Bmc_CexCareMinimizeAig( pGia, nRealPis, pCex, nTryCexes, fCheck, fVerbose );
Gia_ManStop( pGia );
return pCexMin;
}
@@ -341,7 +458,14 @@ void Bmc_CexCareVerify( Aig_Man_t * p, Abc_Cex_t * pCex, Abc_Cex_t * pCexMin, in
printf( "Counter-example verification succeeded.\n" );
Gia_ManStop( pGia );
}
-
+/*
+ {
+ Aig_Man_t * pAig = Abc_NtkToDar( pNtk, 0, 1 );
+ Abc_Cex_t * pCex = Bmc_CexCareMinimize( pAig, 3*Saig_ManPiNum(pAig)/4, 4, pAbc->pCex, 1, 1 );
+ Aig_ManStop( pAig );
+ Abc_CexFree( pCex );
+ }
+*/
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
diff --git a/src/sat/bmc/bmcCexTools.c b/src/sat/bmc/bmcCexTools.c
index 1c0d798c..9c80b278 100644
--- a/src/sat/bmc/bmcCexTools.c
+++ b/src/sat/bmc/bmcCexTools.c
@@ -304,10 +304,10 @@ void Bmc_CexBuildNetworkTest( Gia_Man_t * p, Abc_Cex_t * pCex )
SeeAlso []
***********************************************************************/
-void Bmc_CexPrint( Abc_Cex_t * pCex, int nInputs, int fVerbose )
+void Bmc_CexPrint( Abc_Cex_t * pCex, int nRealPis, int fVerbose )
{
int i, k, Count, iBit = pCex->nRegs;
- Abc_CexPrintStatsInputs( pCex, nInputs );
+ Abc_CexPrintStatsInputs( pCex, nRealPis );
if ( !fVerbose )
return;
@@ -315,7 +315,7 @@ void Bmc_CexPrint( Abc_Cex_t * pCex, int nInputs, int fVerbose )
{
Count = 0;
printf( "%3d : ", i );
- for ( k = 0; k < nInputs; k++ )
+ for ( k = 0; k < nRealPis; k++ )
{
Count += Abc_InfoHasBit(pCex->pData, iBit);
printf( "%d", Abc_InfoHasBit(pCex->pData, iBit++) );
diff --git a/src/sat/bmc/bmcChain.c b/src/sat/bmc/bmcChain.c
index 324c7f6d..5af54306 100644
--- a/src/sat/bmc/bmcChain.c
+++ b/src/sat/bmc/bmcChain.c
@@ -185,10 +185,9 @@ Gia_Man_t * Gia_ManDupPosAndPropagateInit( Gia_Man_t * p )
}
sat_solver * Gia_ManDeriveSatSolver( Gia_Man_t * p, Vec_Int_t * vSatIds )
{
-// extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose );
sat_solver * pSat;
Aig_Man_t * pAig = Gia_ManToAigSimple( p );
-// Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 );
+// Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 );
Cnf_Dat_t * pCnf = Cnf_Derive( pAig, Aig_ManCoNum(pAig) );
// save SAT vars for the primary inputs
if ( vSatIds )
diff --git a/src/sat/bmc/bmcClp.c b/src/sat/bmc/bmcClp.c
index 8a69fe56..cfc608b1 100644
--- a/src/sat/bmc/bmcClp.c
+++ b/src/sat/bmc/bmcClp.c
@@ -30,8 +30,6 @@ ABC_NAMESPACE_IMPL_START
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
-extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose );
-
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
@@ -651,7 +649,7 @@ Vec_Str_t * Bmc_CollapseOneInt2( Gia_Man_t * p, int nCubeLim, int nBTLimit, int
int iOut = 0, iLit, iVar, status, n, Count, Start;
// create SAT solver
- Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 );
+ Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 );
sat_solver * pSat[3] = {
(sat_solver *)Cnf_DataWriteIntoSolver(pCnf, 1, 0),
(sat_solver *)Cnf_DataWriteIntoSolver(pCnf, 1, 0),
@@ -841,7 +839,7 @@ Vec_Str_t * Bmc_CollapseOneOld( Gia_Man_t * p, int nCubeLim, int nBTLimit, int f
{
int fVeryVerbose = fVerbose;
int nVars = Gia_ManCiNum(p);
- Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 );
+ Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 );
sat_solver * pSat[2] = { (sat_solver *)Cnf_DataWriteIntoSolver(pCnf, 1, 0), (sat_solver *)Cnf_DataWriteIntoSolver(pCnf, 1, 0) };
sat_solver * pSatClean[2] = { (sat_solver *)Cnf_DataWriteIntoSolver(pCnf, 1, 0), (sat_solver *)Cnf_DataWriteIntoSolver(pCnf, 1, 0) };
Vec_Str_t * vSop[2] = { Vec_StrAlloc(1000), Vec_StrAlloc(1000) }, * vRes = NULL;
@@ -1173,7 +1171,7 @@ cleanup:
}
Vec_Str_t * Bmc_CollapseOne3( Gia_Man_t * p, int nCubeLim, int nBTLimit, int fCanon, int fReverse, int fVerbose )
{
- Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 );
+ Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 );
sat_solver * pSat0 = (sat_solver *)Cnf_DataWriteIntoSolver(pCnf, 1, 0);
sat_solver * pSat1 = (sat_solver *)Cnf_DataWriteIntoSolver(pCnf, 1, 0);
sat_solver * pSat2 = (sat_solver *)Cnf_DataWriteIntoSolver(pCnf, 1, 0);
@@ -1507,7 +1505,7 @@ cleanup:
}
Vec_Str_t * Bmc_CollapseOne( Gia_Man_t * p, int nCubeLim, int nBTLimit, int fCanon, int fReverse, int fVerbose )
{
- Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 );
+ Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 );
sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver(pCnf, 1, 0);
Vec_Str_t * vSop = Bmc_CollapseOne_int( pSat, Gia_ManCiNum(p), nCubeLim, nBTLimit, fCanon, fReverse, fVerbose );
sat_solver_delete( pSat );
diff --git a/src/sat/bmc/bmcEnum.c b/src/sat/bmc/bmcEnum.c
new file mode 100644
index 00000000..45aeb2b3
--- /dev/null
+++ b/src/sat/bmc/bmcEnum.c
@@ -0,0 +1,223 @@
+/**CFile****************************************************************
+
+ FileName [bmcEnum.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [SAT-based bounded model checking.]
+
+ Synopsis [Enumeration.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: bmcEnum.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "bmc.h"
+#include "sat/cnf/cnf.h"
+#include "sat/bsat/satSolver.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManDeriveOne( Gia_Man_t * p, Vec_Int_t * vValues )
+{
+ Gia_Man_t * pNew;
+ Gia_Obj_t * pObj; int i, fPhase0, fPhase1;
+ assert( Vec_IntSize(vValues) == Gia_ManCiNum(p) );
+ // propagate forward
+ Gia_ManForEachCi( p, pObj, i )
+ pObj->fPhase = Vec_IntEntry(vValues, i);
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ fPhase0 = Gia_ObjPhase(Gia_ObjFanin0(pObj)) ^ Gia_ObjFaninC0(pObj);
+ fPhase1 = Gia_ObjPhase(Gia_ObjFanin1(pObj)) ^ Gia_ObjFaninC1(pObj);
+ pObj->fPhase = fPhase0 & fPhase1;
+ }
+ // propagate backward
+ Gia_ManCleanMark0(p);
+ Gia_ManForEachCo( p, pObj, i )
+ Gia_ObjFanin0(pObj)->fMark0 = 1;
+ Gia_ManForEachAndReverse( p, pObj, i )
+ {
+ if ( !pObj->fMark0 )
+ continue;
+ fPhase0 = Gia_ObjPhase(Gia_ObjFanin0(pObj)) ^ Gia_ObjFaninC0(pObj);
+ fPhase1 = Gia_ObjPhase(Gia_ObjFanin1(pObj)) ^ Gia_ObjFaninC1(pObj);
+ if ( fPhase0 == fPhase1 )
+ {
+ assert( (int)pObj->fPhase == fPhase0 );
+ Gia_ObjFanin0(pObj)->fMark0 = 1;
+ Gia_ObjFanin1(pObj)->fMark0 = 1;
+ }
+ else if ( fPhase0 )
+ {
+ assert( fPhase1 == 0 );
+ assert( pObj->fPhase == 0 );
+ Gia_ObjFanin1(pObj)->fMark0 = 1;
+ }
+ else if ( fPhase1 )
+ {
+ assert( fPhase0 == 0 );
+ assert( pObj->fPhase == 0 );
+ Gia_ObjFanin0(pObj)->fMark0 = 1;
+ }
+ }
+ // create new
+ Gia_ManFillValue( p );
+ pNew = Gia_ManStart( Gia_ManObjNum(p) );
+ pNew->pName = Abc_UtilStrsav( p->pName );
+ pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+ Gia_ManConst0(p)->Value = 0;
+ Gia_ManForEachCi( p, pObj, i )
+ pObj->Value = Abc_LitNotCond( Gia_ManAppendCi(pNew), !Vec_IntEntry(vValues, i) );
+ Gia_ManForEachAnd( p, pObj, i )
+ {
+ if ( !pObj->fMark0 )
+ continue;
+ fPhase0 = Gia_ObjPhase(Gia_ObjFanin0(pObj)) ^ Gia_ObjFaninC0(pObj);
+ fPhase1 = Gia_ObjPhase(Gia_ObjFanin1(pObj)) ^ Gia_ObjFaninC1(pObj);
+ if ( fPhase0 == fPhase1 )
+ {
+ assert( (int)pObj->fPhase == fPhase0 );
+ if ( pObj->fPhase )
+ pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0(pObj)->Value, Gia_ObjFanin1(pObj)->Value );
+ else
+ pObj->Value = Gia_ManAppendOr( pNew, Gia_ObjFanin0(pObj)->Value, Gia_ObjFanin1(pObj)->Value );
+ }
+ else if ( fPhase0 )
+ {
+ assert( fPhase1 == 0 );
+ assert( pObj->fPhase == 0 );
+ pObj->Value = Gia_ObjFanin1(pObj)->Value;
+ }
+ else if ( fPhase1 )
+ {
+ assert( fPhase0 == 0 );
+ assert( pObj->fPhase == 0 );
+ pObj->Value = Gia_ObjFanin0(pObj)->Value;
+ }
+ }
+ Gia_ManForEachCo( p, pObj, i )
+ Gia_ManAppendCo( pNew, Gia_ObjFanin0(pObj)->Value );
+ Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+ Gia_ManCleanMark0(p);
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManDeriveOneTest2( Gia_Man_t * p )
+{
+ Gia_Man_t * pNew;
+ Vec_Int_t * vValues = Vec_IntStart( Gia_ManCiNum(p) );
+ //Vec_IntFill( vValues, Gia_ManCiNum(p), 1 );
+ pNew = Gia_ManDeriveOne( p, vValues );
+ Vec_IntFree( vValues );
+ return pNew;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Gia_ManDeriveOneTest( Gia_Man_t * p )
+{
+ int fVerbose = 1;
+ Gia_Man_t * pNew;
+ Gia_Obj_t * pObj, * pRoot;
+ Vec_Int_t * vValues = Vec_IntStart( Gia_ManCiNum(p) );
+ Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 );
+ int i, iVar, nIter, iPoVarBeg = pCnf->nVars - Gia_ManCiNum(p);
+ sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 );
+ Vec_Int_t * vLits = Vec_IntAlloc( 100 );
+ Vec_IntPush( vLits, Abc_Var2Lit( 1, 1 ) );
+ for ( nIter = 0; nIter < 10000; nIter++ )
+ {
+ int status = sat_solver_solve( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits), 0, 0, 0, 0 );
+ if ( status == l_False )
+ break;
+ // derive new set
+ assert( status == l_True );
+ for ( i = 0; i < Gia_ManCiNum(p); i++ )
+ {
+ Vec_IntWriteEntry( vValues, i, sat_solver_var_value(pSat, iPoVarBeg+i) );
+ printf( "%d", sat_solver_var_value(pSat, iPoVarBeg+i) );
+ }
+ printf( " : " );
+
+ pNew = Gia_ManDeriveOne( p, vValues );
+ // assign variables
+ Gia_ManForEachCi( pNew, pObj, i )
+ pObj->Value = iPoVarBeg+i;
+ iVar = sat_solver_nvars(pSat);
+ Gia_ManForEachAnd( pNew, pObj, i )
+ pObj->Value = iVar++;
+ sat_solver_setnvars( pSat, iVar );
+ // create new clauses
+ Gia_ManForEachAnd( pNew, pObj, i )
+ sat_solver_add_and( pSat, pObj->Value, Gia_ObjFanin0(pObj)->Value, Gia_ObjFanin1(pObj)->Value, Gia_ObjFaninC0(pObj), Gia_ObjFaninC1(pObj), 0 );
+ // add to the assumptions
+ pRoot = Gia_ManCo(pNew, 0);
+ Vec_IntPush( vLits, Abc_Var2Lit(Gia_ObjFanin0(pRoot)->Value, !Gia_ObjFaninC0(pRoot)) );
+ if ( fVerbose )
+ {
+ printf( "Iter = %5d : ", nIter );
+ printf( "And = %4d ", Gia_ManAndNum(pNew) );
+ printf( "\n" );
+ }
+ Gia_ManStop( pNew );
+ }
+ Vec_IntFree( vLits );
+ Vec_IntFree( vValues );
+ Cnf_DataFree( pCnf );
+ sat_solver_delete( pSat );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/sat/bmc/bmcExpand.c b/src/sat/bmc/bmcExpand.c
index f3ec999e..6c7a5988 100644
--- a/src/sat/bmc/bmcExpand.c
+++ b/src/sat/bmc/bmcExpand.c
@@ -33,8 +33,6 @@ ABC_NAMESPACE_IMPL_START
// iterator thought the cubes
#define Bmc_SopForEachCube( pSop, nVars, pCube ) for ( pCube = (pSop); *pCube; pCube += (nVars) + 3 )
-extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose );
-
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
@@ -93,7 +91,7 @@ int Abc_ObjExpandCubes( Vec_Str_t * vSop, Gia_Man_t * p, int nVars )
int fReverse = 0;
Vec_Int_t * vVars = Vec_IntAlloc( nVars );
- Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 );
+ Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 );
sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver(pCnf, 1, 0);
int v, n, iLit, status, nCubesNew, iCiVarBeg = sat_solver_nvars(pSat) - nVars;
diff --git a/src/sat/bmc/bmcFault.c b/src/sat/bmc/bmcFault.c
index 8dc2a57f..71eef2c4 100644
--- a/src/sat/bmc/bmcFault.c
+++ b/src/sat/bmc/bmcFault.c
@@ -280,7 +280,7 @@ static inline Cnf_Dat_t * Cnf_DeriveGiaRemapped( Gia_Man_t * p )
pCnf = Cnf_Derive( pAig, Aig_ManCoNum(pAig) );
Aig_ManStop( pAig );
return pCnf;
-// return Mf_ManGenerateCnf( p, 8, 0, 0, 0 );
+// return (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 );
}
/**Function*************************************************************
diff --git a/src/sat/bmc/bmcFx.c b/src/sat/bmc/bmcFx.c
index 9cd37c88..15ea4f05 100644
--- a/src/sat/bmc/bmcFx.c
+++ b/src/sat/bmc/bmcFx.c
@@ -30,8 +30,6 @@ ABC_NAMESPACE_IMPL_START
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
-extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose );
-
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
@@ -598,7 +596,7 @@ int Bmc_FxCompute( Gia_Man_t * p )
extern Gia_Man_t * Gia_ManDupOnsetOffset( Gia_Man_t * p );
Gia_Man_t * p2 = Gia_ManDupOnsetOffset( p );
// create SAT solver
- Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p2, 8, 0, 0, 0 );
+ Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p2, 8, 0, 0, 0, 0 );
sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 );
// compute parameters
int nOuts = Gia_ManCoNum(p);
@@ -674,7 +672,7 @@ int Bmc_FxComputeOne( Gia_Man_t * p, int nIterMax, int nDiv2Add )
{
int Extra = 1000;
// create SAT solver
- Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 );
+ Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 );
sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 );
// compute parameters
int nCiVars = Gia_ManCiNum(p); // PI count
diff --git a/src/sat/bmc/bmcGen.c b/src/sat/bmc/bmcGen.c
index 74af1b78..460c9fec 100644
--- a/src/sat/bmc/bmcGen.c
+++ b/src/sat/bmc/bmcGen.c
@@ -29,8 +29,6 @@ ABC_NAMESPACE_IMPL_START
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
-extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose );
-
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
@@ -48,13 +46,13 @@ extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfOb
***********************************************************************/
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 )
@@ -67,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];
}
}
@@ -91,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];
}
}
@@ -104,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
@@ -131,7 +129,7 @@ void Gia_ManMoFindSimulate( Gia_Man_t * p, int nWords )
int Gia_ManTestSatEnum( Gia_Man_t * p )
{
abctime clk = Abc_Clock(), clk2, clkTotal = 0;
- Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 );
+ Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( p, 8, 0, 0, 0, 0 );
sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver(pCnf, 1, 0);
int i, v, status, iLit, nWords = 1, iOutVar = 1, Count = 0;
Vec_Int_t * vVars = Vec_IntAlloc( 1000 );
diff --git a/src/sat/bmc/bmcICheck.c b/src/sat/bmc/bmcICheck.c
index a779b1ed..8d8c7c6b 100644
--- a/src/sat/bmc/bmcICheck.c
+++ b/src/sat/bmc/bmcICheck.c
@@ -392,11 +392,10 @@ int Bmc_PerformISearchOne( Gia_Man_t * p, int nFramesMax, int nTimeOut, int fRev
pCnf = Cnf_DeriveGiaRemapped( pMiter );
else
{
- extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose );
//pMiter = Jf_ManDeriveCnf( pTemp = pMiter, 0 );
//Gia_ManStop( pTemp );
//pCnf = (Cnf_Dat_t *)pMiter->pData; pMiter->pData = NULL;
- pCnf = Mf_ManGenerateCnf( pMiter, 8, 0, 0, 0 );
+ pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( pMiter, 8, 0, 0, 0, 0 );
}
/*
// collect positive literals
diff --git a/src/sat/bsat/satSolver.c b/src/sat/bsat/satSolver.c
index 88a05093..df9ada8e 100644
--- a/src/sat/bsat/satSolver.c
+++ b/src/sat/bsat/satSolver.c
@@ -151,6 +151,7 @@ static inline void order_update(sat_solver* s, int v) // updateorder
i = parent;
parent = (i - 1) / 2;
}
+
heap[i] = x;
orderpos[x] = i;
}
@@ -192,11 +193,13 @@ static inline int order_select(sat_solver* s, float random_var_freq) // selectv
int i = 0;
int child = 1;
while (child < size){
+
if (child+1 < size && s->activity[heap[child]] < s->activity[heap[child+1]])
child++;
assert(child < size);
if (s->activity[x] >= s->activity[heap[child]])
break;
+
heap[i] = heap[child];
orderpos[heap[i]] = i;
i = child;
@@ -214,138 +217,234 @@ static inline int order_select(sat_solver* s, float random_var_freq) // selectv
void sat_solver_set_var_activity(sat_solver* s, int * pVars, int nVars)
{
int i;
+ assert( s->VarActType == 1 );
for (i = 0; i < s->size; i++)
s->activity[i] = 0;
- s->var_inc = 1;
+ s->var_inc = Abc_Dbl2Word(1);
for ( i = 0; i < nVars; i++ )
{
int iVar = pVars ? pVars[i] : i;
- s->activity[iVar] = nVars-i;
+ s->activity[iVar] = Abc_Dbl2Word(nVars-i);
order_update( s, iVar );
}
}
//=================================================================================================
-// Activity functions:
+// variable activities
-#ifdef USE_FLOAT_ACTIVITY
+static inline void solver_init_activities(sat_solver* s)
+{
+ // variable activities
+ s->VarActType = 0;
+ if ( s->VarActType == 0 )
+ {
+ s->var_inc = (1 << 5);
+ s->var_decay = -1;
+ }
+ else if ( s->VarActType == 1 )
+ {
+ s->var_inc = Abc_Dbl2Word(1.0);
+ s->var_decay = Abc_Dbl2Word(1.0 / 0.95);
+ }
+ else if ( s->VarActType == 2 )
+ {
+ s->var_inc = Xdbl_FromDouble(1.0);
+ s->var_decay = Xdbl_FromDouble(1.0 / 0.950);
+ }
+ else assert(0);
-static inline void act_var_rescale(sat_solver* s) {
- double* activity = s->activity;
- int i;
- for (i = 0; i < s->size; i++)
- activity[i] *= 1e-100;
- s->var_inc *= 1e-100;
-}
-static inline void act_clause_rescale(sat_solver* s) {
-// static abctime Total = 0;
- clause** cs = (clause**)veci_begin(&s->learnts);
- int i;//, clk = Abc_Clock();
- for (i = 0; i < veci_size(&s->learnts); i++){
- float a = clause_activity(cs[i]);
- clause_setactivity(cs[i], a * (float)1e-20);
- }
- s->cla_inc *= (float)1e-20;
-
- Total += Abc_Clock() - clk;
-// printf( "Rescaling... Cla inc = %10.3f Conf = %10d ", s->cla_inc, s->stats.conflicts );
-// Abc_PrintTime( 1, "Time", Total );
-}
-static inline void act_var_bump(sat_solver* s, int v) {
- s->activity[v] += s->var_inc;
- if (s->activity[v] > 1e100)
- act_var_rescale(s);
- if (s->orderpos[v] != -1)
- order_update(s,v);
-}
-static inline void act_var_bump_global(sat_solver* s, int v) {
- if ( !s->pGlobalVars )
- return;
- s->activity[v] += (s->var_inc * 3.0 * s->pGlobalVars[v]);
- if (s->activity[v] > 1e100)
- act_var_rescale(s);
- if (s->orderpos[v] != -1)
- order_update(s,v);
-}
-static inline void act_var_bump_factor(sat_solver* s, int v) {
- if ( !s->factors )
- return;
- s->activity[v] += (s->var_inc * s->factors[v]);
- if (s->activity[v] > 1e100)
- act_var_rescale(s);
- if (s->orderpos[v] != -1)
- order_update(s,v);
-}
-static inline void act_clause_bump(sat_solver* s, clause *c) {
- float a = clause_activity(c) + s->cla_inc;
- clause_setactivity(c,a);
- if (a > 1e20) act_clause_rescale(s);
+ // clause activities
+ s->ClaActType = 0;
+ if ( s->ClaActType == 0 )
+ {
+ s->cla_inc = (1 << 11);
+ s->cla_decay = -1;
+ }
+ else
+ {
+ s->cla_inc = 1;
+ s->cla_decay = (float)(1 / 0.999);
+ }
}
-static inline void act_var_decay(sat_solver* s) { s->var_inc *= s->var_decay; }
-static inline void act_clause_decay(sat_solver* s) { s->cla_inc *= s->cla_decay; }
-
-#else
-static inline void act_var_rescale(sat_solver* s) {
- unsigned* activity = s->activity;
- int i;
- for (i = 0; i < s->size; i++)
- activity[i] >>= 19;
- s->var_inc >>= 19;
- s->var_inc = Abc_MaxInt( s->var_inc, (1<<4) );
+static inline void act_var_rescale(sat_solver* s)
+{
+ if ( s->VarActType == 0 )
+ {
+ word* activity = s->activity;
+ int i;
+ for (i = 0; i < s->size; i++)
+ activity[i] >>= 19;
+ s->var_inc >>= 19;
+ s->var_inc = Abc_MaxInt( (unsigned)s->var_inc, (1<<4) );
+ }
+ else if ( s->VarActType == 1 )
+ {
+ double* activity = (double*)s->activity;
+ int i;
+ for (i = 0; i < s->size; i++)
+ activity[i] *= 1e-100;
+ s->var_inc = Abc_Dbl2Word( Abc_Word2Dbl(s->var_inc) * 1e-100 );
+ //printf( "Rescaling var activity...\n" );
+ }
+ else if ( s->VarActType == 2 )
+ {
+ xdbl * activity = s->activity;
+ int i;
+ for (i = 0; i < s->size; i++)
+ activity[i] = Xdbl_Div( activity[i], 200 ); // activity[i] / 2^200
+ s->var_inc = Xdbl_Div( s->var_inc, 200 );
+ }
+ else assert(0);
}
-
-static inline void act_clause_rescale(sat_solver* s) {
- static abctime Total = 0;
- abctime clk = Abc_Clock();
- unsigned* activity = (unsigned *)veci_begin(&s->act_clas);
- int i;
- for (i = 0; i < veci_size(&s->act_clas); i++)
- activity[i] >>= 14;
- s->cla_inc >>= 14;
- s->cla_inc = Abc_MaxInt( s->cla_inc, (1<<10) );
- Total += Abc_Clock() - clk;
-// printf( "Rescaling... Cla inc = %5d Conf = %10d ", s->cla_inc, s->stats.conflicts );
-// Abc_PrintTime( 1, "Time", Total );
-}
-
-static inline void act_var_bump(sat_solver* s, int v) {
- s->activity[v] += s->var_inc;
- if (s->activity[v] & 0x80000000)
- act_var_rescale(s);
- if (s->orderpos[v] != -1)
- order_update(s,v);
+static inline void act_var_bump(sat_solver* s, int v)
+{
+ if ( s->VarActType == 0 )
+ {
+ s->activity[v] += s->var_inc;
+ if ((unsigned)s->activity[v] & 0x80000000)
+ act_var_rescale(s);
+ if (s->orderpos[v] != -1)
+ order_update(s,v);
+ }
+ else if ( s->VarActType == 1 )
+ {
+ double act = Abc_Word2Dbl(s->activity[v]) + Abc_Word2Dbl(s->var_inc);
+ s->activity[v] = Abc_Dbl2Word(act);
+ if (act > 1e100)
+ act_var_rescale(s);
+ if (s->orderpos[v] != -1)
+ order_update(s,v);
+ }
+ else if ( s->VarActType == 2 )
+ {
+ s->activity[v] = Xdbl_Add( s->activity[v], s->var_inc );
+ if (s->activity[v] > ABC_CONST(0x014c924d692ca61b))
+ act_var_rescale(s);
+ if (s->orderpos[v] != -1)
+ order_update(s,v);
+ }
+ else assert(0);
}
-static inline void act_var_bump_global(sat_solver* s, int v) {
- if ( !s->pGlobalVars )
+static inline void act_var_bump_global(sat_solver* s, int v)
+{
+ if ( !s->pGlobalVars || !s->pGlobalVars[v] )
return;
- s->activity[v] += (int)(s->var_inc * 3 * s->pGlobalVars[v]);
- if (s->activity[v] & 0x80000000)
- act_var_rescale(s);
- if (s->orderpos[v] != -1)
- order_update(s,v);
+ if ( s->VarActType == 0 )
+ {
+ s->activity[v] += (int)((unsigned)s->var_inc * 3);
+ if (s->activity[v] & 0x80000000)
+ act_var_rescale(s);
+ if (s->orderpos[v] != -1)
+ order_update(s,v);
+ }
+ else if ( s->VarActType == 1 )
+ {
+ double act = Abc_Word2Dbl(s->activity[v]) + Abc_Word2Dbl(s->var_inc) * 3.0;
+ s->activity[v] = Abc_Dbl2Word(act);
+ if ( act > 1e100)
+ act_var_rescale(s);
+ if (s->orderpos[v] != -1)
+ order_update(s,v);
+ }
+ else if ( s->VarActType == 2 )
+ {
+ s->activity[v] = Xdbl_Add( s->activity[v], Xdbl_Mul(s->var_inc, Xdbl_FromDouble(3.0)) );
+ if (s->activity[v] > ABC_CONST(0x014c924d692ca61b))
+ act_var_rescale(s);
+ if (s->orderpos[v] != -1)
+ order_update(s,v);
+ }
+ else assert( 0 );
}
-static inline void act_var_bump_factor(sat_solver* s, int v) {
+static inline void act_var_bump_factor(sat_solver* s, int v)
+{
if ( !s->factors )
return;
- s->activity[v] += (int)(s->var_inc * s->factors[v]);
- if (s->activity[v] & 0x80000000)
- act_var_rescale(s);
- if (s->orderpos[v] != -1)
- order_update(s,v);
+ if ( s->VarActType == 0 )
+ {
+ s->activity[v] += (int)((unsigned)s->var_inc * (float)s->factors[v]);
+ if (s->activity[v] & 0x80000000)
+ act_var_rescale(s);
+ if (s->orderpos[v] != -1)
+ order_update(s,v);
+ }
+ else if ( s->VarActType == 1 )
+ {
+ double act = Abc_Word2Dbl(s->activity[v]) + Abc_Word2Dbl(s->var_inc) * s->factors[v];
+ s->activity[v] = Abc_Dbl2Word(act);
+ if ( act > 1e100)
+ act_var_rescale(s);
+ if (s->orderpos[v] != -1)
+ order_update(s,v);
+ }
+ else if ( s->VarActType == 2 )
+ {
+ s->activity[v] = Xdbl_Add( s->activity[v], Xdbl_Mul(s->var_inc, Xdbl_FromDouble(s->factors[v])) );
+ if (s->activity[v] > ABC_CONST(0x014c924d692ca61b))
+ act_var_rescale(s);
+ if (s->orderpos[v] != -1)
+ order_update(s,v);
+ }
+ else assert( 0 );
}
-static inline void act_clause_bump(sat_solver* s, clause*c) {
- unsigned* act = (unsigned *)veci_begin(&s->act_clas) + c->lits[c->size];
- *act += s->cla_inc;
- if ( *act & 0x80000000 )
- act_clause_rescale(s);
+static inline void act_var_decay(sat_solver* s)
+{
+ if ( s->VarActType == 0 )
+ s->var_inc += (s->var_inc >> 4);
+ else if ( s->VarActType == 1 )
+ s->var_inc = Abc_Dbl2Word( Abc_Word2Dbl(s->var_inc) * Abc_Word2Dbl(s->var_decay) );
+ else if ( s->VarActType == 2 )
+ s->var_inc = Xdbl_Mul(s->var_inc, s->var_decay);
+ else assert(0);
}
-static inline void act_var_decay(sat_solver* s) { s->var_inc += (s->var_inc >> 4); }
-static inline void act_clause_decay(sat_solver* s) { s->cla_inc += (s->cla_inc >> 10); }
-
-#endif
+// clause activities
+static inline void act_clause_rescale(sat_solver* s)
+{
+ if ( s->ClaActType == 0 )
+ {
+ unsigned* activity = (unsigned *)veci_begin(&s->act_clas);
+ int i;
+ for (i = 0; i < veci_size(&s->act_clas); i++)
+ activity[i] >>= 14;
+ s->cla_inc >>= 14;
+ s->cla_inc = Abc_MaxInt( s->cla_inc, (1<<10) );
+ }
+ else
+ {
+ float* activity = (float *)veci_begin(&s->act_clas);
+ int i;
+ for (i = 0; i < veci_size(&s->act_clas); i++)
+ activity[i] *= (float)1e-20;
+ s->cla_inc *= (float)1e-20;
+ }
+}
+static inline void act_clause_bump(sat_solver* s, clause *c)
+{
+ if ( s->ClaActType == 0 )
+ {
+ unsigned* act = (unsigned *)veci_begin(&s->act_clas) + c->lits[c->size];
+ *act += s->cla_inc;
+ if ( *act & 0x80000000 )
+ act_clause_rescale(s);
+ }
+ else
+ {
+ float* act = (float *)veci_begin(&s->act_clas) + c->lits[c->size];
+ *act += s->cla_inc;
+ if (*act > 1e20)
+ act_clause_rescale(s);
+ }
+}
+static inline void act_clause_decay(sat_solver* s)
+{
+ if ( s->ClaActType == 0 )
+ s->cla_inc += (s->cla_inc >> 10);
+ else
+ s->cla_inc *= s->cla_decay;
+}
//=================================================================================================
@@ -447,7 +546,10 @@ int sat_solver_clause_new(sat_solver* s, lit* begin, lit* end, int learnt)
assert( clause_id(c) == veci_size(&s->act_clas) );
// veci_push(&s->learned, h);
// act_clause_bump(s,clause_read(s, h));
- veci_push(&s->act_clas, (1<<10));
+ if ( s->ClaActType == 0 )
+ veci_push(&s->act_clas, (1<<10));
+ else
+ veci_push(&s->act_clas, s->cla_inc);
s->stats.learnts++;
s->stats.learnts_literals += size;
}
@@ -1037,7 +1139,6 @@ sat_solver* sat_solver_new(void)
veci_new(&s->act_clas);
veci_new(&s->stack);
// veci_new(&s->model);
- veci_new(&s->act_vars);
veci_new(&s->unit_lits);
veci_new(&s->temp_clause);
veci_new(&s->conf_final);
@@ -1054,15 +1155,10 @@ sat_solver* sat_solver_new(void)
s->cap = 0;
s->qhead = 0;
s->qtail = 0;
-#ifdef USE_FLOAT_ACTIVITY
- s->var_inc = 1;
- s->cla_inc = 1;
- s->var_decay = (float)(1 / 0.95 );
- s->cla_decay = (float)(1 / 0.999);
-#else
- s->var_inc = (1 << 5);
- s->cla_inc = (1 << 11);
-#endif
+
+ solver_init_activities(s);
+ veci_new(&s->act_vars);
+
s->root_level = 0;
// s->simpdb_assigns = 0;
// s->simpdb_props = 0;
@@ -1085,6 +1181,71 @@ sat_solver* sat_solver_new(void)
return s;
}
+sat_solver* zsat_solver_new_seed(double seed)
+{
+ sat_solver* s = (sat_solver*)ABC_CALLOC( char, sizeof(sat_solver));
+
+// Vec_SetAlloc_(&s->Mem, 15);
+ Sat_MemAlloc_(&s->Mem, 15);
+ s->hLearnts = -1;
+ s->hBinary = Sat_MemAppend( &s->Mem, NULL, 2, 0, 0 );
+ s->binary = clause_read( s, s->hBinary );
+
+ s->nLearntStart = LEARNT_MAX_START_DEFAULT; // starting learned clause limit
+ s->nLearntDelta = LEARNT_MAX_INCRE_DEFAULT; // delta of learned clause limit
+ s->nLearntRatio = LEARNT_MAX_RATIO_DEFAULT; // ratio of learned clause limit
+ s->nLearntMax = s->nLearntStart;
+
+ // initialize vectors
+ veci_new(&s->order);
+ veci_new(&s->trail_lim);
+ veci_new(&s->tagged);
+// veci_new(&s->learned);
+ veci_new(&s->act_clas);
+ veci_new(&s->stack);
+// veci_new(&s->model);
+ veci_new(&s->unit_lits);
+ veci_new(&s->temp_clause);
+ veci_new(&s->conf_final);
+
+ // initialize arrays
+ s->wlists = 0;
+ s->activity = 0;
+ s->orderpos = 0;
+ s->reasons = 0;
+ s->trail = 0;
+
+ // initialize other vars
+ s->size = 0;
+ s->cap = 0;
+ s->qhead = 0;
+ s->qtail = 0;
+
+ solver_init_activities(s);
+ veci_new(&s->act_vars);
+
+ s->root_level = 0;
+// s->simpdb_assigns = 0;
+// s->simpdb_props = 0;
+ s->random_seed = seed;
+ s->progress_estimate = 0;
+// s->binary = (clause*)ABC_ALLOC( char, sizeof(clause) + sizeof(lit)*2);
+// s->binary->size_learnt = (2 << 1);
+ s->verbosity = 0;
+
+ s->stats.starts = 0;
+ s->stats.decisions = 0;
+ s->stats.propagations = 0;
+ s->stats.inspects = 0;
+ s->stats.conflicts = 0;
+ s->stats.clauses = 0;
+ s->stats.clauses_literals = 0;
+ s->stats.learnts = 0;
+ s->stats.learnts_literals = 0;
+ s->stats.tot_literals = 0;
+ return s;
+}
+
void sat_solver_setnvars(sat_solver* s,int n)
{
int var;
@@ -1102,12 +1263,8 @@ void sat_solver_setnvars(sat_solver* s,int n)
s->polarity = ABC_REALLOC(char, s->polarity, s->cap);
s->tags = ABC_REALLOC(char, s->tags, s->cap);
s->loads = ABC_REALLOC(char, s->loads, s->cap);
-#ifdef USE_FLOAT_ACTIVITY
- s->activity = ABC_REALLOC(double, s->activity, s->cap);
-#else
- s->activity = ABC_REALLOC(unsigned, s->activity, s->cap);
- s->activity2 = ABC_REALLOC(unsigned, s->activity2,s->cap);
-#endif
+ s->activity = ABC_REALLOC(word, s->activity, s->cap);
+ s->activity2 = ABC_REALLOC(word, s->activity2,s->cap);
s->pFreqs = ABC_REALLOC(char, s->pFreqs, s->cap);
if ( s->factors )
@@ -1126,11 +1283,15 @@ void sat_solver_setnvars(sat_solver* s,int n)
veci_new(&s->wlists[2*var]);
if ( s->wlists[2*var+1].ptr == NULL )
veci_new(&s->wlists[2*var+1]);
-#ifdef USE_FLOAT_ACTIVITY
- s->activity[var] = 0;
-#else
- s->activity[var] = (1<<10);
-#endif
+
+ if ( s->VarActType == 0 )
+ s->activity[var] = (1<<10);
+ else if ( s->VarActType == 1 )
+ s->activity[var] = 0;
+ else if ( s->VarActType == 2 )
+ s->activity[var] = 0;
+ else assert(0);
+
s->pFreqs[var] = 0;
if ( s->factors )
s->factors [var] = 0;
@@ -1207,7 +1368,6 @@ void sat_solver_restart( sat_solver* s )
s->hBinary = Sat_MemAppend( &s->Mem, NULL, 2, 0, 0 );
s->binary = clause_read( s, s->hBinary );
- veci_resize(&s->act_clas, 0);
veci_resize(&s->trail_lim, 0);
veci_resize(&s->order, 0);
for ( i = 0; i < s->size*2; i++ )
@@ -1220,15 +1380,13 @@ void sat_solver_restart( sat_solver* s )
// s->cap = 0;
s->qhead = 0;
s->qtail = 0;
-#ifdef USE_FLOAT_ACTIVITY
- s->var_inc = 1;
- s->cla_inc = 1;
- s->var_decay = (float)(1 / 0.95 );
- s->cla_decay = (float)(1 / 0.999 );
-#else
- s->var_inc = (1 << 5);
- s->cla_inc = (1 << 11);
-#endif
+
+
+ // variable activities
+ solver_init_activities(s);
+ veci_resize(&s->act_clas, 0);
+
+
s->root_level = 0;
// s->simpdb_assigns = 0;
// s->simpdb_props = 0;
@@ -1248,6 +1406,49 @@ void sat_solver_restart( sat_solver* s )
s->stats.tot_literals = 0;
}
+void zsat_solver_restart_seed( sat_solver* s, double seed )
+{
+ int i;
+ Sat_MemRestart( &s->Mem );
+ s->hLearnts = -1;
+ s->hBinary = Sat_MemAppend( &s->Mem, NULL, 2, 0, 0 );
+ s->binary = clause_read( s, s->hBinary );
+
+ veci_resize(&s->trail_lim, 0);
+ veci_resize(&s->order, 0);
+ for ( i = 0; i < s->size*2; i++ )
+ s->wlists[i].size = 0;
+
+ s->nDBreduces = 0;
+
+ // initialize other vars
+ s->size = 0;
+// s->cap = 0;
+ s->qhead = 0;
+ s->qtail = 0;
+
+ solver_init_activities(s);
+ veci_resize(&s->act_clas, 0);
+
+ s->root_level = 0;
+// s->simpdb_assigns = 0;
+// s->simpdb_props = 0;
+ s->random_seed = seed;
+ s->progress_estimate = 0;
+ s->verbosity = 0;
+
+ s->stats.starts = 0;
+ s->stats.decisions = 0;
+ s->stats.propagations = 0;
+ s->stats.inspects = 0;
+ s->stats.conflicts = 0;
+ s->stats.clauses = 0;
+ s->stats.clauses_literals = 0;
+ s->stats.learnts = 0;
+ s->stats.learnts_literals = 0;
+ s->stats.tot_literals = 0;
+}
+
// returns memory in bytes used by the SAT solver
double sat_solver_memory( sat_solver* s )
{
@@ -1261,13 +1462,9 @@ double sat_solver_memory( sat_solver* s )
Mem += s->cap * sizeof(char); // ABC_FREE(s->polarity );
Mem += s->cap * sizeof(char); // ABC_FREE(s->tags );
Mem += s->cap * sizeof(char); // ABC_FREE(s->loads );
-#ifdef USE_FLOAT_ACTIVITY
- Mem += s->cap * sizeof(double); // ABC_FREE(s->activity );
-#else
- Mem += s->cap * sizeof(unsigned); // ABC_FREE(s->activity );
+ Mem += s->cap * sizeof(word); // ABC_FREE(s->activity );
if ( s->activity2 )
- Mem += s->cap * sizeof(unsigned); // ABC_FREE(s->activity2);
-#endif
+ Mem += s->cap * sizeof(word); // ABC_FREE(s->activity );
if ( s->factors )
Mem += s->cap * sizeof(double); // ABC_FREE(s->factors );
Mem += s->cap * sizeof(int); // ABC_FREE(s->orderpos );
@@ -1314,7 +1511,7 @@ void sat_solver_reducedb(sat_solver* s)
s->nDBreduces++;
-// printf( "Calling reduceDB with %d learned clause limit.\n", s->nLearntMax );
+ //printf( "Calling reduceDB with %d learned clause limit.\n", s->nLearntMax );
s->nLearntMax = s->nLearntStart + s->nLearntDelta * s->nDBreduces;
// return;
@@ -1323,8 +1520,11 @@ void sat_solver_reducedb(sat_solver* s)
Sat_MemForEachLearned( pMem, c, i, k )
{
Id = clause_id(c);
- pSortValues[Id] = (((7 - Abc_MinInt(c->lbd, 7)) << 28) | (act_clas[Id] >> 4));
// pSortValues[Id] = act[Id];
+ if ( s->ClaActType == 0 )
+ pSortValues[Id] = ((7 - Abc_MinInt(c->lbd, 7)) << 28) | (act_clas[Id] >> 4);
+ else
+ pSortValues[Id] = ((7 - Abc_MinInt(c->lbd, 7)) << 28);// | (act_clas[Id] >> 4);
assert( pSortValues[Id] >= 0 );
}
@@ -1430,7 +1630,7 @@ void sat_solver_rollback( sat_solver* s )
if ( s->activity2 )
{
s->var_inc = s->var_inc2;
- memcpy( s->activity, s->activity2, sizeof(unsigned) * s->iVarPivot );
+ memcpy( s->activity, s->activity2, sizeof(word) * s->iVarPivot );
}
veci_resize(&s->order, 0);
for ( i = 0; i < s->iVarPivot; i++ )
@@ -1479,15 +1679,9 @@ void sat_solver_rollback( sat_solver* s )
// s->cap = 0;
s->qhead = 0;
s->qtail = 0;
-#ifdef USE_FLOAT_ACTIVITY
- s->var_inc = 1;
- s->cla_inc = 1;
- s->var_decay = (float)(1 / 0.95 );
- s->cla_decay = (float)(1 / 0.999 );
-#else
- s->var_inc = (1 << 5);
- s->cla_inc = (1 << 11);
-#endif
+
+ solver_init_activities(s);
+
s->root_level = 0;
s->random_seed = 91648253;
s->progress_estimate = 0;
diff --git a/src/sat/bsat/satSolver.h b/src/sat/bsat/satSolver.h
index 7ef2c9e8..5a8483c1 100644
--- a/src/sat/bsat/satSolver.h
+++ b/src/sat/bsat/satSolver.h
@@ -30,11 +30,10 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
#include "satVec.h"
#include "satClause.h"
+#include "misc/util/utilDouble.h"
ABC_NAMESPACE_HEADER_START
-//#define USE_FLOAT_ACTIVITY
-
//=================================================================================================
// Public interface:
@@ -42,6 +41,7 @@ struct sat_solver_t;
typedef struct sat_solver_t sat_solver;
extern sat_solver* sat_solver_new(void);
+extern sat_solver* zsat_solver_new_seed(double seed);
extern void sat_solver_delete(sat_solver* s);
extern int sat_solver_addclause(sat_solver* s, lit* begin, lit* end);
@@ -54,6 +54,7 @@ extern int sat_solver_push(sat_solver* s, int p);
extern void sat_solver_pop(sat_solver* s);
extern void sat_solver_set_resource_limits(sat_solver* s, ABC_INT64_T nConfLimit, ABC_INT64_T nInsLimit, ABC_INT64_T nConfLimitGlobal, ABC_INT64_T nInsLimitGlobal);
extern void sat_solver_restart( sat_solver* s );
+extern void zsat_solver_restart_seed( sat_solver* s, double seed );
extern void sat_solver_rollback( sat_solver* s );
extern int sat_solver_nvars(sat_solver* s);
@@ -106,7 +107,6 @@ struct sat_solver_t
int hBinary; // the special binary clause
clause * binary;
veci* wlists; // watcher lists
- veci act_clas; // contain clause activities
// rollback
int iVarPivot; // the pivot for variables
@@ -114,19 +114,17 @@ struct sat_solver_t
int hProofPivot; // the pivot for proof records
// activities
-#ifdef USE_FLOAT_ACTIVITY
- double var_inc; // Amount to bump next variable with.
- double var_decay; // INVERSE decay factor for variable activity: stores 1/decay.
- float cla_inc; // Amount to bump next clause with.
- float cla_decay; // INVERSE decay factor for clause activity: stores 1/decay.
- double* activity; // A heuristic measurement of the activity of a variable.
-#else
- int var_inc; // Amount to bump next variable with.
- int var_inc2; // Amount to bump next variable with.
- int cla_inc; // Amount to bump next clause with.
- unsigned* activity; // A heuristic measurement of the activity of a variable.
- unsigned* activity2; // backup variable activity
-#endif
+ int VarActType;
+ int ClaActType;
+ word var_inc; // Amount to bump next variable with.
+ word var_inc2; // Amount to bump next variable with.
+ word var_decay; // INVERSE decay factor for variable activity: stores 1/decay.
+ word* activity; // A heuristic measurement of the activity of a variable.
+ word* activity2; // backup variable activity
+ unsigned cla_inc; // Amount to bump next clause with.
+ unsigned cla_decay; // INVERSE decay factor for clause activity: stores 1/decay.
+ veci act_clas; // contain clause activities
+
char * pFreqs; // how many times this variable was assigned a value
int nVarUsed;
@@ -216,9 +214,25 @@ static int sat_solver_var_literal( sat_solver* s, int v )
static void sat_solver_act_var_clear(sat_solver* s)
{
int i;
- for (i = 0; i < s->size; i++)
- s->activity[i] = 0;
- s->var_inc = 1;
+ if ( s->VarActType == 0 )
+ {
+ for (i = 0; i < s->size; i++)
+ s->activity[i] = (1 << 10);
+ s->var_inc = (1 << 5);
+ }
+ else if ( s->VarActType == 1 )
+ {
+ for (i = 0; i < s->size; i++)
+ s->activity[i] = 0;
+ s->var_inc = 1;
+ }
+ else if ( s->VarActType == 2 )
+ {
+ for (i = 0; i < s->size; i++)
+ s->activity[i] = Xdbl_Const1();
+ s->var_inc = Xdbl_Const1();
+ }
+ else assert(0);
}
static void sat_solver_compress(sat_solver* s)
{
@@ -229,7 +243,12 @@ static void sat_solver_compress(sat_solver* s)
(void) RetValue;
}
}
-
+static void sat_solver_delete_p( sat_solver ** ps )
+{
+ if ( *ps )
+ sat_solver_delete( *ps );
+ *ps = NULL;
+}
static void sat_solver_clean_polarity(sat_solver* s, int * pVars, int nVars )
{
int i;
@@ -280,7 +299,7 @@ static inline void sat_solver_bookmark(sat_solver* s)
if ( s->activity2 )
{
s->var_inc2 = s->var_inc;
- memcpy( s->activity2, s->activity, sizeof(unsigned) * s->iVarPivot );
+ memcpy( s->activity2, s->activity, sizeof(word) * s->iVarPivot );
}
}
static inline void sat_solver_set_pivot_variables( sat_solver* s, int * pPivots, int nPivots )
diff --git a/src/sat/cnf/cnfUtil.c b/src/sat/cnf/cnfUtil.c
index 96002df8..5ccbeb0d 100644
--- a/src/sat/cnf/cnfUtil.c
+++ b/src/sat/cnf/cnfUtil.c
@@ -374,7 +374,7 @@ Cnf_Dat_t * Cnf_DataReadFromFile( char * pFileName )
// create
pCnf = ABC_CALLOC( Cnf_Dat_t, 1 );
pCnf->nVars = nVars;
- pCnf->nClauses = nClas;
+ pCnf->nClauses = Vec_IntSize(vClas)-1;
pCnf->nLiterals = Vec_IntSize(vLits);
pCnf->pClauses = ABC_ALLOC( int *, Vec_IntSize(vClas) );
pCnf->pClauses[0] = Vec_IntReleaseArray(vLits);
diff --git a/src/sat/satoko/LICENSE b/src/sat/satoko/LICENSE
new file mode 100644
index 00000000..51938137
--- /dev/null
+++ b/src/sat/satoko/LICENSE
@@ -0,0 +1,22 @@
+Copyright 2017, Bruno Schmitt - UC Berkeley / UFRGS (bruno@oschmitt.com)
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/src/sat/satoko/act_clause.h b/src/sat/satoko/act_clause.h
new file mode 100644
index 00000000..ade5e569
--- /dev/null
+++ b/src/sat/satoko/act_clause.h
@@ -0,0 +1,43 @@
+//===--- act_var.h ----------------------------------------------------------===
+//
+// satoko: Satisfiability solver
+//
+// This file is distributed under the BSD 2-Clause License.
+// See LICENSE for details.
+//
+//===------------------------------------------------------------------------===
+#ifndef satoko__act_clause_h
+#define satoko__act_clause_h
+
+#include "solver.h"
+#include "types.h"
+
+#include "misc/util/abc_global.h"
+ABC_NAMESPACE_HEADER_START
+
+static inline void clause_act_rescale(solver_t *s)
+{
+ unsigned i, cref;
+ struct clause *clause;
+
+ vec_uint_foreach(s->learnts, cref, i) {
+ clause = clause_read(s, cref);
+ clause->data[clause->size].act >>= 10;
+ }
+ s->clause_act_inc = stk_uint_max((s->clause_act_inc >> 10), (1 << 11));
+}
+
+static inline void clause_act_bump(solver_t *s, struct clause *clause)
+{
+ clause->data[clause->size].act += s->clause_act_inc;
+ if (clause->data[clause->size].act & 0x80000000)
+ clause_act_rescale(s);
+}
+
+static inline void clause_act_decay(solver_t *s)
+{
+ s->clause_act_inc += (s->clause_act_inc >> 10);
+}
+
+ABC_NAMESPACE_HEADER_END
+#endif /* satoko__act_clause_h */
diff --git a/src/sat/satoko/act_var.h b/src/sat/satoko/act_var.h
new file mode 100644
index 00000000..6b0ff98a
--- /dev/null
+++ b/src/sat/satoko/act_var.h
@@ -0,0 +1,53 @@
+//===--- act_var.h ----------------------------------------------------------===
+//
+// satoko: Satisfiability solver
+//
+// This file is distributed under the BSD 2-Clause License.
+// See LICENSE for details.
+//
+//===------------------------------------------------------------------------===
+#ifndef satoko__act_var_h
+#define satoko__act_var_h
+
+#include "solver.h"
+#include "types.h"
+#include "utils/heap.h"
+#include "utils/sdbl.h"
+
+#include "misc/util/abc_global.h"
+ABC_NAMESPACE_HEADER_START
+
+/** Re-scale the activity value for all variables.
+ */
+static inline void var_act_rescale(solver_t *s)
+{
+ unsigned i;
+ act_t *activity = vec_act_data(s->activity);
+
+ for (i = 0; i < vec_sdbl_size(s->activity); i++)
+ activity[i] = sdbl_div(activity[i], s->opts.var_act_rescale);
+ s->var_act_inc = sdbl_div(s->var_act_inc, s->opts.var_act_rescale);
+}
+
+/** Increment the activity value of one variable ('var')
+ */
+static inline void var_act_bump(solver_t *s, unsigned var)
+{
+ act_t *activity = vec_act_data(s->activity);
+
+ activity[var] = sdbl_add(activity[var], s->var_act_inc);
+ if (activity[var] > s->opts.var_act_limit)
+ var_act_rescale(s);
+ if (heap_in_heap(s->var_order, var))
+ heap_decrease(s->var_order, var);
+}
+
+/** Increment the value by which variables activity values are incremented
+ */
+static inline void var_act_decay(solver_t *s)
+{
+ s->var_act_inc = sdbl_mult(s->var_act_inc, double2sdbl(1 /s->opts.var_decay));
+}
+
+ABC_NAMESPACE_HEADER_END
+#endif /* satoko__act_var_h */
diff --git a/src/sat/satoko/cdb.h b/src/sat/satoko/cdb.h
new file mode 100644
index 00000000..32b0bf93
--- /dev/null
+++ b/src/sat/satoko/cdb.h
@@ -0,0 +1,106 @@
+//===--- cdb.h --------------------------------------------------------------===
+//
+// satoko: Satisfiability solver
+//
+// This file is distributed under the BSD 2-Clause License.
+// See LICENSE for details.
+//
+//===------------------------------------------------------------------------===
+#ifndef satoko__cdb_h
+#define satoko__cdb_h
+
+#include "clause.h"
+
+#include "misc/util/abc_global.h"
+ABC_NAMESPACE_HEADER_START
+
+/* Clauses DB data structure */
+struct cdb {
+ unsigned size;
+ unsigned cap;
+ unsigned wasted;
+ unsigned *data;
+};
+
+//===------------------------------------------------------------------------===
+// Clause DB API
+//===------------------------------------------------------------------------===
+static inline struct clause *cdb_handler(struct cdb *p, unsigned cref)
+{
+ return cref != 0xFFFFFFFF ? (struct clause *)(p->data + cref) : NULL;
+}
+
+static inline unsigned cdb_cref(struct cdb *p, unsigned *clause)
+{
+ return (unsigned)(clause - &(p->data[0]));
+}
+
+static inline void cdb_grow(struct cdb *p, unsigned cap)
+{
+ unsigned prev_cap = p->cap;
+
+ if (p->cap >= cap)
+ return;
+ while (p->cap < cap) {
+ unsigned delta = ((p->cap >> 1) + (p->cap >> 3) + 2) & (unsigned)(~1);
+ p->cap += delta;
+ assert(p->cap >= prev_cap);
+ }
+ assert(p->cap > 0);
+ p->data = satoko_realloc(unsigned, p->data, p->cap);
+}
+
+static inline struct cdb *cdb_alloc(unsigned cap)
+{
+ struct cdb *p = satoko_calloc(struct cdb, 1);
+ if (cap <= 0)
+ cap = 1024 * 1024;
+ cdb_grow(p, cap);
+ return p;
+}
+
+static inline void cdb_free(struct cdb *p)
+{
+ satoko_free(p->data);
+ satoko_free(p);
+}
+
+static inline unsigned cdb_append(struct cdb *p, unsigned size)
+{
+ unsigned prev_size;
+ assert(size > 0);
+ cdb_grow(p, p->size + size);
+ prev_size = p->size;
+ p->size += size;
+ assert(p->size > prev_size);
+ return prev_size;
+}
+
+static inline void cdb_remove(struct cdb *p, struct clause *clause)
+{
+ p->wasted += clause->size;
+}
+
+static inline void cdb_clear(struct cdb *p)
+{
+ p->wasted = 0;
+ p->size = 0;
+}
+
+static inline unsigned cdb_capacity(struct cdb *p)
+{
+ return p->cap;
+}
+
+static inline unsigned cdb_size(struct cdb *p)
+{
+ return p->size;
+}
+
+static inline unsigned cdb_wasted(struct cdb *p)
+{
+ return p->wasted;
+}
+
+ABC_NAMESPACE_HEADER_END
+#endif /* satoko__cdb_h */
diff --git a/src/sat/satoko/clause.h b/src/sat/satoko/clause.h
new file mode 100644
index 00000000..2be18cd6
--- /dev/null
+++ b/src/sat/satoko/clause.h
@@ -0,0 +1,63 @@
+//===--- clause.h -----------------------------------------------------------===
+//
+// satoko: Satisfiability solver
+//
+// This file is distributed under the BSD 2-Clause License.
+// See LICENSE for details.
+//
+//===------------------------------------------------------------------------===
+#ifndef satoko__clause_h
+#define satoko__clause_h
+
+#include "types.h"
+
+#include "misc/util/abc_global.h"
+ABC_NAMESPACE_HEADER_START
+
+struct clause {
+ unsigned f_learnt : 1;
+ unsigned f_mark : 1;
+ unsigned f_reallocd : 1;
+ unsigned f_deletable : 1;
+ unsigned lbd : 28;
+ unsigned size;
+ union {
+ unsigned lit;
+ clause_act_t act;
+ } data[0];
+};
+
+//===------------------------------------------------------------------------===
+// Clause API
+//===------------------------------------------------------------------------===
+static inline int clause_compare(const void *p1, const void *p2)
+{
+ const struct clause *c1 = (const struct clause *)p1;
+ const struct clause *c2 = (const struct clause *)p2;
+
+ if (c1->size > 2 && c2->size == 2)
+ return 1;
+ if (c1->size == 2 && c2->size > 2)
+ return 0;
+ if (c1->size == 2 && c2->size == 2)
+ return 0;
+
+ if (c1->lbd > c2->lbd)
+ return 1;
+ if (c1->lbd < c2->lbd)
+ return 0;
+
+ return c1->data[c1->size].act < c2->data[c2->size].act;
+}
+
+static inline void clause_print(struct clause *clause)
+{
+ unsigned i;
+ printf("{ ");
+ for (i = 0; i < clause->size; i++)
+ printf("%u ", clause->data[i].lit);
+ printf("}\n");
+}
+
+ABC_NAMESPACE_HEADER_END
+#endif /* satoko__clause_h */
diff --git a/src/sat/satoko/cnf_reader.c b/src/sat/satoko/cnf_reader.c
new file mode 100644
index 00000000..adb9a47b
--- /dev/null
+++ b/src/sat/satoko/cnf_reader.c
@@ -0,0 +1,156 @@
+//===--- cnf_reader.h -------------------------------------------------------===
+//
+// satoko: Satisfiability solver
+//
+// This file is distributed under the BSD 2-Clause License.
+// See LICENSE for details.
+//
+//===------------------------------------------------------------------------===
+#include <assert.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "satoko.h"
+#include "solver.h"
+#include "utils/mem.h"
+#include "utils/vec/vec_uint.h"
+
+#include "misc/util/abc_global.h"
+ABC_NAMESPACE_IMPL_START
+
+/** Read the file into an internal buffer.
+ *
+ * This function will receive a file name. The return data is a string ended
+ * with '\0'.
+ *
+ */
+static char * file_open(const char *fname)
+{
+ FILE *file = fopen(fname, "rb");
+ char *buffer;
+ int sz_file;
+ int ret;
+
+ if (file == NULL) {
+ printf("Couldn't open file: %s\n", fname);
+ return NULL;
+ }
+ fseek(file, 0, SEEK_END);
+ sz_file = ftell(file);
+ rewind(file);
+ buffer = satoko_alloc(char, sz_file + 3);
+ ret = fread(buffer, sz_file, 1, file);
+ buffer[sz_file + 0] = '\n';
+ buffer[sz_file + 1] = '\0';
+ return buffer;
+}
+
+static void skip_spaces(char **pos)
+{
+ assert(pos != NULL);
+ for (; isspace(**pos); (*pos)++);
+}
+
+static void skip_line(char **pos)
+{
+ assert(pos != NULL);
+ for(; **pos != '\n' && **pos != '\r' && **pos != EOF; (*pos)++);
+ if (**pos != EOF)
+ (*pos)++;
+ return;
+}
+
+static int read_int(char **token)
+{
+ int value = 0;
+ int neg = 0;
+
+ skip_spaces(token);
+ if (**token == '-') {
+ neg = 1;
+ (*token)++;
+ } else if (**token == '+')
+ (*token)++;
+
+ if (!isdigit(**token)) {
+ printf("Parsing error. Unexpected char: %c.\n", **token);
+ exit(EXIT_FAILURE);
+ }
+ while (isdigit(**token)) {
+ value = (value * 10) + (**token - '0');
+ (*token)++;
+ }
+ return neg ? -value : value;
+}
+
+static void read_clause(char **token, vec_uint_t *lits)
+{
+ int var;
+ unsigned sign;
+
+ vec_uint_clear(lits);
+ while (1) {
+ var = read_int(token);
+ if (var == 0)
+ break;
+ sign = (var > 0);
+ var = abs(var) - 1;
+ vec_uint_push_back(lits, var2lit((unsigned) var, (char)!sign));
+ }
+}
+
+/** Start the solver and reads the DIMAC file.
+ *
+ * Returns false upon immediate conflict.
+ */
+int satoko_parse_dimacs(char *fname, satoko_t **solver)
+{
+ satoko_t *p = NULL;
+ vec_uint_t *lits = NULL;
+ int n_var;
+ int n_clause;
+ char *buffer = file_open(fname);
+ char *token;
+
+ if (buffer == NULL)
+ return -1;
+
+ token = buffer;
+ while (1) {
+ skip_spaces(&token);
+ if (*token == 0)
+ break;
+ else if (*token == 'c')
+ skip_line(&token);
+ else if (*token == 'p') {
+ token++;
+ skip_spaces(&token);
+ for(; !isspace(*token); token++); /* skip 'cnf' */
+
+ n_var = read_int(&token);
+ n_clause = read_int(&token);
+ skip_line(&token);
+ lits = vec_uint_alloc((unsigned) n_var);
+ p = satoko_create();
+ } else {
+ if (lits == NULL) {
+ printf("There is no parameter line.\n");
+ satoko_free(buffer);
+ return -1;
+ }
+ read_clause(&token, lits);
+ if (!satoko_add_clause(p, (int*)vec_uint_data(lits), vec_uint_size(lits))) {
+ vec_uint_print(lits);
+ return 0;
+ }
+ }
+ }
+ vec_uint_free(lits);
+ satoko_free(buffer);
+ *solver = p;
+ return satoko_simplify(p);
+}
+
+ABC_NAMESPACE_IMPL_END
diff --git a/src/sat/satoko/module.make b/src/sat/satoko/module.make
new file mode 100644
index 00000000..512094ee
--- /dev/null
+++ b/src/sat/satoko/module.make
@@ -0,0 +1,3 @@
+SRC += src/sat/satoko/solver.c \
+ src/sat/satoko/solver_api.c \
+ src/sat/satoko/cnf_reader.c
diff --git a/src/sat/satoko/satoko.h b/src/sat/satoko/satoko.h
new file mode 100644
index 00000000..a0c4d216
--- /dev/null
+++ b/src/sat/satoko/satoko.h
@@ -0,0 +1,114 @@
+//===--- satoko.h -----------------------------------------------------------===
+//
+// satoko: Satisfiability solver
+//
+// This file is distributed under the BSD 2-Clause License.
+// See LICENSE for details.
+//
+//===------------------------------------------------------------------------===
+#ifndef satoko__satoko_h
+#define satoko__satoko_h
+
+#include "types.h"
+#include "misc/util/abc_global.h"
+ABC_NAMESPACE_HEADER_START
+
+/** Return valeus */
+enum {
+ SATOKO_ERR = 0,
+ SATOKO_OK = 1
+};
+
+enum {
+ SATOKO_UNDEC = 0, /* Undecided */
+ SATOKO_SAT = 1,
+ SATOKO_UNSAT = -1
+};
+
+struct solver_t_;
+typedef struct solver_t_ satoko_t;
+
+typedef struct satoko_opts satoko_opts_t;
+struct satoko_opts {
+ /* Limits */
+ long conf_limit; /* Limit on the n.of conflicts */
+ long prop_limit; /* Limit on the n.of propagations */
+
+ /* Constants used for restart heuristic */
+ double f_rst; /* Used to force a restart */
+ double b_rst; /* Used to block a restart */
+ unsigned fst_block_rst; /* Lower bound n.of conflicts for start blocking restarts */
+ unsigned sz_lbd_bqueue; /* Size of the moving avarege queue for LBD (force restart) */
+ unsigned sz_trail_bqueue; /* Size of the moving avarege queue for Trail size (block restart) */
+
+ /* Constants used for clause database reduction heuristic */
+ unsigned n_conf_fst_reduce; /* N.of conflicts before first clause databese reduction */
+ unsigned inc_reduce; /* Increment to reduce */
+ unsigned inc_special_reduce; /* Special increment to reduce */
+ unsigned lbd_freeze_clause;
+ float learnt_ratio; /* Percentage of learned clauses to remove */
+
+ /* VSIDS heuristic */
+ double var_decay;
+ float clause_decay;
+ unsigned var_act_rescale;
+ act_t var_act_limit;
+
+
+ /* Binary resolution */
+ unsigned clause_max_sz_bin_resol;
+ unsigned clause_min_lbd_bin_resol;
+ float garbage_max_ratio;
+ char verbose;
+};
+
+typedef struct satoko_stats satoko_stats_t;
+struct satoko_stats {
+ unsigned n_starts;
+ unsigned n_reduce_db;
+
+ long n_decisions;
+ long n_propagations;
+ long n_inspects;
+ long n_conflicts;
+
+ long n_original_lits;
+ long n_learnt_lits;
+};
+
+
+//===------------------------------------------------------------------------===
+extern satoko_t *satoko_create(void);
+extern void satoko_destroy(satoko_t *);
+extern void satoko_reset(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 int satoko_add_variable(satoko_t *, char);
+extern int satoko_add_clause(satoko_t *, int *, int);
+extern void satoko_assump_push(satoko_t *s, int);
+extern void satoko_assump_pop(satoko_t *s);
+extern int satoko_simplify(satoko_t *);
+extern int satoko_solve(satoko_t *);
+extern void satoko_mark_cone(satoko_t *, int *, int);
+extern void satoko_unmark_cone(satoko_t *, int *, int);
+
+extern void satoko_rollback(satoko_t *);
+extern void satoko_bookmark(satoko_t *);
+extern void satoko_unbookmark(satoko_t *);
+/* If problem is unsatisfiable under assumptions, this function is used to
+ * obtain the final conflict clause expressed in the assumptions.
+ *
+ * - It receives as inputs the solver and a pointer to a array where clause
+ * will be copied. The memory is allocated by the solver, but must be freed by
+ * the caller.
+ * - The return value is either the size of the array or -1 in case the final
+ * conflict cluase was not generated.
+ */
+extern int satoko_final_conflict(satoko_t *, unsigned *);
+
+extern satoko_stats_t satoko_stats(satoko_t *);
+
+ABC_NAMESPACE_HEADER_END
+#endif /* satoko__satoko_h */
diff --git a/src/sat/satoko/solver.c b/src/sat/satoko/solver.c
new file mode 100644
index 00000000..af3dcffb
--- /dev/null
+++ b/src/sat/satoko/solver.c
@@ -0,0 +1,718 @@
+//===--- solver.c -----------------------------------------------------------===
+//
+// satoko: Satisfiability solver
+//
+// This file is distributed under the BSD 2-Clause License.
+// See LICENSE for details.
+//
+//===------------------------------------------------------------------------===
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+#include <math.h>
+
+#include "act_clause.h"
+#include "act_var.h"
+#include "solver.h"
+#include "utils/heap.h"
+#include "utils/mem.h"
+#include "utils/sort.h"
+
+#include "misc/util/abc_global.h"
+ABC_NAMESPACE_IMPL_START
+
+//===------------------------------------------------------------------------===
+// Lit funtions
+//===------------------------------------------------------------------------===
+/**
+ * A literal is said to be redundant in a given clause if and only if all
+ * variables in its reason are either present in that clause or (recursevely)
+ * redundant.
+ */
+static inline int lit_is_removable(solver_t* s, unsigned lit, unsigned min_level)
+{
+ unsigned top = vec_uint_size(s->tagged);
+
+ assert(lit_reason(s, lit) != UNDEF);
+ vec_uint_clear(s->stack);
+ vec_uint_push_back(s->stack, lit2var(lit));
+ while (vec_uint_size(s->stack)) {
+ unsigned i;
+ unsigned var = vec_uint_pop_back(s->stack);
+ struct clause *c = clause_read(s, var_reason(s, var));
+ unsigned *lits = &(c->data[0].lit);
+
+ assert(var_reason(s, var) != UNDEF);
+ if (c->size == 2 && lit_value(s, lits[0]) == LIT_FALSE) {
+ assert(lit_value(s, lits[1]) == LIT_TRUE);
+ stk_swap(unsigned, lits[0], lits[1]);
+ }
+
+ /* Check scan the literals of the reason clause.
+ * The first literal is skiped because is the literal itself. */
+ for (i = 1; i < c->size; i++) {
+ var = lit2var(lits[i]);
+
+ /* Check if the variable has already been seen or if it
+ * was assinged a value at the decision level 0. In a
+ * positive case, there is no need to look any further */
+ if (vec_char_at(s->seen, var) || var_dlevel(s, var) == 0)
+ continue;
+
+ /* If the variable has a reason clause and if it was
+ * assingned at a 'possible' level, then we need to
+ * check if it is recursively redundant, otherwise the
+ * literal being checked is not redundant */
+ if (var_reason(s, var) != UNDEF && ((1 << (var_dlevel(s, var) & 31)) & min_level)) {
+ vec_uint_push_back(s->stack, var);
+ vec_uint_push_back(s->tagged, var);
+ vec_char_assign(s->seen, var, 1);
+ } else {
+ vec_uint_foreach_start(s->tagged, var, i, top)
+ vec_char_assign(s->seen, var, 0);
+ vec_uint_shrink(s->tagged, top);
+ return 0;
+ }
+ }
+ }
+ return 1;
+}
+
+//===------------------------------------------------------------------------===
+// Clause functions
+//===------------------------------------------------------------------------===
+/* Calculate clause LBD (Literal Block Distance):
+ * - It's the number of variables in the final conflict clause that come from
+ * different decision levels
+ */
+static inline unsigned clause_clac_lbd(solver_t *s, unsigned *lits, unsigned size)
+{
+ unsigned i;
+ unsigned lbd = 0;
+
+ s->cur_stamp++;
+ for (i = 0; i < size; i++) {
+ unsigned level = lit_dlevel(s, lits[i]);
+ if (vec_uint_at(s->stamps, level) != s->cur_stamp) {
+ vec_uint_assign(s->stamps, level, s->cur_stamp);
+ lbd++;
+ }
+ }
+ return lbd;
+}
+
+static inline void clause_bin_resolution(solver_t *s, vec_uint_t *clause_lits)
+{
+ unsigned *lits = vec_uint_data(clause_lits);
+ unsigned counter, sz, i;
+ unsigned lit;
+ unsigned neg_lit = lit_neg(lits[0]);
+ struct watcher *w;
+
+ s->cur_stamp++;
+ vec_uint_foreach(clause_lits, lit, i)
+ vec_uint_assign(s->stamps, lit2var(lit), s->cur_stamp);
+
+ counter = 0;
+ watch_list_foreach_bin(s->watches, w, neg_lit) {
+ unsigned imp_lit = w->blocker;
+ if (vec_uint_at(s->stamps, lit2var(imp_lit)) == s->cur_stamp &&
+ lit_value(s, imp_lit) == LIT_TRUE) {
+ counter++;
+ vec_uint_assign(s->stamps, lit2var(imp_lit), (s->cur_stamp - 1));
+ }
+ }
+ if (counter > 0) {
+ sz = vec_uint_size(clause_lits) - 1;
+ for (i = 1; i < vec_uint_size(clause_lits) - counter; i++)
+ if (vec_uint_at(s->stamps, lit2var(lits[i])) != s->cur_stamp) {
+ stk_swap(unsigned, lits[i], lits[sz]);
+ i--;
+ sz--;
+ }
+ vec_uint_shrink(clause_lits, vec_uint_size(clause_lits) - counter);
+ }
+}
+
+static inline void clause_minimize(solver_t *s, vec_uint_t *clause_lits)
+{
+ unsigned i, j;
+ unsigned *lits = vec_uint_data(clause_lits);
+ unsigned min_level = 0;
+ unsigned clause_size;
+
+ for (i = 1; i < vec_uint_size(clause_lits); i++) {
+ unsigned level = lit_dlevel(s, lits[i]);
+ min_level |= 1 << (level & 31);
+ }
+
+ /* Remove reduntant literals */
+ vec_uint_foreach(clause_lits, i, j)
+ vec_uint_push_back(s->tagged, lit2var(i));
+ for (i = j = 1; i < vec_uint_size(clause_lits); i++)
+ if (lit_reason(s, lits[i]) == UNDEF || !lit_is_removable(s, lits[i], min_level))
+ lits[j++] = lits[i];
+ vec_uint_shrink(clause_lits, j);
+
+ /* Binary Resolution */
+ clause_size = vec_uint_size(clause_lits);
+ if (clause_size <= s->opts.clause_max_sz_bin_resol &&
+ clause_clac_lbd(s, lits, clause_size) <= s->opts.clause_min_lbd_bin_resol)
+ clause_bin_resolution(s, clause_lits);
+}
+
+static inline void clause_realloc(struct cdb *dest, struct cdb *src, unsigned *cref)
+{
+ unsigned new_cref;
+ struct clause *new_clause;
+ struct clause *old_clause = cdb_handler(src, *cref);
+
+ if (old_clause->f_reallocd) {
+ *cref = (unsigned) old_clause->size;
+ return;
+ }
+ new_cref = cdb_append(dest, 3 + old_clause->f_learnt + old_clause->size);
+ new_clause = cdb_handler(dest, new_cref);
+ memcpy(new_clause, old_clause, (3 + old_clause->f_learnt + old_clause->size) * 4);
+ old_clause->f_reallocd = 1;
+ old_clause->size = (unsigned) new_cref;
+ *cref = new_cref;
+}
+
+//===------------------------------------------------------------------------===
+// Solver internal functions
+//===------------------------------------------------------------------------===
+static inline unsigned solver_decide(solver_t *s)
+{
+ unsigned next_var = UNDEF;
+
+ while (next_var == UNDEF || var_value(s, next_var) != VAR_UNASSING) {
+ if (heap_size(s->var_order) == 0) {
+ next_var = UNDEF;
+ return UNDEF;
+ }
+ next_var = heap_remove_min(s->var_order);
+ if (solver_has_marks(s) && !var_mark(s, next_var))
+ next_var = UNDEF;
+ }
+ return var2lit(next_var, var_polarity(s, next_var));
+}
+
+static inline void solver_new_decision(solver_t *s, unsigned lit)
+{
+ if (solver_has_marks(s) && !var_mark(s, lit2var(lit)))
+ return;
+ assert(var_value(s, lit2var(lit)) == VAR_UNASSING);
+ vec_uint_push_back(s->trail_lim, vec_uint_size(s->trail));
+ solver_enqueue(s, lit, UNDEF);
+}
+
+/* Calculate Backtrack Level from the learnt clause */
+static inline unsigned solver_calc_bt_level(solver_t *s, vec_uint_t *learnt)
+{
+ unsigned i, tmp;
+ unsigned i_max = 1;
+ unsigned *lits = vec_uint_data(learnt);
+ unsigned max = lit_dlevel(s, lits[1]);
+
+ if (vec_uint_size(learnt) == 1)
+ return 0;
+ for (i = 2; i < vec_uint_size(learnt); i++) {
+ if (lit_dlevel(s, lits[i]) > max) {
+ max = lit_dlevel(s, lits[i]);
+ i_max = i;
+ }
+ }
+ tmp = lits[1];
+ lits[1] = lits[i_max];
+ lits[i_max] = tmp;
+ return lit_dlevel(s, lits[1]);
+}
+
+/**
+ * Most books and papers explain conflict analysis and the calculation of the
+ * 1UIP (first Unique Implication Point) using an implication graph. This
+ * function, however, do not explicity constructs the graph! It inspects the
+ * trail in reverse and figure out which literals should be added to the
+ * to-be-learnt clause using the reasons of each assignment.
+ *
+ * cur_lit: current literal being analyzed.
+ * n_paths: number of unprocessed paths from conlfict node to the current
+ * literal being analyzed (cur_lit).
+ *
+ * This functions performs a backward BFS (breadth-first search) for 1UIP node.
+ * The trail works as the BFS queue. The counter of unprocessed but seen
+ * variables (n_paths) allows us to identify when 'cur_lit' is the closest
+ * cause of conflict.
+ *
+ * When 'n_paths' reaches zero it means there are no unprocessed reverse paths
+ * back from the conflict node to 'cur_lit' - meaning it is the 1UIP decision
+ * variable.
+ *
+ */
+static inline void solver_analyze(solver_t *s, unsigned cref, vec_uint_t *learnt,
+ unsigned *bt_level, unsigned *lbd)
+{
+ unsigned i;
+ unsigned *trail = vec_uint_data(s->trail);
+ unsigned idx = vec_uint_size(s->trail) - 1;
+ unsigned n_paths = 0;
+ unsigned p = UNDEF;
+ unsigned var;
+
+ vec_uint_push_back(learnt, UNDEF);
+ do {
+ struct clause *clause;
+ unsigned *lits;
+ unsigned j;
+
+ assert(cref != UNDEF);
+ clause = clause_read(s, cref);
+ lits = &(clause->data[0].lit);
+
+ if (p != UNDEF && clause->size == 2 && lit_value(s, lits[0]) == LIT_FALSE) {
+ assert(lit_value(s, lits[1]) == LIT_TRUE);
+ stk_swap(unsigned, lits[0], lits[1] );
+ }
+
+ if (clause->f_learnt)
+ clause_act_bump(s, clause);
+
+ if (clause->f_learnt && clause->lbd > 2) {
+ unsigned n_levels = clause_clac_lbd(s, lits, clause->size);
+ if (n_levels + 1 < clause->lbd) {
+ if (clause->lbd <= s->opts.lbd_freeze_clause)
+ clause->f_deletable = 0;
+ clause->lbd = n_levels;
+ }
+ }
+
+ for (j = (p == UNDEF ? 0 : 1); j < clause->size; j++) {
+ var = lit2var(lits[j]);
+ if (vec_char_at(s->seen, var) || var_dlevel(s, var) == 0)
+ continue;
+ vec_char_assign(s->seen, var, 1);
+ var_act_bump(s, var);
+ if (var_dlevel(s, var) == solver_dlevel(s)) {
+ n_paths++;
+ if (var_reason(s, var) != UNDEF && clause_read(s, var_reason(s, var))->f_learnt)
+ vec_uint_push_back(s->last_dlevel, var);
+ } else
+ vec_uint_push_back(learnt, lits[j]);
+ }
+
+ while (!vec_char_at(s->seen, lit2var(trail[idx--])));
+
+ p = trail[idx + 1];
+ cref = lit_reason(s, p);
+ vec_char_assign(s->seen, lit2var(p), 0);
+ n_paths--;
+ } while (n_paths > 0);
+
+ vec_uint_data(learnt)[0] = lit_neg(p);
+ clause_minimize(s, learnt);
+ *bt_level = solver_calc_bt_level(s, learnt);
+ *lbd = clause_clac_lbd(s, vec_uint_data(learnt), vec_uint_size(learnt));
+
+ if (vec_uint_size(s->last_dlevel) > 0) {
+ vec_uint_foreach(s->last_dlevel, var, i) {
+ if (clause_read(s, var_reason(s, var))->lbd < *lbd)
+ var_act_bump(s, var);
+ }
+ vec_uint_clear(s->last_dlevel);
+ }
+ vec_uint_foreach(s->tagged, var, i)
+ vec_char_assign(s->seen, var, 0);
+ vec_uint_clear(s->tagged);
+}
+
+static inline int solver_rst(solver_t *s)
+{
+ return b_queue_is_valid(s->bq_lbd) &&
+ (((long)b_queue_avg(s->bq_lbd) * s->opts.f_rst) > (s->sum_lbd / s->stats.n_conflicts));
+}
+
+static inline int solver_block_rst(solver_t *s)
+{
+ return s->stats.n_conflicts > (int)s->opts.fst_block_rst &&
+ b_queue_is_valid(s->bq_lbd) &&
+ ((long)vec_uint_size(s->trail) > (s->opts.b_rst * (long)b_queue_avg(s->bq_trail)));
+}
+
+static inline void solver_handle_conflict(solver_t *s, unsigned confl_cref)
+{
+ unsigned bt_level;
+ unsigned lbd;
+ unsigned cref;
+
+ vec_uint_clear(s->temp_lits);
+ solver_analyze(s, confl_cref, s->temp_lits, &bt_level, &lbd);
+ s->sum_lbd += lbd;
+ b_queue_push(s->bq_lbd, lbd);
+ solver_cancel_until(s, bt_level);
+ cref = UNDEF;
+ if (vec_uint_size(s->temp_lits) > 1) {
+ cref = solver_clause_create(s, s->temp_lits, 1);
+ clause_watch(s, cref);
+ }
+ solver_enqueue(s, vec_uint_at(s->temp_lits, 0), cref);
+ var_act_decay(s);
+ clause_act_decay(s);
+}
+
+static inline void solver_analyze_final(solver_t *s, unsigned lit)
+{
+ int i;
+
+ vec_uint_clear(s->final_conflict);
+ vec_uint_push_back(s->final_conflict, lit);
+ if (solver_dlevel(s) == 0)
+ return;
+ vec_char_assign(s->seen, lit2var(lit), 1);
+ for (i = (int) vec_uint_size(s->trail) - 1; i >= (int) vec_uint_at(s->trail_lim, 0); i--) {
+ unsigned var = lit2var(vec_uint_at(s->trail, i));
+
+ if (vec_char_at(s->seen, var)) {
+ unsigned reason = var_reason(s, var);
+ if (reason == UNDEF) {
+ assert(var_dlevel(s, var) > 0);
+ vec_uint_push_back(s->final_conflict, lit_neg(vec_uint_at(s->trail, i)));
+ } else {
+ unsigned j;
+ struct clause *clause = clause_read(s, reason);
+ for (j = (clause->size == 2 ? 0 : 1); j < clause->size; j++) {
+ if (lit_dlevel(s, clause->data[j].lit) > 0)
+ vec_char_assign(s->seen, lit2var(clause->data[j].lit), 1);
+ }
+ }
+ vec_char_assign(s->seen, var, 0);
+ }
+ }
+ vec_char_assign(s->seen, lit2var(lit), 0);
+}
+
+static inline void solver_garbage_collect(solver_t *s)
+{
+ unsigned i;
+ unsigned *array;
+ struct cdb *new_cdb = cdb_alloc(cdb_capacity(s->all_clauses) - cdb_wasted(s->all_clauses));
+
+ if (s->book_cdb)
+ s->book_cdb = 0;
+
+ for (i = 0; i < 2 * vec_char_size(s->assigns); i++) {
+ struct watcher *w;
+ watch_list_foreach(s->watches, w, i)
+ clause_realloc(new_cdb, s->all_clauses, &(w->cref));
+ }
+
+ /* Update CREFS */
+ for (i = 0; i < vec_uint_size(s->trail); i++)
+ if (lit_reason(s, vec_uint_at(s->trail, i)) != UNDEF)
+ clause_realloc(new_cdb, s->all_clauses, &(vec_uint_data(s->reasons)[lit2var(vec_uint_at(s->trail, i))]));
+
+ array = vec_uint_data(s->learnts);
+ for (i = 0; i < vec_uint_size(s->learnts); i++)
+ clause_realloc(new_cdb, s->all_clauses, &(array[i]));
+
+ array = vec_uint_data(s->originals);
+ for (i = 0; i < vec_uint_size(s->originals); i++)
+ clause_realloc(new_cdb, s->all_clauses, &(array[i]));
+
+ cdb_free(s->all_clauses);
+ s->all_clauses = new_cdb;
+}
+
+static inline void solver_reduce_cdb(solver_t *s)
+{
+ unsigned i, limit;
+ unsigned n_learnts = vec_uint_size(s->learnts);
+ unsigned cref;
+ struct clause *clause;
+ struct clause **learnts_cls;
+
+ learnts_cls = satoko_alloc(struct clause *, n_learnts);
+ vec_uint_foreach_start(s->learnts, cref, i, s->book_cl_lrnt)
+ learnts_cls[i] = clause_read(s, cref);
+
+ limit = (unsigned)(n_learnts * s->opts.learnt_ratio);
+
+ satoko_sort((void *)learnts_cls, n_learnts,
+ (int (*)(const void *, const void *)) clause_compare);
+
+ if (learnts_cls[n_learnts / 2]->lbd <= 3)
+ s->RC2 += s->opts.inc_special_reduce;
+ if (learnts_cls[n_learnts - 1]->lbd <= 6)
+ s->RC2 += s->opts.inc_special_reduce;
+
+ vec_uint_clear(s->learnts);
+ for (i = 0; i < n_learnts; i++) {
+ clause = learnts_cls[i];
+ cref = cdb_cref(s->all_clauses, (unsigned *)clause);
+ assert(clause->f_mark == 0);
+ if (clause->f_deletable && clause->lbd > 2 && clause->size > 2 && lit_reason(s, clause->data[0].lit) != cref && (i < limit)) {
+ clause->f_mark = 1;
+ s->stats.n_learnt_lits -= clause->size;
+ clause_unwatch(s, cref);
+ cdb_remove(s->all_clauses, clause);
+ } else {
+ if (!clause->f_deletable)
+ limit++;
+ clause->f_deletable = 1;
+ vec_uint_push_back(s->learnts, cref);
+ }
+ }
+ satoko_free(learnts_cls);
+
+ if (s->opts.verbose) {
+ printf("reduceDB: Keeping %7d out of %7d clauses (%5.2f %%) \n",
+ vec_uint_size(s->learnts), n_learnts,
+ 100.0 * vec_uint_size(s->learnts) / n_learnts);
+ fflush(stdout);
+ }
+ if (cdb_wasted(s->all_clauses) > cdb_size(s->all_clauses) * s->opts.garbage_max_ratio)
+ solver_garbage_collect(s);
+}
+
+//===------------------------------------------------------------------------===
+// Solver external functions
+//===------------------------------------------------------------------------===
+unsigned solver_clause_create(solver_t *s, vec_uint_t *lits, unsigned f_learnt)
+{
+ struct clause *clause;
+ unsigned cref;
+ unsigned n_words;
+
+ assert(vec_uint_size(lits) > 1);
+ assert(f_learnt == 0 || f_learnt == 1);
+
+ n_words = 3 + f_learnt + vec_uint_size(lits);
+ cref = cdb_append(s->all_clauses, n_words);
+ clause = clause_read(s, cref);
+ clause->f_learnt = f_learnt;
+ clause->f_mark = 0;
+ clause->f_reallocd = 0;
+ clause->f_deletable = f_learnt;
+ clause->size = vec_uint_size(lits);
+ memcpy(&(clause->data[0].lit), vec_uint_data(lits), sizeof(unsigned) * vec_uint_size(lits));
+
+ if (f_learnt) {
+ vec_uint_push_back(s->learnts, cref);
+ clause->lbd = clause_clac_lbd(s, vec_uint_data(lits), vec_uint_size(lits));
+ clause->data[clause->size].act = 0;
+ s->stats.n_learnt_lits += vec_uint_size(lits);
+ clause_act_bump(s, clause);
+ } else {
+ vec_uint_push_back(s->originals, cref);
+ s->stats.n_original_lits += vec_uint_size(lits);
+ }
+ return cref;
+}
+
+void solver_cancel_until(solver_t *s, unsigned level)
+{
+ int i;
+
+ if (solver_dlevel(s) <= level)
+ return;
+ for (i = (int) vec_uint_size(s->trail) - 1; i >= (int) vec_uint_at(s->trail_lim, level); i--) {
+ unsigned var = lit2var(vec_uint_at(s->trail, (unsigned) i));
+
+ vec_char_assign(s->assigns, var, VAR_UNASSING);
+ vec_uint_assign(s->reasons, var, UNDEF);
+ vec_char_assign(s->polarity, var, lit_polarity(vec_uint_at(s->trail, (unsigned) i)));
+ if (!heap_in_heap(s->var_order, var))
+ heap_insert(s->var_order, var);
+ }
+ s->i_qhead = vec_uint_at(s->trail_lim, level);
+ vec_uint_shrink(s->trail, vec_uint_at(s->trail_lim, level));
+ vec_uint_shrink(s->trail_lim, level);
+}
+
+unsigned solver_propagate(solver_t *s)
+{
+ unsigned conf_cref = UNDEF;
+ unsigned *lits;
+ unsigned neg_lit;
+ unsigned n_propagations = 0;
+
+ while (s->i_qhead < vec_uint_size(s->trail)) {
+ unsigned p = vec_uint_at(s->trail, s->i_qhead++);
+ struct watch_list *ws;
+ struct watcher *begin;
+ struct watcher *end;
+ struct watcher *i, *j;
+
+ n_propagations++;
+ watch_list_foreach_bin(s->watches, i, p) {
+ if (solver_has_marks(s) && !var_mark(s, lit2var(i->blocker)))
+ continue;
+ if (var_value(s, lit2var(i->blocker)) == VAR_UNASSING)
+ solver_enqueue(s, i->blocker, i->cref);
+ else if (lit_value(s, i->blocker) == LIT_FALSE)
+ return i->cref;
+ }
+
+ ws = vec_wl_at(s->watches, p);
+ begin = watch_list_array(ws);
+ end = begin + watch_list_size(ws);
+ for (i = j = begin + ws->n_bin; i < end;) {
+ struct clause *clause;
+ struct watcher w;
+
+ if (solver_has_marks(s) && !var_mark(s, lit2var(i->blocker))) {
+ *j++ = *i++;
+ continue;
+ }
+ if (lit_value(s, i->blocker) == LIT_TRUE) {
+ *j++ = *i++;
+ continue;
+ }
+
+ clause = clause_read(s, i->cref);
+ lits = &(clause->data[0].lit);
+
+ // Make sure the false literal is data[1]:
+ neg_lit = lit_neg(p);
+ if (lits[0] == neg_lit)
+ stk_swap(unsigned, lits[0], lits[1]);
+ assert(lits[1] == neg_lit);
+
+ w.cref = i->cref;
+ w.blocker = lits[0];
+
+ /* If 0th watch is true, then clause is already satisfied. */
+ if (lits[0] != i->blocker && lit_value(s, lits[0]) == LIT_TRUE)
+ *j++ = w;
+ else {
+ /* Look for new watch */
+ unsigned k;
+ for (k = 2; k < clause->size; k++) {
+ if (lit_value(s, lits[k]) != LIT_FALSE) {
+ lits[1] = lits[k];
+ lits[k] = neg_lit;
+ watch_list_push(vec_wl_at(s->watches, lit_neg(lits[1])), w, 0);
+ goto next;
+ }
+ }
+
+ *j++ = w;
+
+ /* Clause becomes unit under this assignment */
+ if (lit_value(s, lits[0]) == LIT_FALSE) {
+ conf_cref = i->cref;
+ s->i_qhead = vec_uint_size(s->trail);
+ i++;
+ // Copy the remaining watches:
+ while (i < end)
+ *j++ = *i++;
+ } else
+ solver_enqueue(s, lits[0], i->cref);
+ }
+ next:
+ i++;
+ }
+
+ s->stats.n_inspects += j - watch_list_array(ws);
+ watch_list_shrink(ws, j - watch_list_array(ws));
+ }
+ s->stats.n_propagations += n_propagations;
+ s->n_props_simplify -= n_propagations;
+ return conf_cref;
+}
+
+char solver_search(solver_t *s)
+{
+ s->stats.n_starts++;
+ while (1) {
+ unsigned confl_cref = solver_propagate(s);
+ if (confl_cref != UNDEF) {
+ s->stats.n_conflicts++;
+ if (solver_dlevel(s) == 0)
+ return SATOKO_UNSAT;
+ /* Restart heuristic */
+ b_queue_push(s->bq_trail, vec_uint_size(s->trail));
+ if (solver_block_rst(s))
+ b_queue_clean(s->bq_lbd);
+ solver_handle_conflict(s, confl_cref);
+ } else {
+ /* No conflict */
+ unsigned next_lit;
+
+ if (solver_rst(s)) {
+ b_queue_clean(s->bq_lbd);
+ solver_cancel_until(s, 0);
+ return SATOKO_UNDEC;
+ }
+ if (solver_dlevel(s) == 0)
+ satoko_simplify(s);
+
+ /* Reduce the set of learnt clauses */
+ if (s->opts.learnt_ratio &&
+ s->stats.n_conflicts >= s->n_confl_bfr_reduce) {
+ s->RC1 = (s->stats.n_conflicts / s->RC2) + 1;
+ solver_reduce_cdb(s);
+ s->RC2 += s->opts.inc_reduce;
+ s->n_confl_bfr_reduce = s->RC1 * s->RC2;
+ }
+
+ /* Make decisions based on user assumptions */
+ next_lit = UNDEF;
+ while (solver_dlevel(s) < vec_uint_size(s->assumptions)) {
+ unsigned lit = vec_uint_at(s->assumptions, solver_dlevel(s));
+ if (lit_value(s, lit) == LIT_TRUE) {
+ vec_uint_push_back(s->trail_lim, vec_uint_size(s->trail));
+ } else if (lit_value(s, lit) == LIT_FALSE) {
+ solver_analyze_final(s, lit_neg(lit));
+ return SATOKO_UNSAT;
+ } else {
+ next_lit = lit;
+ break;
+ }
+
+ }
+ if (next_lit == UNDEF) {
+ s->stats.n_decisions++;
+ next_lit = solver_decide(s);
+ if (next_lit == UNDEF)
+ return SATOKO_SAT;
+ }
+ solver_new_decision(s, next_lit);
+ }
+ }
+}
+
+//===------------------------------------------------------------------------===
+// Debug procedure
+//===------------------------------------------------------------------------===
+void solver_debug_check(solver_t *s, int result)
+{
+ unsigned cref, i;
+ unsigned *array;
+
+ printf("Checking for trail(%u) inconsistencies...", vec_uint_size(s->trail));
+ array = vec_uint_data(s->trail);
+ for (i = 1; i < vec_uint_size(s->trail); i++)
+ if (array[i - 1] == lit_neg(array[i])) {
+ printf("Inconsistent trail: %u %u\n", array[i - 1], array[i]);
+ return;
+ }
+ printf(" TRAIL OK\n");
+
+ printf("Checking clauses... \n");
+ vec_uint_foreach(s->originals, cref, i) {
+ unsigned j;
+ struct clause *clause = clause_read(s, cref);
+ for (j = 0; j < clause->size; j++) {
+ if (vec_uint_find(s->trail, clause->data[j].lit)) {
+ break;
+ }
+ }
+ if (result == SATOKO_SAT && j == clause->size) {
+ printf("FOUND UNSAT CLAUSE!!!!\n");
+ clause_print(clause);
+ }
+ }
+}
+
+ABC_NAMESPACE_IMPL_END
diff --git a/src/sat/satoko/solver.h b/src/sat/satoko/solver.h
new file mode 100644
index 00000000..33f8ce88
--- /dev/null
+++ b/src/sat/satoko/solver.h
@@ -0,0 +1,254 @@
+//===--- solver.h -----------------------------------------------------------===
+//
+// satoko: Satisfiability solver
+//
+// This file is distributed under the BSD 2-Clause License.
+// See LICENSE for details.
+//
+//===------------------------------------------------------------------------===
+#ifndef satoko__solver_h
+#define satoko__solver_h
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "clause.h"
+#include "cdb.h"
+#include "satoko.h"
+#include "types.h"
+#include "watch_list.h"
+#include "utils/b_queue.h"
+#include "utils/heap.h"
+#include "utils/mem.h"
+#include "utils/misc.h"
+#include "utils/vec/vec_char.h"
+#include "utils/vec/vec_sdbl.h"
+#include "utils/vec/vec_uint.h"
+
+#include "misc/util/abc_global.h"
+ABC_NAMESPACE_HEADER_START
+
+enum {
+ LIT_FALSE = 1,
+ LIT_TRUE = 0,
+ VAR_UNASSING = 3
+};
+
+#define UNDEF 0xFFFFFFFF
+
+typedef struct solver_t_ solver_t;
+struct solver_t_ {
+ /* User data */
+ vec_uint_t *assumptions;
+ vec_uint_t *final_conflict;
+
+ /* Clauses Database */
+ struct cdb *all_clauses;
+ vec_uint_t *learnts;
+ vec_uint_t *originals;
+ vec_wl_t *watches;
+
+ /* Activity heuristic */
+ act_t var_act_inc; /* Amount to bump next variable with. */
+ clause_act_t clause_act_inc; /* Amount to bump next clause with. */
+
+ /* Variable Information */
+ vec_act_t *activity; /* A heuristic measurement of the activity of a variable. */
+ heap_t *var_order;
+ vec_uint_t *levels; /* Decision level of the current assignment */
+ vec_uint_t *reasons; /* Reason (clause) of the current assignment */
+ vec_char_t *assigns;
+ vec_char_t *polarity;
+
+ /* Assignments */
+ vec_uint_t *trail;
+ vec_uint_t *trail_lim; /* Separator indices for different decision levels in 'trail'. */
+ unsigned i_qhead; /* Head of propagation queue (as index into the trail). */
+ unsigned n_assigns_simplify; /* Number of top-level assignments since
+ last execution of 'simplify()'. */
+ long n_props_simplify; /* Remaining number of propagations that
+ must be made before next execution of
+ 'simplify()'. */
+
+ /* Temporary data used by Analyze */
+ vec_uint_t *temp_lits;
+ vec_char_t *seen;
+ vec_uint_t *tagged; /* Stack */
+ vec_uint_t *stack;
+ vec_uint_t *last_dlevel;
+
+ /* Temporary data used by Search method */
+ b_queue_t *bq_trail;
+ b_queue_t *bq_lbd;
+ long RC1;
+ long RC2;
+ long n_confl_bfr_reduce;
+ float sum_lbd;
+
+ /* Misc temporary */
+ unsigned cur_stamp; /* Used for marking literals and levels of interest */
+ vec_uint_t *stamps; /* Multipurpose stamp used to calculate LBD and
+ * clauses minimization with binary resolution */
+
+ /* Bookmark */
+ unsigned book_cl_orig; /* Bookmark for orignal problem clauses vector */
+ unsigned book_cl_lrnt; /* Bookmark for learnt clauses vector */
+ unsigned book_cdb; /* Bookmark clause database size */
+ unsigned book_vars; /* Bookmark number of variables */
+ unsigned book_trail; /* Bookmark trail size */
+
+ /* Temporary data used for solving cones */
+ vec_char_t *marks;
+
+ struct satoko_stats stats;
+ struct satoko_opts opts;
+};
+
+//===------------------------------------------------------------------------===
+extern unsigned solver_clause_create(solver_t *, vec_uint_t *, unsigned);
+extern char solver_search(solver_t *);
+extern void solver_cancel_until(solver_t *, unsigned);
+extern unsigned solver_propagate(solver_t *);
+extern void solver_debug_check(solver_t *, int);
+
+//===------------------------------------------------------------------------===
+// Inline var/lit functions
+//===------------------------------------------------------------------------===
+static inline unsigned var2lit(unsigned var, char polarity)
+{
+ return var + var + ((unsigned) polarity != 0);
+}
+
+static inline unsigned lit2var(unsigned lit)
+{
+ return lit >> 1;
+}
+//===------------------------------------------------------------------------===
+// Inline var functions
+//===------------------------------------------------------------------------===
+static inline char var_value(solver_t *s, unsigned var)
+{
+ return vec_char_at(s->assigns, var);
+}
+
+static inline char var_polarity(solver_t *s, unsigned var)
+{
+ return vec_char_at(s->polarity, var);
+}
+
+static inline unsigned var_dlevel(solver_t *s, unsigned var)
+{
+ return vec_uint_at(s->levels, var);
+}
+
+static inline unsigned var_reason(solver_t *s, unsigned var)
+{
+ return vec_uint_at(s->reasons, var);
+}
+static inline int var_mark(solver_t *s, unsigned var)
+{
+ return (int)vec_char_at(s->marks, var);
+}
+static inline void var_set_mark(solver_t *s, unsigned var)
+{
+ vec_char_assign(s->marks, var, 1);
+}
+static inline void var_clean_mark(solver_t *s, unsigned var)
+{
+ vec_char_assign(s->marks, var, 0);
+}
+//===------------------------------------------------------------------------===
+// Inline lit functions
+//===------------------------------------------------------------------------===
+static inline unsigned lit_neg(unsigned lit)
+{
+ return lit ^ 1;
+}
+
+static inline char lit_polarity(unsigned lit)
+{
+ return (char)(lit & 1);
+}
+
+static inline char lit_value(solver_t *s, unsigned lit)
+{
+ return lit_polarity(lit) ^ vec_char_at(s->assigns, lit2var(lit));
+}
+
+static inline unsigned lit_dlevel(solver_t *s, unsigned lit)
+{
+ return vec_uint_at(s->levels, lit2var(lit));
+}
+
+static inline unsigned lit_reason(solver_t *s, unsigned lit)
+{
+ return vec_uint_at(s->reasons, lit2var(lit));
+}
+//===------------------------------------------------------------------------===
+// Inline solver minor functions
+//===------------------------------------------------------------------------===
+static inline unsigned solver_check_limits(solver_t *s)
+{
+ return (s->opts.conf_limit == 0 || s->opts.conf_limit >= s->stats.n_conflicts) &&
+ (s->opts.prop_limit == 0 || s->opts.prop_limit >= s->stats.n_propagations);
+}
+
+/** Returns current decision level */
+static inline unsigned solver_dlevel(solver_t *s)
+{
+ return vec_uint_size(s->trail_lim);
+}
+
+static inline int solver_enqueue(solver_t *s, unsigned lit, unsigned reason)
+{
+ unsigned var = lit2var(lit);
+
+ vec_char_assign(s->assigns, var, lit_polarity(lit));
+ vec_uint_assign(s->levels, var, solver_dlevel(s));
+ vec_uint_assign(s->reasons, var, reason);
+ vec_uint_push_back(s->trail, lit);
+ return SATOKO_OK;
+}
+
+static inline int solver_varnum(solver_t *s)
+{
+ return vec_char_size(s->assigns);
+}
+static inline int solver_has_marks(solver_t *s)
+{
+ return (int)(s->marks != NULL);
+}
+
+//===------------------------------------------------------------------------===
+// Inline clause functions
+//===------------------------------------------------------------------------===
+static inline struct clause *clause_read(solver_t *s, unsigned cref)
+{
+ return cdb_handler(s->all_clauses, cref);
+}
+
+static inline void clause_watch(solver_t *s, unsigned cref)
+{
+ struct clause *clause = cdb_handler(s->all_clauses, cref);
+ struct watcher w1;
+ struct watcher w2;
+
+ w1.cref = cref;
+ w2.cref = cref;
+ w1.blocker = clause->data[1].lit;
+ w2.blocker = clause->data[0].lit;
+ watch_list_push(vec_wl_at(s->watches, lit_neg(clause->data[0].lit)), w1, (clause->size == 2));
+ watch_list_push(vec_wl_at(s->watches, lit_neg(clause->data[1].lit)), w2, (clause->size == 2));
+}
+
+static inline void clause_unwatch(solver_t *s, unsigned cref)
+{
+ struct clause *clause = cdb_handler(s->all_clauses, cref);
+ watch_list_remove(vec_wl_at(s->watches, lit_neg(clause->data[0].lit)), cref, (clause->size == 2));
+ watch_list_remove(vec_wl_at(s->watches, lit_neg(clause->data[1].lit)), cref, (clause->size == 2));
+}
+
+ABC_NAMESPACE_HEADER_END
+#endif /* satoko__solver_h */
diff --git a/src/sat/satoko/solver_api.c b/src/sat/satoko/solver_api.c
new file mode 100644
index 00000000..3cb9f3d3
--- /dev/null
+++ b/src/sat/satoko/solver_api.c
@@ -0,0 +1,445 @@
+//===--- solver_api.h -------------------------------------------------------===
+//
+// satoko: Satisfiability solver
+//
+// This file is distributed under the BSD 2-Clause License.
+// See LICENSE for details.
+//
+//===------------------------------------------------------------------------===
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+#include <math.h>
+
+#include "act_var.h"
+#include "solver.h"
+#include "utils/misc.h"
+
+#include "misc/util/abc_global.h"
+ABC_NAMESPACE_IMPL_START
+
+//===------------------------------------------------------------------------===
+// Satoko internal functions
+//===------------------------------------------------------------------------===
+static inline void solver_rebuild_order(solver_t *s)
+{
+ unsigned var;
+ vec_uint_t *vars = vec_uint_alloc(vec_char_size(s->assigns));
+
+ for (var = 0; var < vec_char_size(s->assigns); var++)
+ if (var_value(s, var) == VAR_UNASSING)
+ vec_uint_push_back(vars, var);
+ heap_build(s->var_order, vars);
+ vec_uint_free(vars);
+}
+
+static inline int clause_is_satisfied(solver_t *s, struct clause *clause)
+{
+ unsigned i;
+ unsigned *lits = &(clause->data[0].lit);
+ for (i = 0; i < clause->size; i++)
+ if (lit_value(s, lits[i]) == LIT_TRUE)
+ return SATOKO_OK;
+ return SATOKO_ERR;
+}
+
+static inline void print_opts(solver_t *s)
+{
+ printf( "+-[ BLACK MAGIC - PARAMETERS ]-+\n");
+ printf( "| |\n");
+ printf( "|--> Restarts heuristic |\n");
+ printf( "| * LBD Queue = %6d |\n", s->opts.sz_lbd_bqueue);
+ printf( "| * Trail Queue = %6d |\n", s->opts.sz_trail_bqueue);
+ printf( "| * f_rst = %6.2f |\n", s->opts.f_rst);
+ printf( "| * b_rst = %6.2f |\n", s->opts.b_rst);
+ printf( "| |\n");
+ printf( "|--> Clause DB reduction: |\n");
+ printf( "| * First = %6d |\n", s->opts.n_conf_fst_reduce);
+ printf( "| * Inc = %6d |\n", s->opts.inc_reduce);
+ printf( "| * Special Inc = %6d |\n", s->opts.inc_special_reduce);
+ printf( "| * Protected (LBD) < %2d |\n", s->opts.lbd_freeze_clause);
+ printf( "| |\n");
+ printf( "|--> Binary resolution: |\n");
+ printf( "| * Clause size < %3d |\n", s->opts.clause_max_sz_bin_resol);
+ printf( "| * Clause lbd < %3d |\n", s->opts.clause_min_lbd_bin_resol);
+ printf( "+------------------------------+\n\n");
+}
+
+static inline void print_stats(solver_t *s)
+{
+ printf("starts : %10d\n", s->stats.n_starts);
+ printf("conflicts : %10ld\n", s->stats.n_conflicts);
+ printf("decisions : %10ld\n", s->stats.n_decisions);
+ printf("propagations : %10ld\n", s->stats.n_propagations);
+}
+
+//===------------------------------------------------------------------------===
+// Satoko external functions
+//===------------------------------------------------------------------------===
+solver_t * satoko_create()
+{
+ solver_t *s = satoko_calloc(solver_t, 1);
+
+ satoko_default_opts(&s->opts);
+ /* User data */
+ s->assumptions = vec_uint_alloc(0);
+ s->final_conflict = vec_uint_alloc(0);
+ /* Clauses Database */
+ s->all_clauses = cdb_alloc(0);
+ s->originals = vec_uint_alloc(0);
+ s->learnts = vec_uint_alloc(0);
+ s->watches = vec_wl_alloc(0);
+ /* Activity heuristic */
+ s->var_act_inc = VAR_ACT_INIT_INC;
+ s->clause_act_inc = CLAUSE_ACT_INIT_INC;
+ /* Variable Information */
+ s->activity = vec_act_alloc(0);
+ s->var_order = heap_alloc(s->activity);
+ s->levels = vec_uint_alloc(0);
+ s->reasons = vec_uint_alloc(0);
+ s->assigns = vec_char_alloc(0);
+ s->polarity = vec_char_alloc(0);
+ /* Assignments */
+ s->trail = vec_uint_alloc(0);
+ s->trail_lim = vec_uint_alloc(0);
+ /* Temporary data used by Search method */
+ s->bq_trail = b_queue_alloc(s->opts.sz_trail_bqueue);
+ s->bq_lbd = b_queue_alloc(s->opts.sz_lbd_bqueue);
+ s->n_confl_bfr_reduce = s->opts.n_conf_fst_reduce;
+ s->RC1 = 1;
+ s->RC2 = s->opts.n_conf_fst_reduce;
+ /* Temporary data used by Analyze */
+ s->temp_lits = vec_uint_alloc(0);
+ s->seen = vec_char_alloc(0);
+ s->tagged = vec_uint_alloc(0);
+ s->stack = vec_uint_alloc(0);
+ s->last_dlevel = vec_uint_alloc(0);
+ /* Misc temporary */
+ s->stamps = vec_uint_alloc(0);
+ return s;
+}
+
+void satoko_destroy(solver_t *s)
+{
+ vec_uint_free(s->assumptions);
+ vec_uint_free(s->final_conflict);
+ cdb_free(s->all_clauses);
+ vec_uint_free(s->originals);
+ vec_uint_free(s->learnts);
+ vec_wl_free(s->watches);
+ vec_act_free(s->activity);
+ heap_free(s->var_order);
+ vec_uint_free(s->levels);
+ vec_uint_free(s->reasons);
+ vec_char_free(s->assigns);
+ vec_char_free(s->polarity);
+ vec_uint_free(s->trail);
+ vec_uint_free(s->trail_lim);
+ b_queue_free(s->bq_lbd);
+ b_queue_free(s->bq_trail);
+ vec_uint_free(s->temp_lits);
+ vec_char_free(s->seen);
+ vec_uint_free(s->tagged);
+ vec_uint_free(s->stack);
+ vec_uint_free(s->last_dlevel);
+ vec_uint_free(s->stamps);
+ if (s->marks)
+ vec_char_free(s->marks);
+ satoko_free(s);
+}
+
+void satoko_default_opts(satoko_opts_t *opts)
+{
+ memset(opts, 0, sizeof(satoko_opts_t));
+ opts->verbose = 0;
+ /* Limits */
+ opts->conf_limit = 0;
+ opts->prop_limit = 0;
+ /* Constants used for restart heuristic */
+ opts->f_rst = 0.8;
+ opts->b_rst = 1.4;
+ opts->fst_block_rst = 10000;
+ opts->sz_lbd_bqueue = 50;
+ opts->sz_trail_bqueue = 5000;
+ /* Constants used for clause database reduction heuristic */
+ opts->n_conf_fst_reduce = 2000;
+ opts->inc_reduce = 300;
+ opts->inc_special_reduce = 1000;
+ opts->lbd_freeze_clause = 30;
+ opts->learnt_ratio = 0.5;
+ /* VSIDS heuristic */
+ opts->var_act_limit = VAR_ACT_LIMIT;
+ opts->var_act_rescale = VAR_ACT_RESCALE;
+ opts->var_decay = 0.95;
+ opts->clause_decay = (clause_act_t) 0.995;
+ /* Binary resolution */
+ opts->clause_max_sz_bin_resol = 30;
+ opts->clause_min_lbd_bin_resol = 6;
+
+ opts->garbage_max_ratio = (float) 0.3;
+}
+
+/**
+ * TODO: sanity check on configuration options
+ */
+void satoko_configure(satoko_t *s, satoko_opts_t *user_opts)
+{
+ assert(user_opts);
+ memcpy(&s->opts, user_opts, sizeof(satoko_opts_t));
+}
+
+int satoko_simplify(solver_t * s)
+{
+ unsigned i, j = 0;
+ unsigned cref;
+
+ assert(solver_dlevel(s) == 0);
+ if (solver_propagate(s) != UNDEF)
+ return SATOKO_ERR;
+ if (s->n_assigns_simplify == vec_uint_size(s->trail) || s->n_props_simplify > 0)
+ return SATOKO_OK;
+
+ vec_uint_foreach(s->originals, cref, i) {
+ struct clause *clause = clause_read(s, cref);
+
+ if (clause_is_satisfied(s, clause)) {
+ clause->f_mark = 1;
+ s->stats.n_original_lits -= clause->size;
+ clause_unwatch(s, cref);
+ } else
+ vec_uint_assign(s->originals, j++, cref);
+ }
+ vec_uint_shrink(s->originals, j);
+ solver_rebuild_order(s);
+ s->n_assigns_simplify = vec_uint_size(s->trail);
+ s->n_props_simplify = s->stats.n_original_lits + s->stats.n_learnt_lits;
+ return SATOKO_OK;
+}
+
+int satoko_add_variable(solver_t *s, char sign)
+{
+ unsigned var = vec_act_size(s->activity);
+ vec_wl_push(s->watches);
+ vec_wl_push(s->watches);
+ vec_act_push_back(s->activity, 0);
+ vec_uint_push_back(s->levels, 0);
+ vec_char_push_back(s->assigns, VAR_UNASSING);
+ vec_char_push_back(s->polarity, sign);
+ vec_uint_push_back(s->reasons, UNDEF);
+ vec_uint_push_back(s->stamps, 0);
+ vec_char_push_back(s->seen, 0);
+ 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, int *lits, int size)
+{
+ unsigned i, j;
+ unsigned prev_lit;
+ unsigned max_var;
+ unsigned cref;
+
+ qsort((void *) lits, size, sizeof(unsigned), stk_uint_compare);
+ max_var = lit2var(lits[size - 1]);
+ while (max_var >= vec_act_size(s->activity))
+ satoko_add_variable(s, LIT_FALSE);
+
+ vec_uint_clear(s->temp_lits);
+ j = 0;
+ prev_lit = UNDEF;
+ for (i = 0; i < (unsigned)size; i++) {
+ if ((unsigned)lits[i] == lit_neg(prev_lit) || lit_value(s, lits[i]) == LIT_TRUE)
+ return SATOKO_OK;
+ else if ((unsigned)lits[i] != prev_lit && var_value(s, lit2var(lits[i])) == VAR_UNASSING) {
+ prev_lit = lits[i];
+ vec_uint_push_back(s->temp_lits, lits[i]);
+ }
+ }
+
+ if (vec_uint_size(s->temp_lits) == 0)
+ return SATOKO_ERR;
+ if (vec_uint_size(s->temp_lits) == 1) {
+ solver_enqueue(s, vec_uint_at(s->temp_lits, 0), UNDEF);
+ return (solver_propagate(s) == UNDEF);
+ }
+
+ cref = solver_clause_create(s, s->temp_lits, 0);
+ clause_watch(s, cref);
+ return SATOKO_OK;
+}
+
+void satoko_assump_push(solver_t *s, int lit)
+{
+ vec_uint_push_back(s->assumptions, lit);
+}
+
+void satoko_assump_pop(solver_t *s)
+{
+ assert(vec_uint_size(s->assumptions) > 0);
+ vec_uint_pop_back(s->assumptions);
+ solver_cancel_until(s, vec_uint_size(s->assumptions));
+}
+
+int satoko_solve(solver_t *s)
+{
+ char status = SATOKO_UNDEC;
+
+ assert(s);
+ //if (s->opts.verbose)
+ // print_opts(s);
+
+ while (status == SATOKO_UNDEC) {
+ status = solver_search(s);
+ if (solver_check_limits(s) == 0)
+ break;
+ }
+ if (s->opts.verbose)
+ print_stats(s);
+ solver_cancel_until(s, vec_uint_size(s->assumptions));
+ return status;
+}
+
+int satoko_final_conflict(solver_t *s, unsigned *out)
+{
+ if (vec_uint_size(s->final_conflict) == 0)
+ return -1;
+ out = satoko_alloc(unsigned, vec_uint_size(s->final_conflict));
+ memcpy(out, vec_uint_data(s->final_conflict),
+ sizeof(unsigned) * vec_uint_size(s->final_conflict));
+ return vec_uint_size(s->final_conflict);
+
+}
+
+satoko_stats_t satoko_stats(satoko_t *s)
+{
+ return s->stats;
+}
+
+void satoko_bookmark(satoko_t *s)
+{
+ assert(solver_dlevel(s) == 0);
+ s->book_cl_orig = vec_uint_size(s->originals);
+ s->book_cl_lrnt = vec_uint_size(s->learnts);
+ s->book_vars = vec_char_size(s->assigns);
+ s->book_trail = vec_uint_size(s->trail);
+}
+
+void satoko_unbookmark(satoko_t *s)
+{
+ s->book_cl_orig = 0;
+ s->book_cl_lrnt = 0;
+ s->book_cdb = 0;
+ s->book_vars = 0;
+ s->book_trail = 0;
+}
+
+void satoko_reset(satoko_t *s)
+{
+ vec_uint_clear(s->assumptions);
+ vec_uint_clear(s->final_conflict);
+ cdb_clear(s->all_clauses);
+ vec_uint_clear(s->originals);
+ vec_uint_clear(s->learnts);
+ vec_wl_clean(s->watches);
+ vec_act_clear(s->activity);
+ heap_clear(s->var_order);
+ vec_uint_clear(s->levels);
+ vec_uint_clear(s->reasons);
+ vec_char_clear(s->assigns);
+ vec_char_clear(s->polarity);
+ vec_uint_clear(s->trail);
+ vec_uint_clear(s->trail_lim);
+ b_queue_clean(s->bq_lbd);
+ b_queue_clean(s->bq_trail);
+ vec_uint_clear(s->temp_lits);
+ vec_char_clear(s->seen);
+ vec_uint_clear(s->tagged);
+ vec_uint_clear(s->stack);
+ vec_uint_clear(s->last_dlevel);
+ vec_uint_clear(s->stamps);
+ s->var_act_inc = VAR_ACT_INIT_INC;
+ s->clause_act_inc = CLAUSE_ACT_INIT_INC;
+ s->n_confl_bfr_reduce = s->opts.n_conf_fst_reduce;
+ s->RC1 = 1;
+ s->RC2 = s->opts.n_conf_fst_reduce;
+ s->book_cl_orig = 0;
+ s->book_cl_lrnt = 0;
+ s->book_cdb = 0;
+ s->book_vars = 0;
+ s->book_trail = 0;
+}
+
+void satoko_rollback(satoko_t *s)
+{
+ unsigned i, cref;
+ unsigned n_originals = vec_uint_size(s->originals) - s->book_cl_orig;
+ unsigned n_learnts = vec_uint_size(s->learnts) - s->book_cl_lrnt;
+ struct clause **cl_to_remove;
+
+ assert(solver_dlevel(s) == 0);
+ if (!s->book_vars) {
+ satoko_reset(s);
+ return;
+ }
+
+ cl_to_remove = satoko_alloc(struct clause *, n_originals + n_learnts);
+ /* Mark clauses */
+ vec_uint_foreach_start(s->originals, cref, i, s->book_cl_orig)
+ cl_to_remove[i] = clause_read(s, cref);
+ vec_uint_foreach_start(s->learnts, cref, i, s->book_cl_lrnt)
+ cl_to_remove[n_originals + i] = clause_read(s, cref);
+ for (i = 0; i < n_originals + n_learnts; i++) {
+ 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 */
+ for (i = s->book_vars; i < 2 * vec_char_size(s->assigns); i++) {
+ vec_wl_at(s->watches, i)->size = 0;
+ vec_wl_at(s->watches, i)->n_bin = 0;
+ }
+ s->watches->size = s->book_vars;
+ vec_act_shrink(s->activity, s->book_vars);
+ vec_uint_shrink(s->levels, s->book_vars);
+ vec_uint_shrink(s->reasons, s->book_vars);
+ vec_uint_shrink(s->stamps, s->book_vars);
+ vec_char_shrink(s->assigns, s->book_vars);
+ vec_char_shrink(s->seen, s->book_vars);
+ vec_char_shrink(s->polarity, s->book_vars);
+ solver_rebuild_order(s);
+ /* Rewind solver and cancel level 0 assignments to the trail */
+ solver_cancel_until(s, 0);
+ vec_uint_shrink(s->trail, s->book_trail);
+ if (s->book_cdb)
+ s->all_clauses->size = s->book_cdb;
+ s->book_cl_orig = 0;
+ s->book_cl_lrnt = 0;
+ s->book_vars = 0;
+ s->book_trail = 0;
+}
+
+void satoko_mark_cone(satoko_t *s, int * pvars, int n_vars)
+{
+ int i;
+ if (!solver_has_marks(s))
+ s->marks = vec_char_init(solver_varnum(s), 0);
+ for (i = 0; i < n_vars; i++) {
+ var_set_mark(s, pvars[i]);
+ if (!heap_in_heap(s->var_order, pvars[i]))
+ heap_insert(s->var_order, pvars[i]);
+ }
+}
+
+void satoko_unmark_cone(satoko_t *s, int *pvars, int n_vars)
+{
+ int i;
+ assert(solver_has_marks(s));
+ for (i = 0; i < n_vars; i++)
+ var_clean_mark(s, pvars[i]);
+}
+
+ABC_NAMESPACE_IMPL_END
diff --git a/src/sat/satoko/types.h b/src/sat/satoko/types.h
new file mode 100644
index 00000000..06c190ab
--- /dev/null
+++ b/src/sat/satoko/types.h
@@ -0,0 +1,39 @@
+//===--- types.h ------------------------------------------------------------===
+//
+// satoko: Satisfiability solver
+//
+// This file is distributed under the BSD 2-Clause License.
+// See LICENSE for details.
+//
+//===------------------------------------------------------------------------===
+#ifndef satoko__types_h
+#define satoko__types_h
+
+#include "utils/sdbl.h"
+#include "utils/vec/vec_sdbl.h"
+
+#include "misc/util/abc_global.h"
+ABC_NAMESPACE_HEADER_START
+
+/* In Satoko ABC version this file is useless */
+
+#define VAR_ACT_INIT_INC SDBL_CONST1
+#define VAR_ACT_LIMIT ABC_CONST(0x014c924d692ca61b)
+#define VAR_ACT_RESCALE 200
+typedef sdbl_t act_t;
+typedef vec_sdbl_t vec_act_t ;
+#define vec_act_alloc(size) vec_sdbl_alloc(size)
+#define vec_act_free(vec) vec_sdbl_free(vec)
+#define vec_act_size(vec) vec_sdbl_size(vec)
+#define vec_act_data(vec) vec_sdbl_data(vec)
+#define vec_act_clear(vec) vec_sdbl_clear(vec)
+#define vec_act_shrink(vec, size) vec_sdbl_shrink(vec, size)
+#define vec_act_at(vec, idx) vec_sdbl_at(vec, idx)
+#define vec_act_push_back(vec, value) vec_sdbl_push_back(vec, value)
+
+
+#define CLAUSE_ACT_INIT_INC (1 << 11)
+typedef unsigned clause_act_t;
+
+ABC_NAMESPACE_HEADER_END
+#endif /* satoko__types_h */
diff --git a/src/sat/satoko/utils/b_queue.h b/src/sat/satoko/utils/b_queue.h
new file mode 100644
index 00000000..b9b62676
--- /dev/null
+++ b/src/sat/satoko/utils/b_queue.h
@@ -0,0 +1,81 @@
+//===--- b_queue.h ----------------------------------------------------------===
+//
+// satoko: Satisfiability solver
+//
+// This file is distributed under the BSD 2-Clause License.
+// See LICENSE for details.
+//
+//===------------------------------------------------------------------------===
+#ifndef satoko__utils__b_queue_h
+#define satoko__utils__b_queue_h
+
+#include "mem.h"
+
+#include "misc/util/abc_global.h"
+ABC_NAMESPACE_HEADER_START
+
+/* Bounded Queue */
+typedef struct b_queue_t_ b_queue_t;
+struct b_queue_t_ {
+ unsigned size;
+ unsigned cap;
+ unsigned i_first;
+ unsigned i_empty;
+ unsigned long sum;
+ unsigned *data;
+};
+
+//===------------------------------------------------------------------------===
+// Bounded Queue API
+//===------------------------------------------------------------------------===
+static inline b_queue_t *b_queue_alloc(unsigned cap)
+{
+ b_queue_t *p = satoko_calloc(b_queue_t, 1);
+ p->cap = cap;
+ p->data = satoko_calloc(unsigned, cap);
+ return p;
+}
+
+static inline void b_queue_free(b_queue_t *p)
+{
+ satoko_free(p->data);
+ satoko_free(p);
+}
+
+static inline void b_queue_push(b_queue_t *p, unsigned Value)
+{
+ if (p->size == p->cap) {
+ assert(p->i_first == p->i_empty);
+ p->sum -= p->data[p->i_first];
+ p->i_first = (p->i_first + 1) % p->cap;
+ } else
+ p->size++;
+
+ p->sum += Value;
+ p->data[p->i_empty] = Value;
+ if ((++p->i_empty) == p->cap) {
+ p->i_empty = 0;
+ p->i_first = 0;
+ }
+}
+
+static inline unsigned b_queue_avg(b_queue_t *p)
+{
+ return (unsigned)(p->sum / ((unsigned long) p->size));
+}
+
+static inline unsigned b_queue_is_valid(b_queue_t *p)
+{
+ return (p->cap == p->size);
+}
+
+static inline void b_queue_clean(b_queue_t *p)
+{
+ p->i_first = 0;
+ p->i_empty = 0;
+ p->size = 0;
+ p->sum = 0;
+}
+
+ABC_NAMESPACE_HEADER_END
+#endif /* satoko__utils__b_queue_h */
diff --git a/src/sat/satoko/utils/heap.h b/src/sat/satoko/utils/heap.h
new file mode 100644
index 00000000..391b8a7e
--- /dev/null
+++ b/src/sat/satoko/utils/heap.h
@@ -0,0 +1,178 @@
+//===--- heap.h ----------------------------------------------------------===
+//
+// satoko: Satisfiability solver
+//
+// This file is distributed under the BSD 2-Clause License.
+// See LICENSE for details.
+//
+//===------------------------------------------------------------------------===
+#ifndef satoko__utils__heap_h
+#define satoko__utils__heap_h
+
+#include "mem.h"
+#include "../types.h"
+#include "vec/vec_sdbl.h"
+#include "vec/vec_int.h"
+#include "vec/vec_uint.h"
+
+#include "misc/util/abc_global.h"
+ABC_NAMESPACE_HEADER_START
+
+typedef struct heap_t_ heap_t;
+struct heap_t_ {
+ vec_int_t *indices;
+ vec_uint_t *data;
+ vec_act_t *weights;
+};
+//===------------------------------------------------------------------------===
+// Heap internal functions
+//===------------------------------------------------------------------------===
+static inline unsigned left(unsigned i) { return 2 * i + 1; }
+static inline unsigned right(unsigned i) { return (i + 1) * 2; }
+static inline unsigned parent(unsigned i) { return (i - 1) >> 1; }
+
+static inline int compare(heap_t *p, unsigned x, unsigned y)
+{
+ return vec_act_at(p->weights, x) > vec_act_at(p->weights, y);
+}
+
+static inline void heap_percolate_up(heap_t *h, unsigned i)
+{
+ unsigned x = vec_uint_at(h->data, i);
+ unsigned p = parent(i);
+
+ while (i != 0 && compare(h, x, vec_uint_at(h->data, p))) {
+ vec_uint_assign(h->data, i, vec_uint_at(h->data, p));
+ vec_int_assign(h->indices, vec_uint_at(h->data, p), (int) i);
+ i = p;
+ p = parent(p);
+ }
+ vec_uint_assign(h->data, i, x);
+ vec_int_assign(h->indices, x, (int) i);
+}
+
+static inline void heap_percolate_down(heap_t *h, unsigned i)
+{
+ unsigned x = vec_uint_at(h->data, i);
+
+ while (left(i) < vec_uint_size(h->data)) {
+ unsigned child = right(i) < vec_uint_size(h->data) &&
+ compare(h, vec_uint_at(h->data, right(i)), vec_uint_at(h->data, left(i)))
+ ? right(i)
+ : left(i);
+
+ if (!compare(h, vec_uint_at(h->data, child), x))
+ break;
+
+ vec_uint_assign(h->data, i, vec_uint_at(h->data, child));
+ vec_int_assign(h->indices, vec_uint_at(h->data, i), (int) i);
+ i = child;
+ }
+ vec_uint_assign(h->data, i, x);
+ vec_int_assign(h->indices, x, (int) i);
+}
+
+//===------------------------------------------------------------------------===
+// Heap API
+//===------------------------------------------------------------------------===
+static inline heap_t *heap_alloc(vec_act_t *weights)
+{
+ heap_t *p = satoko_alloc(heap_t, 1);
+ p->weights = weights;
+ p->indices = vec_int_alloc(0);
+ p->data = vec_uint_alloc(0);
+ return p;
+}
+
+static inline void heap_free(heap_t *p)
+{
+ vec_int_free(p->indices);
+ vec_uint_free(p->data);
+ satoko_free(p);
+}
+
+static inline unsigned heap_size(heap_t *p)
+{
+ return vec_uint_size(p->data);
+}
+
+static inline int heap_in_heap(heap_t *p, unsigned entry)
+{
+ return (entry < vec_int_size(p->indices)) &&
+ (vec_int_at(p->indices, entry) >= 0);
+}
+
+static inline void heap_increase(heap_t *p, unsigned entry)
+{
+ assert(heap_in_heap(p, entry));
+ heap_percolate_down(p, (unsigned) vec_int_at(p->indices, entry));
+}
+
+static inline void heap_decrease(heap_t *p, unsigned entry)
+{
+ assert(heap_in_heap(p, entry));
+ heap_percolate_up(p, (unsigned) vec_int_at(p->indices, entry));
+}
+
+static inline void heap_insert(heap_t *p, unsigned entry)
+{
+ if (vec_int_size(p->indices) < entry + 1) {
+ unsigned old_size = vec_int_size(p->indices);
+ unsigned i;
+ int e;
+ vec_int_resize(p->indices, entry + 1);
+ vec_int_foreach_start(p->indices, e, i, old_size)
+ vec_int_assign(p->indices, i, -1);
+ }
+ assert(!heap_in_heap(p, entry));
+ vec_int_assign(p->indices, entry, (int) vec_uint_size(p->data));
+ vec_uint_push_back(p->data, entry);
+ heap_percolate_up(p, (unsigned) vec_int_at(p->indices, entry));
+}
+
+static inline void heap_update(heap_t *p, unsigned i)
+{
+ if (!heap_in_heap(p, i))
+ heap_insert(p, i);
+ else {
+ heap_percolate_up(p, (unsigned) vec_int_at(p->indices, i));
+ heap_percolate_down(p, (unsigned) vec_int_at(p->indices, i));
+ }
+}
+
+static inline void heap_build(heap_t *p, vec_uint_t *entries)
+{
+ int i;
+ unsigned j, entry;
+
+ vec_uint_foreach(p->data, entry, j)
+ vec_int_assign(p->indices, entry, -1);
+ vec_uint_clear(p->data);
+ vec_uint_foreach(entries, entry, j) {
+ vec_int_assign(p->indices, entry, (int) j);
+ vec_uint_push_back(p->data, entry);
+ }
+ for ((i = vec_uint_size(p->data) / 2 - 1); i >= 0; i--)
+ heap_percolate_down(p, (unsigned) i);
+}
+
+static inline void heap_clear(heap_t *p)
+{
+ vec_int_clear(p->indices);
+ vec_uint_clear(p->data);
+}
+
+static inline unsigned heap_remove_min(heap_t *p)
+{
+ unsigned x = vec_uint_at(p->data, 0);
+ vec_uint_assign(p->data, 0, vec_uint_at(p->data, vec_uint_size(p->data) - 1));
+ vec_int_assign(p->indices, vec_uint_at(p->data, 0), 0);
+ vec_int_assign(p->indices, x, -1);
+ vec_uint_pop_back(p->data);
+ if (vec_uint_size(p->data) > 1)
+ heap_percolate_down(p, 0);
+ return x;
+}
+
+ABC_NAMESPACE_HEADER_END
+#endif /* satoko__utils__heap_h */
diff --git a/src/sat/satoko/utils/mem.h b/src/sat/satoko/utils/mem.h
new file mode 100755
index 00000000..5ff9873d
--- /dev/null
+++ b/src/sat/satoko/utils/mem.h
@@ -0,0 +1,23 @@
+//===--- mem.h --------------------------------------------------------------===
+//
+// satoko: Satisfiability solver
+//
+// This file is distributed under the BSD 2-Clause License.
+// See LICENSE for details.
+//
+//===------------------------------------------------------------------------===
+#ifndef satoko__utils__mem_h
+#define satoko__utils__mem_h
+
+#include <stdlib.h>
+
+#include "misc/util/abc_global.h"
+ABC_NAMESPACE_HEADER_START
+
+#define satoko_alloc(type, n_elements) ((type *) malloc((n_elements) * sizeof(type)))
+#define satoko_calloc(type, n_elements) ((type *) calloc((n_elements), sizeof(type)))
+#define satoko_realloc(type, ptr, n_elements) ((type *) realloc(ptr, (n_elements) * sizeof(type)))
+#define satoko_free(p) do { free(p); p = NULL; } while(0)
+
+ABC_NAMESPACE_HEADER_END
+#endif
diff --git a/src/sat/satoko/utils/misc.h b/src/sat/satoko/utils/misc.h
new file mode 100755
index 00000000..7205a096
--- /dev/null
+++ b/src/sat/satoko/utils/misc.h
@@ -0,0 +1,35 @@
+//===--- misc.h -------------------------------------------------------------===
+//
+// satoko: Satisfiability solver
+//
+// This file is distributed under the BSD 2-Clause License.
+// See LICENSE for details.
+//
+//===------------------------------------------------------------------------===
+#ifndef satoko__utils__misc_h
+#define satoko__utils__misc_h
+
+#include "misc/util/abc_global.h"
+ABC_NAMESPACE_HEADER_START
+
+#define stk_swap(type, a, b) { type t = a; a = b; b = t; }
+
+static inline unsigned stk_uint_max(unsigned a, unsigned b)
+{
+ return a > b ? a : b;
+}
+
+static inline int stk_uint_compare(const void *p1, const void *p2)
+{
+ const unsigned pp1 = *(const unsigned *)p1;
+ const unsigned pp2 = *(const unsigned *)p2;
+
+ if (pp1 < pp2)
+ return -1;
+ if (pp1 > pp2)
+ return 1;
+ return 0;
+}
+
+ABC_NAMESPACE_HEADER_END
+#endif /* satoko__utils__misc_h */
diff --git a/src/sat/satoko/utils/sdbl.h b/src/sat/satoko/utils/sdbl.h
new file mode 100644
index 00000000..9f90ba02
--- /dev/null
+++ b/src/sat/satoko/utils/sdbl.h
@@ -0,0 +1,133 @@
+//===--- sdbl.h -------------------------------------------------------------===
+//
+// satoko: Satisfiability solver
+//
+// This file is distributed under the BSD 2-Clause License.
+// See LICENSE for details.
+//
+//===------------------------------------------------------------------------===
+// by Alan Mishchenko
+#ifndef satoko__utils__sdbl_h
+#define satoko__utils__sdbl_h
+
+#include "misc/util/abc_global.h"
+ABC_NAMESPACE_HEADER_START
+/*
+ The sdbl_t floating-point number is represented as a 64-bit unsigned int.
+ The number is (2^expt)*mnt, where expt is a 16-bit exponent and mnt is a
+ 48-bit mantissa. The decimal point is located between the MSB of mnt,
+ which is always 1, and the remaining 15 digits of mnt.
+
+ Currently, only positive numbers are represented.
+
+ The range of possible values is [1.0; 2^(2^16-1)*1.111111111111111]
+ that is, the smallest possible number is 1.0 and the largest possible
+ number is 2^(---16 ones---).(1.---47 ones---)
+
+ Comparison of numbers can be done by comparing the underlying unsigned ints.
+
+ Only addition, multiplication, and division by 2^n are currently implemented.
+*/
+
+typedef word sdbl_t;
+
+static sdbl_t SDBL_CONST1 = ABC_CONST(0x0000800000000000);
+static sdbl_t SDBL_MAX = ~(sdbl_t)(0);
+
+union ui64_dbl { word ui64; double dbl; };
+
+static inline word sdbl_exp(sdbl_t a) { return a >> 48; }
+static inline word sdbl_mnt(sdbl_t a) { return (a << 16) >> 16; }
+
+static inline double sdbl2double(sdbl_t a) {
+ union ui64_dbl temp;
+ assert(sdbl_exp(a) < 1023);
+ temp.ui64 = ((sdbl_exp(a) + 1023) << 52) | (((a << 17) >> 17) << 5);
+ return temp.dbl;
+}
+
+static inline sdbl_t double2sdbl(double value)
+{
+ union ui64_dbl temp;
+ sdbl_t expt, mnt;
+ assert(value >= 1.0);
+ temp.dbl = value;
+ expt = (temp.ui64 >> 52) - 1023;
+ mnt = SDBL_CONST1 | ((temp.ui64 << 12) >> 17);
+ return (expt << 48) + mnt;
+}
+
+static inline sdbl_t sdbl_add(sdbl_t a, sdbl_t b)
+{
+ sdbl_t expt, mnt;
+ if (a < b) {
+ a ^= b;
+ b ^= a;
+ a ^= b;
+ }
+ assert(a >= b);
+ expt = sdbl_exp(a);
+ mnt = sdbl_mnt(a) + (sdbl_mnt(b) >> (sdbl_exp(a) - sdbl_exp(b)));
+ /* Check for carry */
+ if (mnt >> 48) {
+ expt++;
+ mnt >>= 1;
+ }
+ if (expt >> 16) /* overflow */
+ return SDBL_MAX;
+ return (expt << 48) + mnt;
+}
+
+static inline sdbl_t sdbl_mult(sdbl_t a, sdbl_t b)
+{
+ sdbl_t expt, mnt;
+ sdbl_t a_mnt, a_mnt_hi, a_mnt_lo;
+ sdbl_t b_mnt, b_mnt_hi, b_mnt_lo;
+ if (a < b) {
+ a ^= b;
+ b ^= a;
+ a ^= b;
+ }
+ assert( a >= b );
+ a_mnt = sdbl_mnt(a);
+ b_mnt = sdbl_mnt(b);
+ a_mnt_hi = a_mnt>>32;
+ b_mnt_hi = b_mnt>>32;
+ a_mnt_lo = (a_mnt<<32)>>32;
+ b_mnt_lo = (b_mnt<<32)>>32;
+ mnt = ((a_mnt_hi * b_mnt_hi) << 17) +
+ ((a_mnt_lo * b_mnt_lo) >> 47) +
+ ((a_mnt_lo * b_mnt_hi) >> 15) +
+ ((a_mnt_hi * b_mnt_lo) >> 15);
+ expt = sdbl_exp(a) + sdbl_exp(b);
+ /* Check for carry */
+ if (mnt >> 48) {
+ expt++;
+ mnt >>= 1;
+ }
+ if (expt >> 16) /* overflow */
+ return SDBL_MAX;
+ return (expt << 48) + mnt;
+}
+
+static inline sdbl_t sdbl_div(sdbl_t a, unsigned deg2)
+{
+ if (sdbl_exp(a) >= (word)deg2)
+ return ((sdbl_exp(a) - deg2) << 48) + sdbl_mnt(a);
+ return SDBL_CONST1;
+}
+
+static inline void sdbl_test()
+{
+ sdbl_t ten100_ = ABC_CONST(0x014c924d692ca61b);
+ printf("%f\n", sdbl2double(ten100_));
+ printf("%016lX\n", double2sdbl(1 /0.95));
+ printf("%016lX\n", SDBL_CONST1);
+ printf("%f\n", sdbl2double(SDBL_CONST1));
+ printf("%f\n", sdbl2double(ABC_CONST(0x000086BCA1AF286B)));
+
+}
+
+ABC_NAMESPACE_HEADER_END
+
+#endif /* satoko__utils__sdbl_h */
diff --git a/src/sat/satoko/utils/sort.h b/src/sat/satoko/utils/sort.h
new file mode 100644
index 00000000..285f4b91
--- /dev/null
+++ b/src/sat/satoko/utils/sort.h
@@ -0,0 +1,65 @@
+//===--- sort.h -------------------------------------------------------------===
+//
+// satoko: Satisfiability solver
+//
+// This file is distributed under the BSD 2-Clause License.
+// See LICENSE for details.
+//
+//===------------------------------------------------------------------------===
+#ifndef satoko__utils__sort_h
+#define satoko__utils__sort_h
+
+#include "misc/util/abc_global.h"
+ABC_NAMESPACE_HEADER_START
+
+static inline void select_sort(void **data, unsigned size,
+ int (*comp_fn)(const void *, const void *))
+{
+ unsigned i, j, i_best;
+ void *temp;
+
+ for (i = 0; i < (size - 1); i++) {
+ i_best = i;
+ for (j = i + 1; j < size; j++) {
+ if (comp_fn(data[j], data[i_best]))
+ i_best = j;
+ }
+ temp = data[i];
+ data[i] = data[i_best];
+ data[i_best] = temp;
+ }
+}
+
+static void satoko_sort(void **data, unsigned size,
+ int (*comp_fn)(const void *, const void *))
+{
+ if (size <= 15)
+ select_sort(data, size, comp_fn);
+ else {
+ void *pivot = data[size / 2];
+ void *temp;
+ unsigned j = size;
+ int i = -1;
+
+ for (;;) {
+ do {
+ i++;
+ } while (comp_fn(data[i], pivot));
+ do {
+ j--;
+ } while (comp_fn(pivot, data[j]));
+
+ if ((unsigned) i >= j)
+ break;
+
+ temp = data[i];
+ data[i] = data[j];
+ data[j] = temp;
+ }
+ satoko_sort(data, (unsigned) i, comp_fn);
+ satoko_sort(data + i, (size - (unsigned) i), comp_fn);
+ }
+}
+
+ABC_NAMESPACE_HEADER_END
+#endif /* satoko__utils__sort_h */
diff --git a/src/sat/satoko/utils/vec/vec_char.h b/src/sat/satoko/utils/vec/vec_char.h
new file mode 100644
index 00000000..7d5732ec
--- /dev/null
+++ b/src/sat/satoko/utils/vec/vec_char.h
@@ -0,0 +1,260 @@
+//===--- vec_char.h ---------------------------------------------------------===
+//
+// satoko: Satisfiability solver
+//
+// This file is distributed under the BSD 2-Clause License.
+// See LICENSE for details.
+//
+//===------------------------------------------------------------------------===
+#ifndef satoko__utils__vec__vec_char_h
+#define satoko__utils__vec__vec_char_h
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "../mem.h"
+
+#include "misc/util/abc_global.h"
+ABC_NAMESPACE_HEADER_START
+
+typedef struct vec_char_t_ vec_char_t;
+struct vec_char_t_ {
+ unsigned cap;
+ unsigned size;
+ char *data;
+};
+
+//===------------------------------------------------------------------------===
+// Vector Macros
+//===------------------------------------------------------------------------===
+#define vec_char_foreach(vec, entry, i) \
+ for (i = 0; (i < vec_char_size(vec)) && (((entry) = vec_char_at(vec, i)), 1); i++)
+
+#define vec_char_foreach_start(vec, entry, i, start) \
+ for (i = start; (i < vec_char_size(vec)) && (((entry) = vec_char_at(vec, i)), 1); i++)
+
+#define vec_char_foreach_stop(vec, entry, i, stop) \
+ for (i = 0; (i < stop) && (((entry) = vec_char_at(vec, i)), 1); i++)
+
+//===------------------------------------------------------------------------===
+// Vector API
+//===------------------------------------------------------------------------===
+static inline vec_char_t * vec_char_alloc(unsigned cap)
+{
+ vec_char_t *p = satoko_alloc(vec_char_t, 1);
+
+ if (cap > 0 && cap < 16)
+ cap = 16;
+ p->size = 0;
+ p->cap = cap;
+ p->data = p->cap ? satoko_alloc(char, p->cap) : NULL;
+ return p;
+}
+
+static inline vec_char_t * vec_char_alloc_exact(unsigned cap)
+{
+ vec_char_t *p = satoko_alloc(vec_char_t, 1);
+
+ cap = 0;
+ p->size = 0;
+ p->cap = cap;
+ p->data = p->cap ? satoko_alloc(char, p->cap ) : NULL;
+ return p;
+}
+
+static inline vec_char_t * vec_char_init(unsigned size, char value)
+{
+ vec_char_t *p = satoko_alloc(vec_char_t, 1);
+
+ p->cap = size;
+ p->size = size;
+ p->data = p->cap ? satoko_alloc(char, p->cap) : NULL;
+ memset(p->data, value, sizeof(char) * p->size);
+ return p;
+}
+
+static inline void vec_char_free(vec_char_t *p)
+{
+ if (p->data != NULL)
+ satoko_free(p->data);
+ satoko_free(p);
+}
+
+static inline unsigned vec_char_size(vec_char_t *p)
+{
+ return p->size;
+}
+
+static inline void vec_char_resize(vec_char_t *p, unsigned new_size)
+{
+ p->size = new_size;
+ if (p->cap >= new_size)
+ return;
+ p->data = satoko_realloc(char, p->data, new_size);
+ assert(p->data != NULL);
+ p->cap = new_size;
+}
+
+static inline void vec_char_shrink(vec_char_t *p, unsigned new_size)
+{
+ assert(p->cap > new_size);
+ p->size = new_size;
+}
+
+static inline void vec_char_reserve(vec_char_t *p, unsigned new_cap)
+{
+ if (p->cap >= new_cap)
+ return;
+ p->data = satoko_realloc(char, p->data, new_cap);
+ assert(p->data != NULL);
+ p->cap = new_cap;
+}
+
+static inline unsigned vec_char_capacity(vec_char_t *p)
+{
+ return p->cap;
+}
+
+static inline int vec_char_empty(vec_char_t *p)
+{
+ return p->size ? 0 : 1;
+}
+
+static inline void vec_char_erase(vec_char_t *p)
+{
+ satoko_free(p->data);
+ p->size = 0;
+ p->cap = 0;
+}
+
+static inline char vec_char_at(vec_char_t *p, unsigned idx)
+{
+ assert(idx >= 0 && idx < p->size);
+ return p->data[idx];
+}
+
+static inline char * vec_char_at_ptr(vec_char_t *p, unsigned idx)
+{
+ assert(idx >= 0 && idx < p->size);
+ return p->data + idx;
+}
+
+static inline char * vec_char_data(vec_char_t *p)
+{
+ assert(p);
+ return p->data;
+}
+
+static inline void vec_char_duplicate(vec_char_t *dest, const vec_char_t *src)
+{
+ assert(dest != NULL && src != NULL);
+ vec_char_resize(dest, src->cap);
+ memcpy(dest->data, src->data, sizeof(char) * src->cap);
+ dest->size = src->size;
+}
+
+static inline void vec_char_copy(vec_char_t *dest, const vec_char_t *src)
+{
+ assert(dest != NULL && src != NULL);
+ vec_char_resize(dest, src->size);
+ memcpy(dest->data, src->data, sizeof(char) * src->size);
+ dest->size = src->size;
+}
+
+static inline void vec_char_push_back(vec_char_t *p, char value)
+{
+ if (p->size == p->cap) {
+ if (p->cap < 16)
+ vec_char_reserve(p, 16);
+ else
+ vec_char_reserve(p, 2 * p->cap);
+ }
+ p->data[p->size] = value;
+ p->size++;
+}
+
+static inline char vec_char_pop_back(vec_char_t *p)
+{
+ assert(p && p->size);
+ return p->data[--p->size];
+}
+
+static inline void vec_char_assign(vec_char_t *p, unsigned idx, char value)
+{
+ assert((idx >= 0) && (idx < vec_char_size(p)));
+ p->data[idx] = value;
+}
+
+static inline void vec_char_insert(vec_char_t *p, unsigned idx, char value)
+{
+ assert((idx >= 0) && (idx < vec_char_size(p)));
+ vec_char_push_back(p, 0);
+ memmove(p->data + idx + 1, p->data + idx, (p->size - idx - 2) * sizeof(char));
+ p->data[idx] = value;
+}
+
+static inline void vec_char_drop(vec_char_t *p, unsigned idx)
+{
+ assert((idx >= 0) && (idx < vec_char_size(p)));
+ memmove(p->data + idx, p->data + idx + 1, (p->size - idx - 1) * sizeof(char));
+ p->size -= 1;
+}
+
+static inline void vec_char_clear(vec_char_t *p)
+{
+ p->size = 0;
+}
+
+static inline int vec_char_asc_compare(const void *p1, const void *p2)
+{
+ const char *pp1 = (const char *)p1;
+ const char *pp2 = (const char *)p2;
+
+ if (*pp1 < *pp2)
+ return -1;
+ if (*pp1 > *pp2)
+ return 1;
+ return 0;
+}
+
+static inline int vec_char_desc_compare(const void *p1, const void *p2)
+{
+ const char *pp1 = (const char *)p1;
+ const char *pp2 = (const char *)p2;
+
+ if (*pp1 > *pp2)
+ return -1;
+ if (*pp1 < *pp2)
+ return 1;
+ return 0;
+}
+
+static inline void vec_char_sort(vec_char_t *p, int ascending)
+{
+ if (ascending)
+ qsort((void *) p->data, p->size, sizeof(char),
+ (int (*)(const void *, const void *)) vec_char_asc_compare);
+ else
+ qsort((void*) p->data, p->size, sizeof(char),
+ (int (*)(const void *, const void *)) vec_char_desc_compare);
+}
+
+
+static inline long vec_char_memory(vec_char_t *p)
+{
+ return p == NULL ? 0 : sizeof(char) * p->cap + sizeof(vec_char_t);
+}
+
+static inline void vec_char_print(vec_char_t* p)
+{
+ unsigned i;
+ assert(p != NULL);
+ fprintf(stdout, "Vector has %u(%u) entries: {", p->size, p->cap);
+ for (i = 0; i < p->size; i++)
+ fprintf(stdout, " %d", p->data[i]);
+ fprintf(stdout, " }\n");
+}
+
+ABC_NAMESPACE_HEADER_END
+#endif /* satoko__utils__vec__vec_char_h */
diff --git a/src/sat/satoko/utils/vec/vec_flt.h b/src/sat/satoko/utils/vec/vec_flt.h
new file mode 100644
index 00000000..d7c896d9
--- /dev/null
+++ b/src/sat/satoko/utils/vec/vec_flt.h
@@ -0,0 +1,246 @@
+//===--- vec_int.h ----------------------------------------------------------===
+//
+// satoko: Satisfiability solver
+//
+// This file is distributed under the BSD 2-Clause License.
+// See LICENSE for details.
+//
+//===------------------------------------------------------------------------===
+#ifndef satoko__utils__vec__vec_flt_h
+#define satoko__utils__vec__vec_flt_h
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "../mem.h"
+
+#include "misc/util/abc_global.h"
+ABC_NAMESPACE_HEADER_START
+
+typedef struct vec_flt_t_ vec_flt_t;
+struct vec_flt_t_ {
+ unsigned cap;
+ unsigned size;
+ float *data;
+};
+
+//===------------------------------------------------------------------------===
+// Vector Macros
+//===------------------------------------------------------------------------===
+#define vec_flt_foreach(vec, entry, i) \
+ for (i = 0; (i < vec->size) && (((entry) = vec_flt_at(vec, i)), 1); i++)
+
+#define vec_flt_foreach_start(vec, entry, i, start) \
+ for (i = start; (i < vec_flt_size(vec)) && (((entry) = vec_flt_at(vec, i)), 1); i++)
+
+#define vec_flt_foreach_stop(vec, entry, i, stop) \
+ for (i = 0; (i < stop) && (((entry) = vec_flt_at(vec, i)), 1); i++)
+
+//===------------------------------------------------------------------------===
+// Vector API
+//===------------------------------------------------------------------------===
+static inline vec_flt_t *vec_flt_alloc(unsigned cap)
+{
+ vec_flt_t* p = satoko_alloc(vec_flt_t, 1);
+
+ if (cap > 0 && cap < 16)
+ cap = 16;
+ p->size = 0;
+ p->cap = cap;
+ p->data = p->cap ? satoko_alloc(float, p->cap) : NULL;
+ return p;
+}
+
+static inline vec_flt_t *vec_flt_alloc_exact(unsigned cap)
+{
+ vec_flt_t* p = satoko_alloc(vec_flt_t, 1);
+
+ p->size = 0;
+ p->cap = cap;
+ p->data = p->cap ? satoko_alloc(float, p->cap) : NULL;
+ return p;
+}
+
+static inline vec_flt_t *vec_flt_init(unsigned size, float value)
+{
+ vec_flt_t* p = satoko_alloc(vec_flt_t, 1);
+
+ p->cap = size;
+ p->size = size;
+ p->data = p->cap ? satoko_alloc(float, p->cap) : NULL;
+ memset(p->data, value, sizeof(float) * p->size);
+ return p;
+}
+
+static inline void vec_flt_free(vec_flt_t *p)
+{
+ if (p->data != NULL)
+ satoko_free(p->data);
+ satoko_free(p);
+}
+
+static inline unsigned vec_flt_size(vec_flt_t *p)
+{
+ return p->size;
+}
+
+static inline void vec_flt_resize(vec_flt_t *p, unsigned new_size)
+{
+ p->size = new_size;
+ if (p->cap >= new_size)
+ return;
+ p->data = satoko_realloc(float, p->data, new_size);
+ assert(p->data != NULL);
+ p->cap = new_size;
+}
+
+static inline void vec_flt_reserve(vec_flt_t *p, unsigned new_cap)
+{
+ if (p->cap >= new_cap)
+ return;
+ p->data = satoko_realloc(float, p->data, new_cap);
+ assert(p->data != NULL);
+ p->cap = new_cap;
+}
+
+static inline unsigned vec_flt_capacity(vec_flt_t *p)
+{
+ return p->cap;
+}
+
+static inline int vec_flt_empty(vec_flt_t *p)
+{
+ return p->size ? 0 : 1;
+}
+
+static inline void vec_flt_erase(vec_flt_t *p)
+{
+ satoko_free(p->data);
+ p->size = 0;
+ p->cap = 0;
+}
+
+static inline float vec_flt_at(vec_flt_t *p, unsigned i)
+{
+ assert(i >= 0 && i < p->size);
+ return p->data[i];
+}
+
+static inline float *vec_flt_at_ptr(vec_flt_t *p, unsigned i)
+{
+ assert(i >= 0 && i < p->size);
+ return p->data + i;
+}
+
+static inline float *vec_flt_data(vec_flt_t *p)
+{
+ assert(p);
+ return p->data;
+}
+
+static inline void vec_flt_duplicate(vec_flt_t *dest, const vec_flt_t *src)
+{
+ assert(dest != NULL && src != NULL);
+ vec_flt_resize(dest, src->cap);
+ memcpy(dest->data, src->data, sizeof(float) * src->cap);
+ dest->size = src->size;
+}
+
+static inline void vec_flt_copy(vec_flt_t *dest, const vec_flt_t *src)
+{
+ assert(dest != NULL && src != NULL);
+ vec_flt_resize(dest, src->size);
+ memcpy(dest->data, src->data, sizeof(float) * src->size);
+ dest->size = src->size;
+}
+
+static inline void vec_flt_push_back(vec_flt_t *p, float value)
+{
+ if (p->size == p->cap) {
+ if (p->cap < 16)
+ vec_flt_reserve(p, 16);
+ else
+ vec_flt_reserve(p, 2 * p->cap);
+ }
+ p->data[p->size] = value;
+ p->size++;
+}
+
+static inline void vec_flt_assign(vec_flt_t *p, unsigned i, float value)
+{
+ assert((i >= 0) && (i < vec_flt_size(p)));
+ p->data[i] = value;
+}
+
+static inline void vec_flt_insert(vec_flt_t *p, unsigned i, float value)
+{
+ assert((i >= 0) && (i < vec_flt_size(p)));
+ vec_flt_push_back(p, 0);
+ memmove(p->data + i + 1, p->data + i, (p->size - i - 2) * sizeof(float));
+ p->data[i] = value;
+}
+
+static inline void vec_flt_drop(vec_flt_t *p, unsigned i)
+{
+ assert((i >= 0) && (i < vec_flt_size(p)));
+ memmove(p->data + i, p->data + i + 1, (p->size - i - 1) * sizeof(float));
+ p->size -= 1;
+}
+
+static inline void vec_flt_clear(vec_flt_t *p)
+{
+ p->size = 0;
+}
+
+static inline int vec_flt_asc_compare(const void *p1, const void *p2)
+{
+ const float *pp1 = (const float *) p1;
+ const float *pp2 = (const float *) p2;
+
+ if (*pp1 < *pp2)
+ return -1;
+ if (*pp1 > *pp2)
+ return 1;
+ return 0;
+}
+
+static inline int vec_flt_desc_compare(const void* p1, const void* p2)
+{
+ const float *pp1 = (const float *) p1;
+ const float *pp2 = (const float *) p2;
+
+ if (*pp1 > *pp2)
+ return -1;
+ if (*pp1 < *pp2)
+ return 1;
+ return 0;
+}
+
+static inline void vec_flt_sort(vec_flt_t* p, int ascending)
+{
+ if (ascending)
+ qsort((void *) p->data, p->size, sizeof(float),
+ (int (*)(const void*, const void*)) vec_flt_asc_compare);
+ else
+ qsort((void *) p->data, p->size, sizeof(float),
+ (int (*)(const void*, const void*)) vec_flt_desc_compare);
+}
+
+static inline long vec_flt_memory(vec_flt_t *p)
+{
+ return p == NULL ? 0 : sizeof(float) * p->cap + sizeof(vec_flt_t);
+}
+
+static inline void vec_flt_print(vec_flt_t *p)
+{
+ unsigned i;
+ assert(p != NULL);
+ fprintf(stdout, "Vector has %u(%u) entries: {", p->size, p->cap);
+ for (i = 0; i < p->size; i++)
+ fprintf(stdout, " %f", p->data[i]);
+ fprintf(stdout, " }\n");
+}
+
+ABC_NAMESPACE_HEADER_END
+#endif /* satoko__utils__vec__vec_flt_h */
diff --git a/src/sat/satoko/utils/vec/vec_int.h b/src/sat/satoko/utils/vec/vec_int.h
new file mode 100755
index 00000000..75c5d134
--- /dev/null
+++ b/src/sat/satoko/utils/vec/vec_int.h
@@ -0,0 +1,240 @@
+//===--- vec_int.h ----------------------------------------------------------===
+//
+// satoko: Satisfiability solver
+//
+// This file is distributed under the BSD 2-Clause License.
+// See LICENSE for details.
+//
+//===------------------------------------------------------------------------===
+#ifndef satoko__utils__vec__vec_int_h
+#define satoko__utils__vec__vec_int_h
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "../mem.h"
+
+#include "misc/util/abc_global.h"
+ABC_NAMESPACE_HEADER_START
+
+typedef struct vec_int_t_ vec_int_t;
+struct vec_int_t_ {
+ unsigned cap;
+ unsigned size;
+ int *data;
+};
+
+//===------------------------------------------------------------------------===
+// Vector Macros
+//===------------------------------------------------------------------------===
+#define vec_int_foreach(vec, entry, i) \
+ for (i = 0; (i < vec->size) && (((entry) = vec_int_at(vec, i)), 1); i++)
+
+#define vec_int_foreach_start(vec, entry, i, start) \
+ for (i = start; (i < vec_int_size(vec)) && (((entry) = vec_int_at(vec, i)), 1); i++)
+
+#define vec_int_foreach_stop(vec, entry, i, stop) \
+ for (i = 0; (i < stop) && (((entry) = vec_int_at(vec, i)), 1); i++)
+
+//===------------------------------------------------------------------------===
+// Vector API
+//===------------------------------------------------------------------------===
+static inline vec_int_t *vec_int_alloc(unsigned cap)
+{
+ vec_int_t* p = satoko_alloc(vec_int_t, 1);
+
+ if (cap > 0 && cap < 16)
+ cap = 16;
+ p->size = 0;
+ p->cap = cap;
+ p->data = p->cap ? satoko_alloc(int, p->cap) : NULL;
+ return p;
+}
+
+static inline vec_int_t *vec_int_alloc_exact(unsigned cap)
+{
+ vec_int_t* p = satoko_alloc(vec_int_t, 1);
+
+ p->size = 0;
+ p->cap = cap;
+ p->data = p->cap ? satoko_alloc(int, p->cap) : NULL;
+ return p;
+}
+
+static inline vec_int_t *vec_int_init(unsigned size, int value)
+{
+ vec_int_t* p = satoko_alloc(vec_int_t, 1);
+
+ p->cap = size;
+ p->size = size;
+ p->data = p->cap ? satoko_alloc(int, p->cap) : NULL;
+ memset(p->data, value, sizeof(int) * p->size);
+ return p;
+}
+
+static inline void vec_int_free(vec_int_t *p)
+{
+ if (p->data != NULL)
+ satoko_free(p->data);
+ satoko_free(p);
+}
+
+static inline unsigned vec_int_size(vec_int_t *p)
+{
+ return p->size;
+}
+
+static inline void vec_int_resize(vec_int_t *p, unsigned new_size)
+{
+ p->size = new_size;
+ if (p->cap >= new_size)
+ return;
+ p->data = satoko_realloc(int, p->data, new_size);
+ assert(p->data != NULL);
+ p->cap = new_size;
+}
+
+static inline void vec_int_reserve(vec_int_t *p, unsigned new_cap)
+{
+ if (p->cap >= new_cap)
+ return;
+ p->data = satoko_realloc(int, p->data, new_cap);
+ assert(p->data != NULL);
+ p->cap = new_cap;
+}
+
+static inline unsigned vec_int_capacity(vec_int_t *p)
+{
+ return p->cap;
+}
+
+static inline int vec_int_empty(vec_int_t *p)
+{
+ return p->size ? 0 : 1;
+}
+
+static inline void vec_int_erase(vec_int_t *p)
+{
+ satoko_free(p->data);
+ p->size = 0;
+ p->cap = 0;
+}
+
+static inline int vec_int_at(vec_int_t *p, unsigned i)
+{
+ assert(i >= 0 && i < p->size);
+ return p->data[i];
+}
+
+static inline int *vec_int_at_ptr(vec_int_t *p, unsigned i)
+{
+ assert(i >= 0 && i < p->size);
+ return p->data + i;
+}
+
+static inline void vec_int_duplicate(vec_int_t *dest, const vec_int_t *src)
+{
+ assert(dest != NULL && src != NULL);
+ vec_int_resize(dest, src->cap);
+ memcpy(dest->data, src->data, sizeof(int) * src->cap);
+ dest->size = src->size;
+}
+
+static inline void vec_int_copy(vec_int_t *dest, const vec_int_t *src)
+{
+ assert(dest != NULL && src != NULL);
+ vec_int_resize(dest, src->size);
+ memcpy(dest->data, src->data, sizeof(int) * src->size);
+ dest->size = src->size;
+}
+
+static inline void vec_int_push_back(vec_int_t *p, int value)
+{
+ if (p->size == p->cap) {
+ if (p->cap < 16)
+ vec_int_reserve(p, 16);
+ else
+ vec_int_reserve(p, 2 * p->cap);
+ }
+ p->data[p->size] = value;
+ p->size++;
+}
+
+static inline void vec_int_assign(vec_int_t *p, unsigned i, int value)
+{
+ assert((i >= 0) && (i < vec_int_size(p)));
+ p->data[i] = value;
+}
+
+static inline void vec_int_insert(vec_int_t *p, unsigned i, int value)
+{
+ assert((i >= 0) && (i < vec_int_size(p)));
+ vec_int_push_back(p, 0);
+ memmove(p->data + i + 1, p->data + i, (p->size - i - 2) * sizeof(int));
+ p->data[i] = value;
+}
+
+static inline void vec_int_drop(vec_int_t *p, unsigned i)
+{
+ assert((i >= 0) && (i < vec_int_size(p)));
+ memmove(p->data + i, p->data + i + 1, (p->size - i - 1) * sizeof(int));
+ p->size -= 1;
+}
+
+static inline void vec_int_clear(vec_int_t *p)
+{
+ p->size = 0;
+}
+
+static inline int vec_int_asc_compare(const void *p1, const void *p2)
+{
+ const int *pp1 = (const int *) p1;
+ const int *pp2 = (const int *) p2;
+
+ if (*pp1 < *pp2)
+ return -1;
+ if (*pp1 > *pp2)
+ return 1;
+ return 0;
+}
+
+static inline int vec_int_desc_compare(const void* p1, const void* p2)
+{
+ const int *pp1 = (const int *) p1;
+ const int *pp2 = (const int *) p2;
+
+ if (*pp1 > *pp2)
+ return -1;
+ if (*pp1 < *pp2)
+ return 1;
+ return 0;
+}
+
+static inline void vec_int_sort(vec_int_t* p, int ascending)
+{
+ if (ascending)
+ qsort((void *) p->data, p->size, sizeof(int),
+ (int (*)(const void*, const void*)) vec_int_asc_compare);
+ else
+ qsort((void *) p->data, p->size, sizeof(int),
+ (int (*)(const void*, const void*)) vec_int_desc_compare);
+}
+
+static inline long vec_int_memory(vec_int_t *p)
+{
+ return p == NULL ? 0 : sizeof(int) * p->cap + sizeof(vec_int_t);
+}
+
+static inline void vec_int_print(vec_int_t *p)
+{
+ unsigned i;
+ assert(p != NULL);
+ fprintf(stdout, "Vector has %u(%u) entries: {", p->size, p->cap);
+ for (i = 0; i < p->size; i++)
+ fprintf(stdout, " %d", p->data[i]);
+ fprintf(stdout, " }\n");
+}
+
+ABC_NAMESPACE_HEADER_END
+#endif /* satoko__utils__vec__vec_int_h */
diff --git a/src/sat/satoko/utils/vec/vec_sdbl.h b/src/sat/satoko/utils/vec/vec_sdbl.h
new file mode 100755
index 00000000..ec1c731c
--- /dev/null
+++ b/src/sat/satoko/utils/vec/vec_sdbl.h
@@ -0,0 +1,253 @@
+//===--- vec_int.h ----------------------------------------------------------===
+//
+// satoko: Satisfiability solver
+//
+// This file is distributed under the BSD 2-Clause License.
+// See LICENSE for details.
+//
+//===------------------------------------------------------------------------===
+#ifndef satoko__utils__vec__vec_sdbl_h
+#define satoko__utils__vec__vec_sdbl_h
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "../mem.h"
+#include "../sdbl.h"
+
+#include "misc/util/abc_global.h"
+ABC_NAMESPACE_HEADER_START
+
+typedef struct vec_sdbl_t_ vec_sdbl_t;
+struct vec_sdbl_t_ {
+ unsigned cap;
+ unsigned size;
+ sdbl_t *data;
+};
+
+//===------------------------------------------------------------------------===
+// Vector Macros
+//===------------------------------------------------------------------------===
+#define vec_sdbl_foreach(vec, entry, i) \
+ for (i = 0; (i < vec->size) && (((entry) = vec_sdbl_at(vec, i)), 1); i++)
+
+#define vec_sdbl_foreach_start(vec, entry, i, start) \
+ for (i = start; (i < vec_sdbl_size(vec)) && (((entry) = vec_sdbl_at(vec, i)), 1); i++)
+
+#define vec_sdbl_foreach_stop(vec, entry, i, stop) \
+ for (i = 0; (i < stop) && (((entry) = vec_sdbl_at(vec, i)), 1); i++)
+
+//===------------------------------------------------------------------------===
+// Vector API
+//===------------------------------------------------------------------------===
+static inline vec_sdbl_t *vec_sdbl_alloc(unsigned cap)
+{
+ vec_sdbl_t* p = satoko_alloc(vec_sdbl_t, 1);
+
+ if (cap > 0 && cap < 16)
+ cap = 16;
+ p->size = 0;
+ p->cap = cap;
+ p->data = p->cap ? satoko_alloc(sdbl_t, p->cap) : NULL;
+ return p;
+}
+
+static inline vec_sdbl_t *vec_sdbl_alloc_exact(unsigned cap)
+{
+ vec_sdbl_t* p = satoko_alloc(vec_sdbl_t, 1);
+
+ p->size = 0;
+ p->cap = cap;
+ p->data = p->cap ? satoko_alloc(sdbl_t, p->cap) : NULL;
+ return p;
+}
+
+static inline vec_sdbl_t *vec_sdbl_init(unsigned size, sdbl_t value)
+{
+ vec_sdbl_t* p = satoko_alloc(vec_sdbl_t, 1);
+
+ p->cap = size;
+ p->size = size;
+ p->data = p->cap ? satoko_alloc(sdbl_t, p->cap) : NULL;
+ memset(p->data, value, sizeof(sdbl_t) * p->size);
+ return p;
+}
+
+static inline void vec_sdbl_free(vec_sdbl_t *p)
+{
+ if (p->data != NULL)
+ satoko_free(p->data);
+ satoko_free(p);
+}
+
+static inline unsigned vec_sdbl_size(vec_sdbl_t *p)
+{
+ return p->size;
+}
+
+static inline void vec_sdbl_shrink(vec_sdbl_t *p, unsigned new_size)
+{
+ assert(new_size <= p->cap);
+ p->size = new_size;
+}
+
+static inline void vec_sdbl_resize(vec_sdbl_t *p, unsigned new_size)
+{
+ p->size = new_size;
+ if (p->cap >= new_size)
+ return;
+ p->data = satoko_realloc(sdbl_t, p->data, new_size);
+ assert(p->data != NULL);
+ p->cap = new_size;
+}
+
+static inline void vec_sdbl_reserve(vec_sdbl_t *p, unsigned new_cap)
+{
+ if (p->cap >= new_cap)
+ return;
+ p->data = satoko_realloc(sdbl_t, p->data, new_cap);
+ assert(p->data != NULL);
+ p->cap = new_cap;
+}
+
+static inline unsigned vec_sdbl_capacity(vec_sdbl_t *p)
+{
+ return p->cap;
+}
+
+static inline int vec_sdbl_empty(vec_sdbl_t *p)
+{
+ return p->size ? 0 : 1;
+}
+
+static inline void vec_sdbl_erase(vec_sdbl_t *p)
+{
+ satoko_free(p->data);
+ p->size = 0;
+ p->cap = 0;
+}
+
+static inline sdbl_t vec_sdbl_at(vec_sdbl_t *p, unsigned i)
+{
+ assert(i >= 0 && i < p->size);
+ return p->data[i];
+}
+
+static inline sdbl_t *vec_sdbl_at_ptr(vec_sdbl_t *p, unsigned i)
+{
+ assert(i >= 0 && i < p->size);
+ return p->data + i;
+}
+
+static inline sdbl_t *vec_sdbl_data(vec_sdbl_t *p)
+{
+ assert(p);
+ return p->data;
+}
+
+static inline void vec_sdbl_duplicate(vec_sdbl_t *dest, const vec_sdbl_t *src)
+{
+ assert(dest != NULL && src != NULL);
+ vec_sdbl_resize(dest, src->cap);
+ memcpy(dest->data, src->data, sizeof(sdbl_t) * src->cap);
+ dest->size = src->size;
+}
+
+static inline void vec_sdbl_copy(vec_sdbl_t *dest, const vec_sdbl_t *src)
+{
+ assert(dest != NULL && src != NULL);
+ vec_sdbl_resize(dest, src->size);
+ memcpy(dest->data, src->data, sizeof(sdbl_t) * src->size);
+ dest->size = src->size;
+}
+
+static inline void vec_sdbl_push_back(vec_sdbl_t *p, sdbl_t value)
+{
+ if (p->size == p->cap) {
+ if (p->cap < 16)
+ vec_sdbl_reserve(p, 16);
+ else
+ vec_sdbl_reserve(p, 2 * p->cap);
+ }
+ p->data[p->size] = value;
+ p->size++;
+}
+
+static inline void vec_sdbl_assign(vec_sdbl_t *p, unsigned i, sdbl_t value)
+{
+ assert((i >= 0) && (i < vec_sdbl_size(p)));
+ p->data[i] = value;
+}
+
+static inline void vec_sdbl_insert(vec_sdbl_t *p, unsigned i, sdbl_t value)
+{
+ assert((i >= 0) && (i < vec_sdbl_size(p)));
+ vec_sdbl_push_back(p, 0);
+ memmove(p->data + i + 1, p->data + i, (p->size - i - 2) * sizeof(sdbl_t));
+ p->data[i] = value;
+}
+
+static inline void vec_sdbl_drop(vec_sdbl_t *p, unsigned i)
+{
+ assert((i >= 0) && (i < vec_sdbl_size(p)));
+ memmove(p->data + i, p->data + i + 1, (p->size - i - 1) * sizeof(sdbl_t));
+ p->size -= 1;
+}
+
+static inline void vec_sdbl_clear(vec_sdbl_t *p)
+{
+ p->size = 0;
+}
+
+static inline int vec_sdbl_asc_compare(const void *p1, const void *p2)
+{
+ const sdbl_t *pp1 = (const sdbl_t *) p1;
+ const sdbl_t *pp2 = (const sdbl_t *) p2;
+
+ if (*pp1 < *pp2)
+ return -1;
+ if (*pp1 > *pp2)
+ return 1;
+ return 0;
+}
+
+static inline int vec_sdbl_desc_compare(const void* p1, const void* p2)
+{
+ const sdbl_t *pp1 = (const sdbl_t *) p1;
+ const sdbl_t *pp2 = (const sdbl_t *) p2;
+
+ if (*pp1 > *pp2)
+ return -1;
+ if (*pp1 < *pp2)
+ return 1;
+ return 0;
+}
+
+static inline void vec_sdbl_sort(vec_sdbl_t* p, int ascending)
+{
+ if (ascending)
+ qsort((void *) p->data, p->size, sizeof(sdbl_t),
+ (int (*)(const void*, const void*)) vec_sdbl_asc_compare);
+ else
+ qsort((void *) p->data, p->size, sizeof(sdbl_t),
+ (int (*)(const void*, const void*)) vec_sdbl_desc_compare);
+}
+
+static inline long vec_sdbl_memory(vec_sdbl_t *p)
+{
+ return p == NULL ? 0 : sizeof(sdbl_t) * p->cap + sizeof(vec_sdbl_t);
+}
+
+static inline void vec_sdbl_print(vec_sdbl_t *p)
+{
+ unsigned i;
+ assert(p != NULL);
+ fprintf(stdout, "Vector has %u(%u) entries: {", p->size, p->cap);
+ for (i = 0; i < p->size; i++)
+ fprintf(stdout, " %f", sdbl2double(p->data[i]));
+ fprintf(stdout, " }\n");
+}
+
+ABC_NAMESPACE_HEADER_END
+#endif /* satoko__utils__vec__vec_sdbl_h */
diff --git a/src/sat/satoko/utils/vec/vec_uint.h b/src/sat/satoko/utils/vec/vec_uint.h
new file mode 100755
index 00000000..e6719ca3
--- /dev/null
+++ b/src/sat/satoko/utils/vec/vec_uint.h
@@ -0,0 +1,268 @@
+//===--- vec_uint.h ---------------------------------------------------------===
+//
+// satoko: Satisfiability solver
+//
+// This file is distributed under the BSD 2-Clause License.
+// See LICENSE for details.
+//
+//===------------------------------------------------------------------------===
+#ifndef satoko__utils__vec__vec_uint_h
+#define satoko__utils__vec__vec_uint_h
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "../mem.h"
+
+#include "misc/util/abc_global.h"
+ABC_NAMESPACE_HEADER_START
+
+typedef struct vec_uint_t_ vec_uint_t;
+struct vec_uint_t_ {
+ unsigned cap;
+ unsigned size;
+ unsigned* data;
+};
+
+//===------------------------------------------------------------------------===
+// Vector Macros
+//===------------------------------------------------------------------------===
+#define vec_uint_foreach(vec, entry, i) \
+ for (i = 0; (i < vec_uint_size(vec)) && (((entry) = vec_uint_at(vec, i)), 1); i++)
+
+#define vec_uint_foreach_start(vec, entry, i, start) \
+ for (i = start; (i < vec_uint_size(vec)) && (((entry) = vec_uint_at(vec, i)), 1); i++)
+
+#define vec_uint_foreach_stop(vec, entry, i, stop) \
+ for (i = 0; (i < stop) && (((entry) = vec_uint_at(vec, i)), 1); i++)
+
+//===------------------------------------------------------------------------===
+// Vector API
+//===------------------------------------------------------------------------===
+static inline vec_uint_t * vec_uint_alloc(unsigned cap)
+{
+ vec_uint_t *p = satoko_alloc(vec_uint_t, 1);
+
+ if (cap > 0 && cap < 16)
+ cap = 16;
+ p->size = 0;
+ p->cap = cap;
+ p->data = p->cap ? satoko_alloc(unsigned, p->cap) : NULL;
+ return p;
+}
+
+static inline vec_uint_t * vec_uint_alloc_exact(unsigned cap)
+{
+ vec_uint_t *p = satoko_alloc(vec_uint_t, 1);
+
+ cap = 0;
+ p->size = 0;
+ p->cap = cap;
+ p->data = p->cap ? satoko_alloc(unsigned, p->cap ) : NULL;
+ return p;
+}
+
+static inline vec_uint_t * vec_uint_init(unsigned size, unsigned value)
+{
+ vec_uint_t *p = satoko_alloc(vec_uint_t, 1);
+
+ p->cap = size;
+ p->size = size;
+ p->data = p->cap ? satoko_alloc(unsigned, p->cap ) : NULL;
+ memset(p->data, value, sizeof(unsigned) * p->size);
+ return p;
+}
+
+static inline void vec_uint_free(vec_uint_t *p)
+{
+ if (p->data != NULL)
+ satoko_free(p->data);
+ satoko_free(p);
+}
+
+static inline unsigned vec_uint_size(vec_uint_t *p)
+{
+ return p->size;
+}
+
+static inline void vec_uint_resize(vec_uint_t *p, unsigned new_size)
+{
+ p->size = new_size;
+ if (p->cap >= new_size)
+ return;
+ p->data = satoko_realloc(unsigned, p->data, new_size);
+ assert(p->data != NULL);
+ p->cap = new_size;
+}
+
+static inline void vec_uint_shrink(vec_uint_t *p, unsigned new_size)
+{
+ assert(p->cap >= new_size);
+ p->size = new_size;
+}
+
+static inline void vec_uint_reserve(vec_uint_t *p, unsigned new_cap)
+{
+ if (p->cap >= new_cap)
+ return;
+ p->data = satoko_realloc(unsigned, p->data, new_cap);
+ assert(p->data != NULL);
+ p->cap = new_cap;
+}
+
+static inline unsigned vec_uint_capacity(vec_uint_t *p)
+{
+ return p->cap;
+}
+
+static inline int vec_uint_empty(vec_uint_t *p)
+{
+ return p->size ? 0 : 1;
+}
+
+static inline void vec_uint_erase(vec_uint_t *p)
+{
+ satoko_free(p->data);
+ p->size = 0;
+ p->cap = 0;
+}
+
+static inline unsigned vec_uint_at(vec_uint_t *p, unsigned idx)
+{
+ assert(idx >= 0 && idx < p->size);
+ return p->data[idx];
+}
+
+static inline unsigned * vec_uint_at_ptr(vec_uint_t *p, unsigned idx)
+{
+ assert(idx >= 0 && idx < p->size);
+ return p->data + idx;
+}
+
+static inline unsigned vec_uint_find(vec_uint_t *p, unsigned entry)
+{
+ unsigned i;
+ for (i = 0; i < p->size; i++)
+ if (p->data[i] == entry)
+ return 1;
+ return 0;
+}
+
+static inline unsigned * vec_uint_data(vec_uint_t *p)
+{
+ assert(p);
+ return p->data;
+}
+
+static inline void vec_uint_duplicate(vec_uint_t *dest, const vec_uint_t *src)
+{
+ assert(dest != NULL && src != NULL);
+ vec_uint_resize(dest, src->cap);
+ memcpy(dest->data, src->data, sizeof(unsigned) * src->cap);
+ dest->size = src->size;
+}
+
+static inline void vec_uint_copy(vec_uint_t *dest, const vec_uint_t *src)
+{
+ assert(dest != NULL && src != NULL);
+ vec_uint_resize(dest, src->size);
+ memcpy(dest->data, src->data, sizeof(unsigned) * src->size);
+ dest->size = src->size;
+}
+
+static inline void vec_uint_push_back(vec_uint_t *p, unsigned value)
+{
+ if (p->size == p->cap) {
+ if (p->cap < 16)
+ vec_uint_reserve(p, 16);
+ else
+ vec_uint_reserve(p, 2 * p->cap);
+ }
+ p->data[p->size] = value;
+ p->size++;
+}
+
+static inline unsigned vec_uint_pop_back(vec_uint_t *p)
+{
+ assert(p && p->size);
+ return p->data[--p->size];
+}
+
+static inline void vec_uint_assign(vec_uint_t *p, unsigned idx, unsigned value)
+{
+ assert((idx >= 0) && (idx < vec_uint_size(p)));
+ p->data[idx] = value;
+}
+
+static inline void vec_uint_insert(vec_uint_t *p, unsigned idx, unsigned value)
+{
+ assert((idx >= 0) && (idx < vec_uint_size(p)));
+ vec_uint_push_back(p, 0);
+ memmove(p->data + idx + 1, p->data + idx, (p->size - idx - 2) * sizeof(unsigned));
+ p->data[idx] = value;
+}
+
+static inline void vec_uint_drop(vec_uint_t *p, unsigned idx)
+{
+ assert((idx >= 0) && (idx < vec_uint_size(p)));
+ memmove(p->data + idx, p->data + idx + 1, (p->size - idx - 1) * sizeof(unsigned));
+ p->size -= 1;
+}
+
+static inline void vec_uint_clear(vec_uint_t *p)
+{
+ p->size = 0;
+}
+
+static inline int vec_uint_asc_compare(const void *p1, const void *p2)
+{
+ const unsigned *pp1 = (const unsigned *) p1;
+ const unsigned *pp2 = (const unsigned *) p2;
+
+ if ( *pp1 < *pp2 )
+ return -1;
+ if ( *pp1 > *pp2 )
+ return 1;
+ return 0;
+}
+
+static inline int vec_uint_desc_compare(const void *p1, const void *p2)
+{
+ const unsigned *pp1 = (const unsigned *) p1;
+ const unsigned *pp2 = (const unsigned *) p2;
+
+ if ( *pp1 > *pp2 )
+ return -1;
+ if ( *pp1 < *pp2 )
+ return 1;
+ return 0;
+}
+
+static inline void vec_uint_sort(vec_uint_t *p, int ascending)
+{
+ if (ascending)
+ qsort((void *) p->data, p->size, sizeof(unsigned),
+ (int (*)(const void *, const void *)) vec_uint_asc_compare);
+ else
+ qsort((void*) p->data, p->size, sizeof(unsigned),
+ (int (*)(const void *, const void *)) vec_uint_desc_compare);
+}
+
+static inline long vec_uint_memory(vec_uint_t *p)
+{
+ return p == NULL ? 0 : sizeof(unsigned) * p->cap + sizeof(vec_uint_t);
+}
+
+static inline void vec_uint_print(vec_uint_t* p)
+{
+ unsigned i;
+ assert(p != NULL);
+ fprintf(stdout, "Vector has %u(%u) entries: {", p->size, p->cap);
+ for (i = 0; i < p->size; i++)
+ fprintf(stdout, " %u", p->data[i]);
+ fprintf(stdout, " }\n");
+}
+
+ABC_NAMESPACE_HEADER_END
+#endif /* satoko__utils__vec__vec_uint_h */
diff --git a/src/sat/satoko/watch_list.h b/src/sat/satoko/watch_list.h
new file mode 100644
index 00000000..1bcbf3b4
--- /dev/null
+++ b/src/sat/satoko/watch_list.h
@@ -0,0 +1,203 @@
+//===--- watch_list.h -------------------------------------------------------===
+//
+// satoko: Satisfiability solver
+//
+// This file is distributed under the BSD 2-Clause License.
+// See LICENSE for details.
+//
+//===------------------------------------------------------------------------===
+#ifndef satoko__watch_list_h
+#define satoko__watch_list_h
+
+#include "utils/mem.h"
+#include "utils/misc.h"
+
+#include "misc/util/abc_global.h"
+ABC_NAMESPACE_HEADER_START
+
+struct watcher {
+ unsigned cref;
+ unsigned blocker;
+};
+
+struct watch_list {
+ unsigned cap;
+ unsigned size;
+ unsigned n_bin;
+ struct watcher *watchers;
+};
+
+typedef struct vec_wl_t_ vec_wl_t;
+struct vec_wl_t_ {
+ unsigned cap;
+ unsigned size;
+ struct watch_list *watch_lists;
+};
+
+//===------------------------------------------------------------------------===
+// Watch list Macros
+//===------------------------------------------------------------------------===
+#define watch_list_foreach(vec, watch, lit) \
+ for (watch = watch_list_array(vec_wl_at(vec, lit)); \
+ watch < watch_list_array(vec_wl_at(vec, lit)) + watch_list_size(vec_wl_at(vec, lit)); \
+ watch++)
+
+#define watch_list_foreach_bin(vec, watch, lit) \
+ for (watch = watch_list_array(vec_wl_at(vec, lit)); \
+ watch < watch_list_array(vec_wl_at(vec, lit)) + vec_wl_at(vec, lit)->n_bin; \
+ watch++)
+//===------------------------------------------------------------------------===
+// Watch list API
+//===------------------------------------------------------------------------===
+static inline void watch_list_free(struct watch_list *wl)
+{
+ if (wl->watchers)
+ satoko_free(wl->watchers);
+}
+
+static inline unsigned watch_list_size(struct watch_list *wl)
+{
+ return wl->size;
+}
+
+static inline void watch_list_shrink(struct watch_list *wl, unsigned size)
+{
+ assert(size <= wl->size);
+ wl->size = size;
+}
+
+static inline void watch_list_grow(struct watch_list *wl)
+{
+ unsigned new_size = (wl->cap < 4) ? 4 : (wl->cap / 2) * 3;
+ struct watcher *watchers =
+ satoko_realloc(struct watcher, wl->watchers, new_size);
+ if (watchers == NULL) {
+ printf("Failed to realloc memory from %.1f MB to %.1f "
+ "MB.\n",
+ 1.0 * wl->cap / (1 << 20),
+ 1.0 * new_size / (1 << 20));
+ fflush(stdout);
+ return;
+ }
+ wl->watchers = watchers;
+ wl->cap = new_size;
+}
+
+static inline void watch_list_push(struct watch_list *wl, struct watcher w, unsigned is_bin)
+{
+ assert(wl);
+ if (wl->size == wl->cap)
+ watch_list_grow(wl);
+ wl->watchers[wl->size++] = w;
+ if (is_bin && wl->size > wl->n_bin) {
+ stk_swap(struct watcher, wl->watchers[wl->n_bin], wl->watchers[wl->size - 1]);
+ wl->n_bin++;
+ }
+}
+
+static inline struct watcher *watch_list_array(struct watch_list *wl)
+{
+ return wl->watchers;
+}
+
+/* TODO: I still have mixed feelings if this change should be done, keeping the
+ * old code commented after it. */
+static inline void watch_list_remove(struct watch_list *wl, unsigned cref, unsigned is_bin)
+{
+ struct watcher *watchers = watch_list_array(wl);
+ unsigned i;
+ if (is_bin) {
+ for (i = 0; watchers[i].cref != cref; i++);
+ assert(i < watch_list_size(wl));
+ wl->n_bin--;
+ memmove((wl->watchers + i), (wl->watchers + i + 1),
+ (wl->size - i - 1) * sizeof(struct watcher));
+ } else {
+ for (i = wl->n_bin; watchers[i].cref != cref; i++);
+ assert(i < watch_list_size(wl));
+ stk_swap(struct watcher, wl->watchers[i], wl->watchers[wl->size - 1]);
+ }
+ wl->size -= 1;
+}
+
+/*
+static inline void watch_list_remove(struct watch_list *wl, unsigned cref, unsigned is_bin)
+{
+ struct watcher *watchers = watch_list_array(wl);
+ unsigned i;
+ if (is_bin) {
+ for (i = 0; watchers[i].cref != cref; i++);
+ wl->n_bin--;
+ } else
+ for (i = wl->n_bin; watchers[i].cref != cref; i++);
+ assert(i < watch_list_size(wl));
+ memmove((wl->watchers + i), (wl->watchers + i + 1),
+ (wl->size - i - 1) * sizeof(struct watcher));
+ wl->size -= 1;
+}
+*/
+
+static inline vec_wl_t *vec_wl_alloc(unsigned cap)
+{
+ vec_wl_t *vec_wl = satoko_alloc(vec_wl_t, 1);
+
+ if (cap == 0)
+ vec_wl->cap = 4;
+ else
+ vec_wl->cap = cap;
+ vec_wl->size = 0;
+ vec_wl->watch_lists = satoko_calloc(
+ struct watch_list, sizeof(struct watch_list) * vec_wl->cap);
+ return vec_wl;
+}
+
+static inline void vec_wl_free(vec_wl_t *vec_wl)
+{
+ unsigned i;
+ for (i = 0; i < vec_wl->cap; i++)
+ watch_list_free(vec_wl->watch_lists + i);
+ satoko_free(vec_wl->watch_lists);
+ satoko_free(vec_wl);
+}
+
+static inline void vec_wl_clean(vec_wl_t *vec_wl)
+{
+ unsigned i;
+ for (i = 0; i < vec_wl->size; i++) {
+ vec_wl->watch_lists[i].size = 0;
+ vec_wl->watch_lists[i].n_bin = 0;
+ }
+ vec_wl->size = 0;
+}
+
+static inline void vec_wl_push(vec_wl_t *vec_wl)
+{
+ if (vec_wl->size == vec_wl->cap) {
+ unsigned new_size =
+ (vec_wl->cap < 4) ? vec_wl->cap * 2 : (vec_wl->cap / 2) * 3;
+
+ vec_wl->watch_lists = satoko_realloc(
+ struct watch_list, vec_wl->watch_lists, new_size);
+ memset(vec_wl->watch_lists + vec_wl->cap, 0,
+ sizeof(struct watch_list) * (new_size - vec_wl->cap));
+ if (vec_wl->watch_lists == NULL) {
+ printf("failed to realloc memory from %.1f mb to %.1f "
+ "mb.\n",
+ 1.0 * vec_wl->cap / (1 << 20),
+ 1.0 * new_size / (1 << 20));
+ fflush(stdout);
+ }
+ vec_wl->cap = new_size;
+ }
+ vec_wl->size++;
+}
+
+static inline struct watch_list *vec_wl_at(vec_wl_t *vec_wl, unsigned idx)
+{
+ assert(idx < vec_wl->cap);
+ assert(idx < vec_wl->size);
+ return vec_wl->watch_lists + idx;
+}
+
+ABC_NAMESPACE_HEADER_END
+#endif /* satoko__watch_list_h */
diff --git a/src/sat/xsat/license b/src/sat/xsat/license
new file mode 100644
index 00000000..a6389ab1
--- /dev/null
+++ b/src/sat/xsat/license
@@ -0,0 +1,39 @@
+xSAT - Copyright (c) 2016, Bruno Schmitt - UC Berkeley / UFRGS (boschmitt@inf.ufrgs.br)
+
+xSAT is based on Glucose v3(see Glucose copyrights below) and ABC C version of
+MiniSat (bsat) developed by Niklas Sorensson and modified by Alan Mishchenko.
+Permissions and copyrights of xSAT are exactly the same as Glucose v3/Minisat.
+(see below).
+
+---------------
+
+Glucose -- Copyright (c) 2013, Gilles Audemard, Laurent Simon
+ CRIL - Univ. Artois, France
+ LRI - Univ. Paris Sud, France
+
+Glucose sources are based on MiniSat (see below MiniSat copyrights). Permissions
+and copyrights of Glucose are exactly the same as Minisat on which it is based
+on. (see below).
+
+---------------
+
+Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
+Copyright (c) 2007-2010, Niklas Sorensson
+
+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.
+*******************************************************************************/
diff --git a/src/sat/xsat/module.make b/src/sat/xsat/module.make
new file mode 100644
index 00000000..1d7352e2
--- /dev/null
+++ b/src/sat/xsat/module.make
@@ -0,0 +1,3 @@
+SRC += src/sat/xsat/xsatSolver.c \
+ src/sat/xsat/xsatSolverAPI.c \
+ src/sat/xsat/xsatCnfReader.c
diff --git a/src/sat/xsat/xsat.h b/src/sat/xsat/xsat.h
new file mode 100644
index 00000000..b2962d91
--- /dev/null
+++ b/src/sat/xsat/xsat.h
@@ -0,0 +1,59 @@
+/**CFile****************************************************************
+
+ FileName [xsat.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [xSAT - A SAT solver written in C.
+ Read the license file for more info.]
+
+ Synopsis [External definitions of the solver.]
+
+ Author [Bruno Schmitt <boschmitt@inf.ufrgs.br>]
+
+ Affiliation [UC Berkeley / UFRGS]
+
+ Date [Ver. 1.0. Started - November 10, 2016.]
+
+ Revision []
+
+***********************************************************************/
+#ifndef ABC__sat__xSAT__xSAT_h
+#define ABC__sat__xSAT__xSAT_h
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+#include "misc/util/abc_global.h"
+#include "misc/vec/vecInt.h"
+
+ABC_NAMESPACE_HEADER_START
+
+////////////////////////////////////////////////////////////////////////
+/// STRUCTURE DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+struct xSAT_Solver_t_;
+typedef struct xSAT_Solver_t_ xSAT_Solver_t;
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+/*=== xsatCnfReader.c ================================================*/
+extern int xSAT_SolverParseDimacs( FILE *, xSAT_Solver_t ** );
+
+/*=== xsatSolverAPI.c ================================================*/
+extern xSAT_Solver_t * xSAT_SolverCreate();
+extern void xSAT_SolverDestroy( xSAT_Solver_t * );
+
+extern int xSAT_SolverAddClause( xSAT_Solver_t *, Vec_Int_t * );
+extern int xSAT_SolverSimplify( xSAT_Solver_t * );
+extern int xSAT_SolverSolve( xSAT_Solver_t * );
+
+extern void xSAT_SolverPrintStats( xSAT_Solver_t * );
+
+ABC_NAMESPACE_HEADER_END
+
+#endif
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
diff --git a/src/sat/xsat/xsatBQueue.h b/src/sat/xsat/xsatBQueue.h
new file mode 100644
index 00000000..f75f3650
--- /dev/null
+++ b/src/sat/xsat/xsatBQueue.h
@@ -0,0 +1,190 @@
+/**CFile****************************************************************
+
+ FileName [xsatBQueue.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [xSAT - A SAT solver written in C.
+ Read the license file for more info.]
+
+ Synopsis [Bounded queue implementation.]
+
+ Author [Bruno Schmitt <boschmitt@inf.ufrgs.br>]
+
+ Affiliation [UC Berkeley / UFRGS]
+
+ Date [Ver. 1.0. Started - November 10, 2016.]
+
+ Revision []
+
+***********************************************************************/
+#ifndef ABC__sat__xSAT__xsatBQueue_h
+#define ABC__sat__xSAT__xsatBQueue_h
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+#include "misc/util/abc_global.h"
+
+ABC_NAMESPACE_HEADER_START
+
+////////////////////////////////////////////////////////////////////////
+/// STRUCTURE DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+typedef struct xSAT_BQueue_t_ xSAT_BQueue_t;
+struct xSAT_BQueue_t_
+{
+ int nSize;
+ int nCap;
+ int iFirst;
+ int iEmpty;
+ word nSum;
+ unsigned * pData;
+};
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline xSAT_BQueue_t * xSAT_BQueueNew( int nCap )
+{
+ xSAT_BQueue_t * p = ABC_CALLOC( xSAT_BQueue_t, 1 );
+ p->nCap = nCap;
+ p->pData = ABC_CALLOC( unsigned, nCap );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_BQueueFree( xSAT_BQueue_t * p )
+{
+ ABC_FREE( p->pData );
+ ABC_FREE( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_BQueuePush( xSAT_BQueue_t * p, unsigned Value )
+{
+ if ( p->nSize == p->nCap )
+ {
+ assert(p->iFirst == p->iEmpty);
+ p->nSum -= p->pData[p->iFirst];
+ p->iFirst = ( p->iFirst + 1 ) % p->nCap;
+ }
+ else
+ p->nSize++;
+
+ p->nSum += Value;
+ p->pData[p->iEmpty] = Value;
+ if ( ( ++p->iEmpty ) == p->nCap )
+ {
+ p->iEmpty = 0;
+ p->iFirst = 0;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int xSAT_BQueuePop( xSAT_BQueue_t * p )
+{
+ int RetValue;
+ assert( p->nSize >= 1 );
+ RetValue = p->pData[p->iFirst];
+ p->nSum -= RetValue;
+ p->iFirst = ( p->iFirst + 1 ) % p->nCap;
+ p->nSize--;
+ return RetValue;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline unsigned xSAT_BQueueAvg( xSAT_BQueue_t * p )
+{
+ return ( unsigned )( p->nSum / ( ( word ) p->nSize ) );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int xSAT_BQueueIsValid( xSAT_BQueue_t * p )
+{
+ return ( p->nCap == p->nSize );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_BQueueClean( xSAT_BQueue_t * p )
+{
+ p->iFirst = 0;
+ p->iEmpty = 0;
+ p->nSize = 0;
+ p->nSum = 0;
+}
+
+ABC_NAMESPACE_HEADER_END
+
+#endif
diff --git a/src/sat/xsat/xsatClause.h b/src/sat/xsat/xsatClause.h
new file mode 100644
index 00000000..ef353198
--- /dev/null
+++ b/src/sat/xsat/xsatClause.h
@@ -0,0 +1,109 @@
+/**CFile****************************************************************
+
+ FileName [xsatClause.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [xSAT - A SAT solver written in C.
+ Read the license file for more info.]
+
+ Synopsis [Clause data type definition.]
+
+ Author [Bruno Schmitt <boschmitt@inf.ufrgs.br>]
+
+ Affiliation [UC Berkeley / UFRGS]
+
+ Date [Ver. 1.0. Started - November 10, 2016.]
+
+ Revision []
+
+***********************************************************************/
+#ifndef ABC__sat__xSAT__xsatClause_h
+#define ABC__sat__xSAT__xsatClause_h
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+#include "misc/util/abc_global.h"
+
+ABC_NAMESPACE_HEADER_START
+
+////////////////////////////////////////////////////////////////////////
+/// STRUCTURE DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+typedef struct xSAT_Clause_t_ xSAT_Clause_t;
+struct xSAT_Clause_t_
+{
+ unsigned fLearnt : 1;
+ unsigned fMark : 1;
+ unsigned fReallocd : 1;
+ unsigned fCanBeDel : 1;
+ unsigned nLBD : 28;
+ int nSize;
+ union {
+ int Lit;
+ unsigned Act;
+ } pData[0];
+};
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int xSAT_ClauseCompare( const void * p1, const void * p2 )
+{
+ xSAT_Clause_t * pC1 = ( xSAT_Clause_t * ) p1;
+ xSAT_Clause_t * pC2 = ( xSAT_Clause_t * ) p2;
+
+ if ( pC1->nSize > 2 && pC2->nSize == 2 )
+ return 1;
+ if ( pC1->nSize == 2 && pC2->nSize > 2 )
+ return 0;
+ if ( pC1->nSize == 2 && pC2->nSize == 2 )
+ return 0;
+
+ if ( pC1->nLBD > pC2->nLBD )
+ return 1;
+ if ( pC1->nLBD < pC2->nLBD )
+ return 0;
+
+ return pC1->pData[pC1->nSize].Act < pC2->pData[pC2->nSize].Act;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_ClausePrint( xSAT_Clause_t * pCla )
+{
+ int i;
+
+ printf("{ ");
+ for ( i = 0; i < pCla->nSize; i++ )
+ printf("%d ", pCla->pData[i].Lit );
+ printf("}\n");
+}
+
+ABC_NAMESPACE_HEADER_END
+
+#endif
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
diff --git a/src/sat/xsat/xsatCnfReader.c b/src/sat/xsat/xsatCnfReader.c
new file mode 100644
index 00000000..d23e8a0a
--- /dev/null
+++ b/src/sat/xsat/xsatCnfReader.c
@@ -0,0 +1,236 @@
+/**CFile****************************************************************
+
+ FileName [xsatCnfReader.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [xSAT - A SAT solver written in C.
+ Read the license file for more info.]
+
+ Synopsis [CNF DIMACS file format parser.]
+
+ Author [Bruno Schmitt <boschmitt@inf.ufrgs.br>]
+
+ Affiliation [UC Berkeley / UFRGS]
+
+ Date [Ver. 1.0. Started - November 10, 2016.]
+
+ Revision []
+
+***********************************************************************/
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+#include <ctype.h>
+
+#include "misc/util/abc_global.h"
+#include "misc/vec/vecInt.h"
+
+#include "xsatSolver.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Read the file into the internal buffer.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+char * xSAT_FileRead( FILE * pFile )
+{
+ int nFileSize;
+ char * pBuffer;
+ int RetValue;
+ // get the file size, in bytes
+ fseek( pFile, 0, SEEK_END );
+ nFileSize = ftell( pFile );
+ // move the file current reading position to the beginning
+ rewind( pFile );
+ // load the contents of the file into memory
+ pBuffer = ABC_ALLOC( char, nFileSize + 3 );
+ RetValue = fread( pBuffer, nFileSize, 1, pFile );
+ // terminate the string with '\0'
+ pBuffer[ nFileSize + 0] = '\n';
+ pBuffer[ nFileSize + 1] = '\0';
+ return pBuffer;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static void skipLine( char ** pIn )
+{
+ while ( 1 )
+ {
+ if (**pIn == 0)
+ return;
+ if (**pIn == '\n')
+ {
+ (*pIn)++;
+ return;
+ }
+ (*pIn)++;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static int xSAT_ReadInt( char ** pIn )
+{
+ int val = 0;
+ int neg = 0;
+
+ for(; isspace(**pIn); (*pIn)++);
+ if ( **pIn == '-' )
+ neg = 1,
+ (*pIn)++;
+ else if ( **pIn == '+' )
+ (*pIn)++;
+ if ( !isdigit(**pIn) )
+ fprintf(stderr, "PARSE ERROR! Unexpected char: %c\n", **pIn),
+ exit(1);
+ while ( isdigit(**pIn) )
+ val = val*10 + (**pIn - '0'),
+ (*pIn)++;
+ return neg ? -val : val;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static void xSAT_ReadClause( char ** pIn, xSAT_Solver_t * p, Vec_Int_t * vLits )
+{
+ int token, var, sign;
+
+ Vec_IntClear( vLits );
+ while ( 1 )
+ {
+ token = xSAT_ReadInt( pIn );
+ if ( token == 0 )
+ break;
+ var = abs(token) - 1;
+ sign = (token > 0);
+ Vec_IntPush( vLits, xSAT_Var2Lit( var, !sign ) );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static int xSAT_ParseDimacs( char * pText, xSAT_Solver_t ** pS )
+{
+ xSAT_Solver_t * p = NULL;
+ Vec_Int_t * vLits = NULL;
+ char * pIn = pText;
+ int nVars, nClas;
+ while ( 1 )
+ {
+ for(; isspace(*pIn); pIn++);
+ if ( *pIn == 0 )
+ break;
+ else if ( *pIn == 'c' )
+ skipLine( &pIn );
+ else if ( *pIn == 'p' )
+ {
+ pIn++;
+ for(; isspace(*pIn); pIn++);
+ for(; !isspace(*pIn); pIn++);
+
+ nVars = xSAT_ReadInt( &pIn );
+ nClas = xSAT_ReadInt( &pIn );
+ skipLine( &pIn );
+
+ /* start the solver */
+ p = xSAT_SolverCreate();
+ /* allocate the vector */
+ vLits = Vec_IntAlloc( nVars );
+ }
+ else
+ {
+ if ( p == NULL )
+ {
+ printf( "There is no parameter line.\n" );
+ exit(1);
+ }
+ xSAT_ReadClause( &pIn, p, vLits );
+ if ( !xSAT_SolverAddClause( p, vLits ) )
+ {
+ Vec_IntPrint(vLits);
+ return 0;
+ }
+ }
+ }
+ Vec_IntFree( vLits );
+ *pS = p;
+ return xSAT_SolverSimplify( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Starts the solver and reads the DIMAC file.]
+
+ Description [Returns FALSE upon immediate conflict.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int xSAT_SolverParseDimacs( FILE * pFile, xSAT_Solver_t ** p )
+{
+ char * pText;
+ int Value;
+ pText = xSAT_FileRead( pFile );
+ Value = xSAT_ParseDimacs( pText, p );
+ ABC_FREE( pText );
+ return Value;
+}
+
+ABC_NAMESPACE_IMPL_END
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
diff --git a/src/sat/xsat/xsatHeap.h b/src/sat/xsat/xsatHeap.h
new file mode 100644
index 00000000..409ce460
--- /dev/null
+++ b/src/sat/xsat/xsatHeap.h
@@ -0,0 +1,330 @@
+/**CFile****************************************************************
+
+ FileName [xsatHeap.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [xSAT - A SAT solver written in C.
+ Read the license file for more info.]
+
+ Synopsis [Heap implementation.]
+
+ Author [Bruno Schmitt <boschmitt@inf.ufrgs.br>]
+
+ Affiliation [UC Berkeley / UFRGS]
+
+ Date [Ver. 1.0. Started - November 10, 2016.]
+
+ Revision []
+
+***********************************************************************/
+#ifndef ABC__sat__xSAT__xsatHeap_h
+#define ABC__sat__xSAT__xsatHeap_h
+
+#include "misc/util/abc_global.h"
+#include "misc/vec/vecInt.h"
+
+ABC_NAMESPACE_HEADER_START
+
+////////////////////////////////////////////////////////////////////////
+/// STRUCTURE DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+typedef struct xSAT_Heap_t_ xSAT_Heap_t;
+struct xSAT_Heap_t_
+{
+ Vec_Int_t * vActivity;
+ Vec_Int_t * vIndices;
+ Vec_Int_t * vHeap;
+};
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int xSAT_HeapSize( xSAT_Heap_t * h )
+{
+ return Vec_IntSize( h->vHeap );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int xSAT_HeapInHeap( xSAT_Heap_t * h, int Var )
+{
+ return ( Var < Vec_IntSize( h->vIndices ) ) && ( Vec_IntEntry( h->vIndices, Var ) >= 0 );
+}
+
+static inline int Left ( int i ) { return 2 * i + 1; }
+static inline int Right ( int i ) { return ( i + 1 ) * 2; }
+static inline int Parent( int i ) { return ( i - 1 ) >> 1; }
+static inline int Compare( xSAT_Heap_t * p, int x, int y )
+{
+ return ( unsigned )Vec_IntEntry( p->vActivity, x ) > ( unsigned )Vec_IntEntry( p->vActivity, y );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_HeapPercolateUp( xSAT_Heap_t * h, int i )
+{
+ int x = Vec_IntEntry( h->vHeap, i );
+ int p = Parent( i );
+
+ while ( i != 0 && Compare( h, x, Vec_IntEntry( h->vHeap, p ) ) )
+ {
+ Vec_IntWriteEntry( h->vHeap, i, Vec_IntEntry( h->vHeap, p ) );
+ Vec_IntWriteEntry( h->vIndices, Vec_IntEntry( h->vHeap, p ), i );
+ i = p;
+ p = Parent(p);
+ }
+ Vec_IntWriteEntry( h->vHeap, i, x );
+ Vec_IntWriteEntry( h->vIndices, x, i );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_HeapPercolateDown( xSAT_Heap_t * h, int i )
+{
+ int x = Vec_IntEntry( h->vHeap, i );
+
+ while ( Left( i ) < Vec_IntSize( h->vHeap ) )
+ {
+ int child = Right( i ) < Vec_IntSize( h->vHeap ) &&
+ Compare( h, Vec_IntEntry( h->vHeap, Right( i ) ), Vec_IntEntry( h->vHeap, Left( i ) ) ) ?
+ Right( i ) : Left( i );
+
+ if ( !Compare( h, Vec_IntEntry( h->vHeap, child ), x ) )
+ break;
+
+ Vec_IntWriteEntry( h->vHeap, i, Vec_IntEntry( h->vHeap, child ) );
+ Vec_IntWriteEntry( h->vIndices, Vec_IntEntry( h->vHeap, i ), i );
+ i = child;
+ }
+ Vec_IntWriteEntry( h->vHeap, i, x );
+ Vec_IntWriteEntry( h->vIndices, x, i );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline xSAT_Heap_t * xSAT_HeapAlloc( Vec_Int_t * vActivity )
+{
+ xSAT_Heap_t * p = ABC_ALLOC( xSAT_Heap_t, 1 );
+ p->vActivity = vActivity;
+ p->vIndices = Vec_IntAlloc( 0 );
+ p->vHeap = Vec_IntAlloc( 0 );
+
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_HeapFree( xSAT_Heap_t * p )
+{
+ Vec_IntFree( p->vIndices );
+ Vec_IntFree( p->vHeap );
+ ABC_FREE( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_HeapIncrease( xSAT_Heap_t * h, int e )
+{
+ assert( xSAT_HeapInHeap( h, e ) );
+ xSAT_HeapPercolateDown( h, Vec_IntEntry( h->vIndices, e ) );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_HeapDecrease( xSAT_Heap_t * p, int e )
+{
+ assert( xSAT_HeapInHeap( p, e ) );
+ xSAT_HeapPercolateUp( p , Vec_IntEntry( p->vIndices, e ) );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_HeapInsert( xSAT_Heap_t * p, int n )
+{
+ Vec_IntFillExtra( p->vIndices, n + 1, -1);
+ assert( !xSAT_HeapInHeap( p, n ) );
+
+ Vec_IntWriteEntry( p->vIndices, n, Vec_IntSize( p->vHeap ) );
+ Vec_IntPush( p->vHeap, n );
+ xSAT_HeapPercolateUp( p, Vec_IntEntry( p->vIndices, n ) );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_HeapUpdate( xSAT_Heap_t * p, int i )
+{
+ if ( !xSAT_HeapInHeap( p, i ) )
+ xSAT_HeapInsert( p, i );
+ else
+ {
+ xSAT_HeapPercolateUp( p, Vec_IntEntry( p->vIndices, i ) );
+ xSAT_HeapPercolateDown( p, Vec_IntEntry( p->vIndices, i ) );
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_HeapBuild( xSAT_Heap_t * p, Vec_Int_t * Vars )
+{
+ int i, Var;
+
+ Vec_IntForEachEntry( p->vHeap, Var, i )
+ Vec_IntWriteEntry( p->vIndices, Var, -1 );
+ Vec_IntClear( p->vHeap );
+
+ Vec_IntForEachEntry( Vars, Var, i )
+ {
+ Vec_IntWriteEntry( p->vIndices, Var, i );
+ Vec_IntPush( p->vHeap, Var );
+ }
+
+ for ( ( i = Vec_IntSize( p->vHeap ) / 2 - 1 ); i >= 0; i-- )
+ xSAT_HeapPercolateDown( p, i );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_HeapClear( xSAT_Heap_t * p )
+{
+ Vec_IntFill( p->vIndices, Vec_IntSize( p->vIndices ), -1 );
+ Vec_IntClear( p->vHeap );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int xSAT_HeapRemoveMin( xSAT_Heap_t * p )
+{
+ int x = Vec_IntEntry( p->vHeap, 0 );
+ Vec_IntWriteEntry( p->vHeap, 0, Vec_IntEntryLast( p->vHeap ) );
+ Vec_IntWriteEntry( p->vIndices, Vec_IntEntry( p->vHeap, 0), 0 );
+ Vec_IntWriteEntry( p->vIndices, x, -1 );
+ Vec_IntPop( p->vHeap );
+ if ( Vec_IntSize( p->vHeap ) > 1 )
+ xSAT_HeapPercolateDown( p, 0 );
+ return x;
+}
+
+ABC_NAMESPACE_HEADER_END
+
+#endif
diff --git a/src/sat/xsat/xsatMemory.h b/src/sat/xsat/xsatMemory.h
new file mode 100644
index 00000000..129c2f50
--- /dev/null
+++ b/src/sat/xsat/xsatMemory.h
@@ -0,0 +1,222 @@
+/**CFile****************************************************************
+
+ FileName [xsatMemory.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [xSAT - A SAT solver written in C.
+ Read the license file for more info.]
+
+ Synopsis [Memory management implementation.]
+
+ Author [Bruno Schmitt <boschmitt@inf.ufrgs.br>]
+
+ Affiliation [UC Berkeley / UFRGS]
+
+ Date [Ver. 1.0. Started - November 10, 2016.]
+
+ Revision []
+
+***********************************************************************/
+#ifndef ABC__sat__xSAT__xsatMemory_h
+#define ABC__sat__xSAT__xsatMemory_h
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+#include "misc/util/abc_global.h"
+
+#include "xsatClause.h"
+
+ABC_NAMESPACE_HEADER_START
+
+////////////////////////////////////////////////////////////////////////
+/// STRUCTURE DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+typedef struct xSAT_Mem_t_ xSAT_Mem_t;
+struct xSAT_Mem_t_
+{
+ unsigned nSize;
+ unsigned nCap;
+ unsigned nWasted;
+ unsigned * pData;
+};
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline xSAT_Clause_t * xSAT_MemClauseHand( xSAT_Mem_t * p, int h )
+{
+ return h != 0xFFFFFFFF ? ( xSAT_Clause_t * )( p->pData + h ) : NULL;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_MemGrow( xSAT_Mem_t * p, unsigned nCap )
+{
+ unsigned nPrevCap = p->nCap;
+ if ( p->nCap >= nCap )
+ return;
+ while (p->nCap < nCap)
+ {
+ unsigned delta = ( ( p->nCap >> 1 ) + ( p->nCap >> 3 ) + 2 ) & ~1;
+ p->nCap += delta;
+ assert(p->nCap >= nPrevCap);
+ }
+ assert(p->nCap > 0);
+ p->pData = ABC_REALLOC( unsigned, p->pData, p->nCap );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Allocating vector.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline xSAT_Mem_t * xSAT_MemAlloc( int nCap )
+{
+ xSAT_Mem_t * p;
+ p = ABC_CALLOC( xSAT_Mem_t, 1 );
+ if (nCap <= 0)
+ nCap = 1024*1024;
+
+ xSAT_MemGrow(p, nCap);
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Resetting vector.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_MemRestart( xSAT_Mem_t * p )
+{
+ p->nSize = 0;
+ p->nWasted = 0;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Freeing vector.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_MemFree( xSAT_Mem_t * p )
+{
+ ABC_FREE( p->pData );
+ ABC_FREE( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Creates new clause.]
+
+ Description [The resulting clause is fully initialized.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline unsigned xSAT_MemAppend( xSAT_Mem_t * p, int nSize )
+{
+ unsigned nPrevSize;
+ assert(nSize > 0);
+ xSAT_MemGrow( p, p->nSize + nSize );
+ nPrevSize = p->nSize;
+ p->nSize += nSize;
+ assert(p->nSize > nPrevSize);
+ return nPrevSize;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline unsigned xSAT_MemCRef( xSAT_Mem_t * p, unsigned * pC )
+{
+ return ( unsigned )( pC - &(p->pData[0]) );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline unsigned xSAT_MemCap( xSAT_Mem_t * p )
+{
+ return p->nCap;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline unsigned xSAT_MemWastedCap( xSAT_Mem_t * p )
+{
+ return p->nWasted;
+}
+
+ABC_NAMESPACE_HEADER_END
+
+#endif
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
diff --git a/src/sat/xsat/xsatSolver.c b/src/sat/xsat/xsatSolver.c
new file mode 100644
index 00000000..9807e1b7
--- /dev/null
+++ b/src/sat/xsat/xsatSolver.c
@@ -0,0 +1,1003 @@
+/**CFile****************************************************************
+
+ FileName [xsatSolver.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [xSAT - A SAT solver written in C.
+ Read the license file for more info.]
+
+ Synopsis [Solver internal functions implementation.]
+
+ Author [Bruno Schmitt <boschmitt@inf.ufrgs.br>]
+
+ Affiliation [UC Berkeley / UFRGS]
+
+ Date [Ver. 1.0. Started - November 10, 2016.]
+
+ Revision []
+
+***********************************************************************/
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+#include <math.h>
+
+#include "xsatHeap.h"
+#include "xsatSolver.h"
+#include "xsatUtils.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int xSAT_SolverDecide( xSAT_Solver_t * s )
+{
+ int NextVar = VarUndef;
+
+ while ( NextVar == VarUndef || Vec_StrEntry( s->vAssigns, NextVar ) != VarX )
+ {
+ if ( xSAT_HeapSize( s->hOrder ) == 0 )
+ {
+ NextVar = VarUndef;
+ break;
+ }
+ else
+ NextVar = xSAT_HeapRemoveMin( s->hOrder );
+ }
+ return NextVar;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void xSAT_SolverRebuildOrderHeap( xSAT_Solver_t * s )
+{
+ Vec_Int_t * vTemp = Vec_IntAlloc( Vec_StrSize( s->vAssigns ) );
+ int Var;
+
+ for ( Var = 0; Var < Vec_StrSize( s->vAssigns ); Var++ )
+ if ( Vec_StrEntry( s->vAssigns, Var ) == VarX )
+ Vec_IntPush( vTemp, Var );
+
+ xSAT_HeapBuild( s->hOrder, vTemp );
+ Vec_IntFree( vTemp );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_SolverVarActRescale( xSAT_Solver_t * s )
+{
+ int i;
+ unsigned * pActivity = ( unsigned * ) Vec_IntArray( s->vActivity );
+
+ for ( i = 0; i < Vec_IntSize( s->vActivity ); i++ )
+ pActivity[i] >>= 19;
+
+ s->nVarActInc >>= 19;
+ s->nVarActInc = Abc_MaxInt( s->nVarActInc, ( 1 << 5 ) );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_SolverVarActBump( xSAT_Solver_t * s, int Var )
+{
+ unsigned * pActivity = ( unsigned * ) Vec_IntArray( s->vActivity );
+
+ pActivity[Var] += s->nVarActInc;
+ if ( pActivity[Var] & 0x80000000 )
+ xSAT_SolverVarActRescale( s );
+
+ if ( xSAT_HeapInHeap( s->hOrder, Var ) )
+ xSAT_HeapDecrease( s->hOrder, Var );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_SolverVarActDecay( xSAT_Solver_t * s )
+{
+ s->nVarActInc += ( s->nVarActInc >> 4 );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_SolverClaActRescale( xSAT_Solver_t * s )
+{
+ xSAT_Clause_t * pC;
+ int i, CRef;
+
+ Vec_IntForEachEntry( s->vLearnts, CRef, i )
+ {
+ pC = xSAT_SolverReadClause( s, ( unsigned ) CRef );
+ pC->pData[pC->nSize].Act >>= 14;
+ }
+ s->nClaActInc >>= 14;
+ s->nClaActInc = Abc_MaxInt( s->nClaActInc, ( 1 << 10 ) );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_SolverClaActBump( xSAT_Solver_t* s, xSAT_Clause_t * pCla )
+{
+ pCla->pData[pCla->nSize].Act += s->nClaActInc;
+ if ( pCla->pData[pCla->nSize].Act & 0x80000000 )
+ xSAT_SolverClaActRescale( s );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_SolverClaActDecay( xSAT_Solver_t * s )
+{
+ s->nClaActInc += ( s->nClaActInc >> 10 );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int xSAT_SolverClaCalcLBD( xSAT_Solver_t * s, xSAT_Clause_t * pCla )
+{
+ int i;
+ int nLBD = 0;
+
+ s->nStamp++;
+ for ( i = 0; i < pCla->nSize; i++ )
+ {
+ int Level = Vec_IntEntry( s->vLevels, xSAT_Lit2Var( pCla->pData[i].Lit ) );
+ if ( ( unsigned ) Vec_IntEntry( s->vStamp, Level ) != s->nStamp )
+ {
+ Vec_IntWriteEntry( s->vStamp, Level, ( int ) s->nStamp );
+ nLBD++;
+ }
+ }
+ return nLBD;
+}
+
+static inline int xSAT_SolverClaCalcLBD2( xSAT_Solver_t * s, Vec_Int_t * vLits )
+{
+ int i;
+ int nLBD = 0;
+
+ s->nStamp++;
+ for ( i = 0; i < Vec_IntSize( vLits ); i++ )
+ {
+ int Level = Vec_IntEntry( s->vLevels, xSAT_Lit2Var( Vec_IntEntry( vLits, i ) ) );
+ if ( ( unsigned ) Vec_IntEntry( s->vStamp, Level ) != s->nStamp )
+ {
+ Vec_IntWriteEntry( s->vStamp, Level, ( int ) s->nStamp );
+ nLBD++;
+ }
+ }
+ return nLBD;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+unsigned xSAT_SolverClaNew( xSAT_Solver_t * s, Vec_Int_t * vLits , int fLearnt )
+{
+ unsigned CRef;
+ xSAT_Clause_t * pCla;
+ xSAT_Watcher_t w1;
+ xSAT_Watcher_t w2;
+ unsigned nWords;
+
+ assert( Vec_IntSize( vLits ) > 1);
+ assert( fLearnt == 0 || fLearnt == 1 );
+
+ nWords = 3 + fLearnt + Vec_IntSize( vLits );
+ CRef = xSAT_MemAppend( s->pMemory, nWords );
+ pCla = xSAT_SolverReadClause( s, CRef );
+ pCla->fLearnt = fLearnt;
+ pCla->fMark = 0;
+ pCla->fReallocd = 0;
+ pCla->fCanBeDel = fLearnt;
+ pCla->nSize = Vec_IntSize( vLits );
+ memcpy( &( pCla->pData[0].Lit ), Vec_IntArray( vLits ), sizeof( int ) * Vec_IntSize( vLits ) );
+
+ if ( fLearnt )
+ {
+ Vec_IntPush( s->vLearnts, CRef );
+ pCla->nLBD = xSAT_SolverClaCalcLBD2( s, vLits );
+ pCla->pData[pCla->nSize].Act = 0;
+ s->Stats.nLearntLits += Vec_IntSize( vLits );
+ xSAT_SolverClaActBump(s, pCla);
+ }
+ else
+ {
+ Vec_IntPush( s->vClauses, CRef );
+ s->Stats.nClauseLits += Vec_IntSize( vLits );
+ }
+
+ w1.CRef = CRef;
+ w2.CRef = CRef;
+ w1.Blocker = pCla->pData[1].Lit;
+ w2.Blocker = pCla->pData[0].Lit;
+
+ if ( Vec_IntSize( vLits ) == 2 )
+ {
+ xSAT_WatchListPush( xSAT_VecWatchListEntry( s->vBinWatches, xSAT_NegLit( pCla->pData[0].Lit ) ), w1 );
+ xSAT_WatchListPush( xSAT_VecWatchListEntry( s->vBinWatches, xSAT_NegLit( pCla->pData[1].Lit ) ), w2 );
+ }
+ else
+ {
+ xSAT_WatchListPush( xSAT_VecWatchListEntry( s->vWatches, xSAT_NegLit( pCla->pData[0].Lit ) ), w1 );
+ xSAT_WatchListPush( xSAT_VecWatchListEntry( s->vWatches, xSAT_NegLit( pCla->pData[1].Lit ) ), w2 );
+ }
+ return CRef;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int xSAT_SolverEnqueue( xSAT_Solver_t * s, int Lit, unsigned Reason )
+{
+ int Var = xSAT_Lit2Var( Lit );
+
+ Vec_StrWriteEntry( s->vAssigns, Var, (char)xSAT_LitSign( Lit ) );
+ Vec_IntWriteEntry( s->vLevels, Var, xSAT_SolverDecisionLevel( s ) );
+ Vec_IntWriteEntry( s->vReasons, Var, ( int ) Reason );
+ Vec_IntPush( s->vTrail, Lit );
+
+ return true;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_SolverNewDecision( xSAT_Solver_t * s, int Lit )
+{
+ assert( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lit ) ) == VarX );
+ s->Stats.nDecisions++;
+ Vec_IntPush( s->vTrailLim, Vec_IntSize( s->vTrail ) );
+ xSAT_SolverEnqueue( s, Lit, CRefUndef );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void xSAT_SolverCancelUntil( xSAT_Solver_t * s, int Level )
+{
+ int c;
+
+ if ( xSAT_SolverDecisionLevel( s ) <= Level )
+ return;
+
+ for ( c = Vec_IntSize( s->vTrail ) - 1; c >= Vec_IntEntry( s->vTrailLim, Level ); c-- )
+ {
+ int Var = xSAT_Lit2Var( Vec_IntEntry( s->vTrail, c ) );
+
+ Vec_StrWriteEntry( s->vAssigns, Var, VarX );
+ Vec_IntWriteEntry( s->vReasons, Var, ( int ) CRefUndef );
+ Vec_StrWriteEntry( s->vPolarity, Var, ( char )xSAT_LitSign( Vec_IntEntry( s->vTrail, c ) ) );
+
+ if ( !xSAT_HeapInHeap( s->hOrder, Var ) )
+ xSAT_HeapInsert( s->hOrder, Var );
+ }
+
+ s->iQhead = Vec_IntEntry( s->vTrailLim, Level );
+ Vec_IntShrink( s->vTrail, Vec_IntEntry( s->vTrailLim, Level ) );
+ Vec_IntShrink( s->vTrailLim, Level );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static int xSAT_SolverIsLitRemovable( xSAT_Solver_t* s, int Lit, int MinLevel )
+{
+ int top = Vec_IntSize( s->vTagged );
+
+ assert( ( unsigned ) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( Lit ) ) != CRefUndef );
+ Vec_IntClear( s->vStack );
+ Vec_IntPush( s->vStack, xSAT_Lit2Var( Lit ) );
+
+ while ( Vec_IntSize( s->vStack ) )
+ {
+ int i;
+ int v = Vec_IntPop( s->vStack );
+ xSAT_Clause_t* c = xSAT_SolverReadClause(s, ( unsigned ) Vec_IntEntry( s->vReasons, v ) );
+ int * Lits = &( c->pData[0].Lit );
+
+ assert( (unsigned) Vec_IntEntry( s->vReasons, v ) != CRefUndef);
+ if( c->nSize == 2 && Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lits[0] ) ) == xSAT_LitSign( xSAT_NegLit( Lits[0] ) ) )
+ {
+ assert( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lits[1] ) ) == xSAT_LitSign( ( Lits[1] ) ) );
+ ABC_SWAP( int, Lits[0], Lits[1] );
+ }
+
+ for ( i = 1; i < c->nSize; i++ )
+ {
+ int v = xSAT_Lit2Var( Lits[i] );
+ if ( !Vec_StrEntry( s->vSeen, v ) && Vec_IntEntry( s->vLevels, v ) )
+ {
+ if ( ( unsigned ) Vec_IntEntry( s->vReasons, v ) != CRefUndef && ( ( 1 << (Vec_IntEntry( s->vLevels, v ) & 31 ) ) & MinLevel ) )
+ {
+ Vec_IntPush( s->vStack, v );
+ Vec_IntPush( s->vTagged, Lits[i] );
+ Vec_StrWriteEntry( s->vSeen, v, 1 );
+ }
+ else
+ {
+ int Lit;
+ Vec_IntForEachEntryStart( s->vTagged, Lit, i, top )
+ Vec_StrWriteEntry( s->vSeen, xSAT_Lit2Var( Lit ), 0 );
+ Vec_IntShrink( s->vTagged, top );
+ return 0;
+ }
+ }
+ }
+ }
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static void xSAT_SolverClaMinimisation( xSAT_Solver_t * s, Vec_Int_t * vLits )
+{
+ int * pLits = Vec_IntArray( vLits );
+ int MinLevel = 0;
+ int i, j;
+
+ for ( i = 1; i < Vec_IntSize( vLits ); i++ )
+ {
+ int Level = Vec_IntEntry( s->vLevels, xSAT_Lit2Var( pLits[i] ) );
+ MinLevel |= 1 << ( Level & 31 );
+ }
+
+ /* Remove reduntant literals */
+ Vec_IntAppend( s->vTagged, vLits );
+ for ( i = j = 1; i < Vec_IntSize( vLits ); i++ )
+ if ( ( unsigned ) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( pLits[i] ) ) == CRefUndef || !xSAT_SolverIsLitRemovable( s, pLits[i], MinLevel ) )
+ pLits[j++] = pLits[i];
+ Vec_IntShrink( vLits, j );
+
+ /* Binary Resolution */
+ if( Vec_IntSize( vLits ) <= 30 && xSAT_SolverClaCalcLBD2( s, vLits ) <= 6 )
+ {
+ int nb, l;
+ int Lit;
+ int FlaseLit = xSAT_NegLit( pLits[0] );
+ xSAT_WatchList_t * ws = xSAT_VecWatchListEntry( s->vBinWatches, FlaseLit );
+ xSAT_Watcher_t * begin = xSAT_WatchListArray( ws );
+ xSAT_Watcher_t * end = begin + xSAT_WatchListSize( ws );
+ xSAT_Watcher_t * pWatcher;
+
+ s->nStamp++;
+ Vec_IntForEachEntry( vLits, Lit, i )
+ Vec_IntWriteEntry( s->vStamp, xSAT_Lit2Var( Lit ), ( int ) s->nStamp );
+
+ nb = 0;
+ for ( pWatcher = begin; pWatcher < end; pWatcher++ )
+ {
+ int ImpLit = pWatcher->Blocker;
+
+ if ( ( unsigned ) Vec_IntEntry( s->vStamp, xSAT_Lit2Var( ImpLit ) ) == s->nStamp && Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( ImpLit ) ) == xSAT_LitSign( ImpLit ) )
+ {
+ nb++;
+ Vec_IntWriteEntry( s->vStamp, xSAT_Lit2Var( ImpLit ), ( int )( s->nStamp - 1 ) );
+ }
+ }
+
+ l = Vec_IntSize( vLits ) - 1;
+ if ( nb > 0 )
+ {
+ for ( i = 1; i < Vec_IntSize( vLits ) - nb; i++ )
+ if ( ( unsigned ) Vec_IntEntry( s->vStamp, xSAT_Lit2Var( pLits[i] ) ) != s->nStamp )
+ {
+ int TempLit = pLits[l];
+ pLits[l] = pLits[i];
+ pLits[i] = TempLit;
+ i--; l--;
+ }
+
+ Vec_IntShrink( vLits, Vec_IntSize( vLits ) - nb );
+ }
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static void xSAT_SolverAnalyze( xSAT_Solver_t* s, unsigned ConfCRef, Vec_Int_t * vLearnt, int * OutBtLevel, unsigned * nLBD )
+{
+ int * trail = Vec_IntArray( s->vTrail );
+ int Count = 0;
+ int p = LitUndef;
+ int Idx = Vec_IntSize( s->vTrail ) - 1;
+ int * Lits;
+ int Lit;
+ int i, j;
+
+ Vec_IntPush( vLearnt, LitUndef );
+ do
+ {
+ xSAT_Clause_t * pCla;
+
+ assert( ConfCRef != CRefUndef );
+ pCla = xSAT_SolverReadClause(s, ConfCRef);
+ Lits = &( pCla->pData[0].Lit );
+
+ if( p != LitUndef && pCla->nSize == 2 && Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lits[0] ) ) == xSAT_LitSign( xSAT_NegLit( Lits[0] ) ) )
+ {
+ assert( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lits[1] ) ) == xSAT_LitSign( ( Lits[1] ) ) );
+ ABC_SWAP( int, Lits[0], Lits[1] );
+ }
+
+ if ( pCla->fLearnt )
+ xSAT_SolverClaActBump( s, pCla );
+
+ if ( pCla->fLearnt && pCla->nLBD > 2 )
+ {
+ unsigned int nLevels = xSAT_SolverClaCalcLBD( s, pCla );
+ if ( nLevels + 1 < pCla->nLBD )
+ {
+ if ( pCla->nLBD <= s->Config.nLBDFrozenClause )
+ pCla->fCanBeDel = 0;
+ pCla->nLBD = nLevels;
+ }
+ }
+
+ for ( j = ( p == LitUndef ? 0 : 1 ); j < pCla->nSize; j++ )
+ {
+ int Var = xSAT_Lit2Var( Lits[j] );
+
+ if ( Vec_StrEntry( s->vSeen, Var ) == 0 && Vec_IntEntry( s->vLevels, Var ) > 0 )
+ {
+ Vec_StrWriteEntry( s->vSeen, Var, 1 );
+ xSAT_SolverVarActBump( s, Var );
+ if ( Vec_IntEntry( s->vLevels, Var ) >= xSAT_SolverDecisionLevel( s ) )
+ {
+ Count++;
+ if ( Vec_IntEntry( s->vReasons, Var ) != CRefUndef && xSAT_SolverReadClause( s, Vec_IntEntry( s->vReasons, Var ) )->fLearnt )
+ Vec_IntPush( s->vLastDLevel, Var );
+ }
+ else
+ Vec_IntPush( vLearnt, Lits[j] );
+ }
+ }
+
+ while ( !Vec_StrEntry( s->vSeen, xSAT_Lit2Var( trail[Idx--] ) ) );
+
+ // Next clause to look at
+ p = trail[Idx+1];
+ ConfCRef = ( unsigned ) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( p ) );
+ Vec_StrWriteEntry( s->vSeen, xSAT_Lit2Var( p ), 0 );
+ Count--;
+
+ } while ( Count > 0 );
+
+ Vec_IntArray( vLearnt )[0] = xSAT_NegLit( p );
+ xSAT_SolverClaMinimisation( s, vLearnt );
+
+ // Find the backtrack level
+ Lits = Vec_IntArray( vLearnt );
+ if ( Vec_IntSize( vLearnt ) == 1 )
+ *OutBtLevel = 0;
+ else
+ {
+ int iMax = 1;
+ int Max = Vec_IntEntry( s->vLevels, xSAT_Lit2Var( Lits[1] ) );
+ int Tmp;
+
+ for (i = 2; i < Vec_IntSize( vLearnt ); i++)
+ if ( Vec_IntEntry( s->vLevels, xSAT_Lit2Var( Lits[i]) ) > Max)
+ {
+ Max = Vec_IntEntry( s->vLevels, xSAT_Lit2Var( Lits[i]) );
+ iMax = i;
+ }
+
+ Tmp = Lits[1];
+ Lits[1] = Lits[iMax];
+ Lits[iMax] = Tmp;
+ *OutBtLevel = Vec_IntEntry( s->vLevels, xSAT_Lit2Var( Lits[1] ) );
+ }
+
+ *nLBD = xSAT_SolverClaCalcLBD2( s, vLearnt );
+ if ( Vec_IntSize( s->vLastDLevel ) > 0 )
+ {
+ int Var;
+ Vec_IntForEachEntry( s->vLastDLevel, Var, i )
+ {
+ if ( xSAT_SolverReadClause( s, Vec_IntEntry( s->vReasons, Var ) )->nLBD < *nLBD )
+ xSAT_SolverVarActBump( s, Var );
+ }
+
+ Vec_IntClear( s->vLastDLevel );
+ }
+
+ Vec_IntForEachEntry( s->vTagged, Lit, i )
+ Vec_StrWriteEntry( s->vSeen, xSAT_Lit2Var( Lit ), 0 );
+ Vec_IntClear( s->vTagged );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+unsigned xSAT_SolverPropagate( xSAT_Solver_t* s )
+{
+ unsigned hConfl = CRefUndef;
+ int * Lits;
+ int NegLit;
+ int nProp = 0;
+
+ while ( s->iQhead < Vec_IntSize( s->vTrail ) )
+ {
+ int p = Vec_IntEntry( s->vTrail, s->iQhead++ );
+ xSAT_WatchList_t* ws = xSAT_VecWatchListEntry( s->vBinWatches, p );
+ xSAT_Watcher_t* begin = xSAT_WatchListArray( ws );
+ xSAT_Watcher_t* end = begin + xSAT_WatchListSize( ws );
+ xSAT_Watcher_t *i, *j;
+
+ nProp++;
+ for ( i = begin; i < end; i++ )
+ {
+ if ( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( i->Blocker ) ) == VarX )
+ xSAT_SolverEnqueue( s, i->Blocker, i->CRef );
+ else if ( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( i->Blocker ) ) == xSAT_LitSign( xSAT_NegLit( i->Blocker ) ) )
+ return i->CRef;
+ }
+
+ ws = xSAT_VecWatchListEntry( s->vWatches, p );
+ begin = xSAT_WatchListArray( ws );
+ end = begin + xSAT_WatchListSize( ws );
+
+ for ( i = j = begin; i < end; )
+ {
+ xSAT_Clause_t * pCla;
+ xSAT_Watcher_t w;
+ if ( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( i->Blocker ) ) == xSAT_LitSign( i->Blocker ) )
+ {
+ *j++ = *i++;
+ continue;
+ }
+
+ pCla = xSAT_SolverReadClause( s, i->CRef );
+ Lits = &( pCla->pData[0].Lit );
+
+ // Make sure the false literal is data[1]:
+ NegLit = xSAT_NegLit( p );
+ if ( Lits[0] == NegLit )
+ {
+ Lits[0] = Lits[1];
+ Lits[1] = NegLit;
+ }
+ assert( Lits[1] == NegLit );
+
+ w.CRef = i->CRef;
+ w.Blocker = Lits[0];
+
+ // If 0th watch is true, then clause is already satisfied.
+ if ( Lits[0] != i->Blocker && Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lits[0] ) ) == xSAT_LitSign( Lits[0] ) )
+ *j++ = w;
+ else
+ {
+ // Look for new watch:
+ int * stop = Lits + pCla->nSize;
+ int * k;
+ for ( k = Lits + 2; k < stop; k++ )
+ {
+ if (Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( *k ) ) != !xSAT_LitSign( *k ) )
+ {
+ Lits[1] = *k;
+ *k = NegLit;
+ xSAT_WatchListPush( xSAT_VecWatchListEntry( s->vWatches, xSAT_NegLit( Lits[1] ) ), w );
+ goto next;
+ }
+ }
+
+ *j++ = w;
+
+ // Clause is unit under assignment:
+ if (Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lits[0] ) ) == xSAT_LitSign( xSAT_NegLit( Lits[0] ) ) )
+ {
+ hConfl = i->CRef;
+ i++;
+ s->iQhead = Vec_IntSize( s->vTrail );
+ // Copy the remaining watches:
+ while (i < end)
+ *j++ = *i++;
+ }
+ else
+ xSAT_SolverEnqueue( s, Lits[0], i->CRef );
+ }
+ next:
+ i++;
+ }
+
+ s->Stats.nInspects += j - xSAT_WatchListArray( ws );
+ xSAT_WatchListShrink( ws, j - xSAT_WatchListArray( ws ) );
+ }
+
+ s->Stats.nPropagations += nProp;
+ s->nPropSimplify -= nProp;
+
+ return hConfl;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void xSAT_SolverReduceDB( xSAT_Solver_t * s )
+{
+ static abctime TimeTotal = 0;
+ abctime clk = Abc_Clock();
+ int nLearnedOld = Vec_IntSize( s->vLearnts );
+ int i, limit;
+ unsigned CRef;
+ xSAT_Clause_t * pCla;
+ xSAT_Clause_t ** learnts_cls;
+
+ learnts_cls = ABC_ALLOC( xSAT_Clause_t *, nLearnedOld );
+ Vec_IntForEachEntry( s->vLearnts, CRef, i )
+ learnts_cls[i] = xSAT_SolverReadClause(s, CRef);
+
+ limit = nLearnedOld / 2;
+
+ xSAT_UtilSort((void *) learnts_cls, nLearnedOld,
+ (int (*)( const void *, const void * )) xSAT_ClauseCompare);
+
+ if ( learnts_cls[nLearnedOld / 2]->nLBD <= 3 )
+ s->nRC2 += s->Config.nSpecialIncReduce;
+ if ( learnts_cls[nLearnedOld - 1]->nLBD <= 5 )
+ s->nRC2 += s->Config.nSpecialIncReduce;
+
+ Vec_IntClear( s->vLearnts );
+ for ( i = 0; i < nLearnedOld; i++ )
+ {
+ unsigned CRef;
+
+ pCla = learnts_cls[i];
+ CRef = xSAT_MemCRef( s->pMemory, ( unsigned * ) pCla );
+ assert( pCla->fMark == 0 );
+ if ( pCla->fCanBeDel && pCla->nLBD > 2 && pCla->nSize > 2 && (unsigned) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( pCla->pData[0].Lit ) ) != CRef && ( i < limit ) )
+ {
+ pCla->fMark = 1;
+ s->Stats.nLearntLits -= pCla->nSize;
+ xSAT_WatchListRemove( xSAT_VecWatchListEntry( s->vWatches, xSAT_NegLit( pCla->pData[0].Lit ) ), CRef );
+ xSAT_WatchListRemove( xSAT_VecWatchListEntry( s->vWatches, xSAT_NegLit( pCla->pData[1].Lit ) ), CRef );
+ }
+ else
+ {
+ if ( !pCla->fCanBeDel )
+ limit++;
+ pCla->fCanBeDel = 1;
+ Vec_IntPush( s->vLearnts, CRef );
+ }
+ }
+ ABC_FREE( learnts_cls );
+
+ TimeTotal += Abc_Clock() - clk;
+ if ( s->Config.fVerbose )
+ {
+ Abc_Print(1, "reduceDB: Keeping %7d out of %7d clauses (%5.2f %%) ",
+ Vec_IntSize( s->vLearnts ), nLearnedOld, 100.0 * Vec_IntSize( s->vLearnts ) / nLearnedOld );
+ Abc_PrintTime( 1, "Time", TimeTotal );
+ }
+ xSAT_SolverGarbageCollect(s);
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+char xSAT_SolverSearch( xSAT_Solver_t * s )
+{
+ iword conflictC = 0;
+
+ s->Stats.nStarts++;
+ for (;;)
+ {
+ unsigned hConfl = xSAT_SolverPropagate( s );
+
+ if ( hConfl != CRefUndef )
+ {
+ /* Conflict */
+ int BacktrackLevel;
+ unsigned nLBD;
+ unsigned CRef;
+
+ s->Stats.nConflicts++;
+ conflictC++;
+
+ if ( xSAT_SolverDecisionLevel( s ) == 0 )
+ return LBoolFalse;
+
+ xSAT_BQueuePush( s->bqTrail, Vec_IntSize( s->vTrail ) );
+ if ( s->Stats.nConflicts > s->Config.nFirstBlockRestart && xSAT_BQueueIsValid( s->bqLBD ) && ( Vec_IntSize( s->vTrail ) > ( s->Config.R * ( iword ) xSAT_BQueueAvg( s->bqTrail ) ) ) )
+ xSAT_BQueueClean(s->bqLBD);
+
+ Vec_IntClear( s->vLearntClause );
+ xSAT_SolverAnalyze( s, hConfl, s->vLearntClause, &BacktrackLevel, &nLBD );
+
+ s->nSumLBD += nLBD;
+ xSAT_BQueuePush( s->bqLBD, nLBD );
+ xSAT_SolverCancelUntil( s, BacktrackLevel );
+
+ CRef = Vec_IntSize( s->vLearntClause ) == 1 ? CRefUndef : xSAT_SolverClaNew( s, s->vLearntClause , 1 );
+ xSAT_SolverEnqueue( s, Vec_IntEntry( s->vLearntClause , 0 ), CRef );
+
+ xSAT_SolverVarActDecay( s );
+ xSAT_SolverClaActDecay( s );
+ }
+ else
+ {
+ /* No conflict */
+ int NextVar;
+ if ( xSAT_BQueueIsValid( s->bqLBD ) && ( ( ( iword )xSAT_BQueueAvg( s->bqLBD ) * s->Config.K ) > ( s->nSumLBD / s->Stats.nConflicts ) ) )
+ {
+ xSAT_BQueueClean( s->bqLBD );
+ xSAT_SolverCancelUntil( s, 0 );
+ return LBoolUndef;
+ }
+
+ // Simplify the set of problem clauses:
+ if ( xSAT_SolverDecisionLevel( s ) == 0 )
+ xSAT_SolverSimplify( s );
+
+ // Reduce the set of learnt clauses:
+ if ( s->Stats.nConflicts >= s->nConfBeforeReduce )
+ {
+ s->nRC1 = ( s->Stats.nConflicts / s->nRC2 ) + 1;
+ xSAT_SolverReduceDB(s);
+ s->nRC2 += s->Config.nIncReduce;
+ s->nConfBeforeReduce = s->nRC1 * s->nRC2;
+ }
+
+ // New variable decision:
+ NextVar = xSAT_SolverDecide( s );
+
+ if ( NextVar == VarUndef )
+ return LBoolTrue;
+
+ xSAT_SolverNewDecision( s, xSAT_Var2Lit( NextVar, ( int ) Vec_StrEntry( s->vPolarity, NextVar ) ) );
+ }
+ }
+
+ return LBoolUndef; // cannot happen
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void xSAT_SolverClaRealloc( xSAT_Mem_t * pDest, xSAT_Mem_t * pSrc, unsigned * pCRef )
+{
+ unsigned nNewCRef;
+ xSAT_Clause_t * pNewCla;
+ xSAT_Clause_t * pOldCla = xSAT_MemClauseHand( pSrc, *pCRef );
+
+ if ( pOldCla->fReallocd )
+ {
+ *pCRef = ( unsigned ) pOldCla->nSize;
+ return;
+ }
+ nNewCRef = xSAT_MemAppend( pDest, 3 + pOldCla->fLearnt + pOldCla->nSize );
+ pNewCla = xSAT_MemClauseHand( pDest, nNewCRef );
+ memcpy( pNewCla, pOldCla, ( 3 + pOldCla->fLearnt + pOldCla->nSize ) * 4 );
+ pOldCla->fReallocd = 1;
+ pOldCla->nSize = ( unsigned ) nNewCRef;
+ *pCRef = nNewCRef;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void xSAT_SolverGarbageCollect( xSAT_Solver_t * s )
+{
+ int i;
+ unsigned * pArray;
+ xSAT_Mem_t * pNewMemMngr = xSAT_MemAlloc( xSAT_MemCap( s->pMemory ) - xSAT_MemWastedCap( s->pMemory ) );
+
+ for ( i = 0; i < 2 * Vec_StrSize( s->vAssigns ); i++ )
+ {
+ xSAT_WatchList_t* ws = xSAT_VecWatchListEntry( s->vWatches, i);
+ xSAT_Watcher_t* begin = xSAT_WatchListArray(ws);
+ xSAT_Watcher_t* end = begin + xSAT_WatchListSize(ws);
+ xSAT_Watcher_t *w;
+
+ for ( w = begin; w != end; w++ )
+ xSAT_SolverClaRealloc( pNewMemMngr, s->pMemory, &(w->CRef) );
+
+ ws = xSAT_VecWatchListEntry( s->vBinWatches, i);
+ begin = xSAT_WatchListArray(ws);
+ end = begin + xSAT_WatchListSize(ws);
+ for ( w = begin; w != end; w++ )
+ xSAT_SolverClaRealloc( pNewMemMngr, s->pMemory, &(w->CRef) );
+ }
+
+ for ( i = 0; i < Vec_IntSize( s->vTrail ); i++ )
+ if ( ( unsigned ) Vec_IntEntry( s->vReasons, xSAT_Lit2Var( Vec_IntEntry( s->vTrail, i ) ) ) != CRefUndef )
+ xSAT_SolverClaRealloc( pNewMemMngr, s->pMemory, ( unsigned * ) &( Vec_IntArray( s->vReasons )[xSAT_Lit2Var( Vec_IntEntry( s->vTrail, i ) )] ) );
+
+ pArray = ( unsigned * ) Vec_IntArray( s->vLearnts );
+ for ( i = 0; i < Vec_IntSize( s->vLearnts ); i++ )
+ xSAT_SolverClaRealloc( pNewMemMngr, s->pMemory, &(pArray[i]) );
+
+ pArray = ( unsigned * ) Vec_IntArray( s->vClauses );
+ for ( i = 0; i < Vec_IntSize( s->vClauses ); i++ )
+ xSAT_SolverClaRealloc( pNewMemMngr, s->pMemory, &(pArray[i]) );
+
+ xSAT_MemFree( s->pMemory );
+ s->pMemory = pNewMemMngr;
+}
+
+ABC_NAMESPACE_IMPL_END
diff --git a/src/sat/xsat/xsatSolver.h b/src/sat/xsat/xsatSolver.h
new file mode 100644
index 00000000..36432e03
--- /dev/null
+++ b/src/sat/xsat/xsatSolver.h
@@ -0,0 +1,248 @@
+/**CFile****************************************************************
+
+ FileName [xsatSolver.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [xSAT - A SAT solver written in C.
+ Read the license file for more info.]
+
+ Synopsis [Internal definitions of the solver.]
+
+ Author [Bruno Schmitt <boschmitt@inf.ufrgs.br>]
+
+ Affiliation [UC Berkeley / UFRGS]
+
+ Date [Ver. 1.0. Started - November 10, 2016.]
+
+ Revision []
+
+***********************************************************************/
+#ifndef ABC__sat__xSAT__xsatSolver_h
+#define ABC__sat__xSAT__xsatSolver_h
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "misc/util/abc_global.h"
+#include "misc/vec/vecStr.h"
+
+#include "xsat.h"
+#include "xsatBQueue.h"
+#include "xsatClause.h"
+#include "xsatHeap.h"
+#include "xsatMemory.h"
+#include "xsatWatchList.h"
+
+ABC_NAMESPACE_HEADER_START
+
+#ifndef __cplusplus
+#ifndef false
+# define false 0
+#endif
+#ifndef true
+# define true 1
+#endif
+#endif
+
+enum
+{
+ Var0 = 1,
+ Var1 = 0,
+ VarX = 3
+};
+
+enum
+{
+ LBoolUndef = 0,
+ LBoolTrue = 1,
+ LBoolFalse = -1
+};
+
+enum
+{
+ VarUndef = -1,
+ LitUndef = -2
+};
+
+#define CRefUndef 0xFFFFFFFF
+
+////////////////////////////////////////////////////////////////////////
+/// STRUCTURE DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+typedef struct xSAT_SolverOptions_t_ xSAT_SolverOptions_t;
+struct xSAT_SolverOptions_t_
+{
+ char fVerbose;
+
+ // Limits
+ iword nConfLimit; // external limit on the number of conflicts
+ iword nInsLimit; // external limit on the number of implications
+ abctime nRuntimeLimit; // external limit on runtime
+
+ // Constants used for restart heuristic
+ double K; // Forces a restart
+ double R; // Block a restart
+ int nFirstBlockRestart; // Lower bound number of conflicts for start blocking restarts
+ int nSizeLBDQueue; // Size of the moving avarege queue for LBD (force restart)
+ int nSizeTrailQueue; // Size of the moving avarege queue for Trail size (block restart)
+
+ // Constants used for clause database reduction heuristic
+ int nConfFirstReduce; // Number of conflicts before first reduction
+ int nIncReduce; // Increment to reduce
+ int nSpecialIncReduce; // Special increment to reduce
+ unsigned nLBDFrozenClause;
+};
+
+typedef struct xSAT_Stats_t_ xSAT_Stats_t;
+struct xSAT_Stats_t_
+{
+ unsigned nStarts;
+ unsigned nReduceDB;
+
+ iword nDecisions;
+ iword nPropagations;
+ iword nInspects;
+ iword nConflicts;
+
+ iword nClauseLits;
+ iword nLearntLits;
+};
+
+struct xSAT_Solver_t_
+{
+ /* Clauses Database */
+ xSAT_Mem_t * pMemory;
+ Vec_Int_t * vLearnts;
+ Vec_Int_t * vClauses;
+ xSAT_VecWatchList_t * vWatches;
+ xSAT_VecWatchList_t * vBinWatches;
+
+ /* Activity heuristic */
+ int nVarActInc; /* Amount to bump next variable with. */
+ int nClaActInc; /* Amount to bump next clause with. */
+
+ /* Variable Information */
+ Vec_Int_t * vActivity; /* A heuristic measurement of the activity of a variable. */
+ xSAT_Heap_t * hOrder;
+ Vec_Int_t * vLevels; /* Decision level of the current assignment */
+ Vec_Int_t * vReasons; /* Reason (clause) of the current assignment */
+ Vec_Str_t * vAssigns; /* Current assignment. */
+ Vec_Str_t * vPolarity;
+ Vec_Str_t * vTags;
+
+ /* Assignments */
+ Vec_Int_t * vTrail;
+ Vec_Int_t * vTrailLim; // Separator indices for different decision levels in 'trail'.
+ int iQhead; // Head of propagation queue (as index into the trail).
+
+ int nAssignSimplify; /* Number of top-level assignments since last
+ * execution of 'simplify()'. */
+ iword nPropSimplify; /* Remaining number of propagations that must be
+ * made before next execution of 'simplify()'. */
+
+ /* Temporary data used by Search method */
+ xSAT_BQueue_t * bqTrail;
+ xSAT_BQueue_t * bqLBD;
+ float nSumLBD;
+ int nConfBeforeReduce;
+ long nRC1;
+ int nRC2;
+
+ /* Temporary data used by Analyze */
+ Vec_Int_t * vLearntClause;
+ Vec_Str_t * vSeen;
+ Vec_Int_t * vTagged;
+ Vec_Int_t * vStack;
+ Vec_Int_t * vLastDLevel;
+
+ /* Misc temporary */
+ unsigned nStamp;
+ Vec_Int_t * vStamp; /* Multipurpose stamp used to calculate LBD and
+ * clauses minimization with binary resolution */
+
+ xSAT_SolverOptions_t Config;
+ xSAT_Stats_t Stats;
+};
+
+static inline int xSAT_Var2Lit( int Var, int c )
+{
+ return Var + Var + ( c != 0 );
+}
+
+static inline int xSAT_NegLit( int Lit )
+{
+ return Lit ^ 1;
+}
+
+static inline int xSAT_Lit2Var( int Lit )
+{
+ return Lit >> 1;
+}
+
+static inline int xSAT_LitSign( int Lit )
+{
+ return Lit & 1;
+}
+
+static inline int xSAT_SolverDecisionLevel( xSAT_Solver_t * s )
+{
+ return Vec_IntSize( s->vTrailLim );
+}
+
+static inline xSAT_Clause_t * xSAT_SolverReadClause( xSAT_Solver_t * s, unsigned h )
+{
+ return xSAT_MemClauseHand( s->pMemory, h );
+}
+
+static inline int xSAT_SolverIsClauseSatisfied( xSAT_Solver_t * s, xSAT_Clause_t * pCla )
+{
+ int i;
+ int * Lits = &( pCla->pData[0].Lit );
+
+ for ( i = 0; i < pCla->nSize; i++ )
+ if ( Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lits[i] ) ) == xSAT_LitSign( ( Lits[i] ) ) )
+ return true;
+
+ return false;
+}
+
+static inline void xSAT_SolverPrintClauses( xSAT_Solver_t * s )
+{
+ int i;
+ unsigned CRef;
+
+ Vec_IntForEachEntry( s->vClauses, CRef, i )
+ xSAT_ClausePrint( xSAT_SolverReadClause( s, CRef ) );
+}
+
+static inline void xSAT_SolverPrintState( xSAT_Solver_t * s )
+{
+ printf( "starts : %10d\n", s->Stats.nStarts );
+ printf( "conflicts : %10ld\n", s->Stats.nConflicts );
+ printf( "decisions : %10ld\n", s->Stats.nDecisions );
+ printf( "propagations : %10ld\n", s->Stats.nPropagations );
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+extern unsigned xSAT_SolverClaNew( xSAT_Solver_t* s, Vec_Int_t * vLits, int fLearnt );
+extern char xSAT_SolverSearch( xSAT_Solver_t * s );
+
+extern void xSAT_SolverGarbageCollect( xSAT_Solver_t * s );
+
+extern int xSAT_SolverEnqueue( xSAT_Solver_t* s, int Lit, unsigned From );
+extern void xSAT_SolverCancelUntil( xSAT_Solver_t* s, int Level);
+extern unsigned xSAT_SolverPropagate( xSAT_Solver_t* s );
+extern void xSAT_SolverRebuildOrderHeap( xSAT_Solver_t* s );
+
+ABC_NAMESPACE_HEADER_END
+
+#endif
diff --git a/src/sat/xsat/xsatSolverAPI.c b/src/sat/xsat/xsatSolverAPI.c
new file mode 100644
index 00000000..7746dc0b
--- /dev/null
+++ b/src/sat/xsat/xsatSolverAPI.c
@@ -0,0 +1,346 @@
+/**CFile****************************************************************
+
+ FileName [xsatSolverAPI.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [xSAT - A SAT solver written in C.
+ Read the license file for more info.]
+
+ Synopsis [Solver external API functions implementation.]
+
+ Author [Bruno Schmitt <boschmitt@inf.ufrgs.br>]
+
+ Affiliation [UC Berkeley / UFRGS]
+
+ Date [Ver. 1.0. Started - November 10, 2016.]
+
+ Revision []
+
+***********************************************************************/
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+#include <math.h>
+
+#include "xsatSolver.h"
+
+ABC_NAMESPACE_IMPL_START
+
+xSAT_SolverOptions_t DefaultConfig =
+{
+ 1, //.fVerbose = 1,
+
+ 0, //.nConfLimit = 0,
+ 0, //.nInsLimit = 0,
+ 0, //.nRuntimeLimit = 0,
+
+ 0.8, //.K = 0.8,
+ 1.4, //.R = 1.4,
+ 10000, //.nFirstBlockRestart = 10000,
+ 50, //.nSizeLBDQueue = 50,
+ 5000, //.nSizeTrailQueue = 5000,
+
+ 2000, //.nConfFirstReduce = 2000,
+ 300, //.nIncReduce = 300,
+ 1000, //.nSpecialIncReduce = 1000,
+
+ 30 //.nLBDFrozenClause = 30
+};
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+xSAT_Solver_t* xSAT_SolverCreate()
+{
+ xSAT_Solver_t * s = (xSAT_Solver_t *) ABC_CALLOC( char, sizeof( xSAT_Solver_t ) );
+ s->Config = DefaultConfig;
+
+ s->pMemory = xSAT_MemAlloc(0);
+ s->vClauses = Vec_IntAlloc(0);
+ s->vLearnts = Vec_IntAlloc(0);
+ s->vWatches = xSAT_VecWatchListAlloc( 0 );
+ s->vBinWatches = xSAT_VecWatchListAlloc( 0 );
+
+ s->vTrailLim = Vec_IntAlloc(0);
+ s->vTrail = Vec_IntAlloc( 0 );
+
+ s->vActivity = Vec_IntAlloc( 0 );
+ s->hOrder = xSAT_HeapAlloc( s->vActivity );
+
+ s->vPolarity = Vec_StrAlloc( 0 );
+ s->vTags = Vec_StrAlloc( 0 );
+ s->vAssigns = Vec_StrAlloc( 0 );
+ s->vLevels = Vec_IntAlloc( 0 );
+ s->vReasons = Vec_IntAlloc( 0 );
+ s->vStamp = Vec_IntAlloc( 0 );
+
+ s->vTagged = Vec_IntAlloc(0);
+ s->vStack = Vec_IntAlloc(0);
+
+ s->vSeen = Vec_StrAlloc( 0 );
+ s->vLearntClause = Vec_IntAlloc(0);
+ s->vLastDLevel = Vec_IntAlloc(0);
+
+
+ s->bqTrail = xSAT_BQueueNew( s->Config.nSizeTrailQueue );
+ s->bqLBD = xSAT_BQueueNew( s->Config.nSizeLBDQueue );
+
+ s->nVarActInc = (1 << 5);
+ s->nClaActInc = (1 << 11);
+
+ s->nConfBeforeReduce = s->Config.nConfFirstReduce;
+ s->nRC1 = 1;
+ s->nRC2 = s->Config.nConfFirstReduce;
+ return s;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void xSAT_SolverDestroy( xSAT_Solver_t * s )
+{
+ xSAT_MemFree( s->pMemory );
+ Vec_IntFree( s->vClauses );
+ Vec_IntFree( s->vLearnts );
+ xSAT_VecWatchListFree( s->vWatches );
+ xSAT_VecWatchListFree( s->vBinWatches );
+
+ xSAT_HeapFree(s->hOrder);
+ Vec_IntFree( s->vTrailLim );
+ Vec_IntFree( s->vTrail );
+ Vec_IntFree( s->vTagged );
+ Vec_IntFree( s->vStack );
+
+ Vec_StrFree( s->vSeen );
+ Vec_IntFree( s->vLearntClause );
+ Vec_IntFree( s->vLastDLevel );
+
+ Vec_IntFree( s->vActivity );
+ Vec_StrFree( s->vPolarity );
+ Vec_StrFree( s->vTags );
+ Vec_StrFree( s->vAssigns );
+ Vec_IntFree( s->vLevels );
+ Vec_IntFree( s->vReasons );
+ Vec_IntFree( s->vStamp );
+
+ xSAT_BQueueFree(s->bqLBD);
+ xSAT_BQueueFree(s->bqTrail);
+
+ ABC_FREE(s);
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int xSAT_SolverSimplify( xSAT_Solver_t * s )
+{
+ int i, j;
+ unsigned CRef;
+ assert( xSAT_SolverDecisionLevel(s) == 0 );
+
+ if ( xSAT_SolverPropagate(s) != CRefUndef )
+ return false;
+
+ if ( s->nAssignSimplify == Vec_IntSize( s->vTrail ) || s->nPropSimplify > 0 )
+ return true;
+
+ j = 0;
+ Vec_IntForEachEntry( s->vClauses, CRef, i )
+ {
+ xSAT_Clause_t * pCla = xSAT_SolverReadClause( s, CRef );
+ if ( xSAT_SolverIsClauseSatisfied( s, pCla ) )
+ {
+ pCla->fMark = 1;
+ s->Stats.nClauseLits -= pCla->nSize;
+
+ if ( pCla->nSize == 2 )
+ {
+ xSAT_WatchListRemove( xSAT_VecWatchListEntry( s->vBinWatches, xSAT_NegLit(pCla->pData[0].Lit) ), CRef );
+ xSAT_WatchListRemove( xSAT_VecWatchListEntry( s->vBinWatches, xSAT_NegLit(pCla->pData[1].Lit) ), CRef );
+ }
+ else
+ {
+ xSAT_WatchListRemove( xSAT_VecWatchListEntry( s->vWatches, xSAT_NegLit(pCla->pData[0].Lit) ), CRef );
+ xSAT_WatchListRemove( xSAT_VecWatchListEntry( s->vWatches, xSAT_NegLit(pCla->pData[1].Lit) ), CRef );
+ }
+ }
+ else
+ Vec_IntWriteEntry( s->vClauses, j++, CRef );
+ }
+ Vec_IntShrink( s->vClauses, j );
+ xSAT_SolverRebuildOrderHeap( s );
+
+ s->nAssignSimplify = Vec_IntSize( s->vTrail );
+ s->nPropSimplify = s->Stats.nClauseLits + s->Stats.nLearntLits;
+
+ return true;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void xSAT_SolverAddVariable( xSAT_Solver_t* s, int Sign )
+{
+ int Var = Vec_IntSize( s->vActivity );
+
+ xSAT_VecWatchListPush( s->vWatches );
+ xSAT_VecWatchListPush( s->vWatches );
+ xSAT_VecWatchListPush( s->vBinWatches );
+ xSAT_VecWatchListPush( s->vBinWatches );
+
+ Vec_IntPush( s->vActivity, 0 );
+ Vec_IntPush( s->vLevels, 0 );
+ Vec_StrPush( s->vAssigns, VarX );
+ Vec_StrPush( s->vPolarity, 1 );
+ Vec_StrPush( s->vTags, 0 );
+ Vec_IntPush( s->vReasons, ( int ) CRefUndef );
+ Vec_IntPush( s->vStamp, 0 );
+ Vec_StrPush( s->vSeen, 0 );
+
+ xSAT_HeapInsert( s->hOrder, Var );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int xSAT_SolverAddClause( xSAT_Solver_t * s, Vec_Int_t * vLits )
+{
+ int i, j;
+ int Lit, PrevLit;
+ int MaxVar;
+
+ Vec_IntSort( vLits, 0 );
+ MaxVar = xSAT_Lit2Var( Vec_IntEntryLast( vLits ) );
+ while ( MaxVar >= Vec_IntSize( s->vActivity ) )
+ xSAT_SolverAddVariable( s, 1 );
+
+ j = 0;
+ PrevLit = LitUndef;
+ Vec_IntForEachEntry( vLits, Lit, i )
+ {
+ if ( Lit == xSAT_NegLit( PrevLit ) || Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lit ) ) == xSAT_LitSign( Lit ) )
+ return true;
+ else if ( Lit != PrevLit && Vec_StrEntry( s->vAssigns, xSAT_Lit2Var( Lit ) ) == VarX )
+ {
+ PrevLit = Lit;
+ Vec_IntWriteEntry( vLits, j++, Lit );
+ }
+ }
+ Vec_IntShrink( vLits, j );
+
+ if ( Vec_IntSize( vLits ) == 0 )
+ return false;
+ if ( Vec_IntSize( vLits ) == 1 )
+ {
+ xSAT_SolverEnqueue( s, Vec_IntEntry( vLits, 0 ), CRefUndef );
+ return ( xSAT_SolverPropagate( s ) == CRefUndef );
+ }
+
+ xSAT_SolverClaNew( s, vLits, 0 );
+ return true;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int xSAT_SolverSolve( xSAT_Solver_t* s )
+{
+ char status = LBoolUndef;
+
+ assert(s);
+ if ( s->Config.fVerbose )
+ {
+ printf( "==========================================[ BLACK MAGIC ]================================================\n" );
+ printf( "| | | |\n" );
+ printf( "| - Restarts: | - Reduce Clause DB: | - Minimize Asserting: |\n" );
+ printf( "| * LBD Queue : %6d | * First : %6d | * size < %3d |\n", s->Config.nSizeLBDQueue, s->Config.nConfFirstReduce, 0 );
+ printf( "| * Trail Queue : %6d | * Inc : %6d | * lbd < %3d |\n", s->Config.nSizeTrailQueue, s->Config.nIncReduce, 0 );
+ printf( "| * K : %6.2f | * Special : %6d | |\n", s->Config.K, s->Config.nSpecialIncReduce );
+ printf( "| * R : %6.2f | * Protected : (lbd)< %2d | |\n", s->Config.R, s->Config.nLBDFrozenClause );
+ printf( "| | | |\n" );
+ printf( "=========================================================================================================\n" );
+ }
+
+ while ( status == LBoolUndef )
+ status = xSAT_SolverSearch( s );
+
+ if ( s->Config.fVerbose )
+ printf( "=========================================================================================================\n" );
+
+ xSAT_SolverCancelUntil( s, 0 );
+ return status;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void xSAT_SolverPrintStats( xSAT_Solver_t * s )
+{
+ printf( "starts : %10d\n", s->Stats.nStarts );
+ printf( "conflicts : %10ld\n", s->Stats.nConflicts );
+ printf( "decisions : %10ld\n", s->Stats.nDecisions );
+ printf( "propagations : %10ld\n", s->Stats.nPropagations );
+}
+
+ABC_NAMESPACE_IMPL_END
diff --git a/src/sat/xsat/xsatUtils.h b/src/sat/xsat/xsatUtils.h
new file mode 100644
index 00000000..7f774d85
--- /dev/null
+++ b/src/sat/xsat/xsatUtils.h
@@ -0,0 +1,106 @@
+/**CFile****************************************************************
+
+ FileName [xsatUtils.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [xSAT - A SAT solver written in C.
+ Read the license file for more info.]
+
+ Synopsis [Utility functions used in xSAT]
+
+ Author [Bruno Schmitt <boschmitt@inf.ufrgs.br>]
+
+ Affiliation [UC Berkeley / UFRGS]
+
+ Date [Ver. 1.0. Started - November 10, 2016.]
+
+ Revision []
+
+***********************************************************************/
+#ifndef ABC__sat__xSAT__xsatUtils_h
+#define ABC__sat__xSAT__xsatUtils_h
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+#include "misc/util/abc_global.h"
+
+ABC_NAMESPACE_HEADER_START
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_UtilSelectSort( void** pArray, int nSize, int(* CompFnct )( const void *, const void * ) )
+{
+ int i, j, iBest;
+ void* pTmp;
+
+ for ( i = 0; i < ( nSize - 1 ); i++ )
+ {
+ iBest = i;
+ for ( j = i + 1; j < nSize; j++ )
+ {
+ if ( CompFnct( pArray[j], pArray[iBest] ) )
+ iBest = j;
+ }
+ pTmp = pArray[i];
+ pArray[i] = pArray[iBest];
+ pArray[iBest] = pTmp;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static void xSAT_UtilSort( void** pArray, int nSize, int(* CompFnct )( const void *, const void *) )
+{
+ if ( nSize <= 15 )
+ xSAT_UtilSelectSort( pArray, nSize, CompFnct );
+ else
+ {
+ void* pPivot = pArray[nSize / 2];
+ void* pTmp;
+ int i = -1;
+ int j = nSize;
+
+ for(;;)
+ {
+ do i++; while( CompFnct( pArray[i], pPivot ) );
+ do j--; while( CompFnct( pPivot, pArray[j] ) );
+
+ if ( i >= j )
+ break;
+
+ pTmp = pArray[i];
+ pArray[i] = pArray[j];
+ pArray[j] = pTmp;
+ }
+
+ xSAT_UtilSort( pArray, i, CompFnct );
+ xSAT_UtilSort( pArray + i, ( nSize - i ), CompFnct );
+ }
+}
+
+ABC_NAMESPACE_HEADER_END
+
+#endif
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
diff --git a/src/sat/xsat/xsatWatchList.h b/src/sat/xsat/xsatWatchList.h
new file mode 100644
index 00000000..284be100
--- /dev/null
+++ b/src/sat/xsat/xsatWatchList.h
@@ -0,0 +1,269 @@
+/**CFile****************************************************************
+
+ FileName [xsatWatchList.h]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [xSAT - A SAT solver written in C.
+ Read the license file for more info.]
+
+ Synopsis [Watch list and its related structures implementation]
+
+ Author [Bruno Schmitt <boschmitt@inf.ufrgs.br>]
+
+ Affiliation [UC Berkeley / UFRGS]
+
+ Date [Ver. 1.0. Started - November 10, 2016.]
+
+ Revision []
+
+***********************************************************************/
+#ifndef ABC__sat__xSAT__xsatWatchList_h
+#define ABC__sat__xSAT__xsatWatchList_h
+
+////////////////////////////////////////////////////////////////////////
+/// INCLUDES ///
+////////////////////////////////////////////////////////////////////////
+#include "misc/util/abc_global.h"
+
+ABC_NAMESPACE_HEADER_START
+
+////////////////////////////////////////////////////////////////////////
+/// STRUCTURE DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+typedef struct xSAT_Watcher_t_ xSAT_Watcher_t;
+struct xSAT_Watcher_t_
+{
+ unsigned CRef;
+ int Blocker;
+};
+
+typedef struct xSAT_WatchList_t_ xSAT_WatchList_t;
+struct xSAT_WatchList_t_
+{
+ int nCap;
+ int nSize;
+ xSAT_Watcher_t * pArray;
+};
+
+typedef struct xSAT_VecWatchList_t_ xSAT_VecWatchList_t;
+struct xSAT_VecWatchList_t_
+{
+ int nCap;
+ int nSize;
+ xSAT_WatchList_t * pArray;
+};
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_WatchListFree( xSAT_WatchList_t * v )
+{
+ if ( v->pArray )
+ ABC_FREE( v->pArray );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline int xSAT_WatchListSize( xSAT_WatchList_t * v )
+{
+ return v->nSize;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_WatchListShrink( xSAT_WatchList_t * v, int k )
+{
+ assert(k <= v->nSize);
+ v->nSize = k;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_WatchListPush( xSAT_WatchList_t * v, xSAT_Watcher_t e )
+{
+ assert( v );
+ if ( v->nSize == v->nCap )
+ {
+ int newsize = ( v->nCap < 4 ) ? 4 : ( v->nCap / 2 ) * 3;
+
+ v->pArray = ABC_REALLOC( xSAT_Watcher_t, v->pArray, newsize );
+ if ( v->pArray == NULL )
+ {
+ printf( "Failed to realloc memory from %.1f MB to %.1f MB.\n",
+ 1.0 * v->nCap / (1<<20), 1.0 * newsize / (1<<20) );
+ fflush( stdout );
+ }
+ v->nCap = newsize;
+ }
+
+ v->pArray[v->nSize++] = e;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline xSAT_Watcher_t* xSAT_WatchListArray( xSAT_WatchList_t * v )
+{
+ return v->pArray;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_WatchListRemove( xSAT_WatchList_t * v, unsigned CRef )
+{
+ xSAT_Watcher_t* ws = xSAT_WatchListArray(v);
+ int j = 0;
+
+ for ( ; ws[j].CRef != CRef; j++ );
+ assert( j < xSAT_WatchListSize( v ) );
+ memmove( v->pArray + j, v->pArray + j + 1, ( v->nSize - j - 1 ) * sizeof( xSAT_Watcher_t ) );
+ v->nSize -= 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline xSAT_VecWatchList_t * xSAT_VecWatchListAlloc( int nCap )
+{
+ xSAT_VecWatchList_t * v = ABC_ALLOC( xSAT_VecWatchList_t, 1 );
+
+ v->nCap = 4;
+ v->nSize = 0;
+ v->pArray = ( xSAT_WatchList_t * ) ABC_CALLOC(xSAT_WatchList_t, sizeof( xSAT_WatchList_t ) * v->nCap);
+ return v;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_VecWatchListFree( xSAT_VecWatchList_t* v )
+{
+ int i;
+ for( i = 0; i < v->nSize; i++ )
+ xSAT_WatchListFree( v->pArray + i );
+
+ ABC_FREE( v->pArray );
+ ABC_FREE( v );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline void xSAT_VecWatchListPush( xSAT_VecWatchList_t* v )
+{
+ if ( v->nSize == v->nCap )
+ {
+ int newsize = (v->nCap < 4) ? v->nCap * 2 : (v->nCap / 2) * 3;
+
+ v->pArray = ABC_REALLOC( xSAT_WatchList_t, v->pArray, newsize );
+ memset( v->pArray + v->nCap, 0, sizeof( xSAT_WatchList_t ) * ( newsize - v->nCap ) );
+ if ( v->pArray == NULL )
+ {
+ printf( "Failed to realloc memory from %.1f MB to %.1f MB.\n",
+ 1.0 * v->nCap / (1<<20), 1.0 * newsize / (1<<20) );
+ fflush( stdout );
+ }
+ v->nCap = newsize;
+ }
+
+ v->nSize++;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline xSAT_WatchList_t * xSAT_VecWatchListEntry( xSAT_VecWatchList_t* v, int iEntry )
+{
+ assert( iEntry < v->nCap );
+ assert( iEntry < v->nSize );
+ return v->pArray + iEntry;
+}
+
+ABC_NAMESPACE_HEADER_END
+
+#endif