[berkeley-abc] 01/01: Imported upstream version 1.01+20141105hg5b5af75+dfsg

Ruben Undheim rubund-guest at moszumanska.debian.org
Sat Nov 8 22:21:38 UTC 2014


This is an automated email from the git hooks/post-receive script.

rubund-guest pushed a commit to tag upstream/1.01+20141105hg5b5af75+dfsg
in repository berkeley-abc.

commit cf3fb82558ee01b0667addb91eb3234f9244739d
Author: Ruben Undheim <ruben.undheim at gmail.com>
Date:   Sat Nov 8 23:19:34 2014 +0100

    Imported upstream version 1.01+20141105hg5b5af75+dfsg
---
 Makefile                             |  15 +-
 abcexe.dsp                           |   8 +-
 abclib.dsp                           |  36 +-
 src/aig/gia/gia.h                    |  24 +-
 src/aig/gia/giaEnable.c              |   4 +-
 src/aig/gia/giaEquiv.c               |   4 +-
 src/aig/gia/giaHash.c                |  19 +
 src/aig/gia/giaQbf.c                 | 492 +++++++++++++++++++
 src/aig/gia/giaSim.c                 |  32 +-
 src/aig/gia/module.make              |   1 +
 src/aig/ivy/ivyRwr.c                 |   2 +-
 src/aig/ivy/ivySeq.c                 |   2 +-
 src/aig/saig/saigDup.c               |  64 +++
 src/base/abci/abc.c                  | 542 ++++++++++++++++++--
 src/base/abci/abcDar.c               |   2 +-
 src/base/abci/abcRec3.c              |   2 +-
 src/base/abci/module.make            |   8 +-
 src/base/cmd/cmdUtils.c              |  22 +-
 src/base/main/main.c                 | 390 +--------------
 src/base/main/mainFrame.c            |   1 +
 src/base/main/mainInit.c             |  43 +-
 src/base/main/mainInt.h              |  17 +-
 src/base/main/{main.c => mainReal.c} |  15 -
 src/base/main/module.make            |   1 +
 src/bdd/mtr/mtr.h                    |  12 +-
 src/bool/lucky/luckySimple.c         |   6 +-
 src/bool/rpo/rpo.c                   |   2 +-
 src/bool/rpo/rpo.h                   |   1 +
 src/map/if/ifTruth.c                 |  20 +-
 src/misc/extra/extra.h               |   2 +
 src/misc/extra/extraUtilFile.c       |  36 +-
 src/misc/extra/extraUtilSupp.c       |   2 +-
 src/misc/vec/vecInt.h                |   6 +
 src/misc/vec/vecPtr.h                |   2 +-
 src/misc/vec/vecStr.h                |   6 +
 src/opt/rwr/rwrEva.c                 |   2 +-
 src/proof/cec/cecCorr.c              |   8 +-
 src/python/pyabc.i                   |  10 +-
 src/sat/bmc/bmc.h                    |   1 +
 src/sat/bmc/bmcBmc3.c                |   2 +-
 src/sat/bmc/bmcCexTools.c            |   2 +-
 src/sat/bmc/bmcChain.c               | 363 ++++++++++++++
 src/sat/bmc/bmcFault.c               | 324 ++++++++----
 src/sat/bmc/module.make              |   1 +
 src/sat/bsat/satSolver.h             |   4 +-
 src/sat/bsat2/AbcApi.cpp             |  59 +++
 src/sat/bsat2/Alg.h                  |  84 ++++
 src/sat/bsat2/Alloc.h                | 131 +++++
 src/sat/bsat2/Dimacs.h               |  89 ++++
 src/sat/bsat2/Heap.h                 | 149 ++++++
 src/sat/bsat2/IntTypes.h             |  47 ++
 src/sat/bsat2/LICENSE                |  21 +
 src/sat/bsat2/MainSat.cpp            | 197 ++++++++
 src/sat/bsat2/MainSimp.cpp           | 206 ++++++++
 src/sat/bsat2/Map.h                  | 193 ++++++++
 src/sat/bsat2/Options.cpp            |  93 ++++
 src/sat/bsat2/Options.h              | 387 +++++++++++++++
 src/sat/bsat2/ParseUtils.h           | 122 +++++
 src/sat/bsat2/Queue.h                |  69 +++
 src/sat/bsat2/README                 |  24 +
 src/sat/bsat2/ReleaseNotes-2.2.0.txt |  79 +++
 src/sat/bsat2/SimpSolver.cpp         | 720 +++++++++++++++++++++++++++
 src/sat/bsat2/SimpSolver.h           | 197 ++++++++
 src/sat/bsat2/Solver.cpp             | 924 +++++++++++++++++++++++++++++++++++
 src/sat/bsat2/Solver.h               | 373 ++++++++++++++
 src/sat/bsat2/SolverTypes.h          | 407 +++++++++++++++
 src/sat/bsat2/Sort.h                 |  98 ++++
 src/sat/bsat2/System.cpp             |  95 ++++
 src/sat/bsat2/System.h               |  60 +++
 src/sat/bsat2/Vec.h                  | 130 +++++
 src/sat/bsat2/XAlloc.h               |  45 ++
 src/sat/bsat2/module.make            |   7 +
 src/sat/bsat2/pstdint.h              | 813 ++++++++++++++++++++++++++++++
 73 files changed, 7740 insertions(+), 637 deletions(-)

diff --git a/Makefile b/Makefile
index 11ac44b..7fe5167 100644
--- a/Makefile
+++ b/Makefile
@@ -12,7 +12,7 @@ $(info $(MSG_PREFIX)Using LD=$(LD))
 PROG := abc
 
 MODULES := \
-	$(wildcard src/ext) src/misc/ext \
+	$(wildcard src/ext*) \
 	src/base/abc src/base/abci src/base/cmd src/base/io \
 	src/base/main src/base/ver src/base/wlc src/base/test \
 	src/bdd/cudd src/bdd/dsd src/bdd/epd src/bdd/mtr src/bdd/parse \
@@ -67,7 +67,7 @@ endif
 endif
 
 # LIBS := -ldl -lrt
-LIBS := -ldl
+LIBS += -ldl
 ifneq ($(findstring Darwin, $(shell uname)), Darwin)
    LIBS += -lrt
 endif
@@ -94,6 +94,7 @@ include $(patsubst %, %/module.make, $(MODULES))
 
 OBJ := \
 	$(patsubst %.cc, %.o, $(filter %.cc, $(SRC))) \
+	$(patsubst %.cpp, %.o, $(filter %.cpp, $(SRC))) \
 	$(patsubst %.c, %.o,  $(filter %.c, $(SRC)))  \
 	$(patsubst %.y, %.o,  $(filter %.y, $(SRC))) 
 
@@ -109,14 +110,22 @@ DEP := $(OBJ:.o=.d)
 	@echo "$(MSG_PREFIX)\`\` Compiling:" $(LOCAL_PATH)/$<
 	@$(CXX) -c $(CXXFLAGS) $< -o $@
 
+%.o: %.cpp
+	@echo "$(MSG_PREFIX)\`\` Compiling:" $(LOCAL_PATH)/$<
+	@$(CXX) -c $(CXXFLAGS) $< -o $@
+
 %.d: %.c
-	@echo "$(MSG_PREFIX)\`\` Dependency:" $(LOCAL_PATH)/$<
+	@echo "$(MSG_PREFIX)\`\` Generating dependency:" $(LOCAL_PATH)/$<
 	@./depends.sh $(CC) `dirname $*.c` $(CFLAGS) $*.c > $@
 
 %.d: %.cc
 	@echo "$(MSG_PREFIX)\`\` Generating dependency:" $(LOCAL_PATH)/$<
 	@./depends.sh $(CXX) `dirname $*.cc` $(CXXFLAGS) $*.cc > $@
 
+%.d: %.cpp
+	@echo "$(MSG_PREFIX)\`\` Generating dependency:" $(LOCAL_PATH)/$<
+	@./depends.sh $(CXX) `dirname $*.cpp` $(CXXFLAGS) $*.cpp > $@
+
 -include $(DEP)
 
 # Actual targets
diff --git a/abcexe.dsp b/abcexe.dsp
index ae8bbe0..6b223f1 100644
--- a/abcexe.dsp
+++ b/abcexe.dsp
@@ -42,7 +42,7 @@ RSC=rc.exe
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "src" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D ABC_DLL=ABC_DLLEXPORT /D "_CRT_SECURE_NO_DEPRECATE" /D "ABC_USE_PTHREADS" /FR /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "src" /D "WIN32" /D "WINDOWS" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D ABC_DLL=ABC_DLLEXPORT /D "_CRT_SECURE_NO_DEPRECATE" /D "ABC_USE_PTHREADS" /FR /YX /FD /c
 # ADD BASE RSC /l 0x409 /d "NDEBUG"
 # ADD RSC /l 0x409 /d "NDEBUG"
 BSC32=bscmake.exe
@@ -50,7 +50,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LINK32=link.exe
 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib lib\abcr.lib lib\x86\pthreadVC2.lib /nologo /subsystem:console /incremental:yes /debug /machine:I386 /out:"_TEST/abc.exe"
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib lib\x86\pthreadVC2.lib /nologo /subsystem:console /incremental:yes /debug /machine:I386 /out:"_TEST/abc.exe"
 # SUBTRACT LINK32 /profile
 
 !ELSEIF  "$(CFG)" == "abcexe - Win32 Debug"
@@ -67,7 +67,7 @@ LINK32=link.exe
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "src" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D ABC_DLL=ABC_DLLEXPORT /D "_CRT_SECURE_NO_DEPRECATE" /D "ABC_USE_PTHREADS" /FR /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "src" /D "WIN32" /D "WINDOWS" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D ABC_DLL=ABC_DLLEXPORT /D "_CRT_SECURE_NO_DEPRECATE" /D "ABC_USE_PTHREADS" /FR /YX /FD /GZ /c
 # ADD BASE RSC /l 0x409 /d "_DEBUG"
 # ADD RSC /l 0x409 /d "_DEBUG"
 BSC32=bscmake.exe
@@ -75,7 +75,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LINK32=link.exe
 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib lib\abcd.lib lib\x86\pthreadVC2.lib /nologo /subsystem:console /debug /machine:I386 /out:"_TEST/abc.exe"
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib lib\x86\pthreadVC2.lib /nologo /subsystem:console /debug /machine:I386 /out:"_TEST/abc.exe"
 
 !ENDIF 
 
diff --git a/abclib.dsp b/abclib.dsp
index 0d86aba..cf7c3fe 100644
--- a/abclib.dsp
+++ b/abclib.dsp
@@ -41,7 +41,7 @@ RSC=rc.exe
 # PROP Intermediate_Dir "ReleaseLib"
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "src" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D ABC_DLL=ABC_DLLEXPORT /D "_CRT_SECURE_NO_DEPRECATE" /D "ABC_USE_PTHREADS" /FR /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "src" /D "WIN32" /D "WINDOWS" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D ABC_DLL=ABC_DLLEXPORT /D "_CRT_SECURE_NO_DEPRECATE" /D "ABC_USE_PTHREADS" /FR /YX /FD /c
 # ADD BASE RSC /l 0x409 /d "NDEBUG"
 # ADD RSC /l 0x409 /d "NDEBUG"
 BSC32=bscmake.exe
@@ -64,7 +64,7 @@ LIB32=link.exe -lib
 # PROP Intermediate_Dir "DebugLib"
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "src" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D ABC_DLL=ABC_DLLEXPORT /D "_CRT_SECURE_NO_DEPRECATE" /D "ABC_USE_PTHREADS" /FR /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "src" /D "WIN32" /D "WINDOWS" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D ABC_DLL=ABC_DLLEXPORT /D "_CRT_SECURE_NO_DEPRECATE" /D "ABC_USE_PTHREADS" /FR /YX /FD /GZ /c
 # ADD BASE RSC /l 0x409 /d "_DEBUG"
 # ADD RSC /l 0x409 /d "_DEBUG"
 BSC32=bscmake.exe
@@ -691,6 +691,10 @@ SOURCE=.\src\base\main\mainLib.c
 # End Source File
 # Begin Source File
 
+SOURCE=.\src\base\main\mainReal.c
+# End Source File
+# Begin Source File
+
 SOURCE=.\src\base\main\mainUtils.c
 # End Source File
 # End Group
@@ -726,22 +730,6 @@ SOURCE=.\src\base\ver\verStream.c
 SOURCE=.\src\base\test\test.c
 # End Source File
 # End Group
-# Begin Group "abc2"
-
-# PROP Default_Filter ""
-# End Group
-# Begin Group "abc2d"
-
-# PROP Default_Filter ""
-# End Group
-# Begin Group "pcm"
-
-# PROP Default_Filter ""
-# End Group
-# Begin Group "ply"
-
-# PROP Default_Filter ""
-# End Group
 # Begin Group "wlc"
 
 # PROP Default_Filter ""
@@ -1491,6 +1479,10 @@ SOURCE=.\src\sat\bmc\bmcCexTools.c
 # End Source File
 # Begin Source File
 
+SOURCE=.\src\sat\bmc\bmcChain.c
+# End Source File
+# Begin Source File
+
 SOURCE=.\src\sat\bmc\bmcEco.c
 # End Source File
 # Begin Source File
@@ -1522,6 +1514,10 @@ SOURCE=.\src\sat\bmc\bmcMulti.c
 SOURCE=.\src\sat\bmc\bmcUnroll.c
 # End Source File
 # End Group
+# Begin Group "bsat2"
+
+# PROP Default_Filter ""
+# End Group
 # End Group
 # Begin Group "opt"
 
@@ -3919,6 +3915,10 @@ SOURCE=.\src\aig\gia\giaPat.c
 # End Source File
 # Begin Source File
 
+SOURCE=.\src\aig\gia\giaQbf.c
+# End Source File
+# Begin Source File
+
 SOURCE=.\src\aig\gia\giaResub.c
 # End Source File
 # Begin Source File
diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h
index 4dfa671..6d90670 100644
--- a/src/aig/gia/gia.h
+++ b/src/aig/gia/gia.h
@@ -188,7 +188,6 @@ struct Gia_Man_t_
     Vec_Int_t *    vStore;        // node storage  
 };
 
-
 
 typedef struct Gps_Par_t_ Gps_Par_t;
 struct Gps_Par_t_
@@ -246,6 +245,20 @@ struct Gia_ParSim_t_
     int            iOutFail;      // index of the failed output
 };
 
+typedef struct Gia_ManSim_t_ Gia_ManSim_t;
+struct Gia_ManSim_t_
+{
+    Gia_Man_t *    pAig;
+    Gia_ParSim_t * pPars; 
+    int            nWords;
+    Vec_Int_t *    vCis2Ids;
+    Vec_Int_t *    vConsts;
+    // simulation information
+    unsigned *     pDataSim;     // simulation data
+    unsigned *     pDataSimCis;  // simulation data for CIs
+    unsigned *     pDataSimCos;  // simulation data for COs
+};
+
 typedef struct Jf_Par_t_ Jf_Par_t; 
 struct Jf_Par_t_
 {
@@ -1174,6 +1187,7 @@ extern int                 Gia_ManHashAnd( Gia_Man_t * p, int iLit0, int iLit1 )
 extern int                 Gia_ManHashOr( Gia_Man_t * p, int iLit0, int iLit1 ); 
 extern int                 Gia_ManHashXor( Gia_Man_t * p, int iLit0, int iLit1 ); 
 extern int                 Gia_ManHashMux( Gia_Man_t * p, int iCtrl, int iData1, int iData0 );
+extern int                 Gia_ManHashMaj( Gia_Man_t * p, int iData0, int iData1, int iData2 );
 extern int                 Gia_ManHashAndTry( Gia_Man_t * p, int iLit0, int iLit1 );
 extern Gia_Man_t *         Gia_ManRehash( Gia_Man_t * p, int fAddStrash );
 extern void                Gia_ManHashProfile( Gia_Man_t * p );
@@ -1277,7 +1291,13 @@ extern Gia_Man_t *         Gia_ManPerformDsdBalanceWin( Gia_Man_t * p, int Level
 extern int *               Gia_SortFloats( float * pArray, int * pPerm, int nSize );
 /*=== giaSim.c ============================================================*/
 extern void                Gia_ManSimSetDefaultParams( Gia_ParSim_t * p );
-extern int                 Gia_ManSimSimulate( Gia_Man_t * pAig, Gia_ParSim_t * pPars );
+extern int                 Gia_ManSimSimulate( Gia_Man_t * pAig, Gia_ParSim_t * pPars );
+extern unsigned *          Gia_SimDataExt( Gia_ManSim_t * p, int i );
+extern unsigned *          Gia_SimDataCiExt( Gia_ManSim_t * p, int i );
+extern unsigned *          Gia_SimDataCoExt( Gia_ManSim_t * p, int i );
+extern void                Gia_ManSimInfoInit( Gia_ManSim_t * p );
+extern void                Gia_ManSimInfoTransfer( Gia_ManSim_t * p );
+extern void                Gia_ManSimulateRound( Gia_ManSim_t * p );
 /*=== giaSpeedup.c ============================================================*/
 extern float               Gia_ManDelayTraceLut( Gia_Man_t * p );
 extern float               Gia_ManDelayTraceLutPrint( Gia_Man_t * p, int fVerbose );
diff --git a/src/aig/gia/giaEnable.c b/src/aig/gia/giaEnable.c
index 14cb6f5..d92e39e 100644
--- a/src/aig/gia/giaEnable.c
+++ b/src/aig/gia/giaEnable.c
@@ -362,7 +362,7 @@ Gia_Man_t * Gia_ManUnrollInit( Gia_Man_t * p, int nFrames )
     Gia_Man_t * pNew;
     Gia_Obj_t * pObj, * pObjRi, * pObjRo;
     int f, i;
-    Vec_IntFill( &p->vCopies, -1, nFrames * Gia_ManObjNum(p) );
+    Vec_IntFill( &p->vCopies, nFrames * Gia_ManObjNum(p), -1 );
     pNew = Gia_ManStart( nFrames * Gia_ManObjNum(p) );
     pNew->pName = Abc_UtilStrsav( p->pName );
     pNew->pSpec = Abc_UtilStrsav( p->pSpec );
@@ -412,7 +412,7 @@ Gia_Man_t * Gia_ManUnrollAndCofactor( Gia_Man_t * p, int nFrames, int nFanMax, i
     vCofSigs = Gia_ManTransferFrames( p, pFrames, nFrames, pAig, vTemp = vCofSigs );
     Vec_IntFree( vTemp );
     Gia_ManStop( pFrames );
-    ABC_FREE( p->vCopies.pArray );
+    Vec_IntErase( &p->vCopies );
     // cofactor all these variables
     pNew = Gia_ManDupCofAllInt( pAig, vCofSigs, fVerbose );
     Vec_IntFree( vCofSigs );
diff --git a/src/aig/gia/giaEquiv.c b/src/aig/gia/giaEquiv.c
index b5b1559..38512a1 100644
--- a/src/aig/gia/giaEquiv.c
+++ b/src/aig/gia/giaEquiv.c
@@ -1017,7 +1017,7 @@ Gia_Man_t * Gia_ManSpecReduceInit( Gia_Man_t * p, Abc_Cex_t * pInit, int nFrames
     }
 */
     assert( pInit->nRegs == Gia_ManRegNum(p) && pInit->nPis == 0 );
-    Vec_IntFill( &p->vCopies, -1, nFrames * Gia_ManObjNum(p) );
+    Vec_IntFill( &p->vCopies, nFrames * Gia_ManObjNum(p), -1 );
     vXorLits = Vec_IntAlloc( 1000 );
     Gia_ManSetPhase( p );
     if ( fDualOut )
@@ -1052,7 +1052,7 @@ Gia_Man_t * Gia_ManSpecReduceInit( Gia_Man_t * p, Abc_Cex_t * pInit, int nFrames
 //        Abc_Print( 1, "Speculatively reduced model has no primary outputs.\n" );
         Gia_ManAppendCo( pNew, 0 );
     }
-    ABC_FREE( p->vCopies.pArray );
+    Vec_IntErase( &p->vCopies );
     Vec_IntFree( vXorLits );
     Gia_ManHashStop( pNew );
     pNew = Gia_ManCleanup( pTemp = pNew );
diff --git a/src/aig/gia/giaHash.c b/src/aig/gia/giaHash.c
index c9d9041..667fdb9 100644
--- a/src/aig/gia/giaHash.c
+++ b/src/aig/gia/giaHash.c
@@ -685,6 +685,25 @@ int Gia_ManHashMux( Gia_Man_t * p, int iCtrl, int iData1, int iData0 )
     iTemp1 = Gia_ManHashAnd( p, iCtrl, iData1 );
     return Abc_LitNotCond( Gia_ManHashAnd( p, Abc_LitNot(iTemp0), Abc_LitNot(iTemp1) ), !fCompl );
 }
+
+/**Function*************************************************************
+
+  Synopsis    []
+
+  Description []
+               
+  SideEffects []
+
+  SeeAlso     []
+
+***********************************************************************/
+int Gia_ManHashMaj( Gia_Man_t * p, int iData0, int iData1, int iData2 )  
+{ 
+    int iTemp0 = Gia_ManHashOr( p, iData1, iData2 );
+    int iTemp1 = Gia_ManHashAnd( p, iData0, iTemp0 );
+    int iTemp2 = Gia_ManHashAnd( p, iData1, iData2 );
+    return Gia_ManHashOr( p, iTemp1, iTemp2 );
+}
 
 /**Function*************************************************************
 
diff --git a/src/aig/gia/giaQbf.c b/src/aig/gia/giaQbf.c
new file mode 100644
index 0000000..d309be7
--- /dev/null
+++ b/src/aig/gia/giaQbf.c
@@ -0,0 +1,492 @@
+/**CFile****************************************************************
+
+  FileName    [giaQbf.c]
+
+  SystemName  [ABC: Logic synthesis and verification system.]
+
+  PackageName [Scalable AIG package.]
+
+  Synopsis    [QBF solver.]
+
+  Author      [Alan Mishchenko]
+  
+  Affiliation [UC Berkeley]
+
+  Date        [Ver. 1.0. Started - October 18, 2014.]
+
+  Revision    [$Id: giaQbf.c,v 1.00 2014/10/18 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "gia.h"
+#include "sat/cnf/cnf.h"
+#include "sat/bsat/satStore.h"
+#include "misc/extra/extra.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+///                        DECLARATIONS                              ///
+////////////////////////////////////////////////////////////////////////
+
+typedef struct Qbf_Man_t_ Qbf_Man_t; 
+struct Qbf_Man_t_
+{
+    Gia_Man_t *     pGia;           // original miter
+    int             nPars;          // parameter variables
+    int             nVars;          // functional variables
+    int             fVerbose;       // verbose flag
+    // internal variables
+    int             iParVarBeg;     // SAT var ID of the first par variable in the ver solver
+    sat_solver *    pSatVer;        // verification instance
+    sat_solver *    pSatSyn;        // synthesis instance
+    Vec_Int_t *     vValues;        // variable values
+    Vec_Int_t *     vParMap;        // parameter mapping
+    Vec_Int_t *     vLits;          // literals for the SAT solver
+    abctime         clkStart;       // global timeout
+    abctime         clkSat;         // SAT solver time
+};
+
+extern Cnf_Dat_t * Mf_ManGenerateCnf( Gia_Man_t * pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose );
+
+////////////////////////////////////////////////////////////////////////
+///                     FUNCTION DEFINITIONS                         ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+  Synopsis    [Naive way to enumerate SAT assignments.]
+
+  Description []
+               
+  SideEffects []
+
+  SeeAlso     []
+
+***********************************************************************/
+int Gia_ManSatEnum( Gia_Man_t * pGia, int nConfLimit, int nTimeOut, int fVerbose )
+{
+    Cnf_Dat_t * pCnf;
+    sat_solver * pSat;
+    Vec_Int_t * vLits;
+    int i, iLit, iParVarBeg, Iter;
+    int nSolutions = 0, RetValue = 0;
+    abctime clkStart = Abc_Clock();
+    pCnf = Mf_ManGenerateCnf( pGia, 8, 0, 1, 0 );
+    pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 );
+    iParVarBeg = pCnf->nVars - Gia_ManPiNum(pGia) - 1;
+    Cnf_DataFree( pCnf );
+    // iterate through the SAT assignment
+    vLits = Vec_IntAlloc( Gia_ManPiNum(pGia) );
+    for ( Iter = 1 ; ; Iter++ )
+    {
+        int status = sat_solver_solve( pSat, NULL, NULL, (ABC_INT64_T)nConfLimit, 0, 0, 0 );
+        if ( status == l_False ) { RetValue =  1; break; }
+        if ( status == l_Undef ) { RetValue =  0; break; }
+        nSolutions++;
+        // extract SAT assignment
+        Vec_IntClear( vLits );
+        for ( i = 0; i < Gia_ManPiNum(pGia); i++ )
+            Vec_IntPush( vLits, Abc_Var2Lit(iParVarBeg+i, sat_solver_var_value(pSat, iParVarBeg+i)) );
+        if ( fVerbose )
+        {
+            printf( "%5d : ", Iter );
+            Vec_IntForEachEntry( vLits, iLit, i )
+                printf( "%d", !Abc_LitIsCompl(iLit) );
+            printf( "\n" );
+        }
+        // add clause
+        if ( !sat_solver_addclause( pSat, Vec_IntArray(vLits), Vec_IntArray(vLits) + Vec_IntSize(vLits) ) )
+            { RetValue =  1; break; }
+        if ( nTimeOut && (Abc_Clock() - clkStart)/CLOCKS_PER_SEC >= nTimeOut ) { RetValue = 0; break; }
+    }
+    sat_solver_delete( pSat );
+    Vec_IntFree( vLits );
+    if ( nTimeOut && (Abc_Clock() - clkStart)/CLOCKS_PER_SEC >= nTimeOut )
+        printf( "Enumerated %d assignments when timeout (%d sec) was reached.  ", nSolutions, nTimeOut );
+    else if ( nConfLimit && !RetValue )
+        printf( "Enumerated %d assignments when conflict limit (%d) was reached.  ", nSolutions, nConfLimit );
+    else 
+        printf( "Enumerated the complete set of %d assignments.  ", nSolutions );
+    Abc_PrintTime( 1, "Time", Abc_Clock() - clkStart );
+    return RetValue;
+}
+
+/**Function*************************************************************
+
+  Synopsis    [Dumps the original problem in QDIMACS format.]
+
+  Description []
+               
+  SideEffects []
+
+  SeeAlso     []
+
+***********************************************************************/
+void Gia_QbfDumpFile( Gia_Man_t * pGia, int nPars )
+{
+    // original problem: \exists p \forall x \exists y.  M(p,x,y)
+    // negated problem:  \forall p \exists x \exists y. !M(p,x,y)
+    Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( pGia, 8, 0, 1, 0 );
+    Vec_Int_t * vVarMap, * vForAlls, * vExists;
+    Gia_Obj_t * pObj;
+    char * pFileName;
+    int i, Entry;
+    // create var map
+    vVarMap = Vec_IntStart( pCnf->nVars );
+    Gia_ManForEachCi( pGia, pObj, i )
+        if ( i < nPars )
+            Vec_IntWriteEntry( vVarMap, pCnf->pVarNums[Gia_ManCiIdToId(pGia, i)], 1 );
+    // create various maps
+    vForAlls = Vec_IntAlloc( nPars );
+    vExists = Vec_IntAlloc( Gia_ManCiNum(pGia) - nPars );
+    Vec_IntForEachEntry( vVarMap, Entry, i )
+        if ( Entry )
+            Vec_IntPush( vForAlls, i );
+        else
+            Vec_IntPush( vExists, i );
+    // generate CNF
+    pFileName = Extra_FileNameGenericAppend( pGia->pSpec, ".qdimacs" );
+    Cnf_DataWriteIntoFile( pCnf, pFileName, 0, vForAlls, vExists );
+    Cnf_DataFree( pCnf );
+    Vec_IntFree( vForAlls );
+    Vec_IntFree( vExists );
+    Vec_IntFree( vVarMap );
+    printf( "The 2QBF formula was written into file \"%s\".\n", pFileName );
+}
+
+/**Function*************************************************************
+
+  Synopsis    [Generate one SAT assignment of the problem.]
+
+  Description []
+               
+  SideEffects []
+
+  SeeAlso     []
+
+***********************************************************************/
+Qbf_Man_t * Gia_QbfAlloc( Gia_Man_t * pGia, int nPars, int fVerbose )
+{
+    Qbf_Man_t * p;
+    Cnf_Dat_t * pCnf;
+    Gia_ObjFlipFaninC0( Gia_ManPo(pGia, 0) );
+    pCnf = Mf_ManGenerateCnf( pGia, 8, 0, 1, 0 );
+    Gia_ObjFlipFaninC0( Gia_ManPo(pGia, 0) );
+    p = ABC_CALLOC( Qbf_Man_t, 1 );
+    p->clkStart   = Abc_Clock();
+    p->pGia       = pGia;
+    p->nPars      = nPars;
+    p->nVars      = Gia_ManPiNum(pGia) - nPars;
+    p->fVerbose   = fVerbose;
+    p->iParVarBeg = pCnf->nVars - Gia_ManPiNum(pGia) - 1;
+    p->pSatVer    = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 );
+    p->pSatSyn    = sat_solver_new();
+    p->vValues    = Vec_IntAlloc( Gia_ManPiNum(pGia) );
+    p->vParMap    = Vec_IntStartFull( nPars );
+    p->vLits      = Vec_IntAlloc( nPars );
+    sat_solver_setnvars( p->pSatSyn, nPars );
+    Cnf_DataFree( pCnf );
+    return p;
+}
+void Gia_QbfFree( Qbf_Man_t * p )
+{
+    sat_solver_delete( p->pSatVer );
+    sat_solver_delete( p->pSatSyn );
+    Vec_IntFree( p->vLits );
+    Vec_IntFree( p->vValues );
+    Vec_IntFree( p->vParMap );
+    ABC_FREE( p );
+}
+
+/**Function*************************************************************
+
+  Synopsis    [Create and add one cofactor.]
+
+  Description []
+               
+  SideEffects []
+
+  SeeAlso     []
+
+***********************************************************************/
+Gia_Man_t * Gia_QbfQuantify( Gia_Man_t * p, int nPars )
+{
+    Gia_Man_t * pNew, * pTemp;
+    Gia_Obj_t * pObj; 
+    int i, m, nMints = (1 << (Gia_ManPiNum(p) - nPars));
+    assert( Gia_ManPoNum(p) == 1 );
+    pNew = Gia_ManStart( Gia_ManObjNum(p) );
+    pNew->pName = Abc_UtilStrsav( p->pName );
+    Gia_ManHashAlloc( pNew );
+    Gia_ManConst0(p)->Value = 0;
+    for ( i = 0; i < nPars; i++ )
+        Gia_ManAppendCi(pNew);
+    for ( m = 0; m < nMints; m++ )
+    {
+        Gia_ManForEachPi( p, pObj, i )
+            pObj->Value = (i < nPars) ? Gia_Obj2Lit(pNew, Gia_ManPi(pNew, i)) : ((m >> (i - nPars)) & 1);
+        Gia_ManForEachAnd( p, pObj, i )
+            pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+        Gia_ManForEachCo( p, pObj, i )
+            pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+    }
+    pNew = Gia_ManCleanup( pTemp = pNew );
+    Gia_ManStop( pTemp );
+    assert( Gia_ManPiNum(pNew) == nPars );
+    assert( Gia_ManPoNum(pNew) == nMints );
+    return pNew;
+}
+
+/**Function*************************************************************
+
+  Synopsis    [Create and add one cofactor.]
+
+  Description []
+               
+  SideEffects []
+
+  SeeAlso     []
+
+***********************************************************************/
+Gia_Man_t * Gia_QbfCofactor( Gia_Man_t * p, int nPars, Vec_Int_t * vValues, Vec_Int_t * vParMap )
+{
+    Gia_Man_t * pNew, * pTemp;
+    Gia_Obj_t * pObj; int i;
+    assert( Gia_ManPiNum(p) == nPars + Vec_IntSize(vValues) );
+    pNew = Gia_ManStart( Gia_ManObjNum(p) );
+    pNew->pName = Abc_UtilStrsav( p->pName );
+    Gia_ManHashAlloc( pNew );
+    Gia_ManConst0(p)->Value = 0;
+    Gia_ManForEachPi( p, pObj, i )
+        if ( i < nPars )
+        {
+            pObj->Value = Gia_ManAppendCi(pNew);
+            if ( Vec_IntEntry(vParMap, i) != -1 )
+                pObj->Value = Vec_IntEntry(vParMap, i);
+        }
+        else
+            pObj->Value = Vec_IntEntry(vValues, i - nPars);
+    Gia_ManForEachAnd( p, pObj, i )
+        pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+    Gia_ManForEachCo( p, pObj, i )
+        pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+    pNew = Gia_ManCleanup( pTemp = pNew );
+    Gia_ManStop( pTemp );
+    assert( Gia_ManPiNum(pNew) == nPars );
+    return pNew;
+}
+int Gia_QbfAddCofactor( Qbf_Man_t * p, Gia_Man_t * pCof )
+{
+    Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( pCof, 8, 0, 1, 0 );
+    int i, iFirstVar = sat_solver_nvars(p->pSatSyn) + pCnf->nVars - Gia_ManPiNum(pCof) - 1;
+    pCnf->pMan = NULL;
+    Cnf_DataLift( pCnf, sat_solver_nvars(p->pSatSyn) );
+    for ( i = 0; i < pCnf->nClauses; i++ )
+        if ( !sat_solver_addclause( p->pSatSyn, pCnf->pClauses[i], pCnf->pClauses[i+1] ) )
+        {
+            Cnf_DataFree( pCnf );
+            return 0;
+        }
+    Cnf_DataFree( pCnf );
+    // add connection clauses
+    for ( i = 0; i < Gia_ManPiNum(p->pGia); i++ )
+        if ( !sat_solver_add_buffer( p->pSatSyn, i, iFirstVar+i, 0 ) )
+            return 0;
+    return 1;
+}
+
+/**Function*************************************************************
+
+  Synopsis    [Extract SAT assignment.]
+
+  Description []
+               
+  SideEffects []
+
+  SeeAlso     []
+
+***********************************************************************/
+void Gia_QbfOnePattern( Qbf_Man_t * p, Vec_Int_t * vValues )
+{
+    int i;
+    Vec_IntClear( vValues );
+    for ( i = 0; i < p->nPars; i++ )
+        Vec_IntPush( vValues, sat_solver_var_value(p->pSatSyn, i) );
+}
+void Gia_QbfPrint( Qbf_Man_t * p, Vec_Int_t * vValues, int Iter )
+{
+    printf( "%5d : ", Iter );
+    assert( Vec_IntSize(vValues) == p->nVars );
+    Vec_IntPrintBinary( vValues ); printf( "  " );
+    printf( "Var = %6d  ", sat_solver_nvars(p->pSatSyn) );
+    printf( "Cla = %6d  ", sat_solver_nclauses(p->pSatSyn) );
+    printf( "Conf = %6d  ", sat_solver_nconflicts(p->pSatSyn) );
+    Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart );
+}
+
+/**Function*************************************************************
+
+  Synopsis    [Generate one SAT assignment in terms of functional vars.]
+
+  Description []
+               
+  SideEffects []
+
+  SeeAlso     []
+
+***********************************************************************/
+int Gia_QbfVerify( Qbf_Man_t * p, Vec_Int_t * vValues )
+{
+    int i, Entry, RetValue;
+    assert( Vec_IntSize(vValues) == p->nPars );
+    Vec_IntClear( p->vLits );
+    Vec_IntForEachEntry( vValues, Entry, i )
+        Vec_IntPush( p->vLits, Abc_Var2Lit(p->iParVarBeg+i, !Entry) );
+    RetValue = sat_solver_solve( p->pSatVer, Vec_IntArray(p->vLits), Vec_IntLimit(p->vLits), 0, 0, 0, 0 );
+    if ( RetValue == l_True )
+    {
+        Vec_IntClear( vValues );
+        for ( i = 0; i < p->nVars; i++ )
+            Vec_IntPush( vValues, sat_solver_var_value(p->pSatVer, p->iParVarBeg+p->nPars+i) );
+    }
+    return RetValue == l_True ? 1 : 0;
+}
+
+/**Function*************************************************************
+
+  Synopsis    [Constraint learning.]
+
+  Description []
+               
+  SideEffects []
+
+  SeeAlso     []
+
+***********************************************************************/
+void Gia_QbfAddSpecialConstr( Qbf_Man_t * p )
+{
+    int i, status, Lits[2];
+    for ( i = 0; i < 4*11; i++ )
+        if ( i % 4 == 0 )
+        {
+            assert( Vec_IntEntry(p->vParMap, i) == -1 );
+            Vec_IntWriteEntry( p->vParMap, i, (i % 4) == 3 );
+            Lits[0] = Abc_Var2Lit( i, (i % 4) != 3 );
+            status = sat_solver_addclause( p->pSatSyn, Lits, Lits+1 );
+            assert( status );
+        }
+}
+void Gia_QbfLearnConstraint( Qbf_Man_t * p, Vec_Int_t * vValues )
+{
+    int i, status, Entry, Lits[2];
+    assert( Vec_IntSize(vValues) == p->nPars );
+    printf( "  Pattern   " );
+    Vec_IntPrintBinary( vValues );
+    printf( "\n" );
+    Vec_IntForEachEntry( vValues, Entry, i )
+    {
+        Lits[0] = Abc_Var2Lit( i, Entry );
+        status = sat_solver_solve( p->pSatSyn, Lits, Lits+1, 0, 0, 0, 0 );
+        printf( "  Var =%4d ", i );
+        if ( status != l_True )
+        {
+            printf( "UNSAT\n" );
+            Lits[0] = Abc_LitNot(Lits[0]);
+            status = sat_solver_addclause( p->pSatSyn, Lits, Lits+1 );
+            assert( status );
+            continue;
+        }
+        Gia_QbfOnePattern( p, p->vLits );
+        Vec_IntPrintBinary( p->vLits );
+        printf( "\n" );
+    }
+    assert( Vec_IntSize(vValues) == p->nPars );
+}
+
+/**Function*************************************************************
+
+  Synopsis    [Performs QBF solving using an improved algorithm.]
+
+  Description []
+               
+  SideEffects []
+
+  SeeAlso     []
+
+***********************************************************************/
+int Gia_QbfSolve( Gia_Man_t * pGia, int nPars, int nIterLimit, int nConfLimit, int nTimeOut, int fVerbose )
+{
+    Qbf_Man_t * p = Gia_QbfAlloc( pGia, nPars, fVerbose );
+    Gia_Man_t * pCof;
+    int i, status, RetValue = 0;
+    abctime clk;
+//    Gia_QbfAddSpecialConstr( p );
+    if ( fVerbose )
+        printf( "Solving QBF for \"%s\" with %d parameters, %d variables and %d AIG nodes.\n", 
+            Gia_ManName(pGia), p->nPars, p->nVars, Gia_ManAndNum(pGia) );
+    assert( Gia_ManRegNum(pGia) == 0 );
+    Vec_IntFill( p->vValues, nPars, 0 );
+    for ( i = 0; Gia_QbfVerify(p, p->vValues); i++ )
+    {
+        // generate next constraint
+        assert( Vec_IntSize(p->vValues) == p->nVars );
+        pCof = Gia_QbfCofactor( pGia, nPars, p->vValues, p->vParMap );
+        status = Gia_QbfAddCofactor( p, pCof );
+        Gia_ManStop( pCof );
+        if ( status == 0 )       { RetValue =  1; break; }
+        // synthesize next assignment
+        clk = Abc_Clock();
+        status = sat_solver_solve( p->pSatSyn, NULL, NULL, (ABC_INT64_T)nConfLimit, 0, 0, 0 );
+        p->clkSat += Abc_Clock() - clk;
+        if ( fVerbose )
+            Gia_QbfPrint( p, p->vValues, i );
+        if ( status == l_False ) { RetValue =  1; break; }
+        if ( status == l_Undef ) { RetValue = -1; break; }
+        // extract SAT assignment
+        Gia_QbfOnePattern( p, p->vValues );
+        assert( Vec_IntSize(p->vValues) == p->nPars );
+        // examine variables
+//        Gia_QbfLearnConstraint( p, p->vValues );
+//        Vec_IntPrintBinary( p->vValues ); printf( "\n" );
+        if ( nIterLimit && i+1 == nIterLimit ) { RetValue = -1; break; }
+        if ( nTimeOut && (Abc_Clock() - p->clkStart)/CLOCKS_PER_SEC >= nTimeOut ) { RetValue = -1; break; }
+    }
+    if ( RetValue == 0 )
+    {
+        printf( "Parameters: " );
+        assert( Vec_IntSize(p->vValues) == nPars );
+        Vec_IntPrintBinary( p->vValues );
+        printf( "\n" );
+    }
+    if ( RetValue == -1 && nTimeOut && (Abc_Clock() - p->clkStart)/CLOCKS_PER_SEC >= nTimeOut )
+        printf( "The problem timed out after %d sec.  ", nTimeOut );
+    else if ( RetValue == -1 && nConfLimit )
+        printf( "The problem aborted after %d conflicts.  ", nConfLimit );
+    else if ( RetValue == -1 && nIterLimit )
+        printf( "The problem aborted after %d iterations.  ", nIterLimit );
+    else if ( RetValue == 1 )
+        printf( "The problem is UNSAT after %d iterations.  ", i );
+    else 
+        printf( "The problem is SAT after %d iterations.  ", i );
+    if ( fVerbose )
+    {
+        printf( "\n" );
+        Abc_PrintTime( 1, "SAT  ", p->clkSat );
+        Abc_PrintTime( 1, "Other", Abc_Clock() - p->clkStart - p->clkSat );
+        Abc_PrintTime( 1, "TOTAL", Abc_Clock() - p->clkStart );
+    }
+    else
+        Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart );
+    Gia_QbfFree( p );
+    return RetValue;
+}
+
+////////////////////////////////////////////////////////////////////////
+///                       END OF FILE                                ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/aig/gia/giaSim.c b/src/aig/gia/giaSim.c
index 4871f17..cf973ec 100644
--- a/src/aig/gia/giaSim.c
+++ b/src/aig/gia/giaSim.c
@@ -26,24 +26,14 @@ ABC_NAMESPACE_IMPL_START
 ////////////////////////////////////////////////////////////////////////
 ///                        DECLARATIONS                              ///
 ////////////////////////////////////////////////////////////////////////
-
-typedef struct Gia_ManSim_t_ Gia_ManSim_t;
-struct Gia_ManSim_t_
-{
-    Gia_Man_t *    pAig;
-    Gia_ParSim_t * pPars; 
-    int            nWords;
-    Vec_Int_t *    vCis2Ids;
-    Vec_Int_t *    vConsts;
-    // simulation information
-    unsigned *     pDataSim;     // simulation data
-    unsigned *     pDataSimCis;  // simulation data for CIs
-    unsigned *     pDataSimCos;  // simulation data for COs
-};
-
-static inline unsigned * Gia_SimData( Gia_ManSim_t * p, int i )    { return p->pDataSim + i * p->nWords;    }
-static inline unsigned * Gia_SimDataCi( Gia_ManSim_t * p, int i )  { return p->pDataSimCis + i * p->nWords; }
-static inline unsigned * Gia_SimDataCo( Gia_ManSim_t * p, int i )  { return p->pDataSimCos + i * p->nWords; }
+
+static inline unsigned * Gia_SimData( Gia_ManSim_t * p, int i )    { return p->pDataSim + i * p->nWords;    }
+static inline unsigned * Gia_SimDataCi( Gia_ManSim_t * p, int i )  { return p->pDataSimCis + i * p->nWords; }
+static inline unsigned * Gia_SimDataCo( Gia_ManSim_t * p, int i )  { return p->pDataSimCos + i * p->nWords; }
+
+unsigned * Gia_SimDataExt( Gia_ManSim_t * p, int i )    { return Gia_SimData(p, i);    }
+unsigned * Gia_SimDataCiExt( Gia_ManSim_t * p, int i )  { return Gia_SimDataCi(p, i);  }
+unsigned * Gia_SimDataCoExt( Gia_ManSim_t * p, int i )  { return Gia_SimDataCo(p, i);  }
 
 ////////////////////////////////////////////////////////////////////////
 ///                     FUNCTION DEFINITIONS                         ///
@@ -436,7 +426,7 @@ static inline void Gia_ManSimulateNode( Gia_ManSim_t * p, Gia_Obj_t * pObj )
   SeeAlso     []
 
 ***********************************************************************/
-static inline void Gia_ManSimInfoInit( Gia_ManSim_t * p )
+void Gia_ManSimInfoInit( Gia_ManSim_t * p )
 {
     int iPioNum, i;
     Vec_IntForEachEntry( p->vCis2Ids, iPioNum, i )
@@ -459,7 +449,7 @@ static inline void Gia_ManSimInfoInit( Gia_ManSim_t * p )
   SeeAlso     []
 
 ***********************************************************************/
-static inline void Gia_ManSimInfoTransfer( Gia_ManSim_t * p )
+void Gia_ManSimInfoTransfer( Gia_ManSim_t * p )
 {
     int iPioNum, i;
     Vec_IntForEachEntry( p->vCis2Ids, iPioNum, i )
@@ -482,7 +472,7 @@ static inline void Gia_ManSimInfoTransfer( Gia_ManSim_t * p )
   SeeAlso     []
 
 ***********************************************************************/
-static inline void Gia_ManSimulateRound( Gia_ManSim_t * p )
+void Gia_ManSimulateRound( Gia_ManSim_t * p )
 {
     Gia_Obj_t * pObj;
     int i, iCis = 0, iCos = 0;
diff --git a/src/aig/gia/module.make b/src/aig/gia/module.make
index 85fe192..e0883b2 100644
--- a/src/aig/gia/module.make
+++ b/src/aig/gia/module.make
@@ -46,6 +46,7 @@ SRC +=	src/aig/gia/giaAig.c \
 	src/aig/gia/giaMuxes.c \
 	src/aig/gia/giaNf.c \
 	src/aig/gia/giaPat.c \
+	src/aig/gia/giaQbf.c \
 	src/aig/gia/giaResub.c \
 	src/aig/gia/giaRetime.c \
 	src/aig/gia/giaScl.c \
diff --git a/src/aig/ivy/ivyRwr.c b/src/aig/ivy/ivyRwr.c
index a4bfe54..30bff58 100644
--- a/src/aig/ivy/ivyRwr.c
+++ b/src/aig/ivy/ivyRwr.c
@@ -163,7 +163,7 @@ int Ivy_NodeRewrite( Ivy_Man_t * pMan, Rwt_Man_t * p, Ivy_Obj_t * pNode, int fUp
     char * pPerm;
     int Required, nNodesSaved;
     int nNodesSaveCur = -1; // Suppress "might be used uninitialized"
-    int i, c, GainCur, GainBest = -1;
+    int i, c, GainCur = -1, GainBest = -1;
     abctime clk, clk2;
 
     p->nNodesConsidered++;
diff --git a/src/aig/ivy/ivySeq.c b/src/aig/ivy/ivySeq.c
index c231dea..0ffe2d1 100644
--- a/src/aig/ivy/ivySeq.c
+++ b/src/aig/ivy/ivySeq.c
@@ -156,7 +156,7 @@ int Ivy_NodeRewriteSeq( Ivy_Man_t * pMan, Rwt_Man_t * p, Ivy_Obj_t * pNode, int
     char * pPerm;
     int nNodesSaved;
     int nNodesSaveCur = -1; // Suppress "might be used uninitialized"
-    int i, c, GainCur, GainBest = -1;
+    int i, c, GainCur = -1, GainBest = -1;
     abctime clk, clk2;//, clk3;
 
     p->nNodesConsidered++;
diff --git a/src/aig/saig/saigDup.c b/src/aig/saig/saigDup.c
index cd97871..81f9a1d 100644
--- a/src/aig/saig/saigDup.c
+++ b/src/aig/saig/saigDup.c
@@ -303,6 +303,70 @@ int Saig_ManVerifyCex( Aig_Man_t * pAig, Abc_Cex_t * p )
     Aig_ManCleanMarkB(pAig);
     return RetValue;
 }
+
+/**Function*************************************************************
+
+  Synopsis    [Resimulates the counter-example.]
+
+  Description []
+               
+  SideEffects []
+
+  SeeAlso     []
+
+***********************************************************************/
+int Saig_ManVerifyCexNoClear( Aig_Man_t * pAig, Abc_Cex_t * p )
+{
+    Aig_Obj_t * pObj, * pObjRi, * pObjRo;
+    int RetValue, i, k, iBit = 0;
+    Aig_ManCleanMarkB(pAig);
+    Aig_ManConst1(pAig)->fMarkB = 1;
+    Saig_ManForEachLo( pAig, pObj, i )
+        pObj->fMarkB = Abc_InfoHasBit(p->pData, iBit++);
+    for ( i = 0; i <= p->iFrame; i++ )
+    {
+        Saig_ManForEachPi( pAig, pObj, k )
+            pObj->fMarkB = Abc_InfoHasBit(p->pData, iBit++);
+        Aig_ManForEachNode( pAig, pObj, k )
+            pObj->fMarkB = (Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj)) & 
+                           (Aig_ObjFanin1(pObj)->fMarkB ^ Aig_ObjFaninC1(pObj));
+        Aig_ManForEachCo( pAig, pObj, k )
+            pObj->fMarkB = Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj);
+        if ( i == p->iFrame )
+            break;
+        Saig_ManForEachLiLo( pAig, pObjRi, pObjRo, k )
+            pObjRo->fMarkB = pObjRi->fMarkB;
+    }
+    assert( iBit == p->nBits );
+    RetValue = Aig_ManCo(pAig, p->iPo)->fMarkB;
+    //Aig_ManCleanMarkB(pAig);
+    return RetValue;
+}
+Vec_Int_t * Saig_ManReturnFailingState( Aig_Man_t * pAig, Abc_Cex_t * p, int fNextOne )
+{
+    Aig_Obj_t * pObj;
+    Vec_Int_t * vState;
+    int i, RetValue = Saig_ManVerifyCexNoClear( pAig, p );
+    if ( RetValue == 0 )
+    {
+        Aig_ManCleanMarkB(pAig);
+        printf( "CEX does fail the given sequential miter.\n" );
+        return NULL;
+    }
+    vState = Vec_IntAlloc( Aig_ManRegNum(pAig) );
+    if ( fNextOne )
+    {
+        Saig_ManForEachLi( pAig, pObj, i )
+            Vec_IntPush( vState, pObj->fMarkB );
+    }
+    else
+    {
+        Saig_ManForEachLo( pAig, pObj, i )
+            Vec_IntPush( vState, pObj->fMarkB );
+    }
+    Aig_ManCleanMarkB(pAig);
+    return vState;
+}
 
 /**Function*************************************************************
 
diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c
index abd4efd..b06d813 100644
--- a/src/base/abci/abc.c
+++ b/src/base/abci/abc.c
@@ -65,6 +65,8 @@ ABC_NAMESPACE_IMPL_START
 ////////////////////////////////////////////////////////////////////////
 ///                        DECLARATIONS                              ///
 ////////////////////////////////////////////////////////////////////////
+
+//#define USE_MINISAT22
 
 static int Abc_CommandPrintStats             ( Abc_Frame_t * pAbc, int argc, char ** argv );
 static int Abc_CommandPrintExdc              ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -186,6 +188,12 @@ static int Abc_CommandNpnSave                ( Abc_Frame_t * pAbc, int argc, cha
 
 static int Abc_CommandSendAig                ( Abc_Frame_t * pAbc, int argc, char ** argv );
 static int Abc_CommandSendStatus             ( Abc_Frame_t * pAbc, int argc, char ** argv );
+
+static int Abc_CommandBackup                 ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandRestore                ( Abc_Frame_t * pAbc, int argc, char ** argv );
+
+static int Abc_CommandMinisat                ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandMinisimp               ( Abc_Frame_t * pAbc, int argc, char ** argv );
 
 static int Abc_CommandIStrash                ( Abc_Frame_t * pAbc, int argc, char ** argv );
 static int Abc_CommandICut                   ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -313,9 +321,9 @@ static int Abc_CommandCexMerge               ( Abc_Frame_t * pAbc, int argc, cha
 static int Abc_CommandDualRail               ( Abc_Frame_t * pAbc, int argc, char ** argv );
 static int Abc_CommandBlockPo                ( Abc_Frame_t * pAbc, int argc, char ** argv );
 static int Abc_CommandIso                    ( Abc_Frame_t * pAbc, int argc, char ** argv );
-
-static int Abc_CommandTraceStart             ( Abc_Frame_t * pAbc, int argc, char ** argv );
-static int Abc_CommandTraceCheck             ( Abc_Frame_t * pAbc, int argc, char ** argv );
+
+static int Abc_CommandTraceStart             ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandTraceCheck             ( Abc_Frame_t * pAbc, int argc, char ** argv );
 
 static int Abc_CommandAbc9Get                ( Abc_Frame_t * pAbc, int argc, char ** argv );
 static int Abc_CommandAbc9Put                ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -370,6 +378,7 @@ static int Abc_CommandAbc9Lcorr              ( Abc_Frame_t * pAbc, int argc, cha
 static int Abc_CommandAbc9Scorr              ( Abc_Frame_t * pAbc, int argc, char ** argv );
 static int Abc_CommandAbc9Choice             ( Abc_Frame_t * pAbc, int argc, char ** argv );
 static int Abc_CommandAbc9Sat                ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandAbc9SatEnum            ( Abc_Frame_t * pAbc, int argc, char ** argv );
 static int Abc_CommandAbc9Fraig              ( Abc_Frame_t * pAbc, int argc, char ** argv );
 static int Abc_CommandAbc9CFraig             ( Abc_Frame_t * pAbc, int argc, char ** argv );
 static int Abc_CommandAbc9Srm                ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -419,10 +428,12 @@ static int Abc_CommandAbc9GroupProve         ( Abc_Frame_t * pAbc, int argc, cha
 static int Abc_CommandAbc9MultiProve         ( Abc_Frame_t * pAbc, int argc, char ** argv );
 static int Abc_CommandAbc9SplitProve         ( Abc_Frame_t * pAbc, int argc, char ** argv );
 static int Abc_CommandAbc9Bmc                ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandAbc9ChainBmc           ( Abc_Frame_t * pAbc, int argc, char ** argv );
 static int Abc_CommandAbc9BCore              ( Abc_Frame_t * pAbc, int argc, char ** argv );
 static int Abc_CommandAbc9ICheck             ( Abc_Frame_t * pAbc, int argc, char ** argv );
 static int Abc_CommandAbc9SatTest            ( Abc_Frame_t * pAbc, int argc, char ** argv );
 static int Abc_CommandAbc9FFTest             ( Abc_Frame_t * pAbc, int argc, char ** argv );
+static int Abc_CommandAbc9Qbf                ( Abc_Frame_t * pAbc, int argc, char ** argv );
 static int Abc_CommandAbc9Inse               ( Abc_Frame_t * pAbc, int argc, char ** argv );
 static int Abc_CommandAbc9Maxi               ( Abc_Frame_t * pAbc, int argc, char ** argv );
 static int Abc_CommandAbc9Bmci               ( Abc_Frame_t * pAbc, int argc, char ** argv );
@@ -780,9 +791,15 @@ void Abc_Init( Abc_Frame_t * pAbc )
     Cmd_CommandAdd( pAbc, "Various",      "senseinput",    Abc_CommandSenseInput,       1 );
     Cmd_CommandAdd( pAbc, "Various",      "npnload",       Abc_CommandNpnLoad,          0 );
     Cmd_CommandAdd( pAbc, "Various",      "npnsave",       Abc_CommandNpnSave,          0 );
-
-    Cmd_CommandAdd( pAbc, "Various",      "send_aig",      Abc_CommandSendAig,          0 );
-    Cmd_CommandAdd( pAbc, "Various",      "send_status",   Abc_CommandSendStatus,       0 );
+
+    Cmd_CommandAdd( pAbc, "Various",      "send_aig",      Abc_CommandSendAig,          0 );
+    Cmd_CommandAdd( pAbc, "Various",      "send_status",   Abc_CommandSendStatus,       0 );
+
+    Cmd_CommandAdd( pAbc, "Various",      "backup",        Abc_CommandBackup,           0 );
+    Cmd_CommandAdd( pAbc, "Various",      "restore",       Abc_CommandRestore,          0 );
+
+    Cmd_CommandAdd( pAbc, "Various",      "minisat",       Abc_CommandMinisat,          0 );
+    Cmd_CommandAdd( pAbc, "Various",      "minisimp",      Abc_CommandMinisimp,         0 );
 
     Cmd_CommandAdd( pAbc, "New AIG",      "istrash",       Abc_CommandIStrash,          1 );
     Cmd_CommandAdd( pAbc, "New AIG",      "icut",          Abc_CommandICut,             0 );
@@ -962,6 +979,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
     Cmd_CommandAdd( pAbc, "ABC9",         "&scorr",        Abc_CommandAbc9Scorr,        0 );
     Cmd_CommandAdd( pAbc, "ABC9",         "&choice",       Abc_CommandAbc9Choice,       0 );
     Cmd_CommandAdd( pAbc, "ABC9",         "&sat",          Abc_CommandAbc9Sat,          0 );
+    Cmd_CommandAdd( pAbc, "ABC9",         "&satenum",      Abc_CommandAbc9SatEnum,      0 );
     Cmd_CommandAdd( pAbc, "ABC9",         "&fraig",        Abc_CommandAbc9Fraig,        0 );
     Cmd_CommandAdd( pAbc, "ABC9",         "&cfraig",       Abc_CommandAbc9CFraig,       0 );
     Cmd_CommandAdd( pAbc, "ABC9",         "&srm",          Abc_CommandAbc9Srm,          0 );
@@ -1011,10 +1029,12 @@ void Abc_Init( Abc_Frame_t * pAbc )
     Cmd_CommandAdd( pAbc, "ABC9",         "&mprove",       Abc_CommandAbc9MultiProve,   0 );
     Cmd_CommandAdd( pAbc, "ABC9",         "&splitprove",   Abc_CommandAbc9SplitProve,   0 );
     Cmd_CommandAdd( pAbc, "ABC9",         "&bmc",          Abc_CommandAbc9Bmc,          0 );
+    Cmd_CommandAdd( pAbc, "ABC9",         "&chainbmc",     Abc_CommandAbc9ChainBmc,     0 );
     Cmd_CommandAdd( pAbc, "ABC9",         "&bcore",        Abc_CommandAbc9BCore,        0 );
     Cmd_CommandAdd( pAbc, "ABC9",         "&icheck",       Abc_CommandAbc9ICheck,       0 );
     Cmd_CommandAdd( pAbc, "ABC9",         "&sattest",      Abc_CommandAbc9SatTest,      0 );
     Cmd_CommandAdd( pAbc, "ABC9",         "&fftest",       Abc_CommandAbc9FFTest,       0 );
+    Cmd_CommandAdd( pAbc, "ABC9",         "&qbf",          Abc_CommandAbc9Qbf,          0 );
     Cmd_CommandAdd( pAbc, "ABC9",         "&inse",         Abc_CommandAbc9Inse,         0 );
     Cmd_CommandAdd( pAbc, "ABC9",         "&maxi",         Abc_CommandAbc9Maxi,         0 );
     Cmd_CommandAdd( pAbc, "ABC9",         "&bmci",         Abc_CommandAbc9Bmci,         0 );
@@ -12877,7 +12897,7 @@ int Abc_CommandQbf( Abc_Frame_t * pAbc, int argc, char ** argv )
     nPars    =  -1;
     nIters   = 500;
     fDumpCnf =   0;
-    fVerbose =   1;
+    fVerbose =   0;
     Extra_UtilGetoptReset();
     while ( ( c = Extra_UtilGetopt( argc, argv, "PIdvh" ) ) != EOF )
     {
@@ -12934,7 +12954,7 @@ int Abc_CommandQbf( Abc_Frame_t * pAbc, int argc, char ** argv )
     }
     if ( !(nPars > 0 && nPars < Abc_NtkPiNum(pNtk)) )
     {
-        Abc_Print( -1, "The number of paramter variables is invalid (should be > 0 and < PI num).\n" );
+        Abc_Print( -1, "The number of parameter variables is invalid (should be > 0 and < PI num).\n" );
         return 1;
     }
     if ( Abc_NtkIsStrash(pNtk) )
@@ -13164,6 +13184,116 @@ usage:
     return 1;
 }
 
+
+/**Function*************************************************************
+
+  Synopsis    []
+
+  Description []
+
+  SideEffects []
+
+  SeeAlso     []
+
+***********************************************************************/
+int Abc_CommandBackup( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+    Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
+    int c;
+    // set defaults
+    Extra_UtilGetoptReset();
+    while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF )
+    {
+        switch ( c )
+        {
+        case 'h':
+            goto usage;
+        default:
+            goto usage;
+        }
+    }
+
+    if ( pNtk == NULL )
+    {
+        Abc_Print( -1, "Empty network.\n" );
+        return 1;
+    }
+    if ( pAbc->pNtkBackup )
+        Abc_NtkDelete( pAbc->pNtkBackup );
+    pAbc->pNtkBackup = Abc_NtkDup( pNtk );
+    return 0;
+
+usage:
+    Abc_Print( -2, "usage: backup [-h]\n" );
+    Abc_Print( -2, "\t        backs up the current network\n" );
+    Abc_Print( -2, "\t-h    : print the command usage\n");
+    return 1;
+}
+int Abc_CommandRestore( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+    int c;
+    // set defaults
+    Extra_UtilGetoptReset();
+    while ( ( c = Extra_UtilGetopt( argc, argv, "h" ) ) != EOF )
+    {
+        switch ( c )
+        {
+        case 'h':
+            goto usage;
+        default:
+            goto usage;
+        }
+    }
+
+    if ( pAbc->pNtkBackup == NULL )
+    {
+        Abc_Print( -1, "There is no backup network.\n" );
+        return 1;
+    }
+    Abc_FrameReplaceCurrentNetwork( pAbc, Abc_NtkDup(pAbc->pNtkBackup) );
+    pAbc->nFrames = -1;
+    pAbc->Status = -1;
+    return 0;
+
+usage:
+    Abc_Print( -2, "usage: restore [-h]\n" );
+    Abc_Print( -2, "\t        restores the current network\n" );
+    Abc_Print( -2, "\t-h    : print the command usage\n");
+    return 1;
+}
+
+/**Function*************************************************************
+
+  Synopsis    []
+
+  Description []
+
+  SideEffects []
+
+  SeeAlso     []
+
+***********************************************************************/
+int Abc_CommandMinisat( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+#ifdef USE_MINISAT22
+    extern int MainSat(int argc, char** argv);
+    MainSat( argc, argv );
+#else
+    printf( "This command is currently disabled.\n" );
+#endif
+    return 1;
+}
+int Abc_CommandMinisimp( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+#ifdef USE_MINISAT22
+    extern int MainSimp(int argc, char** argv);
+    MainSimp( argc, argv );
+#else
+    printf( "This command is currently disabled.\n" );
+#endif
+    return 1;
+}
+
 
 /**Function*************************************************************
 
@@ -16365,20 +16495,17 @@ int Abc_CommandInit( Abc_Frame_t * pAbc, int argc, char ** argv )
 {
     Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
     Abc_Obj_t * pObj;
-    int c, i;
-    int fZeros;
-    int fOnes;
-    int fRandom;
-    int fDontCare;
-    char * pInitStr;
+    char * pInitStr = NULL;
+    int fZeros    = 0;
+    int fOnes     = 0;
+    int fRandom   = 0;
+    int fDontCare = 0;
+    int fUseCexCs = 0;
+    int fUseCexNs = 0;
+    int c, i;
     // set defaults
-    fZeros    = 0;
-    fOnes     = 0;
-    fRandom   = 0;
-    fDontCare = 0;
-    pInitStr  = NULL;
     Extra_UtilGetoptReset();
-    while ( ( c = Extra_UtilGetopt( argc, argv, "Szordh" ) ) != EOF )
+    while ( ( c = Extra_UtilGetopt( argc, argv, "Szordcnh" ) ) != EOF )
     {
         switch ( c )
         {
@@ -16400,9 +16527,15 @@ int Abc_CommandInit( Abc_Frame_t * pAbc, int argc, char ** argv )
         case 'r':
             fRandom ^= 1;
             break;
-        case 'd':
-            fDontCare ^= 1;
-            break;
+        case 'd':
+            fDontCare ^= 1;
+            break;
+        case 'c':
+            fUseCexCs ^= 1;
+            break;
+        case 'n':
+            fUseCexNs ^= 1;
+            break;
         case 'h':
             goto usage;
         default:
@@ -16459,21 +16592,54 @@ int Abc_CommandInit( Abc_Frame_t * pAbc, int argc, char ** argv )
                 Abc_LatchSetInit0( pObj );
     }
     else if ( fDontCare )
-    {
+    {
         Abc_NtkForEachLatch( pNtk, pObj, i )
             Abc_LatchSetInitDc( pObj );
+    }
+    else if ( fUseCexCs || fUseCexNs )
+    {
+        extern Vec_Int_t * Saig_ManReturnFailingState( Aig_Man_t * pMan, Abc_Cex_t * p, int fNextOne );
+        Aig_Man_t * pMan;
+        Vec_Int_t * vFailState;
+        if ( fUseCexCs && fUseCexNs )
+        {
+            Abc_Print( -1, "The two options (-c and -n) are incompatible.\n" );
+            return 0;
+        }
+        if ( !Abc_NtkIsStrash(pNtk) )
+        {
+            Abc_Print( -1, "The current network should be an AIG.\n" );
+            return 0;
+        }
+        if ( pAbc->pCex == NULL )
+        {
+            Abc_Print( -1, "The current CEX is not available.\n" );
+            return 0;
+        }
+        pMan = Abc_NtkToDar( pNtk, 0, 1 );
+        vFailState = Saig_ManReturnFailingState( pMan, pAbc->pCex, fUseCexNs );
+        //Vec_IntPrint( vFailState );
+        Aig_ManStop( pMan );
+        Abc_NtkForEachLatch( pNtk, pObj, i )
+            if ( Vec_IntEntry( vFailState, i ) )
+                Abc_LatchSetInit1( pObj );
+            else
+                Abc_LatchSetInit0( pObj );
+        Vec_IntFree( vFailState );
     }
     else
         Abc_Print( -1, "The initial states remain unchanged.\n" );
     return 0;
 
 usage:
-    Abc_Print( -2, "usage: init [-zordh] [-S <init_string>]\n" );
+    Abc_Print( -2, "usage: init [-zordcnh] [-S <init_string>]\n" );
     Abc_Print( -2, "\t         resets initial states of all latches\n" );
     Abc_Print( -2, "\t-z     : set zeros initial states [default = %s]\n", fZeros? "yes": "no" );
     Abc_Print( -2, "\t-o     : set ones initial states [default = %s]\n", fOnes? "yes": "no" );
     Abc_Print( -2, "\t-d     : set don't-care initial states [default = %s]\n", fDontCare? "yes": "no" );
-    Abc_Print( -2, "\t-r     : set random initial states [default = %s]\n", fRandom? "yes": "no" );
+    Abc_Print( -2, "\t-r     : set random initial states [default = %s]\n", fRandom? "yes": "no" );
+    Abc_Print( -2, "\t-c     : set failure current state from the CEX (and run \"zero\") [default = %s]\n", fUseCexCs? "yes": "no" );
+    Abc_Print( -2, "\t-n     : set next state after failure from the CEX (and run \"zero\") [default = %s]\n", fUseCexNs? "yes": "no" );
     Abc_Print( -2, "\t-h     : print the command usage\n");
     Abc_Print( -2, "\t-S str : (optional) initial state  [default = unused]\n" );
     return 1;
@@ -25203,7 +25369,8 @@ usage:
 ***********************************************************************/
 int Abc_CommandAbc9Read( Abc_Frame_t * pAbc, int argc, char ** argv )
 {
-    Gia_Man_t * pAig;
+    extern void Abc3_ReadShowHie( char * pFileName, int fFlat );
+    Gia_Man_t * pAig = NULL;
     FILE * pFile;
     char ** pArgvNew;
     char * FileName, * pTemp;
@@ -25251,13 +25418,16 @@ int Abc_CommandAbc9Read( Abc_Frame_t * pAbc, int argc, char ** argv )
         Abc_Print( 1, "\n" );
         return 1;
     }
-    fclose( pFile );
-
+    fclose( pFile );
+
     if ( fUseMini )
         pAig = Gia_ManReadMiniAig( FileName );
-    else
-        pAig = Gia_AigerRead( FileName, fSkipStrash, 0 );
-    Abc_FrameUpdateGia( pAbc, pAig );
+//    else if ( Extra_FileIsType( FileName, ".v", NULL, NULL ) )
+//        Abc3_ReadShowHie( FileName, fSkipStrash );
+    else 
+        pAig = Gia_AigerRead( FileName, fSkipStrash, 0 );
+    if ( pAig )
+        Abc_FrameUpdateGia( pAbc, pAig );
     return 0;
 
 usage:
@@ -26505,7 +26675,7 @@ int Abc_CommandAbc9Cof( Abc_Frame_t * pAbc, int argc, char ** argv )
     }
     else
     {
-        Abc_Print( -1, "One of the paramters, -V <num> or -L <num>, should be set on the command line.\n" );
+        Abc_Print( -1, "One of the parameters, -V <num> or -L <num>, should be set on the command line.\n" );
         goto usage;
     }
     return 0;
@@ -29577,6 +29747,73 @@ usage:
     Abc_Print( -2, "\t-h     : print the command usage\n");
     return 1;
 }
+
+/**Function*************************************************************
+
+  Synopsis    []
+
+  Description []
+
+  SideEffects []
+
+  SeeAlso     []
+
+***********************************************************************/
+int Abc_CommandAbc9SatEnum( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+    extern int Gia_ManSatEnum( Gia_Man_t * p, int nConfLimit, int nTimeOut, int fVerbose );
+    int c, nConfLimit = 0, nTimeOut = 0, fVerbose = 0;
+    Extra_UtilGetoptReset();
+    while ( ( c = Extra_UtilGetopt( argc, argv, "CTvh" ) ) != EOF )
+    {
+        switch ( c )
+        {
+        case 'C':
+            if ( globalUtilOptind >= argc )
+            {
+                Abc_Print( -1, "Command line switch \"-C\" should be followed by an integer.\n" );
+                goto usage;
+            }
+            nConfLimit = atoi(argv[globalUtilOptind]);
+            globalUtilOptind++;
+            if ( nConfLimit < 0 )
+                goto usage;
+            break;
+        case 'T':
+            if ( globalUtilOptind >= argc )
+            {
+                Abc_Print( -1, "Command line switch \"-T\" should be followed by an integer.\n" );
+                goto usage;
+            }
+            nTimeOut = atoi(argv[globalUtilOptind]);
+            globalUtilOptind++;
+            if ( nTimeOut < 0 )
+                goto usage;
+            break;
+        case 'v':
+            fVerbose ^= 1;
+            break;
+        default:
+            goto usage;
+        }
+    }
+    if ( pAbc->pGia == NULL )
+    {
+        Abc_Print( -1, "Abc_CommandAbc9SatEnum(): There is no AIG.\n" );
+        return 1;
+    }
+    Gia_ManSatEnum( pAbc->pGia, nConfLimit, nTimeOut, fVerbose );
+    return 0;
+
+usage:
+    Abc_Print( -2, "usage: &satenum [-CT <num>] [-vh]\n" );
+    Abc_Print( -2, "\t         enumerates solutions of the combinational miter\n" );
+    Abc_Print( -2, "\t-C num : the max number of conflicts at a node [default = %d]\n", nConfLimit );
+    Abc_Print( -2, "\t-T num : global timeout [default = %d]\n", nTimeOut );
+    Abc_Print( -2, "\t-v     : toggle printing verbose information [default = %s]\n",   fVerbose? "yes": "no" );
+    Abc_Print( -2, "\t-h     : print the command usage\n");
+    return 1;
+}
 
 /**Function*************************************************************
 
@@ -35223,6 +35460,90 @@ usage:
   SeeAlso     []
 
 ***********************************************************************/
+int Abc_CommandAbc9ChainBmc( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+    extern int Bmc_ChainTest( Gia_Man_t * p, int nFrameMax, int nConfMax, int fVerbose, int fVeryVerbose );
+    int nFrameMax    =  200;
+    int nConfMax     =    0;
+    int fVerbose     =    0;
+    int fVeryVerbose =    0;
+    int c;
+    Extra_UtilGetoptReset();
+    while ( ( c = Extra_UtilGetopt( argc, argv, "FCvwh" ) ) != EOF )
+    {
+        switch ( c )
+        {
+        case 'F':
+            if ( globalUtilOptind >= argc )
+            {
+                Abc_Print( -1, "Command line switch \"-F\" should be followed by an integer.\n" );
+                goto usage;
+            }
+            nFrameMax = atoi(argv[globalUtilOptind]);
+            globalUtilOptind++;
+            if ( nFrameMax < 0 )
+                goto usage;
+            break;
+        case 'C':
+            if ( globalUtilOptind >= argc )
+            {
+                Abc_Print( -1, "Command line switch \"-C\" should be followed by an integer.\n" );
+                goto usage;
+            }
+            nConfMax = atoi(argv[globalUtilOptind]);
+            globalUtilOptind++;
+            if ( nConfMax < 0 )
+                goto usage;
+            break;
+        case 'v':
+            fVerbose ^= 1;
+            break;
+        case 'w':
+            fVeryVerbose ^= 1;
+            break;
+        case 'h':
+            goto usage;
+        default:
+            goto usage;
+        }
+    }
+    if ( pAbc->pGia == NULL )
+    {
+        Abc_Print( -1, "Abc_CommandAbc9ChainBmc(): There is no AIG.\n" );
+        return 0;
+    }
+    if ( !Gia_ManRegNum(pAbc->pGia) )
+    {
+        Abc_Print( -1, "Abc_CommandAbc9ChainBmc(): The AIG is combinational.\n" );
+        return 0;
+    }
+    Bmc_ChainTest( pAbc->pGia, nFrameMax, nConfMax, fVerbose, fVeryVerbose );
+    //pAbc->Status  = ...;
+    //pAbc->nFrames = pPars->iFrame;
+    //Abc_FrameReplaceCex( pAbc, &pAbc->pGia->pCexSeq );
+    return 0;
+usage:
+    Abc_Print( -2, "usage: &chainbmc [-FC <num>] [-vwh]\n" );
+    Abc_Print( -2, "\t           runs a specialized flavor of BMC\n" );
+    Abc_Print( -2, "\t-F <num> : the max number of timeframes (0 = unused) [default = %d]\n", nFrameMax );
+    Abc_Print( -2, "\t-C <num> : the max number of conflicts (0 = unused) [default = %d]\n", nConfMax );
+    Abc_Print( -2, "\t-v       : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
+    Abc_Print( -2, "\t-w       : toggle printing even more information [default = %s]\n", fVeryVerbose? "yes": "no" );
+    Abc_Print( -2, "\t-h       : print the command usage\n");
+    return 1;
+}
+
+/**Function*************************************************************
+
+  Synopsis    []
+
+  Description []
+
+  SideEffects []
+
+  SeeAlso     []
+
+***********************************************************************/
 int Abc_CommandAbc9BCore( Abc_Frame_t * pAbc, int argc, char ** argv )
 {
     int c;
@@ -35505,7 +35826,7 @@ int Abc_CommandAbc9FFTest( Abc_Frame_t * pAbc, int argc, char ** argv )
     int c;
     Gia_ParFfSetDefault( pPars );
     Extra_UtilGetoptReset();
-    while ( ( c = Extra_UtilGetopt( argc, argv, "ATSGsbduvh" ) ) != EOF )
+    while ( ( c = Extra_UtilGetopt( argc, argv, "ATNSGsbduvh" ) ) != EOF )
     {
         switch ( c )
         {
@@ -35531,6 +35852,17 @@ int Abc_CommandAbc9FFTest( Abc_Frame_t * pAbc, int argc, char ** argv )
             if ( pPars->nTimeOut < 0 )
                 goto usage;
             break;
+        case 'N':
+            if ( globalUtilOptind >= argc )
+            {
+                Abc_Print( -1, "Command line switch \"-N\" should be followed by an integer.\n" );
+                goto usage;
+            }
+            pPars->nIterCheck = atoi(argv[globalUtilOptind]);
+            globalUtilOptind++;
+            if ( pPars->nIterCheck < 0 )
+                goto usage;
+            break;
         case 'S':
             if ( globalUtilOptind >= argc )
             {
@@ -35639,7 +35971,7 @@ int Abc_CommandAbc9FFTest( Abc_Frame_t * pAbc, int argc, char ** argv )
     return 0;
 
 usage:
-    Abc_Print( -2, "usage: &fftest [-AT num] [-sbduvh] <file> [-G file] [-S str]\n" );
+    Abc_Print( -2, "usage: &fftest [-ATN num] [-sbduvh] <file> [-G file] [-S str]\n" );
     Abc_Print( -2, "\t          performs functional fault test generation\n" );
     Abc_Print( -2, "\t-A num  : selects fault model for all gates [default = %d]\n", pPars->Algo );
     Abc_Print( -2, "\t                0: fault model is not selected (use -S str)\n" );
@@ -35648,6 +35980,7 @@ usage:
     Abc_Print( -2, "\t                3: complement fault: -S ((a&b)^p)\n" );
     Abc_Print( -2, "\t                4: functionally observable fault\n" );
     Abc_Print( -2, "\t-T num  : specifies approximate runtime limit in seconds [default = %d]\n",        pPars->nTimeOut );
+    Abc_Print( -2, "\t-N num  : specifies iteration to check for fixed parameters [default = %d]\n",     pPars->nIterCheck );
     Abc_Print( -2, "\t-s      : toggles starting with the all-0 and all-1 patterns [default = %s]\n",    pPars->fStartPats?  "yes": "no" );
     Abc_Print( -2, "\t-b      : toggles testing for single faults only [default = %s]\n",                pPars->fBasic?      "yes": "no" );
     Abc_Print( -2, "\t-d      : toggles dumping test patterns into file \"tests.txt\" [default = %s]\n", pPars->fDump?       "yes": "no" );
@@ -35686,6 +36019,145 @@ usage:
   SeeAlso     []
 
 ***********************************************************************/
+int Abc_CommandAbc9Qbf( Abc_Frame_t * pAbc, int argc, char ** argv )
+{
+    extern Gia_Man_t * Gia_QbfQuantify( Gia_Man_t * p, int nPars );
+    extern void Gia_QbfDumpFile( Gia_Man_t * pGia, int nPars );
+    extern int Gia_QbfSolve( Gia_Man_t * pGia, int nPars, int nIterLimit, int nConfLimit, int nTimeOut, int fVerbose );
+    int c, nPars   = -1;
+    int nIterLimit =  0;
+    int nConfLimit =  0;
+    int nTimeOut   =  0;
+    int fDumpCnf   =  0;
+    int fQuantX    =  0;
+    int fVerbose   =  0;
+    Extra_UtilGetoptReset();
+    while ( ( c = Extra_UtilGetopt( argc, argv, "PICTdqvh" ) ) != EOF )
+    {
+        switch ( c )
+        {
+        case 'P':
+            if ( globalUtilOptind >= argc )
+            {
+                Abc_Print( -1, "Command line switch \"-P\" should be followed by an integer.\n" );
+                goto usage;
+            }
+            nPars = atoi(argv[globalUtilOptind]);
+            globalUtilOptind++;
+            if ( nPars < 0 )
+                goto usage;
+            break;
+        case 'I':
+            if ( globalUtilOptind >= argc )
+            {
+                Abc_Print( -1, "Command line switch \"-I\" should be followed by an integer.\n" );
+                goto usage;
+            }
+            nIterLimit = atoi(argv[globalUtilOptind]);
+            globalUtilOptind++;
+            if ( nIterLimit < 0 )
+                goto usage;
+            break;
+        case 'C':
+            if ( globalUtilOptind >= argc )
+            {
+                Abc_Print( -1, "Command line switch \"-C\" should be followed by an integer.\n" );
+                goto usage;
+            }
+            nConfLimit = atoi(argv[globalUtilOptind]);
+            globalUtilOptind++;
+            if ( nConfLimit < 0 )
+                goto usage;
+            break;
+        case 'T':
+            if ( globalUtilOptind >= argc )
+            {
+                Abc_Print( -1, "Command line switch \"-T\" should be followed by an integer.\n" );
+                goto usage;
+            }
+            nTimeOut = atoi(argv[globalUtilOptind]);
+            globalUtilOptind++;
+            if ( nTimeOut < 0 )
+                goto usage;
+            break;
+        case 'd':
+            fDumpCnf ^= 1;
+            break;
+        case 'q':
+            fQuantX ^= 1;
+            break;
+        case 'v':
+            fVerbose ^= 1;
+            break;
+        case 'h':
+            goto usage;
+        default:
+            goto usage;
+        }
+    }
+    if ( pAbc->pGia == NULL )
+    {
+        Abc_Print( -1, "There is no current GIA.\n" );
+        return 1;
+    }
+    if ( Gia_ManRegNum(pAbc->pGia) )
+    {
+        Abc_Print( -1, "Works only for combinational networks.\n" );
+        return 1;
+    }
+    if ( Gia_ManPoNum(pAbc->pGia) != 1 )
+    {
+        Abc_Print( -1, "The miter should have one primary output.\n" );
+        return 1;
+    }
+    if ( !(nPars > 0 && nPars < Gia_ManPiNum(pAbc->pGia)) )
+    {
+        Abc_Print( -1, "The number of parameter variables is invalid (should be > 0 and < PI num).\n" );
+        return 1;
+    }
+    if ( fQuantX )
+    {
+        Gia_Man_t * pTemp;
+        if ( Gia_ManPiNum(pAbc->pGia) - nPars > 16 )
+        {
+            Abc_Print( -1, "Cannot quantify more than 16 variables.\n" );
+            return 1;
+        }
+        pTemp = Gia_QbfQuantify( pAbc->pGia, nPars );
+        Abc_FrameUpdateGia( pAbc, pTemp );
+        return 0;
+    }
+    if ( fDumpCnf )
+        Gia_QbfDumpFile( pAbc->pGia, nPars );
+    else
+        Gia_QbfSolve( pAbc->pGia, nPars, nIterLimit, nConfLimit, nTimeOut, fVerbose );
+    return 0;
+
+usage:
+    Abc_Print( -2, "usage: &qbf [-PICT num] [-dqvh]\n" );
+    Abc_Print( -2, "\t         solves QBF problem EpVxM(p,x)\n" );
+    Abc_Print( -2, "\t-P num : number of parameters p (should be the first PIs) [default = %d]\n", nPars );
+    Abc_Print( -2, "\t-I num : quit after the given iteration even if unsolved [default = %d]\n", nIterLimit );
+    Abc_Print( -2, "\t-C num : conflict limit per problem [default = %d]\n", nConfLimit );
+    Abc_Print( -2, "\t-T num : global timeout [default = %d]\n", nTimeOut );
+    Abc_Print( -2, "\t-d     : toggle dumping QDIMACS file instead of solving [default = %s]\n", fDumpCnf? "yes": "no" );
+    Abc_Print( -2, "\t-q     : toggle quantifying functions variables [default = %s]\n", fQuantX? "yes": "no" );
+    Abc_Print( -2, "\t-v     : toggle verbose output [default = %s]\n", fVerbose? "yes": "no" );
+    Abc_Print( -2, "\t-h     : print the command usage\n");
+    return 1;
+}
+
+/**Function*************************************************************
+
+  Synopsis    []
+
+  Description []
+
+  SideEffects []
+
+  SeeAlso     []
+
+***********************************************************************/
 int Abc_CommandAbc9Inse( Abc_Frame_t * pAbc, int argc, char ** argv )
 {
     extern Vec_Int_t * Gia_ManInseTest( Gia_Man_t * p, Vec_Int_t * vInit, int nFrames, int nWords, int nTimeOut, int fSim, int fVerbose );
diff --git a/src/base/abci/abcDar.c b/src/base/abci/abcDar.c
index 7ef1da3..8f78d42 100644
--- a/src/base/abci/abcDar.c
+++ b/src/base/abci/abcDar.c
@@ -2307,7 +2307,7 @@ int Abc_NtkDarBmc3( Abc_Ntk_t * pNtk, Saig_ParBmc_t * pPars, int fOrDecomp )
                     if ( pPars->nDropOuts )
                         Abc_Print( 1, " while others timed out (%d out of %d)", pPars->nDropOuts, nOutputs );
                 }
-                Abc_Print( 1, " after %d frames", pPars->iFrame );
+                Abc_Print( 1, " after %d frames", pPars->iFrame+2 );
                 Abc_Print( 1, ".   " );
             }
         }
diff --git a/src/base/abci/abcRec3.c b/src/base/abci/abcRec3.c
index 39bff00..411f4e9 100644
--- a/src/base/abci/abcRec3.c
+++ b/src/base/abci/abcRec3.c
@@ -1430,4 +1430,4 @@ void Abc_NtkRecStop3()
 ////////////////////////////////////////////////////////////////////////
 
 
-ABC_NAMESPACE_IMPL_END
\ No newline at end of file
+ABC_NAMESPACE_IMPL_END
diff --git a/src/base/abci/module.make b/src/base/abci/module.make
index 575a9f3..2f7b5c3 100644
--- a/src/base/abci/module.make
+++ b/src/base/abci/module.make
@@ -17,14 +17,14 @@ SRC +=	src/base/abci/abc.c \
 	src/base/abci/abcDsd.c \
 	src/base/abci/abcExtract.c \
 	src/base/abci/abcFraig.c \
-        src/base/abci/abcFx.c \
-        src/base/abci/abcFxu.c \
-        src/base/abci/abcGen.c \
+	src/base/abci/abcFx.c \
+	src/base/abci/abcFxu.c \
+	src/base/abci/abcGen.c \
 	src/base/abci/abcHaig.c \
 	src/base/abci/abcIf.c \
 	src/base/abci/abcIfif.c \
 	src/base/abci/abcIfMux.c \
-        src/base/abci/abcIvy.c \
+	src/base/abci/abcIvy.c \
 	src/base/abci/abcLog.c \
 	src/base/abci/abcLut.c \
 	src/base/abci/abcLutmin.c \
diff --git a/src/base/cmd/cmdUtils.c b/src/base/cmd/cmdUtils.c
index 2af0304..aef510f 100644
--- a/src/base/cmd/cmdUtils.c
+++ b/src/base/cmd/cmdUtils.c
@@ -482,13 +482,21 @@ FILE * CmdFileOpen( Abc_Frame_t * pAbc, char *sFileName, char *sMode, char **pFi
   SeeAlso     []
 
 ***********************************************************************/
-void CmdFreeArgv( int argc, char **argv )
-{
-    int i;
-    for ( i = 0; i < argc; i++ )
-        ABC_FREE( argv[i] );
-    ABC_FREE( argv );
-}
+void CmdFreeArgv( int argc, char **argv )
+{
+    int i;
+    for ( i = 0; i < argc; i++ )
+        ABC_FREE( argv[i] );
+    ABC_FREE( argv );
+}
+char ** CmdDupArgv( int argc, char **argv )
+{
+    char ** argvNew = ABC_ALLOC( char *, argc );
+    int i;
+    for ( i = 0; i < argc; i++ )
+        argvNew[i] = Abc_UtilStrsav( argv[i] );
+    return argvNew;
+}
 
 /**Function*************************************************************
 
diff --git a/src/base/main/main.c b/src/base/main/main.c
index a989fda..7857b0c 100644
--- a/src/base/main/main.c
+++ b/src/base/main/main.c
@@ -1,384 +1,6 @@
-/*////////////////////////////////////////////////////////////////////////////
-
-ABC: System for Sequential Synthesis and Verification
-
-http://www.eecs.berkeley.edu/~alanmi/abc/
-
-Copyright (c) The Regents of the University of California. All rights reserved.
-
-Permission is hereby granted, without written agreement and without license or
-royalty fees, to use, copy, modify, and distribute this software and its
-documentation for any purpose, provided that the above copyright notice and
-the following two paragraphs appear in all copies of this software.
-
-IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
-DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF
-THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
-CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
-BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS,
-AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
-SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
-
-////////////////////////////////////////////////////////////////////////////*/
-
-/**CFile****************************************************************
-
-  FileName    [main.c]
-
-  SystemName  [ABC: Logic synthesis and verification system.]
-
-  PackageName [The main package.]
-
-  Synopsis    [Here everything starts.]
-
-  Author      [Alan Mishchenko]
-  
-  Affiliation [UC Berkeley]
-
-  Date        [Ver. 1.0. Started - June 20, 2005.]
-
-  Revision    [$Id: main.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
-
-***********************************************************************/
-
-
-#ifdef ABC_PYTHON_EMBED
-#include <Python.h>
-#endif /* ABC_PYTHON_EMBED */
-
-#include "base/abc/abc.h"
-#include "mainInt.h"
-
-ABC_NAMESPACE_IMPL_START
-
-// this line should be included in the library project
-//#define ABC_LIB
-
-//#define ABC_USE_BINARY 1
-
-////////////////////////////////////////////////////////////////////////
-///                        DECLARATIONS                              ///
-////////////////////////////////////////////////////////////////////////
-
-static int TypeCheck( Abc_Frame_t * pAbc, const char * s);
-
-////////////////////////////////////////////////////////////////////////
-///                     FUNCTION DEFINITIONS                         ///
-////////////////////////////////////////////////////////////////////////
-
-#ifndef ABC_LIB
-
-/**Function*************************************************************
-
-  Synopsis    [The main() procedure.]
-
-  Description []
-               
-  SideEffects []
-
-  SeeAlso     []
-
-***********************************************************************/
-int Abc_RealMain( int argc, char * argv[] )
-{
-    Abc_Frame_t * pAbc;
-    char sCommandUsr[ABC_MAX_STR] = {0}, sCommandTmp[ABC_MAX_STR], sReadCmd[1000], sWriteCmd[1000];
-    const char * sOutFile, * sInFile;
-    char * sCommand;
-    int  fStatus = 0;
-    int c, fInitSource, fInitRead, fFinalWrite;
-
-    enum {
-        INTERACTIVE, // interactive mode
-        BATCH, // batch mode, run a command and quit
-        BATCH_THEN_INTERACTIVE, // run a command, then back to interactive mode
-        BATCH_QUIET // as in batch mode, but don't echo the command
-    } fBatch;
-
-    // added to detect memory leaks
-    // watch for {,,msvcrtd.dll}*__p__crtBreakAlloc()
-    // (http://support.microsoft.com/kb/151585)
-#if defined(_DEBUG) && defined(_MSC_VER)
-    _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
-#endif
-
-    // get global frame (singleton pattern)
-    // will be initialized on first call
-    pAbc = Abc_FrameGetGlobalFrame();
-    pAbc->sBinary = argv[0];
-
-#ifdef ABC_PYTHON_EMBED
-    {
-        PyObject* pModule;
-        void init_pyabc(void);
-
-        Py_SetProgramName(argv[0]);
-        Py_NoSiteFlag = 1;
-        Py_Initialize();
-
-        init_pyabc();
-
-        pModule = PyImport_ImportModule("pyabc");
-        if (pModule)
-        {
-            Py_DECREF(pModule);
-        }
-        else
-        {
-            fprintf( pAbc->Err, "error: pyabc.py not found. PYTHONPATH may not be set properly.\n");
-        }
-    }
-#endif /* ABC_PYTHON_EMBED */
-
-    // default options
-    fBatch      = INTERACTIVE;
-    fInitSource = 1;
-    fInitRead   = 0;
-    fFinalWrite = 0;
-    sInFile = sOutFile = NULL;
-    sprintf( sReadCmd,  "read"  );
-    sprintf( sWriteCmd, "write" );
-
-    Extra_UtilGetoptReset();
-    while ((c = Extra_UtilGetopt(argc, argv, "c:q:C:hf:F:o:st:T:xb")) != EOF) {
-        switch(c) {
-            case 'c':
-                strcpy( sCommandUsr, globalUtilOptarg );
-                fBatch = BATCH;
-                break;
-
-            case 'q':
-                strcpy( sCommandUsr, globalUtilOptarg );
-                fBatch = BATCH_QUIET;
-                break;
-
-            case 'C':
-                strcpy( sCommandUsr, globalUtilOptarg );
-                fBatch = BATCH_THEN_INTERACTIVE;
-                break;
-
-            case 'f':
-                sprintf(sCommandUsr, "source %s", globalUtilOptarg);
-                fBatch = BATCH;
-                break;
-
-            case 'F':
-                sprintf(sCommandUsr, "source -x %s", globalUtilOptarg);
-                fBatch = BATCH;
-                break;
-
-            case 'h':
-                goto usage;
-                break;
-
-            case 'o':
-                sOutFile = globalUtilOptarg;
-                fFinalWrite = 1;
-                break;
-
-            case 's':
-                fInitSource = 0;
-                break;
-
-            case 't':
-                if ( TypeCheck( pAbc, globalUtilOptarg ) )
-                {
-                    if ( !strcmp(globalUtilOptarg, "none") == 0 )
-                    {
-                        fInitRead = 1;
-                        sprintf( sReadCmd, "read_%s", globalUtilOptarg );
-                    }
-                }
-                else {
-                    goto usage;
-                }
-                fBatch = BATCH;
-                break;
-
-            case 'T':
-                if ( TypeCheck( pAbc, globalUtilOptarg ) )
-                {
-                    if (!strcmp(globalUtilOptarg, "none") == 0)
-                    {
-                        fFinalWrite = 1;
-                        sprintf( sWriteCmd, "write_%s", globalUtilOptarg);
-                    }
-                }
-                else {
-                    goto usage;
-                }
-                fBatch = BATCH;
-                break;
-
-            case 'x':
-                fFinalWrite = 0;
-                fInitRead   = 0;
-                fBatch = BATCH;
-                break;
-
-            case 'b':
-                Abc_FrameSetBridgeMode();
-                break;
-
-            default:
-                goto usage;
-        }
-    }
-
-    if ( Abc_FrameIsBridgeMode() )
-    {
-        extern Gia_Man_t * Gia_ManFromBridge( FILE * pFile, Vec_Int_t ** pvInit );
-        pAbc->pGia = Gia_ManFromBridge( stdin, NULL );
-    }
-    else if ( fBatch!=INTERACTIVE && fBatch!=BATCH_QUIET && sCommandUsr[0] )
-        Abc_Print( 1, "ABC command line: \"%s\".\n\n", sCommandUsr );
-
-    if ( fBatch!=INTERACTIVE )
-    {
-        pAbc->fBatchMode = 1;
-
-
-        if (argc - globalUtilOptind == 0)
-        {
-            sInFile = NULL;
-        }
-        else if (argc - globalUtilOptind == 1)
-        {
-            fInitRead = 1;
-            sInFile = argv[globalUtilOptind];
-        }
-        else
-        {
-            Abc_UtilsPrintUsage( pAbc, argv[0] );
-        }
-
-        // source the resource file
-        if ( fInitSource )
-        {
-            Abc_UtilsSource( pAbc );
-        }
-
-        fStatus = 0;
-        if ( fInitRead && sInFile )
-        {
-            sprintf( sCommandTmp, "%s %s", sReadCmd, sInFile );
-            fStatus = Cmd_CommandExecute( pAbc, sCommandTmp );
-        }
-
-        if ( fStatus == 0 )
-        {
-            /* cmd line contains `source <file>' */
-            fStatus = Cmd_CommandExecute( pAbc, sCommandUsr );
-            if ( (fStatus == 0 || fStatus == -1) && fFinalWrite && sOutFile )
-            {
-                sprintf( sCommandTmp, "%s %s", sWriteCmd, sOutFile );
-                fStatus = Cmd_CommandExecute( pAbc, sCommandTmp );
-            }
-        }
-
-        if (fBatch == BATCH_THEN_INTERACTIVE){
-            fBatch = INTERACTIVE;
-            pAbc->fBatchMode = 0;
-        }
-
-    }
-
-    if ( fBatch==INTERACTIVE )
-    {
-        // start interactive mode
-
-        // print the hello line
-        Abc_UtilsPrintHello( pAbc );
-        // print history of the recent commands
-        Cmd_HistoryPrint( pAbc, 10 );
-
-        // source the resource file
-        if ( fInitSource )
-        {
-            Abc_UtilsSource( pAbc );
-        }
-
-        // execute commands given by the user
-        while ( !feof(stdin) )
-        {
-            // print command line prompt and
-            // get the command from the user
-            sCommand = Abc_UtilsGetUsersInput( pAbc );
-
-            // execute the user's command
-            fStatus = Cmd_CommandExecute( pAbc, sCommand );
-
-            // stop if the user quitted or an error occurred
-            if ( fStatus == -1 || fStatus == -2 )
-                break;
-        }
-    }
-
-#ifdef ABC_PYTHON_EMBED
-    {
-        Py_Finalize();
-    }
-#endif /* ABC_PYTHON_EMBED */
-
-    // if the memory should be freed, quit packages
-//    if ( fStatus < 0 ) 
-    {
-        Abc_Stop();
-    }
-    return 0;
-
-usage:
-    Abc_UtilsPrintHello( pAbc );
-    Abc_UtilsPrintUsage( pAbc, argv[0] );
-    return 1;
-}
-
-#endif
-
-/**Function********************************************************************
-
-  Synopsis    [Returns 1 if s is a file type recognized, else returns 0.]
-
-  Description [Returns 1 if s is a file type recognized by ABC, else returns 0. 
-  Recognized types are "blif", "bench", "pla", and "none".]
-
-  SideEffects []
-
-******************************************************************************/
-static int TypeCheck( Abc_Frame_t * pAbc, const char * s )
-{
-    if (strcmp(s, "blif") == 0)
-        return 1;
-    else if (strcmp(s, "bench") == 0)
-        return 1;
-    else if (strcmp(s, "pla") == 0)
-        return 1;
-    else if (strcmp(s, "none") == 0)
-        return 1;
-    else {
-        fprintf( pAbc->Err, "unknown type %s\n", s );
-        return 0;
-    }
-}
-
-
-
-
-////////////////////////////////////////////////////////////////////////
-///                       END OF FILE                                ///
-////////////////////////////////////////////////////////////////////////
-
-
-ABC_NAMESPACE_IMPL_END
-
-#if defined(ABC_USE_BINARY)
-int main_( int argc, char * argv[] )
-#else
-int main( int argc, char * argv[] )
-#endif
-{
-  return ABC_NAMESPACE_PREFIX Abc_RealMain(argc, argv);
-}
+extern int Abc_RealMain(int argc, char *argv[]);
+
+int main(int argc, char *argv[])
+{
+   return Abc_RealMain(argc, argv);
+}
diff --git a/src/base/main/mainFrame.c b/src/base/main/mainFrame.c
index ba799b6..9556b64 100644
--- a/src/base/main/mainFrame.c
+++ b/src/base/main/mainFrame.c
@@ -198,6 +198,7 @@ void Abc_FrameDeallocate( Abc_Frame_t * p )
     if ( p->pSave4    )  Aig_ManStop( (Aig_Man_t *)p->pSave4 );
     if ( p->pManDsd   )  If_DsdManFree( (If_DsdMan_t *)p->pManDsd, 0 );
     if ( p->pManDsd2  )  If_DsdManFree( (If_DsdMan_t *)p->pManDsd2, 0 );
+    if ( p->pNtkBackup)  Abc_NtkDelete( p->pNtkBackup );
     if ( p->vPlugInComBinPairs ) 
     {
         char * pTemp;
diff --git a/src/base/main/mainInit.c b/src/base/main/mainInit.c
index feff2e6..95ad02c 100644
--- a/src/base/main/mainInit.c
+++ b/src/base/main/mainInit.c
@@ -22,9 +22,6 @@
 #include "mainInt.h"
 
 ABC_NAMESPACE_IMPL_START
-
-//#define USE_ABC2
-//#define USE_ABC85
  
 ////////////////////////////////////////////////////////////////////////
 ///                        DECLARATIONS                              ///
@@ -59,6 +56,24 @@ extern void Abc2_End ( Abc_Frame_t * pAbc );
 extern void Abc85_Init( Abc_Frame_t * pAbc );
 extern void Abc85_End( Abc_Frame_t * pAbc );
 
+static Abc_FrameInitializer_t* s_InitializerStart = NULL;
+static Abc_FrameInitializer_t* s_InitializerEnd = NULL;
+
+void Abc_FrameAddInitializer( Abc_FrameInitializer_t* p )
+{
+	if( ! s_InitializerStart )
+		s_InitializerStart = p;
+
+	p->next = NULL;
+	p->prev = s_InitializerEnd;
+
+	if ( s_InitializerEnd )
+		s_InitializerEnd->next = p;
+
+	s_InitializerEnd = p;
+
+}
+
 ////////////////////////////////////////////////////////////////////////
 ///                     FUNCTION DEFINITIONS                         ///
 ////////////////////////////////////////////////////////////////////////
@@ -76,6 +91,7 @@ extern void Abc85_End( Abc_Frame_t * pAbc );
 ***********************************************************************/
 void Abc_FrameInit( Abc_Frame_t * pAbc )
 {
+    Abc_FrameInitializer_t* p;
     Cmd_Init( pAbc );
     Cmd_CommandExecute( pAbc, "set checkread" ); 
     Io_Init( pAbc );
@@ -89,13 +105,9 @@ void Abc_FrameInit( Abc_Frame_t * pAbc )
     Scl_Init( pAbc );
     Wlc_Init( pAbc );
     Test_Init( pAbc );
-#ifdef USE_ABC2
-    Abc2_Init( pAbc );
-#endif
-#ifdef USE_ABC85
-    Abc85_Init( pAbc );
-#endif
-    EXT_ABC_INIT(pAbc) // plugin for external functionality
+    for( p = s_InitializerStart ; p ; p = p->next )
+    	if(p->init)
+    		p->init(pAbc);
 }
 
 
@@ -112,6 +124,10 @@ void Abc_FrameInit( Abc_Frame_t * pAbc )
 ***********************************************************************/
 void Abc_FrameEnd( Abc_Frame_t * pAbc )
 {
+    Abc_FrameInitializer_t* p;
+    for( p = s_InitializerEnd ; p ; p = p->prev )
+    	if ( p->destroy )
+    		p->destroy(pAbc);
     Abc_End( pAbc );
     Io_End( pAbc );
     Cmd_End( pAbc );
@@ -124,13 +140,6 @@ void Abc_FrameEnd( Abc_Frame_t * pAbc )
     Scl_End( pAbc );
     Wlc_End( pAbc );
     Test_End( pAbc );
-#ifdef USE_ABC2
-    Abc2_End( pAbc );
-#endif
-#ifdef USE_ABC85
-    Abc85_End( pAbc );
-#endif
-    EXT_ABC_END(pAbc) // plugin for external functionality
 }
 
 
diff --git a/src/base/main/mainInt.h b/src/base/main/mainInt.h
index 90195f7..aa40f0c 100644
--- a/src/base/main/mainInt.h
+++ b/src/base/main/mainInt.h
@@ -35,7 +35,6 @@
 #include "proof/fra/fra.h"
 //#include "aig/nwk/nwkMerge.h"
 //#include "aig/ntl/ntlnwk.h"
-#include "misc/ext/ext.h"
 #include "misc/extra/extraBdd.h"
 
 ABC_NAMESPACE_HEADER_START
@@ -68,6 +67,7 @@ struct Abc_Frame_t_
     Abc_Ntk_t *     pNtkCur;       // the current network
     Abc_Ntk_t *     pNtkBestDelay; // the current network
     Abc_Ntk_t *     pNtkBestArea;  // the current network
+    Abc_Ntk_t *     pNtkBackup;    // the current network
     int             nSteps;        // the counter of different network processed
     int             fSource;       // marks the source mode
     int             fAutoexac;     // marks the autoexec mode
@@ -127,8 +127,20 @@ struct Abc_Frame_t_
     void *          pAbc85Best;
     void *          pAbc85Delay;
     void *          pAbcWlc;
+};
+
+typedef void (*Abc_Frame_Initialization_Func)( Abc_Frame_t * pAbc );
+
+struct Abc_FrameInitializer_t_;
+typedef struct Abc_FrameInitializer_t_ Abc_FrameInitializer_t;
+
+struct Abc_FrameInitializer_t_
+{
+	Abc_Frame_Initialization_Func init;
+	Abc_Frame_Initialization_Func destroy;
 
-    EXT_ABC_FRAME   // plugin for external functionality
+	Abc_FrameInitializer_t* next;
+	Abc_FrameInitializer_t* prev;
 };
 
 ////////////////////////////////////////////////////////////////////////
@@ -149,6 +161,7 @@ extern ABC_DLL int             main( int argc, char * argv[] );
 /*=== mvInit.c ===================================================*/
 extern ABC_DLL void            Abc_FrameInit( Abc_Frame_t * pAbc );
 extern ABC_DLL void            Abc_FrameEnd( Abc_Frame_t * pAbc );
+extern ABC_DLL void            Abc_FrameAddInitializer( Abc_FrameInitializer_t* p );
 /*=== mvFrame.c =====================================================*/
 extern ABC_DLL Abc_Frame_t *   Abc_FrameAllocate();
 extern ABC_DLL void            Abc_FrameDeallocate( Abc_Frame_t * p );
diff --git a/src/base/main/main.c b/src/base/main/mainReal.c
similarity index 97%
copy from src/base/main/main.c
copy to src/base/main/mainReal.c
index a989fda..55e0163 100644
--- a/src/base/main/main.c
+++ b/src/base/main/mainReal.c
@@ -54,10 +54,6 @@ SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 
 ABC_NAMESPACE_IMPL_START
 
-// this line should be included in the library project
-//#define ABC_LIB
-
-//#define ABC_USE_BINARY 1
 
 ////////////////////////////////////////////////////////////////////////
 ///                        DECLARATIONS                              ///
@@ -69,7 +65,6 @@ static int TypeCheck( Abc_Frame_t * pAbc, const char * s);
 ///                     FUNCTION DEFINITIONS                         ///
 ////////////////////////////////////////////////////////////////////////
 
-#ifndef ABC_LIB
 
 /**Function*************************************************************
 
@@ -336,8 +331,6 @@ usage:
     return 1;
 }
 
-#endif
-
 /**Function********************************************************************
 
   Synopsis    [Returns 1 if s is a file type recognized, else returns 0.]
@@ -374,11 +367,3 @@ static int TypeCheck( Abc_Frame_t * pAbc, const char * s )
 
 ABC_NAMESPACE_IMPL_END
 
-#if defined(ABC_USE_BINARY)
-int main_( int argc, char * argv[] )
-#else
-int main( int argc, char * argv[] )
-#endif
-{
-  return ABC_NAMESPACE_PREFIX Abc_RealMain(argc, argv);
-}
diff --git a/src/base/main/module.make b/src/base/main/module.make
index 4b065f7..2893f4f 100644
--- a/src/base/main/module.make
+++ b/src/base/main/module.make
@@ -2,5 +2,6 @@ SRC +=  src/base/main/main.c \
 	src/base/main/mainFrame.c \
 	src/base/main/mainInit.c \
 	src/base/main/mainLib.c \
+	src/base/main/mainReal.c \
 	src/base/main/libSupport.c \
 	src/base/main/mainUtils.c
diff --git a/src/bdd/mtr/mtr.h b/src/bdd/mtr/mtr.h
index db936ab..cc8c585 100644
--- a/src/bdd/mtr/mtr.h
+++ b/src/bdd/mtr/mtr.h
@@ -76,12 +76,12 @@ ABC_NAMESPACE_HEADER_START
 #define SIZEOF_INT 4
 #endif
 
-#undef CONST
-#if defined(__STDC__) || defined(__cplusplus)
-#define CONST           const
-#else /* !(__STDC__ || __cplusplus) */
-#define CONST
-#endif /* !(__STDC__ || __cplusplus) */
+//#undef CONST
+//#if defined(__STDC__) || defined(__cplusplus)
+//#define CONST           const
+//#else /* !(__STDC__ || __cplusplus) */
+//#define CONST
+//#endif /* !(__STDC__ || __cplusplus) */
 
 #if defined(__GNUC__)
 #define MTR_INLINE __inline__
diff --git a/src/bool/lucky/luckySimple.c b/src/bool/lucky/luckySimple.c
index 14cfab5..12ca732 100644
--- a/src/bool/lucky/luckySimple.c
+++ b/src/bool/lucky/luckySimple.c
@@ -103,7 +103,7 @@ void fillInFlipArray(permInfo* pi)
 	
 	
 }
-inline int factorial(int n)
+static inline int factorial(int n)
 {
 	return (n == 1 || n == 0) ? 1 : factorial(n - 1) * n;
 }
@@ -129,14 +129,14 @@ void freePermInfoPtr(permInfo* x)
     free(x->swapArray);
     free(x);
 }
-inline void minWord(word* a, word* b, word* minimal, int nVars)
+static inline void minWord(word* a, word* b, word* minimal, int nVars)
 {
     if(memCompare(a, b, nVars) == -1)
         Kit_TruthCopy_64bit( minimal, a, nVars );
     else
         Kit_TruthCopy_64bit( minimal, b, nVars );
 }
-inline void minWord3(word* a, word* b, word* minimal, int nVars)
+static inline void minWord3(word* a, word* b, word* minimal, int nVars)
 { 
     if (memCompare(a, b, nVars) <= 0)
     {
diff --git a/src/bool/rpo/rpo.c b/src/bool/rpo/rpo.c
index cf24fbe..f9d2ee0 100644
--- a/src/bool/rpo/rpo.c
+++ b/src/bool/rpo/rpo.c
@@ -380,4 +380,4 @@ Literal_t* Rpo_Recursion(unsigned* target, Literal_t** vecLit, int nLit, int nLi
     return result;
 }
 
-ABC_NAMESPACE_IMPL_END
\ No newline at end of file
+ABC_NAMESPACE_IMPL_END
diff --git a/src/bool/rpo/rpo.h b/src/bool/rpo/rpo.h
index 14ffddd..a55a002 100644
--- a/src/bool/rpo/rpo.h
+++ b/src/bool/rpo/rpo.h
@@ -54,5 +54,6 @@ int Rpo_computeMinEdgeCost(Rpo_LCI_Edge_t** edges, int edgeCount, int* vertexDeg
 ABC_NAMESPACE_HEADER_END
         
 #endif
+
 
   
\ No newline at end of file
diff --git a/src/map/if/ifTruth.c b/src/map/if/ifTruth.c
index 991e600..f88ecc9 100644
--- a/src/map/if/ifTruth.c
+++ b/src/map/if/ifTruth.c
@@ -97,21 +97,20 @@ void If_CutRotatePins( If_Man_t * p, If_Cut_t * pCut )
 ***********************************************************************/
 int If_CutComputeTruth( If_Man_t * p, If_Cut_t * pCut, If_Cut_t * pCut0, If_Cut_t * pCut1, int fCompl0, int fCompl1 )
 {
-    int fCompl, truthId, nLeavesNew, RetValue = 0;
-    int PrevSize, nWords = Abc_TtWordNum( pCut->nLeaves );
+    int fCompl, truthId, nLeavesNew, PrevSize, RetValue = 0;
     word * pTruth0s = Vec_MemReadEntry( p->vTtMem[pCut0->nLeaves], Abc_Lit2Var(pCut0->iCutFunc) );
     word * pTruth1s = Vec_MemReadEntry( p->vTtMem[pCut1->nLeaves], Abc_Lit2Var(pCut1->iCutFunc) );
     word * pTruth0  = (word *)p->puTemp[0];
     word * pTruth1  = (word *)p->puTemp[1];
     word * pTruth   = (word *)p->puTemp[2];
-    Abc_TtCopy( pTruth0, pTruth0s, nWords, fCompl0 ^ pCut0->fCompl ^ Abc_LitIsCompl(pCut0->iCutFunc) );
-    Abc_TtCopy( pTruth1, pTruth1s, nWords, fCompl1 ^ pCut1->fCompl ^ Abc_LitIsCompl(pCut1->iCutFunc) );
+    Abc_TtCopy( pTruth0, pTruth0s, p->nTruth6Words[pCut0->nLeaves], fCompl0 ^ pCut0->fCompl ^ Abc_LitIsCompl(pCut0->iCutFunc) );
+    Abc_TtCopy( pTruth1, pTruth1s, p->nTruth6Words[pCut1->nLeaves], fCompl1 ^ pCut1->fCompl ^ Abc_LitIsCompl(pCut1->iCutFunc) );
     Abc_TtStretch6( pTruth0, pCut0->nLeaves, pCut->nLeaves );
     Abc_TtStretch6( pTruth1, pCut1->nLeaves, pCut->nLeaves );
     Abc_TtExpand( pTruth0, pCut->nLeaves, pCut0->pLeaves, pCut0->nLeaves, pCut->pLeaves, pCut->nLeaves );
     Abc_TtExpand( pTruth1, pCut->nLeaves, pCut1->pLeaves, pCut1->nLeaves, pCut->pLeaves, pCut->nLeaves );
     fCompl         = (pTruth0[0] & pTruth1[0] & 1);
-    Abc_TtAnd( pTruth, pTruth0, pTruth1, nWords, fCompl );
+    Abc_TtAnd( pTruth, pTruth0, pTruth1, p->nTruth6Words[pCut->nLeaves], fCompl );
     if ( p->pPars->fCutMin && (pCut0->nLeaves + pCut1->nLeaves > pCut->nLeaves || pCut0->nLeaves == 0 || pCut1->nLeaves == 0) )
     {
         nLeavesNew = Abc_TtMinBase( pTruth, pCut->pLeaves, pCut->nLeaves, pCut->nLeaves );
@@ -130,7 +129,7 @@ int If_CutComputeTruth( If_Man_t * p, If_Cut_t * pCut, If_Cut_t * pCut0, If_Cut_
     {
         word pCopy[1024];
         char pCanonPerm[16];
-        memcpy( pCopy, If_CutTruthW(pCut), sizeof(word) * nWords );
+        memcpy( pCopy, If_CutTruthW(pCut), sizeof(word) * p->nTruth6Words[pCut->nLeaves] );
         Abc_TtCanonicize( pCopy, pCut->nLeaves, pCanonPerm );
     }
 #endif
@@ -167,7 +166,6 @@ int If_CutComputeTruthPerm_int( If_Man_t * p, If_Cut_t * pCut, If_Cut_t * pCut0,
     abctime clk = 0;
     int pPerm[IF_MAX_LUTSIZE];
     int v, Place, fCompl, truthId, nLeavesNew, RetValue = 0;
-    int nWords      = Abc_TtWordNum( pCut->nLeaves );
     word * pTruth0s = Vec_MemReadEntry( p->vTtMem[pCut0->nLeaves], Abc_Lit2Var(iCutFunc0) );
     word * pTruth1s = Vec_MemReadEntry( p->vTtMem[pCut1->nLeaves], Abc_Lit2Var(iCutFunc1) );
     word * pTruth0  = (word *)p->puTemp[0];
@@ -175,8 +173,8 @@ int If_CutComputeTruthPerm_int( If_Man_t * p, If_Cut_t * pCut, If_Cut_t * pCut0,
     word * pTruth   = (word *)p->puTemp[2];
     assert( pCut0->uMaskFunc >= 0 );
     assert( pCut1->uMaskFunc >= 0 );
-    Abc_TtCopy( pTruth0, pTruth0s, nWords, Abc_LitIsCompl(iCutFunc0) );
-    Abc_TtCopy( pTruth1, pTruth1s, nWords, Abc_LitIsCompl(iCutFunc1) );
+    Abc_TtCopy( pTruth0, pTruth0s, p->nTruth6Words[pCut0->nLeaves], Abc_LitIsCompl(iCutFunc0) );
+    Abc_TtCopy( pTruth1, pTruth1s, p->nTruth6Words[pCut1->nLeaves], Abc_LitIsCompl(iCutFunc1) );
     Abc_TtStretch6( pTruth0, pCut0->nLeaves, pCut->nLeaves );
     Abc_TtStretch6( pTruth1, pCut1->nLeaves, pCut->nLeaves );
 
@@ -192,7 +190,7 @@ if ( fVerbose )
         if ( p->pPerm[1][v] >= (int)pCut0->nLeaves )
             pCut->pLeaves[p->pPerm[1][v]] = Abc_Var2Lit( pCut1->pLeaves[v], If_CutLeafBit(pCut1, v) );
         else if ( If_CutLeafBit(pCut0, p->pPerm[1][v]) != If_CutLeafBit(pCut1, v) )
-            Abc_TtFlip( pTruth1, nWords, v );  
+            Abc_TtFlip( pTruth1, p->nTruth6Words[pCut1->nLeaves], v );  
     // permute variables
     for ( v = (int)pCut1->nLeaves; v < (int)pCut->nLeaves; v++ )
         p->pPerm[1][v] = -1;
@@ -214,7 +212,7 @@ if ( fVerbose )
 }
 
     // perform operation
-    Abc_TtAnd( pTruth, pTruth0, pTruth1, nWords, 0 );
+    Abc_TtAnd( pTruth, pTruth0, pTruth1, p->nTruth6Words[pCut->nLeaves], 0 );
     // minimize support
     if ( p->pPars->fCutMin && (pCut0->nLeaves + pCut1->nLeaves > pCut->nLeaves || pCut0->nLeaves == 0 || pCut1->nLeaves == 0) )
     {
diff --git a/src/misc/extra/extra.h b/src/misc/extra/extra.h
index f84d7cd..f9ccf6a 100644
--- a/src/misc/extra/extra.h
+++ b/src/misc/extra/extra.h
@@ -103,7 +103,9 @@ extern char *       Extra_FileNameExtension( char * FileName );
 extern char *       Extra_FileNameAppend( char * pBase, char * pSuffix );
 extern char *       Extra_FileNameGeneric( char * FileName );
 extern char *       Extra_FileNameGenericAppend( char * pBase, char * pSuffix );
+extern void         Extra_FileNameCorrectPath( char * FileName );
 extern char *       Extra_FileNameWithoutPath( char * FileName );
+extern char *       Extra_FilePathWithoutName( char * FileName );
 extern int          Extra_FileCheck( char * pFileName );
 extern int          Extra_FileSize( char * pFileName );
 extern char *       Extra_FileRead( FILE * pFile );
diff --git a/src/misc/extra/extraUtilFile.c b/src/misc/extra/extraUtilFile.c
index a3c57d9..f5a755d 100644
--- a/src/misc/extra/extraUtilFile.c
+++ b/src/misc/extra/extraUtilFile.c
@@ -192,7 +192,27 @@ char * Extra_FileNameGenericAppend( char * pBase, char * pSuffix )
         *pDot = 0;
     strcat( Buffer, pSuffix );
     return Buffer;
-}
+}
+
+/**Function*************************************************************
+
+  Synopsis    []
+
+  Description []
+
+  SideEffects []
+
+  SeeAlso     []
+
+***********************************************************************/
+void Extra_FileNameCorrectPath( char * FileName )
+{
+    char * pStart;
+    if ( FileName )
+        for ( pStart = FileName; *pStart; pStart++ )
+            if ( *pStart == '>' || *pStart == '\\' )
+                *pStart = '/';
+}
 
 /**Function*************************************************************
 
@@ -213,6 +233,20 @@ char * Extra_FileNameWithoutPath( char * FileName )
             return pRes + 1;
     return FileName;
 }
+char * Extra_FilePathWithoutName( char * FileName )
+{
+    char * pRes;
+    FileName = Abc_UtilStrsav( FileName );
+    for ( pRes = FileName + strlen(FileName) - 1; pRes >= FileName; pRes-- )
+        if ( *pRes == '\\' || *pRes == '/' )
+        {
+           *pRes = 0;
+           Extra_FileNameCorrectPath( FileName );
+           return FileName;
+        }
+    ABC_FREE( FileName );
+    return NULL;
+}
 
 /**Function*************************************************************
 
diff --git a/src/misc/extra/extraUtilSupp.c b/src/misc/extra/extraUtilSupp.c
index a5d8d93..5fcc55b 100644
--- a/src/misc/extra/extraUtilSupp.c
+++ b/src/misc/extra/extraUtilSupp.c
@@ -402,7 +402,7 @@ static inline int Abc_SuppCountOnes64( word i )
 }
 int Abc_SuppFindVar( Vec_Wec_t * pS, Vec_Wec_t * pD, int nVars )
 {
-    int v, vBest = -1, dBest;
+    int v, vBest = -1, dBest = -1;
     for ( v = 0; v < nVars; v++ )
     {
         if ( Vec_WecLevelSize(pS, v) )
diff --git a/src/misc/vec/vecInt.h b/src/misc/vec/vecInt.h
index 74512e2..131db8f 100644
--- a/src/misc/vec/vecInt.h
+++ b/src/misc/vec/vecInt.h
@@ -1758,6 +1758,12 @@ static inline void Vec_IntPrint( Vec_Int_t * vVec )
         printf( " %d", Entry );
     printf( " }\n" );
 }
+static inline void Vec_IntPrintBinary( Vec_Int_t * vVec )
+{
+    int i, Entry;
+    Vec_IntForEachEntry( vVec, Entry, i )
+        printf( "%d", (int)(Entry != 0) );
+}
 
 /**Function*************************************************************
 
diff --git a/src/misc/vec/vecPtr.h b/src/misc/vec/vecPtr.h
index 195b890..48ab40c 100644
--- a/src/misc/vec/vecPtr.h
+++ b/src/misc/vec/vecPtr.h
@@ -891,7 +891,7 @@ static void Vec_PtrUniqify2( Vec_Ptr_t * p, int (*Vec_PtrSortCompare)(void**, vo
         Vec_IntFill( vCounts, 1, 1 );
     if ( p->nSize < 2 )
         return;
-    Vec_PtrSort( p, Vec_PtrSortCompare );
+    Vec_PtrSort( p, (int (*)())Vec_PtrSortCompare );
     for ( i = k = 1; i < p->nSize; i++ )
         if ( Vec_PtrSortCompare(p->pArray+i, p->pArray+k-1) != 0 )
         {
diff --git a/src/misc/vec/vecStr.h b/src/misc/vec/vecStr.h
index 63b9031..8b7b5d8 100644
--- a/src/misc/vec/vecStr.h
+++ b/src/misc/vec/vecStr.h
@@ -634,6 +634,12 @@ static inline void Vec_StrAppend( Vec_Str_t * p, const char * pString )
 {
     Vec_StrPrintStr( p, pString );
 }
+static inline void Vec_StrCopy( Vec_Str_t * p, const char * pString )
+{
+    Vec_StrClear( p );
+    Vec_StrAppend( p, pString );
+    Vec_StrPush( p, '\0' );
+}
 
 /**Function*************************************************************
 
diff --git a/src/opt/rwr/rwrEva.c b/src/opt/rwr/rwrEva.c
index a4d50fc..463e9bd 100644
--- a/src/opt/rwr/rwrEva.c
+++ b/src/opt/rwr/rwrEva.c
@@ -68,7 +68,7 @@ int Rwr_NodeRewrite( Rwr_Man_t * p, Cut_Man_t * pManCut, Abc_Obj_t * pNode, int
     char * pPerm;
     int Required, nNodesSaved;
     int nNodesSaveCur = -1; // Suppress "might be used uninitialized"
-    int i, GainCur, GainBest = -1;
+    int i, GainCur = -1, GainBest = -1;
     abctime clk, clk2;//, Counter;
 
     p->nNodesConsidered++;
diff --git a/src/proof/cec/cecCorr.c b/src/proof/cec/cecCorr.c
index 9e7280d..bfa12fb 100644
--- a/src/proof/cec/cecCorr.c
+++ b/src/proof/cec/cecCorr.c
@@ -112,7 +112,7 @@ Gia_Man_t * Gia_ManCorrSpecReduce( Gia_Man_t * p, int nFrames, int fScorr, Vec_I
     assert( nFrames > 0 );
     assert( Gia_ManRegNum(p) > 0 );
     assert( p->pReprs != NULL );
-    Vec_IntFill( &p->vCopies, -1, (nFrames+fScorr)*Gia_ManObjNum(p) );
+    Vec_IntFill( &p->vCopies, (nFrames+fScorr)*Gia_ManObjNum(p), -1 );
     Gia_ManSetPhase( p );
     pNew = Gia_ManStart( nFrames * Gia_ManObjNum(p) );
     pNew->pName = Abc_UtilStrsav( p->pName );
@@ -200,7 +200,7 @@ Gia_Man_t * Gia_ManCorrSpecReduce( Gia_Man_t * p, int nFrames, int fScorr, Vec_I
         Gia_ManAppendCo( pNew, iObjNew );
     Vec_IntFree( vXorLits );
     Gia_ManHashStop( pNew );
-    ABC_FREE( p->vCopies.pArray );
+    Vec_IntErase( &p->vCopies );
 //Abc_Print( 1, "Before sweeping = %d\n", Gia_ManAndNum(pNew) );
     pNew = Gia_ManCleanup( pTemp = pNew );
 //Abc_Print( 1, "After sweeping = %d\n", Gia_ManAndNum(pNew) );
@@ -229,7 +229,7 @@ Gia_Man_t * Gia_ManCorrSpecReduceInit( Gia_Man_t * p, int nFrames, int nPrefix,
     assert( (!fScorr && nFrames > 1) || (fScorr && nFrames > 0) || nPrefix );
     assert( Gia_ManRegNum(p) > 0 );
     assert( p->pReprs != NULL );
-    Vec_IntFill( &p->vCopies, -1, (nFrames+nPrefix+fScorr)*Gia_ManObjNum(p) );
+    Vec_IntFill( &p->vCopies, (nFrames+nPrefix+fScorr)*Gia_ManObjNum(p), -1 );
     Gia_ManSetPhase( p );
     pNew = Gia_ManStart( (nFrames+nPrefix) * Gia_ManObjNum(p) );
     pNew->pName = Abc_UtilStrsav( p->pName );
@@ -270,7 +270,7 @@ Gia_Man_t * Gia_ManCorrSpecReduceInit( Gia_Man_t * p, int nFrames, int nPrefix,
         Gia_ManAppendCo( pNew, iObjNew );
     Vec_IntFree( vXorLits );
     Gia_ManHashStop( pNew );
-    ABC_FREE( p->vCopies.pArray );
+    Vec_IntErase( &p->vCopies );
 //Abc_Print( 1, "Before sweeping = %d\n", Gia_ManAndNum(pNew) );
     pNew = Gia_ManCleanup( pTemp = pNew );
 //Abc_Print( 1, "After sweeping = %d\n", Gia_ManAndNum(pNew) );
diff --git a/src/python/pyabc.i b/src/python/pyabc.i
index 2b09a25..91c5287 100644
--- a/src/python/pyabc.i
+++ b/src/python/pyabc.i
@@ -744,15 +744,21 @@ void _set_death_signal();
 class _Cex(object):
 
     def __new__(cls, pCex):
+    
         if not pCex:
-            return None        
+            return None
+            
+        if int(pCex)==1:
+        	return True 
+        	      
         return object.__new__(cls)
 
     def __init__(self, pCex):
         self.pCex = pCex
         
     def __del__(self):
-        _cex_free(self.pCex)
+    	if _cex_free:
+        	_cex_free(self.pCex)
 
     def n_regs(self):
         return _cex_n_regs(self.pCex)
diff --git a/src/sat/bmc/bmc.h b/src/sat/bmc/bmc.h
index 8eb965b..f41503c 100644
--- a/src/sat/bmc/bmc.h
+++ b/src/sat/bmc/bmc.h
@@ -129,6 +129,7 @@ struct Bmc_ParFf_t_
     int        fComplVars;
     int        fStartPats;
     int        nTimeOut;
+    int        nIterCheck;
     int        fBasic;
     int        fDump;
     int        fDumpUntest;
diff --git a/src/sat/bmc/bmcBmc3.c b/src/sat/bmc/bmcBmc3.c
index c5cff74..ff45c45 100644
--- a/src/sat/bmc/bmcBmc3.c
+++ b/src/sat/bmc/bmcBmc3.c
@@ -1635,7 +1635,7 @@ nTimeSat += clkSatRun;
                     pCexNew0 = pCexNew; 
                     pCexNew = (Abc_Cex_t *)(ABC_PTRINT_T)1;
                 }
-                Vec_PtrWriteEntry( p->vCexes, i, pCexNew );
+                Vec_PtrWriteEntry( p->vCexes, i, Abc_CexDup(pCexNew, Saig_ManRegNum(pAig)) ); 
                 if ( pPars->pFuncOnFail && pPars->pFuncOnFail(i, pPars->fStoreCex ? (Abc_Cex_t *)Vec_PtrEntry(p->vCexes, i) : NULL) )
                 {
                     Abc_CexFreeP( &pCexNew0 );
diff --git a/src/sat/bmc/bmcCexTools.c b/src/sat/bmc/bmcCexTools.c
index b3340c3..191ab56 100644
--- a/src/sat/bmc/bmcCexTools.c
+++ b/src/sat/bmc/bmcCexTools.c
@@ -306,7 +306,7 @@ void Bmc_CexBuildNetworkTest( Gia_Man_t * p, Abc_Cex_t * pCex )
 ***********************************************************************/
 void Bmc_CexPrint( Abc_Cex_t * pCex, int nInputs, int fVerbose )
 {
-    int i, k, Count, iBit = 0;
+    int i, k, Count, iBit = pCex->nRegs;
     Abc_CexPrintStatsInputs( pCex, nInputs );
     if ( !fVerbose )
         return;
diff --git a/src/sat/bmc/bmcChain.c b/src/sat/bmc/bmcChain.c
new file mode 100644
index 0000000..a5117d9
--- /dev/null
+++ b/src/sat/bmc/bmcChain.c
@@ -0,0 +1,363 @@
+/**CFile****************************************************************
+
+  FileName    [bmcChain.c]
+
+  SystemName  [ABC: Logic synthesis and verification system.]
+
+  PackageName [SAT-based bounded model checking.]
+
+  Synopsis    [Implementation of chain BMC.]
+
+  Author      [Alan Mishchenko]
+  
+  Affiliation [UC Berkeley]
+
+  Date        [Ver. 1.0. Started - June 20, 2005.]
+
+  Revision    [$Id: bmcChain.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "bmc.h"
+#include "aig/gia/giaAig.h"
+#include "sat/cnf/cnf.h"
+#include "sat/bsat/satSolver.h"
+
+ABC_NAMESPACE_IMPL_START
+
+
+////////////////////////////////////////////////////////////////////////
+///                        DECLARATIONS                              ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+///                     FUNCTION DEFINITIONS                         ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+  Synopsis    [Find the first failure.]
+
+  Description []
+               
+  SideEffects []
+
+  SeeAlso     []
+
+***********************************************************************/
+Abc_Cex_t * Bmc_ChainFailOneOutput( Gia_Man_t * p, int nFrameMax, int nConfMax, int fVerbose, int fVeryVerbose )
+{
+    int RetValue;
+    Abc_Cex_t * pCex = NULL;
+    Aig_Man_t * pAig = Gia_ManToAigSimple( p );
+    Saig_ParBmc_t Pars, * pPars = &Pars;
+    Saig_ParBmcSetDefaultParams( pPars );
+    pPars->nFramesMax = nFrameMax;
+    pPars->nConfLimit = nConfMax;
+    pPars->fVerbose   = fVeryVerbose;
+    RetValue = Saig_ManBmcScalable( pAig, pPars );
+    if ( RetValue == 0 ) // SAT
+    {
+        pCex = pAig->pSeqModel, pAig->pSeqModel = NULL;
+        if ( fVeryVerbose )
+            Abc_Print( 1, "Output %d of miter \"%s\" was asserted in frame %d.\n", pCex->iPo, p->pName, pCex->iFrame );
+    }
+    else if ( fVeryVerbose )
+        Abc_Print( 1, "No output asserted in %d frames. Resource limit reached.\n", pPars->iFrame+2 );
+    Aig_ManStop( pAig );
+    return pCex;
+}
+
+/**Function*************************************************************
+
+  Synopsis    [Move GIA into the failing state.]
+
+  Description []
+               
+  SideEffects []
+
+  SeeAlso     []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManDupWithInit( Gia_Man_t * p )
+{
+    Gia_Man_t * pNew;
+    Gia_Obj_t * pObj;
+    int i;
+    pNew = Gia_ManStart( Gia_ManObjNum(p) );
+    pNew->pName = Abc_UtilStrsav( p->pName );
+    pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+    Gia_ManConst0(p)->Value = 0;
+    Gia_ManForEachObj1( p, pObj, i )
+    {
+        if ( Gia_ObjIsAnd(pObj) )
+            pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+        else if ( Gia_ObjIsCi(pObj) )
+        {
+            pObj->Value = Gia_ManAppendCi( pNew );
+            pObj->Value = Abc_LitNotCond( pObj->Value, pObj->fMark0 );
+        }
+        else if ( Gia_ObjIsCo(pObj) )
+        {
+            pObj->Value = Gia_ObjFanin0Copy(pObj);
+            pObj->Value = Abc_LitNotCond( pObj->Value, pObj->fMark0 );
+            pObj->Value = Gia_ManAppendCo( pNew, pObj->Value );
+        }
+    }
+    Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
+    return pNew;
+}
+Gia_Man_t * Gia_ManVerifyCexAndMove( Gia_Man_t * pGia, Abc_Cex_t * p )
+{
+    Gia_Man_t * pNew;
+    Gia_Obj_t * pObj, * pObjRi, * pObjRo;
+    int RetValue, i, k, iBit = 0;
+    Gia_ManCleanMark0(pGia);
+    Gia_ManForEachRo( pGia, pObj, i )
+        pObj->fMark0 = Abc_InfoHasBit(p->pData, iBit++);
+    for ( i = 0; i <= p->iFrame; i++ )
+    {
+        Gia_ManForEachPi( pGia, pObj, k )
+            pObj->fMark0 = Abc_InfoHasBit(p->pData, iBit++);
+        Gia_ManForEachAnd( pGia, pObj, k )
+            pObj->fMark0 = (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)) & 
+                           (Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj));
+        Gia_ManForEachCo( pGia, pObj, k )
+            pObj->fMark0 = Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj);
+        if ( i == p->iFrame )
+            break;
+        Gia_ManForEachRiRo( pGia, pObjRi, pObjRo, k )
+            pObjRo->fMark0 = pObjRi->fMark0;
+    }
+    assert( iBit == p->nBits );
+    RetValue = Gia_ManPo(pGia, p->iPo)->fMark0;
+    assert( RetValue );
+    // set PI/PO values to zero and transfer RO values to RI
+    Gia_ManForEachPi( pGia, pObj, k )
+        pObj->fMark0 = 0;
+    Gia_ManForEachPo( pGia, pObj, k )
+        pObj->fMark0 = 0;
+    Gia_ManForEachRiRo( pGia, pObjRi, pObjRo, k )
+        pObjRi->fMark0 = pObjRo->fMark0;
+    // duplicate assuming CI/CO marks are set correctly
+    pNew = Gia_ManDupWithInit( pGia );
+    Gia_ManCleanMark0(pGia);
+    return pNew;
+}
+
+/**Function*************************************************************
+
+  Synopsis    [Find what outputs fail in this state.]
+
+  Description []
+               
+  SideEffects []
+
+  SeeAlso     []
+
+***********************************************************************/
+Gia_Man_t * Gia_ManDupPosAndPropagateInit( Gia_Man_t * p )
+{
+    Gia_Man_t * pNew, * pTemp;
+    Gia_Obj_t * pObj;  int i;
+    pNew = Gia_ManStart( Gia_ManObjNum(p) );
+    pNew->pName = Abc_UtilStrsav( p->pName );
+    pNew->pSpec = Abc_UtilStrsav( p->pSpec );
+    Gia_ManConst0(p)->Value = 0;
+    Gia_ManHashAlloc( pNew );
+    Gia_ManForEachObj1( p, pObj, i )
+    {
+        if ( Gia_ObjIsAnd(pObj) )
+            pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
+        else if ( Gia_ObjIsPi(p, pObj) )
+            pObj->Value = Gia_ManAppendCi( pNew );
+        else if ( Gia_ObjIsCi(pObj) )
+            pObj->Value = 0;
+        else if ( Gia_ObjIsPo(p, pObj) )
+            Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
+    }
+    Gia_ManHashStop( pNew );
+    assert( Gia_ManPiNum(p) == Gia_ManPiNum(pNew) );
+    assert( Gia_ManPoNum(p) == Gia_ManPoNum(pNew) );
+    pNew = Gia_ManCleanup( pTemp = pNew );
+    Gia_ManStop( pTemp );
+    return pNew;
+}
+sat_solver * Gia_ManDeriveSatSolver( Gia_Man_t * p )
+{
+//    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 = Cnf_Derive( pAig, Aig_ManCoNum(pAig) );
+    Aig_ManStop( pAig );
+//    Cnf_Dat_t * pCnf = Mf_ManGenerateCnf( p, 8, 0, 0, 0 );
+    pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 );
+    Cnf_DataFree( pCnf );
+    assert( p->nRegs == 0 );
+    return pSat;
+}
+Vec_Int_t * Bmc_ChainFindFailedOutputs( Gia_Man_t * p )
+{
+    Vec_Int_t * vOutputs;
+    Gia_Man_t * pInit;
+    Gia_Obj_t * pObj;
+    sat_solver * pSat;
+    int i, Lit, status = 0;
+    // derive output logic cones
+    pInit = Gia_ManDupPosAndPropagateInit( p );
+    // derive SAT solver and test
+    pSat = Gia_ManDeriveSatSolver( pInit );
+    vOutputs = Vec_IntAlloc( 100 );
+    Gia_ManForEachPo( pInit, pObj, i )
+    {
+        if ( Gia_ObjFaninLit0p(pInit, pObj) == 0 )
+            continue;
+        Lit = Abc_Var2Lit( i+1, 0 );
+        status = sat_solver_solve( pSat, &Lit, &Lit + 1, 0, 0, 0, 0 );
+        if ( status == l_True )
+            Vec_IntPush( vOutputs, i );
+    }
+    Gia_ManStop( pInit );
+    sat_solver_delete( pSat );
+    return vOutputs;
+}
+
+/**Function*************************************************************
+
+  Synopsis    [Cleanup AIG by removing COs replacing failed out by const0.]
+
+  Description []
+               
+  SideEffects []
+
+  SeeAlso     []
+
+***********************************************************************/
+static inline void Gia_ObjMakePoConst0( Gia_Man_t * p, Gia_Obj_t * pObj )
+{ 
+    assert( Gia_ObjIsCo(pObj) );
+    pObj->iDiff0 = Gia_ObjId( p, pObj );
+    pObj->fCompl0 = 0;
+}
+int Gia_ManCountNonConst0( Gia_Man_t * p )
+{ 
+    Gia_Obj_t * pObj;
+    int i, Count = 0;
+    Gia_ManForEachPo( p, pObj, i )
+        Count += (Gia_ObjFaninLit0p(p, pObj) != 0);
+    return Count;
+}
+Gia_Man_t * Bmc_ChainCleanup( Gia_Man_t * p, Vec_Int_t * vOutputs )
+{
+    int i, iOut;
+    Vec_IntForEachEntry( vOutputs, iOut, i )
+    {
+        Gia_Obj_t * pObj = Gia_ManPo( p, iOut );
+        assert( Gia_ObjFaninLit0p(p, pObj) != 0 );
+        Gia_ObjMakePoConst0( p, pObj );
+        assert( Gia_ObjFaninLit0p(p, pObj) == 0 );
+    }
+    return Gia_ManCleanup( p );
+}
+
+/**Function*************************************************************
+
+  Synopsis    []
+
+  Description []
+               
+  SideEffects []
+
+  SeeAlso     []
+
+***********************************************************************/
+int Bmc_ChainTest( Gia_Man_t * p, int nFrameMax, int nConfMax, int fVerbose, int fVeryVerbose )
+{
+    int Iter, IterMax = 10000;
+    Gia_Man_t * pTemp, * pNew = Gia_ManDup(p);
+    Abc_Cex_t * pCex = NULL;
+    Vec_Int_t * vOutputs;
+    abctime clk2, clk = Abc_Clock(); 
+    abctime clkBmc = 0;
+    abctime clkMov = 0;
+    abctime clkSat = 0;
+    abctime clkCln = 0;
+    abctime clkSwp = 0;
+    int DepthTotal = 0;
+    for ( Iter = 0; Iter < IterMax; Iter++ )
+    {
+        if ( Gia_ManPoNum(pNew) == 0 )
+        {
+            if ( fVerbose )
+                printf( "Finished all POs.\n" );
+            break;
+        }
+        // run BMC till the first failure
+        clk2 = Abc_Clock(); 
+        pCex = Bmc_ChainFailOneOutput( pNew, nFrameMax, nConfMax, fVerbose, fVeryVerbose );
+        clkBmc += Abc_Clock() - clk2;
+        if ( pCex == NULL )
+        {
+            if ( fVerbose )
+                printf( "BMC could not detect a failed output in %d frames with %d conflicts.\n", nFrameMax, nConfMax );
+            break;
+        }
+        assert( !Iter || pCex->iFrame > 0 );
+        // move the AIG to the failure state
+        clk2 = Abc_Clock(); 
+        pNew = Gia_ManVerifyCexAndMove( pTemp = pNew, pCex );
+        Gia_ManStop( pTemp );
+        DepthTotal += pCex->iFrame;
+        clkMov += Abc_Clock() - clk2;
+        // find outputs that fail in this state
+        clk2 = Abc_Clock(); 
+        vOutputs = Bmc_ChainFindFailedOutputs( pNew );
+        assert( Vec_IntFind(vOutputs, pCex->iPo) >= 0 );
+        Abc_CexFree( pCex );
+        clkSat += Abc_Clock() - clk2;
+        // remove them from the AIG 
+        clk2 = Abc_Clock(); 
+        pNew = Bmc_ChainCleanup( pTemp = pNew, vOutputs );
+        Gia_ManStop( pTemp );
+        clkCln += Abc_Clock() - clk2;
+        // perform sequential cleanup
+        clk2 = Abc_Clock(); 
+//        pNew = Gia_ManSeqStructSweep( pTemp = pNew, 0, 1, 0 );
+//        Gia_ManStop( pTemp );
+        clkSwp += Abc_Clock() - clk2;
+        // printout
+        if ( fVerbose )
+        {
+            int nNonConst = Gia_ManCountNonConst0(pNew);
+            printf( "Iter %4d : ",    Iter+1 );
+            printf( "Depth =%5d  ",   DepthTotal );
+            printf( "FailPo =%5d  ",  Vec_IntSize(vOutputs) );
+            printf( "UndecPo =%5d ",  nNonConst );
+            printf( "(%6.2f %%)  ",   100.0 * nNonConst / Gia_ManPoNum(pNew) );
+            printf( "AIG =%8d  ",     Gia_ManAndNum(pNew) );
+            Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+        }
+        Vec_IntFree( vOutputs );
+    }
+    printf( "Completed a CEX chain with %d segments, %d frames, and %d failed POs (out of %d). ", 
+        Iter, DepthTotal, Gia_ManPoNum(pNew) - Gia_ManCountNonConst0(pNew), Gia_ManPoNum(pNew) );
+    if ( fVerbose )
+    {
+    Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+    Abc_PrintTimeP( 1, "BMC  ", clkBmc, Abc_Clock() - clk );
+    Abc_PrintTimeP( 1, "Init ", clkMov, Abc_Clock() - clk );
+    Abc_PrintTimeP( 1, "SAT  ", clkSat, Abc_Clock() - clk );
+    Abc_PrintTimeP( 1, "Clean", clkCln, Abc_Clock() - clk );
+//    Abc_PrintTimeP( 1, "Sweep", clkSwp, Abc_Clock() - clk );
+    }
+    Gia_ManStop( pNew );
+    return 0;
+}
+
+////////////////////////////////////////////////////////////////////////
+///                       END OF FILE                                ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+
diff --git a/src/sat/bmc/bmcFault.c b/src/sat/bmc/bmcFault.c
index ee2d33c..4582083 100644
--- a/src/sat/bmc/bmcFault.c
+++ b/src/sat/bmc/bmcFault.c
@@ -55,6 +55,7 @@ void Gia_ParFfSetDefault( Bmc_ParFf_t * p )
     p->Algo          =     0; 
     p->fStartPats    =     0; 
     p->nTimeOut      =     0; 
+    p->nIterCheck    =     0;
     p->fBasic        =     0; 
     p->fDump         =     0; 
     p->fDumpUntest   =     0; 
@@ -228,11 +229,11 @@ Gia_Man_t * Gia_ManFaultUnfold( Gia_Man_t * p, int fUseMuxes )
   SeeAlso     []
 
 ***********************************************************************/
-Gia_Man_t * Gia_ManStuckAtUnfold( Gia_Man_t * p )
+Gia_Man_t * Gia_ManStuckAtUnfold( Gia_Man_t * p, Vec_Int_t * vMap )
 {
     Gia_Man_t * pNew, * pTemp;
     Gia_Obj_t * pObj;
-    int i;
+    int i, iFuncVars = 0;
     pNew = Gia_ManStart( 3 * Gia_ManObjNum(p) );
     pNew->pName = Abc_UtilStrsav( p->pName );
     Gia_ManHashAlloc( pNew );
@@ -242,9 +243,18 @@ Gia_Man_t * Gia_ManStuckAtUnfold( Gia_Man_t * p )
     Gia_ManForEachAnd( p, pObj, i )
     {
         pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
-        pObj->Value = Gia_ManHashAnd( pNew, Abc_LitNot(Gia_ManAppendCi(pNew)), pObj->Value );
-        pObj->Value = Gia_ManHashOr( pNew, Gia_ManAppendCi(pNew), pObj->Value );
+
+        if ( Vec_IntEntry(vMap, iFuncVars++) )
+            pObj->Value = Gia_ManHashAnd( pNew, Abc_LitNot(Gia_ManAppendCi(pNew)), pObj->Value );
+        else
+            Gia_ManAppendCi(pNew);
+
+        if ( Vec_IntEntry(vMap, iFuncVars++) )
+            pObj->Value = Gia_ManHashOr( pNew, Gia_ManAppendCi(pNew), pObj->Value );
+        else
+            Gia_ManAppendCi(pNew);
     }
+    assert( iFuncVars == Vec_IntSize(vMap) );
     Gia_ManForEachCo( p, pObj, i )
         pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
     pNew = Gia_ManCleanup( pTemp = pNew );
@@ -264,11 +274,11 @@ Gia_Man_t * Gia_ManStuckAtUnfold( Gia_Man_t * p )
   SeeAlso     []
 
 ***********************************************************************/
-Gia_Man_t * Gia_ManFlipUnfold( Gia_Man_t * p )
+Gia_Man_t * Gia_ManFlipUnfold( Gia_Man_t * p, Vec_Int_t * vMap )
 {
     Gia_Man_t * pNew, * pTemp;
     Gia_Obj_t * pObj;
-    int i;
+    int i, iFuncVars = 0;
     pNew = Gia_ManStart( 4 * Gia_ManObjNum(p) );
     pNew->pName = Abc_UtilStrsav( p->pName );
     Gia_ManHashAlloc( pNew );
@@ -278,8 +288,12 @@ Gia_Man_t * Gia_ManFlipUnfold( Gia_Man_t * p )
     Gia_ManForEachAnd( p, pObj, i )
     {
         pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
-        pObj->Value = Gia_ManHashXor( pNew, Gia_ManAppendCi(pNew), pObj->Value );
+        if ( Vec_IntEntry(vMap, iFuncVars++) )
+            pObj->Value = Gia_ManHashXor( pNew, Gia_ManAppendCi(pNew), pObj->Value );
+        else
+            Gia_ManAppendCi(pNew);
     }
+    assert( iFuncVars == Vec_IntSize(vMap) );
     Gia_ManForEachCo( p, pObj, i )
         pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
     pNew = Gia_ManCleanup( pTemp = pNew );
@@ -299,11 +313,11 @@ Gia_Man_t * Gia_ManFlipUnfold( Gia_Man_t * p )
   SeeAlso     []
 
 ***********************************************************************/
-Gia_Man_t * Gia_ManFOFUnfold( Gia_Man_t * p )
+Gia_Man_t * Gia_ManFOFUnfold( Gia_Man_t * p, Vec_Int_t * vMap )
 {
     Gia_Man_t * pNew, * pTemp;
     Gia_Obj_t * pObj;
-    int i, iCtrl0, iCtrl1, iCtrl2, iCtrl3, iMuxA, iMuxB;
+    int i, iCtrl0, iCtrl1, iCtrl2, iCtrl3, iMuxA, iMuxB, iFuncVars = 0;
     pNew = Gia_ManStart( 9 * Gia_ManObjNum(p) );
     pNew->pName = Abc_UtilStrsav( p->pName );
     Gia_ManHashAlloc( pNew );
@@ -312,10 +326,26 @@ Gia_Man_t * Gia_ManFOFUnfold( Gia_Man_t * p )
         pObj->Value = Gia_ManAppendCi( pNew );
     Gia_ManForEachAnd( p, pObj, i )
     {
-        iCtrl0 = Gia_ManAppendCi(pNew);
-        iCtrl1 = Gia_ManAppendCi(pNew);
-        iCtrl2 = Gia_ManAppendCi(pNew);
-        iCtrl3 = Gia_ManAppendCi(pNew);
+        if ( Vec_IntEntry(vMap, iFuncVars++) )
+            iCtrl0 = Gia_ManAppendCi(pNew);
+        else
+            iCtrl0 = 0, Gia_ManAppendCi(pNew);
+
+        if ( Vec_IntEntry(vMap, iFuncVars++) )
+            iCtrl1 = Gia_ManAppendCi(pNew);
+        else
+            iCtrl1 = 0, Gia_ManAppendCi(pNew);
+
+        if ( Vec_IntEntry(vMap, iFuncVars++) )
+            iCtrl2 = Gia_ManAppendCi(pNew);
+        else
+            iCtrl2 = 0, Gia_ManAppendCi(pNew);
+
+        if ( Vec_IntEntry(vMap, iFuncVars++) )
+            iCtrl3 = Gia_ManAppendCi(pNew);
+        else
+            iCtrl3 = 0, Gia_ManAppendCi(pNew);
+
         if ( Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) )
             iCtrl0 = Abc_LitNot(iCtrl0);
         else if ( !Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) )
@@ -324,10 +354,12 @@ Gia_Man_t * Gia_ManFOFUnfold( Gia_Man_t * p )
             iCtrl2 = Abc_LitNot(iCtrl2);
         else //if ( !Gia_ObjFaninC0(pObj) && !Gia_ObjFaninC1(pObj) )
             iCtrl3 = Abc_LitNot(iCtrl3);
+
         iMuxA       = Gia_ManHashMux( pNew, Gia_ObjFanin0(pObj)->Value, iCtrl1, iCtrl0 );
         iMuxB       = Gia_ManHashMux( pNew, Gia_ObjFanin0(pObj)->Value, iCtrl3, iCtrl2 );
         pObj->Value = Gia_ManHashMux( pNew, Gia_ObjFanin1(pObj)->Value, iMuxB,  iMuxA );
     }
+    assert( iFuncVars == Vec_IntSize(vMap) );
     Gia_ManForEachCo( p, pObj, i )
         pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
     pNew = Gia_ManCleanup( pTemp = pNew );
@@ -802,61 +834,71 @@ Gia_Man_t * Gia_ManDeriveDup( Gia_Man_t * p, int nPisNew )
   SeeAlso     []
 
 ***********************************************************************/
-void Gia_ManFaultTest( Gia_Man_t * p, Gia_Man_t * pG, Bmc_ParFf_t * pPars )
+int Gia_ManFaultAnalyze( sat_solver * pSat, Vec_Int_t * vPars, Vec_Int_t * vMap, Vec_Int_t * vLits, int Iter )
+{
+    int nConfLimit = 100;
+    int status, i, v, iVar, Lit;
+    int nUnsats = 0, nRuns = 0;
+    abctime clk = Abc_Clock();
+    assert( Vec_IntSize(vPars) == Vec_IntSize(vMap) );
+    // check presence of each variable
+    Vec_IntClear( vLits );
+    Vec_IntAppend( vLits, vMap );
+    for ( v = 0; v < Vec_IntSize(vPars); v++ )
+    {
+        if ( !Vec_IntEntry(vLits, v) )
+            continue;
+        assert( Vec_IntEntry(vLits, v) == 1 );
+        nRuns++;
+        Lit = Abc_Var2Lit( Vec_IntEntry(vPars, v), 0 );
+        status = sat_solver_solve( pSat, &Lit, &Lit+1, (ABC_INT64_T)nConfLimit, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 );
+        if ( status == l_Undef )
+            continue;
+        if ( status == l_False )
+        {
+            nUnsats++;
+            assert( Vec_IntEntry(vMap, v) == 1 );
+            Vec_IntWriteEntry( vMap, v, 0 );
+            Lit = Abc_LitNot(Lit);
+            //status = sat_solver_addclause( pSat, &Lit, &Lit+1 );
+            //assert( status );
+            continue;
+        }
+        Vec_IntForEachEntry( vPars, iVar, i )
+            if ( Vec_IntEntry(vLits, i) && sat_solver_var_value(pSat, iVar) )
+                Vec_IntWriteEntry( vLits, i, 0 );
+        assert( Vec_IntEntry(vLits, v) == 0 );
+    }
+    printf( "Iteration %3d has determined %5d (out of %5d) parameters after %6d SAT calls.  ", Iter, Vec_IntSize(vMap) - Vec_IntCountPositive(vMap), Vec_IntSize(vPars), nRuns );
+    Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
+    return nUnsats;
+}
+
+/**Function*************************************************************
+
+  Synopsis    [Generate miter, CNF and solver.]
+
+  Description []
+               
+  SideEffects []
+
+  SeeAlso     []
+
+***********************************************************************/
+int Gia_ManFaultPrepare( Gia_Man_t * p, Gia_Man_t * pG, Bmc_ParFf_t * pPars, int nFuncVars, Vec_Int_t * vMap, Vec_Int_t * vTests, Vec_Int_t * vLits, Gia_Man_t ** ppMiter, Cnf_Dat_t ** ppCnf, sat_solver ** ppSat, int fWarmUp )
 {
-    int nIterMax = 1000000, nVars, nPars;
-    int i, Iter, Iter2, status, nFuncVars = -1;
-    abctime clkSat = 0, clkTotal = Abc_Clock();
-    Vec_Int_t * vLits, * vTests;
     Gia_Man_t * p0 = NULL, * p1 = NULL, * pM;
     Gia_Obj_t * pObj;
     Cnf_Dat_t * pCnf;
     sat_solver * pSat;
+    int i, Iter, status;
+    abctime clkSat = 0;
 
-    if ( pPars->Algo == 0 && Gia_FormStrCount( pPars->pFormStr, &nVars, &nPars ) )
-        return;
-
-    // select algorithm
-    if ( pPars->Algo == 0 )
-        printf( "FFTEST is computing test patterns for fault model \"%s\"...\n", pPars->pFormStr );
-    else if ( pPars->Algo == 1 )
-        printf( "FFTEST is computing test patterns for %sdelay faults...\n", pPars->fBasic ? "single " : "" );
-    else if ( pPars->Algo == 2 )
-        printf( "FFTEST is computing test patterns for %sstuck-at faults...\n", pPars->fBasic ? "single " : "" );
-    else if ( pPars->Algo == 3 )
-        printf( "FFTEST is computing test patterns for %scomplement faults...\n", pPars->fBasic ? "single " : "" );
-    else if ( pPars->Algo == 4 )
-        printf( "FFTEST is computing test patterns for %sfunctionally observable faults...\n", pPars->fBasic ? "single " : "" );
-    else
-    {
-        printf( "Unrecognized algorithm (%d).\n", pPars->Algo );
-        return;
-    }
-
-    // select algorithm
-    if ( pPars->Algo == 0 )
-        nFuncVars = Gia_ManCiNum(p);
-    else if ( pPars->Algo == 1 )
-        nFuncVars = Gia_ManRegNum(p) + 2 * Gia_ManPiNum(p);
-    else if ( pPars->Algo == 2 )
-        nFuncVars = Gia_ManCiNum(p);
-    else if ( pPars->Algo == 3 )
-        nFuncVars = Gia_ManCiNum(p);
-    else if ( pPars->Algo == 4 )
-        nFuncVars = Gia_ManCiNum(p);
-
-    // collect test patterns from file
-    if ( pPars->pFileName )
-        vTests = Gia_ManGetTestPatterns( pPars->pFileName );
-    else
-        vTests = Vec_IntAlloc( 10000 );
-    if ( vTests == NULL )
-        return;
-    if ( Vec_IntSize(vTests) % nFuncVars != 0 )
+    if ( Vec_IntSize(vTests) && (Vec_IntSize(vTests) % nFuncVars != 0) )
     {
         printf( "The number of symbols in the input patterns (%d) does not divide evenly on the number of test variables (%d).\n", Vec_IntSize(vTests), nFuncVars );
         Vec_IntFree( vTests );
-        return;
+        return 0;
     }
 
     // select algorithm
@@ -869,11 +911,11 @@ void Gia_ManFaultTest( Gia_Man_t * p, Gia_Man_t * pG, Bmc_ParFf_t * pPars )
         p1 = Gia_ManFaultUnfold( p, 1 );
     }
     else if ( pPars->Algo == 2 )
-        p1 = Gia_ManStuckAtUnfold( p );
+        p1 = Gia_ManStuckAtUnfold( p, vMap );
     else if ( pPars->Algo == 3 )
-        p1 = Gia_ManFlipUnfold( p );
+        p1 = Gia_ManFlipUnfold( p, vMap );
     else if ( pPars->Algo == 4 )
-        p1 = Gia_ManFOFUnfold( p );
+        p1 = Gia_ManFOFUnfold( p, vMap );
     if ( pPars->Algo != 1 )
         p0 = Gia_ManDeriveDup( pG, Gia_ManCiNum(p1) - Gia_ManCiNum(pG) );
 //    Gia_AigerWrite( p1, "newfault.aig", 0, 0 );
@@ -895,7 +937,7 @@ void Gia_ManFaultTest( Gia_Man_t * p, Gia_Man_t * pG, Bmc_ParFf_t * pPars )
             assert( 0 );
 
     // add one large OR clause
-    vLits = Vec_IntAlloc( Gia_ManCoNum(p) );
+    Vec_IntClear( vLits );
     Gia_ManForEachCo( pM, pObj, i )
         Vec_IntPush( vLits, Abc_Var2Lit(pCnf->pVarNums[Gia_ObjId(pM, pObj)], 0) );
     sat_solver_addclause( pSat, Vec_IntArray(vLits), Vec_IntArray(vLits) + Vec_IntSize(vLits) );
@@ -915,25 +957,31 @@ void Gia_ManFaultTest( Gia_Man_t * p, Gia_Man_t * pG, Bmc_ParFf_t * pPars )
     {
         int nTests = Vec_IntSize(vTests) / nFuncVars;
         assert( Vec_IntSize(vTests) % nFuncVars == 0 );
-        printf( "Reading %d pre-computed test patterns from file \"%s\".\n", Vec_IntSize(vTests) / nFuncVars, pPars->pFileName );
+        if ( pPars->pFileName )
+            printf( "Reading %d pre-computed test patterns from file \"%s\".\n", Vec_IntSize(vTests) / nFuncVars, pPars->pFileName );
+        else
+            printf( "Reading %d pre-computed test patterns from previous rounds.\n", Vec_IntSize(vTests) / nFuncVars );
         for ( Iter = 0; Iter < nTests; Iter++ )
         {
-            abctime clk = Abc_Clock();
-            status = sat_solver_solve( pSat, NULL, NULL, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 );
-            clkSat += Abc_Clock() - clk;
-            if ( status == l_Undef )
+            if ( fWarmUp )
             {
-                if ( pPars->fVerbose )
-                    printf( "\n" );
-                printf( "Timeout reached after %d seconds and adding %d tests.\n", pPars->nTimeOut, Iter );
-                goto finish;
-            }
-            if ( status == l_False )
-            {
-                if ( pPars->fVerbose )
-                    printf( "\n" );
-                printf( "The problem is UNSAT after adding %d tests.\n", Iter );
-                goto finish;
+                abctime clk = Abc_Clock();
+                status = sat_solver_solve( pSat, NULL, NULL, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 );
+                clkSat += Abc_Clock() - clk;
+                if ( status == l_Undef )
+                {
+                    if ( pPars->fVerbose )
+                        printf( "\n" );
+                    printf( "Timeout reached after %d seconds and adding %d tests.\n", pPars->nTimeOut, Iter );
+                    return 0;
+                }
+                if ( status == l_False )
+                {
+                    if ( pPars->fVerbose )
+                        printf( "\n" );
+                    printf( "The problem is UNSAT after adding %d tests.\n", Iter );
+                    return 0;
+                }
             }
             // get pattern
             Vec_IntClear( vLits );
@@ -961,14 +1009,14 @@ void Gia_ManFaultTest( Gia_Man_t * p, Gia_Man_t * pG, Bmc_ParFf_t * pPars )
                 if ( pPars->fVerbose )
                     printf( "\n" );
                 printf( "Timeout reached after %d seconds and %d iterations.\n", pPars->nTimeOut, Iter );
-                goto finish;
+                return 0;
             }
             if ( status == l_False )
             {
                 if ( pPars->fVerbose )
                     printf( "\n" );
                 printf( "The problem is UNSAT after %d iterations.\n", Iter );
-                goto finish;
+                return 0;
             }
             // initialize simple pattern
             Vec_IntFill( vLits, nFuncVars, Iter );
@@ -977,10 +1025,120 @@ void Gia_ManFaultTest( Gia_Man_t * p, Gia_Man_t * pG, Bmc_ParFf_t * pPars )
         }
     }
 
+    printf( "Using miter with:  AIG nodes = %6d.  CNF variables = %6d.  CNF clauses = %8d.\n", Gia_ManAndNum(pM), pCnf->nVars, pCnf->nClauses );
+
+    *ppMiter = pM;
+    *ppCnf = pCnf;
+    *ppSat = pSat;
+    return 1;
+}
+
+/**Function*************************************************************
+
+  Synopsis    []
+
+  Description []
+               
+  SideEffects []
+
+  SeeAlso     []
+
+***********************************************************************/
+void Gia_ManFaultTest( Gia_Man_t * p, Gia_Man_t * pG, Bmc_ParFf_t * pPars )
+{
+    int nIterMax = 1000000, nVars, nPars;
+    int i, Iter, Iter2, status, nFuncVars = -1;
+    abctime clk, clkSat = 0, clkTotal = Abc_Clock();
+    Vec_Int_t * vLits, * vMap = NULL, * vTests, * vPars = NULL;
+    Gia_Man_t * pM;
+    Gia_Obj_t * pObj;
+    Cnf_Dat_t * pCnf;
+    sat_solver * pSat;
+
+    if ( pPars->Algo == 0 && Gia_FormStrCount( pPars->pFormStr, &nVars, &nPars ) )
+        return;
+
+    // select algorithm
+    if ( pPars->Algo == 0 )
+        printf( "FFTEST is computing test patterns for fault model \"%s\"...\n", pPars->pFormStr );
+    else if ( pPars->Algo == 1 )
+        printf( "FFTEST is computing test patterns for %sdelay faults...\n", pPars->fBasic ? "single " : "" );
+    else if ( pPars->Algo == 2 )
+        printf( "FFTEST is computing test patterns for %sstuck-at faults...\n", pPars->fBasic ? "single " : "" );
+    else if ( pPars->Algo == 3 )
+        printf( "FFTEST is computing test patterns for %scomplement faults...\n", pPars->fBasic ? "single " : "" );
+    else if ( pPars->Algo == 4 )
+        printf( "FFTEST is computing test patterns for %sfunctionally observable faults...\n", pPars->fBasic ? "single " : "" );
+    else
+    {
+        printf( "Unrecognized algorithm (%d).\n", pPars->Algo );
+        return;
+    }
+
+    // select algorithm
+    if ( pPars->Algo == 0 )
+        nFuncVars = Gia_ManCiNum(p);
+    else if ( pPars->Algo == 1 )
+        nFuncVars = Gia_ManRegNum(p) + 2 * Gia_ManPiNum(p);
+    else if ( pPars->Algo == 2 )
+        nFuncVars = Gia_ManCiNum(p);
+    else if ( pPars->Algo == 3 )
+        nFuncVars = Gia_ManCiNum(p);
+    else if ( pPars->Algo == 4 )
+        nFuncVars = Gia_ManCiNum(p);
+
+    // collect test patterns from file
+    if ( pPars->pFileName )
+        vTests = Gia_ManGetTestPatterns( pPars->pFileName );
+    else
+        vTests = Vec_IntAlloc( 10000 );
+    if ( vTests == NULL )
+        return;
+
+    // select algorithm
+    vMap = Vec_IntAlloc( 0 );
+    if ( pPars->Algo == 2 )
+        Vec_IntFill( vMap, 2 * Gia_ManAndNum(p), 1 );
+    else if ( pPars->Algo == 3 )
+        Vec_IntFill( vMap,     Gia_ManAndNum(p), 1 );
+    else if ( pPars->Algo == 4 )
+        Vec_IntFill( vMap, 4 * Gia_ManAndNum(p), 1 );
+
+    // prepare SAT solver
+    vLits = Vec_IntAlloc( Gia_ManCoNum(p) );
+    if ( !Gia_ManFaultPrepare(p, pG, pPars, nFuncVars, vMap, vTests, vLits, &pM, &pCnf, &pSat, 1) )
+        return;
+
     // iterate through the test vectors
     for ( Iter = pPars->fStartPats ? 2 : Vec_IntSize(vTests) / nFuncVars; Iter < nIterMax; Iter++ )
     {
-        abctime clk = Abc_Clock();
+        // collect parameter variables
+        if ( pPars->nIterCheck && vPars == NULL )
+        {
+            vPars = Vec_IntAlloc( Gia_ManPiNum(pM) - nFuncVars );
+            Gia_ManForEachPi( pM, pObj, i )
+                if ( i >= nFuncVars )
+                    Vec_IntPush( vPars, pCnf->pVarNums[Gia_ObjId(pM, pObj)] );
+            assert( Vec_IntSize(vPars) == Gia_ManPiNum(pM) - nFuncVars );
+        }
+        // derive unit parameter variables
+        if ( Iter && pPars->nIterCheck && (Iter % pPars->nIterCheck) == 0 )
+        {
+            Gia_ManFaultAnalyze( pSat, vPars, vMap, vLits, Iter );
+            // cleanup
+            Gia_ManStop( pM );
+            Cnf_DataFree( pCnf );
+            sat_solver_delete( pSat );
+            // recompute
+            if ( !Gia_ManFaultPrepare(p, pG, pPars, nFuncVars, vMap, vTests, vLits, &pM, &pCnf, &pSat, 0) )
+            {
+                printf( "This should never happen.\n" );
+                return;
+            }
+            Vec_IntFreeP( &vPars );
+        }
+        // solve
+        clk = Abc_Clock();
         status = sat_solver_solve( pSat, NULL, NULL, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0, (ABC_INT64_T)0 );
         clkSat += Abc_Clock() - clk;
         if ( pPars->fVerbose )
@@ -1141,7 +1299,9 @@ finish:
     Cnf_DataFree( pCnf );
     Gia_ManStop( pM );
     Vec_IntFree( vTests );
+    Vec_IntFree( vMap );
     Vec_IntFree( vLits );
+    Vec_IntFreeP( &vPars );
 }
 
 
diff --git a/src/sat/bmc/module.make b/src/sat/bmc/module.make
index 2d45e18..830b05e 100644
--- a/src/sat/bmc/module.make
+++ b/src/sat/bmc/module.make
@@ -10,6 +10,7 @@ SRC +=	src/sat/bmc/bmcBCore.c \
 	src/sat/bmc/bmcCexMin1.c \
 	src/sat/bmc/bmcCexMin2.c \
 	src/sat/bmc/bmcCexTools.c \
+	src/sat/bmc/bmcChain.c \
 	src/sat/bmc/bmcEco.c \
 	src/sat/bmc/bmcFault.c \
 	src/sat/bmc/bmcICheck.c \
diff --git a/src/sat/bsat/satSolver.h b/src/sat/bsat/satSolver.h
index aa9ad7e..714a0cd 100644
--- a/src/sat/bsat/satSolver.h
+++ b/src/sat/bsat/satSolver.h
@@ -211,8 +211,8 @@ static void sat_solver_act_var_clear(sat_solver* s)
 {
     int i;
     for (i = 0; i < s->size; i++)
-        s->activity[i] = 0.0;
-    s->var_inc = 1.0;
+        s->activity[i] = 0;
+    s->var_inc = 1;
 }
 static void sat_solver_compress(sat_solver* s) 
 {
diff --git a/src/sat/bsat2/AbcApi.cpp b/src/sat/bsat2/AbcApi.cpp
new file mode 100644
index 0000000..5c6f133
--- /dev/null
+++ b/src/sat/bsat2/AbcApi.cpp
@@ -0,0 +1,59 @@
+/**CFile****************************************************************
+
+  FileName    [AbcApi.cpp]
+
+  PackageName [A C++ version of SAT solver MiniSAT 2.2 developed 
+  by Niklas Sorensson and Niklas Een. http://minisat.se.]
+
+  Synopsis    [Interface to the SAT solver.]
+
+  Author      [Niklas Sorensson and Niklas Een.]
+  
+  Affiliation [UC Berkeley]
+
+  Date        [Ver. 1.0. Started - January 1, 2004.]
+
+  Revision    [$Id: AbcApi.cpp,v 1.0 2004/01/01 1:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "Solver.h"
+#include "sat/cnf/cnf.h"
+
+ABC_NAMESPACE_IMPL_START
+
+using namespace Minisat;
+
+////////////////////////////////////////////////////////////////////////
+///                        DECLARATIONS                              ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+///                     FUNCTION DEFINITIONS                         ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+  Synopsis    []
+
+  Description []
+               
+  SideEffects []
+
+  SeeAlso     []
+
+***********************************************************************/
+int Abc_CallMiniSat22( Cnf_Dat_t * p )
+{
+    Solver S;
+    int Result = -1;
+    return Result;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+///                       END OF FILE                                ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
diff --git a/src/sat/bsat2/Alg.h b/src/sat/bsat2/Alg.h
new file mode 100644
index 0000000..3e0745f
--- /dev/null
+++ b/src/sat/bsat2/Alg.h
@@ -0,0 +1,84 @@
+/*******************************************************************************************[Alg.h]
+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.
+**************************************************************************************************/
+
+#ifndef Minisat_Alg_h
+#define Minisat_Alg_h
+
+#include "Vec.h"
+
+namespace Minisat {
+
+//=================================================================================================
+// Useful functions on vector-like types:
+
+//=================================================================================================
+// Removing and searching for elements:
+//
+
+template<class V, class T>
+static inline void remove(V& ts, const T& t)
+{
+    int j = 0;
+    for (; j < ts.size() && ts[j] != t; j++);
+    assert(j < ts.size());
+    for (; j < ts.size()-1; j++) ts[j] = ts[j+1];
+    ts.pop();
+}
+
+
+template<class V, class T>
+static inline bool find(V& ts, const T& t)
+{
+    int j = 0;
+    for (; j < ts.size() && ts[j] != t; j++);
+    return j < ts.size();
+}
+
+
+//=================================================================================================
+// Copying vectors with support for nested vector types:
+//
+
+// Base case:
+template<class T>
+static inline void copy(const T& from, T& to)
+{
+    to = from;
+}
+
+// Recursive case:
+template<class T>
+static inline void copy(const vec<T>& from, vec<T>& to, bool append = false)
+{
+    if (!append)
+        to.clear();
+    for (int i = 0; i < from.size(); i++){
+        to.push();
+        copy(from[i], to.last());
+    }
+}
+
+template<class T>
+static inline void append(const vec<T>& from, vec<T>& to){ copy(from, to, true); }
+
+//=================================================================================================
+}
+
+#endif
diff --git a/src/sat/bsat2/Alloc.h b/src/sat/bsat2/Alloc.h
new file mode 100644
index 0000000..7f506cb
--- /dev/null
+++ b/src/sat/bsat2/Alloc.h
@@ -0,0 +1,131 @@
+/*****************************************************************************************[Alloc.h]
+Copyright (c) 2008-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.
+**************************************************************************************************/
+
+
+#ifndef Minisat_Alloc_h
+#define Minisat_Alloc_h
+
+#include "XAlloc.h"
+#include "Vec.h"
+
+namespace Minisat {
+
+//=================================================================================================
+// Simple Region-based memory allocator:
+
+template<class T>
+class RegionAllocator
+{
+    T*        memory;
+    uint32_t  sz;
+    uint32_t  cap;
+    uint32_t  wasted_;
+
+    void capacity(uint32_t min_cap);
+
+ public:
+    // TODO: make this a class for better type-checking?
+    typedef uint32_t Ref;
+    enum { Ref_Undef = UINT32_MAX };
+    enum { Unit_Size = sizeof(uint32_t) };
+
+    explicit RegionAllocator(uint32_t start_cap = 1024*1024) : memory(NULL), sz(0), cap(0), wasted_(0){ capacity(start_cap); }
+    ~RegionAllocator()
+    {
+        if (memory != NULL)
+            ::free(memory);
+    }
+
+
+    uint32_t size      () const      { return sz; }
+    uint32_t wasted    () const      { return wasted_; }
+
+    Ref      alloc     (int size); 
+    void     _free      (int size)    { wasted_ += size; }
+
+    // Deref, Load Effective Address (LEA), Inverse of LEA (AEL):
+    T&       operator[](Ref r)       { assert(r >= 0 && r < sz); return memory[r]; }
+    const T& operator[](Ref r) const { assert(r >= 0 && r < sz); return memory[r]; }
+
+    T*       lea       (Ref r)       { assert(r >= 0 && r < sz); return &memory[r]; }
+    const T* lea       (Ref r) const { assert(r >= 0 && r < sz); return &memory[r]; }
+    Ref      ael       (const T* t)  { assert((void*)t >= (void*)&memory[0] && (void*)t < (void*)&memory[sz-1]);
+        return  (Ref)(t - &memory[0]); }
+
+    void     moveTo(RegionAllocator& to) {
+        if (to.memory != NULL) ::free(to.memory);
+        to.memory = memory;
+        to.sz = sz;
+        to.cap = cap;
+        to.wasted_ = wasted_;
+
+        memory = NULL;
+        sz = cap = wasted_ = 0;
+    }
+
+
+};
+
+template<class T>
+void RegionAllocator<T>::capacity(uint32_t min_cap)
+{
+    if (cap >= min_cap) return;
+
+    uint32_t prev_cap = cap;
+    while (cap < min_cap){
+        // NOTE: Multiply by a factor (13/8) without causing overflow, then add 2 and make the
+        // result even by clearing the least significant bit. The resulting sequence of capacities
+        // is carefully chosen to hit a maximum capacity that is close to the '2^32-1' limit when
+        // using 'uint32_t' as indices so that as much as possible of this space can be used.
+        uint32_t delta = ((cap >> 1) + (cap >> 3) + 2) & ~1;
+        cap += delta;
+
+        if (cap <= prev_cap)
+            throw OutOfMemoryException();
+    }
+    // printf(" .. (%p) cap = %u\n", this, cap);
+
+    assert(cap > 0);
+    memory = (T*)xrealloc(memory, sizeof(T)*cap);
+}
+
+
+template<class T>
+typename RegionAllocator<T>::Ref
+RegionAllocator<T>::alloc(int size)
+{ 
+    // printf("ALLOC called (this = %p, size = %d)\n", this, size); fflush(stdout);
+    assert(size > 0);
+    capacity(sz + size);
+
+    uint32_t prev_sz = sz;
+    sz += size;
+    
+    // Handle overflow:
+    if (sz < prev_sz)
+        throw OutOfMemoryException();
+
+    return prev_sz;
+}
+
+
+//=================================================================================================
+}
+
+#endif
diff --git a/src/sat/bsat2/Dimacs.h b/src/sat/bsat2/Dimacs.h
new file mode 100644
index 0000000..f26f152
--- /dev/null
+++ b/src/sat/bsat2/Dimacs.h
@@ -0,0 +1,89 @@
+/****************************************************************************************[Dimacs.h]
+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.
+**************************************************************************************************/
+
+#ifndef Minisat_Dimacs_h
+#define Minisat_Dimacs_h
+
+#include <stdio.h>
+
+#include "ParseUtils.h"
+#include "SolverTypes.h"
+
+namespace Minisat {
+
+//=================================================================================================
+// DIMACS Parser:
+
+template<class B, class Solver>
+static void readClause(B& in, Solver& S, vec<Lit>& lits) {
+    int     parsed_lit, var;
+    lits.clear();
+    for (;;){
+        parsed_lit = parseInt(in);
+        if (parsed_lit == 0) break;
+        var = abs(parsed_lit)-1;
+        while (var >= S.nVars()) S.newVar();
+        lits.push( (parsed_lit > 0) ? mkLit(var) : ~mkLit(var) );
+    }
+}
+
+template<class B, class Solver>
+static void parse_DIMACS_main(B& in, Solver& S) {
+    vec<Lit> lits;
+    int vars    = 0;
+    int clauses = 0;
+    int cnt     = 0;
+    for (;;){
+        skipWhitespace(in);
+        if (*in == EOF) break;
+        else if (*in == 'p'){
+            if (eagerMatch(in, "p cnf")){
+                vars    = parseInt(in);
+                clauses = parseInt(in);
+                // SATRACE'06 hack
+                // if (clauses > 4000000)
+                //     S.eliminate(true);
+            }else{
+                printf("PARSE ERROR! Unexpected char: %c\n", *in), exit(3);
+            }
+        } else if (*in == 'c' || *in == 'p')
+            skipLine(in);
+        else{
+            cnt++;
+            readClause(in, S, lits);
+            S.addClause_(lits); }
+    }
+    if (vars != S.nVars())
+        fprintf(stderr, "WARNING! DIMACS header mismatch: wrong number of variables.\n");
+    if (cnt  != clauses)
+        fprintf(stderr, "WARNING! DIMACS header mismatch: wrong number of clauses.\n");
+}
+
+// Inserts problem into solver.
+//
+template<class Solver>
+static void parse_DIMACS(gzFile input_stream, Solver& S) {
+    StreamBuffer in(input_stream);
+    parse_DIMACS_main(in, S); }
+
+//=================================================================================================
+}
+
+#endif
diff --git a/src/sat/bsat2/Heap.h b/src/sat/bsat2/Heap.h
new file mode 100644
index 0000000..68950f3
--- /dev/null
+++ b/src/sat/bsat2/Heap.h
@@ -0,0 +1,149 @@
+/******************************************************************************************[Heap.h]
+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.
+**************************************************************************************************/
+
+#ifndef Minisat_Heap_h
+#define Minisat_Heap_h
+
+#include "Vec.h"
+
+namespace Minisat {
+
+//=================================================================================================
+// A heap implementation with support for decrease/increase key.
+
+
+template<class Comp>
+class Heap {
+    Comp     lt;       // The heap is a minimum-heap with respect to this comparator
+    vec<int> heap;     // Heap of integers
+    vec<int> indices;  // Each integers position (index) in the Heap
+
+    // Index "traversal" functions
+    static inline int left  (int i) { return i*2+1; }
+    static inline int right (int i) { return (i+1)*2; }
+    static inline int parent(int i) { return (i-1) >> 1; }
+
+
+    void percolateUp(int i)
+    {
+        int x  = heap[i];
+        int p  = parent(i);
+        
+        while (i != 0 && lt(x, heap[p])){
+            heap[i]          = heap[p];
+            indices[heap[p]] = i;
+            i                = p;
+            p                = parent(p);
+        }
+        heap   [i] = x;
+        indices[x] = i;
+    }
+
+
+    void percolateDown(int i)
+    {
+        int x = heap[i];
+        while (left(i) < heap.size()){
+            int child = right(i) < heap.size() && lt(heap[right(i)], heap[left(i)]) ? right(i) : left(i);
+            if (!lt(heap[child], x)) break;
+            heap[i]          = heap[child];
+            indices[heap[i]] = i;
+            i                = child;
+        }
+        heap   [i] = x;
+        indices[x] = i;
+    }
+
+
+  public:
+    Heap(const Comp& c) : lt(c) { }
+
+    int  size      ()          const { return heap.size(); }
+    bool empty     ()          const { return heap.size() == 0; }
+    bool inHeap    (int n)     const { return n < indices.size() && indices[n] >= 0; }
+    int  operator[](int index) const { assert(index < heap.size()); return heap[index]; }
+
+
+    void decrease  (int n) { assert(inHeap(n)); percolateUp  (indices[n]); }
+    void increase  (int n) { assert(inHeap(n)); percolateDown(indices[n]); }
+
+
+    // Safe variant of insert/decrease/increase:
+    void update(int n)
+    {
+        if (!inHeap(n))
+            insert(n);
+        else {
+            percolateUp(indices[n]);
+            percolateDown(indices[n]); }
+    }
+
+
+    void insert(int n)
+    {
+        indices.growTo(n+1, -1);
+        assert(!inHeap(n));
+
+        indices[n] = heap.size();
+        heap.push(n);
+        percolateUp(indices[n]); 
+    }
+
+
+    int  removeMin()
+    {
+        int x            = heap[0];
+        heap[0]          = heap.last();
+        indices[heap[0]] = 0;
+        indices[x]       = -1;
+        heap.pop();
+        if (heap.size() > 1) percolateDown(0);
+        return x; 
+    }
+
+
+    // Rebuild the heap from scratch, using the elements in 'ns':
+    void build(vec<int>& ns) {
+        int i;
+        for (i = 0; i < heap.size(); i++)
+            indices[heap[i]] = -1;
+        heap.clear();
+
+        for (i = 0; i < ns.size(); i++){
+            indices[ns[i]] = i;
+            heap.push(ns[i]); }
+
+        for (i = heap.size() / 2 - 1; i >= 0; i--)
+            percolateDown(i);
+    }
+
+    void clear(bool dealloc = false) 
+    { 
+        for (int i = 0; i < heap.size(); i++)
+            indices[heap[i]] = -1;
+        heap.clear(dealloc); 
+    }
+};
+
+
+//=================================================================================================
+}
+
+#endif
diff --git a/src/sat/bsat2/IntTypes.h b/src/sat/bsat2/IntTypes.h
new file mode 100644
index 0000000..a5b6c9c
--- /dev/null
+++ b/src/sat/bsat2/IntTypes.h
@@ -0,0 +1,47 @@
+/**************************************************************************************[IntTypes.h]
+Copyright (c) 2009-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.
+**************************************************************************************************/
+
+#ifndef Minisat_IntTypes_h
+#define Minisat_IntTypes_h
+
+#ifdef __sun
+    // Not sure if there are newer versions that support C99 headers. The
+    // needed features are implemented in the headers below though:
+
+#   include <sys/int_types.h>
+#   include <sys/int_fmtio.h>
+#   include <sys/int_limits.h>
+
+#elif _WIN32
+
+#   include "pstdint.h"
+
+#else
+
+#   define __STDC_LIMIT_MACROS
+#   include <stdint.h>
+#   include <inttypes.h>
+
+#endif
+
+#include <limits.h>
+
+//=================================================================================================
+
+#endif
diff --git a/src/sat/bsat2/LICENSE b/src/sat/bsat2/LICENSE
new file mode 100644
index 0000000..22816ff
--- /dev/null
+++ b/src/sat/bsat2/LICENSE
@@ -0,0 +1,21 @@
+MiniSat -- 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/bsat2/MainSat.cpp b/src/sat/bsat2/MainSat.cpp
new file mode 100644
index 0000000..068372e
--- /dev/null
+++ b/src/sat/bsat2/MainSat.cpp
@@ -0,0 +1,197 @@
+/*****************************************************************************************[Main.cc]
+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.
+**************************************************************************************************/
+
+#include <errno.h>
+
+#include <signal.h>
+#include "misc/zlib/zlib.h"
+
+#include "System.h"
+#include "ParseUtils.h"
+#include "Options.h"
+#include "Dimacs.h"
+#include "Solver.h"
+
+using namespace Minisat;
+
+//=================================================================================================
+
+
+void printStats(Solver& solver)
+{
+    double cpu_time = cpuTime();
+    double mem_used = memUsedPeak();
+    printf("restarts              : %-12.0f\n",                                (double)(int64_t)solver.starts);
+    printf("conflicts             : %-12.0f  (%.0f /sec)\n",                   (double)(int64_t)solver.conflicts,    (double)(int64_t)solver.conflicts / cpu_time);
+    printf("decisions             : %-12.0f  (%4.2f %% random) (%.0f /sec)\n", (double)(int64_t)solver.decisions,    (double)(int64_t)solver.rnd_decisions*100 / (double)(int64_t)solver.decisions, (double)(int64_t)solver.decisions / cpu_time);
+    printf("propagations          : %-12.0f  (%.0f /sec)\n",                   (double)(int64_t)solver.propagations, (double)(int64_t)solver.propagations / cpu_time);
+    printf("conflict literals     : %-12.0f  (%4.2f %% deleted)\n",            (double)(int64_t)solver.tot_literals, (double)(int64_t)(solver.max_literals - solver.tot_literals)*100 / (double)(int64_t)solver.max_literals);
+    if (mem_used != 0) printf("Memory used           : %.2f MB\n", mem_used);
+    printf("CPU time              : %g s\n", cpu_time);
+}
+
+
+static Solver* solver;
+// Terminate by notifying the solver and back out gracefully. This is mainly to have a test-case
+// for this feature of the Solver as it may take longer than an immediate call to '_exit()'.
+static void SIGINT_interrupt(int signum) { solver->interrupt(); }
+
+// Note that '_exit()' rather than 'exit()' has to be used. The reason is that 'exit()' calls
+// destructors and may cause deadlocks if a malloc/free function happens to be running (these
+// functions are guarded by locks for multithreaded use).
+static void SIGINT_exit(int signum) {
+    printf("\n"); printf("*** INTERRUPTED ***\n");
+    if (solver->verbosity > 0){
+        printStats(*solver);
+        printf("\n"); printf("*** INTERRUPTED ***\n"); }
+    _exit(1); }
+
+
+//=================================================================================================
+// Main:
+
+
+extern "C" int MainSat(int argc, char** argv)
+{
+    try {
+        setUsageHelp("USAGE: %s [options] <input-file> <result-output-file>\n\n  where input may be either in plain or gzipped DIMACS.\n");
+        // printf("This is MiniSat 2.0 beta\n");
+        
+#if defined(__linux__)
+        fpu_control_t oldcw, newcw;
+        _FPU_GETCW(oldcw); newcw = (oldcw & ~_FPU_EXTENDED) | _FPU_DOUBLE; _FPU_SETCW(newcw);
+        printf("WARNING: for repeatability, setting FPU to use double precision\n");
+#endif
+        // Extra options:
+        //
+        IntOption    verb   ("MAIN", "verb",   "Verbosity level (0=silent, 1=some, 2=more).", 1, IntRange(0, 2));
+        IntOption    cpu_lim("MAIN", "cpu-lim","Limit on CPU time allowed in seconds.\n", INT32_MAX, IntRange(0, INT32_MAX));
+        IntOption    mem_lim("MAIN", "mem-lim","Limit on memory usage in megabytes.\n", INT32_MAX, IntRange(0, INT32_MAX));
+        
+        if ( !parseOptions(argc, argv, true) )
+            return 1;
+
+        Solver S;
+        double initial_time = cpuTime();
+
+        S.verbosity = verb;
+        
+        solver = &S;
+/*
+        // Use signal handlers that forcibly quit until the solver will be able to respond to
+        // interrupts:
+        signal(SIGINT, SIGINT_exit);
+        signal(SIGXCPU,SIGINT_exit);
+
+        // Set limit on CPU-time:
+        if (cpu_lim != INT32_MAX){
+            rlimit rl;
+            getrlimit(RLIMIT_CPU, &rl);
+            if (rl.rlim_max == RLIM_INFINITY || (rlim_t)cpu_lim < rl.rlim_max){
+                rl.rlim_cur = cpu_lim;
+                if (setrlimit(RLIMIT_CPU, &rl) == -1)
+                    printf("WARNING! Could not set resource limit: CPU-time.\n");
+            } }
+
+        // Set limit on virtual memory:
+        if (mem_lim != INT32_MAX){
+            rlim_t new_mem_lim = (rlim_t)mem_lim * 1024*1024;
+            rlimit rl;
+            getrlimit(RLIMIT_AS, &rl);
+            if (rl.rlim_max == RLIM_INFINITY || new_mem_lim < rl.rlim_max){
+                rl.rlim_cur = new_mem_lim;
+                if (setrlimit(RLIMIT_AS, &rl) == -1)
+                    printf("WARNING! Could not set resource limit: Virtual memory.\n");
+            } }
+*/        
+        if (argc == 1)
+        {
+            printf("Reading from standard input... Use '--help' for help.\n");
+            return 1;
+        }
+        
+        gzFile in = (argc == 1) ? gzdopen(0, "rb") : gzopen(argv[1], "rb");
+        if (in == NULL)
+            printf("ERROR! Could not open file: %s\n", argc == 1 ? "<stdin>" : argv[1]), exit(1);
+        
+        if (S.verbosity > 0){
+            printf("============================[ Problem Statistics ]=============================\n");
+            printf("|                                                                             |\n"); }
+        
+        parse_DIMACS(in, S);
+        gzclose(in);
+        FILE* res = (argc >= 3) ? fopen(argv[2], "wb") : NULL;
+        
+        if (S.verbosity > 0){
+            printf("|  Number of variables:  %12d                                         |\n", S.nVars());
+            printf("|  Number of clauses:    %12d                                         |\n", S.nClauses()); }
+        
+        double parsed_time = cpuTime();
+        if (S.verbosity > 0){
+            printf("|  Parse time:           %12.2f s                                       |\n", parsed_time - initial_time);
+            printf("|                                                                             |\n"); }
+ 
+        // Change to signal-handlers that will only notify the solver and allow it to terminate
+        // voluntarily:
+//        signal(SIGINT, SIGINT_interrupt);
+//        signal(SIGXCPU,SIGINT_interrupt);
+       
+        if (!S.simplify()){
+            if (res != NULL) fprintf(res, "UNSAT\n"), fclose(res);
+            if (S.verbosity > 0){
+                printf("===============================================================================\n");
+                printf("Solved by unit propagation\n");
+                printStats(S);
+                printf("\n"); }
+            printf("UNSATISFIABLE\n");
+            exit(20);
+        }
+        
+        vec<Lit> dummy;
+        lbool ret = S.solveLimited(dummy);
+        if (S.verbosity > 0){
+            printStats(S);
+            printf("\n"); }
+        printf(ret == l_True ? "SATISFIABLE\n" : ret == l_False ? "UNSATISFIABLE\n" : "INDETERMINATE\n");
+        if (res != NULL){
+            if (ret == l_True){
+                fprintf(res, "SAT\n");
+                for (int i = 0; i < S.nVars(); i++)
+                    if (S.model[i] != l_Undef)
+                        fprintf(res, "%s%s%d", (i==0)?"":" ", (S.model[i]==l_True)?"":"-", i+1);
+                fprintf(res, " 0\n");
+            }else if (ret == l_False)
+                fprintf(res, "UNSAT\n");
+            else
+                fprintf(res, "INDET\n");
+            fclose(res);
+        }
+        
+//#ifdef NDEBUG
+//        exit(ret == l_True ? 10 : ret == l_False ? 20 : 0);     // (faster than "return", which will invoke the destructor for 'Solver')
+//#else
+        return (ret == l_True ? 10 : ret == l_False ? 20 : 0);
+//#endif
+    } catch (OutOfMemoryException&){
+        printf("===============================================================================\n");
+        printf("INDETERMINATE\n");
+        exit(0);
+    }
+}
diff --git a/src/sat/bsat2/MainSimp.cpp b/src/sat/bsat2/MainSimp.cpp
new file mode 100644
index 0000000..897ca7e
--- /dev/null
+++ b/src/sat/bsat2/MainSimp.cpp
@@ -0,0 +1,206 @@
+/*****************************************************************************************[Main.cc]
+Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson
+Copyright (c) 2007,      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.
+**************************************************************************************************/
+
+#include <errno.h>
+
+#include <signal.h>
+#include "misc/zlib/zlib.h"
+
+#ifndef _WIN32
+#include <sys/resource.h>
+#endif
+
+#include "System.h"
+#include "ParseUtils.h"
+#include "Options.h"
+#include "Dimacs.h"
+#include "SimpSolver.h"
+
+using namespace Minisat;
+
+//=================================================================================================
+
+extern void printStats(Solver& solver);
+
+static Solver* solver;
+// Terminate by notifying the solver and back out gracefully. This is mainly to have a test-case
+// for this feature of the Solver as it may take longer than an immediate call to '_exit()'.
+static void SIGINT_interrupt(int signum) { solver->interrupt(); }
+
+// Note that '_exit()' rather than 'exit()' has to be used. The reason is that 'exit()' calls
+// destructors and may cause deadlocks if a malloc/free function happens to be running (these
+// functions are guarded by locks for multithreaded use).
+static void SIGINT_exit(int signum) {
+    printf("\n"); printf("*** INTERRUPTED ***\n");
+    if (solver->verbosity > 0){
+        printStats(*solver);
+        printf("\n"); printf("*** INTERRUPTED ***\n"); }
+    _exit(1); }
+
+
+//=================================================================================================
+// Main:
+
+extern "C" int MainSimp(int argc, char** argv)
+{
+    try {
+        setUsageHelp("USAGE: %s [options] <input-file> <result-output-file>\n\n  where input may be either in plain or gzipped DIMACS.\n");
+        // printf("This is MiniSat 2.0 beta\n");
+        
+#if defined(__linux__)
+        fpu_control_t oldcw, newcw;
+        _FPU_GETCW(oldcw); newcw = (oldcw & ~_FPU_EXTENDED) | _FPU_DOUBLE; _FPU_SETCW(newcw);
+        printf("WARNING: for repeatability, setting FPU to use double precision\n");
+#endif
+        // Extra options:
+        //
+        IntOption    verb   ("MAIN", "verb",   "Verbosity level (0=silent, 1=some, 2=more).", 1, IntRange(0, 2));
+        BoolOption   pre    ("MAIN", "pre",    "Completely turn on/off any preprocessing.", true);
+        StringOption dimacs ("MAIN", "dimacs", "If given, stop after preprocessing and write the result to this file.");
+        IntOption    cpu_lim("MAIN", "cpu-lim","Limit on CPU time allowed in seconds.\n", INT32_MAX, IntRange(0, INT32_MAX));
+        IntOption    mem_lim("MAIN", "mem-lim","Limit on memory usage in megabytes.\n", INT32_MAX, IntRange(0, INT32_MAX));
+
+        if ( !parseOptions(argc, argv, true) )
+            return 1;
+        
+        SimpSolver  S;
+        double      initial_time = cpuTime();
+
+        if (!pre) S.eliminate(true);
+
+        S.verbosity = verb;
+        
+        solver = &S;
+/*
+        // Use signal handlers that forcibly quit until the solver will be able to respond to
+        // interrupts:
+        signal(SIGINT, SIGINT_exit);
+        signal(SIGXCPU,SIGINT_exit);
+
+        // Set limit on CPU-time:
+        if (cpu_lim != INT32_MAX){
+            rlimit rl;
+            getrlimit(RLIMIT_CPU, &rl);
+            if (rl.rlim_max == RLIM_INFINITY || (rlim_t)cpu_lim < rl.rlim_max){
+                rl.rlim_cur = cpu_lim;
+                if (setrlimit(RLIMIT_CPU, &rl) == -1)
+                    printf("WARNING! Could not set resource limit: CPU-time.\n");
+            } }
+
+        // Set limit on virtual memory:
+        if (mem_lim != INT32_MAX){
+            rlim_t new_mem_lim = (rlim_t)mem_lim * 1024*1024;
+            rlimit rl;
+            getrlimit(RLIMIT_AS, &rl);
+            if (rl.rlim_max == RLIM_INFINITY || new_mem_lim < rl.rlim_max){
+                rl.rlim_cur = new_mem_lim;
+                if (setrlimit(RLIMIT_AS, &rl) == -1)
+                    printf("WARNING! Could not set resource limit: Virtual memory.\n");
+            } }
+*/        
+        if (argc == 1)
+        {
+            printf("Reading from standard input... Use '--help' for help.\n");
+            return 1;
+        }
+
+        gzFile in = (argc == 1) ? gzdopen(0, "rb") : gzopen(argv[1], "rb");
+        if (in == NULL)
+            printf("ERROR! Could not open file: %s\n", argc == 1 ? "<stdin>" : argv[1]), exit(1);
+        
+        if (S.verbosity > 0){
+            printf("============================[ Problem Statistics ]=============================\n");
+            printf("|                                                                             |\n"); }
+        
+        parse_DIMACS(in, S);
+        gzclose(in);
+        FILE* res = (argc >= 3) ? fopen(argv[2], "wb") : NULL;
+
+        if (S.verbosity > 0){
+            printf("|  Number of variables:  %12d                                         |\n", S.nVars());
+            printf("|  Number of clauses:    %12d                                         |\n", S.nClauses()); }
+        
+        double parsed_time = cpuTime();
+        if (S.verbosity > 0)
+            printf("|  Parse time:           %12.2f s                                       |\n", parsed_time - initial_time);
+
+        // Change to signal-handlers that will only notify the solver and allow it to terminate
+        // voluntarily:
+//        signal(SIGINT, SIGINT_interrupt);
+//        signal(SIGXCPU,SIGINT_interrupt);
+
+        S.eliminate(true);
+        double simplified_time = cpuTime();
+        if (S.verbosity > 0){
+            printf("|  Simplification time:  %12.2f s                                       |\n", simplified_time - parsed_time);
+            printf("|                                                                             |\n"); }
+
+        if (!S.okay()){
+            if (res != NULL) fprintf(res, "UNSAT\n"), fclose(res);
+            if (S.verbosity > 0){
+                printf("===============================================================================\n");
+                printf("Solved by simplification\n");
+                printStats(S);
+                printf("\n"); }
+            printf("UNSATISFIABLE\n");
+            exit(20);
+        }
+
+        if (dimacs){
+            if (S.verbosity > 0)
+                printf("==============================[ Writing DIMACS ]===============================\n");
+            S.toDimacs((const char*)dimacs);
+            if (S.verbosity > 0)
+                printStats(S);
+            exit(0);
+        }
+
+        vec<Lit> dummy;
+        lbool ret = S.solveLimited(dummy);
+        
+        if (S.verbosity > 0){
+            printStats(S);
+            printf("\n"); }
+        printf(ret == l_True ? "SATISFIABLE\n" : ret == l_False ? "UNSATISFIABLE\n" : "INDETERMINATE\n");
+        if (res != NULL){
+            if (ret == l_True){
+                fprintf(res, "SAT\n");
+                for (int i = 0; i < S.nVars(); i++)
+                    if (S.model[i] != l_Undef)
+                        fprintf(res, "%s%s%d", (i==0)?"":" ", (S.model[i]==l_True)?"":"-", i+1);
+                fprintf(res, " 0\n");
+            }else if (ret == l_False)
+                fprintf(res, "UNSAT\n");
+            else
+                fprintf(res, "INDET\n");
+            fclose(res);
+        }
+
+//#ifdef NDEBUG
+//        exit(ret == l_True ? 10 : ret == l_False ? 20 : 0);     // (faster than "return", which will invoke the destructor for 'Solver')
+//#else
+        return (ret == l_True ? 10 : ret == l_False ? 20 : 0);
+//#endif
+    } catch (OutOfMemoryException&){
+        printf("===============================================================================\n");
+        printf("INDETERMINATE\n");
+        exit(0);
+    }
+}
diff --git a/src/sat/bsat2/Map.h b/src/sat/bsat2/Map.h
new file mode 100644
index 0000000..1dd22a0
--- /dev/null
+++ b/src/sat/bsat2/Map.h
@@ -0,0 +1,193 @@
+/*******************************************************************************************[Map.h]
+Copyright (c) 2006-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.
+**************************************************************************************************/
+
+#ifndef Minisat_Map_h
+#define Minisat_Map_h
+
+#include "IntTypes.h"
+#include "Vec.h"
+
+namespace Minisat {
+
+//=================================================================================================
+// Default hash/equals functions
+//
+
+template<class K> struct Hash  { uint32_t operator()(const K& k)               const { return hash(k);  } };
+template<class K> struct Equal { bool     operator()(const K& k1, const K& k2) const { return k1 == k2; } };
+
+template<class K> struct DeepHash  { uint32_t operator()(const K* k)               const { return hash(*k);  } };
+template<class K> struct DeepEqual { bool     operator()(const K* k1, const K* k2) const { return *k1 == *k2; } };
+
+static inline uint32_t hash(uint32_t x){ return x; }
+static inline uint32_t hash(uint64_t x){ return (uint32_t)x; }
+static inline uint32_t hash(int32_t x) { return (uint32_t)x; }
+static inline uint32_t hash(int64_t x) { return (uint32_t)x; }
+
+
+//=================================================================================================
+// Some primes
+//
+
+static const int nprimes          = 25;
+static const int primes [nprimes] = { 31, 73, 151, 313, 643, 1291, 2593, 5233, 10501, 21013, 42073, 84181, 168451, 337219, 674701, 1349473, 2699299, 5398891, 10798093, 21596719, 43193641, 86387383, 172775299, 345550609, 691101253 };
+
+//=================================================================================================
+// Hash table implementation of Maps
+//
+
+template<class K, class D, class H = Hash<K>, class E = Equal<K> >
+class Map {
+ public:
+    struct Pair { K key; D data; };
+
+ private:
+    H          hash;
+    E          equals;
+
+    vec<Pair>* table;
+    int        cap;
+    int        size;
+
+    // Don't allow copying (error prone):
+    Map<K,D,H,E>&  operator = (Map<K,D,H,E>& other) { assert(0); }
+                   Map        (Map<K,D,H,E>& other) { assert(0); }
+
+    bool    checkCap(int new_size) const { return new_size > cap; }
+
+    int32_t index  (const K& k) const { return hash(k) % cap; }
+    void   _insert (const K& k, const D& d) { 
+        vec<Pair>& ps = table[index(k)];
+        ps.push(); ps.last().key = k; ps.last().data = d; }
+
+    void    rehash () {
+        const vec<Pair>* old = table;
+
+        int old_cap = cap;
+        int newsize = primes[0];
+        for (int i = 1; newsize <= cap && i < nprimes; i++)
+           newsize = primes[i];
+
+        table = new vec<Pair>[newsize];
+        cap   = newsize;
+
+        for (int i = 0; i < old_cap; i++){
+            for (int j = 0; j < old[i].size(); j++){
+                _insert(old[i][j].key, old[i][j].data); }}
+
+        delete [] old;
+
+        // printf(" --- rehashing, old-cap=%d, new-cap=%d\n", cap, newsize);
+    }
+
+    
+ public:
+
+    Map () : table(NULL), cap(0), size(0) {}
+    Map (const H& h, const E& e) : hash(h), equals(e), table(NULL), cap(0), size(0){}
+    ~Map () { delete [] table; }
+
+    // PRECONDITION: the key must already exist in the map.
+    const D& operator [] (const K& k) const
+    {
+        assert(size != 0);
+        const D*         res = NULL;
+        const vec<Pair>& ps  = table[index(k)];
+        for (int i = 0; i < ps.size(); i++)
+            if (equals(ps[i].key, k))
+                res = &ps[i].data;
+        assert(res != NULL);
+        return *res;
+    }
+
+    // PRECONDITION: the key must already exist in the map.
+    D& operator [] (const K& k)
+    {
+        assert(size != 0);
+        D*         res = NULL;
+        vec<Pair>& ps  = table[index(k)];
+        for (int i = 0; i < ps.size(); i++)
+            if (equals(ps[i].key, k))
+                res = &ps[i].data;
+        assert(res != NULL);
+        return *res;
+    }
+
+    // PRECONDITION: the key must *NOT* exist in the map.
+    void insert (const K& k, const D& d) { if (checkCap(size+1)) rehash(); _insert(k, d); size++; }
+    bool peek   (const K& k, D& d) const {
+        if (size == 0) return false;
+        const vec<Pair>& ps = table[index(k)];
+        for (int i = 0; i < ps.size(); i++)
+            if (equals(ps[i].key, k)){
+                d = ps[i].data;
+                return true; } 
+        return false;
+    }
+
+    bool has   (const K& k) const {
+        if (size == 0) return false;
+        const vec<Pair>& ps = table[index(k)];
+        for (int i = 0; i < ps.size(); i++)
+            if (equals(ps[i].key, k))
+                return true;
+        return false;
+    }
+
+    // PRECONDITION: the key must exist in the map.
+    void remove(const K& k) {
+        assert(table != NULL);
+        vec<Pair>& ps = table[index(k)];
+        int j = 0;
+        for (; j < ps.size() && !equals(ps[j].key, k); j++);
+        assert(j < ps.size());
+        ps[j] = ps.last();
+        ps.pop();
+        size--;
+    }
+
+    void clear  () {
+        cap = size = 0;
+        delete [] table;
+        table = NULL;
+    }
+
+    int  elems() const { return size; }
+    int  bucket_count() const { return cap; }
+
+    // NOTE: the hash and equality objects are not moved by this method:
+    void moveTo(Map& other){
+        delete [] other.table;
+
+        other.table = table;
+        other.cap   = cap;
+        other.size  = size;
+
+        table = NULL;
+        size = cap = 0;
+    }
+
+    // NOTE: given a bit more time, I could make a more C++-style iterator out of this:
+    const vec<Pair>& bucket(int i) const { return table[i]; }
+};
+
+//=================================================================================================
+}
+
+#endif
diff --git a/src/sat/bsat2/Options.cpp b/src/sat/bsat2/Options.cpp
new file mode 100644
index 0000000..6af1e7a
--- /dev/null
+++ b/src/sat/bsat2/Options.cpp
@@ -0,0 +1,93 @@
+/**************************************************************************************[Options.cc]
+Copyright (c) 2008-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.
+**************************************************************************************************/
+
+#include "Sort.h"
+#include "Options.h"
+#include "ParseUtils.h"
+
+using namespace Minisat;
+
+int Minisat::parseOptions(int& argc, char** argv, bool strict)
+{
+    int i, j;
+    for (i = j = 1; i < argc; i++){
+        const char* str = argv[i];
+        if (match(str, "--") && match(str, Option::getHelpPrefixString()) && match(str, "help")){
+            if (*str == '\0')
+                return printUsageAndExit(argc, argv);
+            else if (match(str, "-verb"))
+                return printUsageAndExit(argc, argv, true);
+        } else {
+            bool parsed_ok = false;
+        
+            for (int k = 0; !parsed_ok && k < Option::getOptionList().size(); k++){
+                parsed_ok = Option::getOptionList()[k]->parse(argv[i]);
+
+                // fprintf(stderr, "checking %d: %s against flag <%s> (%s)\n", i, argv[i], Option::getOptionList()[k]->name, parsed_ok ? "ok" : "skip");
+            }
+
+            if (!parsed_ok)
+                if (strict && match(argv[i], "-"))
+                    { fprintf(stderr, "ERROR! Unknown flag \"%s\". Use '--%shelp' for help.\n", argv[i], Option::getHelpPrefixString()); return 0; } //  exit(0);
+                else
+                    argv[j++] = argv[i];
+        }
+    }
+
+    argc -= (i - j);
+    return 1;
+}
+
+
+void Minisat::setUsageHelp      (const char* str){ Option::getUsageString() = str; }
+void Minisat::setHelpPrefixStr  (const char* str){ Option::getHelpPrefixString() = str; }
+int Minisat::printUsageAndExit (int argc, char** argv, bool verbose)
+{
+    const char* usage = Option::getUsageString();
+    if (usage != NULL)
+        fprintf(stderr, usage, argv[0]);
+
+    sort(Option::getOptionList(), Option::OptionLt());
+
+    const char* prev_cat  = NULL;
+    const char* prev_type = NULL;
+
+    for (int i = 0; i < Option::getOptionList().size(); i++){
+        const char* cat  = Option::getOptionList()[i]->category;
+        const char* type = Option::getOptionList()[i]->type_name;
+
+        if (cat != prev_cat)
+            fprintf(stderr, "\n%s OPTIONS:\n\n", cat);
+        else if (type != prev_type)
+            fprintf(stderr, "\n");
+
+        Option::getOptionList()[i]->help(verbose);
+
+        prev_cat  = Option::getOptionList()[i]->category;
+        prev_type = Option::getOptionList()[i]->type_name;
+    }
+
+    fprintf(stderr, "\nHELP OPTIONS:\n\n");
+    fprintf(stderr, "  --%shelp        Print help message.\n", Option::getHelpPrefixString());
+    fprintf(stderr, "  --%shelp-verb   Print verbose help message.\n", Option::getHelpPrefixString());
+    fprintf(stderr, "\n");
+//    exit(0);
+    return 0;
+}
+
diff --git a/src/sat/bsat2/Options.h b/src/sat/bsat2/Options.h
new file mode 100644
index 0000000..bf57334
--- /dev/null
+++ b/src/sat/bsat2/Options.h
@@ -0,0 +1,387 @@
+/***************************************************************************************[Options.h]
+Copyright (c) 2008-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.
+**************************************************************************************************/
+
+#ifndef Minisat_Options_h
+#define Minisat_Options_h
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+
+#include "IntTypes.h"
+#include "Vec.h"
+#include "ParseUtils.h"
+
+namespace Minisat {
+
+//==================================================================================================
+// Top-level option parse/help functions:
+
+
+extern int parseOptions     (int& argc, char** argv, bool strict = false);
+extern int printUsageAndExit(int  argc, char** argv, bool verbose = false);
+extern void setUsageHelp     (const char* str);
+extern void setHelpPrefixStr (const char* str);
+
+
+//==================================================================================================
+// Options is an abstract class that gives the interface for all types options:
+
+
+class Option
+{
+ public:
+    const char* name;
+    const char* description;
+    const char* category;
+    const char* type_name;
+
+    static vec<Option*>& getOptionList () { static vec<Option*> options; return options; }
+    static const char*&  getUsageString() { static const char* usage_str; return usage_str; }
+    static const char*&  getHelpPrefixString() { static const char* help_prefix_str = ""; return help_prefix_str; }
+
+    struct OptionLt {
+        bool operator()(const Option* x, const Option* y) {
+            int test1 = strcmp(x->category, y->category);
+            return test1 < 0 || test1 == 0 && strcmp(x->type_name, y->type_name) < 0;
+        }
+    };
+
+    Option(const char* name_, 
+           const char* desc_,
+           const char* cate_,
+           const char* type_) : 
+      name       (name_)
+    , description(desc_)
+    , category   (cate_)
+    , type_name  (type_)
+    { 
+        getOptionList().push(this); 
+    }
+
+ public:
+    virtual ~Option() {}
+
+    virtual bool parse             (const char* str)      = 0;
+    virtual void help              (bool verbose = false) = 0;
+
+    friend  int parseOptions      (int& argc, char** argv, bool strict);
+    friend  int printUsageAndExit (int  argc, char** argv, bool verbose);
+    friend  void setUsageHelp      (const char* str);
+    friend  void setHelpPrefixStr  (const char* str);
+};
+
+
+//==================================================================================================
+// Range classes with specialization for floating types:
+
+
+struct IntRange {
+    int begin;
+    int end;
+    IntRange(int b, int e) : begin(b), end(e) {}
+};
+
+struct Int64Range {
+    int64_t begin;
+    int64_t end;
+    Int64Range(int64_t b, int64_t e) : begin(b), end(e) {}
+};
+
+struct DoubleRange {
+    double begin;
+    double end;
+    bool  begin_inclusive;
+    bool  end_inclusive;
+    DoubleRange(double b, bool binc, double e, bool einc) : begin(b), end(e), begin_inclusive(binc), end_inclusive(einc) {}
+};
+
+
+//==================================================================================================
+// Double options:
+
+
+class DoubleOption : public Option
+{
+ protected:
+    DoubleRange range;
+    double      value;
+
+ public:
+    DoubleOption(const char* c, const char* n, const char* d, double def = double(), DoubleRange r = DoubleRange(-HUGE_VAL, false, HUGE_VAL, false))
+        : Option(n, d, c, "<double>"), range(r), value(def) {
+        // FIXME: set LC_NUMERIC to "C" to make sure that strtof/strtod parses decimal point correctly.
+    }
+
+    operator      double   (void) const { return value; }
+    operator      double&  (void)       { return value; }
+    DoubleOption& operator=(double x)   { value = x; return *this; }
+
+    virtual bool parse(const char* str){
+        const char* span = str; 
+
+        if (!match(span, "-") || !match(span, name) || !match(span, "="))
+            return false;
+
+        char*  end;
+        double tmp = strtod(span, &end);
+
+        if (end == NULL) 
+            return false;
+        else if (tmp >= range.end && (!range.end_inclusive || tmp != range.end)){
+            fprintf(stderr, "ERROR! value <%s> is too large for option \"%s\".\n", span, name);
+            exit(1);
+        }else if (tmp <= range.begin && (!range.begin_inclusive || tmp != range.begin)){
+            fprintf(stderr, "ERROR! value <%s> is too small for option \"%s\".\n", span, name);
+            exit(1); }
+
+        value = tmp;
+        // fprintf(stderr, "READ VALUE: %g\n", value);
+
+        return true;
+    }
+
+    virtual void help (bool verbose = false){
+        fprintf(stderr, "  -%-12s = %-8s %c%4.2g .. %4.2g%c (default: %g)\n", 
+                name, type_name, 
+                range.begin_inclusive ? '[' : '(', 
+                range.begin,
+                range.end,
+                range.end_inclusive ? ']' : ')', 
+                value);
+        if (verbose){
+            fprintf(stderr, "\n        %s\n", description);
+            fprintf(stderr, "\n");
+        }
+    }
+};
+
+
+//==================================================================================================
+// Int options:
+
+
+class IntOption : public Option
+{
+ protected:
+    IntRange range;
+    int32_t  value;
+
+ public:
+    IntOption(const char* c, const char* n, const char* d, int32_t def = int32_t(), IntRange r = IntRange(INT32_MIN, INT32_MAX))
+        : Option(n, d, c, "<int32>"), range(r), value(def) {}
+ 
+    operator   int32_t   (void) const { return value; }
+    operator   int32_t&  (void)       { return value; }
+    IntOption& operator= (int32_t x)  { value = x; return *this; }
+
+    virtual bool parse(const char* str){
+        const char* span = str; 
+
+        if (!match(span, "-") || !match(span, name) || !match(span, "="))
+            return false;
+
+        char*   end;
+        int32_t tmp = strtol(span, &end, 10);
+
+        if (end == NULL) 
+            return false;
+        else if (tmp > range.end){
+            fprintf(stderr, "ERROR! value <%s> is too large for option \"%s\".\n", span, name);
+            exit(1);
+        }else if (tmp < range.begin){
+            fprintf(stderr, "ERROR! value <%s> is too small for option \"%s\".\n", span, name);
+            exit(1); }
+
+        value = tmp;
+
+        return true;
+    }
+
+    virtual void help (bool verbose = false){
+        fprintf(stderr, "  -%-12s = %-8s [", name, type_name);
+        if (range.begin == INT32_MIN)
+            fprintf(stderr, "imin");
+        else
+            fprintf(stderr, "%4d", range.begin);
+
+        fprintf(stderr, " .. ");
+        if (range.end == INT32_MAX)
+            fprintf(stderr, "imax");
+        else
+            fprintf(stderr, "%4d", range.end);
+
+        fprintf(stderr, "] (default: %d)\n", value);
+        if (verbose){
+            fprintf(stderr, "\n        %s\n", description);
+            fprintf(stderr, "\n");
+        }
+    }
+};
+
+/*
+// Leave this out for visual C++ until Microsoft implements C99 and gets support for strtoll.
+#ifndef _MSC_VER
+
+class Int64Option : public Option
+{
+ protected:
+    Int64Range range;
+    int64_t  value;
+
+ public:
+    Int64Option(const char* c, const char* n, const char* d, int64_t def = int64_t(), Int64Range r = Int64Range(INT64_MIN, INT64_MAX))
+        : Option(n, d, c, "<int64>"), range(r), value(def) {}
+ 
+    operator     int64_t   (void) const { return value; }
+    operator     int64_t&  (void)       { return value; }
+    Int64Option& operator= (int64_t x)  { value = x; return *this; }
+
+    virtual bool parse(const char* str){
+        const char* span = str; 
+
+        if (!match(span, "-") || !match(span, name) || !match(span, "="))
+            return false;
+
+        char*   end;
+        int64_t tmp = strtoll(span, &end, 10);
+
+        if (end == NULL) 
+            return false;
+        else if (tmp > range.end){
+            fprintf(stderr, "ERROR! value <%s> is too large for option \"%s\".\n", span, name);
+            exit(1);
+        }else if (tmp < range.begin){
+            fprintf(stderr, "ERROR! value <%s> is too small for option \"%s\".\n", span, name);
+            exit(1); }
+
+        value = tmp;
+
+        return true;
+    }
+
+    virtual void help (bool verbose = false){
+        fprintf(stderr, "  -%-12s = %-8s [", name, type_name);
+        if (range.begin == INT64_MIN)
+            fprintf(stderr, "imin");
+        else
+            fprintf(stderr, "%4"PRIi64, range.begin);
+
+        fprintf(stderr, " .. ");
+        if (range.end == INT64_MAX)
+            fprintf(stderr, "imax");
+        else
+            fprintf(stderr, "%4"PRIi64, range.end);
+
+        fprintf(stderr, "] (default: %"PRIi64")\n", value);
+        if (verbose){
+            fprintf(stderr, "\n        %s\n", description);
+            fprintf(stderr, "\n");
+        }
+    }
+};
+#endif
+*/
+
+//==================================================================================================
+// String option:
+
+
+class StringOption : public Option
+{
+    const char* value;
+ public:
+    StringOption(const char* c, const char* n, const char* d, const char* def = NULL) 
+        : Option(n, d, c, "<string>"), value(def) {}
+
+    operator      const char*  (void) const     { return value; }
+    operator      const char*& (void)           { return value; }
+    StringOption& operator=    (const char* x)  { value = x; return *this; }
+
+    virtual bool parse(const char* str){
+        const char* span = str; 
+
+        if (!match(span, "-") || !match(span, name) || !match(span, "="))
+            return false;
+
+        value = span;
+        return true;
+    }
+
+    virtual void help (bool verbose = false){
+        fprintf(stderr, "  -%-10s = %8s\n", name, type_name);
+        if (verbose){
+            fprintf(stderr, "\n        %s\n", description);
+            fprintf(stderr, "\n");
+        }
+    }    
+};
+
+
+//==================================================================================================
+// Bool option:
+
+
+class BoolOption : public Option
+{
+    bool value;
+
+ public:
+    BoolOption(const char* c, const char* n, const char* d, bool v) 
+        : Option(n, d, c, "<bool>"), value(v) {}
+
+    operator    bool     (void) const { return value; }
+    operator    bool&    (void)       { return value; }
+    BoolOption& operator=(bool b)     { value = b; return *this; }
+
+    virtual bool parse(const char* str){
+        const char* span = str; 
+        
+        if (match(span, "-")){
+            bool b = !match(span, "no-");
+
+            if (strcmp(span, name) == 0){
+                value = b;
+                return true; }
+        }
+
+        return false;
+    }
+
+    virtual void help (bool verbose = false){
+
+        fprintf(stderr, "  -%s, -no-%s", name, name);
+
+        for (uint32_t i = 0; i < 32 - strlen(name)*2; i++)
+            fprintf(stderr, " ");
+
+        fprintf(stderr, " ");
+        fprintf(stderr, "(default: %s)\n", value ? "on" : "off");
+        if (verbose){
+            fprintf(stderr, "\n        %s\n", description);
+            fprintf(stderr, "\n");
+        }
+    }
+};
+
+//=================================================================================================
+}
+
+#endif
diff --git a/src/sat/bsat2/ParseUtils.h b/src/sat/bsat2/ParseUtils.h
new file mode 100644
index 0000000..8e0f9c8
--- /dev/null
+++ b/src/sat/bsat2/ParseUtils.h
@@ -0,0 +1,122 @@
+/************************************************************************************[ParseUtils.h]
+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.
+**************************************************************************************************/
+
+#ifndef Minisat_ParseUtils_h
+#define Minisat_ParseUtils_h
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "misc/zlib/zlib.h"
+
+namespace Minisat {
+
+//-------------------------------------------------------------------------------------------------
+// A simple buffered character stream class:
+
+static const int buffer_size = 1048576;
+
+
+class StreamBuffer {
+    gzFile        in;
+    unsigned char buf[buffer_size];
+    int           pos;
+    int           size;
+
+    void assureLookahead() {
+        if (pos >= size) {
+            pos  = 0;
+            size = gzread(in, buf, sizeof(buf)); } }
+
+public:
+    explicit StreamBuffer(gzFile i) : in(i), pos(0), size(0) { assureLookahead(); }
+
+    int  operator *  () const { return (pos >= size) ? EOF : buf[pos]; }
+    void operator ++ ()       { pos++; assureLookahead(); }
+    int  position    () const { return pos; }
+};
+
+
+//-------------------------------------------------------------------------------------------------
+// End-of-file detection functions for StreamBuffer and char*:
+
+
+static inline bool isEof(StreamBuffer& in) { return *in == EOF;  }
+static inline bool isEof(const char*   in) { return *in == '\0'; }
+
+//-------------------------------------------------------------------------------------------------
+// Generic parse functions parametrized over the input-stream type.
+
+
+template<class B>
+static void skipWhitespace(B& in) {
+    while ((*in >= 9 && *in <= 13) || *in == 32)
+        ++in; }
+
+
+template<class B>
+static void skipLine(B& in) {
+    for (;;){
+        if (isEof(in)) return;
+        if (*in == '\n') { ++in; return; }
+        ++in; } }
+
+
+template<class B>
+static int parseInt(B& in) {
+    int     val = 0;
+    bool    neg = false;
+    skipWhitespace(in);
+    if      (*in == '-') neg = true, ++in;
+    else if (*in == '+') ++in;
+    if (*in < '0' || *in > '9') fprintf(stderr, "PARSE ERROR! Unexpected char: %c\n", *in), exit(3);
+    while (*in >= '0' && *in <= '9')
+        val = val*10 + (*in - '0'),
+        ++in;
+    return neg ? -val : val; }
+
+
+// String matching: in case of a match the input iterator will be advanced the corresponding
+// number of characters.
+template<class B>
+static bool match(B& in, const char* str) {
+    int i;
+    for (i = 0; str[i] != '\0'; i++)
+        if (in[i] != str[i])
+            return false;
+
+    in += i;
+
+    return true; 
+}
+
+// String matching: consumes characters eagerly, but does not require random access iterator.
+template<class B>
+static bool eagerMatch(B& in, const char* str) {
+    for (; *str != '\0'; ++str, ++in)
+        if (*str != *in)
+            return false;
+    return true; }
+
+
+//=================================================================================================
+}
+
+#endif
diff --git a/src/sat/bsat2/Queue.h b/src/sat/bsat2/Queue.h
new file mode 100644
index 0000000..11b4291
--- /dev/null
+++ b/src/sat/bsat2/Queue.h
@@ -0,0 +1,69 @@
+/*****************************************************************************************[Queue.h]
+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.
+**************************************************************************************************/
+
+#ifndef Minisat_Queue_h
+#define Minisat_Queue_h
+
+#include "Vec.h"
+
+namespace Minisat {
+
+//=================================================================================================
+
+template<class T>
+class Queue {
+    vec<T>  buf;
+    int     first;
+    int     end;
+
+public:
+    typedef T Key;
+
+    Queue() : buf(1), first(0), end(0) {}
+
+    void clear (bool dealloc = false) { buf.clear(dealloc); buf.growTo(1); first = end = 0; }
+    int  size  () const { return (end >= first) ? end - first : end - first + buf.size(); }
+
+    const T& operator [] (int index) const  { assert(index >= 0); assert(index < size()); return buf[(first + index) % buf.size()]; }
+    T&       operator [] (int index)        { assert(index >= 0); assert(index < size()); return buf[(first + index) % buf.size()]; }
+
+    T    peek  () const { assert(first != end); return buf[first]; }
+    void pop   () { assert(first != end); first++; if (first == buf.size()) first = 0; }
+    void insert(T elem) {   // INVARIANT: buf[end] is always unused
+        buf[end++] = elem;
+        if (end == buf.size()) end = 0;
+        if (first == end){  // Resize:
+            vec<T>  tmp((buf.size()*3 + 1) >> 1);
+            //**/printf("queue alloc: %d elems (%.1f MB)\n", tmp.size(), tmp.size() * sizeof(T) / 1000000.0);
+            int j, i = 0;
+            for (j = first; j < buf.size(); j++) tmp[i++] = buf[j];
+            for (j = 0    ; j < end       ; j++) tmp[i++] = buf[j];
+            first = 0;
+            end   = buf.size();
+            tmp.moveTo(buf);
+        }
+    }
+};
+
+
+//=================================================================================================
+}
+
+#endif
diff --git a/src/sat/bsat2/README b/src/sat/bsat2/README
new file mode 100644
index 0000000..e5e5617
--- /dev/null
+++ b/src/sat/bsat2/README
@@ -0,0 +1,24 @@
+================================================================================
+DIRECTORY OVERVIEW:
+
+mtl/            Mini Template Library
+utils/          Generic helper code (I/O, Parsing, CPU-time, etc)
+core/           A core version of the solver
+simp/           An extended solver with simplification capabilities
+README
+LICENSE
+
+================================================================================
+BUILDING: (release version: without assertions, statically linked, etc)
+
+export MROOT=<minisat-dir>              (or setenv in cshell)
+cd { core | simp }
+gmake rs
+cp minisat_static <install-dir>/minisat
+
+================================================================================
+EXAMPLES:
+
+Run minisat with same heuristics as version 2.0:
+
+> minisat <cnf-file> -no-luby -rinc=1.5 -phase-saving=0 -rnd-freq=0.02
diff --git a/src/sat/bsat2/ReleaseNotes-2.2.0.txt b/src/sat/bsat2/ReleaseNotes-2.2.0.txt
new file mode 100644
index 0000000..7f084de
--- /dev/null
+++ b/src/sat/bsat2/ReleaseNotes-2.2.0.txt
@@ -0,0 +1,79 @@
+Release Notes for MiniSat 2.2.0
+===============================
+
+Changes since version 2.0:
+
+ * Started using a more standard release numbering.
+
+ * Includes some now well-known heuristics: phase-saving and luby
+   restarts. The old heuristics are still present and can be activated
+   if needed.
+
+ * Detection/Handling of out-of-memory and vector capacity
+   overflow. This is fairly new and relatively untested.
+
+ * Simple resource controls: CPU-time, memory, number of
+   conflicts/decisions.
+
+ * CPU-time limiting is implemented by a more general, but simple,
+   asynchronous interruption feature. This means that the solving
+   procedure can be interrupted from another thread or in a signal
+   handler.
+
+ * Improved portability with respect to building on Solaris and with
+   Visual Studio. This is not regularly tested and chances are that
+   this have been broken since, but should be fairly easy to fix if
+   so.
+
+ * Changed C++ file-extention to the less problematic ".cc".
+
+ * Source code is now namespace-protected
+
+ * Introducing a new Clause Memory Allocator that brings reduced
+   memory consumption on 64-bit architechtures and improved
+   performance (to some extent). The allocator uses a region-based
+   approach were all references to clauses are represented as a 32-bit
+   index into a global memory region that contains all clauses. To
+   free up and compact memory it uses a simple copying garbage
+   collector.
+
+ * Improved unit-propagation by Blocking Literals. For each entry in
+   the watcher lists, pair the pointer to a clause with some
+   (arbitrary) literal from the clause. The idea is that if the
+   literal is currently true (i.e. the clause is satisfied) the
+   watchers of the clause does not need to be altered. This can thus
+   be detected without touching the clause's memory at all. As often
+   as can be done cheaply, the blocking literal for entries to the
+   watcher list of a literal 'p' is set to the other literal watched
+   in the corresponding clause.
+
+ * Basic command-line/option handling system. Makes it easy to specify
+   options in the class that they affect, and whenever that class is
+   used in an executable, parsing of options and help messages are
+   brought in automatically.
+
+ * General clean-up and various minor bug-fixes.
+
+ * Changed implementation of variable-elimination/model-extension:
+    
+     - The interface is changed so that arbitrary remembering is no longer
+       possible. If you need to mention some variable again in the future,
+       this variable has to be frozen.
+    
+     - When eliminating a variable, only clauses that contain the variable
+       with one sign is necessary to store. Thereby making the other sign
+       a "default" value when extending models.
+    
+     - The memory consumption for eliminated clauses is further improved
+       by storing all eliminated clauses in a single contiguous vector.
+
+  * Some common utility code (I/O, Parsing, CPU-time, etc) is ripped
+    out and placed in a separate "utils" directory.
+
+  * The DIMACS parse is refactored so that it can be reused in other
+    applications (not very elegant, but at least possible).
+
+  * Some simple improvements to scalability of preprocessing, using
+    more lazy clause removal from data-structures and a couple of
+    ad-hoc limits (the longest clause that can be produced in variable
+    elimination, and the longest clause used in backward subsumption).
diff --git a/src/sat/bsat2/SimpSolver.cpp b/src/sat/bsat2/SimpSolver.cpp
new file mode 100644
index 0000000..c4a905e
--- /dev/null
+++ b/src/sat/bsat2/SimpSolver.cpp
@@ -0,0 +1,720 @@
+/***********************************************************************************[SimpSolver.cc]
+Copyright (c) 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.
+**************************************************************************************************/
+
+#include "Sort.h"
+#include "SimpSolver.h"
+#include "System.h"
+
+using namespace Minisat;
+
+//=================================================================================================
+// Options:
+
+
+static const char* _cat = "SIMP";
+
+static BoolOption   opt_use_asymm        (_cat, "asymm",        "Shrink clauses by asymmetric branching.", false);
+static BoolOption   opt_use_rcheck       (_cat, "rcheck",       "Check if a clause is already implied. (costly)", false);
+static BoolOption   opt_use_elim         (_cat, "elim",         "Perform variable elimination.", true);
+static IntOption    opt_grow             (_cat, "grow",         "Allow a variable elimination step to grow by a number of clauses.", 0);
+static IntOption    opt_clause_lim       (_cat, "cl-lim",       "Variables are not eliminated if it produces a resolvent with a length above this limit. -1 means no limit", 20,   IntRange(-1, INT32_MAX));
+static IntOption    opt_subsumption_lim  (_cat, "sub-lim",      "Do not check if subsumption against a clause larger than this. -1 means no limit.", 1000, IntRange(-1, INT32_MAX));
+static DoubleOption opt_simp_garbage_frac(_cat, "simp-gc-frac", "The fraction of wasted memory allowed before a garbage collection is triggered during simplification.",  0.5, DoubleRange(0, false, HUGE_VAL, false));
+
+
+//=================================================================================================
+// Constructor/Destructor:
+
+
+SimpSolver::SimpSolver() :
+    grow               (opt_grow)
+  , clause_lim         (opt_clause_lim)
+  , subsumption_lim    (opt_subsumption_lim)
+  , simp_garbage_frac  (opt_simp_garbage_frac)
+  , use_asymm          (opt_use_asymm)
+  , use_rcheck         (opt_use_rcheck)
+  , use_elim           (opt_use_elim)
+  , merges             (0)
+  , asymm_lits         (0)
+  , eliminated_vars    (0)
+  , elimorder          (1)
+  , use_simplification (true)
+  , occurs             (ClauseDeleted(ca))
+  , elim_heap          (ElimLt(n_occ))
+  , bwdsub_assigns     (0)
+  , n_touched          (0)
+{
+    vec<Lit> dummy(1,lit_Undef);
+    ca.extra_clause_field = true; // NOTE: must happen before allocating the dummy clause below.
+    bwdsub_tmpunit        = ca.alloc(dummy);
+    remove_satisfied      = false;
+}
+
+
+SimpSolver::~SimpSolver()
+{
+}
+
+
+Var SimpSolver::newVar(bool sign, bool dvar) {
+    Var v = Solver::newVar(sign, dvar);
+
+    frozen    .push((char)false);
+    eliminated.push((char)false);
+
+    if (use_simplification){
+        n_occ     .push(0);
+        n_occ     .push(0);
+        occurs    .init(v);
+        touched   .push(0);
+        elim_heap .insert(v);
+    }
+    return v; }
+
+
+
+lbool SimpSolver::solve_(bool do_simp, bool turn_off_simp)
+{
+    vec<Var> extra_frozen;
+    lbool    result = l_True;
+
+    do_simp &= use_simplification;
+
+    if (do_simp){
+        // Assumptions must be temporarily frozen to run variable elimination:
+        for (int i = 0; i < assumptions.size(); i++){
+            Var v = var(assumptions[i]);
+
+            // If an assumption has been eliminated, remember it.
+            assert(!isEliminated(v));
+
+            if (!frozen[v]){
+                // Freeze and store.
+                setFrozen(v, true);
+                extra_frozen.push(v);
+            } }
+
+        result = lbool(eliminate(turn_off_simp));
+    }
+
+    if (result == l_True)
+        result = Solver::solve_();
+    else if (verbosity >= 1)
+        printf("===============================================================================\n");
+
+    if (result == l_True)
+        extendModel();
+
+    if (do_simp)
+        // Unfreeze the assumptions that were frozen:
+        for (int i = 0; i < extra_frozen.size(); i++)
+            setFrozen(extra_frozen[i], false);
+
+    return result;
+}
+
+
+
+bool SimpSolver::addClause_(vec<Lit>& ps)
+{
+#ifndef NDEBUG
+    for (int i = 0; i < ps.size(); i++)
+        assert(!isEliminated(var(ps[i])));
+#endif
+
+    int nclauses = clauses.size();
+
+    if (use_rcheck && implied(ps))
+        return true;
+
+    if (!Solver::addClause_(ps))
+        return false;
+
+    if (use_simplification && clauses.size() == nclauses + 1){
+        CRef          cr = clauses.last();
+        const Clause& c  = ca[cr];
+
+        // NOTE: the clause is added to the queue immediately and then
+        // again during 'gatherTouchedClauses()'. If nothing happens
+        // in between, it will only be checked once. Otherwise, it may
+        // be checked twice unnecessarily. This is an unfortunate
+        // consequence of how backward subsumption is used to mimic
+        // forward subsumption.
+        subsumption_queue.insert(cr);
+        for (int i = 0; i < c.size(); i++){
+            occurs[var(c[i])].push(cr);
+            n_occ[toInt(c[i])]++;
+            touched[var(c[i])] = 1;
+            n_touched++;
+            if (elim_heap.inHeap(var(c[i])))
+                elim_heap.increase(var(c[i]));
+        }
+    }
+
+    return true;
+}
+
+
+void SimpSolver::removeClause(CRef cr)
+{
+    const Clause& c = ca[cr];
+
+    if (use_simplification)
+        for (int i = 0; i < c.size(); i++){
+            n_occ[toInt(c[i])]--;
+            updateElimHeap(var(c[i]));
+            occurs.smudge(var(c[i]));
+        }
+
+    Solver::removeClause(cr);
+}
+
+
+bool SimpSolver::strengthenClause(CRef cr, Lit l)
+{
+    Clause& c = ca[cr];
+    assert(decisionLevel() == 0);
+    assert(use_simplification);
+
+    // FIX: this is too inefficient but would be nice to have (properly implemented)
+    // if (!find(subsumption_queue, &c))
+    subsumption_queue.insert(cr);
+
+    if (c.size() == 2){
+        removeClause(cr);
+        c.strengthen(l);
+    }else{
+        detachClause(cr, true);
+        c.strengthen(l);
+        attachClause(cr);
+        remove(occurs[var(l)], cr);
+        n_occ[toInt(l)]--;
+        updateElimHeap(var(l));
+    }
+
+    return c.size() == 1 ? enqueue(c[0]) && propagate() == CRef_Undef : true;
+}
+
+
+// Returns FALSE if clause is always satisfied ('out_clause' should not be used).
+bool SimpSolver::merge(const Clause& _ps, const Clause& _qs, Var v, vec<Lit>& out_clause)
+{
+    merges++;
+    out_clause.clear();
+
+    bool  ps_smallest = _ps.size() < _qs.size();
+    const Clause& ps  =  ps_smallest ? _qs : _ps;
+    const Clause& qs  =  ps_smallest ? _ps : _qs;
+    int i, j;
+
+    for (i = 0; i < qs.size(); i++){
+        if (var(qs[i]) != v){
+            for (j = 0; j < ps.size(); j++)
+                if (var(ps[j]) == var(qs[i]))
+                    if (ps[j] == ~qs[i])
+                        return false;
+                    else
+                        goto next;
+            out_clause.push(qs[i]);
+        }
+        next:;
+    }
+
+    for (i = 0; i < ps.size(); i++)
+        if (var(ps[i]) != v)
+            out_clause.push(ps[i]);
+
+    return true;
+}
+
+
+// Returns FALSE if clause is always satisfied.
+bool SimpSolver::merge(const Clause& _ps, const Clause& _qs, Var v, int& size)
+{
+    merges++;
+
+    bool  ps_smallest = _ps.size() < _qs.size();
+    const Clause& ps  =  ps_smallest ? _qs : _ps;
+    const Clause& qs  =  ps_smallest ? _ps : _qs;
+    const Lit*  __ps  = (const Lit*)ps;
+    const Lit*  __qs  = (const Lit*)qs;
+
+    size = ps.size()-1;
+
+    for (int i = 0; i < qs.size(); i++){
+        if (var(__qs[i]) != v){
+            for (int j = 0; j < ps.size(); j++)
+                if (var(__ps[j]) == var(__qs[i]))
+                    if (__ps[j] == ~__qs[i])
+                        return false;
+                    else
+                        goto next;
+            size++;
+        }
+        next:;
+    }
+
+    return true;
+}
+
+
+void SimpSolver::gatherTouchedClauses()
+{
+    if (n_touched == 0) return;
+
+    int i,j;
+    for (i = j = 0; i < subsumption_queue.size(); i++)
+        if (ca[subsumption_queue[i]].mark() == 0)
+            ca[subsumption_queue[i]].mark(2);
+
+    for (i = 0; i < touched.size(); i++)
+        if (touched[i]){
+            const vec<CRef>& cs = occurs.lookup(i);
+            for (j = 0; j < cs.size(); j++)
+                if (ca[cs[j]].mark() == 0){
+                    subsumption_queue.insert(cs[j]);
+                    ca[cs[j]].mark(2);
+                }
+            touched[i] = 0;
+        }
+
+    for (i = 0; i < subsumption_queue.size(); i++)
+        if (ca[subsumption_queue[i]].mark() == 2)
+            ca[subsumption_queue[i]].mark(0);
+
+    n_touched = 0;
+}
+
+
+bool SimpSolver::implied(const vec<Lit>& c)
+{
+    assert(decisionLevel() == 0);
+
+    trail_lim.push(trail.size());
+    for (int i = 0; i < c.size(); i++)
+        if (value(c[i]) == l_True){
+            cancelUntil(0);
+            return false;
+        }else if (value(c[i]) != l_False){
+            assert(value(c[i]) == l_Undef);
+            uncheckedEnqueue(~c[i]);
+        }
+
+    bool result = propagate() != CRef_Undef;
+    cancelUntil(0);
+    return result;
+}
+
+
+// Backward subsumption + backward subsumption resolution
+bool SimpSolver::backwardSubsumptionCheck(bool verbose)
+{
+    int cnt = 0;
+    int subsumed = 0;
+    int deleted_literals = 0;
+    assert(decisionLevel() == 0);
+
+    while (subsumption_queue.size() > 0 || bwdsub_assigns < trail.size()){
+
+        // Empty subsumption queue and return immediately on user-interrupt:
+        if (asynch_interrupt){
+            subsumption_queue.clear();
+            bwdsub_assigns = trail.size();
+            break; }
+
+        // Check top-level assignments by creating a dummy clause and placing it in the queue:
+        if (subsumption_queue.size() == 0 && bwdsub_assigns < trail.size()){
+            Lit l = trail[bwdsub_assigns++];
+            ca[bwdsub_tmpunit][0] = l;
+            ca[bwdsub_tmpunit].calcAbstraction();
+            subsumption_queue.insert(bwdsub_tmpunit); }
+
+        CRef    cr = subsumption_queue.peek(); subsumption_queue.pop();
+        Clause& c  = ca[cr];
+
+        if (c.mark()) continue;
+
+        if (verbose && verbosity >= 2 && cnt++ % 1000 == 0)
+            printf("subsumption left: %10d (%10d subsumed, %10d deleted literals)\r", subsumption_queue.size(), subsumed, deleted_literals);
+
+        assert(c.size() > 1 || value(c[0]) == l_True);    // Unit-clauses should have been propagated before this point.
+
+        // Find best variable to scan:
+        Var best = var(c[0]);
+        for (int i = 1; i < c.size(); i++)
+            if (occurs[var(c[i])].size() < occurs[best].size())
+                best = var(c[i]);
+
+        // Search all candidates:
+        vec<CRef>& _cs = occurs.lookup(best);
+        CRef*       cs = (CRef*)_cs;
+
+        for (int j = 0; j < _cs.size(); j++)
+            if (c.mark())
+                break;
+            else if (!ca[cs[j]].mark() &&  cs[j] != cr && (subsumption_lim == -1 || ca[cs[j]].size() < subsumption_lim)){
+                Lit l = c.subsumes(ca[cs[j]]);
+
+                if (l == lit_Undef)
+                    subsumed++, removeClause(cs[j]);
+                else if (l != lit_Error){
+                    deleted_literals++;
+
+                    if (!strengthenClause(cs[j], ~l))
+                        return false;
+
+                    // Did current candidate get deleted from cs? Then check candidate at index j again:
+                    if (var(l) == best)
+                        j--;
+                }
+            }
+    }
+
+    return true;
+}
+
+
+bool SimpSolver::asymm(Var v, CRef cr)
+{
+    Clause& c = ca[cr];
+    assert(decisionLevel() == 0);
+
+    if (c.mark() || satisfied(c)) return true;
+
+    trail_lim.push(trail.size());
+    Lit l = lit_Undef;
+    for (int i = 0; i < c.size(); i++)
+        if (var(c[i]) != v && value(c[i]) != l_False)
+            uncheckedEnqueue(~c[i]);
+        else
+            l = c[i];
+
+    if (propagate() != CRef_Undef){
+        cancelUntil(0);
+        asymm_lits++;
+        if (!strengthenClause(cr, l))
+            return false;
+    }else
+        cancelUntil(0);
+
+    return true;
+}
+
+
+bool SimpSolver::asymmVar(Var v)
+{
+    assert(use_simplification);
+
+    const vec<CRef>& cls = occurs.lookup(v);
+
+    if (value(v) != l_Undef || cls.size() == 0)
+        return true;
+
+    for (int i = 0; i < cls.size(); i++)
+        if (!asymm(v, cls[i]))
+            return false;
+
+    return backwardSubsumptionCheck();
+}
+
+
+static void mkElimClause(vec<uint32_t>& elimclauses, Lit x)
+{
+    elimclauses.push(toInt(x));
+    elimclauses.push(1);
+}
+
+
+static void mkElimClause(vec<uint32_t>& elimclauses, Var v, Clause& c)
+{
+    int first = elimclauses.size();
+    int v_pos = -1;
+
+    // Copy clause to elimclauses-vector. Remember position where the
+    // variable 'v' occurs:
+    for (int i = 0; i < c.size(); i++){
+        elimclauses.push(toInt(c[i]));
+        if (var(c[i]) == v)
+            v_pos = i + first;
+    }
+    assert(v_pos != -1);
+
+    // Swap the first literal with the 'v' literal, so that the literal
+    // containing 'v' will occur first in the clause:
+    uint32_t tmp = elimclauses[v_pos];
+    elimclauses[v_pos] = elimclauses[first];
+    elimclauses[first] = tmp;
+
+    // Store the length of the clause last:
+    elimclauses.push(c.size());
+}
+
+
+
+bool SimpSolver::eliminateVar(Var v)
+{
+    assert(!frozen[v]);
+    assert(!isEliminated(v));
+    assert(value(v) == l_Undef);
+    int i;
+
+    // Split the occurrences into positive and negative:
+    //
+    const vec<CRef>& cls = occurs.lookup(v);
+    vec<CRef>        pos, neg;
+    for (i = 0; i < cls.size(); i++)
+        (find(ca[cls[i]], mkLit(v)) ? pos : neg).push(cls[i]);
+
+    // Check wether the increase in number of clauses stays within the allowed ('grow'). Moreover, no
+    // clause must exceed the limit on the maximal clause size (if it is set):
+    //
+    int cnt         = 0;
+    int clause_size = 0;
+
+    for (i = 0; i < pos.size(); i++)
+        for (int j = 0; j < neg.size(); j++)
+            if (merge(ca[pos[i]], ca[neg[j]], v, clause_size) && 
+                (++cnt > cls.size() + grow || (clause_lim != -1 && clause_size > clause_lim)))
+                return true;
+
+    // Delete and store old clauses:
+    eliminated[v] = true;
+    setDecisionVar(v, false);
+    eliminated_vars++;
+
+    if (pos.size() > neg.size()){
+        for (int i = 0; i < neg.size(); i++)
+            mkElimClause(elimclauses, v, ca[neg[i]]);
+        mkElimClause(elimclauses, mkLit(v));
+    }else{
+        for (int i = 0; i < pos.size(); i++)
+            mkElimClause(elimclauses, v, ca[pos[i]]);
+        mkElimClause(elimclauses, ~mkLit(v));
+    }
+
+    for (i = 0; i < cls.size(); i++)
+        removeClause(cls[i]); 
+
+    // Produce clauses in cross product:
+    vec<Lit>& resolvent = add_tmp;
+    for (i = 0; i < pos.size(); i++)
+        for (int j = 0; j < neg.size(); j++)
+            if (merge(ca[pos[i]], ca[neg[j]], v, resolvent) && !addClause_(resolvent))
+                return false;
+
+    // Free occurs list for this variable:
+    occurs[v].clear(true);
+    
+    // Free watchers lists for this variable, if possible:
+    if (watches[ mkLit(v)].size() == 0) watches[ mkLit(v)].clear(true);
+    if (watches[~mkLit(v)].size() == 0) watches[~mkLit(v)].clear(true);
+
+    return backwardSubsumptionCheck();
+}
+
+
+bool SimpSolver::substitute(Var v, Lit x)
+{
+    assert(!frozen[v]);
+    assert(!isEliminated(v));
+    assert(value(v) == l_Undef);
+
+    if (!ok) return false;
+
+    eliminated[v] = true;
+    setDecisionVar(v, false);
+    const vec<CRef>& cls = occurs.lookup(v);
+    
+    vec<Lit>& subst_clause = add_tmp;
+    for (int i = 0; i < cls.size(); i++){
+        Clause& c = ca[cls[i]];
+
+        subst_clause.clear();
+        for (int j = 0; j < c.size(); j++){
+            Lit p = c[j];
+            subst_clause.push(var(p) == v ? x ^ sign(p) : p);
+        }
+
+        removeClause(cls[i]);
+
+        if (!addClause_(subst_clause))
+            return ok = false;
+    }
+
+    return true;
+}
+
+
+void SimpSolver::extendModel()
+{
+    int i, j;
+    Lit x;
+
+    for (i = elimclauses.size()-1; i > 0; i -= j){
+        for (j = elimclauses[i--]; j > 1; j--, i--)
+            if (modelValue(toLit(elimclauses[i])) != l_False)
+                goto next;
+
+        x = toLit(elimclauses[i]);
+        model[var(x)] = lbool(!sign(x));
+    next:;
+    }
+}
+
+
+bool SimpSolver::eliminate(bool turn_off_elim)
+{
+    if (!simplify())
+        return false;
+    else if (!use_simplification)
+        return true;
+
+    // Main simplification loop:
+    //
+    while (n_touched > 0 || bwdsub_assigns < trail.size() || elim_heap.size() > 0){
+
+        gatherTouchedClauses();
+        // printf("  ## (time = %6.2f s) BWD-SUB: queue = %d, trail = %d\n", cpuTime(), subsumption_queue.size(), trail.size() - bwdsub_assigns);
+        if ((subsumption_queue.size() > 0 || bwdsub_assigns < trail.size()) && 
+            !backwardSubsumptionCheck(true)){
+            ok = false; goto cleanup; }
+
+        // Empty elim_heap and return immediately on user-interrupt:
+        if (asynch_interrupt){
+            assert(bwdsub_assigns == trail.size());
+            assert(subsumption_queue.size() == 0);
+            assert(n_touched == 0);
+            elim_heap.clear();
+            goto cleanup; }
+
+        // printf("  ## (time = %6.2f s) ELIM: vars = %d\n", cpuTime(), elim_heap.size());
+        for (int cnt = 0; !elim_heap.empty(); cnt++){
+            Var elim = elim_heap.removeMin();
+            
+            if (asynch_interrupt) break;
+
+            if (isEliminated(elim) || value(elim) != l_Undef) continue;
+
+            if (verbosity >= 2 && cnt % 100 == 0)
+                printf("elimination left: %10d\r", elim_heap.size());
+
+            if (use_asymm){
+                // Temporarily freeze variable. Otherwise, it would immediately end up on the queue again:
+                bool was_frozen = frozen[elim];
+                frozen[elim] = true;
+                if (!asymmVar(elim)){
+                    ok = false; goto cleanup; }
+                frozen[elim] = was_frozen; }
+
+            // At this point, the variable may have been set by assymetric branching, so check it
+            // again. Also, don't eliminate frozen variables:
+            if (use_elim && value(elim) == l_Undef && !frozen[elim] && !eliminateVar(elim)){
+                ok = false; goto cleanup; }
+
+            checkGarbage(simp_garbage_frac);
+        }
+
+        assert(subsumption_queue.size() == 0);
+    }
+ cleanup:
+
+    // If no more simplification is needed, free all simplification-related data structures:
+    if (turn_off_elim){
+        touched  .clear(true);
+        occurs   .clear(true);
+        n_occ    .clear(true);
+        elim_heap.clear(true);
+        subsumption_queue.clear(true);
+
+        use_simplification    = false;
+        remove_satisfied      = true;
+        ca.extra_clause_field = false;
+
+        // Force full cleanup (this is safe and desirable since it only happens once):
+        rebuildOrderHeap();
+        garbageCollect();
+    }else{
+        // Cheaper cleanup:
+        cleanUpClauses(); // TODO: can we make 'cleanUpClauses()' not be linear in the problem size somehow?
+        checkGarbage();
+    }
+
+    if (verbosity >= 1 && elimclauses.size() > 0)
+        printf("|  Eliminated clauses:     %10.2f Mb                                      |\n", 
+               double(elimclauses.size() * sizeof(uint32_t)) / (1024*1024));
+
+    return ok;
+}
+
+
+void SimpSolver::cleanUpClauses()
+{
+    occurs.cleanAll();
+    int i,j;
+    for (i = j = 0; i < clauses.size(); i++)
+        if (ca[clauses[i]].mark() == 0)
+            clauses[j++] = clauses[i];
+    clauses.shrink(i - j);
+}
+
+
+//=================================================================================================
+// Garbage Collection methods:
+
+
+void SimpSolver::relocAll(ClauseAllocator& to)
+{
+    if (!use_simplification) return;
+
+    // All occurs lists:
+    //
+    int i;
+    for (i = 0; i < nVars(); i++){
+        vec<CRef>& cs = occurs[i];
+        for (int j = 0; j < cs.size(); j++)
+            ca.reloc(cs[j], to);
+    }
+
+    // Subsumption queue:
+    //
+    for (i = 0; i < subsumption_queue.size(); i++)
+        ca.reloc(subsumption_queue[i], to);
+
+    // Temporary clause:
+    //
+    ca.reloc(bwdsub_tmpunit, to);
+}
+
+
+void SimpSolver::garbageCollect()
+{
+    // Initialize the next region to a size corresponding to the estimated utilization degree. This
+    // is not precise but should avoid some unnecessary reallocations for the new region:
+    ClauseAllocator to(ca.size() - ca.wasted()); 
+
+    cleanUpClauses();
+    to.extra_clause_field = ca.extra_clause_field; // NOTE: this is important to keep (or lose) the extra fields.
+    relocAll(to);
+    Solver::relocAll(to);
+    if (verbosity >= 2)
+        printf("|  Garbage collection:   %12d bytes => %12d bytes             |\n", 
+               ca.size()*ClauseAllocator::Unit_Size, to.size()*ClauseAllocator::Unit_Size);
+    to.moveTo(ca);
+}
diff --git a/src/sat/bsat2/SimpSolver.h b/src/sat/bsat2/SimpSolver.h
new file mode 100644
index 0000000..e24b0e4
--- /dev/null
+++ b/src/sat/bsat2/SimpSolver.h
@@ -0,0 +1,197 @@
+/************************************************************************************[SimpSolver.h]
+Copyright (c) 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.
+**************************************************************************************************/
+
+#ifndef Minisat_SimpSolver_h
+#define Minisat_SimpSolver_h
+
+#include "Queue.h"
+#include "Solver.h"
+
+
+namespace Minisat {
+
+//=================================================================================================
+
+
+class SimpSolver : public Solver {
+ public:
+    // Constructor/Destructor:
+    //
+    SimpSolver();
+    ~SimpSolver();
+
+    // Problem specification:
+    //
+    Var     newVar    (bool polarity = true, bool dvar = true);
+    bool    addClause (const vec<Lit>& ps);
+    bool    addEmptyClause();                // Add the empty clause to the solver.
+    bool    addClause (Lit p);               // Add a unit clause to the solver.
+    bool    addClause (Lit p, Lit q);        // Add a binary clause to the solver.
+    bool    addClause (Lit p, Lit q, Lit r); // Add a ternary clause to the solver.
+    bool    addClause_(      vec<Lit>& ps);
+    bool    substitute(Var v, Lit x);  // Replace all occurences of v with x (may cause a contradiction).
+
+    // Variable mode:
+    // 
+    void    setFrozen (Var v, bool b); // If a variable is frozen it will not be eliminated.
+    bool    isEliminated(Var v) const;
+
+    // Solving:
+    //
+    bool    solve       (const vec<Lit>& assumps, bool do_simp = true, bool turn_off_simp = false);
+    lbool   solveLimited(const vec<Lit>& assumps, bool do_simp = true, bool turn_off_simp = false);
+    bool    solve       (                     bool do_simp = true, bool turn_off_simp = false);
+    bool    solve       (Lit p       ,        bool do_simp = true, bool turn_off_simp = false);       
+    bool    solve       (Lit p, Lit q,        bool do_simp = true, bool turn_off_simp = false);
+    bool    solve       (Lit p, Lit q, Lit r, bool do_simp = true, bool turn_off_simp = false);
+    bool    eliminate   (bool turn_off_elim = false);  // Perform variable elimination based simplification. 
+
+    // Memory managment:
+    //
+    virtual void garbageCollect();
+
+
+    // Generate a (possibly simplified) DIMACS file:
+    //
+#if 0
+    void    toDimacs  (const char* file, const vec<Lit>& assumps);
+    void    toDimacs  (const char* file);
+    void    toDimacs  (const char* file, Lit p);
+    void    toDimacs  (const char* file, Lit p, Lit q);
+    void    toDimacs  (const char* file, Lit p, Lit q, Lit r);
+#endif
+
+    // Mode of operation:
+    //
+    int     grow;              // Allow a variable elimination step to grow by a number of clauses (default to zero).
+    int     clause_lim;        // Variables are not eliminated if it produces a resolvent with a length above this limit.
+                               // -1 means no limit.
+    int     subsumption_lim;   // Do not check if subsumption against a clause larger than this. -1 means no limit.
+    double  simp_garbage_frac; // A different limit for when to issue a GC during simplification (Also see 'garbage_frac').
+
+    bool    use_asymm;         // Shrink clauses by asymmetric branching.
+    bool    use_rcheck;        // Check if a clause is already implied. Prett costly, and subsumes subsumptions :)
+    bool    use_elim;          // Perform variable elimination.
+
+    // Statistics:
+    //
+    int     merges;
+    int     asymm_lits;
+    int     eliminated_vars;
+
+ protected:
+
+    // Helper structures:
+    //
+    struct ElimLt {
+        const vec<int>& n_occ;
+        explicit ElimLt(const vec<int>& no) : n_occ(no) {}
+
+        // TODO: are 64-bit operations here noticably bad on 32-bit platforms? Could use a saturating
+        // 32-bit implementation instead then, but this will have to do for now.
+        uint64_t cost  (Var x)        const { return (uint64_t)n_occ[toInt(mkLit(x))] * (uint64_t)n_occ[toInt(~mkLit(x))]; }
+        bool operator()(Var x, Var y) const { return cost(x) < cost(y); }
+        
+        // TODO: investigate this order alternative more.
+        // bool operator()(Var x, Var y) const { 
+        //     int c_x = cost(x);
+        //     int c_y = cost(y);
+        //     return c_x < c_y || c_x == c_y && x < y; }
+    };
+
+    struct ClauseDeleted {
+        const ClauseAllocator& ca;
+        explicit ClauseDeleted(const ClauseAllocator& _ca) : ca(_ca) {}
+        bool operator()(const CRef& cr) const { return ca[cr].mark() == 1; } };
+
+    // Solver state:
+    //
+    int                 elimorder;
+    bool                use_simplification;
+    vec<uint32_t>       elimclauses;
+    vec<char>           touched;
+    OccLists<Var, vec<CRef>, ClauseDeleted>
+                        occurs;
+    vec<int>            n_occ;
+    Heap<ElimLt>        elim_heap;
+    Queue<CRef>         subsumption_queue;
+    vec<char>           frozen;
+    vec<char>           eliminated;
+    int                 bwdsub_assigns;
+    int                 n_touched;
+
+    // Temporaries:
+    //
+    CRef                bwdsub_tmpunit;
+
+    // Main internal methods:
+    //
+    lbool         solve_                   (bool do_simp = true, bool turn_off_simp = false);
+    bool          asymm                    (Var v, CRef cr);
+    bool          asymmVar                 (Var v);
+    void          updateElimHeap           (Var v);
+    void          gatherTouchedClauses     ();
+    bool          merge                    (const Clause& _ps, const Clause& _qs, Var v, vec<Lit>& out_clause);
+    bool          merge                    (const Clause& _ps, const Clause& _qs, Var v, int& size);
+    bool          backwardSubsumptionCheck (bool verbose = false);
+    bool          eliminateVar             (Var v);
+    void          extendModel              ();
+
+    void          removeClause             (CRef cr);
+    bool          strengthenClause         (CRef cr, Lit l);
+    void          cleanUpClauses           ();
+    bool          implied                  (const vec<Lit>& c);
+    void          relocAll                 (ClauseAllocator& to);
+};
+
+
+//=================================================================================================
+// Implementation of inline methods:
+
+
+inline bool SimpSolver::isEliminated (Var v) const { return eliminated[v]; }
+inline void SimpSolver::updateElimHeap(Var v) {
+    assert(use_simplification);
+    // if (!frozen[v] && !isEliminated(v) && value(v) == l_Undef)
+    if (elim_heap.inHeap(v) || (!frozen[v] && !isEliminated(v) && value(v) == l_Undef))
+        elim_heap.update(v); }
+
+
+inline bool SimpSolver::addClause    (const vec<Lit>& ps)    { ps.copyTo(add_tmp); return addClause_(add_tmp); }
+inline bool SimpSolver::addEmptyClause()                     { add_tmp.clear(); return addClause_(add_tmp); }
+inline bool SimpSolver::addClause    (Lit p)                 { add_tmp.clear(); add_tmp.push(p); return addClause_(add_tmp); }
+inline bool SimpSolver::addClause    (Lit p, Lit q)          { add_tmp.clear(); add_tmp.push(p); add_tmp.push(q); return addClause_(add_tmp); }
+inline bool SimpSolver::addClause    (Lit p, Lit q, Lit r)   { add_tmp.clear(); add_tmp.push(p); add_tmp.push(q); add_tmp.push(r); return addClause_(add_tmp); }
+inline void SimpSolver::setFrozen    (Var v, bool b) { frozen[v] = (char)b; if (use_simplification && !b) { updateElimHeap(v); } }
+
+inline bool SimpSolver::solve        (                     bool do_simp, bool turn_off_simp)  { budgetOff(); assumptions.clear(); return solve_(do_simp, turn_off_simp) == l_True; }
+inline bool SimpSolver::solve        (Lit p       ,        bool do_simp, bool turn_off_simp)  { budgetOff(); assumptions.clear(); assumptions.push(p); return solve_(do_simp, turn_off_simp) == l_True; }
+inline bool SimpSolver::solve        (Lit p, Lit q,        bool do_simp, bool turn_off_simp)  { budgetOff(); assumptions.clear(); assumptions.push(p); assumptions.push(q); return solve_(do_simp, turn_off_simp) == l_True; }
+inline bool SimpSolver::solve        (Lit p, Lit q, Lit r, bool do_simp, bool turn_off_simp)  { budgetOff(); assumptions.clear(); assumptions.push(p); assumptions.push(q); assumptions.push(r); return solve_(do_simp, turn_off_simp) == l_True; }
+inline bool SimpSolver::solve        (const vec<Lit>& assumps, bool do_simp, bool turn_off_simp){ 
+    budgetOff(); assumps.copyTo(assumptions); return solve_(do_simp, turn_off_simp) == l_True; }
+
+inline lbool SimpSolver::solveLimited (const vec<Lit>& assumps, bool do_simp, bool turn_off_simp){ 
+    assumps.copyTo(assumptions); return solve_(do_simp, turn_off_simp); }
+
+//=================================================================================================
+}
+
+#endif
diff --git a/src/sat/bsat2/Solver.cpp b/src/sat/bsat2/Solver.cpp
new file mode 100644
index 0000000..8a56d64
--- /dev/null
+++ b/src/sat/bsat2/Solver.cpp
@@ -0,0 +1,924 @@
+/***************************************************************************************[Solver.cc]
+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.
+**************************************************************************************************/
+
+#include <math.h>
+
+#include "Sort.h"
+#include "Solver.h"
+
+using namespace Minisat;
+
+//=================================================================================================
+// Options:
+
+
+static const char* _cat = "CORE";
+
+static DoubleOption  opt_var_decay         (_cat, "var-decay",   "The variable activity decay factor",            0.95,     DoubleRange(0, false, 1, false));
+static DoubleOption  opt_clause_decay      (_cat, "cla-decay",   "The clause activity decay factor",              0.999,    DoubleRange(0, false, 1, false));
+static DoubleOption  opt_random_var_freq   (_cat, "rnd-freq",    "The frequency with which the decision heuristic tries to choose a random variable", 0, DoubleRange(0, true, 1, true));
+static DoubleOption  opt_random_seed       (_cat, "rnd-seed",    "Used by the random variable selection",         91648253, DoubleRange(0, false, HUGE_VAL, false));
+static IntOption     opt_ccmin_mode        (_cat, "ccmin-mode",  "Controls conflict clause minimization (0=none, 1=basic, 2=deep)", 2, IntRange(0, 2));
+static IntOption     opt_phase_saving      (_cat, "phase-saving", "Controls the level of phase saving (0=none, 1=limited, 2=full)", 2, IntRange(0, 2));
+static BoolOption    opt_rnd_init_act      (_cat, "rnd-init",    "Randomize the initial activity", false);
+static BoolOption    opt_luby_restart      (_cat, "luby",        "Use the Luby restart sequence", true);
+static IntOption     opt_restart_first     (_cat, "rfirst",      "The base restart interval", 100, IntRange(1, INT32_MAX));
+static DoubleOption  opt_restart_inc       (_cat, "rinc",        "Restart interval increase factor", 2, DoubleRange(1, false, HUGE_VAL, false));
+static DoubleOption  opt_garbage_frac      (_cat, "gc-frac",     "The fraction of wasted memory allowed before a garbage collection is triggered",  0.20, DoubleRange(0, false, HUGE_VAL, false));
+
+
+//=================================================================================================
+// Constructor/Destructor:
+
+
+Solver::Solver() :
+
+    // Parameters (user settable):
+    //
+    verbosity        (0)
+  , var_decay        (opt_var_decay)
+  , clause_decay     (opt_clause_decay)
+  , random_var_freq  (opt_random_var_freq)
+  , random_seed      (opt_random_seed)
+  , luby_restart     (opt_luby_restart)
+  , ccmin_mode       (opt_ccmin_mode)
+  , phase_saving     (opt_phase_saving)
+  , rnd_pol          (false)
+  , rnd_init_act     (opt_rnd_init_act)
+  , garbage_frac     (opt_garbage_frac)
+  , restart_first    (opt_restart_first)
+  , restart_inc      (opt_restart_inc)
+
+    // Parameters (the rest):
+    //
+  , learntsize_factor((double)1/(double)3), learntsize_inc(1.1)
+
+    // Parameters (experimental):
+    //
+  , learntsize_adjust_start_confl (100)
+  , learntsize_adjust_inc         (1.5)
+
+    // Statistics: (formerly in 'SolverStats')
+    //
+  , solves(0), starts(0), decisions(0), rnd_decisions(0), propagations(0), conflicts(0)
+  , dec_vars(0), clauses_literals(0), learnts_literals(0), max_literals(0), tot_literals(0)
+
+  , ok                 (true)
+  , cla_inc            (1)
+  , var_inc            (1)
+  , watches            (WatcherDeleted(ca))
+  , qhead              (0)
+  , simpDB_assigns     (-1)
+  , simpDB_props       (0)
+  , order_heap         (VarOrderLt(activity))
+  , progress_estimate  (0)
+  , remove_satisfied   (true)
+
+    // Resource constraints:
+    //
+  , conflict_budget    (-1)
+  , propagation_budget (-1)
+  , asynch_interrupt   (false)
+{}
+
+
+Solver::~Solver()
+{
+}
+
+
+//=================================================================================================
+// Minor methods:
+
+
+// Creates a new SAT variable in the solver. If 'decision' is cleared, variable will not be
+// used as a decision variable (NOTE! This has effects on the meaning of a SATISFIABLE result).
+//
+Var Solver::newVar(bool sign, bool dvar)
+{
+    int v = nVars();
+    watches  .init(mkLit(v, false));
+    watches  .init(mkLit(v, true ));
+    assigns  .push(l_Undef);
+    vardata  .push(mkVarData(CRef_Undef, 0));
+    //activity .push(0);
+    activity .push(rnd_init_act ? drand(random_seed) * 0.00001 : 0);
+    seen     .push(0);
+    polarity .push(sign);
+    decision .push();
+    trail    .capacity(v+1);
+    setDecisionVar(v, dvar);
+    return v;
+}
+
+
+bool Solver::addClause_(vec<Lit>& ps)
+{
+    assert(decisionLevel() == 0);
+    if (!ok) return false;
+
+    // Check if clause is satisfied and remove false/duplicate literals:
+    sort(ps);
+    Lit p; int i, j;
+    for (i = j = 0, p = lit_Undef; i < ps.size(); i++)
+        if (value(ps[i]) == l_True || ps[i] == ~p)
+            return true;
+        else if (value(ps[i]) != l_False && ps[i] != p)
+            ps[j++] = p = ps[i];
+    ps.shrink(i - j);
+
+    if (ps.size() == 0)
+        return ok = false;
+    else if (ps.size() == 1){
+        uncheckedEnqueue(ps[0]);
+        return ok = (propagate() == CRef_Undef);
+    }else{
+        CRef cr = ca.alloc(ps, false);
+        clauses.push(cr);
+        attachClause(cr);
+    }
+
+    return true;
+}
+
+
+void Solver::attachClause(CRef cr) {
+    const Clause& c = ca[cr];
+    assert(c.size() > 1);
+    watches[~c[0]].push(Watcher(cr, c[1]));
+    watches[~c[1]].push(Watcher(cr, c[0]));
+    if (c.learnt()) learnts_literals += c.size();
+    else            clauses_literals += c.size(); }
+
+
+void Solver::detachClause(CRef cr, bool strict) {
+    const Clause& c = ca[cr];
+    assert(c.size() > 1);
+    
+    if (strict){
+        remove(watches[~c[0]], Watcher(cr, c[1]));
+        remove(watches[~c[1]], Watcher(cr, c[0]));
+    }else{
+        // Lazy detaching: (NOTE! Must clean all watcher lists before garbage collecting this clause)
+        watches.smudge(~c[0]);
+        watches.smudge(~c[1]);
+    }
+
+    if (c.learnt()) learnts_literals -= c.size();
+    else            clauses_literals -= c.size(); }
+
+
+void Solver::removeClause(CRef cr) {
+    Clause& c = ca[cr];
+    detachClause(cr);
+    // Don't leave pointers to free'd memory!
+    if (locked(c)) vardata[var(c[0])].reason = CRef_Undef;
+    c.mark(1); 
+    ca._free(cr);
+}
+
+
+bool Solver::satisfied(const Clause& c) const {
+    for (int i = 0; i < c.size(); i++)
+        if (value(c[i]) == l_True)
+            return true;
+    return false; }
+
+
+// Revert to the state at given level (keeping all assignment at 'level' but not beyond).
+//
+void Solver::cancelUntil(int level) {
+    if (decisionLevel() > level){
+        for (int c = trail.size()-1; c >= trail_lim[level]; c--){
+            Var      x  = var(trail[c]);
+            assigns [x] = l_Undef;
+            if (phase_saving > 1 || (phase_saving == 1) && c > trail_lim.last())
+                polarity[x] = sign(trail[c]);
+            insertVarOrder(x); }
+        qhead = trail_lim[level];
+        trail.shrink(trail.size() - trail_lim[level]);
+        trail_lim.shrink(trail_lim.size() - level);
+    } }
+
+
+//=================================================================================================
+// Major methods:
+
+
+Lit Solver::pickBranchLit()
+{
+    Var next = var_Undef;
+
+    // Random decision:
+    if (drand(random_seed) < random_var_freq && !order_heap.empty()){
+        next = order_heap[irand(random_seed,order_heap.size())];
+        if (value(next) == l_Undef && decision[next])
+            rnd_decisions++; }
+
+    // Activity based decision:
+    while (next == var_Undef || value(next) != l_Undef || !decision[next])
+        if (order_heap.empty()){
+            next = var_Undef;
+            break;
+        }else
+            next = order_heap.removeMin();
+
+    return next == var_Undef ? lit_Undef : mkLit(next, rnd_pol ? drand(random_seed) < 0.5 : polarity[next]);
+}
+
+
+/*_________________________________________________________________________________________________
+|
+|  analyze : (confl : Clause*) (out_learnt : vec<Lit>&) (out_btlevel : int&)  ->  [void]
+|  
+|  Description:
+|    Analyze conflict and produce a reason clause.
+|  
+|    Pre-conditions:
+|      * 'out_learnt' is assumed to be cleared.
+|      * Current decision level must be greater than root level.
+|  
+|    Post-conditions:
+|      * 'out_learnt[0]' is the asserting literal at level 'out_btlevel'.
+|      * If out_learnt.size() > 1 then 'out_learnt[1]' has the greatest decision level of the 
+|        rest of literals. There may be others from the same level though.
+|  
+|________________________________________________________________________________________________@*/
+void Solver::analyze(CRef confl, vec<Lit>& out_learnt, int& out_btlevel)
+{
+    int pathC = 0;
+    Lit p     = lit_Undef;
+
+    // Generate conflict clause:
+    //
+    out_learnt.push();      // (leave room for the asserting literal)
+    int index   = trail.size() - 1;
+
+    do{
+        assert(confl != CRef_Undef); // (otherwise should be UIP)
+        Clause& c = ca[confl];
+
+        if (c.learnt())
+            claBumpActivity(c);
+
+        for (int j = (p == lit_Undef) ? 0 : 1; j < c.size(); j++){
+            Lit q = c[j];
+
+            if (!seen[var(q)] && level(var(q)) > 0){
+                varBumpActivity(var(q));
+                seen[var(q)] = 1;
+                if (level(var(q)) >= decisionLevel())
+                    pathC++;
+                else
+                    out_learnt.push(q);
+            }
+        }
+        
+        // Select next clause to look at:
+        while (!seen[var(trail[index--])]);
+        p     = trail[index+1];
+        confl = reason(var(p));
+        seen[var(p)] = 0;
+        pathC--;
+
+    }while (pathC > 0);
+    out_learnt[0] = ~p;
+
+    // Simplify conflict clause:
+    //
+    int i, j;
+    out_learnt.copyTo(analyze_toclear);
+    if (ccmin_mode == 2){
+        uint32_t abstract_level = 0;
+        for (i = 1; i < out_learnt.size(); i++)
+            abstract_level |= abstractLevel(var(out_learnt[i])); // (maintain an abstraction of levels involved in conflict)
+
+        for (i = j = 1; i < out_learnt.size(); i++)
+            if (reason(var(out_learnt[i])) == CRef_Undef || !litRedundant(out_learnt[i], abstract_level))
+                out_learnt[j++] = out_learnt[i];
+        
+    }else if (ccmin_mode == 1){
+        for (i = j = 1; i < out_learnt.size(); i++){
+            Var x = var(out_learnt[i]);
+
+            if (reason(x) == CRef_Undef)
+                out_learnt[j++] = out_learnt[i];
+            else{
+                Clause& c = ca[reason(var(out_learnt[i]))];
+                for (int k = 1; k < c.size(); k++)
+                    if (!seen[var(c[k])] && level(var(c[k])) > 0){
+                        out_learnt[j++] = out_learnt[i];
+                        break; }
+            }
+        }
+    }else
+        i = j = out_learnt.size();
+
+    max_literals += out_learnt.size();
+    out_learnt.shrink(i - j);
+    tot_literals += out_learnt.size();
+
+    // Find correct backtrack level:
+    //
+    if (out_learnt.size() == 1)
+        out_btlevel = 0;
+    else{
+        int max_i = 1;
+        // Find the first literal assigned at the next-highest level:
+        for (int i = 2; i < out_learnt.size(); i++)
+            if (level(var(out_learnt[i])) > level(var(out_learnt[max_i])))
+                max_i = i;
+        // Swap-in this literal at index 1:
+        Lit p             = out_learnt[max_i];
+        out_learnt[max_i] = out_learnt[1];
+        out_learnt[1]     = p;
+        out_btlevel       = level(var(p));
+    }
+
+    for (j = 0; j < analyze_toclear.size(); j++) seen[var(analyze_toclear[j])] = 0;    // ('seen[]' is now cleared)
+}
+
+
+// Check if 'p' can be removed. 'abstract_levels' is used to abort early if the algorithm is
+// visiting literals at levels that cannot be removed later.
+bool Solver::litRedundant(Lit p, uint32_t abstract_levels)
+{
+    analyze_stack.clear(); analyze_stack.push(p);
+    int top = analyze_toclear.size();
+    while (analyze_stack.size() > 0){
+        assert(reason(var(analyze_stack.last())) != CRef_Undef);
+        Clause& c = ca[reason(var(analyze_stack.last()))]; analyze_stack.pop();
+
+        for (int i = 1; i < c.size(); i++){
+            Lit p  = c[i];
+            if (!seen[var(p)] && level(var(p)) > 0){
+                if (reason(var(p)) != CRef_Undef && (abstractLevel(var(p)) & abstract_levels) != 0){
+                    seen[var(p)] = 1;
+                    analyze_stack.push(p);
+                    analyze_toclear.push(p);
+                }else{
+                    for (int j = top; j < analyze_toclear.size(); j++)
+                        seen[var(analyze_toclear[j])] = 0;
+                    analyze_toclear.shrink(analyze_toclear.size() - top);
+                    return false;
+                }
+            }
+        }
+    }
+
+    return true;
+}
+
+
+/*_________________________________________________________________________________________________
+|
+|  analyzeFinal : (p : Lit)  ->  [void]
+|  
+|  Description:
+|    Specialized analysis procedure to express the final conflict in terms of assumptions.
+|    Calculates the (possibly empty) set of assumptions that led to the assignment of 'p', and
+|    stores the result in 'out_conflict'.
+|________________________________________________________________________________________________@*/
+void Solver::analyzeFinal(Lit p, vec<Lit>& out_conflict)
+{
+    out_conflict.clear();
+    out_conflict.push(p);
+
+    if (decisionLevel() == 0)
+        return;
+
+    seen[var(p)] = 1;
+
+    for (int i = trail.size()-1; i >= trail_lim[0]; i--){
+        Var x = var(trail[i]);
+        if (seen[x]){
+            if (reason(x) == CRef_Undef){
+                assert(level(x) > 0);
+                out_conflict.push(~trail[i]);
+            }else{
+                Clause& c = ca[reason(x)];
+                for (int j = 1; j < c.size(); j++)
+                    if (level(var(c[j])) > 0)
+                        seen[var(c[j])] = 1;
+            }
+            seen[x] = 0;
+        }
+    }
+
+    seen[var(p)] = 0;
+}
+
+
+void Solver::uncheckedEnqueue(Lit p, CRef from)
+{
+    assert(value(p) == l_Undef);
+    assigns[var(p)] = lbool(!sign(p));
+    vardata[var(p)] = mkVarData(from, decisionLevel());
+    trail.push_(p);
+}
+
+
+/*_________________________________________________________________________________________________
+|
+|  propagate : [void]  ->  [Clause*]
+|  
+|  Description:
+|    Propagates all enqueued facts. If a conflict arises, the conflicting clause is returned,
+|    otherwise CRef_Undef.
+|  
+|    Post-conditions:
+|      * the propagation queue is empty, even if there was a conflict.
+|________________________________________________________________________________________________@*/
+CRef Solver::propagate()
+{
+    CRef    confl     = CRef_Undef;
+    int     num_props = 0;
+    watches.cleanAll();
+
+    while (qhead < trail.size()){
+        Lit            p   = trail[qhead++];     // 'p' is enqueued fact to propagate.
+        vec<Watcher>&  ws  = watches[p];
+        Watcher        *i, *j, *end;
+        num_props++;
+
+        for (i = j = (Watcher*)ws, end = i + ws.size();  i != end;){
+            // Try to avoid inspecting the clause:
+            Lit blocker = i->blocker;
+            if (value(blocker) == l_True){
+                *j++ = *i++; continue; }
+
+            // Make sure the false literal is data[1]:
+            CRef     cr        = i->cref;
+            Clause&  c         = ca[cr];
+            Lit      false_lit = ~p;
+            if (c[0] == false_lit)
+                c[0] = c[1], c[1] = false_lit;
+            assert(c[1] == false_lit);
+            i++;
+
+            // If 0th watch is true, then clause is already satisfied.
+            Lit     first = c[0];
+            Watcher w     = Watcher(cr, first);
+            if (first != blocker && value(first) == l_True){
+                *j++ = w; continue; }
+
+            // Look for new watch:
+            for (int k = 2; k < c.size(); k++)
+                if (value(c[k]) != l_False){
+                    c[1] = c[k]; c[k] = false_lit;
+                    watches[~c[1]].push(w);
+                    goto NextClause; }
+
+            // Did not find watch -- clause is unit under assignment:
+            *j++ = w;
+            if (value(first) == l_False){
+                confl = cr;
+                qhead = trail.size();
+                // Copy the remaining watches:
+                while (i < end)
+                    *j++ = *i++;
+            }else
+                uncheckedEnqueue(first, cr);
+
+        NextClause:;
+        }
+        ws.shrink(i - j);
+    }
+    propagations += num_props;
+    simpDB_props -= num_props;
+
+    return confl;
+}
+
+
+/*_________________________________________________________________________________________________
+|
+|  reduceDB : ()  ->  [void]
+|  
+|  Description:
+|    Remove half of the learnt clauses, minus the clauses locked by the current assignment. Locked
+|    clauses are clauses that are reason to some assignment. Binary clauses are never removed.
+|________________________________________________________________________________________________@*/
+struct reduceDB_lt { 
+    ClauseAllocator& ca;
+    reduceDB_lt(ClauseAllocator& ca_) : ca(ca_) {}
+    bool operator () (CRef x, CRef y) { 
+        return ca[x].size() > 2 && (ca[y].size() == 2 || ca[x].activity() < ca[y].activity()); } 
+};
+void Solver::reduceDB()
+{
+    int     i, j;
+    double  extra_lim = cla_inc / learnts.size();    // Remove any clause below this activity
+
+    sort(learnts, reduceDB_lt(ca));
+    // Don't delete binary or locked clauses. From the rest, delete clauses from the first half
+    // and clauses with activity smaller than 'extra_lim':
+    for (i = j = 0; i < learnts.size(); i++){
+        Clause& c = ca[learnts[i]];
+        if (c.size() > 2 && !locked(c) && (i < learnts.size() / 2 || c.activity() < extra_lim))
+            removeClause(learnts[i]);
+        else
+            learnts[j++] = learnts[i];
+    }
+    learnts.shrink(i - j);
+    checkGarbage();
+}
+
+
+void Solver::removeSatisfied(vec<CRef>& cs)
+{
+    int i, j;
+    for (i = j = 0; i < cs.size(); i++){
+        Clause& c = ca[cs[i]];
+        if (satisfied(c))
+            removeClause(cs[i]);
+        else
+            cs[j++] = cs[i];
+    }
+    cs.shrink(i - j);
+}
+
+
+void Solver::rebuildOrderHeap()
+{
+    vec<Var> vs;
+    for (Var v = 0; v < nVars(); v++)
+        if (decision[v] && value(v) == l_Undef)
+            vs.push(v);
+    order_heap.build(vs);
+}
+
+
+/*_________________________________________________________________________________________________
+|
+|  simplify : [void]  ->  [bool]
+|  
+|  Description:
+|    Simplify the clause database according to the current top-level assigment. Currently, the only
+|    thing done here is the removal of satisfied clauses, but more things can be put here.
+|________________________________________________________________________________________________@*/
+bool Solver::simplify()
+{
+    assert(decisionLevel() == 0);
+
+    if (!ok || propagate() != CRef_Undef)
+        return ok = false;
+
+    if (nAssigns() == simpDB_assigns || (simpDB_props > 0))
+        return true;
+
+    // Remove satisfied clauses:
+    removeSatisfied(learnts);
+    if (remove_satisfied)        // Can be turned off.
+        removeSatisfied(clauses);
+    checkGarbage();
+    rebuildOrderHeap();
+
+    simpDB_assigns = nAssigns();
+    simpDB_props   = clauses_literals + learnts_literals;   // (shouldn't depend on stats really, but it will do for now)
+
+    return true;
+}
+
+
+/*_________________________________________________________________________________________________
+|
+|  search : (nof_conflicts : int) (params : const SearchParams&)  ->  [lbool]
+|  
+|  Description:
+|    Search for a model the specified number of conflicts. 
+|    NOTE! Use negative value for 'nof_conflicts' indicate infinity.
+|  
+|  Output:
+|    'l_True' if a partial assigment that is consistent with respect to the clauseset is found. If
+|    all variables are decision variables, this means that the clause set is satisfiable. 'l_False'
+|    if the clause set is unsatisfiable. 'l_Undef' if the bound on number of conflicts is reached.
+|________________________________________________________________________________________________@*/
+lbool Solver::search(int nof_conflicts)
+{
+    assert(ok);
+    int         backtrack_level;
+    int         conflictC = 0;
+    vec<Lit>    learnt_clause;
+    starts++;
+
+    for (;;){
+        CRef confl = propagate();
+        if (confl != CRef_Undef){
+            // CONFLICT
+            conflicts++; conflictC++;
+            if (decisionLevel() == 0) return l_False;
+
+            learnt_clause.clear();
+            analyze(confl, learnt_clause, backtrack_level);
+            cancelUntil(backtrack_level);
+
+            if (learnt_clause.size() == 1){
+                uncheckedEnqueue(learnt_clause[0]);
+            }else{
+                CRef cr = ca.alloc(learnt_clause, true);
+                learnts.push(cr);
+                attachClause(cr);
+                claBumpActivity(ca[cr]);
+                uncheckedEnqueue(learnt_clause[0], cr);
+            }
+
+            varDecayActivity();
+            claDecayActivity();
+
+            if (--learntsize_adjust_cnt == 0){
+                learntsize_adjust_confl *= learntsize_adjust_inc;
+                learntsize_adjust_cnt    = (int)learntsize_adjust_confl;
+                max_learnts             *= learntsize_inc;
+
+                if (verbosity >= 1)
+                    printf("| %9d | %7d %8d %8d | %8d %8d %6.0f | %6.3f %% |\n", 
+                           (int)conflicts, 
+                           (int)dec_vars - (trail_lim.size() == 0 ? trail.size() : trail_lim[0]), nClauses(), (int)clauses_literals, 
+                           (int)max_learnts, nLearnts(), ((double)((int64_t)learnts_literals))/nLearnts(), progressEstimate()*100);
+            }
+
+        }else{
+            // NO CONFLICT
+            if (nof_conflicts >= 0 && conflictC >= nof_conflicts || !withinBudget()){
+                // Reached bound on number of conflicts:
+                progress_estimate = progressEstimate();
+                cancelUntil(0);
+                return l_Undef; }
+
+            // Simplify the set of problem clauses:
+            if (decisionLevel() == 0 && !simplify())
+                return l_False;
+
+            if (learnts.size()-nAssigns() >= max_learnts)
+                // Reduce the set of learnt clauses:
+                reduceDB();
+
+            Lit next = lit_Undef;
+            while (decisionLevel() < assumptions.size()){
+                // Perform user provided assumption:
+                Lit p = assumptions[decisionLevel()];
+                if (value(p) == l_True){
+                    // Dummy decision level:
+                    newDecisionLevel();
+                }else if (value(p) == l_False){
+                    analyzeFinal(~p, conflict);
+                    return l_False;
+                }else{
+                    next = p;
+                    break;
+                }
+            }
+
+            if (next == lit_Undef){
+                // New variable decision:
+                decisions++;
+                next = pickBranchLit();
+
+                if (next == lit_Undef)
+                    // Model found:
+                    return l_True;
+            }
+
+            // Increase decision level and enqueue 'next'
+            newDecisionLevel();
+            uncheckedEnqueue(next);
+        }
+    }
+}
+
+
+double Solver::progressEstimate() const
+{
+    double  progress = 0;
+    double  F = 1.0 / nVars();
+
+    for (int i = 0; i <= decisionLevel(); i++){
+        int beg = i == 0 ? 0 : trail_lim[i - 1];
+        int end = i == decisionLevel() ? trail.size() : trail_lim[i];
+        progress += pow(F, i) * (end - beg);
+    }
+
+    return progress / nVars();
+}
+
+/*
+  Finite subsequences of the Luby-sequence:
+
+  0: 1
+  1: 1 1 2
+  2: 1 1 2 1 1 2 4
+  3: 1 1 2 1 1 2 4 1 1 2 1 1 2 4 8
+  ...
+
+
+ */
+
+static double luby(double y, int x){
+
+    // Find the finite subsequence that contains index 'x', and the
+    // size of that subsequence:
+    int size, seq;
+    for (size = 1, seq = 0; size < x+1; seq++, size = 2*size+1);
+
+    while (size-1 != x){
+        size = (size-1)>>1;
+        seq--;
+        x = x % size;
+    }
+
+    return pow(y, seq);
+}
+
+// NOTE: assumptions passed in member-variable 'assumptions'.
+lbool Solver::solve_()
+{
+    model.clear();
+    conflict.clear();
+    if (!ok) return l_False;
+
+    solves++;
+
+    max_learnts               = nClauses() * learntsize_factor;
+    learntsize_adjust_confl   = learntsize_adjust_start_confl;
+    learntsize_adjust_cnt     = (int)learntsize_adjust_confl;
+    lbool   status            = l_Undef;
+
+    if (verbosity >= 1){
+        printf("============================[ Search Statistics ]==============================\n");
+        printf("| Conflicts |          ORIGINAL         |          LEARNT          | Progress |\n");
+        printf("|           |    Vars  Clauses Literals |    Limit  Clauses Lit/Cl |          |\n");
+        printf("===============================================================================\n");
+    }
+
+    // Search:
+    int curr_restarts = 0;
+    while (status == l_Undef){
+        double rest_base = luby_restart ? luby(restart_inc, curr_restarts) : pow(restart_inc, curr_restarts);
+        status = search(rest_base * restart_first);
+        if (!withinBudget()) break;
+        curr_restarts++;
+    }
+
+    if (verbosity >= 1)
+        printf("===============================================================================\n");
+
+
+    if (status == l_True){
+        // Extend & copy model:
+        model.growTo(nVars());
+        for (int i = 0; i < nVars(); i++) model[i] = value(i);
+    }else if (status == l_False && conflict.size() == 0)
+        ok = false;
+
+    cancelUntil(0);
+    return status;
+}
+
+//=================================================================================================
+// Writing CNF to DIMACS:
+// 
+// FIXME: this needs to be rewritten completely.
+
+static Var mapVar(Var x, vec<Var>& map, Var& max)
+{
+    if (map.size() <= x || map[x] == -1){
+        map.growTo(x+1, -1);
+        map[x] = max++;
+    }
+    return map[x];
+}
+
+
+void Solver::toDimacs(FILE* f, Clause& c, vec<Var>& map, Var& max)
+{
+    if (satisfied(c)) return;
+
+    for (int i = 0; i < c.size(); i++)
+        if (value(c[i]) != l_False)
+            fprintf(f, "%s%d ", sign(c[i]) ? "-" : "", mapVar(var(c[i]), map, max)+1);
+    fprintf(f, "0\n");
+}
+
+
+void Solver::toDimacs(const char *file, const vec<Lit>& assumps)
+{
+    FILE* f = fopen(file, "wr");
+    if (f == NULL)
+        fprintf(stderr, "could not open file %s\n", file), exit(1);
+    toDimacs(f, assumps);
+    fclose(f);
+}
+
+
+void Solver::toDimacs(FILE* f, const vec<Lit>& assumps)
+{
+    // Handle case when solver is in contradictory state:
+    if (!ok){
+        fprintf(f, "p cnf 1 2\n1 0\n-1 0\n");
+        return; }
+
+    vec<Var> map; Var max = 0;
+
+    // Cannot use removeClauses here because it is not safe
+    // to deallocate them at this point. Could be improved.
+    int i, cnt = 0;
+    for (i = 0; i < clauses.size(); i++)
+        if (!satisfied(ca[clauses[i]]))
+            cnt++;
+        
+    for (i = 0; i < clauses.size(); i++)
+        if (!satisfied(ca[clauses[i]])){
+            Clause& c = ca[clauses[i]];
+            for (int j = 0; j < c.size(); j++)
+                if (value(c[j]) != l_False)
+                    mapVar(var(c[j]), map, max);
+        }
+
+    // Assumptions are added as unit clauses:
+    cnt += assumptions.size();
+
+    fprintf(f, "p cnf %d %d\n", max, cnt);
+
+    for (i = 0; i < assumptions.size(); i++){
+        assert(value(assumptions[i]) != l_False);
+        fprintf(f, "%s%d 0\n", sign(assumptions[i]) ? "-" : "", mapVar(var(assumptions[i]), map, max)+1);
+    }
+
+    for (i = 0; i < clauses.size(); i++)
+        toDimacs(f, ca[clauses[i]], map, max);
+
+    if (verbosity > 0)
+        printf("Wrote %d clauses with %d variables.\n", cnt, max);
+}
+
+
+//=================================================================================================
+// Garbage Collection methods:
+
+void Solver::relocAll(ClauseAllocator& to)
+{
+    // All watchers:
+    //
+    // for (int i = 0; i < watches.size(); i++)
+    watches.cleanAll();
+    for (int v = 0; v < nVars(); v++)
+        for (int s = 0; s < 2; s++){
+            Lit p = mkLit(v, s);
+            // printf(" >>> RELOCING: %s%d\n", sign(p)?"-":"", var(p)+1);
+            vec<Watcher>& ws = watches[p];
+            for (int j = 0; j < ws.size(); j++)
+                ca.reloc(ws[j].cref, to);
+        }
+
+    // All reasons:
+    //
+    int i;
+    for (i = 0; i < trail.size(); i++){
+        Var v = var(trail[i]);
+
+        if (reason(v) != CRef_Undef && (ca[reason(v)].reloced() || locked(ca[reason(v)])))
+            ca.reloc(vardata[v].reason, to);
+    }
+
+    // All learnt:
+    //
+    for (i = 0; i < learnts.size(); i++)
+        ca.reloc(learnts[i], to);
+
+    // All original:
+    //
+    for (i = 0; i < clauses.size(); i++)
+        ca.reloc(clauses[i], to);
+}
+
+
+void Solver::garbageCollect()
+{
+    // Initialize the next region to a size corresponding to the estimated utilization degree. This
+    // is not precise but should avoid some unnecessary reallocations for the new region:
+    ClauseAllocator to(ca.size() - ca.wasted()); 
+
+    relocAll(to);
+    if (verbosity >= 2)
+        printf("|  Garbage collection:   %12d bytes => %12d bytes             |\n", 
+               ca.size()*ClauseAllocator::Unit_Size, to.size()*ClauseAllocator::Unit_Size);
+    to.moveTo(ca);
+}
diff --git a/src/sat/bsat2/Solver.h b/src/sat/bsat2/Solver.h
new file mode 100644
index 0000000..fc0bb4b
--- /dev/null
+++ b/src/sat/bsat2/Solver.h
@@ -0,0 +1,373 @@
+/****************************************************************************************[Solver.h]
+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.
+**************************************************************************************************/
+
+#ifndef Minisat_Solver_h
+#define Minisat_Solver_h
+
+#include "Vec.h"
+#include "Heap.h"
+#include "Alg.h"
+#include "Options.h"
+#include "SolverTypes.h"
+
+
+namespace Minisat {
+
+//=================================================================================================
+// Solver -- the main class:
+
+class Solver {
+public:
+
+    // Constructor/Destructor:
+    //
+    Solver();
+    virtual ~Solver();
+
+    // Problem specification:
+    //
+    Var     newVar    (bool polarity = true, bool dvar = true); // Add a new variable with parameters specifying variable mode.
+
+    bool    addClause (const vec<Lit>& ps);                     // Add a clause to the solver. 
+    bool    addEmptyClause();                                   // Add the empty clause, making the solver contradictory.
+    bool    addClause (Lit p);                                  // Add a unit clause to the solver. 
+    bool    addClause (Lit p, Lit q);                           // Add a binary clause to the solver. 
+    bool    addClause (Lit p, Lit q, Lit r);                    // Add a ternary clause to the solver. 
+    bool    addClause_(      vec<Lit>& ps);                     // Add a clause to the solver without making superflous internal copy. Will
+                                                                // change the passed vector 'ps'.
+
+    // Solving:
+    //
+    bool    simplify     ();                        // Removes already satisfied clauses.
+    bool    solve        (const vec<Lit>& assumps); // Search for a model that respects a given set of assumptions.
+    lbool   solveLimited (const vec<Lit>& assumps); // Search for a model that respects a given set of assumptions (With resource constraints).
+    bool    solve        ();                        // Search without assumptions.
+    bool    solve        (Lit p);                   // Search for a model that respects a single assumption.
+    bool    solve        (Lit p, Lit q);            // Search for a model that respects two assumptions.
+    bool    solve        (Lit p, Lit q, Lit r);     // Search for a model that respects three assumptions.
+    bool    okay         () const;                  // FALSE means solver is in a conflicting state
+
+    void    toDimacs     (FILE* f, const vec<Lit>& assumps);            // Write CNF to file in DIMACS-format.
+    void    toDimacs     (const char *file, const vec<Lit>& assumps);
+    void    toDimacs     (FILE* f, Clause& c, vec<Var>& map, Var& max);
+
+    // Convenience versions of 'toDimacs()':
+    void    toDimacs     (const char* file);
+    void    toDimacs     (const char* file, Lit p);
+    void    toDimacs     (const char* file, Lit p, Lit q);
+    void    toDimacs     (const char* file, Lit p, Lit q, Lit r);
+    
+    // Variable mode:
+    // 
+    void    setPolarity    (Var v, bool b); // Declare which polarity the decision heuristic should use for a variable. Requires mode 'polarity_user'.
+    void    setDecisionVar (Var v, bool b); // Declare if a variable should be eligible for selection in the decision heuristic.
+
+    // Read state:
+    //
+    lbool   value      (Var x) const;       // The current value of a variable.
+    lbool   value      (Lit p) const;       // The current value of a literal.
+    lbool   modelValue (Var x) const;       // The value of a variable in the last model. The last call to solve must have been satisfiable.
+    lbool   modelValue (Lit p) const;       // The value of a literal in the last model. The last call to solve must have been satisfiable.
+    int     nAssigns   ()      const;       // The current number of assigned literals.
+    int     nClauses   ()      const;       // The current number of original clauses.
+    int     nLearnts   ()      const;       // The current number of learnt clauses.
+    int     nVars      ()      const;       // The current number of variables.
+    int     nFreeVars  ()      const;
+
+    // Resource contraints:
+    //
+    void    setConfBudget(int64_t x);
+    void    setPropBudget(int64_t x);
+    void    budgetOff();
+    void    interrupt();          // Trigger a (potentially asynchronous) interruption of the solver.
+    void    clearInterrupt();     // Clear interrupt indicator flag.
+
+    // Memory managment:
+    //
+    virtual void garbageCollect();
+    void    checkGarbage(double gf);
+    void    checkGarbage();
+
+    // Extra results: (read-only member variable)
+    //
+    vec<lbool> model;             // If problem is satisfiable, this vector contains the model (if any).
+    vec<Lit>   conflict;          // If problem is unsatisfiable (possibly under assumptions),
+                                  // this vector represent the final conflict clause expressed in the assumptions.
+
+    // Mode of operation:
+    //
+    int       verbosity;
+    double    var_decay;
+    double    clause_decay;
+    double    random_var_freq;
+    double    random_seed;
+    bool      luby_restart;
+    int       ccmin_mode;         // Controls conflict clause minimization (0=none, 1=basic, 2=deep).
+    int       phase_saving;       // Controls the level of phase saving (0=none, 1=limited, 2=full).
+    bool      rnd_pol;            // Use random polarities for branching heuristics.
+    bool      rnd_init_act;       // Initialize variable activities with a small random value.
+    double    garbage_frac;       // The fraction of wasted memory allowed before a garbage collection is triggered.
+
+    int       restart_first;      // The initial restart limit.                                                                (default 100)
+    double    restart_inc;        // The factor with which the restart limit is multiplied in each restart.                    (default 1.5)
+    double    learntsize_factor;  // The intitial limit for learnt clauses is a factor of the original clauses.                (default 1 / 3)
+    double    learntsize_inc;     // The limit for learnt clauses is multiplied with this factor each restart.                 (default 1.1)
+
+    int       learntsize_adjust_start_confl;
+    double    learntsize_adjust_inc;
+
+    // Statistics: (read-only member variable)
+    //
+    uint64_t solves, starts, decisions, rnd_decisions, propagations, conflicts;
+    uint64_t dec_vars, clauses_literals, learnts_literals, max_literals, tot_literals;
+
+protected:
+
+    // Helper structures:
+    //
+    struct VarData { CRef reason; int level; };
+    static inline VarData mkVarData(CRef cr, int l){ VarData d = {cr, l}; return d; }
+
+    struct Watcher {
+        CRef cref;
+        Lit  blocker;
+        Watcher(CRef cr, Lit p) : cref(cr), blocker(p) {}
+        bool operator==(const Watcher& w) const { return cref == w.cref; }
+        bool operator!=(const Watcher& w) const { return cref != w.cref; }
+    };
+
+    struct WatcherDeleted
+    {
+        const ClauseAllocator& ca;
+        WatcherDeleted(const ClauseAllocator& _ca) : ca(_ca) {}
+        bool operator()(const Watcher& w) const { return ca[w.cref].mark() == 1; }
+    };
+
+    struct VarOrderLt {
+        const vec<double>&  activity;
+        bool operator () (Var x, Var y) const { return activity[x] > activity[y]; }
+        VarOrderLt(const vec<double>&  act) : activity(act) { }
+    };
+
+    // Solver state:
+    //
+    bool                ok;               // If FALSE, the constraints are already unsatisfiable. No part of the solver state may be used!
+    vec<CRef>           clauses;          // List of problem clauses.
+    vec<CRef>           learnts;          // List of learnt clauses.
+    double              cla_inc;          // Amount to bump next clause with.
+    vec<double>         activity;         // A heuristic measurement of the activity of a variable.
+    double              var_inc;          // Amount to bump next variable with.
+    OccLists<Lit, vec<Watcher>, WatcherDeleted>
+                        watches;          // 'watches[lit]' is a list of constraints watching 'lit' (will go there if literal becomes true).
+    vec<lbool>          assigns;          // The current assignments.
+    vec<char>           polarity;         // The preferred polarity of each variable.
+    vec<char>           decision;         // Declares if a variable is eligible for selection in the decision heuristic.
+    vec<Lit>            trail;            // Assignment stack; stores all assigments made in the order they were made.
+    vec<int>            trail_lim;        // Separator indices for different decision levels in 'trail'.
+    vec<VarData>        vardata;          // Stores reason and level for each variable.
+    int                 qhead;            // Head of queue (as index into the trail -- no more explicit propagation queue in MiniSat).
+    int                 simpDB_assigns;   // Number of top-level assignments since last execution of 'simplify()'.
+    int64_t             simpDB_props;     // Remaining number of propagations that must be made before next execution of 'simplify()'.
+    vec<Lit>            assumptions;      // Current set of assumptions provided to solve by the user.
+    Heap<VarOrderLt>    order_heap;       // A priority queue of variables ordered with respect to the variable activity.
+    double              progress_estimate;// Set by 'search()'.
+    bool                remove_satisfied; // Indicates whether possibly inefficient linear scan for satisfied clauses should be performed in 'simplify'.
+
+    ClauseAllocator     ca;
+
+    // Temporaries (to reduce allocation overhead). Each variable is prefixed by the method in which it is
+    // used, exept 'seen' wich is used in several places.
+    //
+    vec<char>           seen;
+    vec<Lit>            analyze_stack;
+    vec<Lit>            analyze_toclear;
+    vec<Lit>            add_tmp;
+
+    double              max_learnts;
+    double              learntsize_adjust_confl;
+    int                 learntsize_adjust_cnt;
+
+    // Resource contraints:
+    //
+    int64_t             conflict_budget;    // -1 means no budget.
+    int64_t             propagation_budget; // -1 means no budget.
+    bool                asynch_interrupt;
+
+    // Main internal methods:
+    //
+    void     insertVarOrder   (Var x);                                                 // Insert a variable in the decision order priority queue.
+    Lit      pickBranchLit    ();                                                      // Return the next decision variable.
+    void     newDecisionLevel ();                                                      // Begins a new decision level.
+    void     uncheckedEnqueue (Lit p, CRef from = CRef_Undef);                         // Enqueue a literal. Assumes value of literal is undefined.
+    bool     enqueue          (Lit p, CRef from = CRef_Undef);                         // Test if fact 'p' contradicts current state, enqueue otherwise.
+    CRef     propagate        ();                                                      // Perform unit propagation. Returns possibly conflicting clause.
+    void     cancelUntil      (int level);                                             // Backtrack until a certain level.
+    void     analyze          (CRef confl, vec<Lit>& out_learnt, int& out_btlevel);    // (bt = backtrack)
+    void     analyzeFinal     (Lit p, vec<Lit>& out_conflict);                         // COULD THIS BE IMPLEMENTED BY THE ORDINARIY "analyze" BY SOME REASONABLE GENERALIZATION?
+    bool     litRedundant     (Lit p, uint32_t abstract_levels);                       // (helper method for 'analyze()')
+    lbool    search           (int nof_conflicts);                                     // Search for a given number of conflicts.
+    lbool    solve_           ();                                                      // Main solve method (assumptions given in 'assumptions').
+    void     reduceDB         ();                                                      // Reduce the set of learnt clauses.
+    void     removeSatisfied  (vec<CRef>& cs);                                         // Shrink 'cs' to contain only non-satisfied clauses.
+    void     rebuildOrderHeap ();
+
+    // Maintaining Variable/Clause activity:
+    //
+    void     varDecayActivity ();                      // Decay all variables with the specified factor. Implemented by increasing the 'bump' value instead.
+    void     varBumpActivity  (Var v, double inc);     // Increase a variable with the current 'bump' value.
+    void     varBumpActivity  (Var v);                 // Increase a variable with the current 'bump' value.
+    void     claDecayActivity ();                      // Decay all clauses with the specified factor. Implemented by increasing the 'bump' value instead.
+    void     claBumpActivity  (Clause& c);             // Increase a clause with the current 'bump' value.
+
+    // Operations on clauses:
+    //
+    void     attachClause     (CRef cr);               // Attach a clause to watcher lists.
+    void     detachClause     (CRef cr, bool strict = false); // Detach a clause to watcher lists.
+    void     removeClause     (CRef cr);               // Detach and free a clause.
+    bool     locked           (const Clause& c) const; // Returns TRUE if a clause is a reason for some implication in the current state.
+    bool     satisfied        (const Clause& c) const; // Returns TRUE if a clause is satisfied in the current state.
+
+    void     relocAll         (ClauseAllocator& to);
+
+    // Misc:
+    //
+    int      decisionLevel    ()      const; // Gives the current decisionlevel.
+    uint32_t abstractLevel    (Var x) const; // Used to represent an abstraction of sets of decision levels.
+    CRef     reason           (Var x) const;
+    int      level            (Var x) const;
+    double   progressEstimate ()      const; // DELETE THIS ?? IT'S NOT VERY USEFUL ...
+    bool     withinBudget     ()      const;
+
+    // Static helpers:
+    //
+
+    // Returns a random float 0 <= x < 1. Seed must never be 0.
+    static inline double drand(double& seed) {
+        seed *= 1389796;
+        int q = (int)(seed / 2147483647);
+        seed -= (double)q * 2147483647;
+        return seed / 2147483647; }
+
+    // Returns a random integer 0 <= x < size. Seed must never be 0.
+    static inline int irand(double& seed, int size) {
+        return (int)(drand(seed) * size); }
+};
+
+
+//=================================================================================================
+// Implementation of inline methods:
+
+inline CRef Solver::reason(Var x) const { return vardata[x].reason; }
+inline int  Solver::level (Var x) const { return vardata[x].level; }
+
+inline void Solver::insertVarOrder(Var x) {
+    if (!order_heap.inHeap(x) && decision[x]) order_heap.insert(x); }
+
+inline void Solver::varDecayActivity() { var_inc *= (1 / var_decay); }
+inline void Solver::varBumpActivity(Var v) { varBumpActivity(v, var_inc); }
+inline void Solver::varBumpActivity(Var v, double inc) {
+    if ( (activity[v] += inc) > 1e100 ) {
+        // Rescale:
+        for (int i = 0; i < nVars(); i++)
+            activity[i] *= 1e-100;
+        var_inc *= 1e-100; }
+
+    // Update order_heap with respect to new activity:
+    if (order_heap.inHeap(v))
+        order_heap.decrease(v); }
+
+inline void Solver::claDecayActivity() { cla_inc *= (1 / clause_decay); }
+inline void Solver::claBumpActivity (Clause& c) {
+        if ( (c.activity() += cla_inc) > 1e20 ) {
+            // Rescale:
+            for (int i = 0; i < learnts.size(); i++)
+                ca[learnts[i]].activity() *= (float)1e-20;
+            cla_inc *= 1e-20; } }
+
+inline void Solver::checkGarbage(void){ checkGarbage(garbage_frac); }
+inline void Solver::checkGarbage(double gf){
+    if (ca.wasted() > ca.size() * gf)
+        garbageCollect(); }
+
+// NOTE: enqueue does not set the ok flag! (only public methods do)
+inline bool     Solver::enqueue         (Lit p, CRef from)      { return value(p) != l_Undef ? value(p) != l_False : (uncheckedEnqueue(p, from), true); }
+inline bool     Solver::addClause       (const vec<Lit>& ps)    { ps.copyTo(add_tmp); return addClause_(add_tmp); }
+inline bool     Solver::addEmptyClause  ()                      { add_tmp.clear(); return addClause_(add_tmp); }
+inline bool     Solver::addClause       (Lit p)                 { add_tmp.clear(); add_tmp.push(p); return addClause_(add_tmp); }
+inline bool     Solver::addClause       (Lit p, Lit q)          { add_tmp.clear(); add_tmp.push(p); add_tmp.push(q); return addClause_(add_tmp); }
+inline bool     Solver::addClause       (Lit p, Lit q, Lit r)   { add_tmp.clear(); add_tmp.push(p); add_tmp.push(q); add_tmp.push(r); return addClause_(add_tmp); }
+inline bool     Solver::locked          (const Clause& c) const { return value(c[0]) == l_True && reason(var(c[0])) != CRef_Undef && ca.lea(reason(var(c[0]))) == &c; }
+inline void     Solver::newDecisionLevel()                      { trail_lim.push(trail.size()); }
+
+inline int      Solver::decisionLevel ()      const   { return trail_lim.size(); }
+inline uint32_t Solver::abstractLevel (Var x) const   { return 1 << (level(x) & 31); }
+inline lbool    Solver::value         (Var x) const   { return assigns[x]; }
+inline lbool    Solver::value         (Lit p) const   { return assigns[var(p)] ^ sign(p); }
+inline lbool    Solver::modelValue    (Var x) const   { return model[x]; }
+inline lbool    Solver::modelValue    (Lit p) const   { return model[var(p)] ^ sign(p); }
+inline int      Solver::nAssigns      ()      const   { return trail.size(); }
+inline int      Solver::nClauses      ()      const   { return clauses.size(); }
+inline int      Solver::nLearnts      ()      const   { return learnts.size(); }
+inline int      Solver::nVars         ()      const   { return vardata.size(); }
+inline int      Solver::nFreeVars     ()      const   { return (int)dec_vars - (trail_lim.size() == 0 ? trail.size() : trail_lim[0]); }
+inline void     Solver::setPolarity   (Var v, bool b) { polarity[v] = b; }
+inline void     Solver::setDecisionVar(Var v, bool b) 
+{ 
+    if      ( b && !decision[v]) dec_vars++;
+    else if (!b &&  decision[v]) dec_vars--;
+
+    decision[v] = b;
+    insertVarOrder(v);
+}
+inline void     Solver::setConfBudget(int64_t x){ conflict_budget    = conflicts    + x; }
+inline void     Solver::setPropBudget(int64_t x){ propagation_budget = propagations + x; }
+inline void     Solver::interrupt(){ asynch_interrupt = true; }
+inline void     Solver::clearInterrupt(){ asynch_interrupt = false; }
+inline void     Solver::budgetOff(){ conflict_budget = propagation_budget = -1; }
+inline bool     Solver::withinBudget() const {
+    return !asynch_interrupt &&
+           (conflict_budget    < 0 || conflicts < (uint64_t)conflict_budget) &&
+           (propagation_budget < 0 || propagations < (uint64_t)propagation_budget); }
+
+// FIXME: after the introduction of asynchronous interrruptions the solve-versions that return a
+// pure bool do not give a safe interface. Either interrupts must be possible to turn off here, or
+// all calls to solve must return an 'lbool'. I'm not yet sure which I prefer.
+inline bool     Solver::solve         ()                    { budgetOff(); assumptions.clear(); return solve_() == l_True; }
+inline bool     Solver::solve         (Lit p)               { budgetOff(); assumptions.clear(); assumptions.push(p); return solve_() == l_True; }
+inline bool     Solver::solve         (Lit p, Lit q)        { budgetOff(); assumptions.clear(); assumptions.push(p); assumptions.push(q); return solve_() == l_True; }
+inline bool     Solver::solve         (Lit p, Lit q, Lit r) { budgetOff(); assumptions.clear(); assumptions.push(p); assumptions.push(q); assumptions.push(r); return solve_() == l_True; }
+inline bool     Solver::solve         (const vec<Lit>& assumps){ budgetOff(); assumps.copyTo(assumptions); return solve_() == l_True; }
+inline lbool    Solver::solveLimited  (const vec<Lit>& assumps){ assumps.copyTo(assumptions); return solve_(); }
+inline bool     Solver::okay          ()      const   { return ok; }
+
+inline void     Solver::toDimacs     (const char* file){ vec<Lit> as; toDimacs(file, as); }
+inline void     Solver::toDimacs     (const char* file, Lit p){ vec<Lit> as; as.push(p); toDimacs(file, as); }
+inline void     Solver::toDimacs     (const char* file, Lit p, Lit q){ vec<Lit> as; as.push(p); as.push(q); toDimacs(file, as); }
+inline void     Solver::toDimacs     (const char* file, Lit p, Lit q, Lit r){ vec<Lit> as; as.push(p); as.push(q); as.push(r); toDimacs(file, as); }
+
+
+//=================================================================================================
+// Debug etc:
+
+
+//=================================================================================================
+}
+
+#endif
diff --git a/src/sat/bsat2/SolverTypes.h b/src/sat/bsat2/SolverTypes.h
new file mode 100644
index 0000000..ece937c
--- /dev/null
+++ b/src/sat/bsat2/SolverTypes.h
@@ -0,0 +1,407 @@
+/***********************************************************************************[SolverTypes.h]
+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.
+**************************************************************************************************/
+
+
+#ifndef Minisat_SolverTypes_h
+#define Minisat_SolverTypes_h
+
+#include <assert.h>
+
+#include "IntTypes.h"
+#include "Alg.h"
+#include "Vec.h"
+#include "Map.h"
+#include "Alloc.h"
+
+namespace Minisat {
+
+//=================================================================================================
+// Variables, literals, lifted booleans, clauses:
+
+
+// NOTE! Variables are just integers. No abstraction here. They should be chosen from 0..N,
+// so that they can be used as array indices.
+
+typedef int Var;
+#define var_Undef (-1)
+
+
+struct Lit {
+    int     x;
+
+    // Use this as a constructor:
+    friend Lit mkLit(Var var, bool sign = false);
+
+    bool operator == (Lit p) const { return x == p.x; }
+    bool operator != (Lit p) const { return x != p.x; }
+    bool operator <  (Lit p) const { return x < p.x;  } // '<' makes p, ~p adjacent in the ordering.
+};
+
+
+inline  Lit  mkLit     (Var var, bool sign) { Lit p; p.x = var + var + (int)sign; return p; }
+inline  Lit  operator ~(Lit p)              { Lit q; q.x = p.x ^ 1; return q; }
+inline  Lit  operator ^(Lit p, bool b)      { Lit q; q.x = p.x ^ (unsigned int)b; return q; }
+inline  bool sign      (Lit p)              { return p.x & 1; }
+inline  int  var       (Lit p)              { return p.x >> 1; }
+
+// Mapping Literals to and from compact integers suitable for array indexing:
+inline  int  toInt     (Var v)              { return v; } 
+inline  int  toInt     (Lit p)              { return p.x; } 
+inline  Lit  toLit     (int i)              { Lit p; p.x = i; return p; } 
+
+//const Lit lit_Undef = mkLit(var_Undef, false);  // }- Useful special constants.
+//const Lit lit_Error = mkLit(var_Undef, true );  // }
+
+const Lit lit_Undef = { -2 };  // }- Useful special constants.
+const Lit lit_Error = { -1 };  // }
+
+
+//=================================================================================================
+// Lifted booleans:
+//
+// NOTE: this implementation is optimized for the case when comparisons between values are mostly
+//       between one variable and one constant. Some care had to be taken to make sure that gcc 
+//       does enough constant propagation to produce sensible code, and this appears to be somewhat
+//       fragile unfortunately.
+
+#define l_True  (lbool((uint8_t)0)) // gcc does not do constant propagation if these are real constants.
+#define l_False (lbool((uint8_t)1))
+#define l_Undef (lbool((uint8_t)2))
+
+class lbool {
+    uint8_t value;
+
+public:
+    explicit lbool(uint8_t v) : value(v) { }
+
+    lbool()       : value(0) { }
+    explicit lbool(bool x) : value(!x) { }
+
+    bool  operator == (lbool b) const { return ((b.value&2) & (value&2)) | (!(b.value&2)&(value == b.value)); }
+    bool  operator != (lbool b) const { return !(*this == b); }
+    lbool operator ^  (bool  b) const { return lbool((uint8_t)(value^(uint8_t)b)); }
+
+    lbool operator && (lbool b) const { 
+        uint8_t sel = (this->value << 1) | (b.value << 3);
+        uint8_t v   = (0xF7F755F4 >> sel) & 3;
+        return lbool(v); }
+
+    lbool operator || (lbool b) const {
+        uint8_t sel = (this->value << 1) | (b.value << 3);
+        uint8_t v   = (0xFCFCF400 >> sel) & 3;
+        return lbool(v); }
+
+    friend int   toInt  (lbool l);
+    friend lbool toLbool(int   v);
+};
+inline int   toInt  (lbool l) { return l.value; }
+inline lbool toLbool(int   v) { return lbool((uint8_t)v);  }
+
+//=================================================================================================
+// Clause -- a simple class for representing a clause:
+
+class Clause;
+typedef RegionAllocator<uint32_t>::Ref CRef;
+
+class Clause {
+    struct {
+        unsigned mark      : 2;
+        unsigned learnt    : 1;
+        unsigned has_extra : 1;
+        unsigned reloced   : 1;
+        unsigned size      : 27; }                            header;
+    union { Lit lit; float act; uint32_t abs; CRef rel; } data[0];
+
+    friend class ClauseAllocator;
+
+    // NOTE: This constructor cannot be used directly (doesn't allocate enough memory).
+    template<class V>
+    Clause(const V& ps, bool use_extra, bool learnt) {
+        header.mark      = 0;
+        header.learnt    = learnt;
+        header.has_extra = use_extra;
+        header.reloced   = 0;
+        header.size      = ps.size();
+
+        for (int i = 0; i < ps.size(); i++) 
+            data[i].lit = ps[i];
+
+        if (header.has_extra){
+            if (header.learnt)
+                data[header.size].act = 0; 
+            else 
+                calcAbstraction(); }
+    }
+
+public:
+    void calcAbstraction() {
+        assert(header.has_extra);
+        uint32_t abstraction = 0;
+        for (int i = 0; i < size(); i++)
+            abstraction |= 1 << (var(data[i].lit) & 31);
+        data[header.size].abs = abstraction;  }
+
+
+    int          size        ()      const   { return header.size; }
+    void         shrink      (int i)         { assert(i <= size()); if (header.has_extra) data[header.size-i] = data[header.size]; header.size -= i; }
+    void         pop         ()              { shrink(1); }
+    bool         learnt      ()      const   { return header.learnt; }
+    bool         has_extra   ()      const   { return header.has_extra; }
+    uint32_t     mark        ()      const   { return header.mark; }
+    void         mark        (uint32_t m)    { header.mark = m; }
+    const Lit&   last        ()      const   { return data[header.size-1].lit; }
+
+    bool         reloced     ()      const   { return header.reloced; }
+    CRef         relocation  ()      const   { return data[0].rel; }
+    void         relocate    (CRef c)        { header.reloced = 1; data[0].rel = c; }
+
+    // NOTE: somewhat unsafe to change the clause in-place! Must manually call 'calcAbstraction' afterwards for
+    //       subsumption operations to behave correctly.
+    Lit&         operator [] (int i)         { return data[i].lit; }
+    Lit          operator [] (int i) const   { return data[i].lit; }
+    operator const Lit* (void) const         { return (Lit*)data; }
+
+    float&       activity    ()              { assert(header.has_extra); return data[header.size].act; }
+    uint32_t     abstraction () const        { assert(header.has_extra); return data[header.size].abs; }
+
+    Lit          subsumes    (const Clause& other) const;
+    void         strengthen  (Lit p);
+};
+
+
+//=================================================================================================
+// ClauseAllocator -- a simple class for allocating memory for clauses:
+
+
+const CRef CRef_Undef = RegionAllocator<uint32_t>::Ref_Undef;
+class ClauseAllocator : public RegionAllocator<uint32_t>
+{
+    static int clauseWord32Size(int size, bool has_extra){
+        return (sizeof(Clause) + (sizeof(Lit) * (size + (int)has_extra))) / sizeof(uint32_t); }
+ public:
+    bool extra_clause_field;
+
+    ClauseAllocator(uint32_t start_cap) : RegionAllocator<uint32_t>(start_cap), extra_clause_field(false){}
+    ClauseAllocator() : extra_clause_field(false){}
+
+    void moveTo(ClauseAllocator& to){
+        to.extra_clause_field = extra_clause_field;
+        RegionAllocator<uint32_t>::moveTo(to); }
+
+    template<class Lits>
+    CRef alloc(const Lits& ps, bool learnt = false)
+    {
+        assert(sizeof(Lit)      == sizeof(uint32_t));
+        assert(sizeof(float)    == sizeof(uint32_t));
+        bool use_extra = learnt | extra_clause_field;
+
+        CRef cid = RegionAllocator<uint32_t>::alloc(clauseWord32Size(ps.size(), use_extra));
+        new (lea(cid)) Clause(ps, use_extra, learnt);
+
+        return cid;
+    }
+
+    // Deref, Load Effective Address (LEA), Inverse of LEA (AEL):
+    Clause&       operator[](Ref r)       { return (Clause&)RegionAllocator<uint32_t>::operator[](r); }
+    const Clause& operator[](Ref r) const { return (Clause&)RegionAllocator<uint32_t>::operator[](r); }
+    Clause*       lea       (Ref r)       { return (Clause*)RegionAllocator<uint32_t>::lea(r); }
+    const Clause* lea       (Ref r) const { return (Clause*)RegionAllocator<uint32_t>::lea(r); }
+    Ref           ael       (const Clause* t){ return RegionAllocator<uint32_t>::ael((uint32_t*)t); }
+
+    void _free(CRef cid)
+    {
+        Clause& c = operator[](cid);
+        RegionAllocator<uint32_t>::_free(clauseWord32Size(c.size(), c.has_extra()));
+    }
+
+    void reloc(CRef& cr, ClauseAllocator& to)
+    {
+        Clause& c = operator[](cr);
+        
+        if (c.reloced()) { cr = c.relocation(); return; }
+        
+        cr = to.alloc(c, c.learnt());
+        c.relocate(cr);
+        
+        // Copy extra data-fields: 
+        // (This could be cleaned-up. Generalize Clause-constructor to be applicable here instead?)
+        to[cr].mark(c.mark());
+        if (to[cr].learnt())         to[cr].activity() = c.activity();
+        else if (to[cr].has_extra()) to[cr].calcAbstraction();
+    }
+};
+
+
+//=================================================================================================
+// OccLists -- a class for maintaining occurence lists with lazy deletion:
+
+template<class Idx, class Vec, class Deleted>
+class OccLists
+{
+    vec<Vec>  occs;
+    vec<char> dirty;
+    vec<Idx>  dirties;
+    Deleted   deleted;
+
+ public:
+    OccLists(const Deleted& d) : deleted(d) {}
+    
+    void  init      (const Idx& idx){ occs.growTo(toInt(idx)+1); dirty.growTo(toInt(idx)+1, 0); }
+    // Vec&  operator[](const Idx& idx){ return occs[toInt(idx)]; }
+    Vec&  operator[](const Idx& idx){ return occs[toInt(idx)]; }
+    Vec&  lookup    (const Idx& idx){ if (dirty[toInt(idx)]) clean(idx); return occs[toInt(idx)]; }
+
+    void  cleanAll  ();
+    void  clean     (const Idx& idx);
+    void  smudge    (const Idx& idx){
+        if (dirty[toInt(idx)] == 0){
+            dirty[toInt(idx)] = 1;
+            dirties.push(idx);
+        }
+    }
+
+    void  clear(bool free = true){
+        occs   .clear(free);
+        dirty  .clear(free);
+        dirties.clear(free);
+    }
+};
+
+
+template<class Idx, class Vec, class Deleted>
+void OccLists<Idx,Vec,Deleted>::cleanAll()
+{
+    for (int i = 0; i < dirties.size(); i++)
+        // Dirties may contain duplicates so check here if a variable is already cleaned:
+        if (dirty[toInt(dirties[i])])
+            clean(dirties[i]);
+    dirties.clear();
+}
+
+
+template<class Idx, class Vec, class Deleted>
+void OccLists<Idx,Vec,Deleted>::clean(const Idx& idx)
+{
+    Vec& vec = occs[toInt(idx)];
+    int  i, j;
+    for (i = j = 0; i < vec.size(); i++)
+        if (!deleted(vec[i]))
+            vec[j++] = vec[i];
+    vec.shrink(i - j);
+    dirty[toInt(idx)] = 0;
+}
+
+
+//=================================================================================================
+// CMap -- a class for mapping clauses to values:
+
+
+template<class T>
+class CMap
+{
+    struct CRefHash {
+        uint32_t operator()(CRef cr) const { return (uint32_t)cr; } };
+
+    typedef Map<CRef, T, CRefHash> HashTable;
+    HashTable map;
+        
+ public:
+    // Size-operations:
+    void     clear       ()                           { map.clear(); }
+    int      size        ()                const      { return map.elems(); }
+
+    
+    // Insert/Remove/Test mapping:
+    void     insert      (CRef cr, const T& t){ map.insert(cr, t); }
+    void     growTo      (CRef cr, const T& t){ map.insert(cr, t); } // NOTE: for compatibility
+    void     remove      (CRef cr)            { map.remove(cr); }
+    bool     has         (CRef cr, T& t)      { return map.peek(cr, t); }
+
+    // Vector interface (the clause 'c' must already exist):
+    const T& operator [] (CRef cr) const      { return map[cr]; }
+    T&       operator [] (CRef cr)            { return map[cr]; }
+
+    // Iteration (not transparent at all at the moment):
+    int  bucket_count() const { return map.bucket_count(); }
+    const vec<typename HashTable::Pair>& bucket(int i) const { return map.bucket(i); }
+
+    // Move contents to other map:
+    void moveTo(CMap& other){ map.moveTo(other.map); }
+
+    // TMP debug:
+    void debug(){
+        printf(" --- size = %d, bucket_count = %d\n", size(), map.bucket_count()); }
+};
+
+
+/*_________________________________________________________________________________________________
+|
+|  subsumes : (other : const Clause&)  ->  Lit
+|  
+|  Description:
+|       Checks if clause subsumes 'other', and at the same time, if it can be used to simplify 'other'
+|       by subsumption resolution.
+|  
+|    Result:
+|       lit_Error  - No subsumption or simplification
+|       lit_Undef  - Clause subsumes 'other'
+|       p          - The literal p can be deleted from 'other'
+|________________________________________________________________________________________________@*/
+inline Lit Clause::subsumes(const Clause& other) const
+{
+    //if (other.size() < size() || (extra.abst & ~other.extra.abst) != 0)
+    //if (other.size() < size() || (!learnt() && !other.learnt() && (extra.abst & ~other.extra.abst) != 0))
+    assert(!header.learnt);   assert(!other.header.learnt);
+    assert(header.has_extra); assert(other.header.has_extra);
+    if (other.header.size < header.size || (data[header.size].abs & ~other.data[other.header.size].abs) != 0)
+        return lit_Error;
+
+    Lit        ret = lit_Undef;
+    const Lit* c   = (const Lit*)(*this);
+    const Lit* d   = (const Lit*)other;
+
+    for (unsigned i = 0; i < header.size; i++) {
+        // search for c[i] or ~c[i]
+        for (unsigned j = 0; j < other.header.size; j++)
+            if (c[i] == d[j])
+                goto ok;
+            else if (ret == lit_Undef && c[i] == ~d[j]){
+                ret = c[i];
+                goto ok;
+            }
+
+        // did not find it
+        return lit_Error;
+    ok:;
+    }
+
+    return ret;
+}
+
+inline void Clause::strengthen(Lit p)
+{
+    remove(*this, p);
+    calcAbstraction();
+}
+
+//=================================================================================================
+}
+
+#endif
diff --git a/src/sat/bsat2/Sort.h b/src/sat/bsat2/Sort.h
new file mode 100644
index 0000000..cc96486
--- /dev/null
+++ b/src/sat/bsat2/Sort.h
@@ -0,0 +1,98 @@
+/******************************************************************************************[Sort.h]
+Copyright (c) 2003-2007, 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.
+**************************************************************************************************/
+
+#ifndef Minisat_Sort_h
+#define Minisat_Sort_h
+
+#include "Vec.h"
+
+//=================================================================================================
+// Some sorting algorithms for vec's
+
+
+namespace Minisat {
+
+template<class T>
+struct LessThan_default {
+    bool operator () (T x, T y) { return x < y; }
+};
+
+
+template <class T, class LessThan>
+void selectionSort(T* array, int size, LessThan lt)
+{
+    int     i, j, best_i;
+    T       tmp;
+
+    for (i = 0; i < size-1; i++){
+        best_i = i;
+        for (j = i+1; j < size; j++){
+            if (lt(array[j], array[best_i]))
+                best_i = j;
+        }
+        tmp = array[i]; array[i] = array[best_i]; array[best_i] = tmp;
+    }
+}
+template <class T> static inline void selectionSort(T* array, int size) {
+    selectionSort(array, size, LessThan_default<T>()); }
+
+template <class T, class LessThan>
+void sort(T* array, int size, LessThan lt)
+{
+    if (size <= 15)
+        selectionSort(array, size, lt);
+
+    else{
+        T           pivot = array[size / 2];
+        T           tmp;
+        int         i = -1;
+        int         j = size;
+
+        for(;;){
+            do i++; while(lt(array[i], pivot));
+            do j--; while(lt(pivot, array[j]));
+
+            if (i >= j) break;
+
+            tmp = array[i]; array[i] = array[j]; array[j] = tmp;
+        }
+
+        sort(array    , i     , lt);
+        sort(&array[i], size-i, lt);
+    }
+}
+template <class T> static inline void sort(T* array, int size) {
+    sort(array, size, LessThan_default<T>()); }
+
+
+//=================================================================================================
+// For 'vec's:
+
+
+template <class T, class LessThan> void sort(vec<T>& v, LessThan lt) {
+    sort((T*)v, v.size(), lt); }
+template <class T> void sort(vec<T>& v) {
+    sort(v, LessThan_default<T>()); }
+
+
+//=================================================================================================
+}
+
+#endif
diff --git a/src/sat/bsat2/System.cpp b/src/sat/bsat2/System.cpp
new file mode 100644
index 0000000..a7d9a21
--- /dev/null
+++ b/src/sat/bsat2/System.cpp
@@ -0,0 +1,95 @@
+/***************************************************************************************[System.cc]
+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.
+**************************************************************************************************/
+
+#include "System.h"
+
+#if defined(__linux__)
+
+#include <stdio.h>
+#include <stdlib.h>
+
+using namespace Minisat;
+
+// TODO: split the memory reading functions into two: one for reading high-watermark of RSS, and
+// one for reading the current virtual memory size.
+
+static inline int memReadStat(int field)
+{
+    char  name[256];
+    pid_t pid = getpid();
+    int   value;
+
+    sprintf(name, "/proc/%d/statm", pid);
+    FILE* in = fopen(name, "rb");
+    if (in == NULL) return 0;
+
+    for (; field >= 0; field--)
+        if (fscanf(in, "%d", &value) != 1)
+            printf("ERROR! Failed to parse memory statistics from \"/proc\".\n"), exit(1);
+    fclose(in);
+    return value;
+}
+
+
+static inline int memReadPeak(void)
+{
+    char  name[256];
+    pid_t pid = getpid();
+
+    sprintf(name, "/proc/%d/status", pid);
+    FILE* in = fopen(name, "rb");
+    if (in == NULL) return 0;
+
+    // Find the correct line, beginning with "VmPeak:":
+    int peak_kb = 0;
+    while (!feof(in) && fscanf(in, "VmPeak: %d kB", &peak_kb) != 1)
+        while (!feof(in) && fgetc(in) != '\n')
+            ;
+    fclose(in);
+
+    return peak_kb;
+}
+
+double Minisat::memUsed() { return (double)memReadStat(0) * (double)getpagesize() / (1024*1024); }
+double Minisat::memUsedPeak() { 
+    double peak = memReadPeak() / 1024;
+    return peak == 0 ? memUsed() : peak; }
+
+#elif defined(__FreeBSD__)
+
+double Minisat::memUsed(void) {
+    struct rusage ru;
+    getrusage(RUSAGE_SELF, &ru);
+    return (double)ru.ru_maxrss / 1024; }
+double MiniSat::memUsedPeak(void) { return memUsed(); }
+
+
+#elif defined(__APPLE__)
+#include <malloc/malloc.h>
+
+double Minisat::memUsed(void) {
+    malloc_statistics_t t;
+    malloc_zone_statistics(NULL, &t);
+    return (double)t.max_size_in_use / (1024*1024); }
+
+#else
+double Minisat::memUsed()     { return 0; }
+double Minisat::memUsedPeak() { return 0; }
+#endif
diff --git a/src/sat/bsat2/System.h b/src/sat/bsat2/System.h
new file mode 100644
index 0000000..d776c88
--- /dev/null
+++ b/src/sat/bsat2/System.h
@@ -0,0 +1,60 @@
+/****************************************************************************************[System.h]
+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.
+**************************************************************************************************/
+
+#ifndef Minisat_System_h
+#define Minisat_System_h
+
+#if defined(__linux__)
+#include <fpu_control.h>
+#endif
+
+#include "IntTypes.h"
+
+//-------------------------------------------------------------------------------------------------
+
+namespace Minisat {
+
+static inline double cpuTime(void); // CPU-time in seconds.
+extern double memUsed();            // Memory in mega bytes (returns 0 for unsupported architectures).
+extern double memUsedPeak();        // Peak-memory in mega bytes (returns 0 for unsupported architectures).
+
+}
+
+//-------------------------------------------------------------------------------------------------
+// Implementation of inline functions:
+
+#if defined(_MSC_VER) || defined(__MINGW32__)
+#include <time.h>
+
+static inline double Minisat::cpuTime(void) { return (double)clock() / CLOCKS_PER_SEC; }
+
+#else
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <unistd.h>
+
+static inline double Minisat::cpuTime(void) {
+    struct rusage ru;
+    getrusage(RUSAGE_SELF, &ru);
+    return (double)ru.ru_utime.tv_sec + (double)ru.ru_utime.tv_usec / 1000000; }
+
+#endif
+
+#endif
diff --git a/src/sat/bsat2/Vec.h b/src/sat/bsat2/Vec.h
new file mode 100644
index 0000000..f0e07d0
--- /dev/null
+++ b/src/sat/bsat2/Vec.h
@@ -0,0 +1,130 @@
+/*******************************************************************************************[Vec.h]
+Copyright (c) 2003-2007, 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.
+**************************************************************************************************/
+
+#ifndef Minisat_Vec_h
+#define Minisat_Vec_h
+
+#include <assert.h>
+#include <new>
+
+#include "IntTypes.h"
+#include "XAlloc.h"
+
+namespace Minisat {
+
+//=================================================================================================
+// Automatically resizable arrays
+//
+// NOTE! Don't use this vector on datatypes that cannot be re-located in memory (with realloc)
+
+template<class T>
+class vec {
+    T*  data;
+    int sz;
+    int cap;
+
+    // Don't allow copying (error prone):
+    vec<T>&  operator = (vec<T>& other) { assert(0); return *this; }
+             vec        (vec<T>& other) { assert(0); }
+             
+    // Helpers for calculating next capacity:
+    static inline int  imax   (int x, int y) { int mask = (y-x) >> (sizeof(int)*8-1); return (x&mask) + (y&(~mask)); }
+    //static inline void nextCap(int& cap){ cap += ((cap >> 1) + 2) & ~1; }
+    static inline void nextCap(int& cap){ cap += ((cap >> 1) + 2) & ~1; }
+
+public:
+    // Constructors:
+    vec()                       : data(NULL) , sz(0)   , cap(0)    { }
+    explicit vec(int size)      : data(NULL) , sz(0)   , cap(0)    { growTo(size); }
+    vec(int size, const T& pad) : data(NULL) , sz(0)   , cap(0)    { growTo(size, pad); }
+   ~vec()                                                          { clear(true); }
+
+    // Pointer to first element:
+    operator T*       (void)           { return data; }
+
+    // Size operations:
+    int      size     (void) const     { return sz; }
+    void     shrink   (int nelems)     { assert(nelems <= sz); for (int i = 0; i < nelems; i++) sz--, data[sz].~T(); }
+    void     shrink_  (int nelems)     { assert(nelems <= sz); sz -= nelems; }
+    int      capacity (void) const     { return cap; }
+    void     capacity (int min_cap);
+    void     growTo   (int size);
+    void     growTo   (int size, const T& pad);
+    void     clear    (bool dealloc = false);
+
+    // Stack interface:
+    void     push  (void)              { if (sz == cap) capacity(sz+1); new (&data[sz]) T(); sz++; }
+    void     push  (const T& elem)     { if (sz == cap) capacity(sz+1); data[sz++] = elem; }
+    void     push_ (const T& elem)     { assert(sz < cap); data[sz++] = elem; }
+    void     pop   (void)              { assert(sz > 0); sz--, data[sz].~T(); }
+    // NOTE: it seems possible that overflow can happen in the 'sz+1' expression of 'push()', but
+    // in fact it can not since it requires that 'cap' is equal to INT_MAX. This in turn can not
+    // happen given the way capacities are calculated (below). Essentially, all capacities are
+    // even, but INT_MAX is odd.
+
+    const T& last  (void) const        { return data[sz-1]; }
+    T&       last  (void)              { return data[sz-1]; }
+
+    // Vector interface:
+    const T& operator [] (int index) const { return data[index]; }
+    T&       operator [] (int index)       { return data[index]; }
+
+    // Duplicatation (preferred instead):
+    void copyTo(vec<T>& copy) const { copy.clear(); copy.growTo(sz); for (int i = 0; i < sz; i++) copy[i] = data[i]; }
+    void moveTo(vec<T>& dest) { dest.clear(true); dest.data = data; dest.sz = sz; dest.cap = cap; data = NULL; sz = 0; cap = 0; }
+};
+
+
+template<class T>
+void vec<T>::capacity(int min_cap) {
+    if (cap >= min_cap) return;
+    int add = imax((min_cap - cap + 1) & ~1, ((cap >> 1) + 2) & ~1);   // NOTE: grow by approximately 3/2
+    if (add > INT_MAX - cap || (((data = (T*)::realloc(data, (cap += add) * sizeof(T))) == NULL) && errno == ENOMEM))
+        throw OutOfMemoryException();
+ }
+
+
+template<class T>
+void vec<T>::growTo(int size, const T& pad) {
+    if (sz >= size) return;
+    capacity(size);
+    for (int i = sz; i < size; i++) data[i] = pad;
+    sz = size; }
+
+
+template<class T>
+void vec<T>::growTo(int size) {
+    if (sz >= size) return;
+    capacity(size);
+    for (int i = sz; i < size; i++) new (&data[i]) T();
+    sz = size; }
+
+
+template<class T>
+void vec<T>::clear(bool dealloc) {
+    if (data != NULL){
+        for (int i = 0; i < sz; i++) data[i].~T();
+        sz = 0;
+        if (dealloc) free(data), data = NULL, cap = 0; } }
+
+//=================================================================================================
+}
+
+#endif
diff --git a/src/sat/bsat2/XAlloc.h b/src/sat/bsat2/XAlloc.h
new file mode 100644
index 0000000..1da1760
--- /dev/null
+++ b/src/sat/bsat2/XAlloc.h
@@ -0,0 +1,45 @@
+/****************************************************************************************[XAlloc.h]
+Copyright (c) 2009-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.
+**************************************************************************************************/
+
+
+#ifndef Minisat_XAlloc_h
+#define Minisat_XAlloc_h
+
+#include <errno.h>
+#include <stdlib.h>
+
+namespace Minisat {
+
+//=================================================================================================
+// Simple layer on top of malloc/realloc to catch out-of-memory situtaions and provide some typing:
+
+class OutOfMemoryException{};
+static inline void* xrealloc(void *ptr, size_t size)
+{
+    void* mem = realloc(ptr, size);
+    if (mem == NULL && errno == ENOMEM){
+        throw OutOfMemoryException();
+    }else
+        return mem;
+}
+
+//=================================================================================================
+}
+
+#endif
diff --git a/src/sat/bsat2/module.make b/src/sat/bsat2/module.make
new file mode 100644
index 0000000..0d49e1a
--- /dev/null
+++ b/src/sat/bsat2/module.make
@@ -0,0 +1,7 @@
+SRC +=  src/sat/bsat2/AbcApi.cpp \
+	src/sat/bsat2/MainSat.cpp \
+	src/sat/bsat2/MainSimp.cpp \
+	src/sat/bsat2/Options.cpp \
+	src/sat/bsat2/SimpSolver.cpp \
+	src/sat/bsat2/Solver.cpp \
+	src/sat/bsat2/System.cpp
diff --git a/src/sat/bsat2/pstdint.h b/src/sat/bsat2/pstdint.h
new file mode 100644
index 0000000..18a26b5
--- /dev/null
+++ b/src/sat/bsat2/pstdint.h
@@ -0,0 +1,813 @@
+/*  A portable stdint.h
+ ****************************************************************************
+ *  BSD License:
+ ****************************************************************************
+ *
+ *  Copyright (c) 2005-2014 Paul Hsieh
+ *  All rights reserved.
+ *
+ *  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.
+ *  3. The name of the author may not be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ ****************************************************************************
+ *
+ *  Version 0.1.14
+ *
+ *  The ANSI C standard committee, for the C99 standard, specified the
+ *  inclusion of a new standard include file called stdint.h.  This is
+ *  a very useful and long desired include file which contains several
+ *  very precise definitions for integer scalar types that is
+ *  critically important for making portable several classes of
+ *  applications including cryptography, hashing, variable length
+ *  integer libraries and so on.  But for most developers its likely
+ *  useful just for programming sanity.
+ *
+ *  The problem is that most compiler vendors have decided not to
+ *  implement the C99 standard, and the next C++ language standard
+ *  (which has a lot more mindshare these days) will be a long time in
+ *  coming and its unknown whether or not it will include stdint.h or
+ *  how much adoption it will have.  Either way, it will be a long time
+ *  before all compilers come with a stdint.h and it also does nothing
+ *  for the extremely large number of compilers available today which
+ *  do not include this file, or anything comparable to it.
+ *
+ *  So that's what this file is all about.  Its an attempt to build a
+ *  single universal include file that works on as many platforms as
+ *  possible to deliver what stdint.h is supposed to.  A few things
+ *  that should be noted about this file:
+ *
+ *    1) It is not guaranteed to be portable and/or present an identical
+ *       interface on all platforms.  The extreme variability of the
+ *       ANSI C standard makes this an impossibility right from the
+ *       very get go. Its really only meant to be useful for the vast
+ *       majority of platforms that possess the capability of
+ *       implementing usefully and precisely defined, standard sized
+ *       integer scalars.  Systems which are not intrinsically 2s
+ *       complement may produce invalid constants.
+ *
+ *    2) There is an unavoidable use of non-reserved symbols.
+ *
+ *    3) Other standard include files are invoked.
+ *
+ *    4) This file may come in conflict with future platforms that do
+ *       include stdint.h.  The hope is that one or the other can be
+ *       used with no real difference.
+ *
+ *    5) In the current verison, if your platform can't represent
+ *       int32_t, int16_t and int8_t, it just dumps out with a compiler
+ *       error.
+ *
+ *    6) 64 bit integers may or may not be defined.  Test for their
+ *       presence with the test: #ifdef INT64_MAX or #ifdef UINT64_MAX.
+ *       Note that this is different from the C99 specification which
+ *       requires the existence of 64 bit support in the compiler.  If
+ *       this is not defined for your platform, yet it is capable of
+ *       dealing with 64 bits then it is because this file has not yet
+ *       been extended to cover all of your system's capabilities.
+ *
+ *    7) (u)intptr_t may or may not be defined.  Test for its presence
+ *       with the test: #ifdef PTRDIFF_MAX.  If this is not defined
+ *       for your platform, then it is because this file has not yet
+ *       been extended to cover all of your system's capabilities, not
+ *       because its optional.
+ *
+ *    8) The following might not been defined even if your platform is
+ *       capable of defining it:
+ *
+ *       WCHAR_MIN
+ *       WCHAR_MAX
+ *       (u)int64_t
+ *       PTRDIFF_MIN
+ *       PTRDIFF_MAX
+ *       (u)intptr_t
+ *
+ *    9) The following have not been defined:
+ *
+ *       WINT_MIN
+ *       WINT_MAX
+ *
+ *   10) The criteria for defining (u)int_least(*)_t isn't clear,
+ *       except for systems which don't have a type that precisely
+ *       defined 8, 16, or 32 bit types (which this include file does
+ *       not support anyways). Default definitions have been given.
+ *
+ *   11) The criteria for defining (u)int_fast(*)_t isn't something I
+ *       would trust to any particular compiler vendor or the ANSI C
+ *       committee.  It is well known that "compatible systems" are
+ *       commonly created that have very different performance
+ *       characteristics from the systems they are compatible with,
+ *       especially those whose vendors make both the compiler and the
+ *       system.  Default definitions have been given, but its strongly
+ *       recommended that users never use these definitions for any
+ *       reason (they do *NOT* deliver any serious guarantee of
+ *       improved performance -- not in this file, nor any vendor's
+ *       stdint.h).
+ *
+ *   12) The following macros:
+ *
+ *       PRINTF_INTMAX_MODIFIER
+ *       PRINTF_INT64_MODIFIER
+ *       PRINTF_INT32_MODIFIER
+ *       PRINTF_INT16_MODIFIER
+ *       PRINTF_LEAST64_MODIFIER
+ *       PRINTF_LEAST32_MODIFIER
+ *       PRINTF_LEAST16_MODIFIER
+ *       PRINTF_INTPTR_MODIFIER
+ *
+ *       are strings which have been defined as the modifiers required
+ *       for the "d", "u" and "x" printf formats to correctly output
+ *       (u)intmax_t, (u)int64_t, (u)int32_t, (u)int16_t, (u)least64_t,
+ *       (u)least32_t, (u)least16_t and (u)intptr_t types respectively.
+ *       PRINTF_INTPTR_MODIFIER is not defined for some systems which
+ *       provide their own stdint.h.  PRINTF_INT64_MODIFIER is not
+ *       defined if INT64_MAX is not defined.  These are an extension
+ *       beyond what C99 specifies must be in stdint.h.
+ *
+ *       In addition, the following macros are defined:
+ *
+ *       PRINTF_INTMAX_HEX_WIDTH
+ *       PRINTF_INT64_HEX_WIDTH
+ *       PRINTF_INT32_HEX_WIDTH
+ *       PRINTF_INT16_HEX_WIDTH
+ *       PRINTF_INT8_HEX_WIDTH
+ *       PRINTF_INTMAX_DEC_WIDTH
+ *       PRINTF_INT64_DEC_WIDTH
+ *       PRINTF_INT32_DEC_WIDTH
+ *       PRINTF_INT16_DEC_WIDTH
+ *       PRINTF_INT8_DEC_WIDTH
+ *
+ *       Which specifies the maximum number of characters required to
+ *       print the number of that type in either hexadecimal or decimal.
+ *       These are an extension beyond what C99 specifies must be in
+ *       stdint.h.
+ *
+ *  Compilers tested (all with 0 warnings at their highest respective
+ *  settings): Borland Turbo C 2.0, WATCOM C/C++ 11.0 (16 bits and 32
+ *  bits), Microsoft Visual C++ 6.0 (32 bit), Microsoft Visual Studio
+ *  .net (VC7), Intel C++ 4.0, GNU gcc v3.3.3
+ *
+ *  This file should be considered a work in progress.  Suggestions for
+ *  improvements, especially those which increase coverage are strongly
+ *  encouraged.
+ *
+ *  Acknowledgements
+ *
+ *  The following people have made significant contributions to the
+ *  development and testing of this file:
+ *
+ *  Chris Howie
+ *  John Steele Scott
+ *  Dave Thorup
+ *  John Dill
+ *  Florian Wobbe
+ *  Christopher Sean Morrison
+ *
+ */
+
+#include <stddef.h>
+#include <limits.h>
+#include <signal.h>
+
+/*
+ *  For gcc with _STDINT_H, fill in the PRINTF_INT*_MODIFIER macros, and
+ *  do nothing else.  On the Mac OS X version of gcc this is _STDINT_H_.
+ */
+
+#if ((defined(__STDC__) && __STDC__ && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (defined (__WATCOMC__) && (defined (_STDINT_H_INCLUDED) || __WATCOMC__ >= 1250)) || (defined(__GNUC__) && (__GNUC__ > 3 || defined(_STDINT_H) || defined(_STDINT_H_) || defined (__UINT_FAST64_TYPE__)) )) && !defined (_PSTDINT_H_INCLUDED)
+#include <stdint.h>
+#define _PSTDINT_H_INCLUDED
+# if defined(__GNUC__) && (defined(__x86_64__) || defined(__ppc64__))
+#  ifndef PRINTF_INT64_MODIFIER
+#   define PRINTF_INT64_MODIFIER "l"
+#  endif
+#  ifndef PRINTF_INT32_MODIFIER
+#   define PRINTF_INT32_MODIFIER ""
+#  endif
+# else
+#  ifndef PRINTF_INT64_MODIFIER
+#   define PRINTF_INT64_MODIFIER "ll"
+#  endif
+#  ifndef PRINTF_INT32_MODIFIER
+#   define PRINTF_INT32_MODIFIER "l"
+#  endif
+# endif
+# ifndef PRINTF_INT16_MODIFIER
+#  define PRINTF_INT16_MODIFIER "h"
+# endif
+# ifndef PRINTF_INTMAX_MODIFIER
+#  define PRINTF_INTMAX_MODIFIER PRINTF_INT64_MODIFIER
+# endif
+# ifndef PRINTF_INT64_HEX_WIDTH
+#  define PRINTF_INT64_HEX_WIDTH "16"
+# endif
+# ifndef PRINTF_INT32_HEX_WIDTH
+#  define PRINTF_INT32_HEX_WIDTH "8"
+# endif
+# ifndef PRINTF_INT16_HEX_WIDTH
+#  define PRINTF_INT16_HEX_WIDTH "4"
+# endif
+# ifndef PRINTF_INT8_HEX_WIDTH
+#  define PRINTF_INT8_HEX_WIDTH "2"
+# endif
+# ifndef PRINTF_INT64_DEC_WIDTH
+#  define PRINTF_INT64_DEC_WIDTH "20"
+# endif
+# ifndef PRINTF_INT32_DEC_WIDTH
+#  define PRINTF_INT32_DEC_WIDTH "10"
+# endif
+# ifndef PRINTF_INT16_DEC_WIDTH
+#  define PRINTF_INT16_DEC_WIDTH "5"
+# endif
+# ifndef PRINTF_INT8_DEC_WIDTH
+#  define PRINTF_INT8_DEC_WIDTH "3"
+# endif
+# ifndef PRINTF_INTMAX_HEX_WIDTH
+#  define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT64_HEX_WIDTH
+# endif
+# ifndef PRINTF_INTMAX_DEC_WIDTH
+#  define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT64_DEC_WIDTH
+# endif
+
+/*
+ *  Something really weird is going on with Open Watcom.  Just pull some of
+ *  these duplicated definitions from Open Watcom's stdint.h file for now.
+ */
+
+# if defined (__WATCOMC__) && __WATCOMC__ >= 1250
+#  if !defined (INT64_C)
+#   define INT64_C(x)   (x + (INT64_MAX - INT64_MAX))
+#  endif
+#  if !defined (UINT64_C)
+#   define UINT64_C(x)  (x + (UINT64_MAX - UINT64_MAX))
+#  endif
+#  if !defined (INT32_C)
+#   define INT32_C(x)   (x + (INT32_MAX - INT32_MAX))
+#  endif
+#  if !defined (UINT32_C)
+#   define UINT32_C(x)  (x + (UINT32_MAX - UINT32_MAX))
+#  endif
+#  if !defined (INT16_C)
+#   define INT16_C(x)   (x)
+#  endif
+#  if !defined (UINT16_C)
+#   define UINT16_C(x)  (x)
+#  endif
+#  if !defined (INT8_C)
+#   define INT8_C(x)   (x)
+#  endif
+#  if !defined (UINT8_C)
+#   define UINT8_C(x)  (x)
+#  endif
+#  if !defined (UINT64_MAX)
+#   define UINT64_MAX  18446744073709551615ULL
+#  endif
+#  if !defined (INT64_MAX)
+#   define INT64_MAX  9223372036854775807LL
+#  endif
+#  if !defined (UINT32_MAX)
+#   define UINT32_MAX  4294967295UL
+#  endif
+#  if !defined (INT32_MAX)
+#   define INT32_MAX  2147483647L
+#  endif
+#  if !defined (INTMAX_MAX)
+#   define INTMAX_MAX INT64_MAX
+#  endif
+#  if !defined (INTMAX_MIN)
+#   define INTMAX_MIN INT64_MIN
+#  endif
+# endif
+#endif
+
+#ifndef _PSTDINT_H_INCLUDED
+#define _PSTDINT_H_INCLUDED
+
+#ifndef SIZE_MAX
+# define SIZE_MAX (~(size_t)0)
+#endif
+
+/*
+ *  Deduce the type assignments from limits.h under the assumption that
+ *  integer sizes in bits are powers of 2, and follow the ANSI
+ *  definitions.
+ */
+
+#ifndef UINT8_MAX
+# define UINT8_MAX 0xff
+#endif
+#if !defined(uint8_t) && !defined(_UINT8_T)
+# if (UCHAR_MAX == UINT8_MAX) || defined (S_SPLINT_S)
+    typedef unsigned char uint8_t;
+#   define UINT8_C(v) ((uint8_t) v)
+# else
+#   error "Platform not supported"
+# endif
+#endif
+
+#ifndef INT8_MAX
+# define INT8_MAX 0x7f
+#endif
+#ifndef INT8_MIN
+# define INT8_MIN INT8_C(0x80)
+#endif
+#if !defined(int8_t) && !defined(_INT8_T)
+# if (SCHAR_MAX == INT8_MAX) || defined (S_SPLINT_S)
+    typedef signed char int8_t;
+#   define INT8_C(v) ((int8_t) v)
+# else
+#   error "Platform not supported"
+# endif
+#endif
+
+#ifndef UINT16_MAX
+# define UINT16_MAX 0xffff
+#endif
+#if !defined(uint16_t) && !defined(_UINT16_T)
+#if (UINT_MAX == UINT16_MAX) || defined (S_SPLINT_S)
+  typedef unsigned int uint16_t;
+# ifndef PRINTF_INT16_MODIFIER
+#  define PRINTF_INT16_MODIFIER ""
+# endif
+# define UINT16_C(v) ((uint16_t) (v))
+#elif (USHRT_MAX == UINT16_MAX)
+  typedef unsigned short uint16_t;
+# define UINT16_C(v) ((uint16_t) (v))
+# ifndef PRINTF_INT16_MODIFIER
+#  define PRINTF_INT16_MODIFIER "h"
+# endif
+#else
+#error "Platform not supported"
+#endif
+#endif
+
+#ifndef INT16_MAX
+# define INT16_MAX 0x7fff
+#endif
+#ifndef INT16_MIN
+# define INT16_MIN INT16_C(0x8000)
+#endif
+#if !defined(int16_t) && !defined(_INT16_T)
+#if (INT_MAX == INT16_MAX) || defined (S_SPLINT_S)
+  typedef signed int int16_t;
+# define INT16_C(v) ((int16_t) (v))
+# ifndef PRINTF_INT16_MODIFIER
+#  define PRINTF_INT16_MODIFIER ""
+# endif
+#elif (SHRT_MAX == INT16_MAX)
+  typedef signed short int16_t;
+# define INT16_C(v) ((int16_t) (v))
+# ifndef PRINTF_INT16_MODIFIER
+#  define PRINTF_INT16_MODIFIER "h"
+# endif
+#else
+#error "Platform not supported"
+#endif
+#endif
+
+#ifndef UINT32_MAX
+# define UINT32_MAX (0xffffffffUL)
+#endif
+#if !defined(uint32_t) && !defined(_UINT32_T)
+#if (ULONG_MAX == UINT32_MAX) || defined (S_SPLINT_S)
+  typedef unsigned long uint32_t;
+# define UINT32_C(v) v ## UL
+# ifndef PRINTF_INT32_MODIFIER
+#  define PRINTF_INT32_MODIFIER "l"
+# endif
+#elif (UINT_MAX == UINT32_MAX)
+  typedef unsigned int uint32_t;
+# ifndef PRINTF_INT32_MODIFIER
+#  define PRINTF_INT32_MODIFIER ""
+# endif
+# define UINT32_C(v) v ## U
+#elif (USHRT_MAX == UINT32_MAX)
+  typedef unsigned short uint32_t;
+# define UINT32_C(v) ((unsigned short) (v))
+# ifndef PRINTF_INT32_MODIFIER
+#  define PRINTF_INT32_MODIFIER ""
+# endif
+#else
+#error "Platform not supported"
+#endif
+#endif
+
+#ifndef INT32_MAX
+# define INT32_MAX (0x7fffffffL)
+#endif
+#ifndef INT32_MIN
+# define INT32_MIN INT32_C(0x80000000)
+#endif
+#if !defined(int32_t) && !defined(_INT32_T)
+#if (LONG_MAX == INT32_MAX) || defined (S_SPLINT_S)
+  typedef signed long int32_t;
+# define INT32_C(v) v ## L
+# ifndef PRINTF_INT32_MODIFIER
+#  define PRINTF_INT32_MODIFIER "l"
+# endif
+#elif (INT_MAX == INT32_MAX)
+  typedef signed int int32_t;
+# define INT32_C(v) v
+# ifndef PRINTF_INT32_MODIFIER
+#  define PRINTF_INT32_MODIFIER ""
+# endif
+#elif (SHRT_MAX == INT32_MAX)
+  typedef signed short int32_t;
+# define INT32_C(v) ((short) (v))
+# ifndef PRINTF_INT32_MODIFIER
+#  define PRINTF_INT32_MODIFIER ""
+# endif
+#else
+#error "Platform not supported"
+#endif
+#endif
+
+/*
+ *  The macro stdint_int64_defined is temporarily used to record
+ *  whether or not 64 integer support is available.  It must be
+ *  defined for any 64 integer extensions for new platforms that are
+ *  added.
+ */
+
+#undef stdint_int64_defined
+#if (defined(__STDC__) && defined(__STDC_VERSION__)) || defined (S_SPLINT_S)
+# if (__STDC__ && __STDC_VERSION__ >= 199901L) || defined (S_SPLINT_S)
+#  define stdint_int64_defined
+   typedef long long int64_t;
+   typedef unsigned long long uint64_t;
+#  define UINT64_C(v) v ## ULL
+#  define  INT64_C(v) v ## LL
+#  ifndef PRINTF_INT64_MODIFIER
+#   define PRINTF_INT64_MODIFIER "ll"
+#  endif
+# endif
+#endif
+
+#if !defined (stdint_int64_defined)
+# if defined(__GNUC__)
+#  define stdint_int64_defined
+   __extension__ typedef long long int64_t;
+   __extension__ typedef unsigned long long uint64_t;
+#  define UINT64_C(v) v ## ULL
+#  define  INT64_C(v) v ## LL
+#  ifndef PRINTF_INT64_MODIFIER
+#   define PRINTF_INT64_MODIFIER "ll"
+#  endif
+# elif defined(__MWERKS__) || defined (__SUNPRO_C) || defined (__SUNPRO_CC) || defined (__APPLE_CC__) || defined (_LONG_LONG) || defined (_CRAYC) || defined (S_SPLINT_S)
+#  define stdint_int64_defined
+   typedef long long int64_t;
+   typedef unsigned long long uint64_t;
+#  define UINT64_C(v) v ## ULL
+#  define  INT64_C(v) v ## LL
+#  ifndef PRINTF_INT64_MODIFIER
+#   define PRINTF_INT64_MODIFIER "ll"
+#  endif
+# elif (defined(__WATCOMC__) && defined(__WATCOM_INT64__)) || (defined(_MSC_VER) && _INTEGRAL_MAX_BITS >= 64) || (defined (__BORLANDC__) && __BORLANDC__ > 0x460) || defined (__alpha) || defined (__DECC)
+#  define stdint_int64_defined
+   typedef __int64 int64_t;
+   typedef unsigned __int64 uint64_t;
+#  define UINT64_C(v) v ## UI64
+#  define  INT64_C(v) v ## I64
+#  ifndef PRINTF_INT64_MODIFIER
+#   define PRINTF_INT64_MODIFIER "I64"
+#  endif
+# endif
+#endif
+
+#if !defined (LONG_LONG_MAX) && defined (INT64_C)
+# define LONG_LONG_MAX INT64_C (9223372036854775807)
+#endif
+#ifndef ULONG_LONG_MAX
+# define ULONG_LONG_MAX UINT64_C (18446744073709551615)
+#endif
+
+#if !defined (INT64_MAX) && defined (INT64_C)
+# define INT64_MAX INT64_C (9223372036854775807)
+#endif
+#if !defined (INT64_MIN) && defined (INT64_C)
+# define INT64_MIN INT64_C (-9223372036854775808)
+#endif
+#if !defined (UINT64_MAX) && defined (INT64_C)
+# define UINT64_MAX UINT64_C (18446744073709551615)
+#endif
+
+/*
+ *  Width of hexadecimal for number field.
+ */
+
+#ifndef PRINTF_INT64_HEX_WIDTH
+# define PRINTF_INT64_HEX_WIDTH "16"
+#endif
+#ifndef PRINTF_INT32_HEX_WIDTH
+# define PRINTF_INT32_HEX_WIDTH "8"
+#endif
+#ifndef PRINTF_INT16_HEX_WIDTH
+# define PRINTF_INT16_HEX_WIDTH "4"
+#endif
+#ifndef PRINTF_INT8_HEX_WIDTH
+# define PRINTF_INT8_HEX_WIDTH "2"
+#endif
+
+#ifndef PRINTF_INT64_DEC_WIDTH
+# define PRINTF_INT64_DEC_WIDTH "20"
+#endif
+#ifndef PRINTF_INT32_DEC_WIDTH
+# define PRINTF_INT32_DEC_WIDTH "10"
+#endif
+#ifndef PRINTF_INT16_DEC_WIDTH
+# define PRINTF_INT16_DEC_WIDTH "5"
+#endif
+#ifndef PRINTF_INT8_DEC_WIDTH
+# define PRINTF_INT8_DEC_WIDTH "3"
+#endif
+
+/*
+ *  Ok, lets not worry about 128 bit integers for now.  Moore's law says
+ *  we don't need to worry about that until about 2040 at which point
+ *  we'll have bigger things to worry about.
+ */
+
+#ifdef stdint_int64_defined
+  typedef int64_t intmax_t;
+  typedef uint64_t uintmax_t;
+# define  INTMAX_MAX   INT64_MAX
+# define  INTMAX_MIN   INT64_MIN
+# define UINTMAX_MAX  UINT64_MAX
+# define UINTMAX_C(v) UINT64_C(v)
+# define  INTMAX_C(v)  INT64_C(v)
+# ifndef PRINTF_INTMAX_MODIFIER
+#   define PRINTF_INTMAX_MODIFIER PRINTF_INT64_MODIFIER
+# endif
+# ifndef PRINTF_INTMAX_HEX_WIDTH
+#  define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT64_HEX_WIDTH
+# endif
+# ifndef PRINTF_INTMAX_DEC_WIDTH
+#  define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT64_DEC_WIDTH
+# endif
+#else
+  typedef int32_t intmax_t;
+  typedef uint32_t uintmax_t;
+# define  INTMAX_MAX   INT32_MAX
+# define UINTMAX_MAX  UINT32_MAX
+# define UINTMAX_C(v) UINT32_C(v)
+# define  INTMAX_C(v)  INT32_C(v)
+# ifndef PRINTF_INTMAX_MODIFIER
+#   define PRINTF_INTMAX_MODIFIER PRINTF_INT32_MODIFIER
+# endif
+# ifndef PRINTF_INTMAX_HEX_WIDTH
+#  define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT32_HEX_WIDTH
+# endif
+# ifndef PRINTF_INTMAX_DEC_WIDTH
+#  define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT32_DEC_WIDTH
+# endif
+#endif
+
+/*
+ *  Because this file currently only supports platforms which have
+ *  precise powers of 2 as bit sizes for the default integers, the
+ *  least definitions are all trivial.  Its possible that a future
+ *  version of this file could have different definitions.
+ */
+
+#ifndef stdint_least_defined
+  typedef   int8_t   int_least8_t;
+  typedef  uint8_t  uint_least8_t;
+  typedef  int16_t  int_least16_t;
+  typedef uint16_t uint_least16_t;
+  typedef  int32_t  int_least32_t;
+  typedef uint32_t uint_least32_t;
+# define PRINTF_LEAST32_MODIFIER PRINTF_INT32_MODIFIER
+# define PRINTF_LEAST16_MODIFIER PRINTF_INT16_MODIFIER
+# define  UINT_LEAST8_MAX  UINT8_MAX
+# define   INT_LEAST8_MAX   INT8_MAX
+# define UINT_LEAST16_MAX UINT16_MAX
+# define  INT_LEAST16_MAX  INT16_MAX
+# define UINT_LEAST32_MAX UINT32_MAX
+# define  INT_LEAST32_MAX  INT32_MAX
+# define   INT_LEAST8_MIN   INT8_MIN
+# define  INT_LEAST16_MIN  INT16_MIN
+# define  INT_LEAST32_MIN  INT32_MIN
+# ifdef stdint_int64_defined
+    typedef  int64_t  int_least64_t;
+    typedef uint64_t uint_least64_t;
+#   define PRINTF_LEAST64_MODIFIER PRINTF_INT64_MODIFIER
+#   define UINT_LEAST64_MAX UINT64_MAX
+#   define  INT_LEAST64_MAX  INT64_MAX
+#   define  INT_LEAST64_MIN  INT64_MIN
+# endif
+#endif
+#undef stdint_least_defined
+
+/*
+ *  The ANSI C committee pretending to know or specify anything about
+ *  performance is the epitome of misguided arrogance.  The mandate of
+ *  this file is to *ONLY* ever support that absolute minimum
+ *  definition of the fast integer types, for compatibility purposes.
+ *  No extensions, and no attempt to suggest what may or may not be a
+ *  faster integer type will ever be made in this file.  Developers are
+ *  warned to stay away from these types when using this or any other
+ *  stdint.h.
+ */
+
+typedef   int_least8_t   int_fast8_t;
+typedef  uint_least8_t  uint_fast8_t;
+typedef  int_least16_t  int_fast16_t;
+typedef uint_least16_t uint_fast16_t;
+typedef  int_least32_t  int_fast32_t;
+typedef uint_least32_t uint_fast32_t;
+#define  UINT_FAST8_MAX  UINT_LEAST8_MAX
+#define   INT_FAST8_MAX   INT_LEAST8_MAX
+#define UINT_FAST16_MAX UINT_LEAST16_MAX
+#define  INT_FAST16_MAX  INT_LEAST16_MAX
+#define UINT_FAST32_MAX UINT_LEAST32_MAX
+#define  INT_FAST32_MAX  INT_LEAST32_MAX
+#define   INT_FAST8_MIN   INT_LEAST8_MIN
+#define  INT_FAST16_MIN  INT_LEAST16_MIN
+#define  INT_FAST32_MIN  INT_LEAST32_MIN
+#ifdef stdint_int64_defined
+  typedef  int_least64_t  int_fast64_t;
+  typedef uint_least64_t uint_fast64_t;
+# define UINT_FAST64_MAX UINT_LEAST64_MAX
+# define  INT_FAST64_MAX  INT_LEAST64_MAX
+# define  INT_FAST64_MIN  INT_LEAST64_MIN
+#endif
+
+#undef stdint_int64_defined
+
+/*
+ *  Whatever piecemeal, per compiler thing we can do about the wchar_t
+ *  type limits.
+ */
+
+#if defined(__WATCOMC__) || defined(_MSC_VER) || defined (__GNUC__)
+# include <wchar.h>
+# ifndef WCHAR_MIN
+#  define WCHAR_MIN 0
+# endif
+# ifndef WCHAR_MAX
+#  define WCHAR_MAX ((wchar_t)-1)
+# endif
+#endif
+
+/*
+ *  Whatever piecemeal, per compiler/platform thing we can do about the
+ *  (u)intptr_t types and limits.
+ */
+
+#if (defined (_MSC_VER) && defined (_UINTPTR_T_DEFINED)) || defined (_UINTPTR_T)
+# define STDINT_H_UINTPTR_T_DEFINED
+#endif
+
+#ifndef STDINT_H_UINTPTR_T_DEFINED
+# if defined (__alpha__) || defined (__ia64__) || defined (__x86_64__) || defined (_WIN64) || defined (__ppc64__)
+#  define stdint_intptr_bits 64
+# elif defined (__WATCOMC__) || defined (__TURBOC__)
+#  if defined(__TINY__) || defined(__SMALL__) || defined(__MEDIUM__)
+#    define stdint_intptr_bits 16
+#  else
+#    define stdint_intptr_bits 32
+#  endif
+# elif defined (__i386__) || defined (_WIN32) || defined (WIN32) || defined (__ppc64__)
+#  define stdint_intptr_bits 32
+# elif defined (__INTEL_COMPILER)
+/* TODO -- what did Intel do about x86-64? */
+# else
+/* #error "This platform might not be supported yet" */
+# endif
+
+# ifdef stdint_intptr_bits
+#  define stdint_intptr_glue3_i(a,b,c)  a##b##c
+#  define stdint_intptr_glue3(a,b,c)    stdint_intptr_glue3_i(a,b,c)
+#  ifndef PRINTF_INTPTR_MODIFIER
+#    define PRINTF_INTPTR_MODIFIER      stdint_intptr_glue3(PRINTF_INT,stdint_intptr_bits,_MODIFIER)
+#  endif
+#  ifndef PTRDIFF_MAX
+#    define PTRDIFF_MAX                 stdint_intptr_glue3(INT,stdint_intptr_bits,_MAX)
+#  endif
+#  ifndef PTRDIFF_MIN
+#    define PTRDIFF_MIN                 stdint_intptr_glue3(INT,stdint_intptr_bits,_MIN)
+#  endif
+#  ifndef UINTPTR_MAX
+#    define UINTPTR_MAX                 stdint_intptr_glue3(UINT,stdint_intptr_bits,_MAX)
+#  endif
+#  ifndef INTPTR_MAX
+#    define INTPTR_MAX                  stdint_intptr_glue3(INT,stdint_intptr_bits,_MAX)
+#  endif
+#  ifndef INTPTR_MIN
+#    define INTPTR_MIN                  stdint_intptr_glue3(INT,stdint_intptr_bits,_MIN)
+#  endif
+#  ifndef INTPTR_C
+#    define INTPTR_C(x)                 stdint_intptr_glue3(INT,stdint_intptr_bits,_C)(x)
+#  endif
+#  ifndef UINTPTR_C
+#    define UINTPTR_C(x)                stdint_intptr_glue3(UINT,stdint_intptr_bits,_C)(x)
+#  endif
+  typedef stdint_intptr_glue3(uint,stdint_intptr_bits,_t) uintptr_t;
+  typedef stdint_intptr_glue3( int,stdint_intptr_bits,_t)  intptr_t;
+# else
+/* TODO -- This following is likely wrong for some platforms, and does
+   nothing for the definition of uintptr_t. */
+  typedef ptrdiff_t intptr_t;
+# endif
+# define STDINT_H_UINTPTR_T_DEFINED
+#endif
+
+/*
+ *  Assumes sig_atomic_t is signed and we have a 2s complement machine.
+ */
+
+#ifndef SIG_ATOMIC_MAX
+# define SIG_ATOMIC_MAX ((((sig_atomic_t) 1) << (sizeof (sig_atomic_t)*CHAR_BIT-1)) - 1)
+#endif
+
+#endif
+
+#if defined (__TEST_PSTDINT_FOR_CORRECTNESS)
+
+/*
+ *  Please compile with the maximum warning settings to make sure macros are not
+ *  defined more than once.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#define glue3_aux(x,y,z) x ## y ## z
+#define glue3(x,y,z) glue3_aux(x,y,z)
+
+#define DECLU(bits) glue3(uint,bits,_t) glue3(u,bits,) = glue3(UINT,bits,_C) (0);
+#define DECLI(bits) glue3(int,bits,_t) glue3(i,bits,) = glue3(INT,bits,_C) (0);
+
+#define DECL(us,bits) glue3(DECL,us,) (bits)
+
+#define TESTUMAX(bits) glue3(u,bits,) = ~glue3(u,bits,); if (glue3(UINT,bits,_MAX) != glue3(u,bits,)) printf ("Something wrong with UINT%d_MAX\n", bits)
+
+int main () {
+	DECL(I,8)
+	DECL(U,8)
+	DECL(I,16)
+	DECL(U,16)
+	DECL(I,32)
+	DECL(U,32)
+#ifdef INT64_MAX
+	DECL(I,64)
+	DECL(U,64)
+#endif
+	intmax_t imax = INTMAX_C(0);
+	uintmax_t umax = UINTMAX_C(0);
+	char str0[256], str1[256];
+
+	sprintf (str0, "%d %x\n", 0, ~0);
+
+	sprintf (str1, "%d %x\n",  i8, ~0);
+	if (0 != strcmp (str0, str1)) printf ("Something wrong with i8 : %s\n", str1);
+	sprintf (str1, "%u %x\n",  u8, ~0);
+	if (0 != strcmp (str0, str1)) printf ("Something wrong with u8 : %s\n", str1);
+	sprintf (str1, "%d %x\n",  i16, ~0);
+	if (0 != strcmp (str0, str1)) printf ("Something wrong with i16 : %s\n", str1);
+	sprintf (str1, "%u %x\n",  u16, ~0);
+	if (0 != strcmp (str0, str1)) printf ("Something wrong with u16 : %s\n", str1);
+	sprintf (str1, "%" PRINTF_INT32_MODIFIER "d %x\n",  i32, ~0);
+	if (0 != strcmp (str0, str1)) printf ("Something wrong with i32 : %s\n", str1);
+	sprintf (str1, "%" PRINTF_INT32_MODIFIER "u %x\n",  u32, ~0);
+	if (0 != strcmp (str0, str1)) printf ("Something wrong with u32 : %s\n", str1);
+#ifdef INT64_MAX
+	sprintf (str1, "%" PRINTF_INT64_MODIFIER "d %x\n",  i64, ~0);
+	if (0 != strcmp (str0, str1)) printf ("Something wrong with i64 : %s\n", str1);
+#endif
+	sprintf (str1, "%" PRINTF_INTMAX_MODIFIER "d %x\n",  imax, ~0);
+	if (0 != strcmp (str0, str1)) printf ("Something wrong with imax : %s\n", str1);
+	sprintf (str1, "%" PRINTF_INTMAX_MODIFIER "u %x\n",  umax, ~0);
+	if (0 != strcmp (str0, str1)) printf ("Something wrong with umax : %s\n", str1);
+
+	TESTUMAX(8);
+	TESTUMAX(16);
+	TESTUMAX(32);
+#ifdef INT64_MAX
+	TESTUMAX(64);
+#endif
+
+	return EXIT_SUCCESS;
+}
+
+#endif

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/berkeley-abc.git



More information about the debian-science-commits mailing list