]> git.unchartedbackwaters.co.uk Git - francis/stp.git/commitdiff
Importing the new cryptominisat
authormsoos <msoos@e59a4935-1847-0410-ae03-e826735625c1>
Wed, 14 Apr 2010 18:18:39 +0000 (18:18 +0000)
committermsoos <msoos@e59a4935-1847-0410-ae03-e826735625c1>
Wed, 14 Apr 2010 18:18:39 +0000 (18:18 +0000)
git-svn-id: https://stp-fast-prover.svn.sourceforge.net/svnroot/stp-fast-prover/trunk/stp@676 e59a4935-1847-0410-ae03-e826735625c1

65 files changed:
src/AST/Makefile
src/STPManager/Makefile
src/main/Makefile
src/main/main.cpp
src/sat/cryptominisat2/BitArray.h
src/sat/cryptominisat2/BoundedQueue.h
src/sat/cryptominisat2/CSet.h [new file with mode: 0644]
src/sat/cryptominisat2/Clause.cpp [new file with mode: 0644]
src/sat/cryptominisat2/Clause.h
src/sat/cryptominisat2/ClauseCleaner.cpp
src/sat/cryptominisat2/ClauseCleaner.h
src/sat/cryptominisat2/Conglomerate.cpp
src/sat/cryptominisat2/Conglomerate.h
src/sat/cryptominisat2/DoublePackedRow.h [new file with mode: 0644]
src/sat/cryptominisat2/FailedVarSearcher.cpp [new file with mode: 0644]
src/sat/cryptominisat2/FailedVarSearcher.h [new file with mode: 0644]
src/sat/cryptominisat2/FindUndef.cpp
src/sat/cryptominisat2/FindUndef.h
src/sat/cryptominisat2/Gaussian.cpp
src/sat/cryptominisat2/Gaussian.h
src/sat/cryptominisat2/GaussianConfig.h
src/sat/cryptominisat2/Logger.cpp
src/sat/cryptominisat2/Logger.h
src/sat/cryptominisat2/Makefile
src/sat/cryptominisat2/MatrixFinder.cpp
src/sat/cryptominisat2/MatrixFinder.h
src/sat/cryptominisat2/MersenneTwister.h [new file with mode: 0644]
src/sat/cryptominisat2/PackedMatrix.h
src/sat/cryptominisat2/PackedRow.cpp
src/sat/cryptominisat2/PackedRow.h
src/sat/cryptominisat2/PartFinder.cpp [new file with mode: 0644]
src/sat/cryptominisat2/PartFinder.h [new file with mode: 0644]
src/sat/cryptominisat2/PartHandler.cpp [new file with mode: 0644]
src/sat/cryptominisat2/PartHandler.h [new file with mode: 0644]
src/sat/cryptominisat2/RestartTypeChooser.cpp
src/sat/cryptominisat2/RestartTypeChooser.h
src/sat/cryptominisat2/SmallPtr.cpp [new file with mode: 0644]
src/sat/cryptominisat2/SmallPtr.h [new file with mode: 0644]
src/sat/cryptominisat2/Solver.cpp
src/sat/cryptominisat2/Solver.h
src/sat/cryptominisat2/SolverTypes.h
src/sat/cryptominisat2/Subsumer.cpp [new file with mode: 0644]
src/sat/cryptominisat2/Subsumer.h [new file with mode: 0644]
src/sat/cryptominisat2/VERSION
src/sat/cryptominisat2/VarReplacer.cpp
src/sat/cryptominisat2/VarReplacer.h
src/sat/cryptominisat2/XSet.h [new file with mode: 0644]
src/sat/cryptominisat2/XorFinder.cpp
src/sat/cryptominisat2/XorFinder.h
src/sat/cryptominisat2/XorSubsumer.cpp [new file with mode: 0644]
src/sat/cryptominisat2/XorSubsumer.h [new file with mode: 0644]
src/sat/cryptominisat2/constants.h
src/sat/cryptominisat2/msvc/stdint.h [new file with mode: 0644]
src/sat/cryptominisat2/mtl/Alg.h
src/sat/cryptominisat2/mtl/BasicHeap.h
src/sat/cryptominisat2/mtl/BoxedVec.h
src/sat/cryptominisat2/mtl/Heap.h
src/sat/cryptominisat2/mtl/Map.h
src/sat/cryptominisat2/mtl/Queue.h
src/sat/cryptominisat2/mtl/Vec.h
src/sat/cryptominisat2/pool.hpp [new file with mode: 0644]
src/sat/cryptominisat2/poolfwd.hpp [new file with mode: 0644]
src/sat/cryptominisat2/singleton.hpp [new file with mode: 0644]
src/sat/cryptominisat2/time_mem.h
src/to-sat/ToSAT.cpp

index 29d485fbf0ed0738c4db467a58cac64a70ee4591..c801df6dcd0ddc43ba251baa9a2e5077e2e073bd 100644 (file)
@@ -5,7 +5,8 @@ SRCS=$(wildcard  *.cpp)
 SRCS+=$(wildcard  NodeFactory/*.cpp)
 OBJS = $(SRCS:.cpp=.o)
 OBJS+= ASTKind.o
-CFLAGS += -I$(MTL)
+CFLAGS += -I$(MTL) -I$(SOLVER_INCLUDE)
+
 
 #Make the ast library for use by other modules
 libast.a:$(OBJS) depend
index d60996a03949995c3590992488b6f0f743b69872..06abd42ef42d4a1a80fa975fcd21e6089b9b471c 100644 (file)
@@ -16,4 +16,4 @@ clean:
 depend: $(SRCS)
        @$(CXX) -MM $(CXXFLAGS) $(SRCS) > $@
 
-#-include depend
\ No newline at end of file
+#-include depend
index ca818f1794086fcce3a5dee74e4552484cabdc22..83496cce7c988b1ec5de41e443b709dac848a0c6 100644 (file)
@@ -3,6 +3,7 @@ include $(TOP)/scripts/Makefile.common
 
 SRCS=main.cpp versionString.cpp Globals.cpp
 OBJS = $(SRCS:.cpp=.o)
+CFLAGS += -I$(MTL) -I$(SOLVER_INCLUDE)
 
 LIBS =         -L../to-sat -ltosat \
        -L../STPManager -lstpmgr \
@@ -17,7 +18,7 @@ LIBS =        -L../to-sat -ltosat \
 # This rebuilds each time, because the target "parser" is not created
 # Until the dependencies on each of the libraries is included, that's safest.
 parser:  $(OBJS) depend
-       $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(LIBS) -o stp
+       $(CXX) $(CXXFLAGS) -I$(MTL) $(LDFLAGS) $(OBJS) $(LIBS) -o stp
        @mv stp ../../bin/stp
 
 #.PHONY: clean
@@ -40,4 +41,4 @@ depend: $(SRCS)
 
 
 
-#-include depend
\ No newline at end of file
+#-include depend
index bc129464943b17fb6a5c46957f260539a6a98895..afae20b422a9aa778da6eef6a6cc81d8000cf660 100644 (file)
@@ -14,6 +14,8 @@
 #include "../AST/NodeFactory/TypeChecker.h"
 #include "../AST/NodeFactory/SimplifyingNodeFactory.h"
 #include "../parser/ParserInterface.h"
+#include <sys/time.h>
+
 
 #ifdef EXT_HASH_MAP
 using namespace __gnu_cxx;
index 74b3b8edec998d369641bc7d265fa805ef451085..7edc6dbaac06d1895ce20d1d38a02f5815822e7f 100644 (file)
@@ -20,13 +20,17 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 //#define DEBUG_BITARRAY
 
-#include <stdint.h>
 #include <string.h>
 #include <assert.h>
+#ifdef _MSC_VER
+#include <msvc/stdint.h>
+#else
+#include <stdint.h>
+#endif //_MSC_VER
 
-#ifndef uint
-#define uint unsigned int
-#endif
+namespace MINISAT
+{
+using namespace MINISAT;
 
 class BitArray
 {
@@ -124,5 +128,7 @@ private:
     uint64_t* mp;
 };
 
+}; //NAMESPACE MINISAT
+
 #endif //BITARRAY_H
 
index c4115fdeaedbf6db24bc65d12d03e9037dd6752e..a705a6dc0fe41ce4863fa61e574f6e418583ddd5 100644 (file)
@@ -21,62 +21,68 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
 #ifndef BoundedQueue_h
 #define BoundedQueue_h
 
-#include "../mtl/Vec.h"
+#ifdef _MSC_VER
+#include <msvc/stdint.h>
+#else
+#include <stdint.h>
+#endif //_MSC_VER
+
+#include "Vec.h"
 
 //=================================================================================================
 
 namespace MINISAT
 {
+using namespace MINISAT;
 
 template <class T>
 class bqueue {
     vec<T>  elems;
     int     first;
-       int             last;
-       unsigned long long sumofqueue;
-       int     maxsize;
-       int     queuesize; // Number of current elements (must be < maxsize !)
-       
+    int     last;
+    uint64_t sumofqueue;
+    int     maxsize;
+    int     queuesize; // Number of current elements (must be < maxsize !)
+    
 public:
-       bqueue(void) : first(0), last(0), sumofqueue(0), maxsize(0), queuesize(0) { } 
-       
-       void initSize(int size) {growTo(size);} // Init size of bounded size queue
-       
-       void push(T x) {
-               if (queuesize==maxsize) {
-                       assert(last==first); // The queue is full, next value to enter will replace oldest one
-                       sumofqueue -= elems[last];
-                       if ((++last) == maxsize) last = 0;
-               } else 
-                       queuesize++;
-               sumofqueue += x;
-               elems[first] = x;
-               if ((++first) == maxsize) first = 0;
-       }
+    bqueue(void) : first(0), last(0), sumofqueue(0), maxsize(0), queuesize(0) { } 
+    
+    void initSize(int size) {growTo(size);} // Init size of bounded size queue
+    
+    void push(T x) {
+        if (queuesize==maxsize) {
+            assert(last==first); // The queue is full, next value to enter will replace oldest one
+            sumofqueue -= elems[last];
+            if ((++last) == maxsize) last = 0;
+        } else 
+            queuesize++;
+        sumofqueue += x;
+        elems[first] = x;
+        if ((++first) == maxsize) first = 0;
+    }
 
-       T peek() { assert(queuesize>0); return elems[last]; }
-       void pop() {sumofqueue-=elems[last]; queuesize--; if ((++last) == maxsize) last = 0;}
-       
-       unsigned long long getsum() const {return sumofqueue;}
-       unsigned int getavg() const {return (unsigned int)(sumofqueue/((unsigned long long)queuesize));}
-       int isvalid() const {return (queuesize==maxsize);}
-       
-       void growTo(int size) {
-               elems.growTo(size); 
-               first=0; maxsize=size; queuesize = 0;
-               for(int i=0;i<size;i++) elems[i]=0; 
-       }
+    T peek() { assert(queuesize>0); return elems[last]; }
+    void pop() {sumofqueue-=elems[last]; queuesize--; if ((++last) == maxsize) last = 0;}
+    
+    uint64_t getsum() const {return sumofqueue;}
+    uint32_t getavg() const {return (uint64_t)sumofqueue/(uint64_t)queuesize;}
+    int isvalid() const {return (queuesize==maxsize);}
+    
+    void growTo(int size) {
+        elems.growTo(size); 
+        first=0; maxsize=size; queuesize = 0;
+        for(int i=0;i<size;i++) elems[i]=0; 
+    }
 
-       void fastclear() {first = 0; last = 0; queuesize=0; sumofqueue=0;} // to be called after restarts... Discard the queue
-       
+    void fastclear() {first = 0; last = 0; queuesize=0; sumofqueue=0;} // to be called after restarts... Discard the queue
+    
     int  size(void)    { return queuesize; }
 
     void clear(bool dealloc = false)   { elems.clear(dealloc); first = 0; maxsize=0; queuesize=0;sumofqueue=0;}
-
-
-};
-
 };
 
 //=================================================================================================
+
+}; //namespace MINISAT
+
 #endif
diff --git a/src/sat/cryptominisat2/CSet.h b/src/sat/cryptominisat2/CSet.h
new file mode 100644 (file)
index 0000000..cf8661a
--- /dev/null
@@ -0,0 +1,136 @@
+/**************************************************************************************************
+From: Solver.C -- (C) Niklas Een, Niklas Sorensson, 2004
+**************************************************************************************************/
+
+#ifndef CSET_H
+#define CSET_H
+
+#include "Vec.h"
+#include <limits>
+#ifdef _MSC_VER
+#include <msvc/stdint.h>
+#else
+#include <stdint.h>
+#endif //_MSC_VER
+
+namespace MINISAT
+{
+using namespace MINISAT;
+
+class Clause;
+
+template <class T>
+uint32_t calcAbstraction(const T& ps) {
+    uint32_t abstraction = 0;
+    for (uint32_t i = 0; i != ps.size(); i++)
+        abstraction |= 1 << (ps[i].toInt() & 31);
+    return abstraction;
+}
+
+//#pragma pack(push)
+//#pragma pack(1)
+class ClauseSimp
+{
+    public:
+        ClauseSimp(Clause* c, const uint32_t _index) :
+        clause(c)
+        , index(_index)
+        {}
+        
+        Clause* clause;
+        uint32_t index;
+};
+//#pragma pack(pop)
+
+class CSet {
+    vec<uint32_t>       where;  // Map clause ID to position in 'which'.
+    vec<ClauseSimp> which;  // List of clauses (for fast iteration). May contain 'Clause_NULL'.
+    vec<uint32_t>       free;   // List of positions holding 'Clause_NULL'.
+    
+    public:
+        //ClauseSimp& operator [] (uint32_t index) { return which[index]; }
+        void reserve(uint32_t size) { where.reserve(size);}
+        uint32_t size(void) const { return which.size(); }
+        uint32_t nElems(void) const { return which.size() - free.size(); }
+        
+        bool add(const ClauseSimp& c) {
+            assert(c.clause != NULL);
+            where.growTo(c.index+1, std::numeric_limits<uint32_t>::max());
+            if (where[c.index] != std::numeric_limits<uint32_t>::max()) {
+                return true;
+            }
+            if (free.size() > 0){
+                where[c.index] = free.last();
+                which[free.last()] = c;
+                free.pop();
+            }else{
+                where[c.index] = which.size();
+                which.push(c);
+            }
+            return false;
+        }
+        
+        bool exclude(const ClauseSimp& c) {
+            assert(c.clause != NULL);
+            if (c.index >= where.size() || where[c.index] == std::numeric_limits<uint32_t>::max()) {
+                //not inside
+                return false;
+            }
+            free.push(where[c.index]);
+            which[where[c.index]].clause = NULL;
+            where[c.index] = std::numeric_limits<uint32_t>::max();
+            return true;
+        }
+        
+        void clear(void) {
+            for (uint32_t i = 0; i < which.size(); i++)  {
+                if (which[i].clause != NULL) {
+                    where[which[i].index] = std::numeric_limits<uint32_t>::max();
+                }
+            }
+            which.clear();
+            free.clear();
+        }
+        
+        class iterator
+        {
+            public:
+                iterator(ClauseSimp* _it) :
+                it(_it)
+                {}
+                
+                void operator++()
+                {
+                    it++;
+                }
+                
+                const bool operator!=(const iterator& iter) const
+                {
+                    return (it != iter.it);;
+                }
+                
+                ClauseSimp& operator*() {
+                    return *it;
+                }
+                
+                ClauseSimp*& operator->() {
+                    return it;
+                }
+            private:
+                ClauseSimp* it;
+        };
+        
+        iterator begin()
+        {
+            return iterator(which.getData());
+        }
+        
+        iterator end()
+        {
+            return iterator(which.getData() + which.size());
+        }
+};
+
+}; //NAMESPACE MINISAT
+
+#endif //CSET_H
\ No newline at end of file
diff --git a/src/sat/cryptominisat2/Clause.cpp b/src/sat/cryptominisat2/Clause.cpp
new file mode 100644 (file)
index 0000000..b2bc8bc
--- /dev/null
@@ -0,0 +1,3 @@
+#include "Clause.h"
+
+//boost::pool<> binaryClausePool(sizeof(Clause)+2*sizeof(Lit));
index 6983b96329ebbe15d70e5ad263c6f8d997c2213a..730b62c424f6f4119edd9913b5dd13cbefb8ba71 100644 (file)
@@ -21,23 +21,28 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
 #ifndef CLAUSE_H
 #define CLAUSE_H
 
+#ifdef _MSC_VER
+#include <msvc/stdint.h>
+#else
 #include <stdint.h>
+#endif //_MSC_VER
 #include <cstdio>
 #include <vector>
 #include <sys/types.h>
-#include "mtl/Vec.h"
+#include "Vec.h"
 #include "SolverTypes.h"
 #include "PackedRow.h"
-
-namespace MINISAT
-{
-
+#include "constants.h"
+//#include "pool.hpp"
 #ifndef uint
 #define uint unsigned int
 #endif
 
 using std::vector;
 
+namespace MINISAT
+{
+using namespace MINISAT;
 
 //=================================================================================================
 // Clause -- a simple class for representing a clause:
@@ -46,59 +51,109 @@ class MatrixFinder;
 
 class Clause
 {
-public:
-    const uint group;
 protected:
-    /**
-    bit-layout of size_etc:
     
-    range           type             meaning
-    --------------------------------------------
-    0th bit         bool            learnt clause
-    1st - 2nd bit   2bit int        marking
-    3rd bit         bool            inverted xor
-    4th -31st bit  28bit uint       size
-    */
-    uint32_t size_etc; 
-    union { int act; uint32_t abst; } extra;
+    #ifdef STATS_NEEDED
+    uint group;
+    #endif
+    
+    uint32_t isLearnt:1;
+    uint32_t strenghtened:1;
+    uint32_t varChanged:1;
+    uint32_t sorted:1;
+    uint32_t invertedXor:1;
+    uint32_t isXorClause:1;
+    uint32_t subsume0Done:1;
+    uint32_t mySize:20;
+    
+    union  {int32_t act; uint32_t abst;} extra;
+    #ifdef _MSC_VER
+    Lit     data[1];
+    #else
     Lit     data[0];
+    #endif //_MSC_VER
 
+#ifdef _MSC_VER
 public:
-
+#endif //_MSC_VER
     template<class V>
-    Clause(const V& ps, const uint _group, const bool learnt) :
-            group(_group)
+    Clause(const V& ps, const uint _group, const bool learnt)
     {
-        size_etc = 0;
-        setSize(ps.size());
-        setLearnt(learnt);
+        isXorClause = false;
+        strenghtened = false;
+        sorted = false;
+        varChanged = true;
+        subsume0Done = false;
+        mySize = ps.size();
+        isLearnt = learnt;
+        setGroup(_group);
         for (uint i = 0; i < ps.size(); i++) data[i] = ps[i];
         if (learnt) extra.act = 0;
         else calcAbstraction();
     }
 
+public:
+    #ifndef _MSC_VER
     // -- use this function instead:
     template<class T>
     friend Clause* Clause_new(const T& ps, const uint group, const bool learnt = false);
+    #endif //_MSC_VER
 
-    uint         size        ()      const {
-        return size_etc >> 4;
+    const uint   size        ()      const {
+        return mySize;
     }
-    void         shrink      (uint i) {
+    void         resize      (const uint size) {
+        mySize = size;
+    }
+    void         shrink      (const uint i) {
         assert(i <= size());
-        size_etc = (((size_etc >> 4) - i) << 4) | (size_etc & ((1 << 4)-1));
+        mySize -= i;
     }
     void         pop         () {
         shrink(1);
     }
-    bool         learnt      ()      const {
-        return size_etc & 1;
+    const bool   isXor       () {
+        return isXorClause;
+    }
+    const bool   learnt      ()      const {
+        return isLearnt;
+    }
+    const bool getStrenghtened() const {
+        return strenghtened;
     }
-    uint32_t     mark        ()      const {
-        return (size_etc >> 1) & 3;
+    void setStrenghtened() {
+        strenghtened = true;
+        sorted = false;
+        subsume0Done = false;
     }
-    void         mark        (uint32_t m) {
-        size_etc = (size_etc & ~6) | ((m & 3) << 1);
+    void unsetStrenghtened() {
+        strenghtened = false;
+    }
+    const bool getVarChanged() const {
+        return varChanged;
+    }
+    void setVarChanged() {
+        varChanged = true;
+        sorted = false;
+        subsume0Done = false;
+    }
+    void unsetVarChanged() {
+        varChanged = false;
+    }
+    const bool getSorted() const {
+        return sorted;
+    }
+    void setSorted() {
+        sorted = true;
+    }
+    void setUnsorted() {
+        sorted = false;
+    }
+    void subsume0Finished() {
+        subsume0Done = 1;
+    }
+    const bool subsume0IsFinished() {
+        return subsume0Done;
     }
 
     Lit&         operator [] (uint32_t i) {
@@ -116,19 +171,33 @@ public:
         return extra.act;
     }
     
-    Lit subsumes (const Clause& other) const;
+    void         makeNonLearnt()  {
+        assert(isLearnt);
+        isLearnt = false;
+        calcAbstraction();
+    }
+    
+    void         makeLearnt(const uint32_t newActivity)  {
+        extra.act = newActivity;
+        isLearnt = true;
+    }
     
-    inline void strengthen(const Lit p)
+    inline void  strengthen(const Lit p)
     {
         remove(*this, p);
+        sorted = false;
         calcAbstraction();
     }
     
     void calcAbstraction() {
-        uint32_t abstraction = 0;
+        extra.abst = 0;
         for (uint32_t i = 0; i != size(); i++)
-            abstraction |= 1 << (data[i].var() & 31);
-        extra.abst = abstraction;
+            extra.abst |= 1 << (data[i].toInt() & 31);
+    }
+    
+    uint32_t getAbst()
+    {
+        return extra.abst;
     }
 
     const Lit*     getData     () const {
@@ -137,8 +206,14 @@ public:
     Lit*    getData     () {
         return data;
     }
+    const Lit*     getDataEnd     () const {
+        return data+size();
+    }
+    Lit*    getDataEnd     () {
+        return data+size();
+    }
     void print() {
-        printf("Clause   group: %d, size: %d, learnt:%d, lits: ", group, size(), learnt());
+        printf("Clause   group: %d, size: %d, learnt:%d, lits: ", getGroup(), size(), learnt());
         plainPrint();
     }
     void plainPrint(FILE* to = stdout) const {
@@ -148,41 +223,69 @@ public:
         }
         fprintf(to, "0\n");
     }
-protected:
-    void setSize(uint32_t size) {
-        size_etc = (size_etc & ((1 << 4)-1)) + (size << 4);
+    #ifdef STATS_NEEDED
+    const uint32_t getGroup() const
+    {
+        return group;
+    }
+    void setGroup(const uint32_t _group)
+    {
+        group = _group;
+    }
+    #else
+    const uint getGroup() const
+    {
+        return 0;
     }
-    void setLearnt(bool learnt) {
-        size_etc = (size_etc & ~1) + learnt;
+    void setGroup(const uint32_t _group)
+    {
+        return;
     }
+    #endif //STATS_NEEDED
 };
 
 class XorClause : public Clause
 {
+    
+#ifdef _MSC_VER
 public:
+#else //_MSC_VER
+protected:
+#endif //_MSC_VER
+
     // NOTE: This constructor cannot be used directly (doesn't allocate enough memory).
     template<class V>
     XorClause(const V& ps, const bool inverted, const uint _group) :
         Clause(ps, _group, false)
     {
-        setInverted(inverted);
+        invertedXor = inverted;
+        isXorClause = true;
+        calcXorAbstraction();
     }
 
+public:
+    #ifndef _MSC_VER
     // -- use this function instead:
     template<class V>
     friend XorClause* XorClause_new(const V& ps, const bool inverted, const uint group);
+    #endif //_MSC_VER
 
     inline bool xor_clause_inverted() const
     {
-        return size_etc & 8;
+        return invertedXor;
     }
     inline void invert(bool b)
     {
-        size_etc ^= (uint32_t)b << 3;
+        invertedXor ^= b;
+    }
+    void calcXorAbstraction() {
+        extra.abst = 0;
+        for (uint32_t i = 0; i != size(); i++)
+            extra.abst |= 1 << (data[i].var() & 31);
     }
 
     void print() {
-        printf("XOR Clause   group: %d, size: %d, learnt:%d, lits:\"", group, size(), learnt());
+        printf("XOR Clause   group: %d, size: %d, learnt:%d, lits:\"", getGroup(), size(), learnt());
         plainPrint();
     }
     
@@ -197,18 +300,18 @@ public:
     }
     
     friend class MatrixFinder;
-    
-protected:
-    inline void setInverted(bool inverted)
-    {
-        size_etc = (size_etc & 7) + ((uint32_t)inverted << 3) + (size_etc & ~15);
-    }
 };
 
+//extern boost::pool<> binaryClausePool;
+
 template<class T>
 Clause* Clause_new(const T& ps, const uint group, const bool learnt = false)
 {
-    void* mem = malloc(sizeof(Clause) + sizeof(Lit)*(ps.size()));
+    void* mem;
+    //if (ps.size() != 2)
+        mem = malloc(sizeof(Clause) + sizeof(Lit)*(ps.size()));
+    //else
+    //    mem = binaryClausePool.malloc();
     Clause* real= new (mem) Clause(ps, group, learnt);
     return real;
 }
@@ -221,6 +324,13 @@ XorClause* XorClause_new(const T& ps, const bool inverted, const uint group)
     return real;
 }
 
+inline void clauseFree(Clause* c)
+{
+    //if (binaryClausePool.is_from(c)) binaryClausePool.free(c);
+    //else 
+    free(c);
+}
+
 /*_________________________________________________________________________________________________
 |
 |  subsumes : (other : const Clause&)  ->  Lit
@@ -234,7 +344,7 @@ XorClause* XorClause_new(const T& ps, const bool inverted, const uint group)
 |       lit_Undef  - Clause subsumes 'other'
 |       p          - The literal p can be deleted from 'other'
 |________________________________________________________________________________________________@*/
-inline Lit Clause::subsumes(const Clause& other) const
+/*inline Lit Clause::subsumes(const Clause& other) const
 {
     if (other.size() < size() || (extra.abst & ~other.extra.abst) != 0)
         return lit_Error;
@@ -259,23 +369,30 @@ inline Lit Clause::subsumes(const Clause& other) const
     }
     
     return ret;
-}
+}*/
 
+//typedef sptr<Clause> ClausePtr;
+//typedef sptr<XorClause> XorClausePtr;
+typedef Clause* ClausePtr;
+typedef XorClause* XorClausePtr;
 
+#pragma pack(push)
+#pragma pack(1)
 class WatchedBin {
     public:
-        WatchedBin(Clause *_clause, Lit _impliedLit) : impliedLit(_impliedLit), clause(_clause) {};
+        WatchedBin(Clause *_clause, Lit _impliedLit) : clause(_clause), impliedLit(_impliedLit) {};
+        ClausePtr clause;
         Lit impliedLit;
-        Clause *clause;
 };
 
 class Watched {
     public:
-        Watched(Clause *_clause, Lit _blockedLit) : blockedLit(_blockedLit), clause(_clause) {};
+        Watched(Clause *_clause, Lit _blockedLit) : clause(_clause), blockedLit(_blockedLit) {};
+        ClausePtr clause;
         Lit blockedLit;
-        Clause *clause;
 };
+#pragma pack(pop)
 
-};
+}; //NAMESPACE MINISAT
 
 #endif //CLAUSE_H
index 1a9abccec360a7621a7da303c7057c7fbdeda7ee..b7d34f239d7b1e57ceb12a7dad9a351e0156f518 100644 (file)
@@ -16,17 +16,22 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 **************************************************************************************************/
 
 #include "ClauseCleaner.h"
+#include "VarReplacer.h"
+
+#ifdef _MSC_VER
+#define __builtin_prefetch(a,b,c)
+#endif //_MSC_VER
+
+//#define DEBUG_CLEAN
 
 namespace MINISAT
 {
 using namespace MINISAT;
 
-//#define DEBUG_CLEAN
-
 ClauseCleaner::ClauseCleaner(Solver& _solver) :
     solver(_solver)
 {
-    for (uint i = 0; i < 4; i++) {
+    for (uint i = 0; i < 6; i++) {
         lastNumUnitarySat[i] = solver.get_unitary_learnts_num();
         lastNumUnitaryClean[i] = solver.get_unitary_learnts_num();
     }
@@ -62,18 +67,52 @@ void ClauseCleaner::removeSatisfied(vec<Clause*>& cs, ClauseSetType type, const
     if (lastNumUnitarySat[type] + limit >= solver.get_unitary_learnts_num())
         return;
     
-    int i,j;
-    for (i = j = 0; i < cs.size(); i++) {
-        if (satisfied(*cs[i]))
-            solver.removeClause(*cs[i]);
+    Clause **i,**j, **end;
+    for (i = j = cs.getData(), end = i + cs.size(); i != end; i++) {
+        if (i+1 != end)
+            __builtin_prefetch(*(i+1), 0, 0);
+        if (satisfied(**i))
+            solver.removeClause(**i);
         else
-            cs[j++] = cs[i];
+            *j++ = *i;
     }
     cs.shrink_(i - j);
     
     lastNumUnitarySat[type] = solver.get_unitary_learnts_num();
 }
 
+void ClauseCleaner::cleanClauses(vec<Clause*>& cs, ClauseSetType type, const uint limit)
+{
+    assert(solver.decisionLevel() == 0);
+    assert(solver.qhead == solver.trail.size());
+    
+    if (lastNumUnitaryClean[type] + limit >= solver.get_unitary_learnts_num())
+        return;
+    
+    Clause **s, **ss, **end;
+    for (s = ss = cs.getData(), end = s + cs.size();  s != end;) {
+        if (s+1 != end)
+            __builtin_prefetch(*(s+1), 1, 0);
+        if (cleanClause(**s)) {
+            clauseFree(*s);
+            s++;
+        } else if (type != ClauseCleaner::binaryClauses && (*s)->size() == 2) {
+            solver.binaryClauses.push(*s);
+            solver.becameBinary++;
+            s++;
+        } else {
+            *ss++ = *s++;
+        }
+    }
+    cs.shrink(s-ss);
+    
+    lastNumUnitaryClean[type] = solver.get_unitary_learnts_num();
+    
+    #ifdef VERBOSE_DEBUG
+    cout << "cleanClauses(Clause) useful ?? Removed: " << s-ss << endl;
+    #endif
+}
+
 inline const bool ClauseCleaner::cleanClause(Clause& c)
 {
     Lit origLit1 = c[0];
@@ -84,9 +123,10 @@ inline const bool ClauseCleaner::cleanClause(Clause& c)
     for (i = j = c.getData(), end = i + c.size();  i != end; i++) {
         lbool val = solver.value(*i);
         if (val == l_Undef) {
-            *j = *i;
-            j++;
+            *j++ = *i;
+            continue;
         }
+        
         if (val == l_True) {
             solver.detachModifiedClause(origLit1, origLit2, origSize, &c);
             return true;
@@ -96,8 +136,10 @@ inline const bool ClauseCleaner::cleanClause(Clause& c)
     if ((c.size() > 2) && (c.size() - (i-j) == 2)) {
         solver.detachModifiedClause(origLit1, origLit2, c.size(), &c);
         c.shrink(i-j);
+        c.setStrenghtened();
         solver.attachClause(c);
-    } else {
+    } else if (i != j) {
+        c.setStrenghtened();
         c.shrink(i-j);
         if (c.learnt())
             solver.learnts_literals -= i-j;
@@ -108,19 +150,20 @@ inline const bool ClauseCleaner::cleanClause(Clause& c)
     return false;
 }
 
-void ClauseCleaner::cleanClauses(vec<Clause*>& cs, ClauseSetType type, const uint limit)
+void ClauseCleaner::cleanClauses(vec<XorClause*>& cs, ClauseSetType type, const uint limit)
 {
-    #ifdef DEBUG_CLEAN
     assert(solver.decisionLevel() == 0);
-    #endif
+    assert(solver.qhead == solver.trail.size());
     
     if (lastNumUnitaryClean[type] + limit >= solver.get_unitary_learnts_num())
         return;
     
-    Clause **s, **ss, **end;
+    XorClause **s, **ss, **end;
     for (s = ss = cs.getData(), end = s + cs.size();  s != end;) {
+        if (s+1 != end)
+            __builtin_prefetch(*(s+1), 1, 0);
         if (cleanClause(**s)) {
-            free(*s);
+            solver.freeLater.push(*s);
             s++;
         } else {
             *ss++ = *s++;
@@ -131,44 +174,144 @@ void ClauseCleaner::cleanClauses(vec<Clause*>& cs, ClauseSetType type, const uin
     lastNumUnitaryClean[type] = solver.get_unitary_learnts_num();
     
     #ifdef VERBOSE_DEBUG
-    cout << "cleanClauses(Clause) useful ?? Removed: " << s-ss << endl;
+    cout << "cleanClauses(XorClause) useful: ?? Removed: " << s-ss << endl;
     #endif
 }
 
-void ClauseCleaner::cleanClauses(vec<XorClause*>& cs, ClauseSetType type, const uint limit)
+inline const bool ClauseCleaner::cleanClause(XorClause& c)
+{
+    Lit *i, *j, *end;
+    Var origVar1 = c[0].var();
+    Var origVar2 = c[1].var();
+    uint32_t origSize = c.size();
+    for (i = j = c.getData(), end = i + c.size();  i != end; i++) {
+        const lbool& val = solver.assigns[i->var()];
+        if (val.isUndef()) {
+            *j = *i;
+            j++;
+        } else c.invert(val.getBool());
+    }
+    c.shrink(i-j);
+    
+    switch (c.size()) {
+        case 0: {
+            solver.detachModifiedClause(origVar1, origVar2, origSize, &c);
+            return true;
+        }
+        case 2: {
+            vec<Lit> ps(2);
+            ps[0] = c[0].unsign();
+            ps[1] = c[1].unsign();
+            solver.varReplacer->replace(ps, c.xor_clause_inverted(), c.getGroup());
+            solver.detachModifiedClause(origVar1, origVar2, origSize, &c);
+            return true;
+        }
+        default:
+            if (i-j > 0) {
+                c.setStrenghtened();
+                solver.clauses_literals -= i-j;
+            }
+            return false;
+    }
+}
+
+void ClauseCleaner::cleanClausesBewareNULL(vec<ClauseSimp>& cs, ClauseCleaner::ClauseSetType type, Subsumer& subs, const uint limit)
 {
-    #ifdef DEBUG_CLEAN
     assert(solver.decisionLevel() == 0);
-    #endif
+    assert(solver.qhead == solver.trail.size());
     
     if (lastNumUnitaryClean[type] + limit >= solver.get_unitary_learnts_num())
         return;
     
-    XorClause **s, **ss, **end;
-    for (s = ss = cs.getData(), end = s + cs.size();  s != end;) {
-        if (cleanClause(**s)) {
-            (**s).mark(1);
-            solver.freeLater.push(*s);
-            s++;
+    ClauseSimp *s, *end;
+    for (s = cs.getData(), end = s + cs.size();  s != end; s++) {
+        if (s+1 != end)
+            __builtin_prefetch((s+1)->clause, 1, 0);
+        if (s->clause == NULL)
+            continue;
+        
+        if (cleanClauseBewareNULL(*s, subs)) {
+            continue;
+        } else if (s->clause->size() == 2)
+            solver.becameBinary++;
+    }
+    
+    lastNumUnitaryClean[type] = solver.get_unitary_learnts_num();
+}
+
+inline const bool ClauseCleaner::cleanClauseBewareNULL(ClauseSimp cc, Subsumer& subs)
+{
+    Clause& c = *cc.clause;
+    vec<Lit> origClause(c.size());
+    memcpy(origClause.getData(), c.getData(), sizeof(Lit)*c.size());
+    
+    Lit *i, *j, *end;
+    for (i = j = c.getData(), end = i + c.size();  i != end; i++) {
+        lbool val = solver.value(*i);
+        if (val == l_Undef) {
+            *j++ = *i;
+            continue;
+        }
+        
+        if (val == l_True) {
+            subs.unlinkModifiedClause(origClause, cc);
+            free(cc.clause);
+            return true;
+        }
+    }
+    
+    if (i != j) {
+        c.setStrenghtened();
+        if (origClause.size() > 2 && origClause.size()-(i-j) == 2) {
+            subs.unlinkModifiedClause(origClause, cc);
+            subs.clauses[cc.index] = cc;
+            c.shrink(i-j);
+            solver.attachClause(c);
+            subs.linkInAlreadyClause(cc);
         } else {
-            *ss++ = *s++;
+            c.shrink(i-j);
+            subs.unlinkModifiedClauseNoDetachNoNULL(origClause, cc);
+            subs.linkInAlreadyClause(cc);
+            if (c.learnt())
+                solver.learnts_literals -= i-j;
+            else
+                solver.clauses_literals -= i-j;
         }
+        c.calcAbstraction();
+        subs.updateClause(cc);
     }
-    cs.shrink(s-ss);
     
-    lastNumUnitaryClean[type] = solver.get_unitary_learnts_num();
+    return false;
+}
+
+void ClauseCleaner::cleanXorClausesBewareNULL(vec<XorClauseSimp>& cs, ClauseCleaner::ClauseSetType type, XorSubsumer& subs, const uint limit)
+{
+    assert(solver.decisionLevel() == 0);
+    assert(solver.qhead == solver.trail.size());
     
-    #ifdef VERBOSE_DEBUG
-    cout << "cleanClauses(XorClause) useful: ?? Removed: " << s-ss << endl;
-    #endif
+    if (lastNumUnitaryClean[type] + limit >= solver.get_unitary_learnts_num())
+        return;
+    
+    XorClauseSimp *s, *end;
+    for (s = cs.getData(), end = s + cs.size();  s != end; s++) {
+        if (s+1 != end)
+            __builtin_prefetch((s+1)->clause, 1, 0);
+        if (s->clause == NULL)
+            continue;
+        
+        cleanXorClauseBewareNULL(*s, subs);
+    }
+    
+    lastNumUnitaryClean[type] = solver.get_unitary_learnts_num();
 }
 
-inline const bool ClauseCleaner::cleanClause(XorClause& c)
+inline const bool ClauseCleaner::cleanXorClauseBewareNULL(XorClauseSimp cc, XorSubsumer& subs)
 {
+    XorClause& c = *cc.clause;
+    vec<Lit> origClause(c.size());
+    memcpy(origClause.getData(), c.getData(), sizeof(Lit)*c.size());
+    
     Lit *i, *j, *end;
-    Var origVar1 = c[0].var();
-    Var origVar2 = c[1].var();
-    uint32_t origSize = c.size();
     for (i = j = c.getData(), end = i + c.size();  i != end; i++) {
         const lbool& val = solver.assigns[i->var()];
         if (val.isUndef()) {
@@ -178,23 +321,30 @@ inline const bool ClauseCleaner::cleanClause(XorClause& c)
     }
     c.shrink(i-j);
     
-    switch (c.size()) {
+    switch(c.size()) {
         case 0: {
-            solver.detachModifiedClause(origVar1, origVar2, origSize, &c);
+            subs.unlinkModifiedClause(origClause, cc);
+            free(cc.clause);
             return true;
         }
         case 2: {
             vec<Lit> ps(2);
             ps[0] = c[0].unsign();
             ps[1] = c[1].unsign();
-            solver.varReplacer->replace(ps, c.xor_clause_inverted(), c.group);
-            solver.detachModifiedClause(origVar1, origVar2, origSize, &c);
+            solver.varReplacer->replace(ps, c.xor_clause_inverted(), c.getGroup());
+            subs.unlinkModifiedClause(origClause, cc);
+            free(cc.clause);
             return true;
         }
         default:
-            solver.clauses_literals -= i-j;
-            return false;
+            if (i-j > 0) {
+                subs.unlinkModifiedClauseNoDetachNoNULL(origClause, cc);
+                subs.linkInAlreadyClause(cc);
+                c.calcXorAbstraction();
+            }
     }
+    
+    return false;
 }
 
 bool ClauseCleaner::satisfied(const Clause& c) const
@@ -216,4 +366,4 @@ bool ClauseCleaner::satisfied(const XorClause& c) const
     return final;
 }
 
-};
+}; //NAMESPACE MINISAT
index de05c74a990b75739aa7d7b69a1873ea700c0a56..c099ae2f039c7d2dec8a54546515765f351c6c61 100644 (file)
@@ -18,45 +18,62 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #ifndef CLAUSECLEANER_H
 #define CLAUSECLEANER_H
 
+#ifdef _MSC_VER
+#include <msvc/stdint.h>
+#else
+#include <stdint.h>
+#endif //_MSC_VER
+
 #include "Solver.h"
+#include "Subsumer.h"
+#include "XorSubsumer.h"
 
 namespace MINISAT
 {
+using namespace MINISAT;
 
 class ClauseCleaner
 {
     public:
         ClauseCleaner(Solver& solver);
         
-        enum ClauseSetType {clauses, xorclauses, learnts, conglomerate};
+        enum ClauseSetType {clauses, xorclauses, learnts, binaryClauses, simpClauses, xorSimpClauses};
         
         void cleanClauses(vec<Clause*>& cs, ClauseSetType type, const uint limit = 0);
+        void cleanClausesBewareNULL(vec<ClauseSimp>& cs, ClauseSetType type, Subsumer& subs, const uint limit = 0);
+        void cleanXorClausesBewareNULL(vec<XorClauseSimp>& cs, ClauseSetType type, XorSubsumer& subs, const uint limit = 0);
+        const bool cleanClauseBewareNULL(ClauseSimp c, Subsumer& subs);
+        const bool cleanXorClauseBewareNULL(XorClauseSimp c, XorSubsumer& subs);
+        
         void cleanClauses(vec<XorClause*>& cs, ClauseSetType type, const uint limit = 0);
         void removeSatisfied(vec<Clause*>& cs, ClauseSetType type, const uint limit = 0);
         void removeSatisfied(vec<XorClause*>& cs, ClauseSetType type, const uint limit = 0);
-        void removeAndCleanAll();
+        void removeAndCleanAll(const bool nolimit = false);
         bool satisfied(const Clause& c) const;
         bool satisfied(const XorClause& c) const;
         
     private:
-        const bool cleanClause(Clause& c);
         const bool cleanClause(XorClause& c);
+        const bool cleanClause(Clause& c);
         
-        uint lastNumUnitarySat[4];
-        uint lastNumUnitaryClean[4];
+        uint lastNumUnitarySat[6];
+        uint lastNumUnitaryClean[6];
         
         Solver& solver;
 };
 
-inline void ClauseCleaner::removeAndCleanAll()
+inline void ClauseCleaner::removeAndCleanAll(const bool nolimit)
 {
+    //uint limit = std::min((uint)((double)solver.order_heap.size() * PERCENTAGECLEANCLAUSES), FIXCLEANREPLACE);
     uint limit = (double)solver.order_heap.size() * PERCENTAGECLEANCLAUSES;
+    if (nolimit) limit = 0;
     
+    removeSatisfied(solver.binaryClauses, ClauseCleaner::binaryClauses, limit);
     cleanClauses(solver.clauses, ClauseCleaner::clauses, limit);
     cleanClauses(solver.xorclauses, ClauseCleaner::xorclauses, limit);
     cleanClauses(solver.learnts, ClauseCleaner::learnts, limit);
 }
 
+}; //NAMESPACE MINISAT
 
-};
 #endif //CLAUSECLEANER_H
index 49c12cd0d67da103d8aa0b138396351d0bbb00ea..43caf21f3950c3fa25929632e63b38c148cc5da6 100644 (file)
@@ -16,12 +16,14 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 **************************************************************************************************/
 
 #include "Conglomerate.h"
-#include "Solver.h"
 #include "VarReplacer.h"
 #include "ClauseCleaner.h"
 
 #include <utility>
 #include <algorithm>
+#include <cstring>
+#include "time_mem.h"
+#include <iomanip>
 using std::make_pair;
 
 //#define VERBOSE_DEBUG
@@ -32,13 +34,13 @@ using std::cout;
 using std::endl;
 #endif
 
-
 namespace MINISAT
 {
 using namespace MINISAT;
 
-Conglomerate::Conglomerate(Solver *_s) :
-    S(_s)
+Conglomerate::Conglomerate(Solver& _solver) :
+    found(0)
+    , solver(_solver)
 {}
 
 Conglomerate::~Conglomerate()
@@ -47,47 +49,39 @@ Conglomerate::~Conglomerate()
         free(calcAtFinish[i]);
 }
 
-const vector<bool>& Conglomerate::getRemovedVars() const
-{
-    return removedVars;
-}
-
-const vec<XorClause*>& Conglomerate::getCalcAtFinish() const
-{
-    return calcAtFinish;
-}
-
-vec<XorClause*>& Conglomerate::getCalcAtFinish()
+void Conglomerate::blockVars()
 {
-    return calcAtFinish;
-}
-
-void Conglomerate::fillVarToXor()
-{
-    blocked.clear();
-    varToXor.clear();
-    
-    blocked.resize(S->nVars(), false);
-    for (Clause *const*it = S->clauses.getData(), *const*end = it + S->clauses.size(); it != end; it++) {
+    for (Clause *const*it = solver.clauses.getData(), *const*end = it + solver.clauses.size(); it != end; it++) {
         const Clause& c = **it;
         for (const Lit* a = &c[0], *end = a + c.size(); a != end; a++) {
             blocked[a->var()] = true;
         }
     }
     
-    for (Lit* it = &(S->trail[0]), *end = it + S->trail.size(); it != end; it++)
+    for (Clause *const*it = solver.binaryClauses.getData(), *const*end = it + solver.binaryClauses.size(); it != end; it++) {
+        const Clause& c = **it;
+        blocked[c[0].var()] = true;
+        blocked[c[1].var()] = true;
+    }
+    
+    for (Lit* it = &(solver.trail[0]), *end = it + solver.trail.size(); it != end; it++)
         blocked[it->var()] = true;
     
-    const vec<Clause*>& clauses = S->varReplacer->getClauses();
+    const vec<Clause*>& clauses = solver.varReplacer->getClauses();
     for (Clause *const*it = clauses.getData(), *const*end = it + clauses.size(); it != end; it++) {
         const Clause& c = **it;
         for (const Lit* a = &c[0], *end = a + c.size(); a != end; a++) {
             blocked[a->var()] = true;
         }
     }
+}
+
+void Conglomerate::fillVarToXor()
+{
+    varToXor.clear();
     
     uint i = 0;
-    for (XorClause* const* it = S->xorclauses.getData(), *const*end = it + S->xorclauses.size(); it != end; it++, i++) {
+    for (XorClause* const* it = solver.xorclauses.getData(), *const*end = it + solver.xorclauses.size(); it != end; it++, i++) {
         const XorClause& c = **it;
         for (const Lit * a = &c[0], *end = a + c.size(); a != end; a++) {
             if (!blocked[a->var()])
@@ -96,42 +90,172 @@ void Conglomerate::fillVarToXor()
     }
 }
 
-void Conglomerate::process_clause(XorClause& x, const uint num, Var remove_var, vec<Lit>& vars) {
+void Conglomerate::removeVar(const Var var)
+{
+    solver.setDecisionVar(var, false);
+    solver.activity[var] = 0.0;
+    solver.order_heap.update(var);
+    removedVars[var] = true;
+    found++;
+}
+
+void Conglomerate::processClause(XorClause& x, uint32_t num, Var remove_var)
+{
     for (const Lit* a = &x[0], *end = a + x.size(); a != end; a++) {
         Var var = a->var();
         if (var != remove_var) {
-            vars.push(Lit(var, false));
             varToXorMap::iterator finder = varToXor.find(var);
             if (finder != varToXor.end()) {
-                vector<pair<XorClause*, uint> >::iterator it =
-                    std::find(finder->second.begin(), finder->second.end(), make_pair(&x, num));
+                vector<pair<XorClause*, uint32_t> >::iterator it =
+                std::find(finder->second.begin(), finder->second.end(), make_pair(&x, num));
                 finder->second.erase(it);
             }
         }
     }
 }
 
-uint Conglomerate::conglomerateXors()
+const bool Conglomerate::heuleProcessFull()
 {
-    if (S->xorclauses.size() == 0)
-        return 0;
+    #ifdef VERBOSE_DEBUG
+    cout << "Heule XOR-ing started" << endl;
+    #endif
+    
+    double time = cpuTime();
+    found = 0;
+    uint oldToReplaceVars = solver.varReplacer->getNewToReplaceVars();
+    solver.clauseCleaner->cleanClauses(solver.xorclauses, ClauseCleaner::xorclauses);
+    if (solver.ok == false)
+        return false;
+    
+    toRemove.clear();
+    toRemove.resize(solver.xorclauses.size(), false);
+    blocked.clear();
+    blocked.resize(solver.nVars(), false);
+    fillVarToXor();
+    if (!heuleProcess())
+        goto end;
+    
+    if (solver.verbosity >=1) {
+        std::cout << "c |  Heule-processings XORs:" << std::setw(8) << std::setprecision(2) << std::fixed << cpuTime()-time
+        << "  Found smaller XOR-s: " << std::setw(6) << found
+        << "  New bin anti/eq-s: " << std::setw(3) << solver.varReplacer->getNewToReplaceVars() - oldToReplaceVars
+        << std::setw(0) << " |" << std::endl;
+    }
+
+end:
+    
+    clearToRemove();
     
+    return solver.ok;
+}
+
+const bool Conglomerate::conglomerateXorsFull()
+{
     #ifdef VERBOSE_DEBUG
     cout << "Finding conglomerate xors started" << endl;
     #endif
     
-    S->clauseCleaner->cleanClauses(S->xorclauses, ClauseCleaner::xorclauses);
+    double time = cpuTime();
+    found = 0;
+    uint32_t origNumClauses = solver.xorclauses.size();
     
-    toRemove.clear();
-    toRemove.resize(S->xorclauses.size(), false);
+    solver.clauseCleaner->cleanClauses(solver.xorclauses, ClauseCleaner::xorclauses);
+    if (solver.ok == false)
+        return false;
     
+    toRemove.clear();
+    toRemove.resize(solver.xorclauses.size(), false);
+    blocked.clear();
+    blocked.resize(solver.nVars(), false);
+    blockVars();
     fillVarToXor();
+    if (conglomerateXors() == false)
+        goto end;
+    
+end:
+    
+    clearToRemove();
+    assert(origNumClauses >= solver.xorclauses.size());
+    if (solver.verbosity >=1) {
+        std::cout << "c |  Conglomerating XORs:" << std::setw(8) << std::setprecision(2) << std::fixed << cpuTime()-time << " s   "
+        << "   removed " << std::setw(8) << found << " vars"
+        << "   removed " << std::setw(8) << origNumClauses-solver.xorclauses.size() << " clauses"
+        << std::setw(0) << " |" << std::endl;
+    }
+    
+    clearLearntsFromToRemove();
+    solver.order_heap.filter(Solver::VarFilter(solver));
+    
+    return solver.ok;
+}
+
+void Conglomerate::fillNewSet(vector<vector<Lit> >& newSet, vector<pair<XorClause*, uint32_t> >& clauseSet) const
+{
+    newSet.clear();
+    newSet.resize(clauseSet.size());
     
-    uint found = 0;
+    XorClause& firstXorClause = *(clauseSet[0].first);
+    newSet[0].resize(firstXorClause.size());
+    memcpy(&newSet[0][0], firstXorClause.getData(), sizeof(Lit)*firstXorClause.size());
+    
+    for (uint i = 1; i < clauseSet.size(); i++) {
+        XorClause& thisXorClause = *clauseSet[i].first;
+        newSet[i] = newSet[0];
+        newSet[i].resize(firstXorClause.size()+thisXorClause.size());
+        memcpy(&newSet[i][firstXorClause.size()], thisXorClause.getData(), sizeof(Lit)*thisXorClause.size());
+        clearDouble(newSet[i]);
+    }
+}
+
+const bool Conglomerate::heuleProcess()
+{
+    vector<vector<Lit> > newSet;
+    while(varToXor.begin() != varToXor.end()) {
+        varToXorMap::iterator it = varToXor.begin();
+        vector<pair<XorClause*, uint32_t> >& clauseSet = it->second;
+        const Var var = it->first;
+        
+        if (blocked[var] || clauseSet.size() == 1) {
+            varToXor.erase(it);
+            blocked[var] = true;
+            continue;
+        }
+        blocked[var] = true;
+        
+        std::sort(clauseSet.begin(), clauseSet.end(), ClauseSetSorter());
+        fillNewSet(newSet, clauseSet);
+        
+        for (uint i = 1; i < newSet.size(); i++) if (newSet[i].size() <= 2) {
+            found++;
+            XorClause& thisXorClause = *clauseSet[i].first;
+            const bool inverted = !clauseSet[0].first->xor_clause_inverted() ^ thisXorClause.xor_clause_inverted();
+            const uint old_group = thisXorClause.getGroup();
+
+            #ifdef VERBOSE_DEBUG
+            cout << "- XOR1:";
+            clauseSet[0].first->plainPrint();
+            cout << "- XOR2:";
+            thisXorClause.plainPrint();
+            #endif
+            
+            if (!dealWithNewClause(newSet[i], inverted, old_group))
+                return false;
+            assert(newSet.size() == clauseSet.size());
+        }
+        
+        varToXor.erase(it);
+    }
+    
+    return (solver.ok = (solver.propagate() == NULL));
+}
+
+const bool Conglomerate::conglomerateXors()
+{
+    vector<vector<Lit> > newSet;
     while(varToXor.begin() != varToXor.end()) {
         varToXorMap::iterator it = varToXor.begin();
-        const vector<pair<XorClause*, uint> >& c = it->second;
-        const uint& var = it->first;
+        vector<pair<XorClause*, uint32_t> >& clauseSet = it->second;
+        const Var var = it->first;
         
         //We blocked the var during dealWithNewClause (it was in a 2-long xor-clause)
         if (blocked[var]) {
@@ -139,73 +263,68 @@ uint Conglomerate::conglomerateXors()
             continue;
         }
         
-        S->setDecisionVar(var, false);
-        removedVars[var] = true;
-        
-        if (c.size() == 0) {
+        if (clauseSet.size() == 0) {
+            removeVar(var);
             varToXor.erase(it);
             continue;
         }
         
-        #ifdef VERBOSE_DEBUG
-        cout << "--- New conglomerate set ---" << endl;
-        #endif
+        std::sort(clauseSet.begin(), clauseSet.end(), ClauseSetSorter());
+        fillNewSet(newSet, clauseSet);
+        
+        int diff = 0;
+        for (size_t i = 1; i < newSet.size(); i++)
+            diff += (int)newSet[i].size()-(int)clauseSet[i].first->size();
+        
+        if (newSet.size() > 2) {
+            blocked[var] = true;
+            varToXor.erase(it);
+            continue;
+        }
         
-        XorClause& x = *(c[0].first);
-        bool first_inverted = !x.xor_clause_inverted();
-        vec<Lit> first_vars;
-        process_clause(x, c[0].second, var, first_vars);
+        XorClause& firstXorClause = *(clauseSet[0].first);
+        bool first_inverted = !firstXorClause.xor_clause_inverted();
+        removeVar(var);
         
         #ifdef VERBOSE_DEBUG
+        cout << "--- New conglomerate set ---" << endl;
         cout << "- Removing: ";
-        x.plainPrint();
+        firstXorClause.plainPrint();
         cout << "Adding var " << var+1 << " to calcAtFinish" << endl;
         #endif
         
-        assert(!toRemove[c[0].second]);
-        toRemove[c[0].second] = true;
-        S->detachClause(x);
-        calcAtFinish.push(&x);
-        found++;
+        assert(!toRemove[clauseSet[0].second]);
+        toRemove[clauseSet[0].second] = true;
+        processClause(firstXorClause, clauseSet[0].second, var);
+        solver.detachClause(firstXorClause);
+        calcAtFinish.push(&firstXorClause);
         
-        for (uint i = 1; i < c.size(); i++) {
-            vec<Lit> ps(first_vars.size());
-            memcpy(ps.getData(), first_vars.getData(), sizeof(Lit)*first_vars.size());
-            XorClause& x = *c[i].first;
-            process_clause(x, c[i].second, var, ps);
-            
+        for (uint i = 1; i < clauseSet.size(); i++) {
+            XorClause& thisXorClause = *clauseSet[i].first;
             #ifdef VERBOSE_DEBUG
             cout << "- Removing: ";
-            x.plainPrint();
+            thisXorClause.plainPrint();
             #endif
             
-            const uint old_group = x.group;
-            bool inverted = first_inverted ^ x.xor_clause_inverted();
-            assert(!toRemove[c[i].second]);
-            toRemove[c[i].second] = true;
-            S->removeClause(x);
-            found++;
-            clearDouble(ps);
+            const uint old_group = thisXorClause.getGroup();
+            const bool inverted = first_inverted ^ thisXorClause.xor_clause_inverted();
+            assert(!toRemove[clauseSet[i].second]);
+            toRemove[clauseSet[i].second] = true;
+            processClause(thisXorClause, clauseSet[i].second, var);
+            solver.removeClause(thisXorClause);
             
-            if (!dealWithNewClause(ps, inverted, old_group)) {
-                clearToRemove();
-                S->ok = false;
-                return found;
-            }
+            if (!dealWithNewClause(newSet[i], inverted, old_group))
+                return false;
+            assert(newSet.size() == clauseSet.size());
         }
         
         varToXor.erase(it);
     }
     
-    clearToRemove();
-    
-    if (S->ok != false)
-        S->ok = (S->propagate() == NULL);
-    
-    return found;
+    return (solver.ok = (solver.propagate() == NULL));
 }
 
-bool Conglomerate::dealWithNewClause(vec<Lit>& ps, const bool inverted, const uint old_group)
+bool Conglomerate::dealWithNewClause(vector<Lit>& ps, const bool inverted, const uint old_group)
 {
     switch(ps.size()) {
         case 0: {
@@ -213,8 +332,10 @@ bool Conglomerate::dealWithNewClause(vec<Lit>& ps, const bool inverted, const ui
             cout << "--> xor is 0-long" << endl;
             #endif
             
-            if  (!inverted)
+            if  (!inverted) {
+                solver.ok = false;
                 return false;
+            }
             break;
         }
         case 1: {
@@ -222,28 +343,37 @@ bool Conglomerate::dealWithNewClause(vec<Lit>& ps, const bool inverted, const ui
             cout << "--> xor is 1-long, attempting to set variable " << ps[0].var()+1 << endl;
             #endif
             
-            if (S->assigns[ps[0].var()] == l_Undef) {
-                assert(S->decisionLevel() == 0);
+            if (solver.assigns[ps[0].var()] == l_Undef) {
+                assert(solver.decisionLevel() == 0);
                 blocked[ps[0].var()] = true;
-                S->uncheckedEnqueue(Lit(ps[0].var(), inverted));
-            } else if (S->assigns[ps[0].var()] != boolToLBool(!inverted)) {
+                solver.uncheckedEnqueue(Lit(ps[0].var(), inverted));
+            } else if (solver.assigns[ps[0].var()] != boolToLBool(!inverted)) {
                 #ifdef VERBOSE_DEBUG
                 cout << "Conflict. Aborting.";
                 #endif
+                solver.ok = false;
                 return false;
+            } else {
+                #ifdef VERBOSE_DEBUG
+                cout << "Variable already set to correct value";
+                #endif
             }
             break;
         }
         
         case 2: {
             #ifdef VERBOSE_DEBUG
-            cout << "--> xor is 2-long, must later replace variable, adding var " << ps[0].var() + 1 << " to calcAtFinish:" << endl;
+            cout << "--> xor is 2-long, must later replace variable" << endl;
             XorClause* newX = XorClause_new(ps, inverted, old_group);
             newX->plainPrint();
             free(newX);
             #endif
             
-            S->varReplacer->replace(ps, inverted, old_group);
+            vec<Lit> tmpPS(2);
+            tmpPS[0] = ps[0];
+            tmpPS[1] = ps[1];
+            if (solver.varReplacer->replace(tmpPS, inverted, old_group) == false)
+                return false;
             blocked[ps[0].var()] = true;
             blocked[ps[1].var()] = true;
             break;
@@ -257,12 +387,12 @@ bool Conglomerate::dealWithNewClause(vec<Lit>& ps, const bool inverted, const ui
             newX->plainPrint();
             #endif
             
-            S->xorclauses.push(newX);
+            solver.xorclauses.push(newX);
             toRemove.push_back(false);
-            S->attachClause(*newX);
+            solver.attachClause(*newX);
             for (const Lit * a = &((*newX)[0]), *end = a + newX->size(); a != end; a++) {
                 if (!blocked[a->var()])
-                    varToXor[a->var()].push_back(make_pair(newX, toRemove.size()-1));
+                    varToXor[a->var()].push_back(make_pair(newX, (uint32_t)(toRemove.size()-1)));
             }
             break;
         }
@@ -271,51 +401,49 @@ bool Conglomerate::dealWithNewClause(vec<Lit>& ps, const bool inverted, const ui
     return true;
 }
 
-void Conglomerate::clearDouble(vec<Lit>& ps) const
-{
-    std::sort(ps.getData(), ps.getData() + ps.size());
+void Conglomerate::clearDouble(vector<Lit>& ps) const
+{    
+    std::sort(ps.begin(), ps.end());
     Lit p;
-    uint i, j;
-    for (i = j = 0, p = lit_Undef; i < ps.size(); i++) {
+    uint32_t i, j;
+    for (i = j = 0, p = lit_Undef; i != ps.size(); i++) {
+        ps[i] = ps[i].unsign();
         if (ps[i] == p) {
             //added, but easily removed
             j--;
             p = lit_Undef;
-        } else //just add
+        } else
             ps[j++] = p = ps[i];
     }
-    ps.shrink(i - j);
+    ps.resize(ps.size() - (i - j));
 }
 
 void Conglomerate::clearToRemove()
 {
-    assert(toRemove.size() == S->xorclauses.size());
+    assert(toRemove.size() == solver.xorclauses.size());
     
-    XorClause **a = S->xorclauses.getData();
+    XorClause **a = solver.xorclauses.getData();
     XorClause **r = a;
-    XorClause **end = a + S->xorclauses.size();
+    XorClause **end = a + solver.xorclauses.size();
     for (uint i = 0; r != end; i++) {
         if (!toRemove[i])
             *a++ = *r++;
         else {
-            (**a).mark(1);
             r++;
         }
     }
-    S->xorclauses.shrink(r-a);
-    
-    clearLearntsFromToRemove();
+    solver.xorclauses.shrink(r-a);
 }
 
 void Conglomerate::clearLearntsFromToRemove()
 {
-    Clause **a = S->learnts.getData();
+    Clause **a = solver.learnts.getData();
     Clause **r = a;
-    Clause **end = a + S->learnts.size();
+    Clause **end = a + solver.learnts.size();
     for (; r != end;) {
         const Clause& c = **r;
         bool inside = false;
-        if (!S->locked(c)) {
+        if (!solver.locked(c)) {
             for (uint i = 0; i < c.size(); i++) {
                 if (removedVars[c[i].var()]) {
                     inside = true;
@@ -326,11 +454,11 @@ void Conglomerate::clearLearntsFromToRemove()
         if (!inside)
             *a++ = *r++;
         else {
-            S->removeClause(**r);
+            solver.removeClause(**r);
             r++;
         }
     }
-    S->learnts.shrink(r-a);
+    solver.learnts.shrink(r-a);
 }
 
 void Conglomerate::doCalcAtFinish()
@@ -352,7 +480,7 @@ void Conglomerate::doCalcAtFinish()
         
         bool final = c.xor_clause_inverted();
         for (int k = 0, size = c.size(); k < size; k++ ) {
-            const lbool& val = S->assigns[c[k].var()];
+            const lbool& val = solver.assigns[c[k].var()];
             if (val == l_Undef)
                 toAssign.push_back(c[k].var());
             else
@@ -362,7 +490,7 @@ void Conglomerate::doCalcAtFinish()
         if (toAssign.size() == 0) {
             cout << "ERROR: toAssign.size() == 0 !!" << endl;
             for (int k = 0, size = c.size(); k < size; k++ ) {
-                cout << "Var: " << c[k].var() + 1 << " Level: " << S->level[c[k].var()] << endl;
+                cout << "Var: " << c[k].var() + 1 << " Level: " << solver.level[c[k].var()] << endl;
             }
         }
         if (toAssign.size() > 1) {
@@ -375,14 +503,14 @@ void Conglomerate::doCalcAtFinish()
         assert(toAssign.size() > 0);
         
         for (uint i = 1; i < toAssign.size(); i++) {
-            S->uncheckedEnqueue(Lit(toAssign[i], true), &c);
+            solver.uncheckedEnqueue(Lit(toAssign[i], true), &c);
         }
-        S->uncheckedEnqueue(Lit(toAssign[0], final), &c);
-        assert(S->clauseCleaner->satisfied(c));
+        solver.uncheckedEnqueue(Lit(toAssign[0], final), &c);
+        assert(solver.clauseCleaner->satisfied(c));
     }
 }
 
-void Conglomerate::addRemovedClauses()
+const bool Conglomerate::addRemovedClauses()
 {
     #ifdef VERBOSE_DEBUG
     cout << "Executing addRemovedClauses" << endl;
@@ -403,16 +531,22 @@ void Conglomerate::addRemovedClauses()
         for(uint i2 = 0; i2 != c.size() ; i2++) {
             ps.push(Lit(c[i2].var(), false));
         }
-        S->addXorClause(ps, c.xor_clause_inverted(), c.group, tmp, true);
+        if (!solver.addXorClause(ps, c.xor_clause_inverted(), c.getGroup(), tmp))
+            return false;
         free(&c);
     }
     calcAtFinish.clear();
     for (uint i = 0; i < removedVars.size(); i++) {
         if (removedVars[i]) {
             removedVars[i] = false;
-            S->setDecisionVar(i, true);
+            solver.setDecisionVar(i, true);
+            #ifdef VERBOSE_DEBUG
+            std::cout << "Inserting Var " << i+1 << " back into the order_heap" << std::endl;
+            #endif //VERBOSE_DEBUG
         }
     }
+    
+    return true;
 }
 
 void Conglomerate::newVar()
@@ -420,4 +554,4 @@ void Conglomerate::newVar()
     removedVars.resize(removedVars.size()+1, false);
 }
 
-};
+}; //NAMESPACE MINISAT
index 6fe755666fda7290c6a4a5e60c76fbe3b4991bf0..15fcb0bbb3f72c5ad5c54a2a22e3dd26220d59e3 100644 (file)
@@ -21,52 +21,92 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #include <vector>
 #include <map>
 #include <set>
+#ifdef _MSC_VER
+#include <msvc/stdint.h>
+#else
+#include <stdint.h>
+#endif //_MSC_VER
+
 #include "Clause.h"
 #include "VarReplacer.h"
+#include "Solver.h"
 
 using std::vector;
 using std::pair;
 using std::map;
 using std::set;
 
-class Solver;
-
 namespace MINISAT
 {
 using namespace MINISAT;
 
+class Solver;
+
 class Conglomerate
 {
 public:
-    Conglomerate(Solver *S);
+    Conglomerate(Solver& solver);
     ~Conglomerate();
-    uint conglomerateXors(); ///<Conglomerate XOR-s that are attached using a variable
-    void addRemovedClauses(); ///<Add clauses that have been removed. Used if solve() is called multiple times
+    const bool conglomerateXorsFull();
+    const bool heuleProcessFull();
+    const bool addRemovedClauses(); ///<Add clauses that have been removed. Used if solve() is called multiple times
     void doCalcAtFinish(); ///<Calculate variables removed during conglomeration
+    
     const vec<XorClause*>& getCalcAtFinish() const;
     vec<XorClause*>& getCalcAtFinish();
     const vector<bool>& getRemovedVars() const;
+    
     void newVar();
     
 private:
     
-    void process_clause(XorClause& x, const uint num, Var remove_var, vec<Lit>& vars);
+    struct ClauseSetSorter {
+        bool operator () (const pair<XorClause*, uint32_t>& a, const pair<XorClause*, uint32_t>& b) {
+            return a.first->size() < b.first->size();
+        }
+    };
+    
+    const bool conglomerateXors();
+    const bool heuleProcess();
+    
+    void fillNewSet(vector<vector<Lit> >& newSet, vector<pair<XorClause*, uint32_t> >& clauseSet) const;
+    
+    void removeVar(const Var var);
+    void processClause(XorClause& x, uint32_t num, Var remove_var);
+    void blockVars();
     void fillVarToXor();
-    void clearDouble(vec<Lit>& ps) const;
+    void clearDouble(vector<Lit>& ps) const;
     void clearToRemove();
     void clearLearntsFromToRemove();
-    bool dealWithNewClause(vec<Lit>& ps, const bool inverted, const uint old_group);
+    bool dealWithNewClause(vector<Lit>& ps, const bool inverted, const uint old_group);
     
-    typedef map<uint, vector<pair<XorClause*, uint> > > varToXorMap;
+    typedef map<uint, vector<pair<XorClause*, uint32_t> > > varToXorMap;
     varToXorMap varToXor; 
     vector<bool> blocked;
     vector<bool> toRemove;
     vector<bool> removedVars;
     
     vec<XorClause*> calcAtFinish;
+    uint found;
     
-    Solver* S;
-};
+    Solver& solver;
 };
 
+inline const vector<bool>& Conglomerate::getRemovedVars() const
+{
+    return removedVars;
+}
+
+inline const vec<XorClause*>& Conglomerate::getCalcAtFinish() const
+{
+    return calcAtFinish;
+}
+
+inline vec<XorClause*>& Conglomerate::getCalcAtFinish()
+{
+    return calcAtFinish;
+}
+
+}; //NAMESPACE MINISAT
+
 #endif //CONGLOMERATE_H
diff --git a/src/sat/cryptominisat2/DoublePackedRow.h b/src/sat/cryptominisat2/DoublePackedRow.h
new file mode 100644 (file)
index 0000000..50cfd8a
--- /dev/null
@@ -0,0 +1,173 @@
+/***********************************************************************************
+CryptoMiniSat -- Copyright (c) 2009 Mate Soos
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+**************************************************************************************************/
+
+#ifndef DOUBLEPACKEDROW_H
+#define DOUBLEPACKEDROW_H
+
+#ifdef _MSC_VER
+#include <msvc/stdint.h>
+#else
+#include <stdint.h>
+#endif //_MSC_VER
+
+#include <stdlib.h>
+
+#include "SolverTypes.h"
+
+namespace MINISAT
+{
+using namespace MINISAT;
+
+class DoublePackedRow
+{
+    private:
+        class BitIter {
+            public:
+                inline void operator=(const lbool toSet)
+                {
+                    val &= ~((unsigned char)3 << offset);
+                    val |= toSet.value << offset;
+                }
+                
+                inline operator lbool() const
+                {
+                    return lbool((val >> offset) & 3);
+                }
+                
+                inline const bool isUndef() const {
+                    return ((lbool)*this).isUndef();
+                }
+                inline const bool isDef() const {
+                    return ((lbool)*this).isDef();
+                }
+                inline const bool getBool() const {
+                    return ((lbool)*this).getBool();
+                }
+                inline const bool operator==(lbool b) const {
+                    return ((lbool)*this) == b;
+                }
+                inline const bool operator!=(lbool b) const {
+                    return ((lbool)*this) != b;
+                }
+                const lbool operator^(const bool b) const {
+                    return ((lbool)*this) ^ b;
+                }
+                
+            private:
+                friend class DoublePackedRow;
+                inline BitIter(unsigned char& mp, const uint32_t _offset) :
+                val(mp)
+                , offset(_offset)
+                {}
+                
+                unsigned char& val;
+                const uint32_t offset;
+        };
+        
+        class BitIterConst {
+             public:
+                inline operator lbool() const
+                {
+                    return lbool((val >> offset) & 3);
+                }
+                
+                inline const bool isUndef() const {
+                    return ((lbool)*this).isUndef();
+                }
+                inline const bool isDef() const {
+                    return ((lbool)*this).isDef();
+                }
+                inline const bool getBool() const {
+                    return ((lbool)*this).getBool();
+                }
+                inline const bool operator==(lbool b) const {
+                    return ((lbool)*this) == b;
+                }
+                inline const bool operator!=(lbool b) const {
+                    return ((lbool)*this) != b;
+                }
+                const lbool operator^(const bool b) const {
+                    return ((lbool)*this) ^ b;
+                }
+                
+                
+            private:
+                friend class DoublePackedRow;
+                inline BitIterConst(unsigned char& mp, const uint32_t _offset) :
+                val(mp)
+                , offset(_offset)
+                {}
+                
+                const unsigned char& val;
+                const uint32_t offset;
+        };
+    
+    public:
+        DoublePackedRow() :
+            numElems(0)
+            , mp(NULL)
+        {}
+        
+        uint32_t size() const
+        {
+            return numElems;
+        }
+        
+        void growTo(const uint32_t newNumElems)
+        {
+            uint32_t oldSize = numElems/4 + (bool)(numElems % 4);
+            uint32_t newSize = newNumElems/4 + (bool)(newNumElems % 4);
+            
+            if (oldSize >= newSize) {
+                numElems = std::max(newNumElems, numElems);
+                return;
+            }
+            
+            mp = (unsigned char*)realloc(mp, newSize*sizeof(unsigned char));
+            numElems = newNumElems;
+        }
+        
+        inline BitIter operator[](const uint32_t at)
+        {
+            return BitIter(mp[at/4], (at%4)*2);
+        }
+        
+        inline const BitIterConst operator[](const uint32_t at) const
+        {
+            return BitIterConst(mp[at/4], (at%4)*2);
+        }
+        
+        inline void push(const lbool val)
+        {
+            growTo(numElems+1);
+            (*this)[numElems-1] = val;
+        }
+        
+        /*void clear(const uint32_t at)
+        {
+            mp[at/32] &= ~((uint64_t)3 << ((at%32)*2));
+        }*/
+        
+    private:
+        
+        Var numElems;
+        unsigned char *mp;
+};
+
+}; //NAMESPACE MINISAT
+
+#endif //DOUBLEPACKEDROW_H
diff --git a/src/sat/cryptominisat2/FailedVarSearcher.cpp b/src/sat/cryptominisat2/FailedVarSearcher.cpp
new file mode 100644 (file)
index 0000000..7699b69
--- /dev/null
@@ -0,0 +1,395 @@
+/***********************************************************************************
+CryptoMiniSat -- Copyright (c) 2009 Mate Soos
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+**************************************************************************************************/
+
+#include "FailedVarSearcher.h"
+
+#include <iomanip>
+#include <utility>
+#include <set>
+using std::make_pair;
+using std::set;
+
+#include "Solver.h"
+#include "ClauseCleaner.h"
+#include "time_mem.h"
+#include "VarReplacer.h"
+
+//#define FINDBINARYXOR
+
+namespace MINISAT
+{
+using namespace MINISAT;
+
+FailedVarSearcher::FailedVarSearcher(Solver& _solver):
+    solver(_solver)
+    , finishedLastTime(true)
+    , lastTimeWentUntil(0)
+    , numPropsMultiplier(1.0)
+    , lastTimeFoundTruths(0)
+{
+}
+
+void FailedVarSearcher::addFromSolver(const vec< XorClause* >& cs)
+{
+    xorClauseSizes.clear();
+    xorClauseSizes.growTo(cs.size());
+    occur.resize(solver.nVars());
+    for (Var var = 0; var < solver.nVars(); var++) {
+        occur[var].clear();
+    }
+    
+    uint32_t i = 0;
+    for (XorClause * const*it = cs.getData(), * const*end = it + cs.size(); it !=  end; it++, i++) {
+        if (it+1 != end)
+            __builtin_prefetch(*(it+1), 1, 1);
+        
+        const XorClause& cl = **it;
+        xorClauseSizes[i] = cl.size();
+        for (const Lit *l = cl.getData(), *end2 = l + cl.size(); l != end2; l++) {
+            occur[l->var()].push_back(i);
+        }
+    }
+}
+
+inline void FailedVarSearcher::removeVarFromXors(const Var var)
+{
+    vector<uint32_t>& occ = occur[var];
+    if (occ.empty()) return;
+    
+    for (uint32_t *it = &occ[0], *end = it + occ.size(); it != end; it++) {
+        xorClauseSizes[*it]--;
+        if (!xorClauseTouched[*it]) {
+            xorClauseTouched.setBit(*it);
+            investigateXor.push(*it);
+        }
+    }
+}
+
+inline void FailedVarSearcher::addVarFromXors(const Var var)
+{
+    vector<uint32_t>& occ = occur[var];
+    if (occ.empty()) return;
+    
+    for (uint32_t *it = &occ[0], *end = it + occ.size(); it != end; it++) {
+        xorClauseSizes[*it]++;
+    }
+}
+
+const TwoLongXor FailedVarSearcher::getTwoLongXor(const XorClause& c)
+{
+    TwoLongXor tmp;
+    uint32_t num = 0;
+    tmp.inverted = c.xor_clause_inverted();
+    
+    for(const Lit *l = c.getData(), *end = l + c.size(); l != end; l++) {
+        if (solver.assigns[l->var()] == l_Undef) {
+            assert(num < 2);
+            tmp.var[num] = l->var();
+            num++;
+        } else {
+            tmp.inverted ^= (solver.assigns[l->var()] == l_True);
+        }
+    }
+    
+    std::sort(&tmp.var[0], &tmp.var[0]+2);
+    assert(num == 2);
+    return tmp;
+}
+
+const bool FailedVarSearcher::search(uint64_t numProps)
+{
+    assert(solver.decisionLevel() == 0);
+    
+    //Saving Solver state
+    Heap<Solver::VarOrderLt> backup_order_heap(solver.order_heap);
+    vector<bool> backup_polarities = solver.polarity;
+    vec<double> backup_activity;
+    backup_activity.growTo(solver.activity.size());
+    std::copy(solver.activity.getData(), solver.activity.getDataEnd(), backup_activity.getData());
+    double backup_var_inc = solver.var_inc;
+    uint32_t origHeapSize = solver.order_heap.size();
+    
+    //General Stats
+    double time = cpuTime();
+    uint32_t numFailed = 0;
+    uint32_t goodBothSame = 0;
+    uint32_t from;
+    if (finishedLastTime || lastTimeWentUntil >= solver.nVars())
+        from = 0;
+    else
+        from = lastTimeWentUntil;
+    uint64_t origProps = solver.propagations;
+    
+    //If failed var searching is going good, do successively more and more of it
+    if (lastTimeFoundTruths > 500 || (double)lastTimeFoundTruths > (double)solver.order_heap.size() * 0.05) std::max(numPropsMultiplier*1.7, 5.0);
+    else numPropsMultiplier = 1.0;
+    numProps = (uint64_t) ((double)numProps * numPropsMultiplier);
+    
+    //For failure
+    bool failed;
+    
+    //For BothSame
+    BitArray propagated;
+    propagated.resize(solver.nVars());
+    BitArray propValue;
+    propValue.resize(solver.nVars());
+    vector<pair<Var, bool> > bothSame;
+    
+    //For 2-long xor (rule 6 of  Equivalent literal propagation in the DLL procedure by Chu-Min Li)
+    set<TwoLongXor> twoLongXors;
+    uint32_t toReplaceBefore = solver.varReplacer->getNewToReplaceVars();
+    uint32_t lastTrailSize = solver.trail.size();
+    bool binXorFind = true;
+    if (solver.xorclauses.size() < 5 ||
+        solver.xorclauses.size() > 30000 ||
+        solver.order_heap.size() > 30000 ||
+        solver.nClauses() > 100000)
+        binXorFind = false;
+    if (binXorFind) addFromSolver(solver.xorclauses);
+    xorClauseTouched.resize(solver.xorclauses.size());
+    
+    finishedLastTime = true;
+    lastTimeWentUntil = solver.nVars();
+    for (Var var = from; var < solver.nVars(); var++) {
+        if (solver.assigns[var] == l_Undef && solver.order_heap.inHeap(var)) {
+            if ((int)solver.propagations - (int)origProps >= (int)numProps)  {
+                finishedLastTime = false;
+                lastTimeWentUntil = var;
+                break;
+            }
+            
+            if (binXorFind) {
+                if (lastTrailSize < solver.trail.size()) {
+                    for (uint32_t i = lastTrailSize; i != solver.trail.size(); i++) {
+                        removeVarFromXors(solver.trail[i].var());
+                    }
+                }
+                lastTrailSize = solver.trail.size();
+                xorClauseTouched.setZero();
+                investigateXor.clear();
+            }
+            
+            propagated.setZero();
+            twoLongXors.clear();
+            
+            solver.newDecisionLevel();
+            solver.uncheckedEnqueue(Lit(var, false));
+            failed = (solver.propagate(false) != NULL);
+            if (failed) {
+                solver.cancelUntil(0);
+                numFailed++;
+                solver.uncheckedEnqueue(Lit(var, true));
+                solver.ok = (solver.propagate(false) == NULL);
+                if (!solver.ok) goto end;
+                continue;
+            } else {
+                assert(solver.decisionLevel() > 0);
+                for (int c = solver.trail.size()-1; c >= (int)solver.trail_lim[0]; c--) {
+                    Var x = solver.trail[c].var();
+                    propagated.setBit(x);
+                    if (solver.assigns[x].getBool())
+                        propValue.setBit(x);
+                    else
+                        propValue.clearBit(x);
+                    
+                    if (binXorFind) removeVarFromXors(x);
+                }
+                
+                if (binXorFind) {
+                    for (uint32_t *it = investigateXor.getData(), *end = it + investigateXor.size(); it != end; it++) {
+                        if (xorClauseSizes[*it] == 2)
+                            twoLongXors.insert(getTwoLongXor(*solver.xorclauses[*it]));
+                    }
+                    for (int c = solver.trail.size()-1; c >= (int)solver.trail_lim[0]; c--) {
+                        addVarFromXors(solver.trail[c].var());
+                    }
+                    xorClauseTouched.setZero();
+                    investigateXor.clear();
+                }
+                
+                solver.cancelUntil(0);
+            }
+            
+            solver.newDecisionLevel();
+            solver.uncheckedEnqueue(Lit(var, true));
+            failed = (solver.propagate(false) != NULL);
+            if (failed) {
+                solver.cancelUntil(0);
+                numFailed++;
+                solver.uncheckedEnqueue(Lit(var, false));
+                solver.ok = (solver.propagate(false) == NULL);
+                if (!solver.ok) goto end;
+                continue;
+            } else {
+                assert(solver.decisionLevel() > 0);
+                for (int c = solver.trail.size()-1; c >= (int)solver.trail_lim[0]; c--) {
+                    Var     x  = solver.trail[c].var();
+                    if (propagated[x] && propValue[x] == solver.assigns[x].getBool())
+                        bothSame.push_back(make_pair(x, !propValue[x]));
+                    if (binXorFind) removeVarFromXors(x);
+                }
+                
+                if (binXorFind) {
+                    if (twoLongXors.size() > 0) {
+                        for (uint32_t *it = investigateXor.getData(), *end = it + investigateXor.size(); it != end; it++) {
+                            if (xorClauseSizes[*it] == 2) {
+                                TwoLongXor tmp = getTwoLongXor(*solver.xorclauses[*it]);
+                                if (twoLongXors.find(tmp) != twoLongXors.end()) {
+                                    vec<Lit> ps(2);
+                                    ps[0] = Lit(tmp.var[0], false);
+                                    ps[1] = Lit(tmp.var[1], false);
+                                    if (!solver.varReplacer->replace(ps, tmp.inverted, 0))
+                                        goto end;
+                                }
+                            }
+                        }
+                    }
+                    for (int c = solver.trail.size()-1; c >= (int)solver.trail_lim[0]; c--) {
+                        addVarFromXors(solver.trail[c].var());
+                    }
+                }
+                
+                solver.cancelUntil(0);
+            }
+            
+            for(uint32_t i = 0; i != bothSame.size(); i++) {
+                solver.uncheckedEnqueue(Lit(bothSame[i].first, bothSame[i].second));
+            }
+            goodBothSame += bothSame.size();
+            bothSame.clear();
+            solver.ok = (solver.propagate(false) == NULL);
+            if (!solver.ok) goto end;
+        }
+    }
+
+end:
+    //Restoring Solver state
+    if (solver.verbosity >= 1) {
+        std::cout << "c |  Failvars: "<< std::setw(5) << numFailed <<
+        "     Bprop vars: " << std::setw(6) << goodBothSame <<
+        " Replaced: " << std::setw(3) << (solver.varReplacer->getNewToReplaceVars() - toReplaceBefore) <<
+        " Props: " << std::setw(8) << std::setprecision(2) << (int)solver.propagations - (int)origProps  <<
+        " Time: " << std::setw(6) << std::fixed << std::setprecision(2) << cpuTime() - time <<
+        std::setw(5) << " |" << std::endl;
+    }
+    
+    solver.order_heap.filter(Solver::VarFilter(solver));
+    
+    if (solver.ok && (numFailed || goodBothSame)) {
+        double time = cpuTime();
+        if ((int)origHeapSize - (int)solver.order_heap.size() >  origHeapSize/15 && solver.nClauses() + solver.learnts.size() > 500000) {
+            solver.clauses_literals = 0;
+            solver.learnts_literals = 0;
+            for (uint32_t i = 0; i < solver.nVars(); i++) {
+                solver.binwatches[i*2].clear();
+                solver.binwatches[i*2+1].clear();
+                solver.watches[i*2].clear();
+                solver.watches[i*2+1].clear();
+                solver.xorwatches[i].clear();
+            }
+            solver.varReplacer->reattachInternalClauses();
+            cleanAndAttachClauses(solver.binaryClauses);
+            cleanAndAttachClauses(solver.clauses);
+            cleanAndAttachClauses(solver.learnts);
+            cleanAndAttachClauses(solver.xorclauses);
+        } else {
+            solver.clauseCleaner->removeAndCleanAll();
+        }
+        if (solver.verbosity >= 1 && numFailed + goodBothSame > 100) {
+            std::cout << "c |  Cleaning up after failed var search: " << std::setw(8) << std::fixed << std::setprecision(2) << cpuTime() - time << " s "
+            <<  std::setw(33) << " | " << std::endl;
+        }
+    }
+    
+    lastTimeFoundTruths = goodBothSame + numFailed;
+    
+    solver.var_inc = backup_var_inc;
+    std::copy(backup_activity.getData(), backup_activity.getDataEnd(), solver.activity.getData());
+    solver.order_heap = backup_order_heap;
+    solver.polarity = backup_polarities;
+    solver.order_heap.filter(Solver::VarFilter(solver));
+    
+    return solver.ok;
+}
+
+template<class T>
+inline void FailedVarSearcher::cleanAndAttachClauses(vec<T*>& cs)
+{
+    T **i = cs.getData();
+    T **j = i;
+    for (T **end = cs.getDataEnd(); i != end; i++) {
+        if (cleanClause(**i)) {
+            solver.attachClause(**i);
+            *j++ = *i;
+        } else {
+            free(*i);
+        }
+    }
+    cs.shrink(i-j);
+}
+
+inline const bool FailedVarSearcher::cleanClause(Clause& ps)
+{
+    uint32_t origSize = ps.size();
+    
+    Lit *i = ps.getData();
+    Lit *j = i;
+    for (Lit *end = ps.getDataEnd(); i != end; i++) {
+        if (solver.value(*i) == l_True) return false;
+        if (solver.value(*i) == l_Undef) {
+            *j++ = *i;
+        }
+    }
+    ps.shrink(i-j);
+    assert(ps.size() > 1);
+    
+    if (ps.size() != origSize) ps.setStrenghtened();
+    if (origSize != 2 && ps.size() == 2)
+        solver.becameBinary++;
+    
+    return true;
+}
+
+inline const bool FailedVarSearcher::cleanClause(XorClause& ps)
+{
+    uint32_t origSize = ps.size();
+    
+    Lit *i = ps.getData(), *j = i;
+    for (Lit *end = ps.getDataEnd(); i != end; i++) {
+        if (solver.assigns[i->var()] == l_True) ps.invert(true);
+        if (solver.assigns[i->var()] == l_Undef) {
+            *j++ = *i;
+        }
+    }
+    ps.shrink(i-j);
+    
+    if (ps.size() == 0) return false;
+    assert(ps.size() > 1);
+    
+    if (ps.size() != origSize) ps.setStrenghtened();
+    if (ps.size() == 2) {
+        vec<Lit> tmp(2);
+        tmp[0] = ps[0].unsign();
+        tmp[1] = ps[1].unsign();
+        solver.varReplacer->replace(tmp, ps.xor_clause_inverted(), ps.getGroup());
+        return false;
+    }
+    
+    return true;
+}
+
+}; //NAMESPACE MINISAT
diff --git a/src/sat/cryptominisat2/FailedVarSearcher.h b/src/sat/cryptominisat2/FailedVarSearcher.h
new file mode 100644 (file)
index 0000000..79ed82e
--- /dev/null
@@ -0,0 +1,90 @@
+/***********************************************************************************
+CryptoMiniSat -- Copyright (c) 2009 Mate Soos
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+**************************************************************************************************/
+
+#ifndef FAILEDVARSEARCHER_H
+#define FAILEDVARSEARCHER_H
+
+#include "SolverTypes.h"
+#include "Clause.h"
+#include "BitArray.h"
+
+namespace MINISAT
+{
+using namespace MINISAT;
+
+class Solver;
+
+class TwoLongXor
+{
+    public:
+        const bool operator==(const TwoLongXor& other) const
+        {
+            if (var[0] == other.var[0] && var[1] == other.var[1] && inverted == other.inverted)
+                return true;
+            return false;
+        }
+        const bool operator<(const TwoLongXor& other) const
+        {
+            if (var[0] < other.var[0]) return true;
+            if (var[0] > other.var[0]) return false;
+            
+            if (var[1] < other.var[1]) return true;
+            if (var[1] > other.var[1]) return false;
+            
+            if (inverted < other.inverted) return true;
+            if (inverted > other.inverted) return false;
+            
+            return false;
+        }
+        
+        Var var[2];
+        bool inverted;
+};
+
+class FailedVarSearcher {
+    public:
+        FailedVarSearcher(Solver& _solver);
+    
+        const bool search(uint64_t numProps);
+        
+    private:
+        const TwoLongXor getTwoLongXor(const XorClause& c);
+        void addFromSolver(const vec<XorClause*>& cs);
+        
+        template<class T>
+        void cleanAndAttachClauses(vec<T*>& cs);
+        const bool cleanClause(Clause& ps);
+        const bool cleanClause(XorClause& ps);
+        
+        Solver& solver;
+        
+        vec<uint32_t> xorClauseSizes;
+        vector<vector<uint32_t> > occur;
+        void removeVarFromXors(const Var var);
+        void addVarFromXors(const Var var);
+        BitArray xorClauseTouched;
+        vec<uint32_t> investigateXor;
+        
+        bool finishedLastTime;
+        uint32_t lastTimeWentUntil;
+        double numPropsMultiplier;
+        uint32_t lastTimeFoundTruths;
+};
+
+}; //NAMESPACE MINISAT
+
+#endif //FAILEDVARSEARCHER_H
\ No newline at end of file
index 8710ee3ace684c4693c9605bd430890ad06b12bb..4e35dc1cf9ce4ad8749973c2e5e1783e1da9bdba 100644 (file)
@@ -18,49 +18,49 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #include "FindUndef.h"
 
 #include "Solver.h"
+#include "VarReplacer.h"
 #include <algorithm>
 
 namespace MINISAT
 {
+using namespace MINISAT;
 
-FindUndef::FindUndef(Solver& _s) :
-    S(_s)
+FindUndef::FindUndef(Solver& _solver) :
+    solver(_solver)
     , isPotentialSum(0)
 {
-    dontLookAtClause.resize(S.clauses.size(), false);
-    isPotential.resize(S.nVars(), false);
-    fillPotential();
-    satisfies.resize(S.nVars(), 0);
 }
 
 void FindUndef::fillPotential()
 {
-    int trail = S.decisionLevel()-1;
+    int trail = solver.decisionLevel()-1;
     
     while(trail > 0) {
-        assert(trail < S.trail_lim.size());
-        uint at = S.trail_lim[trail];
+        assert(trail < solver.trail_lim.size());
+        uint at = solver.trail_lim[trail];
         
         assert(at > 0);
-        Var v = S.trail[at].var();
-        isPotential[v] = true;
-        isPotentialSum++;
+        Var v = solver.trail[at].var();
+        if (solver.assigns[v] != l_Undef) {
+            isPotential[v] = true;
+            isPotentialSum++;
+        }
         
         trail--;
     }
     
-    for (XorClause** it = S.xorclauses.getData(), **end = it + S.xorclauses.size(); it != end; it++) {
+    for (XorClause** it = solver.xorclauses.getData(), **end = it + solver.xorclauses.size(); it != end; it++) {
         XorClause& c = **it;
         for (Lit *l = c.getData(), *end = l + c.size(); l != end; l++) {
             if (isPotential[l->var()]) {
                 isPotential[l->var()] = false;
                 isPotentialSum--;
             }
-            assert(!S.value(*l).isUndef());
+            assert(!solver.value(*l).isUndef());
         }
     }
     
-    vector<Var> replacingVars = S.varReplacer->getReplacingVars();
+    vector<Var> replacingVars = solver.varReplacer->getReplacingVars();
     for (Var *it = &replacingVars[0], *end = it + replacingVars.size(); it != end; it++) {
         if (isPotential[*it]) {
             isPotential[*it] = false;
@@ -73,11 +73,35 @@ void FindUndef::unboundIsPotentials()
 {
     for (uint i = 0; i < isPotential.size(); i++)
         if (isPotential[i])
-            S.assigns[i] = l_Undef;
+            solver.assigns[i] = l_Undef;
+}
+
+void FindUndef::moveBinToNormal()
+{
+    binPosition = solver.clauses.size();
+    for (uint i = 0; i != solver.binaryClauses.size(); i++)
+        solver.clauses.push(solver.binaryClauses[i]);
+    solver.binaryClauses.clear();
+}
+
+void FindUndef::moveBinFromNormal()
+{
+    for (uint i = binPosition; i != solver.clauses.size(); i++)
+        solver.binaryClauses.push(solver.clauses[i]);
+    solver.clauses.shrink(solver.clauses.size() - binPosition);
 }
 
 const uint FindUndef::unRoll()
 {
+    if (solver.decisionLevel() == 0) return 0;
+    
+    moveBinToNormal();
+    
+    dontLookAtClause.resize(solver.clauses.size(), false);
+    isPotential.resize(solver.nVars(), false);
+    fillPotential();
+    satisfies.resize(solver.nVars(), 0);
+    
     while(!updateTables()) {
         assert(isPotentialSum > 0);
         
@@ -97,6 +121,7 @@ const uint FindUndef::unRoll()
     }
     
     unboundIsPotentials();
+    moveBinFromNormal();
     
     return isPotentialSum;
 }
@@ -106,16 +131,16 @@ bool FindUndef::updateTables()
     bool allSat = true;
     
     uint i = 0;
-    for (Clause** it = S.clauses.getData(), **end = it + S.clauses.size(); it != end; it++, i++) {
+    for (Clause** it = solver.clauses.getData(), **end = it + solver.clauses.size(); it != end; it++, i++) {
         if (dontLookAtClause[i])
             continue;
         
         Clause& c = **it;
         bool definitelyOK = false;
-        Var v;
+        Var v = var_Undef;
         uint numTrue = 0;
         for (Lit *l = c.getData(), *end = l + c.size(); l != end; l++) {
-            if (S.value(*l) == l_True) {
+            if (solver.value(*l) == l_True) {
                 if (!isPotential[l->var()]) {
                     dontLookAtClause[i] = true;
                     definitelyOK = true;
@@ -130,19 +155,22 @@ bool FindUndef::updateTables()
             continue;
         
         if (numTrue == 1) {
+            assert(v != var_Undef);
             isPotential[v] = false;
             isPotentialSum--;
             dontLookAtClause[i] = true;
             continue;
         }
         
+        //numTrue > 1
         allSat = false;
         for (Lit *l = c.getData(), *end = l + c.size(); l != end; l++) {
-            if (S.value(*l) == l_True)
+            if (solver.value(*l) == l_True)
                 satisfies[l->var()]++;
         }
     }
     
     return allSat;
 }
-};
+
+}; //NAMESPACE MINISAT
index 59835c22eb11c68ef694af8ff56ae2ec923d0703..d3612ac6ff315030cd3ac0222dda70fc123f63f9 100644 (file)
@@ -18,6 +18,11 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #ifndef FINDUNDEF_H
 #define FINDUNDEF_H
 
+#ifdef _MSC_VER
+#include <msvc/stdint.h>
+#else
+#include <stdint.h>
+#endif //_MSC_VER
 #include <vector>
 using std::vector;
 
@@ -25,15 +30,18 @@ using std::vector;
 
 namespace MINISAT
 {
+using namespace MINISAT;
 
 class FindUndef {
     public:
-        FindUndef(Solver& S);
+        FindUndef(Solver& _solver);
         const uint unRoll();
         
     private:
-        Solver& S;
+        Solver& solver;
         
+        void moveBinToNormal();
+        void moveBinFromNormal();
         bool updateTables();
         void fillPotential();
         void unboundIsPotentials();
@@ -42,9 +50,10 @@ class FindUndef {
         vector<uint32_t> satisfies;
         vector<bool> isPotential;
         uint32_t isPotentialSum;
+        uint32_t binPosition;
         
 };
-};
 
-#endif //
+}; //NAMESPACE MINISAT
 
+#endif //
\ No newline at end of file
index 3a642732d0dbf88334a55c2036d247da15cbcb6f..2b1938f6e78e0de13982680cd30481dbfbd0c97f 100644 (file)
@@ -62,7 +62,7 @@ Gaussian::Gaussian(Solver& _solver, const GaussianConfig& _config, const uint _m
 Gaussian::~Gaussian()
 {
     for (uint i = 0; i < clauses_toclear.size(); i++)
-        free(clauses_toclear[i].first);
+        clauseFree(clauses_toclear[i].first);
 }
 
 inline void Gaussian::set_matrixset_to_cur()
@@ -85,6 +85,8 @@ llbool Gaussian::full_init()
     while (do_again_gauss) {
         do_again_gauss = false;
         solver.clauseCleaner->cleanClauses(solver.xorclauses, ClauseCleaner::xorclauses);
+        if (solver.ok == false)
+            return l_False;
         init();
         Clause* confl;
         gaussian_ret g = gaussian(confl);
@@ -133,16 +135,11 @@ uint Gaussian::select_columnorder(vector<uint16_t>& var_to_col, matrixset& origM
 
     uint num_xorclauses  = 0;
     for (uint32_t i = 0; i != xorclauses.size(); i++) {
-        #ifdef DEBUG_GAUSS
-        assert(xorclauses[i]->mark() || !Solver.cpplauseCleaner->satisfied(*xorclauses[i]));
-        #endif
-        if (!xorclauses[i]->mark()) {
-            num_xorclauses++;
-            XorClause& c = *xorclauses[i];
-            for (uint i2 = 0; i2 < c.size(); i2++) {
-                assert(solver.assigns[c[i2].var()].isUndef());
-                var_to_col[c[i2].var()] = unassigned_col - 1;
-            }
+        num_xorclauses++;
+        XorClause& c = *xorclauses[i];
+        for (uint i2 = 0; i2 < c.size(); i2++) {
+            assert(solver.assigns[c[i2].var()].isUndef());
+            var_to_col[c[i2].var()] = unassigned_col - 1;
         }
     }
     
@@ -223,11 +220,9 @@ void Gaussian::fill_matrix(matrixset& origMat)
     for (uint32_t i = 0; i != xorclauses.size(); i++) {
         const XorClause& c = *xorclauses[i];
 
-        if (!c.mark()) {
-            origMat.matrix.getVarsetAt(matrix_row).set(c, var_to_col, origMat.num_cols);
-            origMat.matrix.getMatrixAt(matrix_row).set(c, var_to_col, origMat.num_cols);
-            matrix_row++;
-        }
+        origMat.matrix.getVarsetAt(matrix_row).set(c, var_to_col, origMat.num_cols);
+        origMat.matrix.getMatrixAt(matrix_row).set(c, var_to_col, origMat.num_cols);
+        matrix_row++;
     }
     assert(origMat.num_rows == matrix_row);
 }
@@ -552,11 +547,11 @@ Gaussian::gaussian_ret Gaussian::handle_matrix_confl(Clause*& confl, const matri
     assert(best_row != UINT_MAX);
 
     m.matrix.getVarsetAt(best_row).fill(tmp_clause, solver.assigns, col_to_var_original);
-    confl = Clause_new(tmp_clause, solver.learnt_clause_group++, false);
+    confl = (Clause*)XorClause_new(tmp_clause, false, solver.learnt_clause_group++);
     Clause& cla = *confl;
     #ifdef STATS_NEEDED
     if (solver.dynamic_behaviour_analysis)
-        solver.logger.set_group_name(confl->group, "learnt gauss clause");
+        solver.logger.set_group_name(confl->getGroup(), "learnt gauss clause");
     #endif
     
     if (cla.size() <= 1)
@@ -571,7 +566,7 @@ Gaussian::gaussian_ret Gaussian::handle_matrix_confl(Clause*& confl, const matri
     if (maxlevel != solver.decisionLevel()) {
         #ifdef STATS_NEEDED
         if (solver.dynamic_behaviour_analysis)
-            solver.logger.conflict(Logger::gauss_confl_type, maxlevel, confl->group, *confl);
+            solver.logger.conflict(Logger::gauss_confl_type, maxlevel, confl->getGroup(), *confl);
         #endif
         solver.cancelUntil(maxlevel);
     }
@@ -668,7 +663,7 @@ void Gaussian::cancel_until_sublevel(const uint sublevel)
     cout << "(" << matrix_no << ")Canceling until sublevel " << sublevel << endl;
     #endif
     
-    for (Gaussian **gauss = &(solver.gauss_matrixes[0]), **end= gauss + solver.gauss_matrixes.size(); gauss != end; gauss++)
+    for (vector<Gaussian*>::iterator gauss = solver.gauss_matrixes.begin(), end= solver.gauss_matrixes.end(); gauss != end; gauss++)
         if (*gauss != this) (*gauss)->canceling(sublevel);
 
     for (int level = solver.trail.size()-1; level >= (int)sublevel; level--) {
@@ -764,7 +759,7 @@ Gaussian::gaussian_ret Gaussian::handle_matrix_prop(matrixset& m, const uint row
     #endif
 
     m.matrix.getVarsetAt(row).fill(tmp_clause, solver.assigns, col_to_var_original);
-    Clause& cla = *Clause_new(tmp_clause, solver.learnt_clause_group++, false);
+    Clause& cla = *(Clause*)XorClause_new(tmp_clause, false, solver.learnt_clause_group++);
     #ifdef VERBOSE_DEBUG
     cout << "(" << matrix_no << ")matrix prop clause: ";
     cla.plainPrint();
@@ -785,7 +780,7 @@ Gaussian::gaussian_ret Gaussian::handle_matrix_prop(matrixset& m, const uint row
     clauses_toclear.push_back(std::make_pair(&cla, solver.trail.size()-1));
     #ifdef STATS_NEEDED
     if (solver.dynamic_behaviour_analysis)
-        solver.logger.set_group_name(cla.group, "gauss prop clause");
+        solver.logger.set_group_name(cla.getGroup(), "gauss prop clause");
     #endif
     solver.uncheckedEnqueue(cla[0], &cla);
 
@@ -796,9 +791,9 @@ void Gaussian::disable_if_necessary()
 {
     if (//nof_conflicts >= 0
         //&& conflictC >= nof_conflicts/8
-        /*&&*/ called > 100
-        && (double)useful_confl/(double)called < 0.1
-        && (double)useful_prop/(double)called < 0.3 )
+        !config.dontDisable
+        && called > 50
+        && useful_confl*2+useful_prop < (uint)((double)called*0.05) )
             disabled = true;
 }
 
@@ -814,8 +809,8 @@ llbool Gaussian::find_truths(vec<Lit>& learnt_clause, int& conflictC)
         switch (g) {
         case conflict: {
             useful_confl++;
-            llbool ret = solver.handle_conflict(learnt_clause, confl, conflictC);
-            free(confl);
+            llbool ret = solver.handle_conflict(learnt_clause, confl, conflictC, true);
+            clauseFree(confl);
             
             if (ret != l_Nothing) return ret;
             return l_Continue;
@@ -834,19 +829,19 @@ llbool Gaussian::find_truths(vec<Lit>& learnt_clause, int& conflictC)
             Lit lit = (*confl)[0];
             #ifdef STATS_NEEDED
             if (solver.dynamic_behaviour_analysis)
-                solver.logger.conflict(Logger::gauss_confl_type, 0, confl->group, *confl);
+                solver.logger.conflict(Logger::gauss_confl_type, 0, confl->getGroup(), *confl);
             #endif
             
             solver.cancelUntil(0);
             
             if (solver.assigns[lit.var()].isDef()) {
-                free(confl);
+                clauseFree(confl);
                 return l_False;
             }
             
             solver.uncheckedEnqueue(lit);
             
-            free(confl);
+            clauseFree(confl);
             return l_Continue;
         }
         case nothing:
@@ -990,7 +985,7 @@ const bool Gaussian::check_last_one_in_cols(matrixset& m) const
     return true;
 }
 
-const bool Gaussian::check_matrix_against_varset(PackedMatrix& matrix, const matrixset& m) const
+void Gaussian::check_matrix_against_varset(PackedMatrix& matrix, const matrixset& m) const
 {
     for (uint i = 0; i < matrix.getSize(); i++) {
         const PackedRow mat_row = matrix.getMatrixAt(i);
@@ -1164,4 +1159,4 @@ void Gaussian::set_disabled(const bool toset)
 #endif
 }*/
 
-};
+}; //NAMESPACE MINISAT
index 242a1563ceb6a8f4cc77b4341c4da550380469a3..5fb66aa5844f8b4f11319358dbaf440633c1b11d 100644 (file)
@@ -19,16 +19,19 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #define GAUSSIAN_H
 
 #include <vector>
+#include <limits>
+#ifdef _MSC_VER
+#include <msvc/stdint.h>
+#else
+#include <stdint.h>
+#endif //_MSC_VER
+
 #include "SolverTypes.h"
 #include "Solver.h"
 #include "GaussianConfig.h"
 #include "PackedMatrix.h"
 #include "BitArray.h"
 
-namespace MINISAT
-{
-using namespace MINISAT;
-
 //#define VERBOSE_DEBUG
 //#define DEBUG_GAUSS
 
@@ -38,10 +41,14 @@ using std::cout;
 using std::endl;
 #endif
 
+namespace MINISAT
+{
+using namespace MINISAT;
+
 class Clause;
 
-static const uint16_t unassigned_col = -1;
-static const Var unassigned_var = -1;
+static const uint16_t unassigned_col = std::numeric_limits<uint16_t>::max();
+static const Var unassigned_var = std::numeric_limits<Var>::max();
 
 class Gaussian
 {
@@ -155,7 +162,7 @@ private:
     void print_matrix_row(const T& row) const; // Print matrix row 'row'
     template<class T>
     void print_matrix_row_with_assigns(const T& row) const;
-    const bool check_matrix_against_varset(PackedMatrix& matrix,const matrixset& m) const;
+    void check_matrix_against_varset(PackedMatrix& matrix,const matrixset& m) const;
     const bool check_last_one_in_cols(matrixset& m) const;
     const void check_first_one_in_row(matrixset& m, const uint j);
     void print_matrix(matrixset& m) const;
@@ -165,13 +172,12 @@ private:
 
 inline bool Gaussian::should_init() const
 {
-    return (solver.starts >= config.starts_from && config.decision_until > 0);
+    return (config.decision_until > 0);
 }
 
 inline bool Gaussian::should_check_gauss(const uint decisionlevel, const uint starts) const
 {
     return (!disabled
-            && starts >= config.starts_from
             && decisionlevel < config.decision_until);
 }
 
@@ -181,7 +187,7 @@ inline void Gaussian::canceling(const uint sublevel)
         return;
     uint a = 0;
     for (int i = clauses_toclear.size()-1; i >= 0 && clauses_toclear[i].second > sublevel; i--) {
-        free(clauses_toclear[i].first);
+        clauseFree(clauses_toclear[i].first);
         a++;
     }
     clauses_toclear.resize(clauses_toclear.size()-a);
@@ -189,7 +195,7 @@ inline void Gaussian::canceling(const uint sublevel)
     if (messed_matrix_vars_since_reversal)
         return;
     int c = std::min((int)gauss_last_level, (int)(solver.trail.size())-1);
-    for (; c >= sublevel; c--) {
+    for (; c >= (int)sublevel; c--) {
         Var var  = solver.trail[c].var();
         if (var < var_is_in.getSize()
             && var_is_in[var]
@@ -201,6 +207,7 @@ inline void Gaussian::canceling(const uint sublevel)
 }
 
 std::ostream& operator << (std::ostream& os, const vec<Lit>& v);
-};
+
+}; //NAMESPACE MINISAT
 
 #endif //GAUSSIAN_H
index 595dff4670aa10ce5e92b52c452db049eed093d6..f98ec171726aa8f30096b9153615a8421a2c3ecd 100644 (file)
@@ -18,7 +18,12 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #ifndef GAUSSIANCONFIG_H
 #define GAUSSIANCONFIG_H
 
-#include <sys/types.h>
+#ifdef _MSC_VER
+#include <msvc/stdint.h>
+#else
+#include <stdint.h>
+#endif //_MSC_VER
+
 #include "PackedRow.h"
 
 namespace MINISAT
@@ -32,15 +37,16 @@ class GaussianConfig
     GaussianConfig() :
         only_nth_gauss_save(2)
         , decision_until(0)
-        , starts_from(2)
+        , dontDisable(false)
     {
     }
         
     //tuneable gauss parameters
     uint only_nth_gauss_save;  //save only every n-th gauss matrix
     uint decision_until; //do Gauss until this level
-    uint starts_from; //Gauss elimination starts from this restart number
+    bool dontDisable; //If activated, gauss elimination is never disabled
 };
 
-};
+}; //NAMESPACE MINISAT
+
 #endif //GAUSSIANCONFIG_H
index a74f12cd3eebd90e5e5d3e0fddd0e96131c1e920..9677b5c15fe142d6df471bdec81b2b7e9723b75a 100644 (file)
@@ -25,6 +25,7 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
 #include <iomanip>
 #include <fstream>
 #include <sstream>
+#include <limits>
 using std::cout;
 using std::endl;
 using std::ofstream;
@@ -34,13 +35,14 @@ using std::ofstream;
 #include "Solver.h"
 #include "Gaussian.h"
 
-namespace MINISAT
-{
-
 #define FST_WIDTH 10
 #define SND_WIDTH 35
 #define TRD_WIDTH 10
 
+namespace MINISAT
+{
+using namespace MINISAT;
+
 Logger::Logger(int& _verbosity) :
     proof_graph_on(false)
     , mini_proof(false)
@@ -83,6 +85,7 @@ void Logger::new_var(const Var var)
         times_var_propagated.resize(var+1, 0);
         times_var_guessed.resize(var+1, 0);
         depths_of_assigns_for_var.resize(var+1);
+        depths_of_assigns_unit.resize(var+1, false);
     }
 }
 
@@ -94,6 +97,7 @@ void Logger::new_group(const uint group)
         times_group_caused_conflict.resize(group+1, 0);
         times_group_caused_propagation.resize(group+1, 0);
         depths_of_propagations_for_group.resize(group+1);
+        depths_of_propagations_unit.resize(group+1, false);
         depths_of_conflicts_for_group.resize(group+1);
     }
 }
@@ -227,18 +231,17 @@ void Logger::conflict(const confl_type type, const uint goback_level, const uint
 
     if (statistics_on) {
         times_group_caused_conflict[group]++;
-        depths_of_conflicts_for_group[group].push_back(S->decisionLevel());
+        depths_of_conflicts_for_group[group].sum += S->decisionLevel();
+        depths_of_conflicts_for_group[group].num ++;
         
         no_conflicts++;
         sum_conflict_depths += S->trail.size() - S->trail_lim[0];
         sum_decisions_on_branches += S->decisionLevel();
         sum_propagations_on_branches += S->trail.size() - S->trail_lim[0] - S->decisionLevel();
         
-        map<uint, uint>::iterator it = branch_depth_distrib.find(S->decisionLevel());
-        if (it == branch_depth_distrib.end())
-            branch_depth_distrib[S->decisionLevel()] = 1;
-        else
-            it->second++;
+        if (branch_depth_distrib.size() <= S->decisionLevel())
+            branch_depth_distrib.resize(S->decisionLevel()+1, 0);
+        branch_depth_distrib[S->decisionLevel()]++;
     }
 }
 
@@ -259,10 +262,10 @@ void Logger::propagation(const Lit lit, Clause* c)
             type = add_clause_type;
         else
             type = guess_type;
-        group = UINT_MAX;
+        group = std::numeric_limits<uint>::max();
     } else {
         type = simple_propagation_type;
-        group = c->group;
+        group = c->getGroup();
     }
 
     //graph
@@ -298,18 +301,23 @@ void Logger::propagation(const Lit lit, Clause* c)
     if (statistics_on) {
         switch (type) {
         case simple_propagation_type:
-            depths_of_propagations_for_group[group].push_back(S->decisionLevel());
+            depths_of_propagations_for_group[group].sum += S->decisionLevel();
+            depths_of_propagations_for_group[group].num ++;
+            if (S->decisionLevel() == 0) depths_of_propagations_unit[group] = true;
             times_group_caused_propagation[group]++;
         case add_clause_type:
             no_propagations++;
             times_var_propagated[lit.var()]++;
-            depths_of_assigns_for_var[lit.var()].push_back(S->decisionLevel());
+            depths_of_assigns_for_var[lit.var()].sum += S->decisionLevel();
+            depths_of_assigns_for_var[lit.var()].num ++;
+            if (S->decisionLevel() == 0) depths_of_assigns_unit[lit.var()] = true;
             break;
         case guess_type:
             no_decisions++;
             times_var_guessed[lit.var()]++;
             
-            depths_of_assigns_for_var[lit.var()].push_back(S->decisionLevel());
+            depths_of_assigns_for_var[lit.var()].sum += S->decisionLevel();
+            depths_of_assigns_for_var[lit.var()].num ++;
             break;
         }
     }
@@ -362,16 +370,10 @@ void Logger::print_assign_var_order() const
 {
     vector<pair<double, uint> > prop_ordered;
     for (uint i = 0; i < depths_of_assigns_for_var.size(); i++) {
-        double avg = 0.0;
-        bool was_unit = false;
-        for (vector<uint>::const_iterator it = depths_of_assigns_for_var[i].begin(); it != depths_of_assigns_for_var[i].end(); it++) {
-            avg += *it;
-            if (*it == 0) was_unit = true;
-        }
-        if (depths_of_assigns_for_var[i].size() > 0 && !was_unit) {
-            avg /= (double) depths_of_assigns_for_var[i].size();
+        double avg = (double)depths_of_assigns_for_var[i].sum
+                    /(double)depths_of_assigns_for_var[i].num;
+        if (depths_of_assigns_for_var[i].num > 0 && !depths_of_assigns_unit[i])
             prop_ordered.push_back(std::make_pair(avg, i));
-        }
     }
 
     if (!prop_ordered.empty()) {
@@ -388,16 +390,10 @@ void Logger::print_prop_order() const
 {
     vector<pair<double, uint> > prop_ordered;
     for (uint i = 0; i < depths_of_propagations_for_group.size(); i++) {
-        double avg = 0.0;
-        bool was_unit = false;
-        for (vector<uint>::const_iterator it = depths_of_propagations_for_group[i].begin(); it != depths_of_propagations_for_group[i].end(); it++) {
-            avg += *it;
-            if (*it == 0) was_unit = true;
-        }
-        if (depths_of_propagations_for_group[i].size() > 0 && !was_unit) {
-            avg /= (double) depths_of_propagations_for_group[i].size();
+        double avg = (double)depths_of_propagations_for_group[i].sum
+                    /(double)depths_of_propagations_for_group[i].num;
+        if (depths_of_propagations_for_group[i].num > 0 && !depths_of_propagations_unit[i])
             prop_ordered.push_back(std::make_pair(avg, i));
-        }
     }
 
     if (!prop_ordered.empty()) {
@@ -414,13 +410,10 @@ void Logger::print_confl_order() const
 {
     vector<pair<double, uint> > confl_ordered;
     for (uint i = 0; i < depths_of_conflicts_for_group.size(); i++) {
-        double avg = 0.0;
-        for (vector<uint>::const_iterator it = depths_of_conflicts_for_group[i].begin(); it != depths_of_conflicts_for_group[i].end(); it++)
-            avg += *it;
-        if (depths_of_conflicts_for_group[i].size() > 0) {
-            avg /= (double) depths_of_conflicts_for_group[i].size();
+        double avg = (double)depths_of_conflicts_for_group[i].sum
+                    /(double)depths_of_conflicts_for_group[i].num;
+        if (depths_of_conflicts_for_group[i].num > 0)
             confl_ordered.push_back(std::make_pair(avg, i));
-        }
     }
 
     if (!confl_ordered.empty()) {
@@ -556,11 +549,10 @@ void Logger::print_branch_depth_distrib() const
     const uint range = 20;
     map<uint, uint> range_stat;
 
-    for (map<uint, uint>::const_iterator it = branch_depth_distrib.begin(); it != branch_depth_distrib.end(); it++) {
-        //cout << it->first << " : " << it->second << endl;
-        range_stat[it->first/range] += it->second;
+    uint i = 0;
+    for (vector<uint>::const_iterator it = branch_depth_distrib.begin(); it != branch_depth_distrib.end(); it++, i++) {
+        range_stat[i/range] += *it;
     }
-    //cout << endl;
 
     print_footer();
     print_simple_line(" No. search branches with branch depth between");
@@ -571,9 +563,9 @@ void Logger::print_branch_depth_distrib() const
     ss << "branch_depths/branch_depth_file" << runid << "-" << S->starts << ".txt";
     ofstream branch_depth_file;
     branch_depth_file.open(ss.str().c_str());
-    uint i = 0;
+    i = 0;
     
-    for (map<uint, uint>::iterator it = range_stat.begin(); it != range_stat.end(); it++) {
+    for (map<uint, uint>::iterator it = range_stat.begin(); it != range_stat.end(); it++, i++) {
         std::stringstream ss2;
         ss2 << it->first*range << " - " << it->first*range + range-1;
         print_line(ss2.str(), it->second);
@@ -586,7 +578,6 @@ void Logger::print_branch_depth_distrib() const
                 branch_depth_file << "\"\"";
             branch_depth_file << endl;
         }
-        i++;
     }
     if (branch_depth_file.is_open())
         branch_depth_file.close();
@@ -713,11 +704,15 @@ void Logger::print_learnt_unitaries(const uint from, const string display) const
     print_footer();
     print_simple_line(display);
     print_header("var", "name", "value");
-    for (uint i = from; i < S->trail.size(); i++) {
+    uint32_t until;
+    if (S->decisionLevel() > 0)
+        until = S->trail_lim[0];
+    else
+        until = S->trail.size();
+    for (uint i = from; i < until; i++) {
         Var var = S->trail[i].var();
-        bool sign = S->trail[i].sign();
-        std::stringstream ss;
-        print_line(var+1, varnames[var], sign);
+        bool value = !(S->trail[i].sign());
+        print_line(var+1, varnames[var], value);
     }
     print_footer();
 }
@@ -850,16 +845,27 @@ void Logger::reset_statistics()
     for (vecit it = props_by_group.begin(); it != props_by_group.end(); it++)
         *it = 0;
 
-    typedef vector<vector<uint> >::iterator vecvecit;
+    typedef vector<MyAvg>::iterator avgIt;
 
-    for (vecvecit it = depths_of_propagations_for_group.begin(); it != depths_of_propagations_for_group.end(); it++)
-        it->clear();
+    for (avgIt it = depths_of_propagations_for_group.begin(); it != depths_of_propagations_for_group.end(); it++) {
+        it->sum = 0;
+        it->num = 0;
+    }
 
-    for (vecvecit it = depths_of_conflicts_for_group.begin(); it != depths_of_conflicts_for_group.end(); it++)
-        it->clear();
+    for (avgIt it = depths_of_conflicts_for_group.begin(); it != depths_of_conflicts_for_group.end(); it++) {
+        it->sum = 0;
+        it->num = 0;
+    }
 
-    for (vecvecit it = depths_of_assigns_for_var.begin(); it != depths_of_assigns_for_var.end(); it++)
-        it->clear();
+    for (avgIt it = depths_of_assigns_for_var.begin(); it != depths_of_assigns_for_var.end(); it++) {
+        it->sum = 0;
+        it->num = 0;
+    }
+    for (uint i = 0; i < depths_of_assigns_unit.size(); i++)
+        depths_of_assigns_unit[i] = false;
+    
+    for (uint i = 0; i < depths_of_propagations_unit.size(); i++)
+        depths_of_propagations_unit[i] = false;
 
     sum_conflict_depths = 0;
     no_conflicts = 0;
@@ -871,4 +877,4 @@ void Logger::reset_statistics()
     last_unitary_learnt_clauses = S->get_unitary_learnts_num();
 }
 
-};
+}; //NAMESPACE MINISAT
index f0dca8675f752fdef1ce35caf0b737f97cca38dd..3e87fab3a7219680c74b94d6bde4e252cda5288d 100644 (file)
@@ -25,29 +25,41 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
 #include <vector>
 #include <string>
 #include <map>
-
-#include "mtl/Vec.h"
-#include "mtl/Heap.h"
-#include "mtl/Alg.h"
+#ifdef _MSC_VER
+#include <msvc/stdint.h>
+#else
+#include <stdint.h>
+#endif //_MSC_VER
+
+#include "Vec.h"
+#include "Heap.h"
+#include "Alg.h"
 #include "SolverTypes.h"
-#include "stdint.h"
 #include "limits.h"
 #include "Clause.h"
 
-#ifndef uint
-#define uint unsigned int
-#endif
-
-namespace MINISAT
-{
-
 using std::vector;
 using std::pair;
 using std::string;
 using std::map;
 
+namespace MINISAT
+{
+using namespace MINISAT;
+
 class Solver;
 
+class MyAvg {
+public:
+    MyAvg() :
+        sum(0)
+        , num(0)
+        {}
+    
+    uint sum;
+    uint num;
+};
+
 class Logger
 {
 public:
@@ -143,12 +155,14 @@ private:
     vector<uint> times_group_caused_conflict;
     vector<uint> times_group_caused_propagation;
 
-    vector<vector<uint> > depths_of_propagations_for_group;
-    vector<vector<uint> > depths_of_conflicts_for_group;
-    vector<vector<uint> > depths_of_assigns_for_var;
+    vector<MyAvg> depths_of_propagations_for_group;
+    vector<bool>  depths_of_propagations_unit;
+    vector<MyAvg> depths_of_conflicts_for_group;
+    vector<MyAvg> depths_of_assigns_for_var;
+    vector<bool>  depths_of_assigns_unit;
 
     //the distribution of branch depths. first = depth, second = number of occurances
-    map<uint, uint> branch_depth_distrib;
+    vector<uint> branch_depth_distrib;
 
     uint sum_conflict_depths;
     uint no_conflicts;
@@ -168,5 +182,6 @@ private:
     uint proofStarts;
 };
 
-};
+}; //NAMESPACE MINISAT
+
 #endif //LOGGER_H
index 954e0e74f3c6cd893e13202fa5fa25a57b7a80a6..8315c2911ec98972d196a6cd516a877ba11db692 100644 (file)
@@ -3,7 +3,7 @@ include $(TOP)/scripts/Makefile.common
 
 MTL       = mtl
 MTRAND    = MTRand
-SOURCES   = Conglomerate.cpp  FindUndef.cpp  Gaussian.cpp  Logger.cpp  MatrixFinder.cpp  PackedRow.cpp  Solver.cpp  VarReplacer.cpp  XorFinder.cpp ClauseCleaner.cpp RestartTypeChooser.cpp
+SOURCES   = Logger.cpp Solver.cpp Gaussian.cpp PackedRow.cpp XorFinder.cpp Conglomerate.cpp MatrixFinder.cpp VarReplacer.cpp FindUndef.cpp ClauseCleaner.cpp RestartTypeChooser.cpp Clause.cpp FailedVarSearcher.cpp PartFinder.cpp Subsumer.cpp PartHandler.cpp XorSubsumer.cpp
 OBJECTS   = $(SOURCES:.cpp=.o)
 LIB       = libminisat.a
 CFLAGS    += -I$(MTL) -I$(MTRAND) -DEXT_HASH_MAP -ffloat-store $(CFLAGS_M32) -c
index b196a552b68e211dcd3e50193bf25c5d284f19e2..1f08a2c9a4bf1ef9a749f0062fe8d09d685e0291 100644 (file)
@@ -26,9 +26,6 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #include <map>
 #include <iomanip>
 #include <math.h>
-namespace MINISAT
-{
-
 using std::set;
 using std::map;
 
@@ -37,11 +34,14 @@ using std::map;
 using std::cout;
 using std::endl;
 
+namespace MINISAT
+{
+using namespace MINISAT;
+
 //#define PART_FINDING
 
-MatrixFinder::MatrixFinder(Solver *_s) :
-    unAssigned(_s->nVars() + 1)
-    , S(_s)
+MatrixFinder::MatrixFinder(Solver& _solver) :
+    solver(_solver)
 {
 }
 
@@ -73,20 +73,21 @@ inline const bool MatrixFinder::firstPartOfSecond(const XorClause& c1, const Xor
 const uint MatrixFinder::findMatrixes()
 {
     table.clear();
-    table.resize(S->nVars(), unAssigned);
+    table.resize(solver.nVars(), var_Undef);
     reverseTable.clear();
     matrix_no = 0;
     
-    if (S->xorclauses.size() == 0)
+    if (solver.xorclauses.size() == 0)
         return 0;
     
-    S->clauseCleaner->cleanClauses(S->xorclauses, ClauseCleaner::xorclauses);
+    solver.clauseCleaner->cleanClauses(solver.xorclauses, ClauseCleaner::xorclauses);
+    //TODO check for solver.ok == false
     
-    for (XorClause** c = S->xorclauses.getData(), **end = c + S->xorclauses.size(); c != end; c++) {
+    for (XorClause** c = solver.xorclauses.getData(), **end = c + solver.xorclauses.size(); c != end; c++) {
         set<uint> tomerge;
         vector<Var> newSet;
         for (Lit *l = &(**c)[0], *end2 = l + (**c).size(); l != end2; l++) {
-            if (table[l->var()] != unAssigned)
+            if (table[l->var()] != var_Undef)
                 tomerge.insert(table[l->var()]);
             else
                 newSet.push_back(l->var());
@@ -138,7 +139,7 @@ const uint MatrixFinder::setMatrixes()
     vector<vector<Var> > xorFingerprintInMatrix(matrix_no);
     #endif
     
-    for (XorClause** c = S->xorclauses.getData(), **end = c + S->xorclauses.size(); c != end; c++) {
+    for (XorClause** c = solver.xorclauses.getData(), **end = c + solver.xorclauses.size(); c != end; c++) {
         XorClause& x = **c;
         const uint matrix = table[x[0].var()];
         assert(matrix < matrix_no);
@@ -174,23 +175,23 @@ const uint MatrixFinder::setMatrixes()
         double variance = 0.0;
         for (uint i2 = 0; i2 < xorSizesInMatrix[i].size(); i2++)
             variance += pow((double)xorSizesInMatrix[i][i2]-avg, 2);
-        variance /= xorSizesInMatrix.size();
+        variance /= (double)xorSizesInMatrix.size();
         const double stdDeviation = sqrt(variance);
         
         if (numXorInMatrix[a].second >= 20
             && numXorInMatrix[a].second <= 1000
             && realMatrixNum < 3)
         {
-            if (S->verbosity >=1)
+            if (solver.verbosity >=1)
                 cout << "c |  Matrix no " << std::setw(4) << realMatrixNum;
-            S->gauss_matrixes.push_back(new Gaussian(*S, S->gaussconfig, realMatrixNum, xorsInMatrix[i]));
+            solver.gauss_matrixes.push_back(new Gaussian(solver, solver.gaussconfig, realMatrixNum, xorsInMatrix[i]));
             realMatrixNum++;
             
         } else {
-            if (S->verbosity >=1  && numXorInMatrix[a].second >= 20)
+            if (solver.verbosity >=1  /*&& numXorInMatrix[a].second >= 20*/)
                 cout << "c |  Unused Matrix ";
         }
-        if (S->verbosity >=1 && numXorInMatrix[a].second >= 20) {
+        if (solver.verbosity >=1 /*&& numXorInMatrix[a].second >= 20*/) {
             cout << std::setw(5) << numXorInMatrix[a].second << " x" << std::setw(5) << reverseTable[i].size();
             cout << "  density:" << std::setw(5) << std::fixed << std::setprecision(1) << density << "%";
             cout << "  xorlen avg:" << std::setw(5) << std::fixed << std::setprecision(2)  << avg;
@@ -219,4 +220,5 @@ void MatrixFinder::findParts(vector<Var>& xorFingerprintInMatrix, vector<XorClau
         }
     }
 }
-};
+
+}; //NAMESPACE MINISAT
index f4b6aafa9dcca3ca3b193c7798bd8f13222bad03..7be3506acbcbae3f37e496c4216d5bdbb7f3a4aa 100644 (file)
@@ -18,13 +18,20 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #ifndef MATRIXFINDER_H
 #define MATRIXFINDER_H
 
-#include <sys/types.h>
-#include "Clause.h"
 #include <vector>
 #include <map>
+#ifdef _MSC_VER
+#include <msvc/stdint.h>
+#else
+#include <stdint.h>
+#endif //_MSC_VER
+
+#include "Clause.h"
+#include "Solver.h"
 
 namespace MINISAT
 {
+using namespace MINISAT;
 
 class Solver;
 
@@ -35,7 +42,7 @@ using std::pair;
 class MatrixFinder {
     
     public:
-        MatrixFinder(Solver* S);
+        MatrixFinder(Solver& solver);
         const uint findMatrixes();
     
     private:
@@ -54,12 +61,12 @@ class MatrixFinder {
         inline const bool firstPartOfSecond(const XorClause& c1, const XorClause& c2) const;
         
         map<uint, vector<Var> > reverseTable; //matrix -> vars
-        vector<uint> table; //var -> matrix
+        vector<Var> table; //var -> matrix
         uint matrix_no;
-        const uint unAssigned;
         
-        Solver* S;
-};
+        Solver& solver;
 };
 
+}; //NAMESPACE MINISAT
+
 #endif //MATRIXFINDER_H
diff --git a/src/sat/cryptominisat2/MersenneTwister.h b/src/sat/cryptominisat2/MersenneTwister.h
new file mode 100644 (file)
index 0000000..964ecc7
--- /dev/null
@@ -0,0 +1,427 @@
+// MersenneTwister.h
+// Mersenne Twister random number generator -- a C++ class MTRand
+// Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus
+// Richard J. Wagner  v1.0  15 May 2003  rjwagner@writeme.com
+
+// The Mersenne Twister is an algorithm for generating random numbers.  It
+// was designed with consideration of the flaws in various other generators.
+// The period, 2^19937-1, and the order of equidistribution, 623 dimensions,
+// are far greater.  The generator is also fast; it avoids multiplication and
+// division, and it benefits from caches and pipelines.  For more information
+// see the inventors' web page at http://www.math.keio.ac.jp/~matumoto/emt.html
+
+// Reference
+// M. Matsumoto and T. Nishimura, "Mersenne Twister: A 623-Dimensionally
+// Equidistributed Uniform Pseudo-Random Number Generator", ACM Transactions on
+// Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30.
+
+// Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
+// Copyright (C) 2000 - 2003, Richard J. Wagner
+// 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 names of its contributors may not be used to endorse or promote 
+//      products derived from this software without specific prior written 
+//      permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// The original code included the following notice:
+//
+//     When you use this, send an email to: matumoto@math.keio.ac.jp
+//     with an appropriate reference to your work.
+//
+// It would be nice to CC: rjwagner@writeme.com and Cokus@math.washington.edu
+// when you write.
+
+#ifndef MERSENNETWISTER_H
+#define MERSENNETWISTER_H
+
+#include <iostream>
+#include <limits.h>
+#include <stdio.h>
+#include <time.h>
+#include <math.h>
+
+namespace MINISAT
+{
+
+// Not thread safe (unless auto-initialization is avoided and each thread has
+// its own MTRand object)
+
+class MTRand {
+// Data
+public:
+       typedef unsigned long uint32;  // unsigned integer type, at least 32 bits
+       
+       enum { N = 624 };       // length of state vector
+       enum { SAVE = N + 1 };  // length of array for save()
+
+protected:
+       enum { M = 397 };  // period parameter
+       
+       uint32 state[N];   // internal state
+       uint32 *pNext;     // next value to get from state
+       int left;          // number of values left before reload needed
+
+
+//Methods
+public:
+       MTRand( const uint32& oneSeed );  // initialize with a simple uint32
+       MTRand( uint32 *const bigSeed, uint32 const seedLength = N );  // or an array
+       MTRand();  // auto-initialize with /dev/urandom or time() and clock()
+       
+       // Do NOT use for CRYPTOGRAPHY without securely hashing several returned
+       // values together, otherwise the generator state can be learned after
+       // reading 624 consecutive values.
+       
+       // Access to 32-bit random numbers
+       double rand();                          // real number in [0,1]
+       double rand( const double& n );         // real number in [0,n]
+       double randExc();                       // real number in [0,1)
+       double randExc( const double& n );      // real number in [0,n)
+       double randDblExc();                    // real number in (0,1)
+       double randDblExc( const double& n );   // real number in (0,n)
+       uint32 randInt();                       // integer in [0,2^32-1]
+       uint32 randInt( const uint32& n );      // integer in [0,n] for n < 2^32
+       double operator()() { return rand(); }  // same as rand()
+       
+       // Access to 53-bit random numbers (capacity of IEEE double precision)
+       double rand53();  // real number in [0,1)
+       
+       // Access to nonuniform random number distributions
+       double randNorm( const double& mean = 0.0, const double& variance = 0.0 );
+       
+       // Re-seeding functions with same behavior as initializers
+       void seed( const uint32 oneSeed );
+       void seed( uint32 *const bigSeed, const uint32 seedLength = N );
+       void seed();
+       
+       // Saving and loading generator state
+       void save( uint32* saveArray ) const;  // to array of size SAVE
+       void load( uint32 *const loadArray );  // from such array
+       friend std::ostream& operator<<( std::ostream& os, const MTRand& mtrand );
+       friend std::istream& operator>>( std::istream& is, MTRand& mtrand );
+
+protected:
+       void initialize( const uint32 oneSeed );
+       void reload();
+       uint32 hiBit( const uint32& u ) const { return u & 0x80000000UL; }
+       uint32 loBit( const uint32& u ) const { return u & 0x00000001UL; }
+       uint32 loBits( const uint32& u ) const { return u & 0x7fffffffUL; }
+       uint32 mixBits( const uint32& u, const uint32& v ) const
+               { return hiBit(u) | loBits(v); }
+       uint32 twist( const uint32& m, const uint32& s0, const uint32& s1 ) const
+               { return m ^ (mixBits(s0,s1)>>1) ^ (-loBit(s1) & 0x9908b0dfUL); }
+       static uint32 hash( time_t t, clock_t c );
+};
+
+
+inline MTRand::MTRand( const uint32& oneSeed )
+       { seed(oneSeed); }
+
+inline MTRand::MTRand( uint32 *const bigSeed, const uint32 seedLength )
+       { seed(bigSeed,seedLength); }
+
+inline MTRand::MTRand()
+       { seed(); }
+
+inline double MTRand::rand()
+       { return double(randInt()) * (1.0/4294967295.0); }
+
+inline double MTRand::rand( const double& n )
+       { return rand() * n; }
+
+inline double MTRand::randExc()
+       { return double(randInt()) * (1.0/4294967296.0); }
+
+inline double MTRand::randExc( const double& n )
+       { return randExc() * n; }
+
+inline double MTRand::randDblExc()
+       { return ( double(randInt()) + 0.5 ) * (1.0/4294967296.0); }
+
+inline double MTRand::randDblExc( const double& n )
+       { return randDblExc() * n; }
+
+inline double MTRand::rand53()
+{
+       uint32 a = randInt() >> 5, b = randInt() >> 6;
+       return ( a * 67108864.0 + b ) * (1.0/9007199254740992.0);  // by Isaku Wada
+}
+
+inline double MTRand::randNorm( const double& mean, const double& variance )
+{
+       // Return a real number from a normal (Gaussian) distribution with given
+       // mean and variance by Box-Muller method
+       double r = sqrt( -2.0 * log( 1.0-randDblExc()) ) * variance;
+       double phi = 2.0 * 3.14159265358979323846264338328 * randExc();
+       return mean + r * cos(phi);
+}
+
+inline MTRand::uint32 MTRand::randInt()
+{
+       // Pull a 32-bit integer from the generator state
+       // Every other access function simply transforms the numbers extracted here
+       
+       if( left == 0 ) reload();
+       --left;
+               
+       register uint32 s1;
+       s1 = *pNext++;
+       s1 ^= (s1 >> 11);
+       s1 ^= (s1 <<  7) & 0x9d2c5680UL;
+       s1 ^= (s1 << 15) & 0xefc60000UL;
+       return ( s1 ^ (s1 >> 18) );
+}
+
+inline MTRand::uint32 MTRand::randInt( const uint32& n )
+{
+       // Find which bits are used in n
+       // Optimized by Magnus Jonsson (magnus@smartelectronix.com)
+       uint32 used = n;
+       used |= used >> 1;
+       used |= used >> 2;
+       used |= used >> 4;
+       used |= used >> 8;
+       used |= used >> 16;
+       
+       // Draw numbers until one is found in [0,n]
+       uint32 i;
+       do
+               i = randInt() & used;  // toss unused bits to shorten search
+       while( i > n );
+       return i;
+}
+
+
+inline void MTRand::seed( const uint32 oneSeed )
+{
+       // Seed the generator with a simple uint32
+       initialize(oneSeed);
+       reload();
+}
+
+
+inline void MTRand::seed( uint32 *const bigSeed, const uint32 seedLength )
+{
+       // Seed the generator with an array of uint32's
+       // There are 2^19937-1 possible initial states.  This function allows
+       // all of those to be accessed by providing at least 19937 bits (with a
+       // default seed length of N = 624 uint32's).  Any bits above the lower 32
+       // in each element are discarded.
+       // Just call seed() if you want to get array from /dev/urandom
+       initialize(19650218UL);
+       register int i = 1;
+       register uint32 j = 0;
+       register int k = ( N > seedLength ? N : seedLength );
+       for( ; k; --k )
+       {
+               state[i] =
+                       state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1664525UL );
+               state[i] += ( bigSeed[j] & 0xffffffffUL ) + j;
+               state[i] &= 0xffffffffUL;
+               ++i;  ++j;
+               if( i >= N ) { state[0] = state[N-1];  i = 1; }
+               if( j >= seedLength ) j = 0;
+       }
+       for( k = N - 1; k; --k )
+       {
+               state[i] =
+                       state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1566083941UL );
+               state[i] -= i;
+               state[i] &= 0xffffffffUL;
+               ++i;
+               if( i >= N ) { state[0] = state[N-1];  i = 1; }
+       }
+       state[0] = 0x80000000UL;  // MSB is 1, assuring non-zero initial array
+       reload();
+}
+
+
+inline void MTRand::seed()
+{
+       // Seed the generator with an array from /dev/urandom if available
+       // Otherwise use a hash of time() and clock() values
+       
+       // First try getting an array from /dev/urandom
+       FILE* urandom = fopen( "/dev/urandom", "rb" );
+       if( urandom )
+       {
+               uint32 bigSeed[N];
+               register uint32 *s = bigSeed;
+               register int i = N;
+               register bool success = true;
+               while( success && i-- )
+                       success = fread( s++, sizeof(uint32), 1, urandom );
+               fclose(urandom);
+               if( success ) { seed( bigSeed, N );  return; }
+       }
+       
+       // Was not successful, so use time() and clock() instead
+       seed( hash( time(NULL), clock() ) );
+}
+
+
+inline void MTRand::initialize( const uint32 seed )
+{
+       // Initialize generator state with seed
+       // See Knuth TAOCP Vol 2, 3rd Ed, p.106 for multiplier.
+       // In previous versions, most significant bits (MSBs) of the seed affect
+       // only MSBs of the state array.  Modified 9 Jan 2002 by Makoto Matsumoto.
+       register uint32 *s = state;
+       register uint32 *r = state;
+       register int i = 1;
+       *s++ = seed & 0xffffffffUL;
+       for( ; i < N; ++i )
+       {
+               *s++ = ( 1812433253UL * ( *r ^ (*r >> 30) ) + i ) & 0xffffffffUL;
+               r++;
+       }
+}
+
+
+inline void MTRand::reload()
+{
+       // Generate N new values in state
+       // Made clearer and faster by Matthew Bellew (matthew.bellew@home.com)
+       register uint32 *p = state;
+       register int i;
+       for( i = N - M; i--; ++p )
+               *p = twist( p[M], p[0], p[1] );
+       for( i = M; --i; ++p )
+               *p = twist( p[M-N], p[0], p[1] );
+       *p = twist( p[M-N], p[0], state[0] );
+
+       left = N, pNext = state;
+}
+
+
+inline MTRand::uint32 MTRand::hash( time_t t, clock_t c )
+{
+       // Get a uint32 from t and c
+       // Better than uint32(x) in case x is floating point in [0,1]
+       // Based on code by Lawrence Kirby (fred@genesis.demon.co.uk)
+
+       static uint32 differ = 0;  // guarantee time-based seeds will change
+
+       uint32 h1 = 0;
+       unsigned char *p = (unsigned char *) &t;
+       for( size_t i = 0; i < sizeof(t); ++i )
+       {
+               h1 *= UCHAR_MAX + 2U;
+               h1 += p[i];
+       }
+       uint32 h2 = 0;
+       p = (unsigned char *) &c;
+       for( size_t j = 0; j < sizeof(c); ++j )
+       {
+               h2 *= UCHAR_MAX + 2U;
+               h2 += p[j];
+       }
+       return ( h1 + differ++ ) ^ h2;
+}
+
+
+inline void MTRand::save( uint32* saveArray ) const
+{
+       register uint32 *sa = saveArray;
+       register const uint32 *s = state;
+       register int i = N;
+       for( ; i--; *sa++ = *s++ ) {}
+       *sa = left;
+}
+
+
+inline void MTRand::load( uint32 *const loadArray )
+{
+       register uint32 *s = state;
+       register uint32 *la = loadArray;
+       register int i = N;
+       for( ; i--; *s++ = *la++ ) {}
+       left = *la;
+       pNext = &state[N-left];
+}
+
+
+inline std::ostream& operator<<( std::ostream& os, const MTRand& mtrand )
+{
+       register const MTRand::uint32 *s = mtrand.state;
+       register int i = mtrand.N;
+       for( ; i--; os << *s++ << "\t" ) {}
+       return os << mtrand.left;
+}
+
+
+inline std::istream& operator>>( std::istream& is, MTRand& mtrand )
+{
+       register MTRand::uint32 *s = mtrand.state;
+       register int i = mtrand.N;
+       for( ; i--; is >> *s++ ) {}
+       is >> mtrand.left;
+       mtrand.pNext = &mtrand.state[mtrand.N-mtrand.left];
+       return is;
+}
+};
+
+#endif  // MERSENNETWISTER_H
+
+// Change log:
+//
+// v0.1 - First release on 15 May 2000
+//      - Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus
+//      - Translated from C to C++
+//      - Made completely ANSI compliant
+//      - Designed convenient interface for initialization, seeding, and
+//        obtaining numbers in default or user-defined ranges
+//      - Added automatic seeding from /dev/urandom or time() and clock()
+//      - Provided functions for saving and loading generator state
+//
+// v0.2 - Fixed bug which reloaded generator one step too late
+//
+// v0.3 - Switched to clearer, faster reload() code from Matthew Bellew
+//
+// v0.4 - Removed trailing newline in saved generator format to be consistent
+//        with output format of built-in types
+//
+// v0.5 - Improved portability by replacing static const int's with enum's and
+//        clarifying return values in seed(); suggested by Eric Heimburg
+//      - Removed MAXINT constant; use 0xffffffffUL instead
+//
+// v0.6 - Eliminated seed overflow when uint32 is larger than 32 bits
+//      - Changed integer [0,n] generator to give better uniformity
+//
+// v0.7 - Fixed operator precedence ambiguity in reload()
+//      - Added access for real numbers in (0,1) and (0,n)
+//
+// v0.8 - Included time.h header to properly support time_t and clock_t
+//
+// v1.0 - Revised seeding to match 26 Jan 2002 update of Nishimura and Matsumoto
+//      - Allowed for seeding with arrays of any length
+//      - Added access for real numbers in [0,1) with 53-bit resolution
+//      - Added access for real numbers from normal (Gaussian) distributions
+//      - Increased overall speed by optimizing twist()
+//      - Doubled speed of integer [0,n] generation
+//      - Fixed out-of-range number generation on 64-bit machines
+//      - Improved portability by substituting literal constants for long enum's
+//      - Changed license from GNU LGPL to BSD
index 0edf1e086a5ccfbc44649651852265113fbfd9ca..9c7f117d15762fec3ea80b3a7adfce4443f3166f 100644 (file)
@@ -18,25 +18,28 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #ifndef PACKEDMATRIX_H
 #define PACKEDMATRIX_H
 
-#include "PackedRow.h"
 #include <algorithm>
+#ifdef _MSC_VER
+#include <msvc/stdint.h>
+#else
+#include <stdint.h>
+#endif //_MSC_VER
 
-//#define DEBUG_MATRIX
+#include "PackedRow.h"
 
-#ifndef uint
-#define uint unsigned int
-#endif
+//#define DEBUG_MATRIX
 
 namespace MINISAT
 {
+using namespace MINISAT;
 
 class PackedMatrix
 {
 public:
     PackedMatrix() :
-        numRows(0)
+        mp(NULL)
+        , numRows(0)
         , numCols(0)
-        , mp(NULL)
     {
     }
     
@@ -210,11 +213,12 @@ public:
 
 private:
     
+    uint64_t* mp;
     uint numRows;
     uint numCols;
-    uint64_t* mp;
-};
 };
 
+}; //NAMESPACE MINISAT
+
 #endif //PACKEDMATRIX_H
 
index e9356eb145692642449f3117112fe6e711a1d50f..59a4e4332e9be6bfed26abc427a76c36a8907313 100644 (file)
@@ -16,12 +16,14 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 **************************************************************************************************/
 
 #include "PackedRow.h"
+
 namespace MINISAT
 {
+using namespace MINISAT;
 
 std::ostream& operator << (std::ostream& os, const PackedRow& m)
 {
-    for(uint i = 0; i < m.size*64; i++) {
+    for(uint32_t i = 0; i < m.size*64; i++) {
         os << m[i];
     }
     os << " -- xor: " << m.is_true();
@@ -50,10 +52,10 @@ bool PackedRow::operator !=(const PackedRow& b) const
     return (!std::equal(b.mp-1, b.mp+size, mp-1));
 }
 
-uint PackedRow::popcnt() const
+uint32_t PackedRow::popcnt() const
 {
-    uint popcnt = 0;
-    for (uint i = 0; i < size; i++) if (mp[i]) {
+    uint32_t popcnt = 0;
+    for (uint32_t i = 0; i < size; i++) if (mp[i]) {
         uint64_t tmp = mp[i];
         for (uint i2 = 0; i2 < 64; i2++) {
             popcnt += (tmp & 1);
@@ -63,12 +65,12 @@ uint PackedRow::popcnt() const
     return popcnt;
 }
 
-uint PackedRow::popcnt(const uint from) const
+uint32_t PackedRow::popcnt(const uint32_t from) const
 {
-    uint popcnt = 0;
-    for (uint i = from/64; i != size; i++) if (mp[i]) {
+    uint32_t popcnt = 0;
+    for (uint32_t i = from/64; i != size; i++) if (mp[i]) {
         uint64_t tmp = mp[i];
-        uint i2;
+        uint32_t i2;
         if (i == from/64) {
             i2 = from%64;
             tmp >>= i2;
@@ -87,12 +89,12 @@ void PackedRow::fill(vec<Lit>& tmp_clause, const vec<lbool>& assigns, const vect
     bool final = !is_true_internal;
     
     tmp_clause.clear();
-    uint col = 0;
+    uint32_t col = 0;
     bool wasundef = false;
-    for (uint i = 0; i < size; i++) for (uint i2 = 0; i2 < 64; i2++) {
+    for (uint32_t i = 0; i < size; i++) for (uint32_t i2 = 0; i2 < 64; i2++) {
         if ((mp[i] >> i2) &1) {
-            const uint& var = col_to_var_original[col];
-            assert(var != UINT_MAX);
+            const Var& var = col_to_var_original[col];
+            assert(var != std::numeric_limits<Var>::max());
             
             const lbool& val = assigns[var];
             const bool val_bool = val.getBool();
@@ -114,4 +116,5 @@ void PackedRow::fill(vec<Lit>& tmp_clause, const vec<lbool>& assigns, const vect
     } else
         assert(!final);
 }
-};
+
+}; //NAMESPACE MINISAT
index 4c2d67d270fde61203b9995ffdfa5e09831c8d4b..e59ff9b23f490237cabb9ba1f5622c91e5f7379d 100644 (file)
@@ -21,21 +21,27 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 //#define DEBUG_ROW
 
 #include <vector>
-#include <limits.h>
+#ifdef _MSC_VER
+#include <msvc/stdint.h>
+#else
+#include <stdint.h>
+#endif //_MSC_VER
+
 #include "SolverTypes.h"
-#include "mtl/Vec.h"
+#include "Vec.h"
 #include <string.h>
 #include <iostream>
 #include <algorithm>
-
+#include <limits>
 #ifndef uint
 #define uint unsigned int
 #endif
 
+using std::vector;
+
 namespace MINISAT
 {
-
-using std::vector;
+using namespace MINISAT;
 
 
 class PackedMatrix;
@@ -66,7 +72,7 @@ public:
         assert(b.size == size);
         #endif
         
-        for (uint i = 0; i != size; i++) {
+        for (uint32_t i = 0; i != size; i++) {
             *(mp + i) ^= *(b.mp + i);
         }
         
@@ -82,7 +88,7 @@ public:
         assert(b.size == size);
         #endif
         
-        for (uint i = 0; i != 2*size+1; i++) {
+        for (uint32_t i = 0; i != 2*size+1; i++) {
             *(mp + i) ^= *(b.mp + i);
         }
         
@@ -90,13 +96,13 @@ public:
     }
     
     
-    uint popcnt() const;
-    uint popcnt(uint from) const;
+    uint32_t popcnt() const;
+    uint32_t popcnt(uint32_t from) const;
     
     bool popcnt_is_one() const
     {
         char popcount = 0;
-        for (uint i = 0; i != size; i++) {
+        for (uint32_t i = 0; i != size; i++) {
             uint64_t tmp = mp[i];
             while(tmp) {
                 popcount += tmp & 1;
@@ -106,7 +112,7 @@ public:
         return popcount == 1;
     }
     
-    bool popcnt_is_one(uint from) const
+    bool popcnt_is_one(uint32_t from) const
     {
         from++;
         
@@ -114,7 +120,7 @@ public:
         tmp >>= from%64;
         if (tmp) return false;
         
-        for (uint i = from/64+1; i != size; i++)
+        for (uint32_t i = from/64+1; i != size; i++)
             if (mp[i]) return false;
         return true;
     }
@@ -126,7 +132,7 @@ public:
 
     inline const bool isZero() const
     {
-        for (uint i = 0; i != size; i++) {
+        for (uint32_t i = 0; i != size; i++) {
             if (mp[i]) return false;
         }
         return true;
@@ -137,17 +143,17 @@ public:
         memset(mp, 0, sizeof(uint64_t)*size);
     }
 
-    inline void clearBit(const uint i)
+    inline void clearBit(const uint32_t i)
     {
         mp[i/64] &= ~((uint64_t)1 << (i%64));
     }
 
     inline void invert_is_true(const bool b = true)
     {
-        is_true_internal ^= b;
+        is_true_internal ^= (uint64_t)b;
     }
 
-    inline void setBit(const uint i)
+    inline void setBit(const uint32_t i)
     {
         mp[i/64] |= ((uint64_t)1 << (i%64));
     }
@@ -163,7 +169,7 @@ public:
         uint64_t * __restrict mp1 = mp-1;
         uint64_t * __restrict mp2 = b.mp-1;
         
-        uint i = 2*(size+1);
+        uint32_t i = 2*(size+1);
         
         while(i != 0) {
             std::swap(*mp1, *mp2);
@@ -173,7 +179,7 @@ public:
         }
     }
 
-    inline const bool operator[](const uint& i) const
+    inline const bool operator[](const uint32_t& i) const
     {
         #ifdef DEBUG_ROW
         assert(size*64 > i);
@@ -183,14 +189,14 @@ public:
     }
 
     template<class T>
-    void set(const T& v, const vector<uint16_t>& var_to_col, const uint matrix_size)
+    void set(const T& v, const vector<uint16_t>& var_to_col, const uint32_t matrix_size)
     {
         assert(size == (matrix_size/64) + ((bool)(matrix_size % 64)));
         //mp = new uint64_t[size];
         setZero();
-        for (uint i = 0; i != v.size(); i++) {
-            const uint toset_var = var_to_col[v[i].var()];
-            assert(toset_var != UINT_MAX);
+        for (uint32_t i = 0; i != v.size(); i++) {
+            const uint32_t toset_var = var_to_col[v[i].var()];
+            assert(toset_var != std::numeric_limits<uint32_t>::max());
             
             setBit(toset_var);
         }
@@ -206,28 +212,29 @@ public:
         assert(size > 0);
         #endif
         
-        for(uint i = var; i != size*64; i++)
+        for(uint32_t i = var; i != size*64; i++)
             if (this->operator[](i)) return i;
-        return ULONG_MAX;
+            return std::numeric_limits<unsigned long int>::max();
     }
 
     friend std::ostream& operator << (std::ostream& os, const PackedRow& m);
 
-    PackedRow(const uint _size, uint64_t*  const _mp) :
-        size(_size)
-        , mp(_mp+1)
+private:
+    friend class PackedMatrix;
+    PackedRow(const uint32_t _size, uint64_t*  const _mp) :
+        mp(_mp+1)
         , is_true_internal(*_mp)
+        , size(_size)
     {}
-
-private:
-    friend class PackedMatrix;    
-    const uint size;
+    
     uint64_t* __restrict const mp;
     uint64_t& is_true_internal;
+    const uint32_t size;
 };
 
 std::ostream& operator << (std::ostream& os, const PackedRow& m);
-};
+
+}; //NAMESPACE MINISAT
 
 #endif //PACKEDROW_H
 
diff --git a/src/sat/cryptominisat2/PartFinder.cpp b/src/sat/cryptominisat2/PartFinder.cpp
new file mode 100644 (file)
index 0000000..5ab39cd
--- /dev/null
@@ -0,0 +1,185 @@
+/***********************************************************************************
+CryptoMiniSat -- Copyright (c) 2009 Mate Soos
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+**************************************************************************************************/
+
+#include "PartFinder.h"
+
+#include "Solver.h"
+#include "Gaussian.h"
+#include "GaussianConfig.h"
+#include "ClauseCleaner.h"
+#include "time_mem.h"
+#include "VarReplacer.h"
+
+#include <set>
+#include <map>
+#include <iomanip>
+#include <math.h>
+#include "FailedVarSearcher.h"
+using std::set;
+using std::map;
+
+//#define VERBOSE_DEBUG
+
+using std::cout;
+using std::endl;
+
+//#define PART_FINDING
+
+namespace MINISAT
+{
+using namespace MINISAT;
+
+PartFinder::PartFinder(Solver& _solver) :
+    solver(_solver)
+{
+}
+
+const bool PartFinder::findParts()
+{
+    assert(solver.performReplace);
+    
+    double time = cpuTime();
+    
+    table.clear();
+    table.resize(solver.nVars(), std::numeric_limits<uint32_t>::max());
+    reverseTable.clear();
+    part_no = 0;
+    
+    solver.clauseCleaner->removeAndCleanAll(true);
+    if (solver.ok == false) return false;
+    while (solver.varReplacer->getNewToReplaceVars() > 0) {
+        if (solver.performReplace && !solver.varReplacer->performReplace(true))
+            return false;
+        solver.clauseCleaner->removeAndCleanAll(true);
+        if (solver.ok == false) return false;
+    }
+    assert(solver.varReplacer->getClauses().size() == 0);
+    
+    addToPart(solver.clauses);
+    addToPart(solver.binaryClauses);
+    addToPart(solver.xorclauses);
+    
+    const uint parts = setParts();
+    
+    #ifndef NDEBUG
+    for (map<uint, vector<Var> >::const_iterator it = reverseTable.begin(); it != reverseTable.end(); it++) {
+        for (uint i2 = 0; i2 < it->second.size(); i2++) {
+            assert(table[(it->second)[i2]] == it->first);
+        }
+    }
+    #endif
+    
+    if (solver.verbosity >= 2 || (solver.verbosity >=1 && parts > 1)) {
+        std::cout << "c | Found parts: " << std::setw(10) <<  parts
+        << " time: " << std::setprecision(2) << std::setw(4) << cpuTime() - time
+        << " s" << std::setw(28) << " |" << std::endl;
+    }
+    
+    return true;
+}
+
+template<class T>
+void PartFinder::addToPart(const vec<T*>& cs)
+{
+    set<uint> tomerge;
+    vector<Var> newSet;
+    for (T* const* c = cs.getData(), * const*end = c + cs.size(); c != end; c++) {
+        if ((*c)->learnt()) continue;
+        tomerge.clear();
+        newSet.clear();
+        for (const Lit *l = (*c)->getData(), *end2 = l + (*c)->size(); l != end2; l++) {
+            if (table[l->var()] != std::numeric_limits<uint32_t>::max())
+                tomerge.insert(table[l->var()]);
+            else
+                newSet.push_back(l->var());
+        }
+        if (tomerge.size() == 1) {
+            //no trees to merge, only merge the clause into one tree
+            
+            const uint into = *tomerge.begin();
+            map<uint, vector<Var> >::iterator intoReverse = reverseTable.find(into);
+            for (uint i = 0; i < newSet.size(); i++) {
+                intoReverse->second.push_back(newSet[i]);
+                table[newSet[i]] = into;
+            }
+            continue;
+        }
+        
+        for (set<uint>::iterator it = tomerge.begin(); it != tomerge.end(); it++) {
+            newSet.insert(newSet.end(), reverseTable[*it].begin(), reverseTable[*it].end());
+            reverseTable.erase(*it);
+        }
+        
+        for (uint i = 0; i < newSet.size(); i++)
+            table[newSet[i]] = part_no;
+        reverseTable[part_no] = newSet;
+        part_no++;
+    }
+}
+
+const uint PartFinder::setParts()
+{
+    vector<uint> numClauseInPart(part_no, 0);
+    vector<uint> sumLitsInPart(part_no, 0);
+    
+    calcIn(solver.clauses, numClauseInPart, sumLitsInPart);
+    calcIn(solver.binaryClauses, numClauseInPart, sumLitsInPart);
+    calcIn(solver.xorclauses, numClauseInPart, sumLitsInPart);
+    uint parts = 0;
+    for (uint i = 0; i < numClauseInPart.size(); i++) {
+        if (sumLitsInPart[i] == 0) continue;
+        if (solver.verbosity >= 2 || ( solver.verbosity >= 1 && reverseTable.size() > 1) ) {
+            std::cout << "c | Found part " << std::setw(8) << i
+            << " vars: " << std::setw(10) << reverseTable[i].size()
+            << " clauses:" << std::setw(10) << numClauseInPart[i]
+            << " lits size:" << std::setw(10) << sumLitsInPart[i]  << std::endl;
+        }
+        parts++;
+    }
+    
+    if (parts > 1) {
+        #ifdef VERBOSE_DEBUG
+        for (map<uint, vector<Var> >::iterator it = reverseTable.begin(), end = reverseTable.end(); it != end; it++) {
+            cout << "-- set begin --" << endl;
+            for (vector<Var>::iterator it2 = it->second.begin(), end2 = it->second.end(); it2 != end2; it2++) {
+                cout << *it2 << ", ";
+            }
+            cout << "-------" << endl;
+        }
+        #endif
+    }
+    
+    return parts;
+}
+
+template<class T>
+void PartFinder::calcIn(const vec<T*>& cs, vector<uint>& numClauseInPart, vector<uint>& sumLitsInPart)
+{
+    for (T*const* c = cs.getData(), *const*end = c + cs.size(); c != end; c++) {
+        if ((*c)->learnt()) continue;
+        T& x = **c;
+        const uint part = table[x[0].var()];
+        assert(part < part_no);
+        
+        //for stats
+        numClauseInPart[part]++;
+        sumLitsInPart[part] += x.size();
+    }
+}
+
+}; //NAMESPACE MINISAT
diff --git a/src/sat/cryptominisat2/PartFinder.h b/src/sat/cryptominisat2/PartFinder.h
new file mode 100644 (file)
index 0000000..a3261d7
--- /dev/null
@@ -0,0 +1,98 @@
+/***********************************************************************************
+CryptoMiniSat -- Copyright (c) 2009 Mate Soos
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+**************************************************************************************************/
+
+#ifndef PARTFINDER_H
+#define PARTFINDER_H
+
+#include <vector>
+#include <map>
+#ifdef _MSC_VER
+#include <msvc/stdint.h>
+#else
+#include <stdint.h>
+#endif //_MSC_VER
+
+#include "Clause.h"
+
+namespace MINISAT
+{
+using namespace MINISAT;
+
+class Solver;
+
+using std::map;
+using std::vector;
+using std::pair;
+
+class PartFinder {
+    
+    public:
+        PartFinder(Solver& solver);
+        const bool findParts();
+        
+        const map<uint32_t, vector<Var> >& getReverseTable() const; // part->var
+        const uint32_t getVarPart(const Var var) const;
+        const vector<uint32_t>& getTable() const; //var -> part
+        const vector<Var>& getPartVars(const uint32_t part);
+    
+    private:
+        const uint setParts();
+        template<class T>
+        void addToPart(const vec<T*>& cs);
+        
+        struct mysorter
+        {
+            bool operator () (const pair<uint, uint>& left, const pair<uint, uint>& right)
+            {
+                return left.second < right.second;
+            }
+        };
+        
+        //const bool findParts(vector<Var>& xorFingerprintInMatrix, vector<XorClause*>& xorsInMatrix);
+        template<class T>
+        void calcIn(const vec<T*>& cs, vector<uint>& numClauseInPart, vector<uint>& sumLitsInPart);
+        
+        map<uint32_t, vector<Var> > reverseTable; //part -> vars
+        vector<uint32_t> table; //var -> part
+        uint32_t part_no;
+        
+        Solver& solver;
+};
+
+inline const map<uint32_t, vector<Var> >& PartFinder::getReverseTable() const
+{
+    return reverseTable;
+}
+
+inline const vector<Var>& PartFinder::getTable() const
+{
+    return table;
+}
+
+inline const uint32_t PartFinder::getVarPart(const Var var) const
+{
+    return table[var];
+}
+
+inline const vector<Var>& PartFinder::getPartVars(const uint32_t part)
+{
+    return reverseTable[part];
+}
+
+}; //NAMESPACE MINISAT
+
+#endif //PARTFINDER_H
diff --git a/src/sat/cryptominisat2/PartHandler.cpp b/src/sat/cryptominisat2/PartHandler.cpp
new file mode 100644 (file)
index 0000000..8fb9771
--- /dev/null
@@ -0,0 +1,305 @@
+/***********************************************************************************
+CryptoMiniSat -- Copyright (c) 2009 Mate Soos
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+**************************************************************************************************/
+
+#include "PartHandler.h"
+#include "VarReplacer.h"
+#include <iostream>
+#include <assert.h>
+
+//#define VERBOSE_DEBUG
+
+namespace MINISAT
+{
+using namespace MINISAT;
+
+PartHandler::PartHandler(Solver& s) :
+    solver(s)
+{
+}
+
+
+const bool PartHandler::handle()
+{
+    if (solver.performReplace == false)
+        return true;
+    
+    PartFinder partFinder(solver);
+    if (!partFinder.findParts())
+        return false;
+    
+    uint32_t num_parts = partFinder.getReverseTable().size();
+    if (num_parts == 1)
+        return true;
+    
+    map<uint32_t, vector<Var> > reverseTable = partFinder.getReverseTable();
+    assert(num_parts == partFinder.getReverseTable().size());
+    
+    vector<pair<uint32_t, uint32_t> > sizes;
+    for (map<uint32_t, vector<Var> >::iterator it = reverseTable.begin(); it != reverseTable.end(); it++)
+        sizes.push_back(std::make_pair(it->first, (uint32_t)it->second.size()));
+    
+    std::sort(sizes.begin(), sizes.end(), sort_pred());
+    assert(sizes.size() > 1);
+    
+    for (uint32_t it = 0; it < sizes.size()-1; it++) {
+        uint32_t part = sizes[it].first;
+        vector<Var> vars = reverseTable[part];
+        if (solver.verbosity >= 1)
+            std::cout << "c Solving part " << part << std::endl;
+        
+        Solver newSolver;
+        newSolver.mtrand.seed(solver.mtrand.randInt());
+        newSolver.random_var_freq = solver.random_var_freq;
+        newSolver.var_decay = solver.var_decay;
+        newSolver.verbosity = solver.verbosity;
+        newSolver.restrictedPickBranch = solver.restrictedPickBranch;
+        newSolver.greedyUnbound = solver.greedyUnbound;
+        newSolver.findNormalXors = solver.findNormalXors;
+        newSolver.findBinaryXors = solver.findBinaryXors;
+        newSolver.regularlyFindBinaryXors = solver.regularlyFindBinaryXors;
+        newSolver.conglomerateXors = solver.conglomerateXors;
+        newSolver.schedSimplification = solver.schedSimplification;
+        newSolver.performReplace = solver.performReplace;
+        newSolver.failedVarSearch = solver.failedVarSearch;
+        newSolver.gaussconfig.dontDisable = solver.gaussconfig.dontDisable;
+        newSolver.heuleProcess = solver.heuleProcess;
+        newSolver.doSubsumption = solver.doSubsumption;
+        newSolver.doPartHandler = solver.doPartHandler;
+        newSolver.fixRestartType = solver.fixRestartType;
+        newSolver.var_inc = solver.var_inc;
+        newSolver.polarity_mode = Solver::polarity_manual;
+        std::sort(vars.begin(), vars.end());
+        uint32_t i2 = 0;
+        for (Var var = 0; var < solver.nVars(); var++) {
+            if (i2 < vars.size() && vars[i2] == var) {
+                newSolver.newVar(solver.decision_var[var]);
+                newSolver.activity[var] = solver.activity[var];
+                newSolver.defaultPolarities[var] = solver.polarity[var];
+                newSolver.order_heap.update(var);
+                assert(partFinder.getVarPart(var) == part);
+                if (solver.decision_var[var]) {
+                    solver.setDecisionVar(var, false);
+                    if (solver.decision_var[var]) decisionVarRemoved.push(var);
+                }
+                i2++;
+            } else {
+                assert(partFinder.getVarPart(var) != part);
+                newSolver.newVar(false);
+            }
+        }
+        solver.order_heap.filter(Solver::VarFilter(solver));
+        
+        assert(solver.varReplacer->getClauses().size() == 0);
+        moveClauses(solver.clauses, newSolver, part, partFinder);
+        moveClauses(solver.binaryClauses, newSolver, part, partFinder);
+        moveClauses(solver.xorclauses, newSolver, part, partFinder);
+        moveLearntClauses(solver.binaryClauses, newSolver, part, partFinder);
+        moveLearntClauses(solver.learnts, newSolver, part, partFinder);
+        assert(checkClauseMovement(newSolver, part, partFinder));
+        
+        lbool status = newSolver.solve();
+        if (status == l_False)
+            return false;
+        assert(status != l_Undef);
+        
+        for (Var var = 0; var < newSolver.nVars(); var++) {
+            if (newSolver.model[var] != l_Undef) {
+                assert(solver.assigns[var] == l_Undef);
+            }
+        }
+        
+        assert(newSolver.decisionLevel() == 0);
+        for (uint32_t i = 0; i < newSolver.trail.size(); i++) {
+            solver.uncheckedEnqueue(newSolver.trail[i]);
+        }
+        solver.ok = (solver.propagate() == NULL);
+        assert(solver.ok);
+        
+        for (Var var = 0; var < newSolver.nVars(); var++) {
+            if (newSolver.model[var] != l_Undef) {
+                assert(savedState[var] == l_Undef);
+                assert(partFinder.getVarPart(var) == part);
+                savedState[var] = newSolver.model[var];
+            }
+        }
+        
+        if (solver.verbosity >= 1)
+            std::cout << "c Solved part" << std::endl;
+    }
+    if (solver.verbosity >= 1)
+        std::cout << "c Coming back to original instance" << std::endl;
+    
+    solver.order_heap.filter(Solver::VarFilter(solver));
+    
+    //Checking that all variables that are not in the remaining part are all non-decision vars, and none have been set
+    for (Var var = 0; var < solver.nVars(); var++) {
+        if (savedState[var] != l_Undef) {
+            assert(solver.decision_var[var] == false);
+            assert(solver.assigns[var] == l_Undef || solver.level[var] == 0);
+        }
+    }
+    
+    //Checking that all remaining clauses contain only variables that are in the remaining part
+    assert(checkClauseMovement(solver, sizes[sizes.size()-1].first, partFinder));
+    
+    return true;
+}
+
+const bool PartHandler::checkClauseMovement(const Solver& thisSolver, const uint32_t part, const PartFinder& partFinder) const
+{
+    if (!checkOnlyThisPart(thisSolver.clauses, part, partFinder))
+        return false;
+    if (!checkOnlyThisPart(thisSolver.learnts, part, partFinder))
+        return false;
+    if (!checkOnlyThisPart(thisSolver.binaryClauses, part, partFinder))
+        return false;
+    if (!checkOnlyThisPart(thisSolver.xorclauses, part, partFinder))
+        return false;
+    
+    return true;
+}
+
+template<class T>
+const bool PartHandler::checkOnlyThisPart(const vec<T*>& cs, const uint32_t part, const PartFinder& partFinder) const
+{
+    for(T * const*it = cs.getData(), * const*end = it + cs.size(); it != end; it++) {
+        const T& c = **it;
+        for(const Lit *l = c.getData(), *end2 = l + c.size(); l != end2; l++) {
+            if (partFinder.getVarPart(l->var()) != part) return false;
+        }
+    }
+    
+    return true;
+}
+
+void PartHandler::moveClauses(vec<Clause*>& cs, Solver& newSolver, const uint32_t part, PartFinder& partFinder)
+{
+    Clause **i, **j, **end;
+    for (i = j = cs.getData(), j = i , end = i + cs.size(); i != end; i++) {
+        if ((**i).learnt() || partFinder.getVarPart((**i)[0].var()) != part) {
+            *j++ = *i;
+            continue;
+        }
+        solver.detachClause(**i);
+        vec<Lit> cs((*i)->size());
+        std::copy((**i).getData(), (**i).getDataEnd(), cs.getData());
+        newSolver.addClause(cs, (**i).getGroup());
+        //NOTE: we need the CS because otherwise, the addClause could have changed **i, which we need to re-add later!
+        clausesRemoved.push(*i);
+    }
+    cs.shrink(i-j);
+}
+
+void PartHandler::moveClauses(vec<XorClause*>& cs, Solver& newSolver, const uint32_t part, PartFinder& partFinder)
+{
+    XorClause **i, **j, **end;
+    for (i = j = cs.getData(), end = i + cs.size(); i != end; i++) {
+        if (partFinder.getVarPart((**i)[0].var()) != part) {
+            *j++ = *i;
+            continue;
+        }
+        solver.detachClause(**i);
+        vec<Lit> cs((*i)->size());
+        for (uint32_t i2 = 0; i2 < (*i)->size(); i2++)
+            cs[i2] = (**i)[i2].unsign();
+        newSolver.addXorClause(cs, (**i).xor_clause_inverted(), (**i).getGroup());
+        //NOTE: we need the CS because otherwise, the addXorClause could have changed **i, which we need to re-add later!
+        xorClausesRemoved.push(*i);
+    }
+    cs.shrink(i-j);
+}
+
+void PartHandler::moveLearntClauses(vec<Clause*>& cs, Solver& newSolver, const uint32_t part, PartFinder& partFinder)
+{
+    Clause **i, **j, **end;
+    for (i = j = cs.getData(), end = i + cs.size() ; i != end; i++) {
+        if (!(**i).learnt()) {
+            *j++ = *i;
+            continue;
+        }
+        
+        Clause& c = **i;
+        assert(c.size() > 0);
+        uint32_t clause_part = partFinder.getVarPart(c[0].var());
+        bool removed = false;
+        for (const Lit* l = c.getData(), *end = l + c.size(); l != end; l++) {
+            if (partFinder.getVarPart(l->var()) != clause_part) {
+                #ifdef VERBOSE_DEBUG
+                std::cout << "Learnt clause in both parts!" << std::endl;
+                #endif
+                
+                removed = true;
+                solver.removeClause(c);
+                break;
+            }
+        }
+        if (removed) continue;
+        if (clause_part == part) {
+            #ifdef VERBOSE_DEBUG
+            std::cout << "Learnt clause in this part!" << std::endl;
+            #endif
+            
+            solver.detachClause(c);
+            newSolver.addLearntClause(c, c.getGroup(), c.activity());
+            free(*i);
+        } else {
+            #ifdef VERBOSE_DEBUG
+            std::cout << "Learnt clause in other part!" << std::endl;
+            #endif
+            
+            *j++ = *i;
+        }
+    }
+    cs.shrink(i-j);
+}
+
+void PartHandler::addSavedState()
+{
+    for (Var var = 0; var < savedState.size(); var++) {
+        if (savedState[var] != l_Undef) {
+            assert(solver.assigns[var] == l_Undef || (solver.assigns[var] == savedState[var] && solver.level[var] == 0));
+            //decision level should NOT be 0.... TODO
+            solver.uncheckedEnqueue(Lit(var, savedState[var] == l_False));
+            assert(solver.assigns[var] == savedState[var]);
+            savedState[var] = l_Undef;
+        }
+    }
+    
+    for (uint32_t var = 0; var < decisionVarRemoved.size(); var++)
+        solver.setDecisionVar(var, true);
+    decisionVarRemoved.clear();
+}
+
+void PartHandler::readdRemovedClauses()
+{
+    for (Clause **it = clausesRemoved.getData(), **end = clausesRemoved.getDataEnd(); it != end; it++) {
+        solver.addClause(**it, (*it)->getGroup());
+        assert(solver.ok);
+    }
+    clausesRemoved.clear();
+    
+    for (XorClause **it = xorClausesRemoved.getData(), **end = xorClausesRemoved.getDataEnd(); it != end; it++) {
+        for (Lit *l = (*it)->getData(), *end2 = (*it)->getDataEnd(); l != end2; l++) {
+            *l = l->unsign();
+        }
+        solver.addXorClause(**it, (*it)->getGroup());
+        assert(solver.ok);
+    }
+    xorClausesRemoved.clear();
+}
+
+}; //NAMESPACE MINISAT
diff --git a/src/sat/cryptominisat2/PartHandler.h b/src/sat/cryptominisat2/PartHandler.h
new file mode 100644 (file)
index 0000000..a1fe6c1
--- /dev/null
@@ -0,0 +1,82 @@
+/***********************************************************************************
+CryptoMiniSat -- Copyright (c) 2009 Mate Soos
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+**************************************************************************************************/
+
+#ifndef PARTHANDLER_H
+#define PARTHANDLER_H
+
+#include "Solver.h"
+#include "PartFinder.h"
+#include "Vec.h"
+#include "SolverTypes.h"
+
+#include <map>
+#include <vector>
+using std::map;
+using std::vector;
+using std::pair;
+
+namespace MINISAT
+{
+using namespace MINISAT;
+
+class PartHandler
+{
+    public:
+        PartHandler(Solver& solver);
+        const bool handle();
+        const vec<lbool>& getSavedState();
+        void newVar();
+        void addSavedState();
+        void readdRemovedClauses();
+        
+    private:
+        struct sort_pred {
+            bool operator()(const std::pair<int,int> &left, const std::pair<int,int> &right) {
+                return left.second < right.second;
+            }
+        };
+        
+        //For moving clauses
+        void moveClauses(vec<XorClause*>& cs, Solver& newSolver, const uint32_t part, PartFinder& partFinder);
+        void moveClauses(vec<Clause*>& cs, Solver& newSolver, const uint32_t part, PartFinder& partFinder);
+        void moveLearntClauses(vec<Clause*>& cs, Solver& newSolver, const uint32_t part, PartFinder& partFinder);
+        
+        //Checking moved clauses
+        const bool checkClauseMovement(const Solver& thisSolver, const uint32_t part, const PartFinder& partFinder) const;
+        template<class T>
+        const bool checkOnlyThisPart(const vec<T*>& cs, const uint32_t part, const PartFinder& partFinder) const;
+        
+        Solver& solver;
+        vec<lbool> savedState;
+        vec<Var> decisionVarRemoved; //variables whose decision-ness has been removed
+        vec<Clause*> clausesRemoved;
+        vec<XorClause*> xorClausesRemoved;
+};
+
+inline const vec<lbool>& PartHandler::getSavedState()
+{
+    return savedState;
+}
+
+inline void PartHandler::newVar()
+{
+    savedState.push(l_Undef);
+}
+
+}; //NAMESPACE MINISAT
+
+#endif //PARTHANDLER_H
index 0509b34a4d8fe70026bdcf92374d6860eef66ecf..9130a1d2e0de26d52d1e8aa1a74f4db808471cbb 100644 (file)
@@ -19,19 +19,20 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #include "Solver.h"
 
 //#define VERBOSE_DEBUG
+//#define PRINT_VARS
 
 namespace MINISAT
 {
 using namespace MINISAT;
 
-RestartTypeChooser::RestartTypeChooser(const Solver* const _s) :
-    S(_s)
+RestartTypeChooser::RestartTypeChooser(const Solvers) :
+    solver(s)
     , topX(100)
-    , limit(30)
+    , limit(40)
 {
 }
 
-const RestartType RestartTypeChooser::choose()
+void RestartTypeChooser::addInfo()
 {
     firstVarsOld = firstVars;
     calcHeap();
@@ -46,14 +47,17 @@ const RestartType RestartTypeChooser::choose()
         std::cout << "    Same vars in first&second first 100: " << sameIn << std::endl;
         #endif
         sameIns.push_back(sameIn);
-    } else
-        return static_restart;
+    }
     
     #ifdef VERBOSE_DEBUG
-    std::cout << "Avg same vars in first&second first 100: " << avg() << std::endl;
+    std::cout << "Avg same vars in first&second first 100: " << avg() << " standard Deviation:" << stdDeviation(sameIns) <<std::endl;
     #endif
-    
-    if (avg() > (double)limit)
+}
+
+const RestartType RestartTypeChooser::choose()
+{
+    if (countVarsDegreeStDev().second  < 80 &&
+        (avg() > (double)limit || ((avg() > (double)(limit*0.9) && stdDeviation(sameIns) < 5))))
         return static_restart;
     else
         return dynamic_restart;
@@ -67,24 +71,79 @@ const double RestartTypeChooser::avg() const
     return (sum/(double)sameIns.size());
 }
 
+const double RestartTypeChooser::stdDeviation(vector<uint32_t>& measure) const
+{
+    double average = avg();
+    double variance = 0.0;
+    for (uint i = 0; i != measure.size(); i++)
+        variance += pow((double)measure[i]-average, 2);
+    variance /= (double)measure.size();
+    
+    return sqrt(variance);
+}
+
 void RestartTypeChooser::calcHeap()
 {
     firstVars.clear();
     firstVars.reserve(topX);
-    #ifdef VERBOSE_DEBUG
+    #ifdef PRINT_VARS
     std::cout << "First vars:" << std::endl;
     #endif
-    Heap<Solver::VarOrderLt> tmp(S->order_heap);
+    Heap<Solver::VarOrderLt> tmp(solver.order_heap);
     uint32_t thisTopX = std::min(tmp.size(), topX);
     for (uint32_t i = 0; i != thisTopX; i++) {
-        #ifdef VERBOSE_DEBUG
+        #ifdef PRINT_VARS
         std::cout << tmp.removeMin()+1 << ", ";
         #endif
         firstVars.push_back(tmp.removeMin());
     }
-    #ifdef VERBOSE_DEBUG
+    #ifdef PRINT_VARS
     std::cout << std::endl;
     #endif
 }
 
-};
+const std::pair<double, double> RestartTypeChooser::countVarsDegreeStDev() const
+{
+    vector<uint32_t> degrees;
+    degrees.resize(solver.nVars(), 0);
+    addDegrees(solver.clauses, degrees);
+    addDegrees(solver.binaryClauses, degrees);
+    addDegrees(solver.xorclauses, degrees);
+    uint32_t sum = 0;
+    uint32_t *i = &degrees[0], *j = i;
+    for (uint32_t *end = i + degrees.size(); i != end; i++) {
+        if (*i != 0) {
+            sum += *i;
+            *j++ = *i;
+        }
+    }
+    degrees.resize(degrees.size() - (i-j));
+    
+    double avg = (double)sum/(double)degrees.size();
+    double stdDev = stdDeviation(degrees);
+    
+    #ifdef VERBOSE_DEBUG
+    std::cout << "varsDegree avg:" << avg << " stdDev:" << stdDev << std::endl;
+    #endif
+    
+    return std::make_pair(avg, stdDev);
+}
+
+template<class T>
+void RestartTypeChooser::addDegrees(const vec<T*>& cs, vector<uint32_t>& degrees) const
+{
+    for (T * const*c = cs.getData(), * const*end = c + cs.size(); c != end; c++) {
+        T& cl = **c;
+        if (cl.learnt()) continue;
+        
+        for (const Lit *l = cl.getData(), *end2 = l + cl.size(); l != end2; l++) {
+            degrees[l->var()]++;
+        }
+    }
+}
+
+template void RestartTypeChooser::addDegrees(const vec<Clause*>& cs, vector<uint32_t>& degrees) const;
+template void RestartTypeChooser::addDegrees(const vec<XorClause*>& cs, vector<uint32_t>& degrees) const;
+
+}; //NAMESPACE MINISAT
+
index b328225f76c94489a8dccf8d00b079b37981cd1a..4c0628d481520f5c4c141e921ad89414972efc14 100644 (file)
@@ -18,27 +18,42 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #ifndef RESTARTTYPECHOOSER_H
 #define RESTARTTYPECHOOSER_H
 
-#include "SolverTypes.h"
+#include "Solver.h"
 #include <vector>
-#include <sys/types.h>
+#ifdef _MSC_VER
+#include <msvc/stdint.h>
+#else
+#include <stdint.h>
+#endif //_MSC_VER
+
+#include "SolverTypes.h"
+
 using std::vector;
 
 namespace MINISAT
 {
+using namespace MINISAT;
 
 class Solver;
 
 class RestartTypeChooser
 {
     public:
-        RestartTypeChooser(const Solver* const S);
+        RestartTypeChooser(const Solver& s);
+        void addInfo();
         const RestartType choose();
+        void reset();
         
     private:
         void calcHeap();
         const double avg() const;
+        const std::pair<double, double> countVarsDegreeStDev() const;
+        const double stdDeviation(vector<uint32_t>& measure) const;
         
-        const Solver* const S;
+        template<class T>
+        void addDegrees(const vec<T*>& cs, vector<uint32_t>& degrees) const;
+        
+        const Solver& solver;
         const uint32_t topX;
         const uint32_t limit;
         vector<Var> sameIns;
@@ -46,6 +61,11 @@ class RestartTypeChooser
         vector<Var> firstVars, firstVarsOld;
 };
 
-};
+inline void RestartTypeChooser::reset()
+{
+    sameIns.clear();
+}
+
+}; //NAMESPACE MINISAT
 
 #endif //RESTARTTYPECHOOSER_H
diff --git a/src/sat/cryptominisat2/SmallPtr.cpp b/src/sat/cryptominisat2/SmallPtr.cpp
new file mode 100644 (file)
index 0000000..6fca7bc
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+Please see LICENSE-CPOL.html in the root directory for the licencing of this file.
+Originally by: cppnow
+Link: http://www.codeproject.com/KB/cpp/smallptr.aspx
+*/
+
+#include "SmallPtr.h"
+
+namespace MINISAT
+{
+using namespace MINISAT;
+
+uintptr_t sptr_base::_segs = 1;
+//boost::mutex sptr_base::_m;
+uintptr_t sptr_base::_seg_map[sptr_base::ALIGNMENT] = { 0 };
+
+}; //NAMESPACE MINISAT
diff --git a/src/sat/cryptominisat2/SmallPtr.h b/src/sat/cryptominisat2/SmallPtr.h
new file mode 100644 (file)
index 0000000..a530c54
--- /dev/null
@@ -0,0 +1,277 @@
+/*
+Please see LICENSE-CPOL.html in the root directory for the licencing of this file.
+Originally by: cppnow
+Link: http://www.codeproject.com/KB/cpp/smallptr.aspx
+*/
+
+#ifndef __SMALL_PTR_H__
+#define __SMALL_PTR_H__
+
+//#include <boost/static_assert.hpp>
+
+#include <cstring>
+#include <stdlib.h>
+#include "singleton.hpp"
+//#include <boost/thread/mutex.hpp>
+//#include <boost/thread/locks.hpp>
+
+#ifdef _MSC_VER
+#include <msvc/stdint.h>
+#else
+#include <stdint.h>
+#endif //_MSC_VER
+
+#define is_n_aligned(T, N) ((sizeof(T) % (N)) == 0)
+
+#ifdef WIN32
+#  ifdef WIN64
+#    define USE64
+#  else
+#    define USE32
+#  endif
+#endif
+
+#ifdef __GNUG__
+#  if defined(__amd64__) || defined(__x86_64__)
+#    define USE64
+#  elif defined(__i386__)
+#    define USE32
+#  endif
+#endif
+
+#include <exception>
+
+namespace MINISAT
+{
+using namespace MINISAT;
+
+class bad_alignment : public std::exception
+{
+public:
+    bad_alignment(const char *const& w)  {}
+};
+class bad_segment : public std::exception
+{
+public:
+    bad_segment(const char *const& w)  {}
+};
+
+class sptr_base
+{   
+protected:
+    static const uint32_t ALIGNMENT_BITS = 2;
+    static const uint32_t ALIGNMENT = (1<<ALIGNMENT_BITS);
+    static const uintptr_t ALIGNMENT_MASK = ALIGNMENT - 1;
+
+protected:
+    static uintptr_t     _seg_map[ALIGNMENT];
+    static uintptr_t     _segs;
+    //static boost::mutex  _m;
+
+    inline static uintptr_t ptr2seg(uintptr_t p)
+    {
+        p &= ~0xFFFFFFFFULL; // Keep only high part
+        uintptr_t s = _segs;
+        uintptr_t i = 0;
+        for (; i < s; ++i)
+            if (_seg_map[i] == p)
+                return i;
+
+        // Not found - now we do it the "right" way (mutex and all)
+        //boost::lock_guard<boost::mutex> lock(_m);
+        for (i = 0; i < s; ++i)
+            if (_seg_map[i] == p)
+                return i;
+
+        i = _segs++;
+        if (_segs > ALIGNMENT) {
+            //throw bad_segment("Segment out of range");
+            exit(-1);
+        }
+
+        _seg_map[i] = p;
+        return i;
+    }
+
+};
+
+template<class TYPE>
+class sptr : public sptr_base
+{
+public:
+    typedef TYPE  type;
+    typedef TYPE* native_pointer_type;
+    typedef const TYPE* const_native_pointer_type;
+
+    sptr() throw()
+        : _ptr(0)
+    {}
+
+    // Copy constructor
+    sptr(const sptr<TYPE>& o) throw() 
+        : _ptr(o._ptr)
+    {
+    }
+
+    // Copy from a related pointer type
+    // Although just copying _ptr would be more efficient - it may
+    // also be wrong - e.g. multiple inheritence
+    template<class O>
+    sptr(const sptr<O>& o)
+        : _ptr(encode(static_cast<TYPE*>(o.get())))
+    {
+    }
+
+    template<class O>
+    sptr(const O* p)
+        : _ptr(encode(static_cast<const TYPE*>(p)))
+    {
+    }
+
+    sptr<TYPE>& operator=(const sptr<TYPE>& o) throw()
+    {
+        _ptr = o._ptr;
+        return *this;
+    }
+
+    template<class O>
+    sptr<TYPE>& operator=(const sptr<O>& o)
+    {
+        _ptr = encode(static_cast<const TYPE*>(o.get()));
+        return *this;
+    }
+
+private:
+    inline uint32_t encode(const_native_pointer_type ptr) const
+    {
+#ifdef USE64
+
+        uintptr_t p = reinterpret_cast<uintptr_t>(ptr);
+
+        if ((p & ALIGNMENT_MASK) != 0) {
+            //throw bad_alignment("Pointer is not aligned");
+            exit(-1);
+        }
+
+        return (uint32_t)(ptr2seg(p) + p);
+    
+#else // 32 bit machine
+        return reinterpret_cast<uint32_t>(ptr);
+#endif
+    }
+
+    inline native_pointer_type decode(uint32_t e) const
+    {
+#ifdef USE64
+        uintptr_t el = e;
+        uintptr_t ptr = (_seg_map[el & ALIGNMENT_MASK] + el) & ~ALIGNMENT_MASK;
+
+        return reinterpret_cast<native_pointer_type>(ptr);
+#else
+        return reinterpret_cast<native_pointer_type>(e);
+#endif
+    }
+
+    void check_alignment() const
+    {
+        //BOOST_STATIC_ASSERT(is_n_aligned(TYPE, ALIGNMENT));
+    }
+
+    void inc_sptr(uint32_t& e, uintptr_t offset = 1)
+    {
+        check_alignment();
+#ifdef USE64
+        uintptr_t el = e;
+        uintptr_t seg = el & ALIGNMENT_MASK;
+        el += offset*ALIGNMENT;
+
+        // check for overflow
+        if (el > 0xFFFFFFFFULL)
+            return encode(decode(e)+1);
+        e = (uint32_t)el;
+#else
+        e+= (uint32_t)offset;
+#endif
+    }
+
+    void dec_sptr(uint32_t& e, size_t offset = 1)
+    {
+        check_alignment();
+#ifdef USE64
+        uintptr_t el = e;
+        uintptr_t seg = el & ALIGNMENT_MASK;
+        e-= offset*ALIGNMENT;
+
+        // check for underflow
+        if (el > 0xFFFFFFFFULL)
+            return encode(decode(e)-1);
+        e = (uint32_t)el;
+#else
+        e -= (uint32_t)offset;
+#endif
+    }
+public:
+
+    TYPE* get() const throw() { return decode(_ptr); }
+
+    // Pointer operators
+
+    TYPE& operator*() { return *decode(_ptr); }
+    const TYPE& operator*() const { return *decode(_ptr); }
+
+    TYPE* operator->() { return decode(_ptr); }
+    const TYPE* operator->() const { return decode(_ptr); }
+
+    template<class O>
+    bool operator==(const sptr<O>& o) const
+    {
+        return o._ptr == this->_ptr;
+    }
+
+    operator TYPE*() const { return get(); }
+
+    sptr<TYPE>& operator++( )
+    {
+        inc_sptr(_ptr);
+        return *this;
+    }
+
+    sptr<TYPE> operator++( int )
+    {
+        sptr<TYPE> p = *this;
+        inc_sptr(_ptr);
+        return p;
+    }
+
+    sptr<TYPE>& operator--( )
+    {
+        dec_sptr(_ptr);
+        return *this;
+    }
+    sptr<TYPE> operator--( int )
+    {
+        sptr<TYPE> p = *this;
+        dec_sptr(_ptr);
+        return p;
+    }
+
+    sptr<TYPE>& operator+=(size_t offset)
+    {
+        inc_sptr(_ptr, offset);
+        return *this;
+    }
+
+    sptr<TYPE>& operator-=(size_t offset)
+    {
+        dec_sptr(_ptr, offset);
+        return *this;
+    }
+
+private:
+    uint32_t _ptr;
+};
+
+}; //NAMESPACE MINISAT
+
+#endif
+
index e27a86d702d711a136cfd2859a08eb63dcbd35dd..b98ef366f179476197cf8ce6a350ceb3bbd294ae 100644 (file)
@@ -25,10 +25,11 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
 #include <algorithm>
 #include <limits.h>
 #include <vector>
-#include <time.h>
+#include <iomanip>
 
 #include "Clause.h"
 #include "time_mem.h"
+
 #include "VarReplacer.h"
 #include "FindUndef.h"
 #include "Gaussian.h"
@@ -37,6 +38,18 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
 #include "XorFinder.h"
 #include "ClauseCleaner.h"
 #include "RestartTypeChooser.h"
+#include "FailedVarSearcher.h"
+#include "Subsumer.h"
+#include "PartHandler.h"
+#include "XorSubsumer.h"
+
+#ifdef _MSC_VER
+#define __builtin_prefetch(a,b,c)
+//#define __builtin_prefetch(a,b)
+#endif //_MSC_VER
+
+//#define VERBOSE_DEBUG_POLARITIES
+//#define DEBUG_DYNAMIC_RESTART
 
 namespace MINISAT
 {
@@ -54,27 +67,40 @@ Solver::Solver() :
         // More parameters:
         //
         , expensive_ccmin  (true)
-        , polarity_mode    (polarity_user)
+        , polarity_mode    (polarity_auto)
         , verbosity        (0)
         , restrictedPickBranch(0)
-        , xorFinder        (true)
+        , findNormalXors   (true)
+        , findBinaryXors   (true)
+        , regularlyFindBinaryXors(true)
         , performReplace   (true)
+        , conglomerateXors (true)
+        , heuleProcess     (true)
+        , schedSimplification(true)
+        , doSubsumption    (true)
+        , doXorSubsumption (true)
+        , doPartHandler    (true)
+        , doHyperBinRes    (true)
+        , doBlockedClause  (true)
+        , failedVarSearch  (true)
+        , libraryUsage     (true)
         , greedyUnbound    (false)
         , fixRestartType   (auto_restart)
 
         // Statistics: (formerly in 'SolverStats')
         //
-        , starts(0), decisions(0), rnd_decisions(0), propagations(0), conflicts(0)
+        , starts(0), dynStarts(0), staticStarts(0), fullStarts(0), decisions(0), rnd_decisions(0), propagations(0), conflicts(0)
         , clauses_literals(0), learnts_literals(0), max_literals(0), tot_literals(0)
-        , nbDL2(0), nbBin(0), lastNbBin(0), nbReduceDB(0)
+        , nbDL2(0), nbBin(0), lastNbBin(0), becameBinary(0), lastSearchForBinaryXor(0), nbReduceDB(0)
+        , improvedClauseNo(0), improvedClauseSize(0)
         
 
         , ok               (true)
         , var_inc          (1)
         
         , curRestart       (1)
-        , conf4Stats       (0)
         , nbclausesbeforereduce (NBCLAUSESBEFOREREDUCE)
+        , nbCompensateSubsumer (0)
         
         , qhead            (0)
         , simpDB_assigns   (-1)
@@ -83,7 +109,6 @@ Solver::Solver() :
         , progress_estimate(0)
         , remove_satisfied (true)
         , mtrand((unsigned long int)0)
-       //, mtrand((unsigned long int)time(NULL))
         , restartType      (static_restart)
         #ifdef STATS_NEEDED
         , logger(verbosity)
@@ -93,10 +118,15 @@ Solver::Solver() :
         , MYFLAG           (0)
         , learnt_clause_group(0)
         , libraryCNFFile   (NULL)
+        , simplifying      (false)
 {
-    varReplacer = new VarReplacer(this);
-    conglomerate = new Conglomerate(this);
+    varReplacer = new VarReplacer(*this);
+    conglomerate = new Conglomerate(*this);
     clauseCleaner = new ClauseCleaner(*this);
+    failedVarSearcher = new FailedVarSearcher(*this);
+    partHandler = new PartHandler(*this);
+    subsumer = new Subsumer(*this);
+    restartTypeChooser = new RestartTypeChooser(*this);
     
     #ifdef STATS_NEEDED
     logger.setSolver(this);
@@ -105,14 +135,19 @@ Solver::Solver() :
 
 Solver::~Solver()
 {
-    for (uint32_t i = 0; i != learnts.size(); i++) free(learnts[i]);
-    for (uint32_t i = 0; i != clauses.size(); i++) free(clauses[i]);
+    for (uint32_t i = 0; i != learnts.size(); i++) clauseFree(learnts[i]);
+    for (uint32_t i = 0; i != clauses.size(); i++) clauseFree(clauses[i]);
+    for (uint32_t i = 0; i != binaryClauses.size(); i++) clauseFree(binaryClauses[i]);
     for (uint32_t i = 0; i != xorclauses.size(); i++) free(xorclauses[i]);
     clearGaussMatrixes();
     for (uint32_t i = 0; i != freeLater.size(); i++) free(freeLater[i]);
     delete varReplacer;
     delete conglomerate;
     delete clauseCleaner;
+    delete failedVarSearcher;
+    delete partHandler;
+    delete subsumer;
+    delete restartTypeChooser;
     
     if (libraryCNFFile)
         fclose(libraryCNFFile);
@@ -124,7 +159,7 @@ Solver::~Solver()
 
 // Creates a new SAT variable in the solver. If 'decision_var' 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)
+Var Solver::newVar(bool dvar)
 {
     Var v = nVars();
     watches   .push();          // (list for positive literal)
@@ -132,17 +167,24 @@ Var Solver::newVar(bool sign, bool dvar)
     binwatches.push();          // (list for positive literal)
     binwatches.push();          // (list for negative literal)
     xorwatches.push();          // (list for variables in xors)
-    reason    .push(NULL);
+    reason    .push((Clause*)NULL);
     assigns   .push(l_Undef);
     level     .push(-1);
     activity  .push(0);
-    seen      .push(0);
+    seen      .push_back(0);
+    seen      .push_back(0);
     permDiff  .push(0);
-    polarity  .push_back((char)sign);
+    
+    polarity  .push_back(true);
+    defaultPolarities.push_back(true);
 
     decision_var.push_back(dvar);
+    insertVarOrder(v);
+    
     varReplacer->newVar();
     conglomerate->newVar();
+    partHandler->newVar();
+    subsumer->newVar();
 
     insertVarOrder(v);
     
@@ -157,39 +199,16 @@ Var Solver::newVar(bool sign, bool dvar)
     return v;
 }
 
-bool Solver::addXorClause(vec<Lit>& ps, bool xor_clause_inverted, const uint group, char* group_name, const bool internal)
+template<class T>
+XorClause* Solver::addXorClauseInt(T& ps, bool xor_clause_inverted, const uint32_t group)
 {
-    assert(decisionLevel() == 0);
-    if (libraryCNFFile && !internal) {
-        fprintf(libraryCNFFile, "x");
-        for (uint i = 0; i < ps.size(); i++) {
-            fprintf(libraryCNFFile, "%s%d ", ps[i].sign() ? "-" : "", ps[i].var()+1);
-        }
-        fprintf(libraryCNFFile, "0\n");
-    }
-    
-    #ifdef STATS_NEEDED
-    if (dynamic_behaviour_analysis)
-        logger.set_group_name(group, group_name);
-    #endif
-
-    if (!ok)
-        return false;
-
-    // Check if clause is satisfied and remove false/duplicate literals:
-    if (varReplacer->getNumLastReplacedVars()) {
-        for (uint32_t i = 0; i != ps.size(); i++) {
-            ps[i] = varReplacer->getReplaceTable()[ps[i].var()] ^ ps[i].sign();
-        }
-    }
-    
     std::sort(ps.getData(), ps.getData()+ps.size());
     Lit p;
     uint32_t i, j;
     for (i = j = 0, p = lit_Undef; i != ps.size(); i++) {
         xor_clause_inverted ^= ps[i].sign();
         ps[i] ^= ps[i].sign();
-
+        
         if (ps[i] == p) {
             //added, but easily removed
             j--;
@@ -201,48 +220,51 @@ bool Solver::addXorClause(vec<Lit>& ps, bool xor_clause_inverted, const uint gro
         else //modify xor_clause_inverted instead of adding
             xor_clause_inverted ^= (assigns[ps[i].var()].getBool());
     }
-    ps.shrink_(i - j);
-
+    ps.shrink(i - j);
+    
     switch(ps.size()) {
-    case 0: {
-        if (xor_clause_inverted)
-            return true;
-        return ok = false;
-    }
-    case 1: {
-        assert(assigns[ps[0].var()].isUndef());
-        uncheckedEnqueue(ps[0] ^ xor_clause_inverted);
-        return ok = (propagate() == NULL);
-    }
-    case 2: {
-        #ifdef VERBOSE_DEBUG
-        cout << "--> xor is 2-long, replacing var " << ps[0].var()+1 << " with " << (!xor_clause_inverted ? "-" : "") << ps[1].var()+1 << endl;
-        #endif
-        
-        varReplacer->replace(ps, xor_clause_inverted, group);
-        break;
-    }
-    default: {
-        learnt_clause_group = std::max(group+1, learnt_clause_group);
-        XorClause* c = XorClause_new(ps, xor_clause_inverted, group);
-        
-        xorclauses.push(c);
-        attachClause(*c);
-        if (!internal)
-            varReplacer->newClause();
-        break;
-    }
+        case 0: {
+            if (!xor_clause_inverted) ok = false;
+            return NULL;
+        }
+        case 1: {
+            assert(assigns[ps[0].var()].isUndef());
+            uncheckedEnqueue(ps[0] ^ xor_clause_inverted);
+            ok = (propagate() == NULL);
+            return NULL;
+        }
+        case 2: {
+            #ifdef VERBOSE_DEBUG
+            cout << "--> xor is 2-long, replacing var " << ps[0].var()+1 << " with " << (!xor_clause_inverted ? "-" : "") << ps[1].var()+1 << endl;
+            #endif
+            
+            varReplacer->replace(ps, xor_clause_inverted, group);
+            return NULL;
+        }
+        default: {
+            learnt_clause_group = std::max(group+1, learnt_clause_group);
+            XorClause* c = XorClause_new(ps, xor_clause_inverted, group);
+            attachClause(*c);
+            return c;
+        }
     }
-
-    return true;
 }
 
-bool Solver::addClause(vec<Lit>& ps, const uint group, char* group_name)
+template XorClause* Solver::addXorClauseInt(vec<Lit>& ps, bool xor_clause_inverted, const uint32_t group);
+template XorClause* Solver::addXorClauseInt(XorClause& ps, bool xor_clause_inverted, const uint32_t group);
+
+template<class T>
+bool Solver::addXorClause(T& ps, bool xor_clause_inverted, const uint group, char* group_name)
 {
     assert(decisionLevel() == 0);
+    if (ps.size() > (0x01UL << 18)) {
+        std::cout << "Too long clause!" << std::endl;
+        exit(-1);
+    }
     
     if (libraryCNFFile) {
-        for (uint32_t i = 0; i != ps.size(); i++) {
+        fprintf(libraryCNFFile, "x");
+        for (uint i = 0; i < ps.size(); i++) {
             fprintf(libraryCNFFile, "%s%d ", ps[i].sign() ? "-" : "", ps[i].var()+1);
         }
         fprintf(libraryCNFFile, "0\n");
@@ -255,43 +277,127 @@ bool Solver::addClause(vec<Lit>& ps, const uint group, char* group_name)
 
     if (!ok)
         return false;
+    assert(qhead == trail.size());
 
     // Check if clause is satisfied and remove false/duplicate literals:
-    if (varReplacer->getNumLastReplacedVars()) {
+    if (varReplacer->getNumLastReplacedVars() || subsumer->getNumElimed()) {
         for (uint32_t i = 0; i != ps.size(); i++) {
             ps[i] = varReplacer->getReplaceTable()[ps[i].var()] ^ ps[i].sign();
+            if (subsumer->getVarElimed()[ps[i].var()] && !subsumer->unEliminate(ps[i].var()))
+                return false;
         }
     }
     
+    XorClause* c = addXorClauseInt(ps, xor_clause_inverted, group);
+    if (c != NULL) xorclauses.push(c);
+
+    return ok;
+}
+
+template bool Solver::addXorClause(vec<Lit>& ps, bool xor_clause_inverted, const uint group, char* group_name);
+template bool Solver::addXorClause(XorClause& ps, bool xor_clause_inverted, const uint group, char* group_name);
+
+
+template<class T>
+bool Solver::addLearntClause(T& ps, const uint group, const uint32_t activity)
+{
+    Clause* c = addClauseInt(ps, group);
+    if (c == NULL)
+        return ok;
+    
+    clauses_literals -= c->size();
+    
+    c->makeLearnt(activity);
+    learnts.push(c);
+    learnts_literals += c->size();
+    return ok;
+}
+template bool Solver::addLearntClause(Clause& ps, const uint group, const uint32_t activity);
+template bool Solver::addLearntClause(vec<Lit>& ps, const uint group, const uint32_t activity);
+
+template <class T>
+Clause* Solver::addClauseInt(T& ps, uint group)
+{
+    assert(ok);
+    
     std::sort(ps.getData(), ps.getData()+ps.size());
-    Lit p;
+    Lit p = lit_Undef;
     uint32_t i, j;
-    for (i = j = 0, p = lit_Undef; i != ps.size(); i++) {
+    for (i = j = 0; i != ps.size(); i++) {
         if (value(ps[i]).getBool() || ps[i] == ~p)
-            return true;
+            return NULL;
         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;
+        ok = false;
+        return NULL;
     } else if (ps.size() == 1) {
-        assert(value(ps[0]) == l_Undef);
         uncheckedEnqueue(ps[0]);
-        return ok = (propagate() == NULL);
-    } else {
-        learnt_clause_group = std::max(group+1, learnt_clause_group);
-        Clause* c = Clause_new(ps, group);
+        ok = (propagate() == NULL);
+        return NULL;
+    }
+    
+    learnt_clause_group = std::max(group+1, learnt_clause_group);
+    Clause* c = Clause_new(ps, group);
+    attachClause(*c);
+    
+    return c;
+}
 
-        clauses.push(c);
-        attachClause(*c);
-        varReplacer->newClause();
+template Clause* Solver::addClauseInt(Clause& ps, const uint group);
+template Clause* Solver::addClauseInt(vec<Lit>& ps, const uint group);
+
+template<class T>
+bool Solver::addClause(T& ps, const uint group, char* group_name)
+{
+    assert(decisionLevel() == 0);
+    if (ps.size() > (0x01UL << 18)) {
+        std::cout << "Too long clause!" << std::endl;
+        exit(-1);
+    }
+    
+    if (libraryCNFFile) {
+        for (uint32_t i = 0; i != ps.size(); i++) {
+            fprintf(libraryCNFFile, "%s%d ", ps[i].sign() ? "-" : "", ps[i].var()+1);
+        }
+        fprintf(libraryCNFFile, "0\n");
     }
+    
+    #ifdef STATS_NEEDED
+    if (dynamic_behaviour_analysis)
+        logger.set_group_name(group, group_name);
+    #endif
 
-    return true;
+    if (!ok)
+        return false;
+    assert(qhead == trail.size());
+
+    // Check if clause is satisfied and remove false/duplicate literals:
+    if (varReplacer->getNumLastReplacedVars() || subsumer->getNumElimed()) {
+        for (uint32_t i = 0; i != ps.size(); i++) {
+            ps[i] = varReplacer->getReplaceTable()[ps[i].var()] ^ ps[i].sign();
+            if (subsumer->getVarElimed()[ps[i].var()] && !subsumer->unEliminate(ps[i].var()))
+                return false;
+        }
+    }
+    
+    Clause* c = addClauseInt(ps, group);
+    if (c != NULL) {
+        if (c->size() > 2)
+            clauses.push(c);
+        else
+            binaryClauses.push(c);
+    }
+
+    return ok;
 }
 
+template bool Solver::addClause(vec<Lit>& ps, const uint group, char* group_name);
+template bool Solver::addClause(Clause& ps, const uint group, char* group_name);
+
 void Solver::attachClause(XorClause& c)
 {
     assert(c.size() > 2);
@@ -396,9 +502,10 @@ void Solver::cancelUntil(int level)
     
     if (decisionLevel() > level) {
         
-        for (Gaussian **gauss = &gauss_matrixes[0], **end= gauss + gauss_matrixes.size(); gauss != end; gauss++)
+        for (vector<Gaussian*>::iterator gauss = gauss_matrixes.begin(), end= gauss_matrixes.end(); gauss != end; gauss++)
             (*gauss)->canceling(trail_lim[level]);
         
+        
         for (int c = trail.size()-1; c >= (int)trail_lim[level]; c--) {
             Var     x  = trail[c].var();
             #ifdef VERBOSE_DEBUG
@@ -428,11 +535,6 @@ void Solver::needLibraryCNFFile(const char* fileName)
     assert(libraryCNFFile != NULL);
 }
 
-void Solver::set_gaussian_decision_until(const uint to)
-{
-    gaussconfig.decision_until = to;
-}
-
 void Solver::clearGaussMatrixes()
 {
     for (uint i = 0; i < gauss_matrixes.size(); i++)
@@ -440,11 +542,126 @@ void Solver::clearGaussMatrixes()
     gauss_matrixes.clear();
 }
 
+inline bool Solver::defaultPolarity()
+{
+    switch(polarity_mode) {
+        case polarity_false:
+            return true;
+        case polarity_true:
+            return false;
+        case polarity_rnd:
+            return mtrand.randInt(1);
+        default:
+            assert(false);
+    }
+    
+    return true;
+}
+
+void tallyVotes(const vec<Clause*>& cs, vector<double>& votes, vector<bool>& positiveLiteral, vector<bool>& negativeLiteral)
+{
+    for (const Clause * const*it = cs.getData(), * const*end = it + cs.size(); it != end; it++) {
+        const Clause& c = **it;
+        if (c.learnt()) continue;
+        
+        double divider;
+        if (c.size() > 63)
+            divider = 0.0;
+        else
+            divider = 1.0/(double)((uint64_t)1<<(c.size()-1));
+        for (const Lit *it2 = &c[0], *end2 = it2 + c.size(); it2 != end2; it2++) {
+            if (it2->sign()) {
+                negativeLiteral[it2->var()] = true;
+                votes[it2->var()] += divider;
+            } else {
+                positiveLiteral[it2->var()] = true;
+                votes[it2->var()] -= divider;
+            }
+        }
+    }
+}
+
+void tallyVotes(const vec<XorClause*>& cs, vector<double>& votes, vector<bool>& positiveLiteral, vector<bool>& negativeLiteral)
+{
+    for (const XorClause * const*it = cs.getData(), * const*end = it + cs.size(); it != end; it++) {
+        const XorClause& c = **it;
+        double divider;
+        if (c.size() > 63)
+            divider = 0.0;
+        else
+            divider = 1.0/(double)((uint64_t)1<<(c.size()-1));
+        for (const Lit *it2 = &c[0], *end2 = it2 + c.size(); it2 != end2; it2++) {
+            votes[it2->var()] += divider;
+            negativeLiteral[it2->var()] = true;
+            positiveLiteral[it2->var()] = true;
+        }
+    }
+}
+
+const lbool Solver::calculateDefaultPolarities()
+{
+    #ifdef VERBOSE_DEBUG_POLARITIES
+    std::cout << "Default polarities: " << std::endl;
+    #endif
+    
+    assert(decisionLevel() == 0);
+    
+    if (polarity_mode == polarity_auto) {
+        double time = cpuTime();
+        
+        vector<double> votes;
+        vector<bool> positiveLiteral;
+        vector<bool> negativeLiteral;
+        votes.resize(nVars(), 0.0);
+        positiveLiteral.resize(nVars(), false);
+        negativeLiteral.resize(nVars(), false);
+        
+        tallyVotes(clauses, votes, positiveLiteral, negativeLiteral);
+        tallyVotes(binaryClauses, votes, positiveLiteral, negativeLiteral);
+        tallyVotes(varReplacer->getClauses(), votes, positiveLiteral, negativeLiteral);
+        tallyVotes(xorclauses, votes, positiveLiteral, negativeLiteral);
+        
+        Var i = 0;
+        for (vector<double>::const_iterator it = votes.begin(), end = votes.end(); it != end; it++, i++) {
+            defaultPolarities[i] = (*it >= 0.0);
+            #ifdef VERBOSE_DEBUG_POLARITIES
+            std::cout << !defaultPolarities[i] << ", ";
+            #endif //VERBOSE_DEBUG_POLARITIES
+        }
+        
+        if (verbosity >= 2) {
+            std::cout << "c |  Calc-ed default polarities: "
+            << std::fixed << std::setw(6) << std::setprecision(2) << cpuTime()-time << " s"
+            << "    |" << std:: endl;
+        }
+    } else if (polarity_mode != polarity_manual){
+        for (uint i = 0; i != defaultPolarities.size(); i++) {
+            defaultPolarities[i] = defaultPolarity();
+            #ifdef VERBOSE_DEBUG_POLARITIES
+            std::cout << !defaultPolarities[i] << ", ";
+            #endif //VERBOSE_DEBUG_POLARITIES
+        }
+    }
+    #ifdef VERBOSE_DEBUG_POLARITIES
+    std::cout << std::endl;
+    #endif //VERBOSE_DEBUG_POLARITIES
+    
+    return l_Undef;
+}
+
+void Solver::setDefaultPolarities()
+{
+    assert(polarity.size() == defaultPolarities.size());
+    
+    for (uint i = 0; i != polarity.size(); i++)
+        polarity[i] = defaultPolarities[i];
+}
+
 //=================================================================================================
 // Major methods:
 
 
-Lit Solver::pickBranchLit(int polarity_mode)
+Lit Solver::pickBranchLit()
 {
     #ifdef VERBOSE_DEBUG
     cout << "decision level: " << decisionLevel() << " ";
@@ -452,8 +669,11 @@ Lit Solver::pickBranchLit(int polarity_mode)
     
     Var next = var_Undef;
 
+    
+    bool random = mtrand.randDblExc() < random_var_freq;
+    
     // Random decision:
-    if (mtrand.randDblExc() < random_var_freq && !order_heap.empty()) {
+    if (random && !order_heap.empty()) {
         if (restrictedPickBranch == 0) next = order_heap[mtrand.randInt(order_heap.size()-1)];
         else next = order_heap[mtrand.randInt(std::min((uint32_t)order_heap.size()-1, restrictedPickBranch))];
 
@@ -462,8 +682,6 @@ Lit Solver::pickBranchLit(int polarity_mode)
     }
 
     // Activity based decision:
-    //bool dont_do_bad_decision = false;
-    //if (restrictedPickBranch != 0) dont_do_bad_decision = (mtrand.randInt(100) != 0);
     while (next == var_Undef || assigns[next] != l_Undef || !decision_var[next])
         if (order_heap.empty()) {
             next = var_Undef;
@@ -472,23 +690,16 @@ Lit Solver::pickBranchLit(int polarity_mode)
             next = order_heap.removeMin();
         }
 
-    bool sign = false;
-    switch (polarity_mode) {
-    case polarity_true:
-        sign = false;
-        break;
-    case polarity_false:
-        sign = true;
-        break;
-    case polarity_user:
-        if (next != var_Undef)
+    bool sign;
+    if (next != var_Undef) {
+        if (simplifying && random)
+            sign = mtrand.randInt(1);
+        /*else
+            sign = polarity[next] ^ (mtrand.randInt(200) == 1);*/
+        else if (avgBranchDepth.isvalid())
+            sign = polarity[next] ^ (mtrand.randInt(avgBranchDepth.getavg()) == 1);
+        else
             sign = polarity[next];
-        break;
-    case polarity_rnd:
-        sign = mtrand.randInt(1);
-        break;
-    default:
-        assert(false);
     }
 
     assert(next == var_Undef || value(next) == l_Undef);
@@ -508,6 +719,24 @@ Lit Solver::pickBranchLit(int polarity_mode)
     }
 }
 
+// Assumes 'seen' is cleared (will leave it cleared)
+template<class T1, class T2>
+bool subset(const T1& A, const T2& B, vector<bool>& seen)
+{
+    for (uint i = 0; i != B.size(); i++)
+        seen[B[i].toInt()] = 1;
+    for (uint i = 0; i != A.size(); i++) {
+        if (!seen[A[i].toInt()]) {
+            for (uint i = 0; i != B.size(); i++)
+                seen[B[i].toInt()] = 0;
+            return false;
+        }
+    }
+    for (uint i = 0; i != B.size(); i++)
+        seen[B[i].toInt()] = 0;
+    return true;
+}
+
 
 /*_________________________________________________________________________________________________
 |
@@ -526,10 +755,11 @@ Lit Solver::pickBranchLit(int polarity_mode)
 |  Effect:
 |    Will undo part of the trail, upto but not beyond the assumption of the current decision level.
 |________________________________________________________________________________________________@*/
-void Solver::analyze(Clause* confl, vec<Lit>& out_learnt, int& out_btlevel, int &nbLevels/*, int &merged*/)
+Clause* Solver::analyze(Clause* confl, vec<Lit>& out_learnt, int& out_btlevel, int &nbLevels/*, int &merged*/)
 {
     int pathC = 0;
     Lit p     = lit_Undef;
+    Clause* oldConfl = NULL;
 
     // Generate conflict clause:
     //
@@ -543,9 +773,9 @@ void Solver::analyze(Clause* confl, vec<Lit>& out_learnt, int& out_btlevel, int
         if (p != lit_Undef)
             reverse_binary_clause(c);
 
-        for (uint j = (p == lit_Undef) ? 0 : 1; j < c.size(); j++) {
+        for (uint j = (p == lit_Undef) ? 0 : 1; j != c.size(); j++) {
             const Lit& q = c[j];
-            const uint my_var = q.var();
+            const Var my_var = q.var();
 
             if (!seen[my_var] && level[my_var] > 0) {
                 varBumpActivity(my_var);
@@ -567,7 +797,9 @@ void Solver::analyze(Clause* confl, vec<Lit>& out_learnt, int& out_btlevel, int
         // Select next clause to look at:
         while (!seen[trail[index--].var()]);
         p     = trail[index+1];
+        oldConfl = confl;
         confl = reason[p.var()];
+        __builtin_prefetch(confl, 1, 0);
         seen[p.var()] = 0;
         pathC--;
 
@@ -630,17 +862,27 @@ void Solver::analyze(Clause* confl, vec<Lit>& out_learnt, int& out_btlevel, int
     }
     
     #ifdef UPDATEVARACTIVITY
-    if (lastDecisionLevel.size() > 0) {
-        for(uint32_t i = 0; i != lastDecisionLevel.size(); i++) {
-            if (reason[lastDecisionLevel[i].var()]->activity() < nbLevels)
-                varBumpActivity(lastDecisionLevel[i].var());
-        }
-        lastDecisionLevel.clear();
+    for(uint32_t i = 0; i != lastDecisionLevel.size(); i++) {
+        if (reason[lastDecisionLevel[i].var()]->activity() < nbLevels)
+            varBumpActivity(lastDecisionLevel[i].var());
     }
+    lastDecisionLevel.clear();
     #endif
 
     for (uint32_t j = 0; j != analyze_toclear.size(); j++)
         seen[analyze_toclear[j].var()] = 0;    // ('seen[]' is now cleared)
+    
+    if (out_learnt.size() == 1)
+        return NULL;
+    
+    if (!oldConfl->isXor() && out_learnt.size() < oldConfl->size()) {
+        if (!subset(out_learnt, *oldConfl, seen)) return NULL;
+        improvedClauseNo++;
+        improvedClauseSize += oldConfl->size() - out_learnt.size();
+        return oldConfl;
+    }
+    
+    return NULL;
 }
 
 
@@ -718,7 +960,7 @@ void Solver::analyzeFinal(Lit p, vec<Lit>& out_conflict)
 }
 
 
-void Solver::uncheckedEnqueue(Lit p, Clause* from)
+void Solver::uncheckedEnqueue(Lit p, ClausePtr from)
 {
     #ifdef VERBOSE_DEBUG
     cout << "uncheckedEnqueue var " << p.var()+1 << " to " << !p.sign() << " level: " << decisionLevel() << " sublevel: " << trail.size() << endl;
@@ -750,31 +992,39 @@ void Solver::uncheckedEnqueue(Lit p, Clause* from)
 |    Post-conditions:
 |      * the propagation queue is empty, even if there was a conflict.
 |________________________________________________________________________________________________@*/
-Clause* Solver::propagate(const bool xor_as_well)
+Clause* Solver::propagate(const bool update)
 {
     Clause* confl = NULL;
-    int     num_props = 0;
+    uint32_t num_props = 0;
     
     #ifdef VERBOSE_DEBUG
     cout << "Propagation started" << endl;
     #endif
+    uint32_t qheadBin = qhead;
 
     while (qhead < trail.size()) {
+        
         Lit            p   = trail[qhead++];     // 'p' is enqueued fact to propagate.
         vec<Watched>&  ws  = watches[p.toInt()];
-        Watched         *i, *j, *end;
-        num_props++;
+        Watched        *i, *j, *end;
         
         //First propagate binary clauses
-        vec<WatchedBin> & wbin = binwatches[p.toInt()];
-        for(WatchedBin *k = wbin.getData(), *end = k + wbin.size(); k != end; k++) {
-            Lit imp = k->impliedLit;
-            lbool val = value(imp);
-            if (val.isUndef()) {
-                uncheckedEnqueue(imp, k->clause);
-            } else if (val == l_False)
-                return k->clause;
+        while (qheadBin < trail.size()) {
+            Lit p   = trail[qheadBin++];
+            vec<WatchedBin> & wbin = binwatches[p.toInt()];
+            num_props++;
+            for(WatchedBin *k = wbin.getData(), *end = k + wbin.size(); k != end; k++) {
+                lbool val = value(k->impliedLit);
+                if (val.isUndef()) {
+                    uncheckedEnqueue(k->impliedLit, k->clause);
+                } else if (val == l_False) {
+                    confl = k->clause;
+                    //goto EndPropagate;
+                }
+            }
         }
+        if (confl != NULL)
+            goto EndPropagate;
         
         //Next, propagate normal clauses
         
@@ -783,6 +1033,9 @@ Clause* Solver::propagate(const bool xor_as_well)
         #endif
 
         for (i = j = ws.getData(), end = i + ws.size();  i != end;) {
+            if (i+1 != end)
+                __builtin_prefetch((i+1)->clause, 1, 0);
+            
             if(value(i->blockedLit).getBool()) { // Clause is sat
                 *j++ = *i++;
                 continue;
@@ -806,13 +1059,14 @@ Clause* Solver::propagate(const bool xor_as_well)
                 j++;
             } else {
                 // Look for new watch:
-                for (uint32_t k = 2; k != c.size(); k++)
-                    if (value(c[k]) != l_False) {
-                        c[1] = c[k];
-                        c[k] = false_lit;
+                for (Lit *k = &c[2], *end2 = c.getData()+c.size(); k != end2; k++) {
+                    if (value(*k) != l_False) {
+                        c[1] = *k;
+                        *k = false_lit;
                         watches[(~c[1]).toInt()].push(Watched(&c, c[0]));
                         goto FoundWatch;
                     }
+                }
 
                 // Did not find watch -- clause is unit under assignment:
                 j->clause = &c;
@@ -827,13 +1081,13 @@ Clause* Solver::propagate(const bool xor_as_well)
                 } else {
                     uncheckedEnqueue(first, &c);
                     #ifdef DYNAMICNBLEVEL
-                    if (c.learnt() && c.activity() > 2) { // GA
+                    if (update && c.learnt() && c.activity() > 2) { // GA
                         MYFLAG++;
                         int nbLevels =0;
-                        for(Lit *i = c.getData(), *end = i+c.size(); i != end; i++) {
-                            int l = level[i->var()];
-                            if (permDiff[l] != MYFLAG) {
-                                permDiff[l] = MYFLAG;
+                        for(Lit *l = c.getData(), *end2 = l+c.size(); l != end2; l++) {
+                            int lev = level[l->var()];
+                            if (permDiff[lev] != MYFLAG) {
+                                permDiff[lev] = MYFLAG;
                                 nbLevels++;
                             }
                             
@@ -850,8 +1104,9 @@ FoundWatch:
         ws.shrink_(i - j);
 
         //Finally, propagate XOR-clauses
-        if (xor_as_well && !confl) confl = propagate_xors(p);
+        if (xorclauses.size() > 0 && !confl) confl = propagate_xors(p);
     }
+EndPropagate:
     propagations += num_props;
     simpDB_props -= num_props;
     
@@ -870,10 +1125,12 @@ Clause* Solver::propagate_xors(const Lit& p)
     
     Clause* confl = NULL;
 
-    vec<XorClause*>&  ws  = xorwatches[p.var()];
-    XorClause         **i, **j, **end;
+    vec<XorClausePtr>&  ws  = xorwatches[p.var()];
+    XorClausePtr        *i, *j, *end;
     for (i = j = ws.getData(), end = i + ws.size();  i != end;) {
         XorClause& c = **i++;
+        if (i != end)
+            __builtin_prefetch(*i, 1, 0);
 
         // Make sure the false literal is data[1]:
         if (c[0].var() == p.var()) {
@@ -889,7 +1146,7 @@ Clause* Solver::propagate_xors(const Lit& p)
         cout << endl;
         #endif
         bool final = c.xor_clause_inverted();
-        for (int k = 0, size = c.size(); k != size; k++ ) {
+        for (uint32_t k = 0, size = c.size(); k != size; k++ ) {
             const lbool& val = assigns[c[k].var()];
             if (val.isUndef() && k >= 2) {
                 Lit tmp(c[1]);
@@ -975,14 +1232,13 @@ struct reduceDB_lt {
         // First criteria
         if (xsize > 2 && ysize == 2) return 1;
         if (ysize > 2 && xsize == 2) return 0;
-        if (xsize == 2 && ysize == 2) return 0;
         
         // Second criteria
         if (x->activity() > y->activity()) return 1;
         if (x->activity() < y->activity()) return 0;
         
         //return x->oldActivity() < y->oldActivity();
-        return xsize < ysize;
+        return xsize > ysize;
     }
 };
 
@@ -992,7 +1248,19 @@ void Solver::reduceDB()
 
     nbReduceDB++;
     std::sort(learnts.getData(), learnts.getData()+learnts.size(), reduceDB_lt());
-    for (i = j = 0; i != learnts.size() / RATIOREMOVECLAUSES; i++){
+    
+    #ifdef VERBOSE_DEBUG
+    std::cout << "Cleaning clauses" << endl;
+    for (uint i = 0; i != learnts.size(); i++) {
+        std::cout << "activity:" << learnts[i]->activity() << " \tsize:" << learnts[i]->size() << std::endl;
+    }
+    #endif
+    
+    
+    const uint removeNum = (double)learnts.size() / (double)RATIOREMOVECLAUSES;
+    for (i = j = 0; i != removeNum; i++){
+        //NOTE: The next instruciton only works if removeNum < learnts.size() (strictly smaller!!)
+        __builtin_prefetch(learnts[i+1], 0, 0);
         if (learnts[i]->size() > 2 && !locked(*learnts[i]) && learnts[i]->activity() > 2)
             removeClause(*learnts[i]);
         else
@@ -1019,14 +1287,15 @@ const vector<Lit> Solver::get_unitary_learnts() const
 {
     vector<Lit> unitaries;
     if (decisionLevel() > 0) {
-        for (uint32_t i = 0; i != trail_lim[0]; i++)
+        for (uint32_t i = 0; i != trail_lim[0]; i++) {
             unitaries.push_back(trail[i]);
+        }
     }
     
     return unitaries;
 }
 
-void Solver::dump_sorted_learnts(const char* file)
+void Solver::dumpSortedLearnts(const char* file, const uint32_t maxSize)
 {
     FILE* outfile = fopen(file, "w");
     if (!outfile) {
@@ -1034,15 +1303,46 @@ void Solver::dump_sorted_learnts(const char* file)
         exit(-1);
     }
     
-    if (decisionLevel() > 0) {
-        for (uint32_t i = 0; i != trail_lim[0]; i++)
-            printf("%s%d 0\n", trail[i].sign() ? "-" : "", trail[i].var());
+    fprintf(outfile, "c unitaries\n");
+    if (maxSize > 0) {
+        if (trail_lim.size() > 0) {
+            for (uint32_t i = 0; i != trail_lim[0]; i++) {
+                fprintf(outfile,"%s%d 0\n", trail[i].sign() ? "-" : "", trail[i].var()+1);
+            }
+        }
+        else {
+            for (uint32_t i = 0; i != trail.size(); i++) {
+                fprintf(outfile,"%s%d 0\n", trail[i].sign() ? "-" : "", trail[i].var()+1);
+            }
+        }
+    }
+    
+    fprintf(outfile, "c clauses from binaryClauses\n");
+    if (maxSize >= 2) {
+        for (uint i = 0; i != binaryClauses.size(); i++) {
+            if (binaryClauses[i]->learnt())
+                binaryClauses[i]->plainPrint(outfile);
+        }
     }
     
+    fprintf(outfile, "c clauses from learnts\n");
     std::sort(learnts.getData(), learnts.getData()+learnts.size(), reduceDB_lt());
     for (int i = learnts.size()-1; i >= 0 ; i--) {
-        learnts[i]->plainPrint(outfile);
+        if (learnts[i]->size() <= maxSize)
+            learnts[i]->plainPrint(outfile);
     }
+    
+    fprintf(outfile, "c clauses representing 2-long XOR clauses\n");
+    const vector<Lit>& table = varReplacer->getReplaceTable();
+    for (Var var = 0; var != table.size(); var++) {
+        Lit lit = table[var];
+        if (lit.var() == var)
+            continue;
+        
+        fprintf(outfile, "%s%d %d 0\n", (!lit.sign() ? "-" : ""), lit.var()+1, var+1);
+        fprintf(outfile, "%s%d -%d 0\n", (lit.sign() ? "-" : ""), lit.var()+1, var+1);
+    }
+    
     fclose(outfile);
 }
 
@@ -1051,6 +1351,12 @@ void Solver::setMaxRestarts(const uint num)
     maxRestarts = num;
 }
 
+inline int64_t abs64(int64_t a)
+{
+    if (a < 0) return -a;
+    return a;
+}
+
 /*_________________________________________________________________________________________________
 |
 |  simplify : [void]  ->  [bool]
@@ -1068,24 +1374,46 @@ lbool Solver::simplify()
         return l_False;
     }
 
-    if (nAssigns() == simpDB_assigns || (simpDB_props > 0)) {
+    if (simpDB_props > 0) {
         return l_Undef;
     }
-
-    // Remove satisfied clauses:
-    clauseCleaner->removeAndCleanAll();
-    if (((double)(nbBin - lastNbBin)/BINARY_TO_XOR_APPROX) > (double)order_heap.size() * PERCENTAGEPERFORMREPLACE) {
-        XorFinder xorFinder(this, learnts, ClauseCleaner::learnts);
-        xorFinder.doNoPart(2, 2);
-        if (!ok) return l_False;
+    
+    double slowdown = (100000.0/(double)binaryClauses.size());
+    slowdown = std::min(3.5, slowdown);
+    slowdown = std::max(0.2, slowdown);
+    
+    double speedup = 50000000.0/(double)(propagations-lastSearchForBinaryXor);
+    speedup = std::min(3.5, speedup);
+    speedup = std::max(0.2, speedup);
+    
+    /*std::cout << "new:" << nbBin - lastNbBin + becameBinary << std::endl;
+    std::cout << "left:" << ((double)(nbBin - lastNbBin + becameBinary)/BINARY_TO_XOR_APPROX) * slowdown  << std::endl;
+    std::cout << "right:" << (double)order_heap.size() * PERCENTAGEPERFORMREPLACE * speedup << std::endl;*/
+    
+    if (findBinaryXors && regularlyFindBinaryXors &&
+        (((double)abs64((int64_t)nbBin - (int64_t)lastNbBin + (int64_t)becameBinary)/BINARY_TO_XOR_APPROX) * slowdown) >
+        ((double)order_heap.size() * PERCENTAGEPERFORMREPLACE * speedup)) {
+        lastSearchForBinaryXor = propagations;
+        clauseCleaner->cleanClauses(clauses, ClauseCleaner::clauses);
+        clauseCleaner->cleanClauses(learnts, ClauseCleaner::learnts);
+        clauseCleaner->removeSatisfied(binaryClauses, ClauseCleaner::binaryClauses);
+        if (ok == false)
+            return l_False;
+    
+        XorFinder xorFinder(this, binaryClauses, ClauseCleaner::binaryClauses);
+        if (xorFinder.doNoPart(2, 2) == false)
+            return l_False;
         
         lastNbBin = nbBin;
+        becameBinary = 0;
     }
-    if (performReplace
-        && ((double)varReplacer->getNewToReplaceVars()/(double)order_heap.size()) > PERCENTAGEPERFORMREPLACE) {
-        varReplacer->performReplace();
-        if (!ok) return l_False;
-    }
+
+    // Remove satisfied clauses:
+    clauseCleaner->removeAndCleanAll();
+    if (ok == false)
+        return l_False;
+    if (performReplace && varReplacer->performReplace() == false)
+        return l_False;
 
     // Remove fixed variables from the variable heap:
     order_heap.filter(VarFilter(*this));
@@ -1111,7 +1439,7 @@ lbool Solver::simplify()
 |    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)
+lbool Solver::search(int nof_conflicts, int nof_conflicts_fullrestart, const bool update)
 {
     assert(ok);
     int         conflictC = 0;
@@ -1119,48 +1447,72 @@ lbool Solver::search(int nof_conflicts)
     llbool      ret;
 
     starts++;
-    for (Gaussian **gauss = &gauss_matrixes[0], **end= gauss + gauss_matrixes.size(); gauss != end; gauss++) {
+    if (restartType == static_restart)
+        staticStarts++;
+    else
+        dynStarts++;
+    
+    for (vector<Gaussian*>::iterator gauss = gauss_matrixes.begin(), end= gauss_matrixes.end(); gauss != end; gauss++) {
         ret = (*gauss)->full_init();
         if (ret != l_Nothing) return ret;
     }
 
     for (;;) {
-        Clause* confl = propagate();
+        Clause* confl = propagate(update);
 
         if (confl != NULL) {
-            ret = handle_conflict(learnt_clause, confl, conflictC);
+            ret = handle_conflict(learnt_clause, confl, conflictC, update);
             if (ret != l_Nothing) return ret;
         } else {
             bool at_least_one_continue = false;
-            for (Gaussian **gauss = &gauss_matrixes[0], **end= gauss + gauss_matrixes.size(); gauss != end; gauss++)  {
+            for (vector<Gaussian*>::iterator gauss = gauss_matrixes.begin(), end= gauss_matrixes.end(); gauss != end; gauss++) {
                 ret = (*gauss)->find_truths(learnt_clause, conflictC);
                 if (ret == l_Continue) at_least_one_continue = true;
                 else if (ret != l_Nothing) return ret;
             }
             if (at_least_one_continue) continue;
-            ret = new_decision(nof_conflicts, conflictC);
+            ret = new_decision(nof_conflicts, nof_conflicts_fullrestart, conflictC);
             if (ret != l_Nothing) return ret;
         }
     }
 }
 
-llbool Solver::new_decision(int& nof_conflicts, int& conflictC)
+llbool Solver::new_decision(const int& nof_conflicts, const int& nof_conflicts_fullrestart, int& conflictC)
 {
     
     // Reached bound on number of conflicts?
     switch (restartType) {
     case dynamic_restart:
         if (nbDecisionLevelHistory.isvalid() &&
-            ((nbDecisionLevelHistory.getavg()*0.7) > (totalSumOfDecisionLevel / conf4Stats))) {
+            ((nbDecisionLevelHistory.getavg()) > (totalSumOfDecisionLevel / (double)(conflicts - conflictsAtLastSolve)))) {
+            
+            #ifdef DEBUG_DYNAMIC_RESTART
+            if (nbDecisionLevelHistory.isvalid()) {
+                std::cout << "nbDecisionLevelHistory.getavg():" << nbDecisionLevelHistory.getavg() <<std::endl;
+                //std::cout << "calculated limit:" << ((double)(nbDecisionLevelHistory.getavg())*0.9*((double)fullStarts + 20.0)/20.0) << std::endl;
+                std::cout << "totalSumOfDecisionLevel:" << totalSumOfDecisionLevel << std::endl;
+                std::cout << "conflicts:" << conflicts<< std::endl;
+                std::cout << "conflictsAtLastSolve:" << conflictsAtLastSolve << std::endl;
+                std::cout << "conflicts-conflictsAtLastSolve:" << conflicts-conflictsAtLastSolve<< std::endl;
+                std::cout << "fullStarts:" << fullStarts << std::endl;
+            }
+            #endif
+            
             nbDecisionLevelHistory.fastclear();
-            progress_estimate = progressEstimate();
+            #ifdef STATS_NEEDED
+            if (dynamic_behaviour_analysis)
+                progress_estimate = progressEstimate();
+            #endif
             cancelUntil(0);
             return l_Undef;
         }
         break;
     case static_restart:
         if (nof_conflicts >= 0 && conflictC >= nof_conflicts) {
-            progress_estimate = progressEstimate();
+            #ifdef STATS_NEEDED
+            if (dynamic_behaviour_analysis)
+                progress_estimate = progressEstimate();
+            #endif
             cancelUntil(0);
             return l_Undef;
         }
@@ -1169,6 +1521,14 @@ llbool Solver::new_decision(int& nof_conflicts, int& conflictC)
         assert(false);
         break;
     }
+    if (nof_conflicts_fullrestart >= 0 && conflicts >= nof_conflicts_fullrestart)  {
+        #ifdef STATS_NEEDED
+        if (dynamic_behaviour_analysis)
+            progress_estimate = progressEstimate();
+        #endif
+        cancelUntil(0);
+        return l_Undef;
+    }
 
     // Simplify the set of problem clauses:
     if (decisionLevel() == 0 && simplify() == l_False) {
@@ -1176,7 +1536,7 @@ llbool Solver::new_decision(int& nof_conflicts, int& conflictC)
     }
 
     // Reduce the set of learnt clauses:
-    if (conflicts >= curRestart * nbclausesbeforereduce) {
+    if (conflicts >= curRestart * nbclausesbeforereduce + nbCompensateSubsumer) {
         curRestart ++;
         reduceDB();
         nbclausesbeforereduce += 500;
@@ -1201,7 +1561,7 @@ llbool Solver::new_decision(int& nof_conflicts, int& conflictC)
     if (next == lit_Undef) {
         // New variable decision:
         decisions++;
-        next = pickBranchLit(polarity_mode);
+        next = pickBranchLit();
 
         if (next == lit_Undef)
             return l_True;
@@ -1215,7 +1575,7 @@ llbool Solver::new_decision(int& nof_conflicts, int& conflictC)
     return l_Nothing;
 }
 
-llbool Solver::handle_conflict(vec<Lit>& learnt_clause, Clause* confl, int& conflictC)
+llbool Solver::handle_conflict(vec<Lit>& learnt_clause, Clause* confl, int& conflictC, const bool update)
 {
     #ifdef VERBOSE_DEBUG
     cout << "Handling conflict: ";
@@ -1232,16 +1592,19 @@ llbool Solver::handle_conflict(vec<Lit>& learnt_clause, Clause* confl, int& conf
     if (decisionLevel() == 0)
         return l_False;
     learnt_clause.clear();
-    analyze(confl, learnt_clause, backtrack_level, nbLevels);
-    conf4Stats++;
-    if (restartType == dynamic_restart) {
-        nbDecisionLevelHistory.push(nbLevels);
+    Clause* c = analyze(confl, learnt_clause, backtrack_level, nbLevels);
+    if (update) {
+        avgBranchDepth.push(decisionLevel());
+        if (restartType == dynamic_restart)
+            nbDecisionLevelHistory.push(nbLevels);
         totalSumOfDecisionLevel += nbLevels;
+    } else {
+        conflictsAtLastSolve++;
     }
     
     #ifdef STATS_NEEDED
     if (dynamic_behaviour_analysis)
-        logger.conflict(Logger::simple_confl_type, backtrack_level, confl->group, learnt_clause);
+        logger.conflict(Logger::simple_confl_type, backtrack_level, confl->getGroup(), learnt_clause);
     #endif
     cancelUntil(backtrack_level);
     
@@ -1263,15 +1626,29 @@ llbool Solver::handle_conflict(vec<Lit>& learnt_clause, Clause* confl, int& conf
         #endif
     //Normal learnt
     } else {
-        Clause* c = Clause_new(learnt_clause, learnt_clause_group++, true);
-        #ifdef STATS_NEEDED
-        if (dynamic_behaviour_analysis)
-            logger.set_group_name(c->group, "learnt clause");
-        #endif
-        learnts.push(c);
-        c->setActivity(nbLevels); // LS
+        if (c) {
+            detachClause(*c);
+            for (uint i = 0; i != learnt_clause.size(); i++)
+                (*c)[i] = learnt_clause[i];
+            c->resize(learnt_clause.size());
+            if (c->learnt() && c->activity() > nbLevels)
+                c->setActivity(nbLevels); // LS
+            c->setStrenghtened();
+        } else {
+            c = Clause_new(learnt_clause, learnt_clause_group++, true);
+            #ifdef STATS_NEEDED
+            if (dynamic_behaviour_analysis)
+                logger.set_group_name(c->getGroup(), "learnt clause");
+            #endif
+            if (c->size() > 2) {
+                learnts.push(c);
+                c->setActivity(nbLevels); // LS
+            } else {
+                binaryClauses.push(c);
+                nbBin++;
+            }
+        }
         if (nbLevels <= 2) nbDL2++;
-        if (c->size() == 2) nbBin++;
         attachClause(*c);
         uncheckedEnqueue(learnt_clause[0], c);
     }
@@ -1289,7 +1666,7 @@ double Solver::progressEstimate() const
     for (uint32_t 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);
+        progress += pow(F, (int)i) * (end - beg);
     }
 
     return progress / nVars();
@@ -1306,7 +1683,7 @@ void Solver::print_gauss_sum_stats() const
     uint useful_prop = 0;
     uint useful_confl = 0;
     uint disabled = 0;
-    for (Gaussian *const*gauss = &gauss_matrixes[0], *const*end= gauss + gauss_matrixes.size(); gauss != end; gauss++) {
+    for (vector<Gaussian*>::const_iterator gauss = gauss_matrixes.begin(), end= gauss_matrixes.end(); gauss != end; gauss++) {
         disabled += (*gauss)->get_disabled();
         called += (*gauss)->get_called();
         useful_prop += (*gauss)->get_useful_prop();
@@ -1324,113 +1701,255 @@ void Solver::print_gauss_sum_stats() const
     }
 }
 
-inline void Solver::chooseRestartType(const lbool& status, RestartTypeChooser& restartTypeChooser)
+inline void Solver::chooseRestartType(const uint& lastFullRestart)
 {
-    if (status.isUndef() && starts > 2 && starts < 8) {
-        RestartType tmp = restartTypeChooser.choose();
-        if (fixRestartType != auto_restart)
-            tmp = fixRestartType;
-        if (starts == 7) {
+    uint relativeStart = starts - lastFullRestart;
+    
+    if (relativeStart > RESTART_TYPE_DECIDER_FROM  && relativeStart < RESTART_TYPE_DECIDER_UNTIL) {
+        if (fixRestartType == auto_restart)
+            restartTypeChooser->addInfo();
+        
+        if (relativeStart == (RESTART_TYPE_DECIDER_UNTIL-1)) {
+            RestartType tmp;
+            if (fixRestartType == auto_restart)
+                tmp = restartTypeChooser->choose();
+            else
+                tmp = fixRestartType;
+            
             if (tmp == dynamic_restart) {
                 nbDecisionLevelHistory.fastclear();
                 nbDecisionLevelHistory.initSize(100);
-                totalSumOfDecisionLevel = 0;
-                clearGaussMatrixes();
-                if (verbosity >= 1)
+                if (verbosity >= 2)
                     printf("c |                           Decided on dynamic restart strategy                         |\n");
             } else  {
-                if (verbosity >= 1)
+                if (verbosity >= 2)
                     printf("c |                            Decided on static restart strategy                         |\n");
+                                
+                if (gaussconfig.decision_until > 0 && xorclauses.size() > 1 && xorclauses.size() < 20000) {
+                    double time = cpuTime();
+                    MatrixFinder m(*this);
+                    const uint numMatrixes = m.findMatrixes();
+                    if (verbosity >=1)
+                        printf("c |  Finding matrixes :    %4.2lf s (found  %5d)                                |\n", cpuTime()-time, numMatrixes);
+                }
             }
             restartType = tmp;
+            restartTypeChooser->reset();
         }
-    } else {
-        #ifdef VERBOSE_DEBUG
-        restartTypeChooser.choose();
-        #endif
     }
 }
 
-inline void Solver::performStepsBeforeSolve()
+inline void Solver::setDefaultRestartType()
 {
-    if (performReplace
-        && ((double)varReplacer->getNewToReplaceVars()/(double)order_heap.size()) > PERCENTAGEPERFORMREPLACE) {
-        varReplacer->performReplace();
-    if (!ok) return;
+    if (fixRestartType != auto_restart) restartType = fixRestartType;
+    else restartType = static_restart;
+    if (restartType == dynamic_restart) {
+        nbDecisionLevelHistory.fastclear();
+        nbDecisionLevelHistory.initSize(100);
     }
+}
+
+const lbool Solver::simplifyProblem(const uint32_t numConfls, const uint64_t numProps)
+{
+    Heap<VarOrderLt> backup_order_heap(order_heap);
+    vector<bool> backup_polarities = polarity;
+    RestartType backup_restartType= restartType;
+    double backup_random_var_freq = random_var_freq;
+    vec<double> backup_activity;
+    backup_activity.growTo(activity.size());
+    std::copy(activity.getData(), activity.getDataEnd(), backup_activity.getData());
+    double backup_var_inc = var_inc;
     
-    if (xorFinder) {
-        double time;
-        if (clauses.size() < MAX_CLAUSENUM_XORFIND) {
-            XorFinder xorFinder(this, clauses, ClauseCleaner::clauses);
-            xorFinder.doNoPart(2, 10);
-            if (!ok) return;
-            
-            if (performReplace
-                && ((double)varReplacer->getNewToReplaceVars()/(double)order_heap.size()) > PERCENTAGEPERFORMREPLACE) {
-                varReplacer->performReplace();
-            if (!ok) return;
-            }
+    if (verbosity >= 2)
+        std::cout << "c | " << std::setw(24) << " " 
+        << "Simplifying problem for " << std::setw(8) << numConfls << " confls" 
+        << std::setw(24) << " |" << std::endl;
+    random_var_freq = 1;
+    simplifying = true;
+    uint64_t origConflicts = conflicts;
+    
+    lbool status = l_Undef;
+    restartType = static_restart;
+    
+    while(status == l_Undef && conflicts-origConflicts < numConfls) {
+        printRestartStat();
+        status = search(100, -1, false);
+        starts--;
+    }
+    if (status != l_Undef)
+        goto end;
+    printRestartStat();
+    
+    if (heuleProcess && xorclauses.size() > 1) {
+        if (!conglomerate->heuleProcessFull()) {
+            status = l_False;
+            goto end;
         }
         
-        if (xorclauses.size() > 1) {
-            uint orig_total = 0;
-            uint orig_num_cls = xorclauses.size();
-            for (uint i = 0; i < xorclauses.size(); i++) {
-                orig_total += xorclauses[i]->size();
+        while (performReplace && varReplacer->needsReplace()) {
+            if (!varReplacer->performReplace()) {
+                status = l_False;
+                goto end;
             }
-            
-            time = cpuTime();
-            uint foundCong = conglomerate->conglomerateXors();
-            if (verbosity >=1)
-                printf("c |  Conglomerating XORs:  %4.2lf s (removed %6d vars)                         |\n", cpuTime()-time, foundCong);
-            if (!ok) return;
-            
-            uint new_total = 0;
-            uint new_num_cls = xorclauses.size();
-            for (uint i = 0; i < xorclauses.size(); i++) {
-                new_total += xorclauses[i]->size();
-            }
-            if (verbosity >=1) {
-                printf("c |  Sum xclauses before: %8d, after: %12d                         |\n", orig_num_cls, new_num_cls);
-                printf("c |  Sum xlits before: %11d, after: %12d                         |\n", orig_total, new_total);
-            }
-            
-            if (performReplace
-                && ((double)varReplacer->getNewToReplaceVars()/(double)order_heap.size()) > PERCENTAGEPERFORMREPLACE) {
-                varReplacer->performReplace();
-            if (!ok) return;
+            if (!conglomerate->heuleProcessFull()) {
+                status = l_False;
+                goto end;
             }
         }
     }
     
-    if (gaussconfig.decision_until > 0 && xorclauses.size() > 1 && xorclauses.size() < 20000) {
-        double time = cpuTime();
-        MatrixFinder m(this);
-        const uint numMatrixes = m.findMatrixes();
-        if (verbosity >=1)
-            printf("c |  Finding matrixes :    %4.2lf s (found  %5d)                                |\n", cpuTime()-time, numMatrixes);
+    if (failedVarSearch && !failedVarSearcher->search((nClauses() < 500000 && order_heap.size() < 50000) ? 6000000 : 2000000))  {
+        status = l_False;
+        goto end;
+    }
+    
+    if (doXorSubsumption && xorclauses.size() > 1) {
+        XorSubsumer xsub(*this);
+        if (!xsub.simplifyBySubsumption()) {
+            status = l_False;
+            goto end;
+        }
+    }
+    
+    if (doSubsumption) {
+        if (!subsumer->simplifyBySubsumption()) {
+            status = l_False;
+            goto end;
+        }
     }
+    
+end:
+    random_var_freq = backup_random_var_freq;
+    if (verbosity >= 2)
+        printf("c                                      Simplifying finished                               |\n");
+    
+    var_inc = backup_var_inc;
+    std::copy(backup_activity.getData(), backup_activity.getDataEnd(), activity.getData());
+    order_heap = backup_order_heap;
+    simplifying = false;
+    order_heap.filter(VarFilter(*this));
+    polarity = backup_polarities;
+    restartType = backup_restartType;
+    
+    return status;
+}
+
+const bool Solver::checkFullRestart(int& nof_conflicts, int& nof_conflicts_fullrestart, uint& lastFullRestart)
+{
+    if (nof_conflicts_fullrestart > 0 && conflicts >= nof_conflicts_fullrestart) {
+        clearGaussMatrixes();
+        if (verbosity >= 2)
+            printf("c |                                      Fully restarting                                 |\n");
+        nof_conflicts = restart_first + (double)restart_first*restart_inc;
+        nof_conflicts_fullrestart = (double)nof_conflicts_fullrestart * FULLRESTART_MULTIPLIER_MULTIPLIER;
+        restartType = static_restart;
+        lastFullRestart = starts;
+        
+        /*if (findNormalXors && clauses.size() < MAX_CLAUSENUM_XORFIND) {
+            XorFinder xorFinder(this, clauses, ClauseCleaner::clauses);
+            if (!xorFinder.doNoPart(3, 10))
+                return false;
+        }*/
+        
+        if (doPartHandler && !partHandler->handle())
+            return false;
+        
+        /*if (calculateDefaultPolarities() == l_False)
+            return false;
+        setDefaultPolarities();*/
+        
+        fullStarts++;
+    }
+    
+    return true;
+}
+
+inline void Solver::performStepsBeforeSolve()
+{
+    assert(qhead == trail.size());
+    if (performReplace && !varReplacer->performReplace()) return;
+    
+    
+    if (doSubsumption
+        && !libraryUsage
+        && clauses.size() + binaryClauses.size() + learnts.size() < 4800000
+        && !subsumer->simplifyBySubsumption())
+        return;
+    
+    const uint32_t lastReplacedVars = varReplacer->getNumReplacedVars();
+    if (findBinaryXors && binaryClauses.size() < MAX_CLAUSENUM_XORFIND) {
+        XorFinder xorFinder(this, binaryClauses, ClauseCleaner::binaryClauses);
+        if (!xorFinder.doNoPart(2, 2)) return;
+        
+        if (performReplace && !varReplacer->performReplace(true)) return;
+    }
+    
+    if (findNormalXors && clauses.size() < MAX_CLAUSENUM_XORFIND) {
+        XorFinder xorFinder(this, clauses, ClauseCleaner::clauses);
+        if (!xorFinder.doNoPart(3, 10)) return;
+    }
+        
+    if (xorclauses.size() > 1) {
+        if (heuleProcess) {
+            if (!conglomerate->heuleProcessFull()) return;
+            
+            while (performReplace && varReplacer->needsReplace()) {
+                if (!varReplacer->performReplace()) return;
+                if (!conglomerate->heuleProcessFull()) return;
+            }
+        }
+        
+        if (conglomerateXors && !conglomerate->conglomerateXorsFull())
+            return;
+        
+        if (doXorSubsumption && xorclauses.size() > 1) {
+            XorSubsumer xsub(*this);
+            if (!xsub.simplifyBySubsumption())
+                return;
+        }
+        
+        if (performReplace && !varReplacer->performReplace())
+            return;
+    }
+}
+
+void Solver::checkSolution()
+{
+    // Extend & check:
+    model.growTo(nVars());
+    for (Var var = 0; var != nVars(); var++) model[var] = value(var);
+    verifyModel();
+    model.clear();
 }
 
 lbool Solver::solve(const vec<Lit>& assumps)
 {
+    if (!ok) return l_False;
+    assert(qhead == trail.size());
+    
     if (libraryCNFFile)
         fprintf(libraryCNFFile, "c Solver::solve() called\n");
     
     model.clear();
     conflict.clear();
     clearGaussMatrixes();
-    restartType = static_restart;
-    conglomerate->addRemovedClauses();
+    setDefaultRestartType();
+    totalSumOfDecisionLevel = 0;
+    conflictsAtLastSolve = conflicts;
+    avgBranchDepth.fastclear();
+    avgBranchDepth.initSize(500);
+    
+    if (!conglomerate->addRemovedClauses()) return l_False;
     starts = 0;
 
-    if (!ok) return l_False;
-
     assumps.copyTo(assumptions);
 
-    double  nof_conflicts = restart_first;
+    int  nof_conflicts = restart_first;
+    int  nof_conflicts_fullrestart = (double)restart_first * (double)FULLRESTART_MULTIPLIER;
+    //nof_conflicts_fullrestart = -1;
+    uint    lastFullRestart  = starts;
     lbool   status        = l_Undef;
+    uint64_t nextSimplify = 30000;
     
     if (nClauses() * learntsize_factor < nbclausesbeforereduce) {
         if (nClauses() * learntsize_factor < nbclausesbeforereduce/2)
@@ -1439,15 +1958,25 @@ lbool Solver::solve(const vec<Lit>& assumps)
             nbclausesbeforereduce = (nClauses() * learntsize_factor)/2;
     }
     
-    performStepsBeforeSolve();
-    if (!ok) return l_False;
-    
-    printStatHeader();
+    if (conflicts == 0) {
+        performStepsBeforeSolve();
+        if (!ok) return l_False;
     
-    RestartTypeChooser restartTypeChooser(this);
+        printStatHeader();
+        if (calculateDefaultPolarities() == l_False)
+        return l_False;
+        setDefaultPolarities();
+    }
     
     // Search:
     while (status == l_Undef && starts < maxRestarts) {
+        
+        if (schedSimplification && conflicts >= nextSimplify) {
+            status = simplifyProblem(500, 7000000);
+            nextSimplify = conflicts * 1.5;
+            if (status != l_Undef) break;
+        }
+        
         printRestartStat();
         #ifdef STATS_NEEDED
         if (dynamic_behaviour_analysis) {
@@ -1456,10 +1985,13 @@ lbool Solver::solve(const vec<Lit>& assumps)
         }
         #endif
         
-        status = search((int)nof_conflicts);
-        nof_conflicts *= restart_inc;
-        
-        chooseRestartType(status, restartTypeChooser);
+        status = search(nof_conflicts, nof_conflicts_fullrestart);
+        nof_conflicts = (double)nof_conflicts * restart_inc;
+        if (!checkFullRestart(nof_conflicts, nof_conflicts_fullrestart, lastFullRestart))
+            return l_False;
+        chooseRestartType(lastFullRestart);
+        //if (avgBranchDepth.isvalid())
+        //    std::cout << "avg branch depth:" << avgBranchDepth.getavg() << std::endl;
     }
     printEndSearchStat();
     
@@ -1471,14 +2003,6 @@ lbool Solver::solve(const vec<Lit>& assumps)
     freeLater.clear();
 
     if (status == l_True) {
-        conglomerate->doCalcAtFinish();
-        varReplacer->extendModel();
-        // Extend & copy model:
-        model.growTo(nVars());
-        for (uint32_t i = 0; i != nVars(); i++) model[i] = value(i);
-#ifndef NDEBUG
-        verifyModel();
-#endif
         if (greedyUnbound) {
             double time = cpuTime();
             FindUndef finder(*this);
@@ -1486,7 +2010,48 @@ lbool Solver::solve(const vec<Lit>& assumps)
             if (verbosity >= 1)
                 printf("c Greedy unbounding     :%5.2lf s, unbounded: %7d vars\n", cpuTime()-time, unbounded);
         }
-    } if (status == l_False) {
+        
+        partHandler->addSavedState();
+        conglomerate->doCalcAtFinish();
+        varReplacer->extendModelPossible();
+#ifndef NDEBUG
+        //checkSolution();
+#endif
+        
+        if (subsumer->getNumElimed() > 0) {
+            Solver s;
+            s.doSubsumption = false;
+            s.findBinaryXors = false;
+            s.findNormalXors = false;
+            s.failedVarSearch = false;
+            s.greedyUnbound = greedyUnbound;
+            for (Var var = 0; var < nVars(); var++) {
+                s.newVar(decision_var[var] || subsumer->getVarElimed()[var] || varReplacer->varHasBeenReplaced(var));
+                if (value(var) != l_Undef) {
+                    vec<Lit> tmp;
+                    tmp.push(Lit(var, value(var) == l_False));
+                    s.addClause(tmp);
+                }
+            }
+            varReplacer->extendModelImpossible(s);
+            subsumer->extendModel(s);
+            
+            status = s.solve();
+            assert(status == l_True);
+            for (Var var = 0; var < nVars(); var++) {
+                if (assigns[var] == l_Undef) uncheckedEnqueue(Lit(var, s.model[var] == l_False));
+            }
+        }
+        // Extend & copy model:
+#ifndef NDEBUG
+        //checkSolution();
+#endif
+        model.growTo(nVars());
+        for (Var var = 0; var != nVars(); var++) model[var] = value(var);
+    
+    }
+    
+    if (status == l_False) {
         if (conflict.size() == 0)
             ok = false;
     }
@@ -1505,10 +2070,12 @@ lbool Solver::solve(const vec<Lit>& assumps)
     #ifdef LS_STATS_NBBUMP
     for(int i=0;i<learnts.size();i++)
         printf("## %d %d %d\n", learnts[i]->size(),learnts[i]->activity(),
-               (unsigned int)learnts[i]->nbBump());
+               (uint)learnts[i]->nbBump());
     #endif
 
     cancelUntil(0);
+    if (doPartHandler && status != l_False) partHandler->readdRemovedClauses();
+    
     return status;
 }
 
@@ -1528,7 +2095,7 @@ bool Solver::verifyXorClauses(const vec<XorClause*>& cs) const
         bool final = c.xor_clause_inverted();
         
         #ifdef VERBOSE_DEBUG
-        XorClause* c2 = XorClause_new(c, c.xor_clause_inverted(), c.group);
+        XorClause* c2 = XorClause_new(c, c.xor_clause_inverted(), c.getGroup());
         std::sort(c2->getData(), c2->getData()+ c2->size());
         c2->plainPrint();
         free(c2);
@@ -1548,26 +2115,37 @@ bool Solver::verifyXorClauses(const vec<XorClause*>& cs) const
     return failed;
 }
 
-void Solver::verifyModel()
+bool Solver::verifyClauses(const vec<Clause*>& cs) const
 {
+    #ifdef VERBOSE_DEBUG
+    cout << "Checking clauses whether they have been properly satisfied." << endl;;
+    #endif
+    
     bool failed = false;
-    for (uint32_t i = 0; i != clauses.size(); i++) {
-        Clause& c = *clauses[i];
+    
+    for (uint32_t i = 0; i != cs.size(); i++) {
+        Clause& c = *cs[i];
         for (uint j = 0; j < c.size(); j++)
             if (modelValue(c[j]) == l_True)
                 goto next;
-
+            
         printf("unsatisfied clause: ");
-        clauses[i]->plainPrint();
+        cs[i]->plainPrint();
         failed = true;
-next:
+    next:
         ;
     }
     
-    failed |= verifyXorClauses(xorclauses);
-    failed |= verifyXorClauses(conglomerate->getCalcAtFinish());
+    return failed;
+}
 
-    assert(!failed);
+void Solver::verifyModel()
+{
+    assert(!verifyClauses(clauses));
+    assert(!verifyClauses(binaryClauses));
+    
+    assert(!verifyXorClauses(xorclauses));
+    assert(!verifyXorClauses(conglomerate->getCalcAtFinish()));
 
     if (verbosity >=1)
         printf("c Verified %d clauses.\n", clauses.size() + xorclauses.size() + conglomerate->getCalcAtFinish().size());
@@ -1607,11 +2185,11 @@ void Solver::printStatHeader() const
 void Solver::printRestartStat() const
 {
     #ifdef STATS_NEEDED
-    if (verbosity >= 1 && !(dynamic_behaviour_analysis && logger.statistics_on)) {
+    if (verbosity >= 2 && !(dynamic_behaviour_analysis && logger.statistics_on)) {
     #else
-    if (verbosity >= 1) {
+    if (verbosity >= 2) {
     #endif
-        printf("c | %9d | %7d %8d %8d | %8d %8d %6.0f |", (int)conflicts, (int)order_heap.size(), (int)nClauses(), (int)clauses_literals, (int)(nbclausesbeforereduce*curRestart), (int)nLearnts(), (double)learnts_literals/nLearnts());
+    printf("c | %9d | %7d %8d %8d | %8d %8d %6.0f |", (int)conflicts, (int)order_heap.size(), (int)nClauses(), (int)clauses_literals, (int)(nbclausesbeforereduce*curRestart+nbCompensateSubsumer), (int)nLearnts(), (double)learnts_literals/nLearnts());
         print_gauss_sum_stats();
     }
 }
@@ -1628,5 +2206,5 @@ void Solver::printEndSearchStat() const
         }
 }
 
+}; //NAMESPACE MINISAT
 
-};
index 58e2f23b076c7b6ae15c4a18325134dc33fb7e11..3cab2f9c1abe425ca936e8e15d3d44ba4302de7f 100644 (file)
@@ -25,27 +25,22 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
 #include <cstdio>
 #include <string.h>
 #include <stdio.h>
+#ifdef _MSC_VER
+#include <msvc/stdint.h>
+#else
+#include <stdint.h>
+#endif //_MSC_VER
 
-#include "mtl/Vec.h"
-#include "mtl/Heap.h"
-#include "mtl/Alg.h"
-#include "MTRand/MersenneTwister.h"
+#include "Vec.h"
+#include "Heap.h"
+#include "Alg.h"
+#include "MersenneTwister.h"
 #include "SolverTypes.h"
 #include "Clause.h"
-#include "VarReplacer.h"
 #include "GaussianConfig.h"
 #include "Logger.h"
 #include "constants.h"
 #include "BoundedQueue.h"
-#include "RestartTypeChooser.h"
-
-#ifdef _MSC_VER
-  #include <ctime>
-#else
-  #include <sys/time.h>
-  #include <sys/resource.h>
-  #include <unistd.h>
-#endif
 
 namespace MINISAT
 {
@@ -58,16 +53,20 @@ class VarReplacer;
 class XorFinder;
 class FindUndef;
 class ClauseCleaner;
+class FailedVarSearcher;
+class Subsumer;
+class PartHandler;
+class RestartTypeChooser;
 
 #ifdef VERBOSE_DEBUG
 using std::cout;
 using std::endl;
 #endif
 
-
 //=================================================================================================
 // Solver -- the main class:
 
+
 class Solver
 {
 public:
@@ -79,9 +78,11 @@ public:
 
     // Problem specification:
     //
-    Var     newVar    (bool polarity = true, bool dvar = true); // Add a new variable with parameters specifying variable mode.
-    bool    addClause (vec<Lit>& ps, const uint group, char* group_name);  // Add a clause to the solver. NOTE! 'ps' may be shrunk by this method!
-    bool    addXorClause (vec<Lit>& ps, bool xor_clause_inverted, const uint group, char* group_name, const bool internal = false);  // Add a xor-clause to the solver. NOTE! 'ps' may be shrunk by this method!
+    Var     newVar    (bool dvar = true); // Add a new variable with parameters specifying variable mode.
+    template<class T>
+    bool    addClause (T& ps, const uint group = 0, char* group_name = "");  // Add a clause to the solver. NOTE! 'ps' may be shrunk by this method!
+    template<class T>
+    bool    addXorClause (T& ps, bool xor_clause_inverted, const uint group = 0, char* group_name = "");  // Add a xor-clause to the solver. NOTE! 'ps' may be shrunk by this method!
 
     // Solving:
     //
@@ -95,15 +96,6 @@ public:
     void    setDecisionVar (Var v, bool b); // Declare if a variable should be eligible for selection in the decision heuristic.
     void    setSeed (const uint32_t seed);  // Sets the seed to be the given number
     void    setMaxRestarts(const uint num); //sets the maximum number of restarts to given value
-    void    set_gaussian_decision_until(const uint to);
-    template<class T>
-    void    removeWatchedCl(vec<T> &ws, const Clause *c);
-    template<class T>
-    bool    findWatchedCl(vec<T>& ws, const Clause *c);
-    template<class T>
-    void    removeWatchedBinCl(vec<T> &ws, const Clause *c);
-    template<class T>
-    bool    findWatchedBinCl(vec<T>& ws, const Clause *c);
 
     // Read state:
     //
@@ -112,6 +104,7 @@ public:
     lbool   modelValue (const Lit& p) const;       // The value of a literal in the last model. The last call to solve must have been satisfiable.
     uint32_t     nAssigns   ()      const;       // The current number of assigned literals.
     uint32_t     nClauses   ()      const;       // The current number of original clauses.
+    uint32_t     nLiterals  ()      const;       // The current number of total literals.
     uint32_t     nLearnts   ()      const;       // The current number of learnt clauses.
     uint32_t     nVars      ()      const;       // The current number of variables.
 
@@ -133,20 +126,34 @@ public:
     int       polarity_mode;      // Controls which polarity the decision heuristic chooses. See enum below for allowed modes. (default polarity_false)
     int       verbosity;          // Verbosity level. 0=silent, 1=some progress report                                         (default 0)
     Var       restrictedPickBranch; // Pick variables to branch on preferentally from the highest [0, restrictedPickBranch]. If set to 0, preferentiality is turned off (i.e. picked randomly between [0, all])
-    bool      xorFinder;            // Automatically find xor-clauses and convert them
+    bool      findNormalXors;     // Automatically find non-binary xor-clauses and convert them
+    bool      findBinaryXors;     // Automatically find binary xor-clauses and convert them
+    bool      regularlyFindBinaryXors; // Regularly find binary xor-clauses and convert them
     bool      performReplace;       // Should var-replacing be performed?
+    bool      conglomerateXors;   // Conglomerate XORs
+    bool      heuleProcess;       // Process XORs according to Heule
+    bool      schedSimplification;// Schedule simplification
+    bool      doSubsumption;        // Should try to subsume clauses
+    bool      doXorSubsumption;     // Should try to subsume xor clauses
+    bool      doPartHandler;        // Should try to subsume clauses
+    bool      doHyperBinRes;        // Should try carry out hyper-binary resolution
+    bool      doBlockedClause;      // Should try to remove blocked clauses
+    bool      failedVarSearch;      // Should search for failed vars and doulbly propagated vars
+    bool      libraryUsage;         // Set true if not used as a library
+    bool      sateliteUsed;         // whether satielite was used on CNF before calling
     friend class FindUndef;
     bool      greedyUnbound;        //If set, then variables will be greedily unbounded (set to l_Undef)
     RestartType fixRestartType;     // If set, the solver will always choose the given restart strategy
-    
+    GaussianConfig gaussconfig;
 
-    enum { polarity_true = 0, polarity_false = 1, polarity_user = 2, polarity_rnd = 3 };
+    enum { polarity_true = 0, polarity_false = 1, polarity_rnd = 3, polarity_auto = 4, polarity_manual = 5};
 
     // Statistics: (read-only member variable)
     //
-    uint64_t starts, decisions, rnd_decisions, propagations, conflicts;
+    uint64_t starts, dynStarts, staticStarts, fullStarts, decisions, rnd_decisions, propagations, conflicts;
     uint64_t clauses_literals, learnts_literals, max_literals, tot_literals;
-    uint64_t nbDL2, nbBin, lastNbBin, nbReduceDB;
+    uint64_t nbDL2, nbBin, lastNbBin, becameBinary, lastSearchForBinaryXor, nbReduceDB;
+    uint64_t improvedClauseNo, improvedClauseSize;
 
     //Logging
     void needStats();              // Prepares the solver to output statistics
@@ -156,16 +163,29 @@ public:
     const vec<Clause*>& get_learnts() const; //Get all learnt clauses that are >1 long
     const vector<Lit> get_unitary_learnts() const; //return the set of unitary learnt clauses
     const uint get_unitary_learnts_num() const; //return the number of unitary learnt clauses
-    void dump_sorted_learnts(const char* file); // Dumps all learnt clauses (including unitary ones) into the file
+    void dumpSortedLearnts(const char* file, const uint32_t maxSize); // Dumps all learnt clauses (including unitary ones) into the file
     void needLibraryCNFFile(const char* fileName); //creates file in current directory with the filename indicated, and puts all calls from the library into the file.
 
 protected:
     vector<Gaussian*> gauss_matrixes;
-    GaussianConfig gaussconfig;
     void print_gauss_sum_stats() const;
     void clearGaussMatrixes();
     friend class Gaussian;
     
+    template <class T>
+    Clause* addClauseInt(T& ps, uint group);
+    template<class T>
+    XorClause* addXorClauseInt(T& ps, bool xor_clause_inverted, const uint32_t group);
+    template<class T>
+    bool addLearntClause(T& ps, const uint group, const uint32_t activity);
+    template<class T>
+    void    removeWatchedCl(vec<T> &ws, const Clause *c);
+    template<class T>
+    bool    findWatchedCl(vec<T>& ws, const Clause *c);
+    template<class T>
+    void    removeWatchedBinCl(vec<T> &ws, const Clause *c);
+    template<class T>
+    bool    findWatchedBinCl(vec<T>& ws, const Clause *c);
     
     // Helper structures:
     //
@@ -190,28 +210,29 @@ protected:
     //
     bool                ok;               // If FALSE, the constraints are already unsatisfiable. No part of the solver state may be used!
     vec<Clause*>        clauses;          // List of problem clauses.
+    vec<Clause*>        binaryClauses;    // Binary clauses are regularly moved here
     vec<XorClause*>     xorclauses;       // List of problem xor-clauses. Will be freed
     vec<Clause*>        learnts;          // List of learnt clauses.
     vec<XorClause*>     freeLater;        // List of xorclauses to free at the end (due to matrixes, they cannot be freed immediately)
     vec<double>         activity;         // A heuristic measurement of the activity of a variable.
     double              var_inc;          // Amount to bump next variable with.
     vec<vec<Watched> >  watches;          // 'watches[lit]' is a list of constraints watching 'lit' (will go there if literal becomes true).
-    vec<vec<XorClause*> >  xorwatches;    // 'xorwatches[var]' is a list of constraints watching var in XOR clauses.
+    vec<vec<XorClausePtr> > xorwatches;   // 'xorwatches[var]' is a list of constraints watching var in XOR clauses.
     vec<vec<WatchedBin> >  binwatches;
     vec<lbool>          assigns;          // The current assignments
     vector<bool>        polarity;         // The preferred polarity of each variable.
     vector<bool>        decision_var;     // 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<uint32_t>       trail_lim;        // Separator indices for different decision levels in 'trail'.
-    vec<Clause*>        reason;           // 'reason[var]' is the clause that implied the variables current value, or 'NULL' if none.
+    vec<ClausePtr>      reason;           // 'reason[var]' is the clause that implied the variables current value, or 'NULL' if none.
     vec<int32_t>        level;            // 'level[var]' contains the level at which the assignment was made.
     vec<Var>            permDiff;         // LS: permDiff[var] contains the current conflict number... Used to count the number of different decision level variables in learnt clause
     #ifdef UPDATEVARACTIVITY
     vec<Lit>            lastDecisionLevel;
     #endif
     uint64_t            curRestart;
-    uint64_t            conf4Stats;
     uint32_t            nbclausesbeforereduce;
+    uint32_t            nbCompensateSubsumer; // Number of learnt clauses that subsumed normal clauses last time subs. was executed
     uint32_t            qhead;            // Head of queue (as index into the trail -- no more explicit propagation queue in MiniSat).
     uint32_t            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()'.
@@ -219,8 +240,10 @@ protected:
     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'.
-    bqueue<unsigned int> nbDecisionLevelHistory; // Set of last decision level in conflict clauses
-    float               totalSumOfDecisionLevel;
+    bqueue<uint>        nbDecisionLevelHistory; // Set of last decision level in conflict clauses
+    double              totalSumOfDecisionLevel;
+    uint64_t            conflictsAtLastSolve;
+    bqueue<uint>        avgBranchDepth; // Avg branch depth
     MTRand              mtrand;           // random number generaton
     RestartType         restartType;      // Used internally to determine which restart strategy to choose
     friend class        Logger;
@@ -233,7 +256,7 @@ protected:
     // 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;
+    vector<bool>        seen;
     vec<Lit>            analyze_stack;
     vec<Lit>            analyze_toclear;
     vec<Lit>            add_tmp;
@@ -248,20 +271,20 @@ protected:
     lbool    simplify    ();                                                           // Removes already satisfied clauses.
     //int      nbPropagated     (int level);
     void     insertVarOrder   (Var x);                                                 // Insert a variable in the decision order priority queue.
-    Lit      pickBranchLit    (int polarity_mode);                                     // Return the next decision variable.
+    Lit      pickBranchLit    ();                                                      // Return the next decision variable.
     void     newDecisionLevel ();                                                      // Begins a new decision level.
-    void     uncheckedEnqueue (Lit p, Clause* from = NULL);                            // Enqueue a literal. Assumes value of literal is undefined.
+    void     uncheckedEnqueue (Lit p, ClausePtr from = (Clause*)NULL);                 // Enqueue a literal. Assumes value of literal is undefined.
     bool     enqueue          (Lit p, Clause* from = NULL);                            // Test if fact 'p' contradicts current state, enqueue otherwise.
-    Clause*  propagate        (const bool xor_as_well = true);                         // Perform unit propagation. Returns possibly conflicting clause.
+    Clause*  propagate        (const bool update = true);                         // Perform unit propagation. Returns possibly conflicting clause.
     Clause*  propagate_xors   (const Lit& p);
     void     cancelUntil      (int level);                                             // Backtrack until a certain level.
-    void     analyze          (Clause* confl, vec<Lit>& out_learnt, int& out_btlevel, int &nblevels); // (bt = backtrack)
+    Clause*  analyze          (Clause* confl, vec<Lit>& out_learnt, int& out_btlevel, int &nblevels); // (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    search           (int nof_conflicts, int nof_conflicts_fullrestart, const bool update = true);      // Search for a given number of conflicts.
     void     reduceDB         ();                                                      // Reduce the set of learnt clauses.
-    llbool   handle_conflict  (vec<Lit>& learnt_clause, Clause* confl, int& conflictC);// Handles the conflict clause
-    llbool   new_decision     (int& nof_conflicts, int& conflictC);                    // Handles the case when all propagations have been made, and now a decision must be made
+    llbool   handle_conflict  (vec<Lit>& learnt_clause, Clause* confl, int& conflictC, const bool update);// Handles the conflict clause
+    llbool   new_decision     (const int& nof_conflicts, const int& nof_conflicts_fullrestart, int& conflictC);  // Handles the case when all propagations have been made, and now a decision must be made
 
     // Maintaining Variable/Clause activity:
     //
@@ -291,24 +314,45 @@ protected:
     friend class XorFinder;
     friend class Conglomerate;
     friend class MatrixFinder;
+    friend class PartFinder;
     friend class VarReplacer;
     friend class ClauseCleaner;
     friend class RestartTypeChooser;
+    friend class FailedVarSearcher;
+    friend class Subsumer;
+    friend class XorSubsumer;
+    friend class PartHandler;
     Conglomerate* conglomerate;
     VarReplacer* varReplacer;
     ClauseCleaner* clauseCleaner;
-    void chooseRestartType(const lbool& status, RestartTypeChooser& restartTypeChooser);
+    FailedVarSearcher* failedVarSearcher;
+    PartHandler* partHandler;
+    Subsumer* subsumer;
+    RestartTypeChooser* restartTypeChooser;
+    void chooseRestartType(const uint& lastFullRestart);
+    void setDefaultRestartType();
+    const bool checkFullRestart(int& nof_conflicts, int& nof_conflicts_fullrestart, uint& lastFullRestart);
     void performStepsBeforeSolve();
+    const lbool simplifyProblem(const uint32_t numConfls, const uint64_t numProps);
+    bool simplifying;
 
     // Debug & etc:
     void     printLit         (const Lit l) const;
     void     verifyModel      ();
+    bool     verifyClauses    (const vec<Clause*>& cs) const;
     bool     verifyXorClauses (const vec<XorClause*>& cs) const;
+    void     checkSolution();
     void     checkLiteralCount();
     void     printStatHeader  () const;
     void     printRestartStat () const;
     void     printEndSearchStat() const;
     double   progressEstimate () const; // DELETE THIS ?? IT'S NOT VERY USEFUL ...
+    
+    // Polarity chooser
+    vector<bool> defaultPolarities; //The default polarity to set the var polarity when doing a full restart
+    const lbool  calculateDefaultPolarities(); //Calculates the default polarity for each var, and fills defaultPolarities[] with it
+    bool         defaultPolarity(); //if polarity_mode is not polarity_auto, this returns the default polarity of the variable
+    void         setDefaultPolarities(); //sets the polarity[] to that indicated by defaultPolarities[]
 };
 
 
@@ -328,10 +372,22 @@ inline void Solver::varDecayActivity()
 inline void Solver::varBumpActivity(Var v)
 {
     if ( (activity[v] += var_inc) > 1e100 ) {
+        //printf("RESCALE!!!!!!\n");
+        //std::cout << "var_inc: " << var_inc << std::endl;
         // Rescale:
-        for (uint32_t i = 0; i != nVars(); i++)
-            activity[i] *= 1e-100;
+        for (Var var = 0; var != nVars(); var++) {
+            activity[var] *= 1e-95;
+        }
         var_inc *= 1e-100;
+        //var_inc = 1;
+        //std::cout << "var_inc: " << var_inc << std::endl;
+        
+        /*Heap<VarOrderLt> copy_order_heap2(order_heap);
+        while(!copy_order_heap2.empty()) {
+            Var v = copy_order_heap2.getmin();
+            if (decision_var[v])
+                std::cout << "var_" << v+1 << " act: " << activity[v] << std::endl;
+        }*/
     }
 
     // Update order_heap with respect to new activity:
@@ -385,7 +441,11 @@ inline uint32_t      Solver::nAssigns      ()      const
 }
 inline uint32_t      Solver::nClauses      ()      const
 {
-    return clauses.size() + xorclauses.size();
+    return clauses.size() + xorclauses.size()+binaryClauses.size();
+}
+inline uint32_t      Solver::nLiterals      ()      const
+{
+    return clauses_literals + learnts_literals;
 }
 inline uint32_t      Solver::nLearnts      ()      const
 {
@@ -440,6 +500,7 @@ inline void     Solver::setVariableName(Var var, char* name)
 inline void     Solver::setVariableName(Var var, char* name)
 {}
 #endif
+
 inline const uint Solver::get_unitary_learnts_num() const
 {
     if (decisionLevel() > 0)
@@ -484,16 +545,33 @@ inline void Solver::reverse_binary_clause(Clause& c) const {
         c[0] =  c[1], c[1] = tmp;
     }
 }
+/*inline void Solver::calculate_xor_clause(Clause& c2) const {
+    if (c2.isXor() && ((XorClause*)&c2)->updateNeeded())  {
+        XorClause& c = *((XorClause*)&c2);
+        bool final = c.xor_clause_inverted();
+        for (int k = 0, size = c.size(); k != size; k++ ) {
+            const lbool& val = assigns[c[k].var()];
+            assert(val != l_Undef);
+            
+            c[k] = c[k].unsign() ^ val.getBool();
+            final ^= val.getBool();
+        }
+        if (final)
+            c[0] = c[0].unsign() ^ !assigns[c[0].var()].getBool();
+        
+        c.setUpdateNeeded(false);
+    }
+}*/
+
 inline void Solver::removeClause(Clause& c)
 {
     detachClause(c);
-    free(&c);
+    clauseFree(&c);
 }
 inline void Solver::removeClause(XorClause& c)
 {
     detachClause(c);
     freeLater.push(&c);
-    c.mark(1);
 }
 
 
@@ -531,6 +609,7 @@ static inline void check(bool expr)
 }
 
 //=================================================================================================
-};
+
+}; //NAMESPACE MINISAT
 
 #endif //SOLVER_H
index 58f61c6db418bc401e261aac70fa446c9ab88871..5c64d7b40e3d296e004a7a31a6ec45b2b10b745c 100644 (file)
@@ -23,8 +23,13 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
 #define SOLVERTYPES_H
 
 #include <cassert>
+#ifdef _MSC_VER
+#include <msvc/stdint.h>
+#else
 #include <stdint.h>
-#include "mtl/Alg.h"
+#endif //_MSC_VER
+
+#include "Alg.h"
 
 namespace MINISAT
 {
@@ -56,10 +61,10 @@ public:
         return Lit(x ^ 1);
     }
     Lit  operator^(const bool b) const {
-        return Lit(x ^ b);
+        return Lit(x ^ (uint32_t)b);
     }
     Lit& operator^=(const bool b) {
-        x ^= b;
+        x ^= (uint32_t)b;
         return *this;
     }
     bool sign() const {
@@ -109,7 +114,7 @@ public:
         return value;
     }
     inline const bool getBool() const {
-        return (value+1) >> 1;
+        return value == 1;
     }
     inline const bool operator==(lbool b) const {
         return value == b.value;
@@ -118,7 +123,7 @@ public:
         return value != b.value;
     }
     lbool operator^(const bool b) const {
-        return lbool(value - value*2*b);
+        return b ? lbool(-value) : lbool(value);
     }
     //lbool operator ^ (const bool b) const { return b ? lbool(-value) : lbool(value); }
 
@@ -165,6 +170,7 @@ const llbool l_Nothing  = toLbool(2);
 const llbool l_Continue = toLbool(3);
 
 lbool::lbool(llbool b) : value(b.value) {};
-};
+
+}; //NAMESPACE MINISAT
 
 #endif //SOLVERTYPES_H
diff --git a/src/sat/cryptominisat2/Subsumer.cpp b/src/sat/cryptominisat2/Subsumer.cpp
new file mode 100644 (file)
index 0000000..0295fd8
--- /dev/null
@@ -0,0 +1,2033 @@
+/**************************************************************************************************
+Originally From: Solver.C -- (C) Niklas Een, Niklas Sorensson, 2004
+Substantially modified by: Mate Soos (2010)
+**************************************************************************************************/
+
+#include "Solver.h"
+#include "Subsumer.h"
+#include "ClauseCleaner.h"
+#include "time_mem.h"
+#include "assert.h"
+#include <iomanip>
+#include <cmath>
+#include <algorithm>
+#include "VarReplacer.h"
+#include "Conglomerate.h"
+#include "XorFinder.h"
+
+#ifdef _MSC_VER
+#define __builtin_prefetch(a,b,c)
+#endif //_MSC_VER
+
+
+//#define VERBOSE_DEBUG
+#ifdef VERBOSE_DEBUG
+#define BIT_MORE_VERBOSITY
+#endif
+
+//#define BIT_MORE_VERBOSITY
+//#define HYPER_DEBUG
+//#define HYPER_DEBUG2
+//#define TOUCH_LESS
+
+#ifdef VERBOSE_DEBUG
+using std::cout;
+using std::endl;
+#endif //VERBOSE_DEBUG
+
+namespace MINISAT
+{
+using namespace MINISAT;
+
+Subsumer::Subsumer(Solver& s):
+    solver(s)
+    , numCalls(0)
+    , numElimed(0)
+{
+};
+
+Subsumer::~Subsumer()
+{
+}
+
+void Subsumer::extendModel(Solver& solver2)
+{
+    vec<Lit> tmp;
+    typedef map<Var, vector<vector<Lit> > > elimType;
+    for (elimType::iterator it = elimedOutVar.begin(), end = elimedOutVar.end(); it != end; it++) {
+        Var var = it->first;
+        
+        #ifdef VERBOSE_DEBUG
+        std::cout << "Reinserting elimed var: " << var+1 << std::endl;
+        #endif
+        
+        for (vector<vector<Lit> >::iterator it2 = it->second.begin(), end2 = it->second.end(); it2 != end2; it2++) {
+            tmp.clear();
+            tmp.growTo(it2->size());
+            std::copy(it2->begin(), it2->end(), tmp.getData());
+            
+            #ifdef VERBOSE_DEBUG
+            std::cout << "Reinserting Clause: ";
+            for (uint32_t i = 0; i < tmp.size(); i++) {
+                std::cout << (tmp[i].sign() ? "-" : "")<< tmp[i].var()+1 << " ";
+            }
+            std::cout << std::endl;
+            #endif
+            
+            solver2.addClause(tmp);
+            assert(solver2.ok);
+        }
+    }
+}
+
+const bool Subsumer::unEliminate(const Var var)
+{
+    vec<Lit> tmp;
+    typedef map<Var, vector<vector<Lit> > > elimType;
+    elimType::iterator it = elimedOutVar.find(var);
+    assert(it != elimedOutVar.end());
+    
+    solver.setDecisionVar(var, true);
+    var_elimed[var] = false;
+    numElimed--;
+    for (vector<vector<Lit> >::iterator it2 = it->second.begin(), end2 = it->second.end(); it2 != end2; it2++) {
+        tmp.clear();
+        tmp.growTo(it2->size());
+        memcpy(tmp.getData(), &((*it2)[0]), sizeof(Lit)*it2->size());  //*it2 is never empty
+        solver.addClause(tmp);
+    }
+    elimedOutVar.erase(it);
+    
+    if (!solver.ok) return false;
+    return true;
+}
+
+bool selfSubset(uint32_t A, uint32_t B)
+{
+    uint32_t B_tmp = B | ((B & 0xAAAAAAAALL) >> 1) | ((B & 0x55555555LL) << 1);
+    if ((A & ~B_tmp) == 0){
+        uint32_t C = A & ~B;
+        return (C & (C-1)) == 0;
+    }else
+        return false;
+}
+
+// Assumes 'seen' is cleared (will leave it cleared)
+bool selfSubset(Clause& A, Clause& B, vec<char>& seen)
+{
+    for (uint32_t i = 0; i < B.size(); i++)
+        seen[B[i].toInt()] = 1;
+    
+    bool    flip = false;
+    for (uint32_t i = 0; i < A.size(); i++) {
+        if (!seen[A[i].toInt()]) {
+            if (flip == true || !seen[(~A[i]).toInt()]) {
+                for (uint32_t i = 0; i < B.size(); i++) seen[B[i].toInt()] = 0;
+                return false;
+            }
+            flip = true;
+        }
+    }
+    for (uint32_t i = 0; i < B.size(); i++)
+        seen[B[i].toInt()] = 0;
+    return flip;
+}
+
+// Will put NULL in 'cs' if clause removed.
+uint32_t Subsumer::subsume0(Clause& ps)
+{
+    ps.subsume0Finished();
+    ps.unsetVarChanged();
+    uint32_t retIndex = std::numeric_limits<uint32_t>::max();
+    #ifdef VERBOSE_DEBUG
+    cout << "subsume0 orig clause:";
+    ps.plainPrint();
+    cout << "pointer:" << &ps << endl;
+    #endif
+    
+    vec<ClauseSimp> subs;
+    findSubsumed(ps, subs);
+    for (uint32_t i = 0; i < subs.size(); i++){
+        clauses_subsumed++;
+        #ifdef VERBOSE_DEBUG
+        cout << "subsume0 removing:";
+        subs[i].clause->plainPrint();
+        #endif
+        
+        Clause* tmp = subs[i].clause;
+        unlinkClause(subs[i]);
+        free(tmp);
+        retIndex = subs[i].index;
+    }
+    
+    return retIndex;
+}
+
+// Will put NULL in 'cs' if clause removed.
+uint32_t Subsumer::subsume0(Clause& ps, uint32_t abs)
+{
+    ps.subsume0Finished();
+    ps.unsetVarChanged();
+    uint32_t retIndex = std::numeric_limits<uint32_t>::max();
+    #ifdef VERBOSE_DEBUG
+    cout << "subsume0 orig clause:";
+    ps.plainPrint();
+    cout << "pointer:" << &ps << endl;
+    #endif
+    
+    vec<ClauseSimp> subs;
+    findSubsumed(ps, abs, subs);
+    for (uint32_t i = 0; i < subs.size(); i++){
+        clauses_subsumed++;
+        #ifdef VERBOSE_DEBUG
+        cout << "subsume0 removing:";
+        subs[i].clause->plainPrint();
+        #endif
+        
+        Clause* tmp = subs[i].clause;
+        unlinkClause(subs[i]);
+        free(tmp);
+        retIndex = subs[i].index;
+    }
+    
+    return retIndex;
+}
+
+void Subsumer::unlinkClause(ClauseSimp c, Var elim)
+{
+    Clause& cl = *c.clause;
+    
+    if (elim != var_Undef) {
+        assert(!cl.learnt());
+        io_tmp.clear();
+        for (int i = 0; i < cl.size(); i++)
+            io_tmp.push_back(cl[i]);
+        elimedOutVar[elim].push_back(io_tmp);
+    }
+    
+    if (updateOccur(cl)) {
+        for (uint32_t i = 0; i < cl.size(); i++) {
+            maybeRemove(occur[cl[i].toInt()], &cl);
+            #ifndef TOUCH_LESS
+            touch(cl[i]);
+            #endif
+        }
+    }
+    
+    solver.detachClause(cl);
+    
+    // Remove from iterator vectors/sets:
+    for (uint32_t i = 0; i < iter_vecs.size(); i++) {
+        vec<ClauseSimp>& cs = *iter_vecs[i];
+        for (uint32_t j = 0; j < cs.size(); j++)
+            if (cs[j].clause == &cl)
+                cs[j].clause = NULL;
+    }
+    for (uint32_t i = 0; i < iter_sets.size(); i++) {
+        CSet& cs = *iter_sets[i];
+        cs.exclude(c);
+    }
+    
+    // Remove clause from clause touched set:
+    if (updateOccur(cl)) {
+        cl_touched.exclude(c);
+        cl_added.exclude(c);
+    }
+    
+    clauses[c.index].clause = NULL;
+}
+
+void Subsumer::unlinkModifiedClause(vec<Lit>& origClause, ClauseSimp c)
+{
+    if (updateOccur(*c.clause)) {
+        for (uint32_t i = 0; i < origClause.size(); i++) {
+            maybeRemove(occur[origClause[i].toInt()], c.clause);
+            #ifndef TOUCH_LESS
+            touch(origClause[i]);
+            #endif
+        }
+    }
+    
+    solver.detachModifiedClause(origClause[0], origClause[1], origClause.size(), c.clause);
+    
+    // Remove from iterator vectors/sets:
+    for (uint32_t i = 0; i < iter_vecs.size(); i++){
+        vec<ClauseSimp>& cs = *iter_vecs[i];
+        for (uint32_t j = 0; j < cs.size(); j++)
+            if (cs[j].clause == c.clause)
+                cs[j].clause = NULL;
+    }
+    for (uint32_t i = 0; i < iter_sets.size(); i++){
+        CSet& cs = *iter_sets[i];
+        cs.exclude(c);
+    }
+    
+    // Remove clause from clause touched set:
+    if (updateOccur(*c.clause)) {
+        cl_touched.exclude(c);
+        cl_added.exclude(c);
+    }
+    
+    clauses[c.index].clause = NULL;
+}
+
+void Subsumer::unlinkModifiedClauseNoDetachNoNULL(vec<Lit>& origClause, ClauseSimp c)
+{
+    if (updateOccur(*c.clause)) {
+        for (uint32_t i = 0; i < origClause.size(); i++) {
+            maybeRemove(occur[origClause[i].toInt()], c.clause);
+            #ifndef TOUCH_LESS
+            touch(origClause[i]);
+            #endif
+        }
+    }
+    
+    // Remove from iterator vectors/sets:
+    for (uint32_t i = 0; i < iter_vecs.size(); i++){
+        vec<ClauseSimp>& cs = *iter_vecs[i];
+        for (uint32_t j = 0; j < cs.size(); j++)
+            if (cs[j].clause == c.clause)
+                cs[j].clause = NULL;
+    }
+    for (uint32_t i = 0; i < iter_sets.size(); i++){
+        CSet& cs = *iter_sets[i];
+        cs.exclude(c);
+    }
+    
+    // Remove clause from clause touched set:
+    if (updateOccur(*c.clause)) {
+        cl_touched.exclude(c);
+        cl_added.exclude(c);
+    }
+}
+
+void Subsumer::subsume1(ClauseSimp& ps)
+{
+    vec<ClauseSimp>    Q;
+    vec<ClauseSimp>    subs;
+    vec<Lit>        qs;
+    uint32_t        q;
+    
+    ps.clause->unsetStrenghtened();
+    registerIteration(Q);
+    registerIteration(subs);
+    
+    Q.push(ps);
+    q = 0;
+    while (q < Q.size()){
+        if (Q[q].clause == NULL) { q++; continue; }
+        #ifdef VERBOSE_DEBUG
+        cout << "subsume1 orig clause:";
+        Q[q].clause->plainPrint();
+        #endif
+        
+        qs.clear();
+        for (uint32_t i = 0; i < Q[q].clause->size(); i++)
+            qs.push((*Q[q].clause)[i]);
+        
+        for (uint32_t i = 0; i < qs.size(); i++){
+            qs[i] = ~qs[i];
+            
+            uint32_t abst = calcAbstraction(qs);
+            
+            findSubsumed(qs, abst, subs);
+            for (uint32_t j = 0; j < subs.size(); j++){
+                /*#ifndef NDEBUG
+                if (&counter != NULL && counter == -1){
+                    dump(*subs[j].clause);
+                    qs[i] = ~qs[i];
+                    dump(qs);
+                    printf(L_LIT"\n", L_lit(qs[i]));
+                    exit(0);
+                }
+                #endif*/
+                if (subs[j].clause == NULL) continue;
+                ClauseSimp c = subs[j];
+                Clause& cl = *c.clause;
+                #ifdef VERBOSE_DEBUG
+                cout << "orig clause    :";
+                cl.plainPrint();
+                #endif
+                unlinkClause(subs[j]);
+                
+                literals_removed++;
+                cl.strengthen(qs[i]);
+                Lit *a, *b, *end;
+                for (a = b = cl.getData(), end = a + cl.size();  a != end; a++) {
+                    lbool val = solver.value(*a);
+                    if (val == l_Undef)
+                        *b++ = *a;
+                    
+                    if (val == l_True) {
+                        free(&cl);
+                        goto endS;
+                    }
+                }
+                cl.shrink(a-b);
+                cl.setStrenghtened();
+                
+                #ifdef VERBOSE_DEBUG
+                cout << "strenghtened   :";
+                c.clause->plainPrint();
+                #endif
+                
+                if (cl.size() == 0) {
+                    solver.ok = false;
+                    unregisterIteration(Q);
+                    unregisterIteration(subs);
+                    free(&cl);
+                    return;
+                }
+                if (cl.size() > 1) {
+                    cl.calcAbstraction();
+                    linkInAlreadyClause(c);
+                    clauses[c.index] = c;
+                    solver.attachClause(cl);
+                    if (cl.size() == 2) solver.becameBinary++;
+                    updateClause(c);
+                    Q.push(c);
+                } else {
+                    assert(cl.size() == 1);
+                    solver.uncheckedEnqueue(cl[0]);
+                    solver.ok = (solver.propagate() == NULL);
+                    if (!solver.ok) {
+                        unregisterIteration(Q);
+                        unregisterIteration(subs);
+                        return;
+                    }
+                    #ifdef VERBOSE_DEBUG
+                    cout << "Found that var " << cl[0].var()+1 << " must be " << std::boolalpha << !cl[0].sign() << endl;
+                    #endif
+                    free(&cl);
+                }
+                endS:;
+            }
+            
+            qs[i] = ~qs[i];
+            subs.clear();
+        }
+        q++;
+    }
+    
+    unregisterIteration(Q);
+    unregisterIteration(subs);
+}
+
+void Subsumer::updateClause(ClauseSimp c)
+{
+    if (!c.clause->learnt()) subsume0(*c.clause);
+    
+    cl_touched.add(c);
+}
+
+void Subsumer::almost_all_database()
+{
+    #ifdef BIT_MORE_VERBOSITY
+    std::cout << "c Larger database" << std::endl;
+    #endif
+    // Optimized variant when virtually whole database is involved:
+    cl_added  .clear();
+    cl_touched.clear();
+    
+    for (uint32_t i = 0; i < clauses.size(); i++) {
+        if (numMaxSubsume1 == 0) break;
+        if (clauses[i].clause != NULL && updateOccur(*clauses[i].clause)) {
+            subsume1(clauses[i]);
+            numMaxSubsume1--;
+            if (!solver.ok) return;
+        }
+    }
+    
+    assert(solver.ok);
+    solver.ok = (solver.propagate() == NULL);
+    if (!solver.ok) {
+        std::cout << "c (contradiction during subsumption)" << std::endl;
+        return;
+    }
+    solver.clauseCleaner->cleanClausesBewareNULL(clauses, ClauseCleaner::simpClauses, *this);
+    
+    #ifdef VERBOSE_DEBUG
+    cout << "subsume1 part 1 finished" << endl;
+    #endif
+    
+    CSet s1;
+    registerIteration(s1);
+    while (cl_touched.size() > 0 && numMaxSubsume1 > 0){
+        #ifdef VERBOSE_DEBUG
+        std::cout << "c cl_touched was > 0, new iteration" << std::endl;
+        #endif
+        for (CSet::iterator it = cl_touched.begin(), end = cl_touched.end(); it != end; ++it) {
+            if (it->clause != NULL)
+                s1.add(*it);
+        }
+        cl_touched.clear();
+        
+        for (CSet::iterator it = s1.begin(), end = s1.end(); it != end; ++it) {
+            if (numMaxSubsume1 == 0) break;
+            if (it->clause != NULL) {
+                subsume1(*it);
+                numMaxSubsume1--;
+                if (!solver.ok) return;
+            }
+        }
+        s1.clear();
+        
+        if (!solver.ok) return;
+        solver.ok = (solver.propagate() == NULL);
+        if (!solver.ok) {
+            printf("c (contradiction during subsumption)\n");
+            unregisterIteration(s1);
+            return;
+        }
+        solver.clauseCleaner->cleanClausesBewareNULL(clauses, ClauseCleaner::simpClauses, *this);
+    }
+    unregisterIteration(s1);
+}
+
+void Subsumer::smaller_database()
+{
+    #ifdef BIT_MORE_VERBOSITY
+    std::cout << "c Smaller database" << std::endl;
+    #endif
+    //  Set used in 1-subs:
+    //      (1) clauses containing a negated literal of an added clause.
+    //      (2) all added or strengthened ("touched") clauses.
+    //
+    //  Set used in 0-subs:
+    //      (1) clauses containing a (non-negated) literal of an added clause, including the added clause itself.
+    //      (2) all strenghtened clauses -- REMOVED!! We turned on eager backward subsumption which supersedes this.
+    
+    #ifdef BIT_MORE_VERBOSITY
+    printf("  PREPARING\n");
+    #endif
+    
+    CSet s0, s1;     // 's0' is used for 0-subsumption, 's1' for 1-subsumption
+    vec<char>   ol_seen(solver.nVars()*2, 0);
+    for (CSet::iterator it = cl_added.begin(), end = cl_added.end(); it != end; ++it) {
+        if (it->clause == NULL) continue;
+        ClauseSimp& c = *it;
+        Clause& cl = *it->clause;
+        
+        s1.add(c);
+        for (uint32_t j = 0; j < cl.size(); j++){
+            if (ol_seen[cl[j].toInt()]) continue;
+            ol_seen[cl[j].toInt()] = 1;
+            
+            vec<ClauseSimp>& n_occs = occur[(~cl[j]).toInt()];
+            for (uint32_t k = 0; k < n_occs.size(); k++)
+                if (n_occs[k].clause != c.clause && n_occs[k].clause->size() <= cl.size() && selfSubset(n_occs[k].clause->getAbst(), c.clause->getAbst()) && selfSubset(*n_occs[k].clause, cl, seen_tmp))
+                    s1.add(n_occs[k]);
+                
+            vec<ClauseSimp>& p_occs = occur[cl[j].toInt()];
+            for (uint32_t k = 0; k < p_occs.size(); k++)
+                if (subsetAbst(p_occs[k].clause->getAbst(), c.clause->getAbst()))
+                    s0.add(p_occs[k]);
+        }
+    }
+    cl_added.clear();
+    
+    registerIteration(s0);
+    registerIteration(s1);
+    
+    #ifdef BIT_MORE_VERBOSITY
+    printf("  FIXED-POINT\n");
+    #endif
+    
+    // Fixed-point for 1-subsumption:
+    while (s1.size() > 0 || cl_touched.size() > 0){
+        for (CSet::iterator it = cl_touched.begin(), end = cl_touched.end(); it != end; ++it) {
+            if (it->clause != NULL) {
+                s1.add(*it);
+                s0.add(*it);
+            }
+        }
+        
+        cl_touched.clear();
+        assert(solver.qhead == solver.trail.size());
+        
+        #ifdef BIT_MORE_VERBOSITY
+        printf("s1.size()=%d  cl_touched.size()=%d\n", s1.size(), cl_touched.size());
+        #endif
+        
+        for (CSet::iterator it = s1.begin(), end = s1.end(); it != end; ++it) {
+            if (numMaxSubsume1 == 0) break;
+            if (it->clause != NULL) {
+                subsume1(*it);
+                numMaxSubsume1--;
+                if (!solver.ok) return;
+            }
+        }
+        s1.clear();
+        
+        if (!solver.ok) return;
+        solver.ok = (solver.propagate() == NULL);
+        if (!solver.ok){
+            printf("c (contradiction during subsumption)\n");
+            unregisterIteration(s1);
+            unregisterIteration(s0);
+            return; 
+        }
+        solver.clauseCleaner->cleanClausesBewareNULL(clauses, ClauseCleaner::simpClauses, *this);
+    }
+    unregisterIteration(s1);
+    
+    // Iteration pass for 0-subsumption:
+    for (CSet::iterator it = s0.begin(), end = s0.end(); it != end; ++it) {
+        if (it->clause != NULL)
+            subsume0(*it->clause);
+    }
+    s0.clear();
+    unregisterIteration(s0);
+}
+
+ClauseSimp Subsumer::linkInClause(Clause& cl)
+{
+    ClauseSimp c(&cl, clauseID++);
+    clauses.push(c);
+    if (updateOccur(cl)) {
+        for (uint32_t i = 0; i < cl.size(); i++) {
+            occur[cl[i].toInt()].push(c);
+            touch(cl[i].var());
+        }
+    }
+    cl_added.add(c);
+    
+    return c;
+}
+
+void Subsumer::linkInAlreadyClause(ClauseSimp& c)
+{
+    Clause& cl = *c.clause;
+    
+    if (updateOccur(cl)) {
+        for (uint32_t i = 0; i < c.clause->size(); i++) {
+            occur[cl[i].toInt()].push(c);
+            touch(cl[i].var());
+        }
+    }
+}
+
+void Subsumer::addFromSolver(vec<Clause*>& cs)
+{
+    Clause **i = cs.getData();
+    Clause **j = i;
+    for (Clause **end = i + cs.size(); i !=  end; i++) {
+        if (i+1 != end)
+            __builtin_prefetch(*(i+1), 1, 1);
+        
+        if ((*i)->learnt()) {
+            *j++ = *i;
+            (*i)->setUnsorted();
+            continue;
+        }
+        ClauseSimp c(*i, clauseID++);
+        clauses.push(c);
+        Clause& cl = *c.clause;
+        if (updateOccur(cl)) {
+            for (uint32_t i = 0; i < cl.size(); i++) {
+                occur[cl[i].toInt()].push(c);
+                touch(cl[i].var());
+            }
+            if (fullSubsume || cl.getVarChanged()) cl_added.add(c);
+            else if (cl.getStrenghtened()) cl_touched.add(c);
+            
+            if (cl.getVarChanged() || cl.getStrenghtened())
+                cl.calcAbstraction();
+        }
+    }
+    cs.shrink(i-j);
+}
+
+void Subsumer::addBackToSolver()
+{
+    #ifdef HYPER_DEBUG2
+    uint32_t binaryLearntAdded = 0;
+    #endif
+    
+    for (uint32_t i = 0; i < clauses.size(); i++) {
+        if (clauses[i].clause != NULL) {
+            assert(clauses[i].clause->size() > 1);
+            if (clauses[i].clause->size() == 2) {
+                #ifdef HYPER_DEBUG2
+                if (clauses[i].clause->learnt())
+                    binaryLearntAdded++;
+                #endif
+                solver.binaryClauses.push(clauses[i].clause);
+            } else {
+                if (clauses[i].clause->learnt())
+                    solver.learnts.push(clauses[i].clause);
+                else
+                    solver.clauses.push(clauses[i].clause);
+            }
+        }
+    }
+    
+    #ifdef HYPER_DEBUG2
+    std::cout << "Binary learnt added:" << binaryLearntAdded << std::endl;
+    #endif
+}
+
+void Subsumer::removeWrong(vec<Clause*>& cs)
+{
+    Clause **i = cs.getData();
+    Clause **j = i;
+    for (Clause **end =  i + cs.size(); i != end; i++) {
+        Clause& c = **i;
+        if (!c.learnt())  {
+            *j++ = *i;
+            continue;
+        }
+        bool remove = false;
+        for (Lit *l = c.getData(), *end2 = l+c.size(); l != end2; l++) {
+            if (var_elimed[l->var()]) {
+                remove = true;
+                solver.detachClause(c);
+                free(&c);
+                break;
+            }
+        }
+        if (!remove)
+            *j++ = *i;
+    }
+    cs.shrink(i-j);
+}
+
+void Subsumer::fillCannotEliminate()
+{
+    std::fill(cannot_eliminate.getData(), cannot_eliminate.getDataEnd(), false);
+    for (uint32_t i = 0; i < solver.xorclauses.size(); i++) {
+        const XorClause& c = *solver.xorclauses[i];
+        for (uint32_t i2 = 0; i2 < c.size(); i2++)
+            cannot_eliminate[c[i2].var()] = true;
+    }
+    
+    const vector<bool>& tmp2 = solver.conglomerate->getRemovedVars();
+    for (uint32_t i = 0; i < tmp2.size(); i++) {
+        if (tmp2[i]) cannot_eliminate[i] = true;
+    }
+    
+    const vec<Clause*>& tmp = solver.varReplacer->getClauses();
+    for (uint32_t i = 0; i < tmp.size(); i++) {
+        const Clause& c = *tmp[i];
+        for (uint32_t i2 = 0; i2 < c.size(); i2++)
+            cannot_eliminate[c[i2].var()] = true;
+    }
+    
+    #ifdef VERBOSE_DEBUG
+    uint32_t tmpNum = 0;
+    for (uint32_t i = 0; i < cannot_eliminate.size(); i++)
+        if (cannot_eliminate[i])
+            tmpNum++;
+    std::cout << "Cannot eliminate num:" << tmpNum << std::endl;
+    #endif
+}
+
+void Subsumer::subsume0LearntSet(vec<Clause*>& cs)
+{
+    Clause** a = cs.getData();
+    Clause** b = a;
+    for (Clause** end = a + cs.size(); a != end; a++) {
+        if (numMaxSubsume0 == 0) break;
+        if (!(*a)->subsume0IsFinished()) {
+            numMaxSubsume0--;
+            uint32_t index = subsume0(**a, calcAbstraction(**a));
+            if (index != std::numeric_limits<uint32_t>::max()) {
+                (*a)->makeNonLearnt();
+                clauses[index].clause = *a;
+                linkInAlreadyClause(clauses[index]);
+                solver.learnts_literals -= (*a)->size();
+                solver.clauses_literals += (*a)->size();
+                cl_added.add(clauses[index]);
+                continue;
+            }
+            if (numMaxSubsume1 > 0 &&
+                (((*a)->size() == 2 && clauses.size() < 3500000) ||
+                ((*a)->size() <= 3 && clauses.size() < 300000) ||
+                ((*a)->size() <= 4 && clauses.size() < 60000))) {
+                ClauseSimp c(*a, clauseID++);
+                (*a)->calcAbstraction();
+                clauses.push(c);
+                subsume1(c);
+                numMaxSubsume1--;
+                if (!solver.ok)
+                    return;
+                assert(clauses[c.index].clause != NULL);
+                clauses.pop();
+                clauseID--;
+            }
+        }
+        *b++  = *a;
+    }
+    cs.shrink(a-b);
+}
+
+const bool Subsumer::treatLearnts()
+{
+    subsume0LearntSet(solver.learnts);
+    if (!solver.ok) return false;
+    subsume0LearntSet(solver.binaryClauses);
+    if (!solver.ok) return false;
+    solver.ok = (solver.propagate() == NULL);
+    if (!solver.ok){
+        printf("c (contradiction during subsumption)\n");
+        return false;
+    }
+    solver.clauseCleaner->cleanClausesBewareNULL(clauses, ClauseCleaner::simpClauses, *this);
+    return true;
+}
+
+const bool Subsumer::simplifyBySubsumption()
+{
+    if (solver.nClauses() > 20000000)  return true;
+    
+    double myTime = cpuTime();
+    uint32_t origTrailSize = solver.trail.size();
+    clauses_subsumed = 0;
+    literals_removed = 0;
+    numblockedClauseRemoved = 0;
+    numCalls++;
+    clauseID = 0;
+    numVarsElimed = 0;
+    blockTime = 0.0;
+    
+    //if (solver.clauses.size() < 2000000) addAllXorAsNorm();
+    
+    //For VE
+    touched_list.clear();
+    touched.clear();
+    touched.growTo(solver.nVars(), false);
+    for (Var var = 0; var < solver.nVars(); var++) {
+        if (solver.decision_var[var] && solver.assigns[var] == l_Undef) touch(var);
+        occur[2*var].clear();
+        occur[2*var+1].clear();
+    }
+    
+    if (solver.performReplace && !solver.varReplacer->performReplace(true))
+        return false;
+    fillCannotEliminate();
+    
+    clauses.clear();
+    cl_added.clear();
+    cl_touched.clear();
+    
+    clauses.reserve(solver.clauses.size() + solver.binaryClauses.size());
+    cl_added.reserve(solver.clauses.size() + solver.binaryClauses.size());
+    cl_touched.reserve(solver.clauses.size() + solver.binaryClauses.size());
+    
+    solver.clauseCleaner->cleanClauses(solver.clauses, ClauseCleaner::clauses);
+    addFromSolver(solver.clauses);
+    solver.clauseCleaner->cleanClauses(solver.binaryClauses, ClauseCleaner::binaryClauses);
+    addFromSolver(solver.binaryClauses);
+    
+    //Limits
+    if (clauses.size() > 3500000)
+        numMaxSubsume0 = 900000 * (1+numCalls/2);
+    else
+        numMaxSubsume0 = 2000000 * (1+numCalls/2);
+    
+    if (clauses.size() > 3500000)
+        numMaxSubsume1 = 100000 * (1+numCalls/2);
+    else
+        numMaxSubsume1 = 500000 * (1+numCalls/2);
+    
+    if (clauses.size() > 3500000)
+        numMaxElim = (uint32_t)((double)solver.order_heap.size() / 5.0 * (0.8+(double)(numCalls)/4.0));
+    else
+        numMaxElim = (uint32_t)((double)solver.order_heap.size() / 2.0 * (0.8+(double)(numCalls)/4.0));
+    
+    if (clauses.size() > 3500000)
+        numMaxBlockToVisit = (int64_t)(30000.0 * (0.8+(double)(numCalls)/3.0));
+    else
+        numMaxBlockToVisit = (int64_t)(50000.0 * (0.8+(double)(numCalls)/3.0));
+    
+    if (solver.order_heap.size() > 200000)
+        numMaxBlockVars = (uint32_t)((double)solver.order_heap.size() / 3.5 * (0.8+(double)(numCalls)/4.0));
+    else
+        numMaxBlockVars = (uint32_t)((double)solver.order_heap.size() / 1.5 * (0.8+(double)(numCalls)/4.0));
+    
+    if (clauses.size() < 200000)
+        fullSubsume = true;
+    else
+        fullSubsume = false;
+    
+    #ifdef BIT_MORE_VERBOSITY
+    std::cout << "c  num clauses:" << clauses.size() << std::endl;
+    std::cout << "c  time to link in:" << cpuTime()-myTime << std::endl;
+    #endif
+    
+    for (uint32_t i = 0; i < clauses.size(); i++) {
+        if (numMaxSubsume0 == 0) break;
+        if (clauses[i].clause != NULL && 
+            (fullSubsume
+            || !clauses[i].clause->subsume0IsFinished())
+            ) {
+            subsume0(*clauses[i].clause);
+            numMaxSubsume0--;
+        }
+    }
+    
+    origNClauses = clauses.size();
+    uint32_t origNLearnts = solver.learnts.size();
+    
+    if (!treatLearnts()) return false;
+    
+    #ifdef BIT_MORE_VERBOSITY
+    std::cout << "c  time until pre-subsume0 clauses and subsume1 2-learnts:" << cpuTime()-myTime << std::endl;
+    #endif
+    
+    if (!solver.ok) return false;
+    #ifdef VERBOSE_DEBUG
+    std::cout << "c   pre-subsumed:" << clauses_subsumed << std::endl;
+    std::cout << "c   cl_added:" << cl_added.size() << std::endl;
+    std::cout << "c   cl_touched:" << cl_touched.size() << std::endl;
+    std::cout << "c   clauses:" << clauses.size() << std::endl;
+    std::cout << "c   origNClauses:" << origNClauses << std::endl;
+    #endif
+    
+    if (clauses.size() > 10000000)  goto endSimplifyBySubsumption;
+    
+    do{
+        if (solver.doBlockedClause && numCalls % 3 == 1) blockedClauseRemoval();
+        
+        #ifdef BIT_MORE_VERBOSITY
+        std::cout << "c time before the start of almost_all/smaller: " << cpuTime() - myTime << std::endl;
+        #endif
+        if (numMaxSubsume0 > 0) {
+            if (cl_added.size() > origNClauses / 2) {
+                almost_all_database();
+                if (!solver.ok) return false;
+            } else {
+                smaller_database();
+                if (!solver.ok) return false;
+            }
+        }
+        cl_added.clear();
+        assert(cl_added.size() == 0);
+        assert(solver.ok);
+        solver.ok = (solver.propagate() == NULL);
+        if (!solver.ok) {
+            printf("c (contradiction during subsumption)\n");
+            return false;
+        }
+        solver.clauseCleaner->cleanClausesBewareNULL(clauses, ClauseCleaner::simpClauses, *this);
+        
+        #ifdef BIT_MORE_VERBOSITY
+        std::cout << "c time until the end of almost_all/smaller: " << cpuTime() - myTime << std::endl;
+        printf("c VARIABLE ELIMINIATION\n");
+        std::cout << "c  toucheds list size:" << touched_list.size() << std::endl;
+        #endif
+        vec<Var> init_order;
+        orderVarsForElim(init_order);   // (will untouch all variables)
+        
+        for (bool first = true; numMaxElim > 0; first = false){
+            uint32_t vars_elimed = 0;
+            int clauses_before = solver.nClauses();
+            vec<Var> order;
+            
+            if (first) {
+                //init_order.copyTo(order);
+                for (uint32_t i = 0; i < init_order.size(); i++) {
+                    const Var var = init_order[i];
+                    if (!var_elimed[var] && !cannot_eliminate[var] && solver.decision_var[var] && solver.assigns[var] == l_Undef)
+                        order.push(init_order[i]);
+                }
+            } else {
+                for (uint32_t i = 0; i < touched_list.size(); i++) {
+                    const Var var = touched_list[i];
+                    if (!var_elimed[var] && !cannot_eliminate[var] && solver.decision_var[var] && solver.assigns[var] == l_Undef) {
+                        order.push(touched_list[i]);
+                        touched[touched_list[i]] = 0;
+                    }
+                }
+                touched_list.clear();
+            }
+            #ifdef VERBOSE_DEBUG
+            std::cout << "Order size:" << order.size() << std::endl;
+            #endif
+            
+            assert(solver.qhead == solver.trail.size());
+            for (uint32_t i = 0; i < order.size() && numMaxElim > 0; i++, numMaxElim--) {
+                if (maybeEliminate(order[i])) {
+                    if (!solver.ok) {
+                        printf("c (contradiction during subsumption)\n");
+                        return false;
+                    }
+                    solver.ok = (solver.propagate() == NULL);
+                    if (!solver.ok) {
+                        printf("c (contradiction during subsumption)\n");
+                        return false;
+                    }
+                    vars_elimed++;
+                }
+            }
+            assert(solver.qhead == solver.trail.size());
+            
+            if (vars_elimed == 0) break;
+            
+            numVarsElimed += vars_elimed;
+            #ifdef BIT_MORE_VERBOSITY
+            printf("c  #clauses-removed: %-8d #var-elim: %d\n", clauses_before - solver.nClauses(), vars_elimed);
+            std::cout << "c time until the end of varelim: " << cpuTime() - myTime << std::endl;
+            #endif
+        }
+    }while (cl_added.size() > 100);
+    endSimplifyBySubsumption:
+    
+    if (!solver.ok) return false;
+    solver.ok = (solver.propagate() == NULL);
+    if (!solver.ok) {
+        printf("c (contradiction during subsumption)\n");
+        return false;
+    }
+    
+    #ifndef DNDEBUG
+    verifyIntegrity();
+    #endif
+    
+    //vector<char> var_merged = merge();
+    removeWrong(solver.learnts);
+    removeWrong(solver.binaryClauses);
+    
+    solver.clauseCleaner->cleanClausesBewareNULL(clauses, ClauseCleaner::simpClauses, *this);
+    if (solver.doHyperBinRes && clauses.size() < 1000000 && numCalls > 1 && !hyperBinRes())
+        return false;
+    
+    solver.ok = (solver.propagate() == NULL);
+    if (!solver.ok) return false;
+    solver.clauseCleaner->cleanClausesBewareNULL(clauses, ClauseCleaner::simpClauses, *this);
+    
+    solver.order_heap.filter(Solver::VarFilter(solver));
+    
+    addBackToSolver();
+    solver.nbCompensateSubsumer += origNLearnts-solver.learnts.size();
+    /*if (solver.findNormalXors && solver.clauses.size() < MAX_CLAUSENUM_XORFIND) {
+        XorFinder xorFinder(&solver, solver.clauses, ClauseCleaner::clauses);
+        if (!xorFinder.doNoPart(3, 4)) return false;
+    }*/
+    
+    if (solver.verbosity >= 1) {
+        std::cout << "c |  lits-rem: " << std::setw(9) << literals_removed
+        << "  cl-subs: " << std::setw(8) << clauses_subsumed
+        << "  v-elim: " << std::setw(6) << numVarsElimed
+        << "  v-fix: " << std::setw(4) <<solver.trail.size() - origTrailSize
+        << "  time: " << std::setprecision(2) << std::setw(5) << (cpuTime() - myTime) << " s"
+        //<< " blkClRem: " << std::setw(5) << numblockedClauseRemoved
+        << "   |" << std::endl;
+        
+        if (numblockedClauseRemoved > 0 || blockTime > 0.0) {
+            std::cout 
+            << "c |  Blocked clauses removed: " << std::setw(8) << numblockedClauseRemoved 
+            << "    Time: " << std::fixed << std::setprecision(2) << std::setw(4) << blockTime << " s" 
+            << "                                    |" << std::endl;
+        }
+    }
+    
+    return true;
+}
+
+void Subsumer::findSubsumed(Clause& ps, vec<ClauseSimp>& out_subsumed)
+{
+    #ifdef VERBOSE_DEBUG
+    cout << "findSubsumed: ";
+    for (uint32_t i = 0; i < ps.size(); i++) {
+        if (ps[i].sign()) printf("-");
+        printf("%d ", ps[i].var() + 1);
+    }
+    printf("0\n");
+    #endif
+    
+    int min_i = 0;
+    for (uint32_t i = 1; i < ps.size(); i++){
+        if (occur[ps[i].toInt()].size() < occur[ps[min_i].toInt()].size())
+            min_i = i;
+    }
+    
+    vec<ClauseSimp>& cs = occur[ps[min_i].toInt()];
+    for (ClauseSimp *it = cs.getData(), *end = it + cs.size(); it != end; it++){
+        if (it+1 != end)
+            __builtin_prefetch((it+1)->clause, 1, 1);
+        
+        if (it->clause != &ps && subsetAbst(ps.getAbst(), it->clause->getAbst()) && ps.size() <= it->clause->size() && subset(ps, *it->clause)) {
+            out_subsumed.push(*it);
+            #ifdef VERBOSE_DEBUG
+            cout << "subsumed: ";
+            it->clause->plainPrint();
+            #endif
+        }
+    }
+}
+
+void Subsumer::findSubsumed(Clause& ps, uint32_t abs, vec<ClauseSimp>& out_subsumed)
+{
+    #ifdef VERBOSE_DEBUG
+    cout << "findSubsumed: ";
+    for (uint32_t i = 0; i < ps.size(); i++) {
+        if (ps[i].sign()) printf("-");
+        printf("%d ", ps[i].var() + 1);
+    }
+    printf("0\n");
+    #endif
+    
+    int min_i = 0;
+    for (uint32_t i = 1; i < ps.size(); i++){
+        if (occur[ps[i].toInt()].size() < occur[ps[min_i].toInt()].size())
+            min_i = i;
+    }
+    
+    vec<ClauseSimp>& cs = occur[ps[min_i].toInt()];
+    for (ClauseSimp *it = cs.getData(), *end = it + cs.size(); it != end; it++){
+        if (it+1 != end)
+            __builtin_prefetch((it+1)->clause, 1, 1);
+        
+        if (it->clause != &ps && subsetAbst(abs, it->clause->getAbst()) && ps.size() <= it->clause->size() && subset(ps, *it->clause)) {
+            out_subsumed.push(*it);
+            #ifdef VERBOSE_DEBUG
+            cout << "subsumed: ";
+            it->clause->plainPrint();
+            #endif
+        }
+    }
+}
+
+void Subsumer::findSubsumed(const vec<Lit>& ps, const uint32_t abst, vec<ClauseSimp>& out_subsumed)
+{
+    #ifdef VERBOSE_DEBUG
+    cout << "findSubsumed: ";
+    for (uint32_t i = 0; i < ps.size(); i++) {
+        if (ps[i].sign()) printf("-");
+        printf("%d ", ps[i].var() + 1);
+    }
+    printf("0\n");
+    #endif
+    
+    uint32_t min_i = 0;
+    for (uint32_t i = 1; i < ps.size(); i++){
+        if (occur[ps[i].toInt()].size() < occur[ps[min_i].toInt()].size())
+            min_i = i;
+    }
+    
+    vec<ClauseSimp>& cs = occur[ps[min_i].toInt()];
+    for (ClauseSimp *it = cs.getData(), *end = it + cs.size(); it != end; it++){
+        if (it+1 != end)
+            __builtin_prefetch((it+1)->clause, 1, 1);
+        
+        if (subsetAbst(abst, it->clause->getAbst()) && ps.size() <= it->clause->size() && subset(ps, *it->clause)) {
+            out_subsumed.push(*it);
+            #ifdef VERBOSE_DEBUG
+            cout << "subsumed: ";
+            it->clause->plainPrint();
+            #endif
+        }
+    }
+}
+
+void inline Subsumer::MigrateToPsNs(vec<ClauseSimp>& poss, vec<ClauseSimp>& negs, vec<ClauseSimp>& ps, vec<ClauseSimp>& ns, const Var x)
+{
+    poss.moveTo(ps);
+    negs.moveTo(ns);
+    
+    for (uint32_t i = 0; i < ps.size(); i++)
+        unlinkClause(ps[i], x);
+    for (uint32_t i = 0; i < ns.size(); i++)
+        unlinkClause(ns[i], x);
+}
+
+void inline Subsumer::DeallocPsNs(vec<ClauseSimp>& ps, vec<ClauseSimp>& ns)
+{
+    for (uint32_t i = 0; i < ps.size(); i++) {
+        clauses[ps[i].index].clause = NULL;
+        free(ps[i].clause);
+    }
+    for (uint32_t i = 0; i < ns.size(); i++) {
+        clauses[ns[i].index].clause = NULL;
+        free(ns[i].clause);
+    }
+}
+
+// Returns TRUE if variable was eliminated.
+bool Subsumer::maybeEliminate(const Var x)
+{
+    assert(solver.qhead == solver.trail.size());
+    assert(!var_elimed[x]);
+    assert(!cannot_eliminate[x]);
+    assert(solver.decision_var[x]);
+    if (solver.value(x) != l_Undef) return false;
+    if (occur[Lit(x, false).toInt()].size() == 0 && occur[Lit(x, true).toInt()].size() == 0)
+        return false;
+    
+    vec<ClauseSimp>&   poss = occur[Lit(x, false).toInt()];
+    vec<ClauseSimp>&   negs = occur[Lit(x, true).toInt()];
+    
+    // Heuristic CUT OFF:
+    if (poss.size() >= 10 && negs.size() >= 10)
+        return false;
+    
+    // Count clauses/literals before elimination:
+    int before_clauses  = poss.size() + negs.size();
+    uint32_t before_literals = 0;
+    for (int i = 0; i < poss.size(); i++) before_literals += poss[i].clause->size();
+    for (int i = 0; i < negs.size(); i++) before_literals += negs[i].clause->size();
+    
+    // Heuristic CUT OFF2:
+    if ((poss.size() >= 3 && negs.size() >= 3 && before_literals > 300)
+        && clauses.size() > 1500000)
+        return false;
+    if ((poss.size() >= 5 && negs.size() >= 5 && before_literals > 400)
+        && clauses.size() <= 1500000 && clauses.size() > 200000)
+        return false;
+    if ((poss.size() >= 10 && negs.size() >= 10 && before_literals > 700)
+        && clauses.size() <= 200000)
+        return false;
+    
+    // Count clauses/literals after elimination:
+    int after_clauses  = 0;
+    //int after_literals = 0;
+    vec<Lit>  dummy;
+    //vec<ClauseSimp> dummy2;
+    for (int i = 0; i < poss.size(); i++){
+        for (int j = 0; j < negs.size(); j++){
+            // Merge clauses. If 'y' and '~y' exist, clause will not be created.
+            dummy.clear();
+            bool ok = merge(*poss[i].clause, *negs[j].clause, Lit(x, false), Lit(x, true), dummy);
+            if (ok){
+                //findSubsumed(dummy, calcAbstraction(dummy), dummy2);
+                //after_clauses -= (int)dummy2.size();
+                after_clauses++;
+                if (after_clauses > before_clauses) goto Abort;
+                //after_literals += dummy.size();
+            }
+        }
+    }
+    Abort:;
+    
+    // Maybe eliminate:
+    if (after_clauses  <= before_clauses) {
+        vec<ClauseSimp> ps, ns;
+        MigrateToPsNs(poss, negs, ps, ns, x);
+        for (int i = 0; i < ps.size(); i++) for (int j = 0; j < ns.size(); j++){
+            dummy.clear();
+            bool ok = merge(*ps[i].clause, *ns[j].clause, Lit(x, false), Lit(x, true), dummy);
+            if (ok){
+                Clause* cl = solver.addClauseInt(dummy, 0);
+                if (cl != NULL) {
+                    ClauseSimp c = linkInClause(*cl);
+                    subsume0(*cl);
+                    //subsume1(c);
+                }
+                if (!solver.ok) return true;
+            }
+        }
+        DeallocPsNs(ps, ns);
+        goto Eliminated;
+    }
+    
+    after_clauses  = 0;
+    //after_literals = 0;
+    for (int i = 0; i < poss.size(); i++){
+        for (int j = 0; j < negs.size(); j++){
+            // Merge clauses. If 'y' and '~y' exist, clause will not be created.
+            dummy.clear();
+            bool ok = merge(*poss[i].clause, *negs[j].clause, Lit(x, false), Lit(x, true),  dummy);
+            if (ok){
+                //findSubsumed(dummy, calcAbstraction(dummy), dummy2);
+                //after_clauses -= (int)dummy2.size();
+                after_clauses++;
+                if (after_clauses > before_clauses) goto Abort2;
+                //after_literals += dummy.size();
+            }
+        }
+    }
+    Abort2:
+    
+    // Maybe eliminate:
+    if (after_clauses  <= before_clauses) {
+        vec<ClauseSimp> ps, ns;
+        MigrateToPsNs(poss, negs, ps, ns, x);
+        for (int i = 0; i < ps.size(); i++) for (int j = 0; j < ns.size(); j++){
+            dummy.clear();
+            bool ok = merge(*ps[i].clause, *ns[j].clause, Lit(x, false), Lit(x, true), dummy);
+            if (ok){
+                Clause* cl = solver.addClauseInt(dummy, 0);
+                if (cl != NULL) {
+                    ClauseSimp c = linkInClause(*cl);
+                    subsume0(*cl);
+                    //subsume1(c);
+                }
+                if (!solver.ok) return true;
+            }
+        }
+        DeallocPsNs(ps, ns);
+        goto Eliminated;
+    }
+    
+    return false;
+    
+    Eliminated:
+    assert(occur[Lit(x, false).toInt()].size() + occur[Lit(x, true).toInt()].size() == 0);
+    var_elimed[x] = 1;
+    numElimed++;
+    solver.setDecisionVar(x, false);
+    return true;
+}
+
+// Returns FALSE if clause is always satisfied ('out_clause' should not be used). 'seen' is assumed to be cleared.
+bool Subsumer::merge(Clause& ps, Clause& qs, Lit without_p, Lit without_q, vec<Lit>& out_clause)
+{
+    for (uint32_t i = 0; i < ps.size(); i++){
+        if (ps[i] != without_p){
+            seen_tmp[ps[i].toInt()] = 1;
+            out_clause.push(ps[i]);
+        }
+    }
+    
+    for (uint32_t i = 0; i < qs.size(); i++){
+        if (qs[i] != without_q){
+            if (seen_tmp[(~qs[i]).toInt()]){
+                for (uint32_t i = 0; i < ps.size(); i++)
+                    seen_tmp[ps[i].toInt()] = 0;
+                return false;
+            }
+            if (!seen_tmp[qs[i].toInt()])
+                out_clause.push(qs[i]);
+        }
+    }
+    
+    for (uint32_t i = 0; i < ps.size(); i++)
+        seen_tmp[ps[i].toInt()] = 0;
+    
+    return true;
+}
+
+struct myComp {
+    bool operator () (const pair<int, Var>& x, const pair<int, Var>& y) {
+        return x.first < y.first ||
+            (!(y.first < x.first) && x.second < y.second);
+    }
+};
+    
+// Side-effect: Will untouch all variables.
+void Subsumer::orderVarsForElim(vec<Var>& order)
+{
+    order.clear();
+    vec<pair<int, Var> > cost_var;
+    for (int i = 0; i < touched_list.size(); i++){
+        Var x = touched_list[i];
+        touched[x] = 0;
+        cost_var.push(std::make_pair( occur[Lit(x, false).toInt()].size() * occur[Lit(x, true).toInt()].size() , x ));
+    }
+    
+    touched_list.clear();
+    std::sort(cost_var.getData(), cost_var.getData()+cost_var.size(), myComp());
+    
+    for (int x = 0; x < cost_var.size(); x++) {
+        if (cost_var[x].first != 0)
+            order.push(cost_var[x].second);
+    }
+}
+
+const bool Subsumer::hyperUtility(vec<ClauseSimp>& iter, const Lit lit, BitArray& inside, vec<ClauseSimp>& addToClauses, uint32_t& hyperBinAdded, uint32_t& hyperBinUnitary)
+{
+    for (ClauseSimp *it = iter.getData(), *end = it + iter.size() ; it != end; it++) {
+        if (it->clause == NULL) continue;
+        uint32_t notIn = 0;
+        Lit notInLit = Lit(0,false);
+        
+        Clause& cl2 = *it->clause;
+        for (uint32_t i = 0; i < cl2.size(); i++) {
+            if (cl2[i].var() == lit.var()) {
+                notIn = 2;
+                break;
+            }
+            if (!inside[cl2[i].toInt()]) {
+                notIn++;
+                notInLit = cl2[i];
+            }
+            if (notIn > 1) break;
+        }
+        
+        if (notIn == 0) {
+            if (solver.assigns[lit.var()] == l_Undef) {
+                solver.uncheckedEnqueue(lit);
+                solver.ok = (solver.propagate() == NULL);
+                if (!solver.ok) return false;
+                hyperBinUnitary++;
+            } else if (solver.assigns[lit.var()] != boolToLBool(!lit.sign())) {
+                solver.ok = false;
+                return false;
+            }
+        }
+        
+        if (notIn == 1 && !inside[(~notInLit).toInt()]) {
+            vec<Lit> cs(2);
+            cs[0] = lit;
+            cs[1] = notInLit;
+            Clause *cl3 = Clause_new(cs, 0);
+            uint32_t index = subsume0(*cl3);
+            if (index != std::numeric_limits<uint32_t>::max()) {
+                ClauseSimp c(cl3, index);
+                addToClauses.push(c);
+                inside.setBit((~notInLit).toInt());
+                #ifdef HYPER_DEBUG
+                std::cout << "HyperBinRes adding clause: ";
+                cl3->plainPrint();
+                #endif
+                hyperBinAdded++;
+            }
+        }
+    }
+    
+    return true;
+}
+
+const bool Subsumer::hyperBinRes()
+{
+    double myTime = cpuTime();
+    
+    BitArray inside;
+    inside.resize(solver.nVars()*2);
+    uint32_t hyperBinAdded = 0;
+    uint32_t hyperBinUnitary = 0;
+    vec<ClauseSimp> addToClauses;
+    uint64_t totalClausesChecked = 0;
+
+    vec<Var> varsToCheck;
+    
+    if (clauses.size() > 100000 || solver.order_heap.size() > 30000) {
+        Heap<Solver::VarOrderLt> tmp(solver.order_heap);
+        uint32_t thisTopX = std::min(tmp.size(), 1000U);
+        for (uint32_t i = 0; i != thisTopX; i++)
+            varsToCheck.push(tmp.removeMin());
+    } else {
+        for (Var i = 0; i < solver.nVars(); i++)
+            varsToCheck.push(i);
+    }
+    
+    for (Var test = 0; test < 2*varsToCheck.size(); test++) if (solver.assigns[test/2] == l_Undef && solver.decision_var[test/2]) {
+        if (totalClausesChecked > 5000000)
+            break;
+        
+        inside.setZero();
+        Lit lit(varsToCheck[test/2], test&1);
+        #ifdef HYPER_DEBUG
+        std::cout << "Resolving with literal:" << (lit.sign() ? "-" : "") << lit.var()+1 << std::endl;
+        #endif
+        
+        vec<Lit> addedToInside;
+        vec<ClauseSimp>& set = occur[lit.toInt()];
+        for (ClauseSimp *it = set.getData(), *end = it + set.size() ; it != end; it++) {
+            if (it->clause == NULL) continue;
+            Clause& cl2 = *it->clause;
+            if (cl2.size() > 2) continue;
+            assert(cl2[0] == lit || cl2[1] == lit);
+            if (cl2[0] == lit) {
+                inside.setBit((~cl2[1]).toInt());
+                addedToInside.push(~cl2[1]);
+            } else {
+                inside.setBit((~cl2[0]).toInt());
+                addedToInside.push(~cl2[0]);
+            }
+        }
+        
+        uint32_t sum = 0;
+        for (uint32_t add = 0; add < addedToInside.size(); add++) {
+            sum += occur[addedToInside[add].toInt()].size();
+        }
+        
+        if (sum < clauses.size()) {
+            totalClausesChecked += sum;
+            for (uint32_t add = 0; add < addedToInside.size(); add++) {
+                vec<ClauseSimp>& iter = occur[addedToInside[add].toInt()];
+                if (!hyperUtility(iter, lit, inside, addToClauses, hyperBinAdded, hyperBinUnitary))
+                    return false;
+            }
+        } else {
+            totalClausesChecked += clauses.size();
+            if (!hyperUtility(clauses, lit, inside, addToClauses, hyperBinAdded, hyperBinUnitary))
+                return false;
+        }
+        
+        for (uint32_t i = 0; i < addToClauses.size(); i++) {
+            Clause *c = solver.addClauseInt(*addToClauses[i].clause, 0);
+            free(addToClauses[i].clause);
+            if (c != NULL) {
+                ClauseSimp cc(c, addToClauses[i].index);
+                clauses[cc.index] = cc;
+                linkInAlreadyClause(cc);
+                solver.becameBinary++; //since this binary did not exist, and now it exists.
+                subsume1(cc);
+            }
+            if (!solver.ok) return false;
+        }
+        addToClauses.clear();
+    }
+    
+    if (solver.verbosity >= 1) {
+        std::cout << "c |  Hyper-binary res binary added: " << std::setw(5) << hyperBinAdded 
+        << " unitaries: " << std::setw(5) << hyperBinUnitary 
+        << " time: " << std::setprecision(2) << std::setw(5)<< cpuTime() - myTime << " s" 
+        << "                  |"  << std::endl;
+    }
+    
+    return true;
+}
+
+class varDataStruct
+{
+    public:
+        varDataStruct() : 
+            numPosClauses (0)
+            , numNegClauses (0)
+            , sumPosClauseSize (0)
+            , sumNegClauseSize (0)
+            , posHash(0)
+            , negHash(0)
+        {}
+        const bool operator < (const varDataStruct& other) const
+        {
+            if (numPosClauses < other.numPosClauses) return true;
+            if (numPosClauses > other.numPosClauses) return false;
+            
+            if (numNegClauses < other.numNegClauses)  return true;
+            if (numNegClauses > other.numNegClauses)  return false;
+            
+            if (sumPosClauseSize < other.sumPosClauseSize) return true;
+            if (sumPosClauseSize > other.sumPosClauseSize) return false;
+            
+            if (sumNegClauseSize < other.sumNegClauseSize) return true;
+            if (sumNegClauseSize > other.sumNegClauseSize) return false;
+            
+            if (posHash < other.posHash) return true;
+            if (posHash > other.posHash) return false;
+            
+            if (negHash < other.negHash) return true;
+            if (negHash > other.negHash) return false;
+            
+            return false;
+        }
+        
+        const bool operator == (const varDataStruct& other) const
+        {
+            if (numPosClauses == other.numPosClauses &&
+                numNegClauses == other.numNegClauses &&
+                sumPosClauseSize == other.sumPosClauseSize &&
+                sumNegClauseSize == other.sumNegClauseSize &&
+                posHash == other.posHash &&
+                negHash == other.negHash)
+                return true;
+            
+            return false;
+        }
+        
+        void reversePolarity()
+        {
+            std::swap(numPosClauses, numNegClauses);
+            std::swap(sumPosClauseSize, sumNegClauseSize);
+            std::swap(posHash, negHash);
+        }
+        
+        uint32_t numPosClauses;
+        uint32_t numNegClauses;
+        uint32_t sumPosClauseSize;
+        uint32_t sumNegClauseSize;
+        int posHash;
+        int negHash;
+};
+
+int hash32shift(int key)
+{
+    key = ~key + (key << 15); // key = (key << 15) - key - 1;
+    key = key ^ (key >> 12);
+    key = key + (key << 2);
+    key = key ^ (key >> 4);
+    key = key * 2057; // key = (key + (key << 3)) + (key << 11);
+    key = key ^ (key >> 16);
+    return key;
+}
+
+void Subsumer::verifyIntegrity()
+{
+    vector<uint> occurNum(solver.nVars()*2, 0);
+    
+    for (uint32_t i = 0; i < clauses.size(); i++) {
+        if (clauses[i].clause == NULL) continue;
+        Clause& c = *clauses[i].clause;
+        for (uint32_t i2 = 0; i2 < c.size(); i2++)
+            occurNum[c[i2].toInt()]++;
+    }
+    
+    for (uint32_t i = 0; i < occurNum.size(); i++) {
+        assert(occurNum[i] == occur[i].size());
+    }
+}
+
+const bool Subsumer::allTautology(const vec<Lit>& ps, const Lit lit)
+{
+    #ifdef VERBOSE_DEBUG
+    cout << "allTautology: ";
+    for (uint32_t i = 0; i < ps.size(); i++) {
+        if (ps[i].sign()) printf("-");
+        printf("%d ", ps[i].var() + 1);
+    }
+    printf("0\n");
+    #endif
+    
+    vec<ClauseSimp>& cs = occur[lit.toInt()];
+    if (cs.size() == 0) return true;
+    
+    for (const Lit *l = ps.getData(), *end = ps.getDataEnd(); l != end; l++) {
+        seen_tmp[l->toInt()] = true;
+    }
+    
+    bool allIsTautology = true;
+    for (ClauseSimp *it = cs.getData(), *end = cs.getDataEnd(); it != end; it++){
+        if (it+1 != end)
+            __builtin_prefetch((it+1)->clause, 1, 1);
+        
+        Clause& c = *it->clause;
+        for (Lit *l = c.getData(), *end2 = l + c.size(); l != end2; l++) {
+            if (*l != lit && seen_tmp[(~(*l)).toInt()]) {
+                goto next;
+            }
+        }
+        allIsTautology = false;
+        break;
+        
+        next:;
+    }
+    
+    for (const Lit *l = ps.getData(), *end = ps.getDataEnd(); l != end; l++) {
+        seen_tmp[l->toInt()] = false;
+    }
+    
+    return allIsTautology;
+}
+
+void Subsumer::blockedClauseRemoval()
+{
+    if (numMaxBlockToVisit < 0) return;
+    if (solver.order_heap.size() < 1) return;
+    double myTime = cpuTime();
+    vec<ClauseSimp> toRemove;
+    
+    touchedBlockedVars = priority_queue<VarOcc, vector<VarOcc>, MyComp>();
+    touchedBlockedVarsBool.clear();
+    touchedBlockedVarsBool.growTo(solver.nVars(), false);
+    for (uint32_t i =  0; i < solver.order_heap.size() && i < numMaxBlockVars; i++) {
+        touchBlockedVar(solver.order_heap[solver.mtrand.randInt(solver.order_heap.size()-1)]);
+    }
+    
+    while (touchedBlockedVars.size() > 100  && numMaxBlockToVisit > 0) {
+        VarOcc vo = touchedBlockedVars.top();
+        touchedBlockedVars.pop();
+        
+        if (var_elimed[vo.var] || solver.assigns[vo.var] != l_Undef || !solver.decision_var[vo.var] || cannot_eliminate[vo.var])
+            continue;
+        touchedBlockedVarsBool[vo.var] = false;
+        Lit lit = Lit(vo.var, false);
+        Lit negLit = Lit(vo.var, true);
+        
+        numMaxBlockToVisit -= (int64_t)occur[lit.toInt()].size();
+        numMaxBlockToVisit -= (int64_t)occur[negLit.toInt()].size();
+        if (!tryOneSetting(lit, negLit)) {
+            tryOneSetting(negLit, lit);
+        }
+    }
+    blockTime += cpuTime() - myTime;
+    
+    #ifdef BIT_MORE_VERBOSITY
+    std::cout << "c  Total fime for block until now: " << blockTime << std::endl;
+    #endif
+}
+
+const bool Subsumer::tryOneSetting(const Lit lit, const Lit negLit)
+{
+    uint32_t toRemove = 0;
+    bool returnVal = false;
+    vec<Lit> cl;
+    
+    for(ClauseSimp *it = occur[lit.toInt()].getData(), *end = occur[lit.toInt()].getDataEnd(); it != end; it++) {
+        cl.clear();
+        cl.growTo(it->clause->size()-1);
+        for (uint32_t i = 0, i2 = 0; i < it->clause->size(); i++) {
+            if ((*it->clause)[i] != lit) {
+                cl[i2] = (*it->clause)[i];
+                i2++;
+            }
+        }
+        
+        if (allTautology(cl, negLit)) {
+            toRemove++;
+        } else {
+            break;
+        }
+    }
+    
+    if (toRemove == occur[lit.toInt()].size()) {
+        var_elimed[lit.var()] = true;
+        solver.setDecisionVar(lit.var(), false);
+        vec<ClauseSimp> toRemove(occur[lit.toInt()]);
+        for (ClauseSimp *it = toRemove.getData(), *end = toRemove.getDataEnd(); it != end; it++) {
+            unlinkClause(*it, lit.var());
+            numblockedClauseRemoved++;
+        }
+        
+        vec<ClauseSimp> toRemove2(occur[negLit.toInt()]);
+        for (ClauseSimp *it = toRemove2.getData(), *end = toRemove2.getDataEnd(); it != end; it++) {
+            unlinkClause(*it, lit.var());
+            numblockedClauseRemoved++;
+        }
+        returnVal = true;
+    }
+    
+    return returnVal;
+}
+
+void Subsumer::addAllXorAsNorm()
+{
+    uint32_t added = 0;
+    XorClause **i = solver.xorclauses.getData(), **j = i;
+    for (XorClause **end = solver.xorclauses.getDataEnd(); i != end; i++) {
+        if ((*i)->size() > 3) {
+            *j++ = *i;
+            continue;
+        }
+        added++;
+        if ((*i)->size() == 3) addXorAsNormal3(**i);
+        //if ((*i)->size() == 4) addXorAsNormal4(**i);
+        solver.removeClause(**i);
+    }
+    solver.xorclauses.shrink(i-j);
+    std::cout << "Added XOR as norm:" << added << std::endl;
+}
+
+void Subsumer::addXorAsNormal3(XorClause& c)
+{
+    assert(c.size() == 3);
+    Clause *tmp;
+    vec<Var> vars;
+    vec<Lit> vars2(c.size());
+    const bool inverted = c.xor_clause_inverted();
+    
+    for (uint32_t i = 0; i < c.size(); i++) {
+        vars.push(c[i].var());
+    }
+    
+    vars2[0] = Lit(vars[0], false ^ inverted);
+    vars2[1] = Lit(vars[1], false ^ inverted);
+    vars2[2] = Lit(vars[2], false ^ inverted);
+    tmp = solver.addClauseInt(vars2, c.getGroup());
+    if (tmp) solver.clauses.push(tmp);
+    
+    vars2[0] = Lit(vars[0], true ^ inverted);
+    vars2[1] = Lit(vars[1], true ^ inverted);
+    vars2[2] = Lit(vars[2], false ^ inverted);
+    tmp = solver.addClauseInt(vars2, c.getGroup());
+    if (tmp) solver.clauses.push(tmp);
+    
+    vars2[0] = Lit(vars[0], true ^ inverted);
+    vars2[1] = Lit(vars[1], false ^ inverted);
+    vars2[2] = Lit(vars[2], true ^ inverted);
+    tmp = solver.addClauseInt(vars2, c.getGroup());
+    if (tmp) solver.clauses.push(tmp);
+    
+    vars2[0] = Lit(vars[0], false ^ inverted);
+    vars2[1] = Lit(vars[1], true ^ inverted);
+    vars2[2] = Lit(vars[2], true ^ inverted);
+    tmp = solver.addClauseInt(vars2, c.getGroup());
+    if (tmp) solver.clauses.push(tmp);
+}
+
+void Subsumer::addXorAsNormal4(XorClause& c)
+{
+    assert(c.size() == 4);
+    Clause *tmp;
+    vec<Var> vars;
+    vec<Lit> vars2(c.size());
+    const bool inverted = !c.xor_clause_inverted();
+    
+    for (uint32_t i = 0; i < c.size(); i++) {
+        vars.push(c[i].var());
+    }
+    
+    vars2[0] = Lit(vars[0], false ^ inverted);
+    vars2[1] = Lit(vars[1], false ^ inverted);
+    vars2[2] = Lit(vars[2], false ^ inverted);
+    vars2[3] = Lit(vars[3], true ^ inverted);
+    tmp = solver.addClauseInt(vars2, c.getGroup());
+    if (tmp) solver.clauses.push(tmp);
+    
+    vars2[0] = Lit(vars[0], false ^ inverted);
+    vars2[1] = Lit(vars[1], true ^ inverted);
+    vars2[2] = Lit(vars[2], false ^ inverted);
+    vars2[3] = Lit(vars[3], false ^ inverted);
+    tmp = solver.addClauseInt(vars2, c.getGroup());
+    if (tmp) solver.clauses.push(tmp);
+    
+    vars2[0] = Lit(vars[0], false ^ inverted);
+    vars2[1] = Lit(vars[1], false ^ inverted);
+    vars2[2] = Lit(vars[2], true ^ inverted);
+    vars2[3] = Lit(vars[3], false ^ inverted);
+    tmp = solver.addClauseInt(vars2, c.getGroup());
+    if (tmp) solver.clauses.push(tmp);
+    
+    vars2[0] = Lit(vars[0], false ^ inverted);
+    vars2[1] = Lit(vars[1], false ^ inverted);
+    vars2[2] = Lit(vars[2], false ^ inverted);
+    vars2[3] = Lit(vars[3], true ^ inverted);
+    tmp = solver.addClauseInt(vars2, c.getGroup());
+    if (tmp) solver.clauses.push(tmp);
+    
+    vars2[0] = Lit(vars[0], false ^ inverted);
+    vars2[1] = Lit(vars[1], true ^ inverted);
+    vars2[2] = Lit(vars[2], true ^ inverted);
+    vars2[3] = Lit(vars[3], true ^ inverted);
+    tmp = solver.addClauseInt(vars2, c.getGroup());
+    if (tmp) solver.clauses.push(tmp);
+    
+    vars2[0] = Lit(vars[0], true ^ inverted);
+    vars2[1] = Lit(vars[1], false ^ inverted);
+    vars2[2] = Lit(vars[2], true ^ inverted);
+    vars2[3] = Lit(vars[3], true ^ inverted);
+    tmp = solver.addClauseInt(vars2, c.getGroup());
+    if (tmp) solver.clauses.push(tmp);
+    
+    vars2[0] = Lit(vars[0], true ^ inverted);
+    vars2[1] = Lit(vars[1], true ^ inverted);
+    vars2[2] = Lit(vars[2], false ^ inverted);
+    vars2[3] = Lit(vars[3], true ^ inverted);
+    tmp = solver.addClauseInt(vars2, c.getGroup());
+    if (tmp) solver.clauses.push(tmp);
+    
+    vars2[0] = Lit(vars[0], true ^ inverted);
+    vars2[1] = Lit(vars[1], true ^ inverted);
+    vars2[2] = Lit(vars[2], true ^ inverted);
+    vars2[3] = Lit(vars[3], false ^ inverted);
+    tmp = solver.addClauseInt(vars2, c.getGroup());
+    if (tmp) solver.clauses.push(tmp);
+}
+
+/*vector<char> Subsumer::merge()
+{
+    vector<char> var_merged(solver.nVars(), false);
+    double myTime = cpuTime();
+    
+    vector<varDataStruct> varData(solver.nVars());
+    
+    for (Var var = 0; var < solver.nVars(); var++) if (solver.decision_var[var] && solver.assigns[var] == l_Undef && !cannot_eliminate[var]) {
+        varDataStruct thisVar;
+        
+        vec<ClauseSimp>& toCountPos = occur[Lit(var, false).toInt()];
+        thisVar.numPosClauses = toCountPos.size();
+        for (uint32_t i2 = 0; i2 < toCountPos.size(); i2++) {
+            thisVar.sumPosClauseSize += toCountPos[i2].clause->size();
+            for (Lit *l = toCountPos[i2].clause->getData(), *end = l + toCountPos[i2].clause->size(); l != end; l++) {
+                if (l->var() != var) thisVar.posHash ^= hash32shift(l->toInt());
+            }
+        }
+        
+        vec<ClauseSimp>& toCountNeg = occur[Lit(var, true).toInt()];
+        thisVar.numNegClauses = toCountNeg.size();
+        for (uint32_t i2 = 0; i2 < toCountNeg.size(); i2++) {
+            thisVar.sumNegClauseSize += toCountNeg[i2].clause->size();
+            for (Lit *l = toCountNeg[i2].clause->getData(), *end = l + toCountNeg[i2].clause->size(); l != end; l++) {
+                if (l->var() != var) thisVar.negHash ^= hash32shift(l->toInt());
+            }
+        }
+        
+        varData[var] = thisVar;
+    }
+    
+    map<varDataStruct, vector<Var> > dataToVar;
+    for (Var var = 0; var < solver.nVars(); var++) if (solver.decision_var[var] && solver.assigns[var] == l_Undef) {
+        dataToVar[varData[var]].push_back(var);
+        assert(dataToVar[varData[var]].size() > 0);
+    }
+    
+    for (map<varDataStruct, vector<Var> >::iterator it = dataToVar.begin(); it != dataToVar.end(); it++) {
+        //std::cout << "size: " << it->second.size() << std::endl;
+        for (uint i = 0; i < it->second.size()-1; i++) {
+            assert(it->second.size() > i+1);
+            assert(varData[it->second[i]] == varData[it->second[i+1]]);
+        }
+    }
+    
+    uint64_t checked = 0;
+    uint64_t replaced = 0;
+    for (Var var = 0; var < solver.nVars(); var++) if (solver.decision_var[var] && solver.assigns[var] == l_Undef && !cannot_eliminate[var]) {
+        varDataStruct tmp = varData[var];
+        assert(dataToVar[tmp].size() > 0);
+        
+        if (dataToVar[tmp].size() > 0) {
+            map<varDataStruct, vector<Var> >::iterator it = dataToVar.find(tmp);
+            for (uint i = 0; i < it->second.size(); i++) if (it->second[i] != var) {
+                checked ++;
+                if (checkIfSame(Lit(var, false), Lit(it->second[i], false)) &&
+                    (checkIfSame(Lit(var, true), Lit(it->second[i], true))))
+                {
+                    vec<Lit> ps(2);
+                    ps[0] = Lit(var, false);
+                    ps[1] = Lit(it->second[i], false);
+                    solver.varReplacer->replace(ps, true, 0);
+                    replaced++;
+                    goto next;
+                    
+                }
+            }
+        }
+        
+        tmp.reversePolarity();
+        if (dataToVar[tmp].size() > 0) {
+            map<varDataStruct, vector<Var> >::iterator it = dataToVar.find(tmp);
+            for (uint i = 0; i < it->second.size(); i++) if (it->second[i] != var) {
+                checked ++;
+                if (checkIfSame(Lit(var, true), Lit(it->second[i], false)) &&
+                    (checkIfSame(Lit(var, false), Lit(it->second[i], true))))
+                {
+                    vec<Lit> ps(2);
+                    ps[0] = Lit(var, false);
+                    ps[1] = Lit(it->second[i], false);
+                    solver.varReplacer->replace(ps, false, 0);
+                    replaced++;
+                    goto next;
+                }
+            }
+        }
+        
+        next:;
+    }
+        
+    std::cout << "c |  Merging vars in same clauses.  checked: " << std::setw(5) << checked << " replaced: " << std::setw(5) << replaced << " time: " << std::setprecision(2) << std::setw(5) << cpuTime()-myTime << std::endl;
+    
+    return var_merged;
+}*/
+
+/*const bool Subsumer::checkIfSame(const Lit lit1, const Lit lit2)
+{
+    assert(lit1.var() != lit2.var());
+    #ifdef VERBOSE_DEBUG
+    std::cout << "checking : " << lit1.var()+1 << " , " << lit2.var()+1 << std::endl;
+    #endif
+    
+    vec<ClauseSimp>& occSet1 = occur[lit1.toInt()];
+    vec<ClauseSimp>& occSet2 = occur[lit2.toInt()];
+    vec<Lit> tmp;
+    
+    for (ClauseSimp *it = occSet1.getData(), *end = it + occSet1.size(); it != end; it++) {
+        bool found = false;
+        tmp.clear();
+        uint32_t clauseSize = it->clause->size();
+        
+        for (Lit *l = it->clause->getData(), *end2 = l + it->clause->size(); l != end2; l++) {
+            if (l->var() != lit1.var()) {
+                tmp.push(*l);
+                seen_tmp[l->toInt()] = true;
+            }
+        }
+        #ifdef VERBOSE_DEBUG
+        std::cout << "orig: ";
+        it->clause->plainPrint();
+        #endif
+        
+        for (ClauseSimp *it2 = occSet2.getData(), *end2 = it2 + occSet2.size(); (it2 != end2 && !found); it2++) {
+            if (it2->clause->size() != clauseSize) continue;
+            
+            for (Lit *l = it2->clause->getData(), *end3 = l + tmp.size(); l != end3; l++) if (l->var() != lit1.var()) {
+                if (!seen_tmp[l->toInt()]) goto next;
+            }
+            found = true;
+            
+            #ifdef VERBOSE_DEBUG
+            std::cout << "OK:   ";
+            it2->clause->plainPrint();
+            #endif
+            next:;
+        }
+        
+        for (Lit *l = tmp.getData(), *end2 = l + tmp.size(); l != end2; l++) {
+            seen_tmp[l->toInt()] = false;
+        }
+        
+        if (!found) return false;
+    }
+    #ifdef VERBOSE_DEBUG
+    std::cout << "OK" << std::endl;
+    #endif
+    
+    return true;
+}*/
+
+/*void Subsumer::pureLiteralRemoval()
+{
+    for (Var var = 0; var < solver.nVars(); var++) if (solver.decision_var[var] && solver.assigns[var] == l_Undef && !cannot_eliminate[var] && !var_elimed[var] && !solver.varReplacer->varHasBeenReplaced(var)) {
+        uint32_t numPosClauses = occur[Lit(var, false).toInt()].size();
+        uint32_t numNegClauses = occur[Lit(var, true).toInt()].size();
+        if (numNegClauses > 0 && numPosClauses > 0) continue;
+        
+        if (numNegClauses == 0 && numPosClauses == 0) {
+            if (solver.decision_var[var]) madeVarNonDecision.push(var);
+            solver.setDecisionVar(var, false);
+            pureLitRemoved[var] = true;
+            pureLitsRemovedNum++;
+            continue;
+        }
+        
+        if (numPosClauses == 0 && numNegClauses > 0) {
+            if (solver.decision_var[var]) madeVarNonDecision.push(var);
+            solver.setDecisionVar(var, false);
+            pureLitRemoved[var] = true;
+            assignVar.push(Lit(var, true));
+            vec<ClauseSimp> occ(occur[Lit(var, true).toInt()]);
+            for (ClauseSimp *it = occ.getData(), *end = occ.getDataEnd(); it != end; it++) {
+                unlinkClause(*it);
+                pureLitClauseRemoved.push(it->clause);
+            }
+            pureLitsRemovedNum++;
+            continue;
+        }
+        
+        if (numNegClauses == 0 && numPosClauses > 0) {
+            if (solver.decision_var[var]) madeVarNonDecision.push(var);
+            solver.setDecisionVar(var, false);
+            pureLitRemoved[var] = true;
+            assignVar.push(Lit(var, false));
+            vec<ClauseSimp> occ(occur[Lit(var, false).toInt()]);
+            for (ClauseSimp *it = occ.getData(), *end = occ.getDataEnd(); it != end; it++) {
+                unlinkClause(*it);
+                pureLitClauseRemoved.push(it->clause);
+            }
+            pureLitsRemovedNum++;
+            continue;
+        }
+    }
+}*/
+
+/*void Subsumer::undoPureLitRemoval()
+{
+    assert(solver.ok);
+    for (uint32_t i = 0; i < madeVarNonDecision.size(); i++) {
+        assert(!solver.decision_var[madeVarNonDecision[i]]);
+        assert(solver.assigns[madeVarNonDecision[i]] == l_Undef);
+        solver.setDecisionVar(madeVarNonDecision[i], true);
+        pureLitRemoved[madeVarNonDecision[i]] = false;
+    }
+    madeVarNonDecision.clear();
+    
+    for (Lit *l = assignVar.getData(), *end = assignVar.getDataEnd(); l != end; l++) {
+        solver.uncheckedEnqueue(*l);
+        solver.ok = (solver.propagate() == NULL);
+        assert(solver.ok);
+    }
+    assignVar.clear();
+}
+
+void Subsumer::reAddPureLitClauses()
+{
+    for (Clause **it = pureLitClauseRemoved.getData(), **end = pureLitClauseRemoved.getDataEnd(); it != end; it++) {
+        solver.addClause(**it, (*it)->getGroup());
+        free(*it);
+        assert(solver.ok);
+    }
+    pureLitClauseRemoved.clear();
+}*/
+
+}; //NAMESPACE MINISAT
diff --git a/src/sat/cryptominisat2/Subsumer.h b/src/sat/cryptominisat2/Subsumer.h
new file mode 100644 (file)
index 0000000..2d3e95a
--- /dev/null
@@ -0,0 +1,249 @@
+/**************************************************************************************************
+Originally From: Solver.C -- (C) Niklas Een, Niklas Sorensson, 2004
+Substantially modified by: Mate Soos (2010)
+**************************************************************************************************/
+
+#ifndef SIMPLIFIER_H
+#define SIMPLIFIER_H
+
+#include "Solver.h"
+#include "Queue.h"
+#include "CSet.h"
+#include "BitArray.h"
+#include <map>
+#include <vector>
+#include <queue>
+using std::vector;
+using std::map;
+using std::priority_queue;
+
+namespace MINISAT
+{
+using namespace MINISAT;
+
+class ClauseCleaner;
+
+class Subsumer
+{
+public:
+    
+    Subsumer(Solver& S2);
+    ~Subsumer();
+    const bool simplifyBySubsumption();
+    void unlinkModifiedClause(vec<Lit>& origClause, ClauseSimp c);
+    void unlinkModifiedClauseNoDetachNoNULL(vec<Lit>& origClause, ClauseSimp c);
+    void unlinkClause(ClauseSimp cc, Var elim = var_Undef);
+    ClauseSimp linkInClause(Clause& cl);
+    void linkInAlreadyClause(ClauseSimp& c);
+    void updateClause(ClauseSimp c);
+    void newVar();
+    void extendModel(Solver& solver2);
+    const bool unEliminate(const Var var);
+    const vec<char>& getVarElimed() const;
+    const uint32_t getNumElimed() const;
+    
+private:
+    
+    friend class ClauseCleaner;
+    
+    //Main
+    vec<ClauseSimp>        clauses;
+    CSet                   learntClauses;
+    vec<char>              touched;        // Is set to true when a variable is part of a removed clause. Also true initially (upon variable creation).
+    vec<Var>               touched_list;   // A list of the true elements in 'touched'.
+    CSet                   cl_touched;     // Clauses strengthened.
+    CSet                   cl_added;       // Clauses created.
+    vec<vec<ClauseSimp> >  occur;          // 'occur[index(lit)]' is a list of constraints containing 'lit'.
+    vec<vec<ClauseSimp>* > iter_vecs;      // Vectors currently used for iterations. Removed clauses will be looked up and replaced by 'Clause_NULL'.
+    vec<CSet* >            iter_sets;      // Sets currently used for iterations.
+    Solver&                solver;         // The Solver
+    
+    
+    vec<char>              var_elimed;     // 'eliminated[var]' is TRUE if variable has been eliminated.
+    vec<char>              cannot_eliminate;//
+    map<Var, vector<vector<Lit> > > elimedOutVar;
+    
+    // Temporaries (to reduce allocation overhead):
+    //
+    vec<char>           seen_tmp;       // (used in various places)
+    vector<Lit>         io_tmp;         // (used for reading/writing clauses from/to disk)
+    
+    
+    //Limits
+    uint32_t numVarsElimed;
+    uint32_t numMaxSubsume1;
+    uint32_t numMaxSubsume0;
+    uint32_t numMaxElim;
+    int64_t numMaxBlockToVisit;
+    uint32_t numMaxBlockVars;
+    
+    //Start-up
+    void addFromSolver(vec<Clause*>& cs);
+    void addBackToSolver();
+    void removeWrong(vec<Clause*>& cs);
+    void fillCannotEliminate();
+    const bool treatLearnts();
+    void addAllXorAsNorm();
+    void addXorAsNormal3(XorClause& c);
+    void addXorAsNormal4(XorClause& c);
+    
+    //Iterations
+    void registerIteration  (CSet& iter_set) { iter_sets.push(&iter_set); }
+    void unregisterIteration(CSet& iter_set) { remove(iter_sets, &iter_set); }
+    void registerIteration  (vec<ClauseSimp>& iter_vec) { iter_vecs.push(&iter_vec); }
+    void unregisterIteration(vec<ClauseSimp>& iter_vec) { remove(iter_vecs, &iter_vec); }
+    
+    // Subsumption:
+    void touch(const Var x);
+    void touch(const Lit p);
+    bool updateOccur(Clause& c);
+    void findSubsumed(Clause& ps, vec<ClauseSimp>& out_subsumed);
+    void findSubsumed(const vec<Lit>& ps, const uint32_t abst, vec<ClauseSimp>& out_subsumed);
+    void findSubsumed(Clause& ps, uint32_t abs, vec<ClauseSimp>& out_subsumed);
+    bool isSubsumed(Clause& ps);
+    uint32_t subsume0(Clause& ps);
+    uint32_t subsume0(Clause& ps, uint32_t abs);
+    void subsume0LearntSet(vec<Clause*>& cs);
+    void subsume1(ClauseSimp& ps);
+    void smaller_database();
+    void almost_all_database();
+    template<class T1, class T2>
+    bool subset(const T1& A, const T2& B);
+    bool subsetAbst(uint32_t A, uint32_t B);
+    
+    void orderVarsForElim(vec<Var>& order);
+    int  substitute(Lit x, Clause& def, vec<Clause*>& poss, vec<Clause*>& negs, vec<Clause*>& new_clauses);
+    bool maybeEliminate(Var x);
+    void MigrateToPsNs(vec<ClauseSimp>& poss, vec<ClauseSimp>& negs, vec<ClauseSimp>& ps, vec<ClauseSimp>& ns, const Var x);
+    void DeallocPsNs(vec<ClauseSimp>& ps, vec<ClauseSimp>& ns);
+    bool merge(Clause& ps, Clause& qs, Lit without_p, Lit without_q, vec<Lit>& out_clause);
+    
+    
+    //hyperBinRes
+    void addFromSolverAll(vec<Clause*>& cs);
+    const bool hyperBinRes();
+    const bool hyperUtility(vec<ClauseSimp>& iter, const Lit lit, BitArray& inside, vec<ClauseSimp>& addToClauses, uint32_t& hyperBinAdded, uint32_t& hyperBinUnitary);
+    
+    //merging
+    //vector<char> merge();
+    //const bool checkIfSame(const Lit var1, const Lit var2);
+    
+    class VarOcc {
+        public:
+            VarOcc(const Var& v, const uint32_t num) :
+                var(v)
+                , occurnum(num)
+            {}
+            Var var;
+            uint32_t occurnum;
+    };
+    
+    struct MyComp {
+        const bool operator() (const VarOcc& l1, const VarOcc& l2) const {
+            return l1.occurnum > l2.occurnum;
+        }
+    };
+    
+    void blockedClauseRemoval();
+    const bool allTautology(const vec<Lit>& ps, const Lit lit);
+    uint32_t numblockedClauseRemoved;
+    const bool tryOneSetting(const Lit lit, const Lit negLit);
+    priority_queue<VarOcc, vector<VarOcc>, MyComp> touchedBlockedVars;
+    vec<bool> touchedBlockedVarsBool;
+    void touchBlockedVar(const Var x);
+    double blockTime;
+    
+    
+    //validity checking
+    void verifyIntegrity();
+    
+    uint32_t clauses_subsumed;
+    uint32_t literals_removed;
+    uint32_t origNClauses;
+    uint32_t numCalls;
+    bool fullSubsume;
+    uint32_t clauseID;
+    uint32_t numElimed;
+};
+
+template <class T, class T2>
+void maybeRemove(vec<T>& ws, const T2& elem)
+{
+    if (ws.size() > 0)
+        removeW(ws, elem);
+}
+
+inline void Subsumer::touch(const Var x)
+{
+    if (!touched[x]) {
+        touched[x] = 1;
+        touched_list.push(x);
+    }
+}
+
+inline void Subsumer::touchBlockedVar(const Var x)
+{
+    if (!touchedBlockedVarsBool[x]) {
+        touchedBlockedVars.push(VarOcc(x, occur[Lit(x, false).toInt()].size()*occur[Lit(x, true).toInt()].size()));
+        touchedBlockedVarsBool[x] = 1;
+    }
+}
+
+inline void Subsumer::touch(const Lit p)
+{
+    touch(p.var());
+}
+
+inline bool Subsumer::updateOccur(Clause& c)
+{
+    return !c.learnt();
+}
+
+inline bool Subsumer::subsetAbst(uint32_t A, uint32_t B)
+{
+    return !(A & ~B);
+}
+
+// Assumes 'seen' is cleared (will leave it cleared)
+template<class T1, class T2>
+bool Subsumer::subset(const T1& A, const T2& B)
+{
+    for (uint32_t i = 0; i != B.size(); i++)
+        seen_tmp[B[i].toInt()] = 1;
+    for (uint32_t i = 0; i != A.size(); i++) {
+        if (!seen_tmp[A[i].toInt()]) {
+            for (uint32_t i = 0; i != B.size(); i++)
+                seen_tmp[B[i].toInt()] = 0;
+            return false;
+        }
+    }
+    for (uint32_t i = 0; i != B.size(); i++)
+        seen_tmp[B[i].toInt()] = 0;
+    return true;
+}
+
+inline void Subsumer::newVar()
+{
+    occur       .push();
+    occur       .push();
+    seen_tmp    .push(0);       // (one for each polarity)
+    seen_tmp    .push(0);
+    touched     .push(1);
+    var_elimed  .push(0);
+    touchedBlockedVarsBool.push(0);
+    cannot_eliminate.push(0);
+}
+
+inline const vec<char>& Subsumer::getVarElimed() const
+{
+    return var_elimed;
+}
+
+inline const uint32_t Subsumer::getNumElimed() const
+{
+    return numElimed;
+}
+
+}; //NAMESPACE MINISAT
+
+#endif //SIMPLIFIER_H
index c0069382a504bc482592446639a57034c046875a..9f06d3b49ba0599c204751a7508eef80a2552ee3 100644 (file)
@@ -1,3 +1,2 @@
 CryptoMiniSat
-SVN revision: 686
-GIT revision: 30b79471e85e0dde20440ea5c51c78246d14c8ab
+GIT revision: e2b5fe1abd1777f753c775026d905a10006ce79b
index 575a347ea36ec550c38190036c9b0a56550c227a..6a23e22652632020c28abb03f0d44542e5ea9708 100644 (file)
@@ -16,13 +16,17 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 **************************************************************************************************/
 
 #include "VarReplacer.h"
+#include <iostream>
+#include <iomanip>
 
-#include "Solver.h"
 #include "Conglomerate.h"
 #include "ClauseCleaner.h"
+#include "PartHandler.h"
+#include "time_mem.h"
 
 //#define VERBOSE_DEBUG
 //#define DEBUG_REPLACER
+//#define REPLACE_STATISTICS
 
 #ifdef VERBOSE_DEBUG
 #include <iostream>
@@ -32,34 +36,51 @@ using std::endl;
 
 namespace MINISAT
 {
+using namespace MINISAT;
 
-VarReplacer::VarReplacer(Solver *_s) :
+VarReplacer::VarReplacer(Solver& _solver) :
     replacedLits(0)
-    , lastReplacedLits(0)
     , replacedVars(0)
     , lastReplacedVars(0)
-    , addedNewClause(false)
-    , S(_s)
+    , solver(_solver)
 {
 }
 
 VarReplacer::~VarReplacer()
 {
     for (uint i = 0; i != clauses.size(); i++)
+        //binaryClausePool.free(clauses[i]);
         free(clauses[i]);
 }
 
-void VarReplacer::performReplace()
+const bool VarReplacer::performReplaceInternal()
 {
     #ifdef VERBOSE_DEBUG
     cout << "Replacer started." << endl;
     #endif
+    double time = cpuTime();
     
-    S->clauseCleaner->cleanClauses(S->clauses, ClauseCleaner::clauses);
-    S->clauseCleaner->cleanClauses(S->learnts, ClauseCleaner::learnts);
-    S->clauseCleaner->cleanClauses(S->xorclauses, ClauseCleaner::xorclauses);
-    
-    if (replacedVars == lastReplacedVars) return;
+    #ifdef REPLACE_STATISTICS
+    uint numRedir = 0;
+    for (uint i = 0; i < table.size(); i++) {
+        if (table[i].var() != i)
+            numRedir++;
+    }
+    std::cout << "Number of trees:" << reverseTable.size() << std::endl;
+    std::cout << "Number of redirected nodes:" << numRedir << std::endl;
+    /*map<Var, vector<Var> >::iterator it = reverseTable.begin();
+    map<Var, vector<Var> >::iterator end = reverseTable.end();
+    for (;it != end; it++) {
+        std::cout << "Tree size: " << it->second.size() << std::endl;
+    }*/
+    #endif //REPLACE_STATISTICS
+    
+    solver.clauseCleaner->cleanClauses(solver.clauses, ClauseCleaner::clauses);
+    solver.clauseCleaner->cleanClauses(solver.learnts, ClauseCleaner::learnts);
+    solver.clauseCleaner->cleanClauses(solver.xorclauses, ClauseCleaner::xorclauses);
+    solver.clauseCleaner->removeSatisfied(solver.binaryClauses, ClauseCleaner::binaryClauses);
+    if (solver.ok == false)
+        return false;
     
     #ifdef VERBOSE_DEBUG
     {
@@ -71,42 +92,62 @@ void VarReplacer::performReplace()
     }
     #endif
     
-    uint i = 0;
-    const vector<bool>& removedVars = S->conglomerate->getRemovedVars();
-    for (vector<Lit>::const_iterator it = table.begin(); it != table.end(); it++, i++) {
-        if (it->var() == i) continue;
+    Var var = 0;
+    const vector<bool>& removedVars = solver.conglomerate->getRemovedVars();
+    const vec<lbool>& removedVars2 = solver.partHandler->getSavedState();
+    const vec<char>& removedVars3 = solver.subsumer->getVarElimed();
+    for (vector<Lit>::const_iterator it = table.begin(); it != table.end(); it++, var++) {
+        if (it->var() == var || removedVars[it->var()] || removedVars2[it->var()] != l_Undef || removedVars3[it->var()]) continue;
         #ifdef VERBOSE_DEBUG
-        cout << "Setting var " << i+1 << " to a non-decision var" << endl;
+        cout << "Setting var " << var+1 << " to a non-decision var" << endl;
         #endif
-        S->setDecisionVar(i, false);
-        if (!removedVars[it->var()])
-            S->setDecisionVar(it->var(), true);
+        bool wasDecisionVar = solver.decision_var[var];
+        solver.setDecisionVar(var, false);
+        solver.setDecisionVar(it->var(), true);
+        
+        double& activity1 = solver.activity[var];
+        double& activity2 = solver.activity[it->var()];
+        if (wasDecisionVar && activity1 > activity2) {
+            activity2 = activity1;
+            solver.order_heap.update(it->var());
+            solver.polarity[it->var()] = solver.polarity[var]^it->sign();
+        }
+        
+        activity1 = 0.0;
+        solver.order_heap.update(var);
     }
+    assert(solver.order_heap.heapProperty());
+    
+    if (solver.verbosity >= 2)
+        std::cout << "c |  Replacing   " << std::setw(8) << replacedVars-lastReplacedVars << " vars";
     
-    replace_set(S->clauses);
-    replace_set(S->learnts);
+    lastReplacedVars = replacedVars;
     
-    replace_set(S->xorclauses, true);
-    replace_set(S->conglomerate->getCalcAtFinish(), false);
+    if (!replace_set(solver.clauses)) return false;
+    if (!replace_set(solver.learnts)) return false;
+    if (!replace_set(solver.binaryClauses)) return false;
+    
+    if (!replace_set(solver.xorclauses, true)) return false;
+    if (!replace_set(solver.conglomerate->getCalcAtFinish(), false)) return false;
     
     for (uint i = 0; i != clauses.size(); i++)
-        S->removeClause(*clauses[i]);
+        solver.removeClause(*clauses[i]);
     clauses.clear();
     
-    if (S->verbosity >=1)
-        printf("c |  Replacing   %8d vars, replaced %8d lits                          |\n", replacedVars-lastReplacedVars, replacedLits-lastReplacedLits);
+    if (solver.verbosity >= 2) {
+        std::cout << "     Replaced " <<  std::setw(8) << replacedLits<< " lits"
+        << "     Time: " << std::setw(8) << std::fixed << std::setprecision(2) << cpuTime()-time << " s "
+        << std::setw(12) <<  " |" << std::endl;
+    }
     
-    addedNewClause = false;
-    lastReplacedVars = replacedVars;
-    lastReplacedLits = replacedLits;
+    replacedLits = 0;
     
-    if (S->ok)
-        S->ok = (S->propagate() == NULL);
+    solver.order_heap.filter(Solver::VarFilter(solver));
     
-    S->order_heap.filter(Solver::VarFilter(*S));
+    return solver.ok;
 }
 
-void VarReplacer::replace_set(vec<XorClause*>& cs, const bool isAttached)
+const bool VarReplacer::replace_set(vec<XorClause*>& cs, const bool isAttached)
 {
     XorClause **a = cs.getData();
     XorClause **r = a;
@@ -122,19 +163,22 @@ void VarReplacer::replace_set(vec<XorClause*>& cs, const bool isAttached)
                 changed = true;
                 *l = Lit(newlit.var(), false);
                 c.invert(newlit.sign());
+                c.setVarChanged();
                 replacedLits++;
             }
         }
         
         if (isAttached && changed && handleUpdatedClause(c, origVar1, origVar2)) {
-            c.mark(1);
-            S->freeLater.push(&c);
+            if (solver.ok == false) return false;
+            solver.freeLater.push(&c);
             r++;
         } else {
             *a++ = *r++;
         }
     }
     cs.shrink(r-a);
+    
+    return solver.ok;
 }
 
 const bool VarReplacer::handleUpdatedClause(XorClause& c, const Var origVar1, const Var origVar2)
@@ -149,11 +193,12 @@ const bool VarReplacer::handleUpdatedClause(XorClause& c, const Var origVar1, co
             //added, but easily removed
             j--;
             p = lit_Undef;
-            if (!S->assigns[c[i].var()].isUndef())
-                c.invert(S->assigns[c[i].var()].getBool());
-        } else if (S->assigns[c[i].var()].isUndef()) //just add
+            if (!solver.assigns[c[i].var()].isUndef())
+                c.invert(solver.assigns[c[i].var()].getBool());
+            solver.clauses_literals -= 2;
+        } else if (solver.assigns[c[i].var()].isUndef()) //just add
             c[j++] = p = c[i];
-        else c.invert(S->assigns[c[i].var()].getBool()); //modify xor_clause_inverted instead of adding
+        else c.invert(solver.assigns[c[i].var()].getBool()); //modify xor_clause_inverted instead of adding
     }
     c.shrink(i - j);
     
@@ -164,27 +209,26 @@ const bool VarReplacer::handleUpdatedClause(XorClause& c, const Var origVar1, co
     
     switch (c.size()) {
     case 0:
-        S->detachModifiedClause(origVar1, origVar2, origSize, &c);
+        solver.detachModifiedClause(origVar1, origVar2, origSize, &c);
         if (!c.xor_clause_inverted())
-            S->ok = false;
+            solver.ok = false;
         return true;
     case 1:
-        S->detachModifiedClause(origVar1, origVar2, origSize, &c);
-        S->uncheckedEnqueue(c[0] ^ c.xor_clause_inverted());
+        solver.detachModifiedClause(origVar1, origVar2, origSize, &c);
+        solver.uncheckedEnqueue(c[0] ^ c.xor_clause_inverted());
+        solver.ok = (solver.propagate() == NULL);
         return true;
     case 2: {
-        S->detachModifiedClause(origVar1, origVar2, origSize, &c);
+        solver.detachModifiedClause(origVar1, origVar2, origSize, &c);
         vec<Lit> ps(2);
         ps[0] = c[0];
         ps[1] = c[1];
-        addBinaryXorClause(ps, c.xor_clause_inverted(), c.group, true);
+        addBinaryXorClause(ps, c.xor_clause_inverted(), c.getGroup(), true);
         return true;
     }
     default:
-        if (origVar1 != c[0].var() || origVar2 != c[1].var()) {
-            S->detachModifiedClause(origVar1, origVar2, origSize, &c);
-            S->attachClause(c);
-        }
+        solver.detachModifiedClause(origVar1, origVar2, origSize, &c);
+        solver.attachClause(c);
         return false;
     }
     
@@ -192,7 +236,7 @@ const bool VarReplacer::handleUpdatedClause(XorClause& c, const Var origVar1, co
     return false;
 }
 
-void VarReplacer::replace_set(vec<Clause*>& cs)
+const bool VarReplacer::replace_set(vec<Clause*>& cs)
 {
     Clause **a = cs.getData();
     Clause **r = a;
@@ -205,18 +249,22 @@ void VarReplacer::replace_set(vec<Clause*>& cs)
             if (table[l->var()].var() != l->var()) {
                 changed = true;
                 *l = table[l->var()] ^ l->sign();
+                c.setVarChanged();
                 replacedLits++;
             }
         }
         
         if (changed && handleUpdatedClause(c, origLit1, origLit2)) {
-            free(&c);
+            if (solver.ok == false) return false;
+            clauseFree(&c);
             r++;
         } else {
             *a++ = *r++;
         }
     }
     cs.shrink(r-a);
+    
+    return solver.ok;
 }
 
 const bool VarReplacer::handleUpdatedClause(Clause& c, const Lit origLit1, const Lit origLit2)
@@ -227,38 +275,34 @@ const bool VarReplacer::handleUpdatedClause(Clause& c, const Lit origLit1, const
     uint32_t i, j;
     const uint origSize = c.size();
     for (i = j = 0, p = lit_Undef; i != origSize; i++) {
-        if (S->value(c[i]) == l_True || c[i] == ~p) {
+        if (solver.value(c[i]) == l_True || c[i] == ~p) {
             satisfied = true;
             break;
         }
-        else if (S->value(c[i]) != l_False && c[i] != p)
+        else if (solver.value(c[i]) != l_False && c[i] != p)
             c[j++] = p = c[i];
     }
     c.shrink(i - j);
     
     if (satisfied) {
-        S->detachModifiedClause(origLit1, origLit2, origSize, &c);
+        solver.detachModifiedClause(origLit1, origLit2, origSize, &c);
         return true;
     }
     
     switch(c.size()) {
     case 0:
-        S->detachModifiedClause(origLit1, origLit2, origSize, &c);
-        S->ok = false;
+        solver.detachModifiedClause(origLit1, origLit2, origSize, &c);
+        solver.ok = false;
         return true;
     case 1 :
-        S->detachModifiedClause(origLit1, origLit2, origSize, &c);
-        S->uncheckedEnqueue(c[0]);
+        solver.detachModifiedClause(origLit1, origLit2, origSize, &c);
+        solver.uncheckedEnqueue(c[0]);
+        solver.ok = (solver.propagate() == NULL);
         return true;
-    case 2:
-        S->detachModifiedClause(origLit1, origLit2, origSize, &c);
-        S->attachClause(c);
-        return false;
     default:
-        if (origLit1 != c[0] || origLit2 != c[1]) {
-            S->detachModifiedClause(origLit1, origLit2, origSize, &c);
-            S->attachClause(c);
-        }
+        solver.detachModifiedClause(origLit1, origLit2, origSize, &c);
+        solver.attachClause(c);
+        
         return false;
     }
     
@@ -266,31 +310,6 @@ const bool VarReplacer::handleUpdatedClause(Clause& c, const Lit origLit1, const
     return false;
 }
 
-const uint VarReplacer::getNumReplacedLits() const
-{
-    return replacedLits;
-}
-
-const uint VarReplacer::getNumReplacedVars() const
-{
-    return replacedVars;
-}
-
-const uint VarReplacer::getNumLastReplacedVars() const
-{
-    return lastReplacedVars;
-}
-
-const uint VarReplacer::getNewToReplaceVars() const
-{
-    return replacedVars-lastReplacedVars;
-}
-
-const vector<Lit>& VarReplacer::getReplaceTable() const
-{
-    return table;
-}
-
 const vector<Var> VarReplacer::getReplacingVars() const
 {
     vector<Var> replacingVars;
@@ -302,56 +321,78 @@ const vector<Var> VarReplacer::getReplacingVars() const
     return replacingVars;
 }
 
-const vec<Clause*>& VarReplacer::getClauses() const
-{
-    return clauses;
-}
-
-void VarReplacer::extendModel() const
+void VarReplacer::extendModelPossible() const
 {
     uint i = 0;
     for (vector<Lit>::const_iterator it = table.begin(); it != table.end(); it++, i++) {
         if (it->var() == i) continue;
         
         #ifdef VERBOSE_DEBUG
-        cout << "Extending model: var "; S->printLit(Lit(i, false));
-        cout << " to "; S->printLit(*it);
+        cout << "Extending model: var "; solver.printLit(Lit(i, false));
+        cout << " to "; solver.printLit(*it);
         cout << endl;
         #endif
         
-        assert(S->assigns[it->var()] != l_Undef);
-        if (S->assigns[i] == l_Undef) {
-            bool val = (S->assigns[it->var()] == l_False);
-            S->uncheckedEnqueue(Lit(i, val ^ it->sign()));
-        } else {
-            assert(S->assigns[i].getBool() == (S->assigns[it->var()].getBool() ^ it->sign()));
+        if (solver.assigns[it->var()] != l_Undef) {
+            if (solver.assigns[i] == l_Undef) {
+                bool val = (solver.assigns[it->var()] == l_False);
+                solver.uncheckedEnqueue(Lit(i, val ^ it->sign()));
+            } else {
+                assert(solver.assigns[i].getBool() == (solver.assigns[it->var()].getBool() ^ it->sign()));
+            }
+        }
+        solver.ok = (solver.propagate() == NULL);
+        assert(solver.ok);
+    }
+}
+
+void VarReplacer::extendModelImpossible(Solver& solver2) const
+{
+    vec<Lit> tmpClause;
+    uint i = 0;
+    for (vector<Lit>::const_iterator it = table.begin(); it != table.end(); it++, i++) {
+        if (it->var() == i) continue;
+        if (solver.assigns[it->var()] == l_Undef) {
+            assert(solver.assigns[it->var()] == l_Undef);
+            assert(solver.assigns[i] == l_Undef);
+            
+            tmpClause.clear();
+            tmpClause.push(Lit(it->var(), true));
+            tmpClause.push(Lit(i, it->sign()));
+            solver2.addClause(tmpClause);
+            assert(solver2.ok);
+            
+            tmpClause.clear();
+            tmpClause.push(Lit(it->var(), false));
+            tmpClause.push(Lit(i, it->sign()^true));
+            solver2.addClause(tmpClause);
+            assert(solver2.ok);
         }
     }
 }
 
-void VarReplacer::replace(vec<Lit>& ps, const bool xor_clause_inverted, const uint group)
+template<class T>
+const bool VarReplacer::replace(T& ps, const bool xor_clause_inverted, const uint group)
 {
     #ifdef VERBOSE_DEBUG
-    cout << "replace() called with var " << ps[0].var()+1 << " and var " << ps[1].var()+1 << " with xor_clause_inverted " << xor_clause_inverted << endl;
+    std::cout << "replace() called with var " << ps[0].var()+1 << " and var " << ps[1].var()+1 << " with xor_clause_inverted " << xor_clause_inverted << std::endl;
     #endif
     
-    #ifdef DEBUG_REPLACER
     assert(ps.size() == 2);
     assert(!ps[0].sign());
     assert(!ps[1].sign());
-    assert(S->assigns[ps[0].var()].isUndef());
-    assert(S->assigns[ps[1].var()].isUndef());
+    #ifdef DEBUG_REPLACER
+    assert(solver.assigns[ps[0].var()].isUndef());
+    assert(solver.assigns[ps[1].var()].isUndef());
     #endif
     
     
-    addBinaryXorClause(ps, xor_clause_inverted, group);
     Var var = ps[0].var();
     Lit lit = Lit(ps[1].var(), !xor_clause_inverted);
     assert(var != lit.var());
     
     //Detect circle
-    if (alreadyIn(var, lit)) return;
-    replacedVars++;
+    if (alreadyIn(var, lit)) return solver.ok;
     
     Lit lit1 = table[var];
     bool inverted = false;
@@ -366,48 +407,55 @@ void VarReplacer::replace(vec<Lit>& ps, const bool xor_clause_inverted, const ui
     }
     
     if (inverted) {
-        //Inversion is also set
         Lit lit2 = table[var];
         
-        //triangular cycle
+        //Inversion is also set, triangular cycle
+        //A->B, A->C, B->C. There is nothing to add
         if (lit1.var() == lit2.var()) {
             if ((lit1.sign() ^ lit2.sign()) != lit.sign()) {
                 #ifdef VERBOSE_DEBUG
                 cout << "Inverted cycle in var-replacement -> UNSAT" << endl;
                 #endif
-                S->ok = false;
+                return (solver.ok = false);
             }
-            return;
+            return true;
         }
         
+        //Inversion is also set
         if (lit2.var() != var) {
+            assert(table[lit1.var()].var() == lit1.var());
             setAllThatPointsHereTo(lit1.var(), Lit(lit.var(), lit1.sign()));
-            table[lit1.var()] = Lit(lit.var(), lit1.sign());
-            reverseTable[lit.var()].push_back(lit1.var());
             
+            assert(table[lit2.var()].var() == lit2.var());
             setAllThatPointsHereTo(lit2.var(), lit ^ lit2.sign());
-            table[lit2.var()] = lit ^ lit2.sign();
-            reverseTable[lit.var()].push_back(lit2.var());
             
             table[lit.var()] = Lit(lit.var(), false);
-            return;
+            replacedVars++;
+            addBinaryXorClause(ps, xor_clause_inverted, group);
+            return true;
         }
     }
     
     //Follow forwards
-    Lit lit2 = table[lit.var()];
-    if (lit2.var() != lit.var())
-        lit = lit2 ^ lit.sign();
+    Lit litX = table[lit.var()];
+    if (litX.var() != lit.var())
+        lit = litX ^ lit.sign();
     
     //Follow backwards
     setAllThatPointsHereTo(var, lit);
+    replacedVars++;
+    addBinaryXorClause(ps, xor_clause_inverted, group);
     
-    table[var] = lit;
-    reverseTable[lit.var()].push_back(var);
+    return true;
 }
 
-void VarReplacer::addBinaryXorClause(vec<Lit>& ps, const bool xor_clause_inverted, const uint group, const bool internal)
+template const bool VarReplacer::replace(vec<Lit>& ps, const bool xor_clause_inverted, const uint group);
+template const bool VarReplacer::replace(XorClause& ps, const bool xor_clause_inverted, const uint group);
+
+template<class T>
+void VarReplacer::addBinaryXorClause(T& ps, const bool xor_clause_inverted, const uint group, const bool internal)
 {
+    assert(internal || (replacedVars > lastReplacedVars));
     #ifdef DEBUG_REPLACER
     assert(!ps[0].sign());
     assert(!ps[1].sign());
@@ -417,22 +465,27 @@ void VarReplacer::addBinaryXorClause(vec<Lit>& ps, const bool xor_clause_inverte
     ps[0] ^= xor_clause_inverted;
     
     c = Clause_new(ps, group, false);
-    if (internal)
-        S->clauses.push(c);
-    else
+    if (internal) {
+        solver.binaryClauses.push(c);
+        solver.becameBinary++;
+    } else
         clauses.push(c);
-    S->attachClause(*c);
+    solver.attachClause(*c);
     
     ps[0] ^= true;
     ps[1] ^= true;
     c = Clause_new(ps, group, false);
-    if (internal)
-        S->clauses.push(c);
-    else
+    if (internal) {
+        solver.binaryClauses.push(c);
+        solver.becameBinary++;
+    } else
         clauses.push(c);
-    S->attachClause(*c);
+    solver.attachClause(*c);
 }
 
+template void VarReplacer::addBinaryXorClause(vec<Lit>& ps, const bool xor_clause_inverted, const uint group, const bool internal);
+template void VarReplacer::addBinaryXorClause(XorClause& ps, const bool xor_clause_inverted, const uint group, const bool internal);
+
 bool VarReplacer::alreadyIn(const Var var, const Lit lit)
 {
     Lit lit2 = table[var];
@@ -441,7 +494,7 @@ bool VarReplacer::alreadyIn(const Var var, const Lit lit)
             #ifdef VERBOSE_DEBUG
             cout << "Inverted cycle in var-replacement -> UNSAT" << endl;
             #endif
-            S->ok = false;
+            solver.ok = false;
         }
         return true;
     }
@@ -452,7 +505,7 @@ bool VarReplacer::alreadyIn(const Var var, const Lit lit)
             #ifdef VERBOSE_DEBUG
             cout << "Inverted cycle in var-replacement -> UNSAT" << endl;
             #endif
-            S->ok = false;
+            solver.ok = false;
         }
         return true;
     }
@@ -463,16 +516,18 @@ bool VarReplacer::alreadyIn(const Var var, const Lit lit)
 void VarReplacer::setAllThatPointsHereTo(const Var var, const Lit lit)
 {
     map<Var, vector<Var> >::iterator it = reverseTable.find(var);
-    if (it == reverseTable.end())
-        return;
-    
-    for(vector<Var>::const_iterator it2 = it->second.begin(), end = it->second.end(); it2 != end; it2++) {
-        assert(table[*it2].var() == var);
-        table[*it2] = lit ^ table[*it2].sign();
-        if (lit.var() != *it2)
-            reverseTable[lit.var()].push_back(*it2);
+    if (it != reverseTable.end()) {
+        for(vector<Var>::const_iterator it2 = it->second.begin(), end = it->second.end(); it2 != end; it2++) {
+            assert(table[*it2].var() == var);
+            if (lit.var() != *it2) {
+                table[*it2] = lit ^ table[*it2].sign();
+                reverseTable[lit.var()].push_back(*it2);
+            }
+        }
+        reverseTable.erase(it);
     }
-    reverseTable.erase(it);
+    table[var] = lit;
+    reverseTable[lit.var()].push_back(var);
 }
 
 void VarReplacer::newVar()
@@ -480,8 +535,18 @@ void VarReplacer::newVar()
     table.push_back(Lit(table.size(), false));
 }
 
-void VarReplacer::newClause()
+void VarReplacer::reattachInternalClauses()
 {
-    addedNewClause = true;
+    Clause **i = clauses.getData();
+    Clause **j = i;
+    for (Clause **end = clauses.getDataEnd(); i != end; i++) {
+        if (solver.value((**i)[0]) == l_Undef &&
+            solver.value((**i)[1]) == l_Undef) {
+            solver.attachClause(**i);
+            *j++ = *i;
+        }
+    }
+    clauses.shrink(i-j);
 }
-};
+
+}; //NAMESPACE MINISAT
index 36f38fd0a24ae1d7155a3cac3c84abbb6fb7ce1e..3669b8413e1452bf9574aae4d4b1744c64a80a32 100644 (file)
@@ -18,30 +18,40 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #ifndef VARREPLACER_H
 #define VARREPLACER_H
 
-#include "SolverTypes.h"
-#include "Clause.h"
-#include "mtl/Vec.h"
+#ifdef _MSC_VER
+#include <msvc/stdint.h>
+#else
+#include <stdint.h>
+#endif //_MSC_VER
 
-#include <sys/types.h>
 #include <map>
 #include <vector>
-
-namespace MINISAT
-{
-
 using std::map;
 using std::vector;
 
-class Solver;
+#include "Solver.h"
+#include "SolverTypes.h"
+#include "Clause.h"
+#include "Vec.h"
+
+namespace MINISAT
+{
+using namespace MINISAT;
 
 class VarReplacer
 {
     public:
-        VarReplacer(Solver* S);
+        VarReplacer(Solver& solver);
         ~VarReplacer();
-        void replace(vec<Lit>& ps, const bool xor_clause_inverted, const uint group);
-        void extendModel() const;
-        void performReplace();
+        const bool performReplace(const bool always = false);
+        const bool needsReplace();
+        template<class T>
+        const bool replace(T& ps, const bool xor_clause_inverted, const uint group);
+        
+        void extendModelPossible() const;
+        void extendModelImpossible(Solver& solver2) const;
+        void reattachInternalClauses();
+        
         const uint getNumReplacedLits() const;
         const uint getNumReplacedVars() const;
         const uint getNumLastReplacedVars() const;
@@ -49,15 +59,19 @@ class VarReplacer
         const vector<Var> getReplacingVars() const;
         const vector<Lit>& getReplaceTable() const;
         const vec<Clause*>& getClauses() const;
-        void newClause();
+        const bool varHasBeenReplaced(const Var var) const;
+        const bool replacingVar(const Var var) const;
         void newVar();
     
     private:
-        void replace_set(vec<Clause*>& set);
-        void replace_set(vec<XorClause*>& cs, const bool isAttached);
+        const bool performReplaceInternal();
+        
+        const bool replace_set(vec<Clause*>& set);
+        const bool replace_set(vec<XorClause*>& cs, const bool isAttached);
         const bool handleUpdatedClause(Clause& c, const Lit origLit1, const Lit origLit2);
         const bool handleUpdatedClause(XorClause& c, const Var origVar1, const Var origVar2);
-        void addBinaryXorClause(vec<Lit>& ps, const bool xor_clause_inverted, const uint group, const bool internal = false);
+        template<class T>
+        void addBinaryXorClause(T& ps, const bool xor_clause_inverted, const uint group, const bool internal = false);
         
         void setAllThatPointsHereTo(const Var var, const Lit lit);
         bool alreadyIn(const Var var, const Lit lit);
@@ -67,11 +81,67 @@ class VarReplacer
         vec<Clause*> clauses;
         
         uint replacedLits;
-        uint lastReplacedLits;
         uint replacedVars;
         uint lastReplacedVars;
-        bool addedNewClause;
-        Solver* S;
-};
+        Solver& solver;
 };
+
+inline const bool VarReplacer::performReplace(const bool always)
+{
+    //uint32_t limit = std::min((uint32_t)((double)solver.order_heap.size()*PERCENTAGEPERFORMREPLACE), FIXCLEANREPLACE);
+    uint32_t limit = (uint32_t)((double)solver.order_heap.size()*PERCENTAGEPERFORMREPLACE);
+    if ((always && getNewToReplaceVars() > 0) || getNewToReplaceVars() > limit)
+        return performReplaceInternal();
+    
+    return true;
+}
+
+inline const bool VarReplacer::needsReplace()
+{
+    uint32_t limit = (uint32_t)((double)solver.order_heap.size()*PERCENTAGEPERFORMREPLACE);
+    return (getNewToReplaceVars() > limit);
+}
+
+inline const uint VarReplacer::getNumReplacedLits() const
+{
+    return replacedLits;
+}
+
+inline const uint VarReplacer::getNumReplacedVars() const
+{
+    return replacedVars;
+}
+
+inline const uint VarReplacer::getNumLastReplacedVars() const
+{
+    return lastReplacedVars;
+}
+
+inline const uint VarReplacer::getNewToReplaceVars() const
+{
+    return replacedVars-lastReplacedVars;
+}
+
+inline const vector<Lit>& VarReplacer::getReplaceTable() const
+{
+    return table;
+}
+
+inline const vec<Clause*>& VarReplacer::getClauses() const
+{
+    return clauses;
+}
+
+inline const bool VarReplacer::varHasBeenReplaced(const Var var) const
+{
+    return table[var].var() != var;
+}
+
+inline const bool VarReplacer::replacingVar(const Var var) const
+{
+    return (reverseTable.find(var) != reverseTable.end());
+}
+
+}; //NAMESPACE MINISAT
+
 #endif //VARREPLACER_H
diff --git a/src/sat/cryptominisat2/XSet.h b/src/sat/cryptominisat2/XSet.h
new file mode 100644 (file)
index 0000000..cfe0c19
--- /dev/null
@@ -0,0 +1,136 @@
+/**************************************************************************************************
+From: Solver.C -- (C) Niklas Een, Niklas Sorensson, 2004
+**************************************************************************************************/
+
+#ifndef XSET_H
+#define XSET_H
+
+#include "Vec.h"
+#include <limits>
+#ifdef _MSC_VER
+#include <msvc/stdint.h>
+#else
+#include <stdint.h>
+#endif //_MSC_VER
+
+namespace MINISAT
+{
+using namespace MINISAT;
+
+class XorClause;
+
+template <class T>
+uint32_t calcXorAbstraction(const T& ps) {
+    uint32_t abstraction = 0;
+    for (uint32_t i = 0; i != ps.size(); i++)
+        abstraction |= 1 << (ps[i].var() & 31);
+    return abstraction;
+}
+
+//#pragma pack(push)
+//#pragma pack(1)
+class XorClauseSimp
+{
+    public:
+        XorClauseSimp(XorClause* c, const uint32_t _index) :
+        clause(c)
+        , index(_index)
+        {}
+        
+        XorClause* clause;
+        uint32_t index;
+};
+//#pragma pack(pop)
+
+class XSet {
+    vec<uint32_t>       where;  // Map clause ID to position in 'which'.
+    vec<XorClauseSimp> which;  // List of clauses (for fast iteration). May contain 'Clause_NULL'.
+    vec<uint32_t>       free;   // List of positions holding 'Clause_NULL'.
+    
+    public:
+        //XorClauseSimp& operator [] (uint32_t index) { return which[index]; }
+        void reserve(uint32_t size) { where.reserve(size);}
+        uint32_t size(void) const { return which.size(); }
+        uint32_t nElems(void) const { return which.size() - free.size(); }
+        
+        bool add(const XorClauseSimp& c) {
+            assert(c.clause != NULL);
+            where.growTo(c.index+1, std::numeric_limits<uint32_t>::max());
+            if (where[c.index] != std::numeric_limits<uint32_t>::max()) {
+                return true;
+            }
+            if (free.size() > 0){
+                where[c.index] = free.last();
+                which[free.last()] = c;
+                free.pop();
+            }else{
+                where[c.index] = which.size();
+                which.push(c);
+            }
+            return false;
+        }
+        
+        bool exclude(const XorClauseSimp& c) {
+            assert(c.clause != NULL);
+            if (c.index >= where.size() || where[c.index] == std::numeric_limits<uint32_t>::max()) {
+                //not inside
+                return false;
+            }
+            free.push(where[c.index]);
+            which[where[c.index]].clause = NULL;
+            where[c.index] = std::numeric_limits<uint32_t>::max();
+            return true;
+        }
+        
+        void clear(void) {
+            for (uint32_t i = 0; i < which.size(); i++)  {
+                if (which[i].clause != NULL) {
+                    where[which[i].index] = std::numeric_limits<uint32_t>::max();
+                }
+            }
+            which.clear();
+            free.clear();
+        }
+        
+        class iterator
+        {
+            public:
+                iterator(XorClauseSimp* _it) :
+                it(_it)
+                {}
+                
+                void operator++()
+                {
+                    it++;
+                }
+                
+                const bool operator!=(const iterator& iter) const
+                {
+                    return (it != iter.it);;
+                }
+                
+                XorClauseSimp& operator*() {
+                    return *it;
+                }
+                
+                XorClauseSimp*& operator->() {
+                    return it;
+                }
+            private:
+                XorClauseSimp* it;
+        };
+        
+        iterator begin()
+        {
+            return iterator(which.getData());
+        }
+        
+        iterator end()
+        {
+            return iterator(which.getData() + which.size());
+        }
+};
+
+}; //NAMESPACE MINISAT
+
+#endif //XSET_H
\ No newline at end of file
index c4101575ff514aacc339323e902d5ed975c5e7e6..3c1e045f5793aa5532a69206b8ff0de22513a8e6 100644 (file)
@@ -25,11 +25,10 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #include "ClauseCleaner.h"
 #include "time_mem.h"
 
-namespace MINISAT
-{
-
-
 //#define VERBOSE_DEBUG
+#ifdef _MSC_VER
+#define __builtin_prefetch(a,b)
+#endif //_MSC_VER
 
 #ifdef VERBOSE_DEBUG
 #include <iostream>
@@ -37,6 +36,10 @@ using std::cout;
 using std::endl;
 #endif
 
+namespace MINISAT
+{
+using namespace MINISAT;
+
 using std::make_pair;
 
 XorFinder::XorFinder(Solver* _s, vec<Clause*>& _cls, ClauseCleaner::ClauseSetType _type) :
@@ -46,49 +49,124 @@ XorFinder::XorFinder(Solver* _s, vec<Clause*>& _cls, ClauseCleaner::ClauseSetTyp
 {
 }
 
-uint XorFinder::doNoPart(const uint minSize, const uint maxSize)
+const bool XorFinder::doNoPart(const uint minSize, const uint maxSize)
 {
     uint sumLengths = 0;
     double time = cpuTime();
-    
+    foundXors = 0;
     S->clauseCleaner->cleanClauses(cls, type);
+    if (S->ok == false)
+        return false;
     
     toRemove.clear();
     toRemove.resize(cls.size(), false);
     
     table.clear();
-    table.reserve(cls.size()/2);
+    table.reserve(cls.size());
+    
+    ClauseTable unsortedTable;
+    unsortedTable.reserve(cls.size());
+    ClauseTable sortedTable;
+    sortedTable.reserve(cls.size());
+    
+    for (Clause **it = cls.getData(), **end = it + cls.size(); it != end; it ++) {
+        if (it+1 != end)
+            __builtin_prefetch(*(it+1), 0);
+        //if ((**it)[0].toInt() < (**it)[1].toInt())
+        //    std::swap((**it)[0], (**it)[1]);
+        Clause& c = (**it);
+        if ((*it)->size() != 2) {
+            bool sorted = true;
+            for (uint i = 0, size = c.size(); i+1 < size ; i++) {
+                sorted = (c[i].var() <= c[i+1].var());
+                if (!sorted) break;
+            }
+            if (!sorted) {
+                S->detachClause(c);
+                std::sort(c.getData(), c.getData()+c.size());
+                S->attachClause(c);
+            }
+        } else {
+            std::sort(c.getData(), c.getData()+c.size());
+        }
+    }
+    
     uint i = 0;
     for (Clause **it = cls.getData(), **end = it + cls.size(); it != end; it++, i++) {
         const uint size = (*it)->size();
         if ( size > maxSize || size < minSize) continue;
-        table.push_back(make_pair(*it, i));
+        if ((*it)->getSorted()) sortedTable.push_back(make_pair(*it, i));
+        else unsortedTable.push_back(make_pair(*it, i));
     }
     
-    uint found = findXors(sumLengths);
+    clause_sorter_primary sorter;
     
-    if (S->verbosity >=1)
-        printf("c |  Finding XORs:        %5.2lf s (found: %7d, avg size: %3.1lf)               |\n", cpuTime()-time, found, (double)sumLengths/(double)found);
+    std::sort(unsortedTable.begin(), unsortedTable.end(), clause_sorter_primary());
+    //std::sort(sortedTable.begin(), sortedTable.end(), clause_sorter_primary());
+    #ifdef DEBUG_XORFIND
+    for (uint i = 0; i+1 < unsortedTable.size(); i++) {
+        assert(!sorter(unsortedTable[i+1], unsortedTable[i]));
+    }
+    for (uint i = 0; i+1 < sortedTable.size(); i++) {
+        assert(!sorter(sortedTable[i+1], sortedTable[i]));
+    }
+    #endif //DEBUG_XORFIND
     
-    if (found > 0) {
-        clearToRemove();
-        
-        if (S->ok != false)
-            S->ok = (S->propagate() == NULL);
+    for (uint i = 0, j = 0; i < unsortedTable.size() || j <  sortedTable.size();) {
+        if (j == sortedTable.size()) {
+            table.push_back(unsortedTable[i++]);
+            continue;
+        }
+        if (i == unsortedTable.size()) {
+            table.push_back(sortedTable[j++]);
+            continue;
+        }
+        if (sorter(unsortedTable[i], sortedTable[j])) {
+            table.push_back(unsortedTable[i++]);
+        } else {
+            table.push_back(sortedTable[j++]);
+        }
+    }
+    #ifdef DEBUG_XORFIND
+    for (uint i = 0; i+1 < table.size(); i++) {
+        assert(!sorter(table[i+1], table[i]));
+        //table[i].first->plainPrint();
+    }
+    #endif //DEBUG_XORFIND
+    
+    if (findXors(sumLengths) == false)
+        return false;
+    
+    if (S->verbosity >= 2) {
+        if (minSize == maxSize && minSize == 2)
+            printf("c |  Finding binary XORs:        %5.2lf s (found: %7d, avg size: %3.1lf)                  |\n", cpuTime()-time, foundXors, (double)sumLengths/(double)foundXors);
+        else
+            printf("c |  Finding non-binary XORs:    %5.2lf s (found: %7d, avg size: %3.1lf)                  |\n", cpuTime()-time, foundXors, (double)sumLengths/(double)foundXors);
     }
     
-    return found;
+    if (type == ClauseCleaner::binaryClauses) {
+        i = 0;
+        uint j = 0;
+        for (uint size = table.size(); i != size; i++) {
+            if (!toRemove[table[i].second]) {
+                table[i].first->setSorted();
+                cls[j++] = table[i].first;
+            }
+        }
+        cls.shrink(i-j);
+    } else if (foundXors > 0)
+        clearToRemove();
+    
+    return S->ok = (S->propagate() == NULL);
 }
 
-uint XorFinder::findXors(uint& sumLengths)
+const bool XorFinder::findXors(uint& sumLengths)
 {
     #ifdef VERBOSE_DEBUG
     cout << "Finding Xors started" << endl;
     #endif
     
-    uint foundXors = 0;
     sumLengths = 0;
-    std::sort(table.begin(), table.end(), clause_sorter_primary());
     
     ClauseTable::iterator begin = table.begin();
     ClauseTable::iterator end = table.begin();
@@ -100,7 +178,7 @@ uint XorFinder::findXors(uint& sumLengths)
         for (const Lit *it = &c[0], *cend = it+c.size() ; it != cend; it++) {
             lits.push(Lit(it->var(), false));
         }
-        uint old_group = c.group;
+        uint old_group = c.getGroup();
         
         #ifdef VERBOSE_DEBUG
         cout << "- Found clauses:" << endl;
@@ -117,7 +195,8 @@ uint XorFinder::findXors(uint& sumLengths)
         
         switch(lits.size()) {
         case 2: {
-            S->varReplacer->replace(lits, impair, old_group);
+            if (S->varReplacer->replace(lits, impair, old_group) == false)
+                return false;
             
             #ifdef VERBOSE_DEBUG
             XorClause* x = XorClause_new(lits, impair, old_group);
@@ -143,7 +222,7 @@ uint XorFinder::findXors(uint& sumLengths)
         sumLengths += lits.size();
     }
     
-    return foundXors;
+    return true;
 }
 
 void XorFinder::clearToRemove()
@@ -169,9 +248,12 @@ bool XorFinder::getNextXor(ClauseTable::iterator& begin, ClauseTable::iterator&
     while(begin != tableEnd && end != tableEnd) {
         begin = end;
         end++;
-        while(end != tableEnd && clause_vareq(begin->first, end->first))
+        uint32_t size = (end == tableEnd ? 0:1);
+        while(end != tableEnd && clause_vareq(begin->first, end->first)) {
+            size++;
             end++;
-        if (isXor(begin, end, impair))
+        }
+        if (size > 0 && isXor(size, begin, end, impair))
             return true;
     }
     
@@ -196,15 +278,35 @@ bool XorFinder::impairSigns(const Clause& c) const
     return num % 2;
 }
 
-bool XorFinder::isXor(const ClauseTable::iterator& begin, const ClauseTable::iterator& end, bool& impair)
+bool XorFinder::isXor(const uint32_t size, const ClauseTable::iterator& begin, const ClauseTable::iterator& end, bool& impair)
 {
-    uint size = &(*begin) - &(*end);
-    assert(size > 0);
     const uint requiredSize = 1 << (begin->first->size()-1);
     
     if (size < requiredSize)
         return false;
     
+    #ifdef DEBUG_XORFIND2
+    {
+        vec<Var> vars;
+        Clause& c = *begin->first;
+        for (uint i = 0; i < c.size(); i++)
+            vars.push(c[i].var());
+        for (ClauseTable::iterator it = begin; it != end; it++) {
+            Clause& c = *it->first;
+            for (uint i = 0; i < c.size(); i++)
+                assert(vars[i] == c[i].var());
+        }
+        clause_sorter_primary sorter;
+        
+        for (ClauseTable::iterator it = begin; it != end; it++) {
+            ClauseTable::iterator it2 = it;
+            it2++;
+            if (it2 == end) break;
+            assert(!sorter(*it2, *it));
+        }
+    }
+    #endif //DEBUG_XORFIND
+    
     std::sort(begin, end, clause_sorter_secondary());
     
     uint numPair = 0;
@@ -249,4 +351,5 @@ void XorFinder::countImpairs(const ClauseTable::iterator& begin, const ClauseTab
         it2++;
     }
 }
-};
+
+}; //NAMESPACE MINISAT
index bee1e81eec71a1d4971d06f3fa42d908ea37a0dc..7140a5cf7f894f6ee187dd2c39405538ea8943c9 100644 (file)
@@ -18,29 +18,38 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #ifndef XORFINDER_H
 #define XORFINDER_H
 
+#ifdef _MSC_VER
+#include <msvc/stdint.h>
+#else
+#include <stdint.h>
+#endif //_MSC_VER
+
+#define DEBUG_XORFIND
+//#define DEBUG_XORFIND2
+
 #include "Clause.h"
-#include <sys/types.h>
 #include "VarReplacer.h"
 #include "ClauseCleaner.h"
 
-namespace MINISAT
-{
-
 class Solver;
 
 using std::pair;
 
+namespace MINISAT
+{
+using namespace MINISAT;
+
 class XorFinder
 {
     public:
         
         XorFinder(Solver* S, vec<Clause*>& cls, ClauseCleaner::ClauseSetType _type);
-        uint doNoPart(const uint minSize, const uint maxSize);
+        const bool doNoPart(const uint minSize, const uint maxSize);
         
     private:
         typedef vector<pair<Clause*, uint> > ClauseTable;
         
-        uint findXors(uint& sumLengths);
+        const bool findXors(uint& sumLengths);
         bool getNextXor(ClauseTable::iterator& begin, ClauseTable::iterator& end, bool& impair);
         
         struct clause_hasher {
@@ -60,10 +69,20 @@ class XorFinder
             {
                 if (c11.first->size() != c22.first->size())
                     return (c11.first->size() < c22.first->size());
-
+                
+                #ifdef DEBUG_XORFIND2
+                Clause& c1 = *c11.first;
+                for (uint i = 0; i+1 < c1.size(); i++)
+                    assert(c1[i].var() <= c1[i+1].var());
+                
+                Clause& c2 = *c22.first;
+                for (uint i = 0; i+1 < c2.size(); i++)
+                    assert(c2[i].var() <= c2[i+1].var());
+                #endif //DEBUG_XORFIND2
+                
                 for (a = c11.first->getData(), b = c22.first->getData(), end = a + c11.first->size(); a != end; a++, b++) {
                     if (a->var() != b->var())
-                        return (a->var() < b->var());
+                        return (a->var() > b->var());
                 }
 
                 return false;
@@ -82,7 +101,7 @@ class XorFinder
 
                 for (uint i = 0, size = c1.size(); i < size; i++) {
                     if (c1[i].sign() !=  c2[i].sign())
-                        return c2[i].sign();
+                        return c1[i].sign();
                 }
                 
                 return false;
@@ -104,6 +123,7 @@ class XorFinder
         ClauseTable table;
         vector<bool> toRemove;
         void clearToRemove();
+        uint32_t foundXors;
         
         vec<Clause*>& cls;
         ClauseCleaner::ClauseSetType type;
@@ -111,10 +131,11 @@ class XorFinder
         bool clauseEqual(const Clause& c1, const Clause& c2) const;
         bool impairSigns(const Clause& c) const;
         void countImpairs(const ClauseTable::iterator& begin, const ClauseTable::iterator& end, uint& numImpair, uint& numPair) const;
-        bool isXor(const ClauseTable::iterator& begin, const ClauseTable::iterator& end, bool& impair);
+        bool isXor(const uint32_t size, const ClauseTable::iterator& begin, const ClauseTable::iterator& end, bool& impair);
         
         Solver* S;
 };
-};
+
+}; //NAMESPACE MINISAT
 
 #endif //XORFINDER_H
diff --git a/src/sat/cryptominisat2/XorSubsumer.cpp b/src/sat/cryptominisat2/XorSubsumer.cpp
new file mode 100644 (file)
index 0000000..8ec7140
--- /dev/null
@@ -0,0 +1,306 @@
+/**************************************************************************************************
+Originally From: Solver.C -- (C) Niklas Een, Niklas Sorensson, 2004
+Substantially modified by: Mate Soos (2010)
+**************************************************************************************************/
+
+#include "Solver.h"
+#include "XorSubsumer.h"
+#include "ClauseCleaner.h"
+#include "time_mem.h"
+#include "assert.h"
+#include <iomanip>
+#include "VarReplacer.h"
+
+#ifdef _MSC_VER
+#define __builtin_prefetch(a,b,c)
+#endif //_MSC_VER
+
+//#define VERBOSE_DEBUG
+#ifdef VERBOSE_DEBUG
+#define BIT_MORE_VERBOSITY
+#endif
+
+//#define BIT_MORE_VERBOSITY
+//#define TOUCH_LESS
+
+#ifdef VERBOSE_DEBUG
+using std::cout;
+using std::endl;
+#endif //VERBOSE_DEBUG
+
+namespace MINISAT
+{
+using namespace MINISAT;
+
+XorSubsumer::XorSubsumer(Solver& s):
+    solver(s)
+{
+};
+
+// Will put NULL in 'cs' if clause removed.
+void XorSubsumer::subsume0(XorClauseSimp& ps)
+{
+    assert(solver.xorclauses.size() ==  0);
+    #ifdef VERBOSE_DEBUG
+    cout << "subsume0 orig clause:";
+    ps.clause->plainPrint();
+    cout << "pointer:" << &ps << endl;
+    #endif
+    
+    vec<Lit> origClause(ps.clause->size());
+    std::copy(ps.clause->getData(), ps.clause->getDataEnd(), origClause.getData());
+    const bool origClauseInverted = ps.clause->xor_clause_inverted();
+    
+    vec<Lit> unmatchedPart;
+    bool needUnlinkPS = false;
+    
+    vec<XorClauseSimp> subs;
+    findSubsumed(*ps.clause, subs);
+    for (uint32_t i = 0; i < subs.size(); i++){
+        #ifdef VERBOSE_DEBUG
+        cout << "subsume0 removing:";
+        subs[i].clause->plainPrint();
+        #endif
+        
+        XorClause* tmp = subs[i].clause;
+        findUnMatched(origClause, *tmp, unmatchedPart);
+        if (unmatchedPart.size() == 0) {
+            clauses_subsumed++;
+            assert(tmp->size() == origClause.size());
+            if (origClauseInverted == tmp->xor_clause_inverted()) {
+                unlinkClause(subs[i]);
+                free(tmp);
+            } else {
+                solver.ok = false;
+                return;
+            }
+        } else {
+            assert(unmatchedPart.size() > 0);
+            clauses_cut++;
+            //XorClause *c = solver.addXorClauseInt(unmatchedPart, tmp->xor_clause_inverted() ^ origClauseInverted, tmp->getGroup());
+            if (!solver.ok) return;
+            //if (c != NULL) {
+                //linkInClause(*c);
+                needUnlinkPS = true;
+            //}
+        }
+        unmatchedPart.clear();
+    }
+    
+    /*if (needUnlinkPS) {
+        XorClause* tmp = ps.clause;
+        unlinkClause(ps);
+        free(tmp);
+    }*/
+}
+
+void XorSubsumer::findUnMatched(vec<Lit>& A, XorClause& B, vec<Lit>& unmatchedPart)
+{
+    for (uint32_t i = 0; i != B.size(); i++)
+        seen_tmp[B[i].var()] = 1;
+    for (uint32_t i = 0; i != A.size(); i++)
+        seen_tmp[A[i].var()] = 0;
+    for (uint32_t i = 0; i != B.size(); i++) {
+        if (seen_tmp[B[i].var()] == 1) {
+            unmatchedPart.push(Lit(B[i].var(), false));
+            seen_tmp[B[i].var()] = 0;
+        }
+    }
+}
+
+void XorSubsumer::unlinkClause(XorClauseSimp c)
+{
+    XorClause& cl = *c.clause;
+    
+    for (uint32_t i = 0; i < cl.size(); i++) {
+        maybeRemove(occur[cl[i].var()], &cl);
+    }
+    
+    solver.detachClause(cl);
+    
+    clauses[c.index].clause = NULL;
+}
+
+void XorSubsumer::unlinkModifiedClause(vec<Lit>& origClause, XorClauseSimp c)
+{
+    for (uint32_t i = 0; i < origClause.size(); i++) {
+        maybeRemove(occur[origClause[i].var()], c.clause);
+    }
+    
+    solver.detachModifiedClause(origClause[0].var(), origClause[1].var(), origClause.size(), c.clause);
+    
+    clauses[c.index].clause = NULL;
+}
+
+void XorSubsumer::unlinkModifiedClauseNoDetachNoNULL(vec<Lit>& origClause, XorClauseSimp c)
+{
+    for (uint32_t i = 0; i < origClause.size(); i++) {
+        maybeRemove(occur[origClause[i].var()], c.clause);
+    }
+}
+
+XorClauseSimp XorSubsumer::linkInClause(XorClause& cl)
+{
+    XorClauseSimp c(&cl, clauseID++);
+    clauses.push(c);
+    for (uint32_t i = 0; i < cl.size(); i++) {
+        occur[cl[i].var()].push(c);
+    }
+    
+    return c;
+}
+
+void XorSubsumer::linkInAlreadyClause(XorClauseSimp& c)
+{
+    XorClause& cl = *c.clause;
+    
+    for (uint32_t i = 0; i < c.clause->size(); i++) {
+        occur[cl[i].var()].push(c);
+    }
+}
+
+void XorSubsumer::addFromSolver(vec<XorClause*>& cs)
+{
+    XorClause **i = cs.getData();
+    for (XorClause **end = i + cs.size(); i !=  end; i++) {
+        if (i+1 != end)
+            __builtin_prefetch(*(i+1), 1, 1);
+        
+        linkInClause(**i);
+        if ((*i)->getVarChanged() || (*i)->getStrenghtened())
+            (*i)->calcXorAbstraction();
+    }
+    cs.clear();
+}
+
+void XorSubsumer::addBackToSolver()
+{
+    for (uint32_t i = 0; i < clauses.size(); i++) {
+        if (clauses[i].clause != NULL) {
+            solver.xorclauses.push(clauses[i].clause);
+            clauses[i].clause->unsetStrenghtened();
+            clauses[i].clause->unsetVarChanged();
+        }
+    }
+    for (Var var = 0; var < solver.nVars(); var++) {
+        occur[var].clear();
+    }
+    clauses.clear();
+    clauseID = 0;
+}
+
+const bool XorSubsumer::simplifyBySubsumption(const bool doFullSubsume)
+{
+    double myTime = cpuTime();
+    uint32_t origTrailSize = solver.trail.size();
+    clauses_subsumed = 0;
+    clauses_cut = 0;
+    clauseID = 0;
+    
+    for (Var var = 0; var < solver.nVars(); var++) {
+        //occur[var].clear(true);
+        newVar();
+    }
+    
+    while (solver.performReplace && solver.varReplacer->needsReplace()) {
+        if (!solver.varReplacer->performReplace())
+            return false;
+    }
+    
+    solver.clauseCleaner->cleanClauses(solver.xorclauses, ClauseCleaner::xorclauses);
+    if (!solver.ok) return false;
+    
+    clauses.clear();
+    clauses.reserve(solver.xorclauses.size());
+    addFromSolver(solver.xorclauses);
+    #ifdef BIT_MORE_VERBOSITY
+    std::cout << "c time to link in:" << cpuTime()-myTime << std::endl;
+    #endif
+    
+    origNClauses = clauses.size();
+    
+    if (!solver.ok) return false;
+    #ifdef VERBOSE_DEBUG
+    std::cout << "c   clauses:" << clauses.size() << std::endl;
+    #endif
+    
+    bool replaced = true;
+    bool propagated = false;
+    while (replaced || propagated) {
+        replaced = propagated = false;
+        for (uint32_t i = 0; i < clauses.size(); i++) {
+            if (clauses[i].clause != NULL) {
+                subsume0(clauses[i]);
+                if (!solver.ok) return false;
+            }
+        }
+        
+        if (solver.qhead != solver.trail.size()) propagated = true;
+        solver.ok = solver.propagate() == NULL;
+        if (!solver.ok) {
+            std::cout << "c (contradiction during subsumption)" << std::endl;
+            return false;
+        }
+        solver.clauseCleaner->cleanXorClausesBewareNULL(clauses, ClauseCleaner::xorSimpClauses, *this);
+        if (!solver.ok) return false;
+        
+        if (solver.performReplace && solver.varReplacer->needsReplace()) {
+            addBackToSolver();
+            while (solver.performReplace && solver.varReplacer->needsReplace()) {
+                replaced = true;
+                if (!solver.varReplacer->performReplace())
+                    return false;
+            }
+            addFromSolver(solver.xorclauses);
+        }
+    }
+    
+    if (solver.trail.size() - origTrailSize > 0)
+        solver.order_heap.filter(Solver::VarFilter(solver));
+    
+    addBackToSolver();
+    
+    if (solver.verbosity >= 1) {
+        std::cout << "c | xorclauses-subsumed: " << std::setw(9) << clauses_subsumed
+        << " xorclauses-cut: " << std::setw(9) << clauses_cut
+        << " vars fixed: " << std::setw(3) <<solver.trail.size() - origTrailSize
+        << " time: " << std::setw(5) << std::setprecision(2) << (cpuTime() - myTime)
+        << "  |" << std::endl;
+    }
+    
+    return true;
+}
+
+void XorSubsumer::findSubsumed(XorClause& ps, vec<XorClauseSimp>& out_subsumed)
+{
+    #ifdef VERBOSE_DEBUG
+    cout << "findSubsumed: ";
+    for (uint32_t i = 0; i < ps.size(); i++) {
+        if (ps[i].sign()) printf("-");
+        printf("%d ", ps[i].var() + 1);
+    }
+    printf("0\n");
+    #endif
+    
+    uint32_t min_i = 0;
+    for (uint32_t i = 1; i < ps.size(); i++){
+        if (occur[ps[i].var()].size() < occur[ps[min_i].var()].size())
+            min_i = i;
+    }
+    
+    vec<XorClauseSimp>& cs = occur[ps[min_i].var()];
+    for (XorClauseSimp *it = cs.getData(), *end = it + cs.size(); it != end; it++){
+        if (it+1 != end)
+            __builtin_prefetch((it+1)->clause, 1, 1);
+        
+        if (it->clause != &ps && subsetAbst(ps.getAbst(), it->clause->getAbst()) && ps.size() <= it->clause->size() && subset(ps, *it->clause)) {
+            out_subsumed.push(*it);
+            #ifdef VERBOSE_DEBUG
+            cout << "subsumed: ";
+            it->clause->plainPrint();
+            #endif
+        }
+    }
+}
+
+}; //NAMESPACE MINISAT
diff --git a/src/sat/cryptominisat2/XorSubsumer.h b/src/sat/cryptominisat2/XorSubsumer.h
new file mode 100644 (file)
index 0000000..1876bce
--- /dev/null
@@ -0,0 +1,95 @@
+/**************************************************************************************************
+Originally From: Solver.C -- (C) Niklas Een, Niklas Sorensson, 2004
+Substantially modified by: Mate Soos (2010)
+**************************************************************************************************/
+
+#ifndef XORSIMPLIFIER_H
+#define XORSIMPLIFIER_H
+
+#include "Solver.h"
+#include "Vec.h"
+#include "XSet.h"
+
+namespace MINISAT
+{
+using namespace MINISAT;
+
+class ClauseCleaner;
+
+class XorSubsumer
+{
+public:
+    
+    XorSubsumer(Solver& S2);
+    const bool simplifyBySubsumption(const bool doFullSubsume = false);
+    void unlinkModifiedClause(vec<Lit>& origClause, XorClauseSimp c);
+    void unlinkModifiedClauseNoDetachNoNULL(vec<Lit>& origClause, XorClauseSimp c);
+    void unlinkClause(XorClauseSimp cc);
+    XorClauseSimp linkInClause(XorClause& cl);
+    void linkInAlreadyClause(XorClauseSimp& c);
+    void newVar();
+    
+private:
+    
+    friend class ClauseCleaner;
+    
+    //Main
+    vec<XorClauseSimp>        clauses;
+    vec<vec<XorClauseSimp> >  occur;          // 'occur[index(lit)]' is a list of constraints containing 'lit'.
+    Solver&                   solver;         // The Solver
+    
+    // Temporaries (to reduce allocation overhead):
+    //
+    vec<char>                 seen_tmp;       // (used in various places)
+    
+    //Start-up
+    void addFromSolver(vec<XorClause*>& cs);
+    void addBackToSolver();
+    
+    // Subsumption:
+    void findSubsumed(XorClause& ps, vec<XorClauseSimp>& out_subsumed);
+    bool isSubsumed(XorClause& ps);
+    void subsume0(XorClauseSimp& ps);
+    template<class T1, class T2>
+    bool subset(const T1& A, const T2& B);
+    bool subsetAbst(uint32_t A, uint32_t B);
+    void findUnMatched(vec<Lit>& A, XorClause& B, vec<Lit>& unmatchedPart);
+    
+    uint32_t clauses_subsumed;
+    uint32_t clauses_cut;
+    uint32_t origNClauses;
+    uint32_t clauseID;
+};
+
+inline bool XorSubsumer::subsetAbst(uint32_t A, uint32_t B)
+{
+    return !(A & ~B);
+}
+
+// Assumes 'seen' is cleared (will leave it cleared)
+template<class T1, class T2>
+bool XorSubsumer::subset(const T1& A, const T2& B)
+{
+    for (uint32_t i = 0; i != B.size(); i++)
+        seen_tmp[B[i].var()] = 1;
+    for (uint32_t i = 0; i != A.size(); i++) {
+        if (!seen_tmp[A[i].var()]) {
+            for (uint32_t i = 0; i != B.size(); i++)
+                seen_tmp[B[i].var()] = 0;
+            return false;
+        }
+    }
+    for (uint32_t i = 0; i != B.size(); i++)
+        seen_tmp[B[i].var()] = 0;
+    return true;
+}
+
+inline void XorSubsumer::newVar()
+{
+    occur       .push();
+    seen_tmp    .push(0);       // (one for each polarity)
+}
+
+}; //NAMESPACE MINISAT
+
+#endif //XORSIMPLIFIER_H
index d06365132034fea1cc2bdd3021f43dc55d838ea5..a223c7c0f90eae6cc9cc62613f3b52ec85fcda38 100644 (file)
@@ -18,14 +18,18 @@ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 **************************************************************************************************/
 
-#define RATIOREMOVECLAUSES 2
+#define RATIOREMOVECLAUSES 3
 #define NBCLAUSESBEFOREREDUCE 20000
 #define DYNAMICNBLEVEL
 #define UPDATEVARACTIVITY
-#define PERCENTAGEPERFORMREPLACE 0.03
-#define STATS_NEEDED
-#define PERCENTAGECLEANCLAUSES 0.005
-#define MAX_CLAUSENUM_XORFIND 1000000
-#define BINARY_TO_XOR_APPROX 10.0
+#define FIXCLEANREPLACE 30U
+#define PERCENTAGEPERFORMREPLACE 0.01
+#define PERCENTAGECLEANCLAUSES 0.01
+#define MAX_CLAUSENUM_XORFIND 5000000
+#define BINARY_TO_XOR_APPROX 4.0
+#define FULLRESTART_MULTIPLIER 250.0
+#define FULLRESTART_MULTIPLIER_MULTIPLIER 3.5
+#define RESTART_TYPE_DECIDER_FROM 2
+#define RESTART_TYPE_DECIDER_UNTIL 7
 //#define VERBOSE_DEBUG_XOR
 //#define VERBOSE_DEBUG
diff --git a/src/sat/cryptominisat2/msvc/stdint.h b/src/sat/cryptominisat2/msvc/stdint.h
new file mode 100644 (file)
index 0000000..fee624d
--- /dev/null
@@ -0,0 +1,250 @@
+// ISO C9x  compliant stdint.h for Microsoft Visual Studio
+// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 
+// 
+//  Copyright (c) 2006-2008 Alexander Chemeris
+// 
+// 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 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.
+// 
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _MSC_VER // [
+#error "Use this header only with Microsoft Visual C++ compilers!"
+#endif // _MSC_VER ]
+
+#ifndef _MSC_STDINT_H_ // [
+#define _MSC_STDINT_H_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif
+
+#include <limits.h>
+
+// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
+// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
+// or compiler give many errors like this:
+//   error C2733: second C linkage of overloaded function 'wmemchr' not allowed
+#ifdef __cplusplus
+extern "C" {
+#endif
+#  include <wchar.h>
+#ifdef __cplusplus
+}
+#endif
+
+// Define _W64 macros to mark types changing their size, like intptr_t.
+#ifndef _W64
+#  if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
+#     define _W64 __w64
+#  else
+#     define _W64
+#  endif
+#endif
+
+
+// 7.18.1 Integer types
+
+// 7.18.1.1 Exact-width integer types
+
+// Visual Studio 6 and Embedded Visual C++ 4 doesn't
+// realize that, e.g. char has the same size as __int8
+// so we give up on __intX for them.
+#if (_MSC_VER < 1300)
+   typedef signed char       int8_t;
+   typedef signed short      int16_t;
+   typedef signed int        int32_t;
+   typedef unsigned char     uint8_t;
+   typedef unsigned short    uint16_t;
+   typedef unsigned int      uint32_t;
+#else
+   typedef signed __int8     int8_t;
+   typedef signed __int16    int16_t;
+   typedef signed __int32    int32_t;
+   typedef unsigned __int8   uint8_t;
+   typedef unsigned __int16  uint16_t;
+   typedef unsigned __int32  uint32_t;
+#endif
+typedef signed __int64       int64_t;
+typedef unsigned __int64     uint64_t;
+
+
+// 7.18.1.2 Minimum-width integer types
+typedef int8_t    int_least8_t;
+typedef int16_t   int_least16_t;
+typedef int32_t   int_least32_t;
+typedef int64_t   int_least64_t;
+typedef uint8_t   uint_least8_t;
+typedef uint16_t  uint_least16_t;
+typedef uint32_t  uint_least32_t;
+typedef uint64_t  uint_least64_t;
+
+// 7.18.1.3 Fastest minimum-width integer types
+typedef int8_t    int_fast8_t;
+typedef int16_t   int_fast16_t;
+typedef int32_t   int_fast32_t;
+typedef int64_t   int_fast64_t;
+typedef uint8_t   uint_fast8_t;
+typedef uint16_t  uint_fast16_t;
+typedef uint32_t  uint_fast32_t;
+typedef uint64_t  uint_fast64_t;
+
+// 7.18.1.4 Integer types capable of holding object pointers
+#ifdef _WIN64 // [
+   typedef signed __int64    intptr_t;
+   typedef unsigned __int64  uintptr_t;
+#else // _WIN64 ][
+   typedef _W64 signed int   intptr_t;
+   typedef _W64 unsigned int uintptr_t;
+#endif // _WIN64 ]
+
+// 7.18.1.5 Greatest-width integer types
+typedef int64_t   intmax_t;
+typedef uint64_t  uintmax_t;
+
+
+// 7.18.2 Limits of specified-width integer types
+
+#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [   See footnote 220 at page 257 and footnote 221 at page 259
+
+// 7.18.2.1 Limits of exact-width integer types
+#define INT8_MIN     ((int8_t)_I8_MIN)
+#define INT8_MAX     _I8_MAX
+#define INT16_MIN    ((int16_t)_I16_MIN)
+#define INT16_MAX    _I16_MAX
+#define INT32_MIN    ((int32_t)_I32_MIN)
+#define INT32_MAX    _I32_MAX
+#define INT64_MIN    ((int64_t)_I64_MIN)
+#define INT64_MAX    _I64_MAX
+#define UINT8_MAX    _UI8_MAX
+#define UINT16_MAX   _UI16_MAX
+#define UINT32_MAX   _UI32_MAX
+#define UINT64_MAX   _UI64_MAX
+
+// 7.18.2.2 Limits of minimum-width integer types
+#define INT_LEAST8_MIN    INT8_MIN
+#define INT_LEAST8_MAX    INT8_MAX
+#define INT_LEAST16_MIN   INT16_MIN
+#define INT_LEAST16_MAX   INT16_MAX
+#define INT_LEAST32_MIN   INT32_MIN
+#define INT_LEAST32_MAX   INT32_MAX
+#define INT_LEAST64_MIN   INT64_MIN
+#define INT_LEAST64_MAX   INT64_MAX
+#define UINT_LEAST8_MAX   UINT8_MAX
+#define UINT_LEAST16_MAX  UINT16_MAX
+#define UINT_LEAST32_MAX  UINT32_MAX
+#define UINT_LEAST64_MAX  UINT64_MAX
+
+// 7.18.2.3 Limits of fastest minimum-width integer types
+#define INT_FAST8_MIN    INT8_MIN
+#define INT_FAST8_MAX    INT8_MAX
+#define INT_FAST16_MIN   INT16_MIN
+#define INT_FAST16_MAX   INT16_MAX
+#define INT_FAST32_MIN   INT32_MIN
+#define INT_FAST32_MAX   INT32_MAX
+#define INT_FAST64_MIN   INT64_MIN
+#define INT_FAST64_MAX   INT64_MAX
+#define UINT_FAST8_MAX   UINT8_MAX
+#define UINT_FAST16_MAX  UINT16_MAX
+#define UINT_FAST32_MAX  UINT32_MAX
+#define UINT_FAST64_MAX  UINT64_MAX
+
+// 7.18.2.4 Limits of integer types capable of holding object pointers
+#ifdef _WIN64 // [
+#  define INTPTR_MIN   INT64_MIN
+#  define INTPTR_MAX   INT64_MAX
+#  define UINTPTR_MAX  UINT64_MAX
+#else // _WIN64 ][
+#  define INTPTR_MIN   INT32_MIN
+#  define INTPTR_MAX   INT32_MAX
+#  define UINTPTR_MAX  UINT32_MAX
+#endif // _WIN64 ]
+
+// 7.18.2.5 Limits of greatest-width integer types
+#define INTMAX_MIN   INT64_MIN
+#define INTMAX_MAX   INT64_MAX
+#define UINTMAX_MAX  UINT64_MAX
+
+// 7.18.3 Limits of other integer types
+
+#ifdef _WIN64 // [
+#  define PTRDIFF_MIN  _I64_MIN
+#  define PTRDIFF_MAX  _I64_MAX
+#else  // _WIN64 ][
+#  define PTRDIFF_MIN  _I32_MIN
+#  define PTRDIFF_MAX  _I32_MAX
+#endif  // _WIN64 ]
+
+#define SIG_ATOMIC_MIN  INT_MIN
+#define SIG_ATOMIC_MAX  INT_MAX
+
+#ifndef SIZE_MAX // [
+#  ifdef _WIN64 // [
+#     define SIZE_MAX  _UI64_MAX
+#  else // _WIN64 ][
+#     define SIZE_MAX  _UI32_MAX
+#  endif // _WIN64 ]
+#endif // SIZE_MAX ]
+
+// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
+#ifndef WCHAR_MIN // [
+#  define WCHAR_MIN  0
+#endif  // WCHAR_MIN ]
+#ifndef WCHAR_MAX // [
+#  define WCHAR_MAX  _UI16_MAX
+#endif  // WCHAR_MAX ]
+
+#define WINT_MIN  0
+#define WINT_MAX  _UI16_MAX
+
+#endif // __STDC_LIMIT_MACROS ]
+
+
+// 7.18.4 Limits of other integer types
+
+#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [   See footnote 224 at page 260
+
+// 7.18.4.1 Macros for minimum-width integer constants
+
+#define INT8_C(val)  val##i8
+#define INT16_C(val) val##i16
+#define INT32_C(val) val##i32
+#define INT64_C(val) val##i64
+
+#define UINT8_C(val)  val##ui8
+#define UINT16_C(val) val##ui16
+#define UINT32_C(val) val##ui32
+#define UINT64_C(val) val##ui64
+
+// 7.18.4.2 Macros for greatest-width integer constants
+#define INTMAX_C   INT64_C
+#define UINTMAX_C  UINT64_C
+
+#endif // __STDC_CONSTANT_MACROS ]
+
+#ifndef uint
+#define uint unsigned int
+#endif
+
+#endif // _MSC_STDINT_H_ ]
index 0e4d0007f8c8c95e1661c7d931140ec6ee4ac15c..2825a9c17f3f8b1c578edc68e70e7b5f1323751e 100644 (file)
@@ -19,13 +19,20 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
 
 #ifndef Alg_h
 #define Alg_h
-#include "stdint.h"
 
-//=================================================================================================
-// Useful functions on vectors
+#ifdef _MSC_VER
+#include <msvc/stdint.h>
+#else
+#include <stdint.h>
+#endif //_MSC_VER
 
 namespace MINISAT
 {
+using namespace MINISAT;
+
+//=================================================================================================
+// Useful functions on vectors
+
 
 template<class V, class T>
 static inline void remove(V& ts, const T& t)
@@ -63,6 +70,6 @@ static inline bool findW(V& ts, const T& t)
     return j < ts.size();
 }
 
-};
+}; //NAMESPACE MINISAT
 
 #endif
index 4a34e775985fdd57f9d2f22ba4349eef144eb954..8748d2a3d83dcc02455a204f07d3d32fa3fe8e8d 100644 (file)
@@ -19,11 +19,18 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
 
 #ifndef BasicHeap_h
 #define BasicHeap_h
-#include "Vec.h"
 
+#ifdef _MSC_VER
+#include <msvc/stdint.h>
+#else
+#include <stdint.h>
+#endif //_MSC_VERs
+
+#include "Vec.h"
 
 namespace MINISAT
 {
+using namespace MINISAT;
 
 //=================================================================================================
 // A heap implementation with support for decrease/increase key.
@@ -96,7 +103,7 @@ class BasicHeap {
     int  getmin    ()      { return removeMin(); }
 };
 
-};
+}; //NAMESPACE MINISAT
 
 //=================================================================================================
 #endif
index 31788565eb1a4f8f273ca873c850f2204858a7e8..63b8c6d4acee00708b8b43f3811f9568c88d6666 100644 (file)
@@ -26,6 +26,7 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
 
 namespace MINISAT
 {
+using namespace MINISAT;
 
 //=================================================================================================
 // Automatically resizable arrays
@@ -146,6 +147,6 @@ public:
 
 };
 
-};
+}; //NAMESPACE MINISAT
 
 #endif
index e5b20357de1c5e66f75341a35100fa5bc178e08e..24d2df19925db55fc3a225919bf8e6a517d552bf 100644 (file)
@@ -21,14 +21,18 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
 #define Heap_h
 
 #include "Vec.h"
+
 #include "string.h"
+#include <limits>
+#ifdef _MSC_VER
+#include <msvc/stdint.h>
+#else
 #include <stdint.h>
-#ifndef UINT32_MAX
-#define UINT32_MAX ((uint32_t)-1)
-#endif
+#endif //_MSC_VER
 
 namespace MINISAT
 {
+using namespace MINISAT;
 
 //=================================================================================================
 // A heap implementation with support for decrease/increase key.
@@ -87,10 +91,25 @@ class Heap {
         indices.growTo(other.indices.size());
         memcpy(indices.getData(), other.indices.getData(), sizeof(uint32_t)*other.indices.size());
     }
+    
+    void operator=(const Heap<Comp>& other)
+    {
+        if (other.heap.size() > heap.size())
+            heap.growTo(other.heap.size());
+        else
+            heap.shrink(other.heap.size()-heap.size());
+        memcpy(heap.getData(), other.heap.getData(), heap.size()*sizeof(uint32_t));
+        
+        if (other.indices.size() > indices.size())
+            indices.growTo(other.indices.size());
+        else
+            indices.shrink(other.indices.size()-indices.size());
+        memcpy(indices.getData(), other.indices.getData(), indices.size()*sizeof(uint32_t));
+    }
 
     uint32_t  size      ()          const { return heap.size(); }
     bool empty     ()          const { return heap.size() == 0; }
-    bool inHeap    (uint32_t n)     const { return n < indices.size() && indices[n] != UINT32_MAX; }
+    bool inHeap    (uint32_t n)     const { return n < indices.size() && indices[n] != std::numeric_limits<uint32_t>::max(); }
     uint32_t  operator[](uint32_t index) const { assert(index < heap.size()); return heap[index]; }
 
     void decrease  (uint32_t n) { assert(inHeap(n)); percolateUp(indices[n]); }
@@ -101,7 +120,7 @@ class Heap {
 
     void insert(uint32_t n)
     {
-        indices.growTo(n+1, UINT32_MAX);
+        indices.growTo(n+1, std::numeric_limits<uint32_t>::max());
         assert(!inHeap(n));
 
         indices[n] = heap.size();
@@ -115,7 +134,7 @@ class Heap {
         uint32_t x            = heap[0];
         heap[0]          = heap.last();
         indices[heap[0]] = 0;
-        indices[x]       = UINT32_MAX;
+        indices[x]       = std::numeric_limits<uint32_t>::max();
         heap.pop();
         if (heap.size() > 1) percolateDown(0);
         return x; 
@@ -125,10 +144,10 @@ class Heap {
     void clear(bool dealloc = false) 
     { 
         for (uint32_t i = 0; i != heap.size(); i++)
-            indices[heap[i]] = UINT32_MAX;
+            indices[heap[i]] = std::numeric_limits<uint32_t>::max();
 #ifndef NDEBUG
         for (uint32_t i = 0; i != indices.size(); i++)
-            assert(indices[i] == UINT32_MAX);
+            assert(indices[i] == std::numeric_limits<uint32_t>::max());
 #endif
         heap.clear(dealloc); 
     }
@@ -156,7 +175,7 @@ class Heap {
                 heap[j]          = heap[i];
                 indices[heap[i]] = j++;
             }else
-                indices[heap[i]] = UINT32_MAX;
+                indices[heap[i]] = std::numeric_limits<uint32_t>::max();
 
         heap.shrink(i - j);
         for (int i = heap.size() / 2 - 1; i >= 0; i--)
@@ -178,7 +197,8 @@ class Heap {
 
 };
 
-};
-
 //=================================================================================================
+
+}; //NAMESPACE MINISAT
+
 #endif
index 302069aac273fc4018a32bf12285d3943abbb9aa..bd791c3e9af6004f57a2afd6f5351511337b2f91 100644 (file)
@@ -20,11 +20,17 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
 #ifndef Map_h
 #define Map_h
 
+#ifdef _MSC_VER
+#include <msvc/stdint.h>
+#else
 #include <stdint.h>
+#endif //_MSC_VER
+
 #include "Vec.h"
 
 namespace MINISAT
 {
+using namespace MINISAT;
 
 //=================================================================================================
 // Default hash/equals functions
@@ -117,6 +123,6 @@ class Map {
     }
 };
 
-};
+}; //NAMESPACE MINISAT
 
 #endif
index 52f8fb23f91fe9a93ab05f2579663365420dfa67..4138559211145624a38e9a82915b6edc1f0375fb 100644 (file)
@@ -24,6 +24,7 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
 
 namespace MINISAT
 {
+using namespace MINISAT;
 
 //=================================================================================================
 
@@ -81,7 +82,8 @@ public:
 //    }
 //};
 
-};
-
 //=================================================================================================
+
+}; //NAMESPACE MINISAT
+
 #endif
index 3e84bcaecc8047134a8ad53a1f56fe7d216d8fe7..1c6c1aedaf229e91cd3cecfbfbd404c52bedabf5 100644 (file)
@@ -19,13 +19,20 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
 
 #ifndef Vec_h
 #define Vec_h
+
 #include <cstdlib>
 #include <cassert>
 #include <new>
+#ifdef _MSC_VER
+#include <msvc/stdint.h>
+#else
 #include <stdint.h>
+#endif //_MSC_VER
 
 namespace MINISAT
 {
+using namespace MINISAT;
+
 //=================================================================================================
 // Automatically resizable arrays
 //
@@ -42,11 +49,13 @@ class vec {
 
     // Don't allow copying (error prone):
     vec<T>&  operator = (vec<T>& other) { assert(0); return *this; }
-             vec        (vec<T>& other) { assert(0); }
+             //vec        (vec<T>& other) { assert(0); }
 
     static inline uint32_t imax(int x, int y) {
         int mask = (y-x) >> (sizeof(int)*8-1);
         return (x&mask) + (y&(~mask)); }
+    
+    void     myCopy (const vec<T>& other);
 
 public:
     // Types:
@@ -58,12 +67,15 @@ public:
     vec(uint32_t size)               : data(NULL) , sz(0)   , cap(0)    { growTo(size); }
     vec(uint32_t size, const T& pad) : data(NULL) , sz(0)   , cap(0)    { growTo(size, pad); }
     vec(T* array, uint32_t size)     : data(array), sz(size), cap(size) { }      // (takes ownership of array -- will be deallocated with 'free()')
+    vec(const vec<T>& other)         : data(NULL) , sz(0)   , cap(0)    { myCopy(other); }
    ~vec(void)                                                      { clear(true); }
 
     // Ownership of underlying array:
     T*       release  (void)           { T* ret = data; data = NULL; sz = 0; cap = 0; return ret; }
     const T* getData() const {return data; }
+    const T* getDataEnd() const {return data + size(); }
     T* getData() {return data; }
+    T* getDataEnd() {return data + size(); }
 
     // Size operations:
     uint32_t size   (void) const       { return sz; }
@@ -76,6 +88,7 @@ public:
     void     capacity (uint32_t size) { grow(size); }
 
     // Stack interface:
+    void     reserve(uint32_t res)     { if (cap < res) {cap = res; data = (T*)realloc(data, cap * sizeof(T));}}
     void     push  (void)              { if (sz == cap) { cap = imax(2, (cap*3+1)>>1); data = (T*)realloc(data, cap * sizeof(T)); } new (&data[sz]) T(); sz++; }
     void     push  (const T& elem)     { if (sz == cap) { cap = imax(2, (cap*3+1)>>1); data = (T*)realloc(data, cap * sizeof(T)); } data[sz++] = elem; }
     void     push_ (const T& elem)     { assert(sz < cap); data[sz++] = elem; }
@@ -113,6 +126,13 @@ void vec<T>::growTo(uint32_t size) {
     grow(size);
     for (uint32_t i = sz; i != size; i++) new (&data[i]) T();
     sz = size; }
+    
+template<class T>
+void vec<T>::myCopy(const vec<T>& other) {
+    assert(sz == 0);
+    grow(other.size());
+    for (uint32_t i = sz; i != other.size(); i++) new (&data[i]) T(other[i]);
+    sz = other.size(); }
 
 template<class T>
 void vec<T>::clear(bool dealloc) {
@@ -121,6 +141,7 @@ void vec<T>::clear(bool dealloc) {
         sz = 0;
         if (dealloc) free(data), data = NULL, cap = 0; } }
 
-};
+
+}; //NAMESPACE MINISAT
 
 #endif
diff --git a/src/sat/cryptominisat2/pool.hpp b/src/sat/cryptominisat2/pool.hpp
new file mode 100644 (file)
index 0000000..be1137a
--- /dev/null
@@ -0,0 +1,584 @@
+// Copyright (C) 2000, 2001 Stephen Cleary
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#ifndef BOOST_POOL_HPP
+#define BOOST_POOL_HPP
+
+#include <boost/config.hpp>  // for workarounds
+
+// std::less, std::less_equal, std::greater
+#include <functional>
+// new[], delete[], std::nothrow
+#include <new>
+// std::size_t, std::ptrdiff_t
+#include <cstddef>
+// std::malloc, std::free
+#include <cstdlib>
+// std::invalid_argument
+#include <exception>
+// std::max
+#include <algorithm>
+
+#include "poolfwd.hpp"
+
+// boost::details::pool::ct_lcm
+#include <boost/pool/detail/ct_gcd_lcm.hpp>
+// boost::details::pool::lcm
+#include <boost/pool/detail/gcd_lcm.hpp>
+// boost::simple_segregated_storage
+#include <boost/pool/simple_segregated_storage.hpp>
+
+#ifdef BOOST_NO_STDC_NAMESPACE
+ namespace std { using ::malloc; using ::free; }
+#endif
+
+// There are a few places in this file where the expression "this->m" is used.
+// This expression is used to force instantiation-time name lookup, which I am
+//   informed is required for strict Standard compliance.  It's only necessary
+//   if "m" is a member of a base class that is dependent on a template
+//   parameter.
+// Thanks to Jens Maurer for pointing this out!
+
+namespace boost {
+
+struct default_user_allocator_new_delete
+{
+  typedef std::size_t size_type;
+  typedef std::ptrdiff_t difference_type;
+
+  static char * malloc(const size_type bytes)
+  { return new (std::nothrow) char[bytes]; }
+  static void free(char * const block)
+  { delete [] block; }
+};
+
+struct default_user_allocator_malloc_free
+{
+  typedef std::size_t size_type;
+  typedef std::ptrdiff_t difference_type;
+
+  static char * malloc(const size_type bytes)
+  { return reinterpret_cast<char *>(std::malloc(bytes)); }
+  static void free(char * const block)
+  { std::free(block); }
+};
+
+namespace details {
+
+// PODptr is a class that pretends to be a "pointer" to different class types
+//  that don't really exist.  It provides member functions to access the "data"
+//  of the "object" it points to.  Since these "class" types are of variable
+//  size, and contains some information at the *end* of its memory (for
+//  alignment reasons), PODptr must contain the size of this "class" as well as
+//  the pointer to this "object".
+template <typename SizeType>
+class PODptr
+{
+  public:
+    typedef SizeType size_type;
+
+  private:
+    char * ptr;
+    size_type sz;
+
+    char * ptr_next_size() const
+    { return (ptr + sz - sizeof(size_type)); }
+    char * ptr_next_ptr() const
+    {
+      return (ptr_next_size() -
+          pool::ct_lcm<sizeof(size_type), sizeof(void *)>::value);
+    }
+
+  public:
+    PODptr(char * const nptr, const size_type nsize)
+    :ptr(nptr), sz(nsize) { }
+    PODptr()
+    :ptr(0), sz(0) { }
+
+    bool valid() const { return (begin() != 0); }
+    void invalidate() { begin() = 0; }
+    char * & begin() { return ptr; }
+    char * begin() const { return ptr; }
+    char * end() const { return ptr_next_ptr(); }
+    size_type total_size() const { return sz; }
+    size_type element_size() const
+    {
+      return (sz - sizeof(size_type) -
+          pool::ct_lcm<sizeof(size_type), sizeof(void *)>::value);
+    }
+
+    size_type & next_size() const
+    { return *(reinterpret_cast<size_type *>(ptr_next_size())); }
+    char * & next_ptr() const
+    { return *(reinterpret_cast<char **>(ptr_next_ptr())); }
+
+    PODptr next() const
+    { return PODptr<size_type>(next_ptr(), next_size()); }
+    void next(const PODptr & arg) const
+    {
+      next_ptr() = arg.begin();
+      next_size() = arg.total_size();
+    }
+};
+
+} // namespace details
+
+template <typename UserAllocator>
+class pool: protected simple_segregated_storage<
+    typename UserAllocator::size_type>
+{
+  public:
+    typedef UserAllocator user_allocator;
+    typedef typename UserAllocator::size_type size_type;
+    typedef typename UserAllocator::difference_type difference_type;
+
+  private:
+    BOOST_STATIC_CONSTANT(unsigned, min_alloc_size =
+        (::boost::details::pool::ct_lcm<sizeof(void *), sizeof(size_type)>::value) );
+
+    // Returns 0 if out-of-memory
+    // Called if malloc/ordered_malloc needs to resize the free list
+    void * malloc_need_resize();
+    void * ordered_malloc_need_resize();
+
+  protected:
+    details::PODptr<size_type> list;
+
+    simple_segregated_storage<size_type> & store() { return *this; }
+    const simple_segregated_storage<size_type> & store() const { return *this; }
+    const size_type requested_size;
+    size_type next_size;
+    size_type start_size;
+
+    // finds which POD in the list 'chunk' was allocated from
+    details::PODptr<size_type> find_POD(void * const chunk) const;
+
+    // is_from() tests a chunk to determine if it belongs in a block
+    static bool is_from(void * const chunk, char * const i,
+        const size_type sizeof_i)
+    {
+      // We use std::less_equal and std::less to test 'chunk'
+      //  against the array bounds because standard operators
+      //  may return unspecified results.
+      // This is to ensure portability.  The operators < <= > >= are only
+      //  defined for pointers to objects that are 1) in the same array, or
+      //  2) subobjects of the same object [5.9/2].
+      // The functor objects guarantee a total order for any pointer [20.3.3/8]
+//WAS:
+//      return (std::less_equal<void *>()(static_cast<void *>(i), chunk)
+//          && std::less<void *>()(chunk,
+//              static_cast<void *>(i + sizeof_i)));
+      std::less_equal<void *> lt_eq;
+      std::less<void *> lt;
+      return (lt_eq(i, chunk) && lt(chunk, i + sizeof_i));
+    }
+
+    size_type alloc_size() const
+    {
+      const unsigned min_size = min_alloc_size;
+      return details::pool::lcm<size_type>(requested_size, min_size);
+    }
+
+    // for the sake of code readability :)
+    static void * & nextof(void * const ptr)
+    { return *(static_cast<void **>(ptr)); }
+
+  public:
+    // The second parameter here is an extension!
+    // pre: npartition_size != 0 && nnext_size != 0
+    explicit pool(const size_type nrequested_size,
+        const size_type nnext_size = 32)
+    :list(0, 0), requested_size(nrequested_size), next_size(nnext_size), start_size(nnext_size)
+    { }
+
+    ~pool() { purge_memory(); }
+
+    // Releases memory blocks that don't have chunks allocated
+    // pre: lists are ordered
+    //  Returns true if memory was actually deallocated
+    bool release_memory();
+
+    // Releases *all* memory blocks, even if chunks are still allocated
+    //  Returns true if memory was actually deallocated
+    bool purge_memory();
+
+    // These functions are extensions!
+    size_type get_next_size() const { return next_size; }
+    void set_next_size(const size_type nnext_size) { next_size = start_size = nnext_size; }
+    size_type get_requested_size() const { return requested_size; }
+
+    // Both malloc and ordered_malloc do a quick inlined check first for any
+    //  free chunks.  Only if we need to get another memory block do we call
+    //  the non-inlined *_need_resize() functions.
+    // Returns 0 if out-of-memory
+    void * malloc()
+    {
+      // Look for a non-empty storage
+      if (!store().empty())
+        return store().malloc();
+      return malloc_need_resize();
+    }
+
+    void * ordered_malloc()
+    {
+      // Look for a non-empty storage
+      if (!store().empty())
+        return store().malloc();
+      return ordered_malloc_need_resize();
+    }
+
+    // Returns 0 if out-of-memory
+    // Allocate a contiguous section of n chunks
+    void * ordered_malloc(size_type n);
+
+    // pre: 'chunk' must have been previously
+    //        returned by *this.malloc().
+    void free(void * const chunk)
+    { store().free(chunk); }
+
+    // pre: 'chunk' must have been previously
+    //        returned by *this.malloc().
+    void ordered_free(void * const chunk)
+    { store().ordered_free(chunk); }
+
+    // pre: 'chunk' must have been previously
+    //        returned by *this.malloc(n).
+    void free(void * const chunks, const size_type n)
+    {
+      const size_type partition_size = alloc_size();
+      const size_type total_req_size = n * requested_size;
+      const size_type num_chunks = total_req_size / partition_size +
+          ((total_req_size % partition_size) ? true : false);
+
+      store().free_n(chunks, num_chunks, partition_size);
+    }
+
+    // pre: 'chunk' must have been previously
+    //        returned by *this.malloc(n).
+    void ordered_free(void * const chunks, const size_type n)
+    {
+      const size_type partition_size = alloc_size();
+      const size_type total_req_size = n * requested_size;
+      const size_type num_chunks = total_req_size / partition_size +
+          ((total_req_size % partition_size) ? true : false);
+
+      store().ordered_free_n(chunks, num_chunks, partition_size);
+    }
+
+    // is_from() tests a chunk to determine if it was allocated from *this
+    bool is_from(void * const chunk) const
+    {
+      return (find_POD(chunk).valid());
+    }
+};
+
+template <typename UserAllocator>
+bool pool<UserAllocator>::release_memory()
+{
+  // This is the return value: it will be set to true when we actually call
+  //  UserAllocator::free(..)
+  bool ret = false;
+
+  // This is a current & previous iterator pair over the memory block list
+  details::PODptr<size_type> ptr = list;
+  details::PODptr<size_type> prev;
+
+  // This is a current & previous iterator pair over the free memory chunk list
+  //  Note that "prev_free" in this case does NOT point to the previous memory
+  //  chunk in the free list, but rather the last free memory chunk before the
+  //  current block.
+  void * free_p = this->first;
+  void * prev_free_p = 0;
+
+  const size_type partition_size = alloc_size();
+
+  // Search through all the all the allocated memory blocks
+  while (ptr.valid())
+  {
+    // At this point:
+    //  ptr points to a valid memory block
+    //  free_p points to either:
+    //    0 if there are no more free chunks
+    //    the first free chunk in this or some next memory block
+    //  prev_free_p points to either:
+    //    the last free chunk in some previous memory block
+    //    0 if there is no such free chunk
+    //  prev is either:
+    //    the PODptr whose next() is ptr
+    //    !valid() if there is no such PODptr
+
+    // If there are no more free memory chunks, then every remaining
+    //  block is allocated out to its fullest capacity, and we can't
+    //  release any more memory
+    if (free_p == 0)
+      break;
+
+    // We have to check all the chunks.  If they are *all* free (i.e., present
+    //  in the free list), then we can free the block.
+    bool all_chunks_free = true;
+
+    // Iterate 'i' through all chunks in the memory block
+    // if free starts in the memory block, be careful to keep it there
+    void * saved_free = free_p;
+    for (char * i = ptr.begin(); i != ptr.end(); i += partition_size)
+    {
+      // If this chunk is not free
+      if (i != free_p)
+      {
+        // We won't be able to free this block
+        all_chunks_free = false;
+
+        // free_p might have travelled outside ptr
+        free_p = saved_free;
+        // Abort searching the chunks; we won't be able to free this
+        //  block because a chunk is not free.
+        break;
+      }
+
+      // We do not increment prev_free_p because we are in the same block
+      free_p = nextof(free_p);
+    }
+
+    // post: if the memory block has any chunks, free_p points to one of them
+    // otherwise, our assertions above are still valid
+
+    const details::PODptr<size_type> next = ptr.next();
+
+    if (!all_chunks_free)
+    {
+      if (is_from(free_p, ptr.begin(), ptr.element_size()))
+      {
+        std::less<void *> lt;
+        void * const end = ptr.end();
+        do
+        {
+          prev_free_p = free_p;
+          free_p = nextof(free_p);
+        } while (free_p && lt(free_p, end));
+      }
+      // This invariant is now restored:
+      //     free_p points to the first free chunk in some next memory block, or
+      //       0 if there is no such chunk.
+      //     prev_free_p points to the last free chunk in this memory block.
+      
+      // We are just about to advance ptr.  Maintain the invariant:
+      // prev is the PODptr whose next() is ptr, or !valid()
+      // if there is no such PODptr
+      prev = ptr;
+    }
+    else
+    {
+      // All chunks from this block are free
+
+      // Remove block from list
+      if (prev.valid())
+        prev.next(next);
+      else
+        list = next;
+
+      // Remove all entries in the free list from this block
+      if (prev_free_p != 0)
+        nextof(prev_free_p) = free_p;
+      else
+        this->first = free_p;
+
+      // And release memory
+      UserAllocator::free(ptr.begin());
+      ret = true;
+    }
+
+    // Increment ptr
+    ptr = next;
+  }
+
+  next_size = start_size;
+  return ret;
+}
+
+template <typename UserAllocator>
+bool pool<UserAllocator>::purge_memory()
+{
+  details::PODptr<size_type> iter = list;
+
+  if (!iter.valid())
+    return false;
+
+  do
+  {
+    // hold "next" pointer
+    const details::PODptr<size_type> next = iter.next();
+
+    // delete the storage
+    UserAllocator::free(iter.begin());
+
+    // increment iter
+    iter = next;
+  } while (iter.valid());
+
+  list.invalidate();
+  this->first = 0;
+  next_size = start_size;
+
+  return true;
+}
+
+template <typename UserAllocator>
+void * pool<UserAllocator>::malloc_need_resize()
+{
+  // No memory in any of our storages; make a new storage,
+  const size_type partition_size = alloc_size();
+  const size_type POD_size = next_size * partition_size +
+      details::pool::ct_lcm<sizeof(size_type), sizeof(void *)>::value + sizeof(size_type);
+  char * const ptr = UserAllocator::malloc(POD_size);
+  if (ptr == 0)
+    return 0;
+  const details::PODptr<size_type> node(ptr, POD_size);
+  next_size <<= 1;
+
+  //  initialize it,
+  store().add_block(node.begin(), node.element_size(), partition_size);
+
+  //  insert it into the list,
+  node.next(list);
+  list = node;
+
+  //  and return a chunk from it.
+  return store().malloc();
+}
+
+template <typename UserAllocator>
+void * pool<UserAllocator>::ordered_malloc_need_resize()
+{
+  // No memory in any of our storages; make a new storage,
+  const size_type partition_size = alloc_size();
+  const size_type POD_size = next_size * partition_size +
+      details::pool::ct_lcm<sizeof(size_type), sizeof(void *)>::value + sizeof(size_type);
+  char * const ptr = UserAllocator::malloc(POD_size);
+  if (ptr == 0)
+    return 0;
+  const details::PODptr<size_type> node(ptr, POD_size);
+  next_size <<= 1;
+
+  //  initialize it,
+  //  (we can use "add_block" here because we know that
+  //  the free list is empty, so we don't have to use
+  //  the slower ordered version)
+  store().add_block(node.begin(), node.element_size(), partition_size);
+
+  //  insert it into the list,
+  //   handle border case
+  if (!list.valid() || std::greater<void *>()(list.begin(), node.begin()))
+  {
+    node.next(list);
+    list = node;
+  }
+  else
+  {
+    details::PODptr<size_type> prev = list;
+
+    while (true)
+    {
+      // if we're about to hit the end or
+      //  if we've found where "node" goes
+      if (prev.next_ptr() == 0
+          || std::greater<void *>()(prev.next_ptr(), node.begin()))
+        break;
+
+      prev = prev.next();
+    }
+
+    node.next(prev.next());
+    prev.next(node);
+  }
+
+  //  and return a chunk from it.
+  return store().malloc();
+}
+
+template <typename UserAllocator>
+void * pool<UserAllocator>::ordered_malloc(const size_type n)
+{
+  const size_type partition_size = alloc_size();
+  const size_type total_req_size = n * requested_size;
+  const size_type num_chunks = total_req_size / partition_size +
+      ((total_req_size % partition_size) ? true : false);
+
+  void * ret = store().malloc_n(num_chunks, partition_size);
+
+  if (ret != 0)
+    return ret;
+
+  // Not enougn memory in our storages; make a new storage,
+  BOOST_USING_STD_MAX();
+  next_size = max BOOST_PREVENT_MACRO_SUBSTITUTION(next_size, num_chunks);
+  const size_type POD_size = next_size * partition_size +
+      details::pool::ct_lcm<sizeof(size_type), sizeof(void *)>::value + sizeof(size_type);
+  char * const ptr = UserAllocator::malloc(POD_size);
+  if (ptr == 0)
+    return 0;
+  const details::PODptr<size_type> node(ptr, POD_size);
+
+  // Split up block so we can use what wasn't requested
+  //  (we can use "add_block" here because we know that
+  //  the free list is empty, so we don't have to use
+  //  the slower ordered version)
+  if (next_size > num_chunks)
+    store().add_block(node.begin() + num_chunks * partition_size,
+        node.element_size() - num_chunks * partition_size, partition_size);
+
+  next_size <<= 1;
+
+  //  insert it into the list,
+  //   handle border case
+  if (!list.valid() || std::greater<void *>()(list.begin(), node.begin()))
+  {
+    node.next(list);
+    list = node;
+  }
+  else
+  {
+    details::PODptr<size_type> prev = list;
+
+    while (true)
+    {
+      // if we're about to hit the end or
+      //  if we've found where "node" goes
+      if (prev.next_ptr() == 0
+          || std::greater<void *>()(prev.next_ptr(), node.begin()))
+        break;
+
+      prev = prev.next();
+    }
+
+    node.next(prev.next());
+    prev.next(node);
+  }
+
+  //  and return it.
+  return node.begin();
+}
+
+template <typename UserAllocator>
+details::PODptr<typename pool<UserAllocator>::size_type>
+pool<UserAllocator>::find_POD(void * const chunk) const
+{
+  // We have to find which storage this chunk is from.
+  details::PODptr<size_type> iter = list;
+  while (iter.valid())
+  {
+    if (is_from(chunk, iter.begin(), iter.element_size()))
+      return iter;
+    iter = iter.next();
+  }
+
+  return iter;
+}
+
+} // namespace boost
+
+#endif
diff --git a/src/sat/cryptominisat2/poolfwd.hpp b/src/sat/cryptominisat2/poolfwd.hpp
new file mode 100644 (file)
index 0000000..52964f7
--- /dev/null
@@ -0,0 +1,70 @@
+// Copyright (C) 2000, 2001 Stephen Cleary
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#ifndef BOOST_POOLFWD_HPP
+#define BOOST_POOLFWD_HPP
+
+#include <boost/config.hpp> // for workarounds
+
+// std::size_t
+#include <cstddef>
+
+// boost::details::pool::default_mutex
+//#include <boost/pool/detail/mutex.hpp>
+
+namespace boost {
+
+//
+// Location: <boost/pool/simple_segregated_storage.hpp>
+//
+template <typename SizeType = std::size_t>
+class simple_segregated_storage;
+
+//
+// Location: <boost/pool/pool.hpp>
+//
+struct default_user_allocator_new_delete;
+struct default_user_allocator_malloc_free;
+
+template <typename UserAllocator = default_user_allocator_new_delete>
+class pool;
+
+//
+// Location: <boost/pool/object_pool.hpp>
+//
+template <typename T, typename UserAllocator = default_user_allocator_new_delete>
+class object_pool;
+
+//
+// Location: <boost/pool/singleton_pool.hpp>
+//
+template <typename Tag, unsigned RequestedSize,
+    typename UserAllocator = default_user_allocator_new_delete,
+    unsigned NextSize = 32>
+struct singleton_pool;
+
+//
+// Location: <boost/pool/pool_alloc.hpp>
+//
+struct pool_allocator_tag;
+
+template <typename T,
+    typename UserAllocator = default_user_allocator_new_delete,
+    unsigned NextSize = 32>
+class pool_allocator;
+
+struct fast_pool_allocator_tag;
+
+template <typename T,
+    typename UserAllocator = default_user_allocator_new_delete,
+    unsigned NextSize = 32>
+class fast_pool_allocator;
+
+} // namespace boost
+
+#endif
diff --git a/src/sat/cryptominisat2/singleton.hpp b/src/sat/cryptominisat2/singleton.hpp
new file mode 100644 (file)
index 0000000..db7ca67
--- /dev/null
@@ -0,0 +1,107 @@
+// Copyright (C) 2000 Stephen Cleary
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#ifndef BOOST_POOL_SINGLETON_HPP
+#define BOOST_POOL_SINGLETON_HPP
+
+// The following code might be put into some Boost.Config header in a later revision
+#ifdef __BORLANDC__
+# pragma option push -w-inl
+#endif
+
+//
+// The following helper classes are placeholders for a generic "singleton"
+//  class.  The classes below support usage of singletons, including use in
+//  program startup/shutdown code, AS LONG AS there is only one thread
+//  running before main() begins, and only one thread running after main()
+//  exits.
+//
+// This class is also limited in that it can only provide singleton usage for
+//  classes with default constructors.
+//
+
+// The design of this class is somewhat twisted, but can be followed by the
+//  calling inheritance.  Let us assume that there is some user code that
+//  calls "singleton_default<T>::instance()".  The following (convoluted)
+//  sequence ensures that the same function will be called before main():
+//    instance() contains a call to create_object.do_nothing()
+//    Thus, object_creator is implicitly instantiated, and create_object
+//      must exist.
+//    Since create_object is a static member, its constructor must be
+//      called before main().
+//    The constructor contains a call to instance(), thus ensuring that
+//      instance() will be called before main().
+//    The first time instance() is called (i.e., before main()) is the
+//      latest point in program execution where the object of type T
+//      can be created.
+//    Thus, any call to instance() will auto-magically result in a call to
+//      instance() before main(), unless already present.
+//  Furthermore, since the instance() function contains the object, instead
+//  of the singleton_default class containing a static instance of the
+//  object, that object is guaranteed to be constructed (at the latest) in
+//  the first call to instance().  This permits calls to instance() from
+//  static code, even if that code is called before the file-scope objects
+//  in this file have been initialized.
+
+namespace boost {
+
+namespace details {
+namespace pool {
+
+// T must be: no-throw default constructible and no-throw destructible
+template <typename T>
+struct singleton_default
+{
+  private:
+    struct object_creator
+    {
+      // This constructor does nothing more than ensure that instance()
+      //  is called before main() begins, thus creating the static
+      //  T object before multithreading race issues can come up.
+      object_creator() { singleton_default<T>::instance(); }
+      inline void do_nothing() const { }
+    };
+    static object_creator create_object;
+
+    singleton_default();
+
+  public:
+    typedef T object_type;
+
+    // If, at any point (in user code), singleton_default<T>::instance()
+    //  is called, then the following function is instantiated.
+    static object_type & instance()
+    {
+      // This is the object that we return a reference to.
+      // It is guaranteed to be created before main() begins because of
+      //  the next line.
+      static object_type obj;
+
+      // The following line does nothing else than force the instantiation
+      //  of singleton_default<T>::create_object, whose constructor is
+      //  called before main() begins.
+      create_object.do_nothing();
+
+      return obj;
+    }
+};
+template <typename T>
+typename singleton_default<T>::object_creator
+singleton_default<T>::create_object;
+
+} // namespace pool
+} // namespace details
+
+} // namespace boost
+
+// The following code might be put into some Boost.Config header in a later revision
+#ifdef __BORLANDC__
+# pragma option pop
+#endif
+
+#endif
index a4c65522c9392fe7f76143c4fc793418d3c0442a..c76b445f1f7083babda59ccbd46fce87bfb29156 100644 (file)
@@ -21,8 +21,11 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA
 #ifndef TIME_MEM_H
 #define TIME_MEM_H
 
-namespace MINISAT
-{
+#ifdef _MSC_VER
+#include <msvc/stdint.h>
+#else
+#include <stdint.h>
+#endif //_MSC_VER
 
 #ifdef _MSC_VER
 #include <ctime>
@@ -31,7 +34,7 @@ static inline double cpuTime(void)
 {
     return (double)clock() / CLOCKS_PER_SEC;
 }
-#else
+#else //_MSC_VER
 #ifdef CROSS_COMPILE
 #include <ctime>
 
@@ -39,7 +42,7 @@ static inline double cpuTime(void)
 {
     return (double)clock() / CLOCKS_PER_SEC;
 }
-#else
+#else //CROSS_COMPILE
 #include <sys/time.h>
 #include <sys/resource.h>
 #include <unistd.h>
@@ -50,8 +53,8 @@ static inline double cpuTime(void)
     getrusage(RUSAGE_SELF, &ru);
     return (double)ru.ru_utime.tv_sec + (double)ru.ru_utime.tv_usec / 1000000;
 }
-#endif
-#endif
+#endif //CROSS_COMPILE
+#endif //_MSC_VER
 
 
 #if defined(__linux__)
@@ -90,6 +93,4 @@ static inline uint64_t memUsed()
 }
 #endif
 
-};
-
 #endif //TIME_MEM_H
index 477dbd1b751832b1ef9313eefc443243c082e8c9..d20df58a58277f4bcdd48e5eebd6d9a9a0a7bfc8 100644 (file)
@@ -140,9 +140,10 @@ namespace BEEV
 #endif
 
 #if defined CRYPTOMINISAT2
-       newSolver.set_gaussian_decision_until(100);
-       newSolver.performReplace = true;
-       newSolver.xorFinder = false;
+    newSolver.findNormalXors = false;
+    newSolver.doSubsumption = false;
+    newSolver.verbosity = 0;
+    newSolver.doPartHandler = false;
 #endif
 
 //     if(enable_clausal_abstraction &&