diff options
Diffstat (limited to 'src/prop/cryptominisat/Solver')
67 files changed, 0 insertions, 21353 deletions
diff --git a/src/prop/cryptominisat/Solver/BitArray.h b/src/prop/cryptominisat/Solver/BitArray.h deleted file mode 100644 index 2b67998ae..000000000 --- a/src/prop/cryptominisat/Solver/BitArray.h +++ /dev/null @@ -1,188 +0,0 @@ -/*********************************************************************************** -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 BITARRAY_H -#define BITARRAY_H - -//#define DEBUG_BITARRAY - -#include <string.h> -#include <assert.h> -#ifdef _MSC_VER -#include <msvc/stdint.h> -#else -#include <stdint.h> -#endif //_MSC_VER - -namespace CMSat -{ - -class BitArray -{ -public: - BitArray() : - size(0) - , mp(NULL) - { - } - - BitArray(const BitArray& b) : - size(b.size) - { - mp = new uint64_t[size]; - memcpy(mp, b.mp, sizeof(uint64_t)*size); - } - - BitArray& operator=(const BitArray& b) - { - if (size != b.size) { - delete[] mp; - size = b.size; - mp = new uint64_t[size]; - } - memcpy(mp, b.mp, sizeof(uint64_t)*size); - - return *this; - } - - BitArray& operator&=(const BitArray& b) - { - assert(size == b.size); - uint64_t* t1 = mp; - uint64_t* t2 = b.mp; - for (uint64_t i = 0; i < size; i++) { - *t1 &= *t2; - t1++; - t2++; - } - - return *this; - } - - BitArray& removeThese(const BitArray& b) - { - assert(size == b.size); - uint64_t* t1 = mp; - uint64_t* t2 = b.mp; - for (uint64_t i = 0; i < size; i++) { - *t1 &= ~(*t2); - t1++; - t2++; - } - - return *this; - } - - template<class T> - BitArray& removeThese(const T& rem) - { - for (uint32_t i = 0; i < rem.size(); i++) { - clearBit(rem[i]); - } - - return *this; - } - - template<class T> - BitArray& removeTheseLit(const T& rem) - { - for (uint32_t i = 0; i < rem.size(); i++) { - clearBit(rem[i].var()); - } - - return *this; - } - - void resize(uint32_t _size, const bool fill) - { - _size = _size/64 + (bool)(_size%64); - if (size != _size) { - delete[] mp; - size = _size; - mp = new uint64_t[size]; - } - if (fill) setOne(); - else setZero(); - } - - ~BitArray() - { - delete[] mp; - } - - inline bool isZero() const - { - const uint64_t* mp2 = (const uint64_t*)mp; - - for (uint32_t i = 0; i < size; i++) { - if (mp2[i]) return false; - } - return true; - } - - inline void setZero() - { - memset(mp, 0, size*sizeof(uint64_t)); - } - - inline void setOne() - { - memset(mp, 0xff, size*sizeof(uint64_t)); - } - - inline void clearBit(const uint32_t i) - { - #ifdef DEBUG_BITARRAY - assert(size*64 > i); - #endif - - mp[i/64] &= ~((uint64_t)1 << (i%64)); - } - - inline void setBit(const uint32_t i) - { - #ifdef DEBUG_BITARRAY - assert(size*64 > i); - #endif - - mp[i/64] |= ((uint64_t)1 << (i%64)); - } - - inline bool operator[](const uint32_t& i) const - { - #ifdef DEBUG_BITARRAY - assert(size*64 > i); - #endif - - return (mp[i/64] >> (i%64)) & 1; - } - - inline uint32_t getSize() const - { - return size*64; - } - -private: - - uint32_t size; - uint64_t* mp; -}; - -} - -#endif //BITARRAY_H - diff --git a/src/prop/cryptominisat/Solver/BothCache.cpp b/src/prop/cryptominisat/Solver/BothCache.cpp deleted file mode 100644 index 3ffc78f7e..000000000 --- a/src/prop/cryptominisat/Solver/BothCache.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/*************************************************************************** -CryptoMiniSat -- Copyright (c) 2010 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 "BothCache.h" -#include "time_mem.h" -#include <iomanip> -#include "VarReplacer.h" -#include "Subsumer.h" -#include "XorSubsumer.h" - -namespace CMSat { - -BothCache::BothCache(Solver& _solver) : - solver(_solver) -{} - -bool BothCache::tryBoth() -{ - vec<bool> seen(solver.nVars(), 0); - vec<bool> val(solver.nVars(), 0); - vec<Lit> tmp; - uint32_t bProp = 0; - uint32_t bXProp = 0; - double myTime = cpuTime(); - uint32_t backupTrailSize = solver.trail.size(); - - for (Var var = 0; var < solver.nVars(); var++) { - if (solver.value(var) != l_Undef - || solver.subsumer->getVarElimed()[var] - || solver.xorSubsumer->getVarElimed()[var] - || solver.varReplacer->getReplaceTable()[var].var() != var) - continue; - - Lit lit = Lit(var, false); - vector<Lit> const* cache1; - vector<Lit> const* cache2; - - bool startWithTrue; - if (solver.transOTFCache[lit.toInt()].lits.size() < solver.transOTFCache[(~lit).toInt()].lits.size()) { - cache1 = &solver.transOTFCache[lit.toInt()].lits; - cache2 = &solver.transOTFCache[(~lit).toInt()].lits; - startWithTrue = false; - } else { - cache1 = &solver.transOTFCache[(~lit).toInt()].lits; - cache2 = &solver.transOTFCache[lit.toInt()].lits; - startWithTrue = true; - } - - if (cache1->size() == 0) continue; - - for (vector<Lit>::const_iterator it = cache1->begin(), end = cache1->end(); it != end; it++) { - seen[it->var()] = true; - val[it->var()] = it->sign(); - } - - for (vector<Lit>::const_iterator it = cache2->begin(), end = cache2->end(); it != end; it++) { - if (seen[it->var()]) { - Var var2 = it->var(); - if (solver.subsumer->getVarElimed()[var2] - || solver.xorSubsumer->getVarElimed()[var2] - || solver.varReplacer->getReplaceTable()[var2].var() != var2) - continue; - - if (val[it->var()] == it->sign()) { - tmp.clear(); - tmp.push(*it); - solver.addClauseInt(tmp, true); - if (!solver.ok) goto end; - bProp++; - } else { - tmp.clear(); - tmp.push(Lit(var, false)); - tmp.push(Lit(it->var(), false)); - bool sign = true ^ startWithTrue ^ it->sign(); - solver.addXorClauseInt(tmp, sign); - if (!solver.ok) goto end; - bXProp++; - } - } - } - - for (vector<Lit>::const_iterator it = cache1->begin(), end = cache1->end(); it != end; it++) { - seen[it->var()] = false; - } - } - - end: - if (solver.conf.verbosity >= 1) { - std::cout << "c Cache " << - " BProp: " << bProp << - " Set: " << (solver.trail.size() - backupTrailSize) << - " BXProp: " << bXProp << - " T: " << (cpuTime() - myTime) << - std::endl; - } - - return solver.ok; -} - -} diff --git a/src/prop/cryptominisat/Solver/BothCache.h b/src/prop/cryptominisat/Solver/BothCache.h deleted file mode 100644 index 72457319d..000000000 --- a/src/prop/cryptominisat/Solver/BothCache.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef BOTHCACHE_H -#define BOTHCACHE_H - -#include "Solver.h" - -namespace CMSat { - -class BothCache -{ - public: - BothCache(Solver& solver); - bool tryBoth(); - - private: - Solver& solver; -}; - -} - -#endif //BOTHCACHE_H diff --git a/src/prop/cryptominisat/Solver/BoundedQueue.h b/src/prop/cryptominisat/Solver/BoundedQueue.h deleted file mode 100644 index f7f40c158..000000000 --- a/src/prop/cryptominisat/Solver/BoundedQueue.h +++ /dev/null @@ -1,96 +0,0 @@ -/*****************************************************************************************[Queue.h] -MiniSat -- Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson -2008 - Gilles Audemard, Laurent Simon -CryptoMiniSat -- Copyright (c) 2009 Mate Soos - -Original code by MiniSat and glucose authors are under an MIT licence. -Modifications for CryptoMiniSat are under GPLv3 licence. -**************************************************************************************************/ - -#ifndef BOUNDEDQUEUE_H -#define BOUNDEDQUEUE_H - -#ifdef _MSC_VER -#include <msvc/stdint.h> -#else -#include <stdint.h> -#endif //_MSC_VER - -#include "Vec.h" - -namespace CMSat { - -template <class T> -class bqueue { - vec<T> elems; - uint32_t first; - uint32_t last; - int64_t sumofqueue; - int64_t sumOfAllElems; - uint64_t totalNumElems; - uint32_t maxsize; - uint32_t queuesize; // Number of current elements (must be < maxsize !) - -public: - bqueue(void) : - first(0) - , last(0) - , sumofqueue(0) - , sumOfAllElems(0) - , totalNumElems(0) - , maxsize(0) - , queuesize(0) - {} - - void initSize(const uint32_t size) {growTo(size);} // Init size of bounded size queue - - void push(const 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; - sumOfAllElems += x; - totalNumElems++; - elems[first] = x; - if ((++first) == maxsize) first = 0; - } - - const T peek() const { assert(queuesize>0); return elems[last]; } - void pop() {sumofqueue-=elems[last]; queuesize--; if ((++last) == maxsize) last = 0;} - - int64_t getsum() const {return sumofqueue;} - uint32_t getAvgUInt() const {return (uint64_t)sumofqueue/(uint64_t)queuesize;} - double getAvgDouble() const {return (double)sumofqueue/(double)queuesize;} - double getAvgAllDouble() const {return (double)sumOfAllElems/(double)totalNumElems;} - uint64_t getTotalNumeElems() const {return totalNumElems;} - int isvalid() const {return (queuesize==maxsize);} - - void growTo(const uint32_t size) { - elems.growTo(size); - first=0; maxsize=size; queuesize = 0; - for(uint32_t 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 - - int size(void) { return queuesize; } - - void clear(bool dealloc = false) { - elems.clear(dealloc); - first = 0; - last = 0; - maxsize=0; - queuesize=0; - sumofqueue=0; - - totalNumElems = 0; - sumOfAllElems = 0; - } -}; - -} - -#endif //BOUNDEDQUEUE_H diff --git a/src/prop/cryptominisat/Solver/CSet.h b/src/prop/cryptominisat/Solver/CSet.h deleted file mode 100644 index de06ea38f..000000000 --- a/src/prop/cryptominisat/Solver/CSet.h +++ /dev/null @@ -1,209 +0,0 @@ -/************************************************************************************************** -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 CMSat { - -class Clause; - -/** -@brief A class to hold a clause and a related index - -This class is used in Subsumer. Basically, the index could be added to the -Clause class, but it would take space, and that would slow down the solving. - -NOTE: On 64-bit systems, this datastructure needs 128 bits :O -*/ -class ClauseSimp -{ - public: - ClauseSimp(Clause* c, const uint32_t _index) : - clause(c) - , index(_index) - {} - - Clause* clause; ///<The clause to be stored - uint32_t index; ///<The index of the clause in Subsumer::clauses -}; - -/** -@brief Used to quicky add, remove and iterate through a clause set - -Used in Subsumer to put into a set all clauses that need to be treated -*/ -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(); } - ///@brief Number of elements in the set - uint32_t nElems(void) const { return which.size() - free.size(); } - - /** - @brief Add a clause to the set - */ - 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 false; - } - 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 true; - } - - bool alreadyIn(const ClauseSimp& c) const { - assert(c.clause != NULL); - if (where.size() < c.index+1) return false; - if (where[c.index] != std::numeric_limits<uint32_t>::max()) - return true; - return false; - } - - /** - @brief Remove clause from set - - Handles it correctly if the clause was not in the set anyway - */ - 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; - } - - /** - @brief Fully clear the set - */ - 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(); - } - - /** - @brief A normal iterator to iterate through the set - - No other way exists of iterating correctly. - */ - class iterator - { - public: - iterator(ClauseSimp* _it) : - it(_it) - {} - - void operator++() - { - it++; - } - - bool operator!=(const iterator& iter) const - { - return (it != iter.it);; - } - - ClauseSimp& operator*() { - return *it; - } - - ClauseSimp*& operator->() { - return it; - } - private: - ClauseSimp* it; - }; - - /** - @brief A constant iterator to iterate through the set - - No other way exists of iterating correctly. - */ - class const_iterator - { - public: - const_iterator(const ClauseSimp* _it) : - it(_it) - {} - - void operator++() - { - it++; - } - - bool operator!=(const const_iterator& iter) const - { - return (it != iter.it);; - } - - const ClauseSimp& operator*() { - return *it; - } - - const ClauseSimp*& operator->() { - return it; - } - private: - const ClauseSimp* it; - }; - - ///@brief Get starting iterator - iterator begin() - { - return iterator(which.getData()); - } - - ///@brief Get ending iterator - iterator end() - { - return iterator(which.getData() + which.size()); - } - - ///@brief Get starting iterator (constant version) - const_iterator begin() const - { - return const_iterator(which.getData()); - } - - ///@brief Get ending iterator (constant version) - const_iterator end() const - { - return const_iterator(which.getData() + which.size()); - } -}; - -} - -#endif //CSET_H - diff --git a/src/prop/cryptominisat/Solver/Clause.h b/src/prop/cryptominisat/Solver/Clause.h deleted file mode 100644 index e47857add..000000000 --- a/src/prop/cryptominisat/Solver/Clause.h +++ /dev/null @@ -1,344 +0,0 @@ -/***************************************************************************** -MiniSat -- Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson -glucose -- Gilles Audemard, Laurent Simon (2008) -CryptoMiniSat -- Copyright (c) 2009 Mate Soos - -Original code by MiniSat and glucose authors are under an MIT licence. -Modifications for CryptoMiniSat are under GPLv3 licence. -******************************************************************************/ - -#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 <string.h> - -#include "SolverTypes.h" -#include "constants.h" -#include "Watched.h" -#include "Alg.h" -#include "constants.h" - -namespace CMSat { - -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].var() & 31); - return abstraction; -} - -class MatrixFinder; -class ClauseAllocator; - -/** -@brief Holds a clause. Does not allocate space for literals - -Literals are allocated by an external allocator that allocates enough space -for the class that it can hold the literals as well. I.e. it malloc()-s - sizeof(Clause)+LENGHT*sizeof(Lit) -to hold the clause. -*/ -struct Clause -{ -protected: - - uint32_t isLearnt:1; ///<Is the clause a learnt clause? - uint32_t changed:1; ///<Var inside clause has been changed - /** - @brief Is the XOR equal to 1 or 0? - - i.e. "a + b" = TRUE or FALSE? -- we only have variables inside xor clauses, - so this is important to know - - NOTE: ONLY set if the clause is an xor clause. - */ - uint32_t isXorEqualFalse:1; - uint32_t isXorClause:1; ///< Is the clause an XOR clause? - uint32_t isRemoved:1; ///<Is this clause queued for removal because of usless binary removal? - uint32_t isFreed:1; ///<Has this clause been marked as freed by the ClauseAllocator ? - uint32_t glue:MAX_GLUE_BITS; ///<Clause glue -- clause activity according to GLUCOSE - uint32_t mySize:18; ///<The current size of the clause - - float miniSatAct; ///<Clause activity according to MiniSat - - uint32_t abst; //Abstraction of clause - -#ifdef _MSC_VER -public: -#endif //_MSC_VER - template<class V> - Clause(const V& ps, const bool learnt) - { - isFreed = false; - glue = 0; //To stop valgrind from complaining - isXorEqualFalse = false; //To stop valgrind from complaining - isXorClause = false; - assert(ps.size() > 2); - mySize = ps.size(); - isLearnt = learnt; - isRemoved = false; - - assert(ps.size() > 0); - memcpy(getData(), ps.getData(), ps.size()*sizeof(Lit)); - miniSatAct = 0; - setChanged(); - } - -public: - friend class ClauseAllocator; - - uint32_t size() const - { - return mySize; - } - - bool getChanged() const - { - return changed; - } - - void setChanged() - { - changed = 1; - } - - void unsetChanged() - { - changed = 0; - } - - void shrink (const uint32_t i) - { - assert(i <= size()); - mySize -= i; - if (i > 0) - setChanged(); - } - - void pop() - { - shrink(1); - } - - bool isXor() const - { - return isXorClause; - } - - bool learnt() const - { - return isLearnt; - } - - float& getMiniSatAct() - { - return miniSatAct; - } - - void setMiniSatAct(const float newMiniSatAct) - { - miniSatAct = newMiniSatAct; - } - - const float& getMiniSatAct() const - { - return miniSatAct; - } - - Lit& operator [] (const uint32_t i) - { - return *(getData() + i); - } - - const Lit& operator [] (const uint32_t i) const - { - return *(getData() + i); - } - - void setGlue(const uint32_t newGlue) - { - assert(newGlue <= MAX_THEORETICAL_GLUE); - glue = newGlue; - } - - uint32_t getGlue() const - { - return glue; - } - - void makeNonLearnt() - { - assert(isLearnt); - isLearnt = false; - } - - void makeLearnt(const uint32_t newGlue, const float newMiniSatAct) - { - glue = newGlue; - miniSatAct = newMiniSatAct; - isLearnt = true; - } - - inline void strengthen(const Lit p) - { - remove(*this, p); - setChanged(); - } - - void calcAbstractionClause() - { - abst = calcAbstraction(*this); - } - - uint32_t getAbst() const - { - return abst; - } - - const Lit* getData() const - { - return (Lit*)((char*)this + sizeof(Clause)); - } - - Lit* getData() - { - return (Lit*)((char*)this + sizeof(Clause)); - } - - const Lit* getDataEnd() const - { - return getData()+size(); - } - - Lit* getDataEnd() - { - return getData() + size(); - } - - void print(FILE* to = stdout) const - { - plainPrint(to); - fprintf(to, "c clause learnt %s glue %d miniSatAct %.3f\n", (learnt() ? "yes" : "no"), getGlue(), getMiniSatAct()); - } - - void plainPrint(FILE* to = stdout) const - { - for (uint32_t i = 0; i < size(); i++) { - if ((getData()+i)->sign()) fprintf(to, "-"); - fprintf(to, "%d ", (getData()+i)->var() + 1); - } - fprintf(to, "0\n"); - } - - void setRemoved() - { - isRemoved = true; - } - - bool getRemoved() const - { - return isRemoved; - } - - void setFreed() - { - isFreed = true; - } - - bool getFreed() const - { - return isFreed; - } - - void takeMaxOfStats(Clause& other) - { - if (other.getGlue() < getGlue()) - setGlue(other.getGlue()); - if (other.getMiniSatAct() > getMiniSatAct()) - setMiniSatAct(other.getMiniSatAct()); - } -}; - -/** -@brief Holds an xor clause. Similarly to Clause, it cannot be directly used - -The space is not allocated for the literals. See Clause for details -*/ -class XorClause : public Clause -{ -protected: - // NOTE: This constructor cannot be used directly (doesn't allocate enough memory). - template<class V> - XorClause(const V& ps, const bool xorEqualFalse) : - Clause(ps, false) - { - isXorEqualFalse = xorEqualFalse; - isXorClause = true; - } - -public: - friend class ClauseAllocator; - - inline bool xorEqualFalse() const - { - return isXorEqualFalse; - } - - inline void invert(const bool b) - { - isXorEqualFalse ^= b; - } - - void print(FILE* to = stdout) const - { - plainPrint(to); - fprintf(to, "c clause learnt %s glue %d miniSatAct %.3f\n", (learnt() ? "yes" : "no"), getGlue(), getMiniSatAct()); - } - - void plainPrint(FILE* to = stdout) const - { - fprintf(to, "x"); - if (xorEqualFalse()) - fprintf(to, "-"); - for (uint32_t i = 0; i < size(); i++) { - fprintf(to, "%d ", this->operator[](i).var() + 1); - } - fprintf(to, "0\n"); - } - - friend class MatrixFinder; -}; - -inline std::ostream& operator<<(std::ostream& cout, const Clause& cl) -{ - for (uint32_t i = 0; i < cl.size(); i++) { - cout << cl[i] << " "; - } - return cout; -} - -inline std::ostream& operator<<(std::ostream& cout, const XorClause& cl) -{ - cout << "x"; - for (uint32_t i = 0; i < cl.size(); i++) { - cout << cl[i].var() + 1 << " "; - } - if (cl.xorEqualFalse()) cout << " = false"; - else cout << " = true"; - - return cout; -} - -} - -#endif //CLAUSE_H diff --git a/src/prop/cryptominisat/Solver/ClauseAllocator.cpp b/src/prop/cryptominisat/Solver/ClauseAllocator.cpp deleted file mode 100644 index f1576e7fe..000000000 --- a/src/prop/cryptominisat/Solver/ClauseAllocator.cpp +++ /dev/null @@ -1,572 +0,0 @@ -/*********************************************************************** -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 "ClauseAllocator.h" - -#include <string.h> -#include <limits> -#include "assert.h" -#include "SolverTypes.h" -#include "Clause.h" -#include "Solver.h" -#include "time_mem.h" -#include "Subsumer.h" -#include "XorSubsumer.h" -//#include "VarReplacer.h" -#include "Gaussian.h" - -#ifndef _MSC_VER -#include <sys/mman.h> -#endif //_MSC_VER - - -//For mild debug info: -//#define DEBUG_CLAUSEALLOCATOR - -//For listing each and every clause location: -//#define DEBUG_CLAUSEALLOCATOR2 - -#define MIN_LIST_SIZE (300000 * (sizeof(Clause) + 4*sizeof(Lit))/sizeof(BASE_DATA_TYPE)) -//#define MIN_LIST_SIZE (100 * (sizeof(Clause) + 4*sizeof(Lit))/sizeof(BASE_DATA_TYPE)) -#define ALLOC_GROW_MULT 8 -//We shift stuff around in Watched, so not all of 32 bits are useable. -#define EFFECTIVELY_USEABLE_BITS 30 -#define MAXSIZE ((1 << (EFFECTIVELY_USEABLE_BITS-NUM_BITS_OUTER_OFFSET))-1) - -using namespace CMSat; - -ClauseAllocator::ClauseAllocator() -{ - assert(MIN_LIST_SIZE < MAXSIZE); - assert(sizeof(Clause) + 2*sizeof(Lit) >= sizeof(NewPointerAndOffset)); -} - -/** -@brief Frees all stacks -*/ -ClauseAllocator::~ClauseAllocator() -{ - for (uint32_t i = 0; i < dataStarts.size(); i++) { - free(dataStarts[i]); - } -} - -/** -@brief Allocates space&initializes a clause -*/ -template<class T> -Clause* ClauseAllocator::Clause_new(const T& ps, const bool learnt) -{ - assert(ps.size() > 2); - void* mem = allocEnough(ps.size()); - Clause* real= new (mem) Clause(ps, learnt); - //assert(!(ps.size() == 2 && !real->wasBin())); - - return real; -} - -template Clause* ClauseAllocator::Clause_new(const vec<Lit>& ps, const bool learnt); -template Clause* ClauseAllocator::Clause_new(const Clause& ps, const bool learnt); -template Clause* ClauseAllocator::Clause_new(const XorClause& ps, const bool learnt); - -/** -@brief Allocates space&initializes an xor clause -*/ -template<class T> -XorClause* ClauseAllocator::XorClause_new(const T& ps, const bool xorEqualFalse) -{ - assert(ps.size() > 2); - void* mem = allocEnough(ps.size()); - XorClause* real= new (mem) XorClause(ps, xorEqualFalse); - - return real; -} -template XorClause* ClauseAllocator::XorClause_new(const vec<Lit>& ps, const bool inverted); -template XorClause* ClauseAllocator::XorClause_new(const XorClause& ps, const bool inverted); - -/** -@brief Allocates space for a new clause & copies a give clause to it -*/ -Clause* ClauseAllocator::Clause_new(Clause& c) -{ - assert(c.size() > 2); - void* mem = allocEnough(c.size()); - memcpy(mem, &c, sizeof(Clause)+sizeof(Lit)*c.size()); - - return (Clause*)mem; -} - -/** -@brief Allocates enough space for a new clause - -It tries to add the clause to the end of any already created stacks -if that is impossible, it creates a new stack, and adds the clause there -*/ -void* ClauseAllocator::allocEnough(const uint32_t size) throw (std::bad_alloc) -{ - assert(sizes.size() == dataStarts.size()); - assert(maxSizes.size() == dataStarts.size()); - assert(origClauseSizes.size() == dataStarts.size()); - - assert(size > 2 && "Clause size cannot be 2 or less, those are stored natively"); - - const uint32_t needed = sizeof(Clause) + sizeof(Lit)*size; - bool found = false; - uint32_t which = std::numeric_limits<uint32_t>::max(); - for (uint32_t i = 0; i < sizes.size(); i++) { - if (sizes[i] + needed < maxSizes[i]) { - found = true; - which = i; - break; - } - } - - if (!found) { - //Checking whether we are out of memory, because the offset that we can - //store is too little - if (dataStarts.size() == (1<<NUM_BITS_OUTER_OFFSET)) - throw std::bad_alloc(); - - uint32_t nextSize; //number of BYTES to allocate - if (maxSizes.size() != 0) { - nextSize = std::min((uint32_t)(maxSizes[maxSizes.size()-1]*ALLOC_GROW_MULT), (uint32_t)MAXSIZE); - nextSize = std::max(nextSize, (uint32_t)MIN_LIST_SIZE*2); - } else { - nextSize = (uint32_t)MIN_LIST_SIZE; - } - assert(needed < nextSize); - assert(nextSize <= MAXSIZE); - - #ifdef DEBUG_CLAUSEALLOCATOR - std::cout << "c New list in ClauseAllocator. Size: " << nextSize - << " (maxSize: " << MAXSIZE - << ")" << std::endl; - #endif //DEBUG_CLAUSEALLOCATOR - - BASE_DATA_TYPE *dataStart; - dataStart = (BASE_DATA_TYPE *)malloc(sizeof(BASE_DATA_TYPE) * nextSize); - - dataStarts.push(dataStart); - sizes.push(0); - maxSizes.push(nextSize); - origClauseSizes.push(); - currentlyUsedSizes.push(0); - which = dataStarts.size()-1; - } - #ifdef DEBUG_CLAUSEALLOCATOR2 - std::cout - << "selected list = " << which - << " size = " << sizes[which] - << " maxsize = " << maxSizes[which] - << " diff = " << maxSizes[which] - sizes[which] << std::endl; - #endif //DEBUG_CLAUSEALLOCATOR - - assert(which != std::numeric_limits<uint32_t>::max()); - Clause* pointer = (Clause*)(dataStarts[which] + sizes[which]); - sizes[which] += needed; - currentlyUsedSizes[which] += needed; - origClauseSizes[which].push(needed); - - return pointer; -} - -/** -@brief Given the pointer of the clause it finds a 32-bit offset for it - -Calculates the stack frame and the position of the pointer in the stack, and -rerturns a 32-bit value that is a concatenation of these two -*/ -ClauseOffset ClauseAllocator::getOffset(const Clause* ptr) const -{ - uint32_t outerOffset = getOuterOffset(ptr); - uint32_t interOffset = getInterOffset(ptr, outerOffset); - return combineOuterInterOffsets(outerOffset, interOffset); -} - -/** -@brief Combines the stack number and the internal offset into one 32-bit number -*/ -inline ClauseOffset ClauseAllocator::combineOuterInterOffsets(const uint32_t outerOffset, const uint32_t interOffset) const -{ - return (outerOffset | (interOffset << NUM_BITS_OUTER_OFFSET)); -} - -/** -@brief Given a pointer, finds which stack it's in -*/ -inline uint32_t ClauseAllocator::getOuterOffset(const Clause* ptr) const -{ - uint32_t which = std::numeric_limits<uint32_t>::max(); - for (uint32_t i = 0; i < sizes.size(); i++) { - if ((BASE_DATA_TYPE*)ptr >= dataStarts[i] && (BASE_DATA_TYPE*)ptr < dataStarts[i] + maxSizes[i]) { - which = i; - break; - } - } - assert(which != std::numeric_limits<uint32_t>::max()); - - return which; -} - -/** -@brief Given a pointer and its stack number, returns its position inside the stack -*/ -inline uint32_t ClauseAllocator::getInterOffset(const Clause* ptr, uint32_t outerOffset) const -{ - return ((BASE_DATA_TYPE*)ptr - dataStarts[outerOffset]); -} - -/** -@brief Frees a clause - -If clause was binary, it frees it in quite a normal way. If it isn't, then it -needs to set the data in the Clause that it has been freed, and updates the -stack it belongs to such that the stack can now that its effectively used size -is smaller - -NOTE: The size of claues can change. Therefore, currentlyUsedSizes can in fact -be incorrect, since it was incremented by the ORIGINAL size of the clause, but -when the clause is "freed", it is decremented by the POTENTIALLY SMALLER size -of the clause. Therefore, the "currentlyUsedSizes" is an overestimation!! -*/ -void ClauseAllocator::clauseFree(Clause* c) -{ - assert(!c->getFreed()); - - c->setFreed(); - uint32_t outerOffset = getOuterOffset(c); - //uint32_t interOffset = getInterOffset(c, outerOffset); - currentlyUsedSizes[outerOffset] -= sizeof(Clause) + c->size()*sizeof(Lit); - //above should be - //origClauseSizes[outerOffset][interOffset] - //but it cannot be :( -} - -/** -@brief If needed, compacts stacks, removing unused clauses - -Firstly, the algorithm determines if the number of useless slots is large or -small compared to the problem size. If it is small, it does nothing. If it is -large, then it allocates new stacks, copies the non-freed clauses to these new -stacks, updates all pointers and offsets, and frees the original stacks. -*/ -void ClauseAllocator::consolidate(Solver* solver, const bool force) throw (std::bad_alloc) -{ - double myTime = cpuTime(); - #ifdef DEBUG_PROPAGATEFROM - checkGoodPropBy(solver); - #endif - - uint32_t sum = 0; - for (uint32_t i = 0; i < sizes.size(); i++) { - sum += currentlyUsedSizes[i]; - } - uint32_t sumAlloc = 0; - for (uint32_t i = 0; i < sizes.size(); i++) { - sumAlloc += sizes[i]; - } - - #ifdef DEBUG_CLAUSEALLOCATOR - std::cout << "c ratio:" << (double)sum/(double)sumAlloc << std::endl; - #endif //DEBUG_CLAUSEALLOCATOR - - //If re-allocation is not really neccessary, don't do it - //Neccesities: - //1) There is too much memory allocated. Re-allocation will save space - // Avoiding segfault (max is 16 outerOffsets, more than 10 is near) - //2) There is too much empty, unused space (>30%) - if (!force - && ((double)sum/(double)sumAlloc > 0.7 && sizes.size() < 10) - ) { - if (solver->conf.verbosity >= 3) { - std::cout << "c Not consolidating memory." << std::endl; - } - return; - } - - #ifdef DEBUG_CLAUSEALLOCATOR - std::cout << "c ------ Consolidating Memory ------------" << std::endl; - #endif //DEBUG_CLAUSEALLOCATOR - int64_t newMaxSizeNeed = (double)sum*1.2 + MIN_LIST_SIZE; - #ifdef DEBUG_CLAUSEALLOCATOR - std::cout << "c newMaxSizeNeed = " << newMaxSizeNeed << std::endl; - #endif //DEBUG_CLAUSEALLOCATOR - vec<uint32_t> newMaxSizes; - for (uint32_t i = 0; i < (1 << NUM_BITS_OUTER_OFFSET); i++) { - if (newMaxSizeNeed <= 0) break; - - uint32_t thisMaxSize = std::min(newMaxSizeNeed, (int64_t)MAXSIZE); - if (i == 0) { - thisMaxSize = std::max(thisMaxSize, (uint32_t)MIN_LIST_SIZE); - } else { - assert(i > 0); - thisMaxSize = std::max(thisMaxSize, newMaxSizes[i-1]/2); - thisMaxSize = std::max(thisMaxSize, (uint32_t)MIN_LIST_SIZE*2); - } - newMaxSizeNeed -= thisMaxSize; - assert(thisMaxSize <= MAXSIZE); - newMaxSizes.push(thisMaxSize); - //because the clauses don't always fit - //it might occur that there is enough place in total - //but the very last clause would need to be fragmented - //over multiple lists' ends :O - //So this "magic" constant could take care of that.... - //or maybe not (if _very_ large clauses are used, always - //bad chance, etc. :O ) - //NOTE: the + MIN_LIST_SIZE should take care of this above at - // newMaxSizeNeed = sum + MIN_LIST_SIZE; - #ifdef DEBUG_CLAUSEALLOCATOR - std::cout << "c NEW MaxSizes:" << newMaxSizes[i] << std::endl; - #endif //DEBUG_CLAUSEALLOCATOR - } - #ifdef DEBUG_CLAUSEALLOCATOR - std::cout << "c ------------------" << std::endl; - #endif //DEBUG_CLAUSEALLOCATOR - - if (newMaxSizeNeed > 0) - throw std::bad_alloc(); - - vec<uint32_t> newSizes; - vec<vec<uint32_t> > newOrigClauseSizes; - vec<BASE_DATA_TYPE*> newDataStartsPointers; - vec<BASE_DATA_TYPE*> newDataStarts; - for (uint32_t i = 0; i < newMaxSizes.size(); i++) { - newSizes.push(0); - newOrigClauseSizes.push(); - BASE_DATA_TYPE* pointer; - pointer = (BASE_DATA_TYPE*)malloc(newMaxSizes[i]); - newDataStartsPointers.push(pointer); - newDataStarts.push(pointer); - } - - vector<Clause*> clauses; - for (uint32_t i = 0; i < dataStarts.size(); i++) { - uint32_t currentLoc = 0; - for (uint32_t i2 = 0; i2 < origClauseSizes[i].size(); i2++) { - Clause* oldPointer = (Clause*)(dataStarts[i] + currentLoc); - if (!oldPointer->getFreed()) { - clauses.push_back(oldPointer); - } else { - (*((NewPointerAndOffset*)(oldPointer))).newOffset = std::numeric_limits<uint32_t>::max(); - } - currentLoc += origClauseSizes[i][i2]; - } - } - - putClausesIntoDatastruct(clauses); - - uint32_t outerPart = 0; - //uint64_t skippedNum = 0; - for (uint32_t i = 0; i < clauses.size(); i++) { - Clause* clause = getClause(); - - uint32_t sizeNeeded = (sizeof(Clause) + clause->size()*sizeof(Lit))/sizeof(BASE_DATA_TYPE); - - //Next line is needed, because in case of isRemoved() - //, the size of the clause could become 0, thus having less - // than enough space to carry the NewPointerAndOffset info - sizeNeeded = std::max(sizeNeeded, (uint32_t)((sizeof(Clause) + 2*sizeof(Lit))/sizeof(BASE_DATA_TYPE))); - - if (newSizes[outerPart] + sizeNeeded > newMaxSizes[outerPart]) { - outerPart++; - assert(outerPart < newMaxSizes.size()); - } - memcpy(newDataStartsPointers[outerPart], (BASE_DATA_TYPE*)clause, sizeNeeded*sizeof(BASE_DATA_TYPE)); - - NewPointerAndOffset& ptr = *((NewPointerAndOffset*)clause); - ptr.newOffset = combineOuterInterOffsets(outerPart, newSizes[outerPart]); - ptr.newPointer = (Clause*)newDataStartsPointers[outerPart]; - - newSizes[outerPart] += sizeNeeded; - newOrigClauseSizes[outerPart].push(sizeNeeded); - newDataStartsPointers[outerPart] += sizeNeeded; - } - - updateAllOffsetsAndPointers(solver); - - for (uint32_t i = 0; i < dataStarts.size(); i++) - free(dataStarts[i]); - - dataStarts.clear(); - maxSizes.clear(); - sizes.clear(); - origClauseSizes.clear(); - currentlyUsedSizes.clear(); - origClauseSizes.clear(); - - for (uint32_t i = 0; i < newMaxSizes.size(); i++) { - dataStarts.push(newDataStarts[i]); - maxSizes.push(newMaxSizes[i]); - sizes.push(newSizes[i]); - currentlyUsedSizes.push(newSizes[i]); - } - newOrigClauseSizes.moveTo(origClauseSizes); - - if (solver->conf.verbosity >= 3) { - std::cout << "c Consolidated memory. Time: " - << cpuTime() - myTime << std::endl; - } -} - -void ClauseAllocator::putClausesIntoDatastruct(std::vector<Clause*>& clauses) -{ - otherClauses.clear(); - threeLongClauses.clear(); - for (uint32_t i = 0; i < clauses.size(); i++) { - Clause* c = clauses[i]; - if (c->size() <= 3) { - threeLongClauses.push_back(c); - } else { - otherClauses.push_back(c); - } - } -} - -Clause* ClauseAllocator::getClause() -{ - if (!threeLongClauses.empty()) { - Clause* tmp = threeLongClauses[threeLongClauses.size()-1]; - threeLongClauses.pop_back(); - return tmp; - } - - assert(!otherClauses.empty()); - Clause* tmp = otherClauses[otherClauses.size()-1]; - otherClauses.pop_back(); - return tmp; -} - -void ClauseAllocator::checkGoodPropBy(const Solver* solver) -{ - const vec<PropBy>& reason = solver->reason; - Var var = 0; - for (const PropBy *it = reason.getData(), *end = reason.getDataEnd(); it != end; it++, var++) { - if ((uint32_t)solver->level[var] > solver->decisionLevel() - || solver->level[var] == 0 - || solver->value(var) == l_Undef - ) { - continue; - } - - if (it->isClause() && !it->isNULL()) { - assert(!getPointer(it->getClause())->getFreed()); - assert(!getPointer(it->getClause())->getRemoved()); - } - } -} - - -void ClauseAllocator::updateAllOffsetsAndPointers(Solver* solver) -{ - updateOffsets(solver->watches); - - updatePointers(solver->clauses); - updatePointers(solver->learnts); - updatePointers(solver->xorclauses); - updatePointers(solver->freeLater); - #ifdef ENABLE_UNWIND_GLUE - updatePointers(solver->unWindGlue); - #endif //ENABLE_UNWIND_GLUE - - //No need to update varreplacer, since it only stores binary clauses that - //must have been allocated such as to use the pool - //updatePointers(solver->varReplacer->clauses, oldToNewPointer); - - #ifdef USE_GAUSS - for (uint32_t i = 0; i < solver->gauss_matrixes.size(); i++) { - updatePointers(solver->gauss_matrixes[i]->xorclauses); - updatePointers(solver->gauss_matrixes[i]->clauses_toclear); - } - #endif //USE_GAUSS - - vec<PropBy>& reason = solver->reason; - Var var = 0; - for (PropBy *it = reason.getData(), *end = reason.getDataEnd(); it != end; it++, var++) { - if ((uint32_t)solver->level[var] > solver->decisionLevel() - || solver->level[var] == 0 - || solver->value(var) == l_Undef) { - *it = PropBy(); - continue; - } - - if (it->isClause() && !it->isNULL()) { - assert(((NewPointerAndOffset*)(getPointer(it->getClause())))->newOffset != std::numeric_limits<uint32_t>::max()); - *it = PropBy(((NewPointerAndOffset*)(getPointer(it->getClause())))->newOffset); - } - } -} - -/** -@brief A dumb helper function to update offsets -*/ -void ClauseAllocator::updateOffsets(vec<vec<Watched> >& watches) -{ - for (uint32_t i = 0; i < watches.size(); i++) { - vec<Watched>& list = watches[i]; - for (vec<Watched>::iterator it = list.getData(), end = list.getDataEnd(); it != end; it++) { - if (!it->isClause() && !it->isXorClause()) continue; - if (it->isClause()) { - it->setNormOffset(((NewPointerAndOffset*)(getPointer(it->getNormOffset())))->newOffset); - } else { - it->setXorOffset(((NewPointerAndOffset*)(getPointer(it->getXorOffset())))->newOffset); - } - } - } -} - -/** -@brief A dumb helper function to update pointers -*/ -template<class T> -void ClauseAllocator::updatePointers(vec<T*>& toUpdate) -{ - for (T **it = toUpdate.getData(), **end = toUpdate.getDataEnd(); it != end; it++) { - if (*it != NULL) { - *it = (T*)(((NewPointerAndOffset*)(*it))->newPointer); - } - } -} - -/** -@brief A dumb helper function to update pointers -*/ -void ClauseAllocator::updatePointers(vector<Clause*>& toUpdate) -{ - for (vector<Clause*>::iterator it = toUpdate.begin(), end = toUpdate.end(); it != end; it++) { - *it = (((NewPointerAndOffset*)(*it))->newPointer); - } -} - -/** -@brief A dumb helper function to update pointers -*/ -void ClauseAllocator::updatePointers(vector<XorClause*>& toUpdate) -{ - for (vector<XorClause*>::iterator it = toUpdate.begin(), end = toUpdate.end(); it != end; it++) { - *it = (XorClause*)(((NewPointerAndOffset*)(*it))->newPointer); - } -} - -/** -@brief A dumb helper function to update pointers -*/ -void ClauseAllocator::updatePointers(vector<pair<Clause*, uint32_t> >& toUpdate) -{ - for (vector<pair<Clause*, uint32_t> >::iterator it = toUpdate.begin(), end = toUpdate.end(); it != end; it++) { - it->first = (((NewPointerAndOffset*)(it->first))->newPointer); - } -} diff --git a/src/prop/cryptominisat/Solver/ClauseAllocator.h b/src/prop/cryptominisat/Solver/ClauseAllocator.h deleted file mode 100644 index d20c1617b..000000000 --- a/src/prop/cryptominisat/Solver/ClauseAllocator.h +++ /dev/null @@ -1,146 +0,0 @@ -/*********************************************************************** -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 CLAUSEALLOCATOR_H -#define CLAUSEALLOCATOR_H - -#ifdef _MSC_VER -#include <msvc/stdint.h> -#else -#include <stdint.h> -#endif //_MSC_VER - -#include <stdlib.h> -#include "Vec.h" -#include <map> -#include <vector> - -#include "ClauseOffset.h" -#include "Watched.h" - -#define NUM_BITS_OUTER_OFFSET 4 -#define BASE_DATA_TYPE char - -namespace CMSat { - -using std::map; -using std::vector; - -class Clause; -class XorClause; -class Solver; - -/** -@brief Allocates memory for (xor) clauses - -This class allocates memory in large chunks, then distributes it to clauses when -needed. When instructed, it consolidates the unused space (i.e. clauses free()-ed). -Essentially, it is a stack-like allocator for clauses. It is useful to have -this, because this way, we can address clauses according to their number, -which is 32-bit, instead of their address, which might be 64-bit -*/ -class ClauseAllocator { - public: - ClauseAllocator(); - ~ClauseAllocator(); - - template<class T> - Clause* Clause_new(const T& ps, const bool learnt = false); - template<class T> - XorClause* XorClause_new(const T& ps, const bool xorEqualFalse); - Clause* Clause_new(Clause& c); - - ClauseOffset getOffset(const Clause* ptr) const; - - /** - @brief Returns the pointer of a clause given its offset - - Takes the "dataStart" of the correct stack, and adds the offset, - returning the thus created pointer. Used a LOT in propagation, thus this - is very important to be fast (therefore, it is an inlined method) - */ - inline Clause* getPointer(const uint32_t offset) const - { - return (Clause*)(dataStarts[offset&((1 << NUM_BITS_OUTER_OFFSET) - 1)] - +(offset >> NUM_BITS_OUTER_OFFSET)); - } - - void clauseFree(Clause* c); - - void consolidate(Solver* solver, const bool force = false) throw (std::bad_alloc); - - uint32_t getNewClauseNum(); - - private: - uint32_t getOuterOffset(const Clause* c) const; - uint32_t getInterOffset(const Clause* c, const uint32_t outerOffset) const; - ClauseOffset combineOuterInterOffsets(const uint32_t outerOffset, const uint32_t interOffset) const; - - void updateAllOffsetsAndPointers(Solver* solver); - template<class T> - void updatePointers(vec<T*>& toUpdate); - void updatePointers(vector<Clause*>& toUpdate); - void updatePointers(vector<XorClause*>& toUpdate); - void updatePointers(vector<std::pair<Clause*, uint32_t> >& toUpdate); - void updateOffsets(vec<vec<Watched> >& watches); - void checkGoodPropBy(const Solver* solver); - - void releaseClauseNum(const uint32_t num); - - vec<BASE_DATA_TYPE*> dataStarts; ///<Stacks start at these positions - vec<size_t> sizes; ///<The number of 32-bit datapieces currently used in each stack - /** - @brief Clauses in the stack had this size when they were allocated - This my NOT be their current size: the clauses may be shrinked during - the running of the solver. Therefore, it is imperative that their orignal - size is saved. This way, we can later move clauses around. - */ - vec<vec<uint32_t> > origClauseSizes; - vec<size_t> maxSizes; ///<The number of 32-bit datapieces allocated in each stack - /** - @brief The estimated used size of the stack - This is incremented by clauseSize each time a clause is allocated, and - decremetented by clauseSize each time a clause is deallocated. The - problem is, that clauses can shrink, and thus this value will be an - overestimation almost all the time - */ - vec<size_t> currentlyUsedSizes; - - void* allocEnough(const uint32_t size) throw (std::bad_alloc); - - /** - @brief The clause's data is replaced by this to aid updating - - We need to update the pointer or offset that points to the clause - The best way to do that is to simply fill the original place of the clause - with the pointer/offset of the new location. - */ - struct NewPointerAndOffset - { - uint32_t newOffset; ///<The new offset where the clause now resides - Clause* newPointer; ///<The new place - }; - - vector<Clause*> otherClauses; - vector<Clause*> threeLongClauses; - Clause* getClause(); - void putClausesIntoDatastruct(std::vector<Clause*>& clauses); -}; - -} - -#endif //CLAUSEALLOCATOR_H diff --git a/src/prop/cryptominisat/Solver/ClauseCleaner.cpp b/src/prop/cryptominisat/Solver/ClauseCleaner.cpp deleted file mode 100644 index 47dd675f4..000000000 --- a/src/prop/cryptominisat/Solver/ClauseCleaner.cpp +++ /dev/null @@ -1,261 +0,0 @@ -/*************************************************************************** -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 "ClauseCleaner.h" -#include "VarReplacer.h" -#include "DataSync.h" - -//#define DEBUG_CLEAN -//#define VERBOSE_DEBUG - -using namespace CMSat; - -ClauseCleaner::ClauseCleaner(Solver& _solver) : - solver(_solver) -{ - for (uint32_t i = 0; i < 6; i++) { - lastNumUnitarySat[i] = solver.get_unitary_learnts_num(); - lastNumUnitaryClean[i] = solver.get_unitary_learnts_num(); - } -} - -bool ClauseCleaner::satisfied(const Watched& watched, Lit lit) -{ - assert(watched.isBinary()); - if (solver.value(lit) == l_True) return true; - if (solver.value(watched.getOtherLit()) == l_True) return true; - return false; -} - -void ClauseCleaner::removeSatisfiedBins(const uint32_t limit) -{ - #ifdef DEBUG_CLEAN - assert(solver.decisionLevel() == 0); - #endif - - if (lastNumUnitarySat[binaryClauses] + limit >= solver.get_unitary_learnts_num()) - return; - - uint32_t numRemovedHalfNonLearnt = 0; - uint32_t numRemovedHalfLearnt = 0; - uint32_t wsLit = 0; - for (vec<Watched> *it = solver.watches.getData(), *end = solver.watches.getDataEnd(); it != end; it++, wsLit++) { - Lit lit = ~Lit::toLit(wsLit); - vec<Watched>& ws = *it; - - vec<Watched>::iterator i = ws.getData(); - vec<Watched>::iterator j = i; - for (vec<Watched>::iterator end2 = ws.getDataEnd(); i != end2; i++) { - if (i->isBinary() && satisfied(*i, lit)) { - if (i->getLearnt()) numRemovedHalfLearnt++; - else { - numRemovedHalfNonLearnt++; - } - } else { - *j++ = *i; - } - } - ws.shrink_(i - j); - } - - //std::cout << "removedHalfLeart: " << numRemovedHalfLearnt << std::endl; - //std::cout << "removedHalfNonLeart: " << numRemovedHalfNonLearnt << std::endl; - assert(numRemovedHalfLearnt % 2 == 0); - assert(numRemovedHalfNonLearnt % 2 == 0); - solver.clauses_literals -= numRemovedHalfNonLearnt; - solver.learnts_literals -= numRemovedHalfLearnt; - solver.numBins -= (numRemovedHalfLearnt + numRemovedHalfNonLearnt)/2; - - lastNumUnitarySat[binaryClauses] = solver.get_unitary_learnts_num(); -} - -void ClauseCleaner::cleanClauses(vec<Clause*>& cs, ClauseSetType type, const uint32_t limit) -{ - assert(solver.decisionLevel() == 0); - assert(solver.qhead == solver.trail.size()); - - if (lastNumUnitaryClean[type] + limit >= solver.get_unitary_learnts_num()) - return; - - #ifdef VERBOSE_DEBUG - std::cout << "Cleaning " << (type==binaryClauses ? "binaryClauses" : "normal clauses" ) << std::endl; - #endif //VERBOSE_DEBUG - - Clause **s, **ss, **end; - for (s = ss = cs.getData(), end = s + cs.size(); s != end; s++) { - if (s+1 != end) __builtin_prefetch(*(s+1)); - - if (cleanClause(*s)) { - solver.clauseAllocator.clauseFree(*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 bool ClauseCleaner::cleanClause(Clause*& cc) -{ - Clause& c = *cc; - - Lit origLit1 = c[0]; - Lit origLit2 = c[1]; - uint32_t origSize = c.size(); - Lit origLit3 = (origSize == 3) ? c[2] : lit_Undef; - - 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) { - solver.detachModifiedClause(origLit1, origLit2, origLit3, origSize, &c); - return true; - } - } - c.shrink(i-j); - - assert(c.size() != 1); - if (i != j) { - if (c.size() == 2) { - solver.detachModifiedClause(origLit1, origLit2, origLit3, origSize, &c); - solver.attachBinClause(c[0], c[1], c.learnt()); - solver.numNewBin++; - solver.dataSync->signalNewBinClause(c); - return true; - } else if (c.size() == 3) { - solver.detachModifiedClause(origLit1, origLit2, origLit3, origSize, &c); - solver.attachClause(c); - } else { - if (c.learnt()) - solver.learnts_literals -= i-j; - else - solver.clauses_literals -= i-j; - } - } - - return false; -} - -void ClauseCleaner::cleanClauses(vec<XorClause*>& cs, ClauseSetType type, const uint32_t limit) -{ - assert(solver.decisionLevel() == 0); - 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; s++) { - if (s+1 != end) - __builtin_prefetch(*(s+1), 1, 0); - - #ifdef DEBUG_ATTACH_FULL - XorClause& c = **s; - assert(solver.xorClauseIsAttached(c)); - if (solver.assigns[c[0].var()]!=l_Undef || solver.assigns[c[1].var()]!=l_Undef) { - satisfied(**s); - } - #endif //DEBUG_ATTACH - - if (cleanClause(**s)) { - //solver.clauseAllocator.clauseFree(*s); - solver.freeLater.push(*s); - (*s)->setRemoved(); - } else { - #ifdef DEBUG_ATTACH_FULL - assert(solver.xorClauseIsAttached(c)); - #endif //DEBUG_ATTACH - *ss++ = *s; - } - } - cs.shrink(s-ss); - - lastNumUnitaryClean[type] = solver.get_unitary_learnts_num(); - - #ifdef VERBOSE_DEBUG - cout << "cleanClauses(XorClause) useful: ?? Removed: " << s-ss << endl; - #endif -} - -inline 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); - - assert(c.size() != 1); - switch (c.size()) { - case 0: { - solver.detachModifiedClause(origVar1, origVar2, origSize, &c); - return true; - } - case 2: { - c[0] = c[0].unsign(); - c[1] = c[1].unsign(); - solver.varReplacer->replace(c, c.xorEqualFalse()); - solver.detachModifiedClause(origVar1, origVar2, origSize, &c); - return true; - } - default: { - if (i-j > 0) { - solver.clauses_literals -= i-j; - } - return false; - } - } - - assert(false); - return false; -} - -bool ClauseCleaner::satisfied(const Clause& c) const -{ - for (uint32_t i = 0; i != c.size(); i++) - if (solver.value(c[i]) == l_True) - return true; - return false; -} - -bool ClauseCleaner::satisfied(const XorClause& c) const -{ - bool final = c.xorEqualFalse(); - for (uint32_t k = 0; k != c.size(); k++ ) { - const lbool& val = solver.assigns[c[k].var()]; - if (val.isUndef()) return false; - final ^= val.getBool(); - } - return final; -} diff --git a/src/prop/cryptominisat/Solver/ClauseCleaner.h b/src/prop/cryptominisat/Solver/ClauseCleaner.h deleted file mode 100644 index 11886e430..000000000 --- a/src/prop/cryptominisat/Solver/ClauseCleaner.h +++ /dev/null @@ -1,86 +0,0 @@ -/*********************************************************************************** -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 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 CMSat { - -/** -@brief Cleans clauses from false literals & removes satisfied clauses -*/ -class ClauseCleaner -{ - public: - ClauseCleaner(Solver& solver); - - enum ClauseSetType {clauses, binaryClauses, xorclauses, learnts}; - - void cleanClauses(vec<Clause*>& cs, ClauseSetType type, const uint32_t limit = 0); - - void cleanClauses(vec<XorClause*>& cs, ClauseSetType type, const uint32_t limit = 0); - void removeSatisfiedBins(const uint32_t limit = 0); - //void removeSatisfied(vec<Clause*>& cs, ClauseSetType type, const uint32_t limit = 0); - //void removeSatisfied(vec<XorClause*>& cs, ClauseSetType type, const uint32_t limit = 0); - void removeAndCleanAll(const bool nolimit = false); - bool satisfied(const Clause& c) const; - bool satisfied(const XorClause& c) const; - - private: - bool satisfied(const Watched& watched, Lit lit); - bool cleanClause(XorClause& c); - bool cleanClause(Clause*& c); - - uint32_t lastNumUnitarySat[6]; ///<Last time we cleaned from satisfied clauses, this many unitary clauses were known - uint32_t lastNumUnitaryClean[6]; ///<Last time we cleaned from satisfied clauses&false literals, this many unitary clauses were known - - Solver& solver; -}; - -/** -@brief Removes all satisfied clauses, and cleans false literals - -There is a heuristic in place not to try to clean all the time. However, -this limit can be overridden with "nolimit" -@p nolimit set this to force cleaning&removing. Useful if a really clean -state is needed, which is important for certain algorithms -*/ -inline void ClauseCleaner::removeAndCleanAll(const bool nolimit) -{ - //uint32_t limit = std::min((uint32_t)((double)solver.order_heap.size() * PERCENTAGECLEANCLAUSES), FIXCLEANREPLACE); - uint32_t limit = (double)solver.order_heap.size() * PERCENTAGECLEANCLAUSES; - if (nolimit) limit = 0; - - removeSatisfiedBins(limit); - cleanClauses(solver.clauses, ClauseCleaner::clauses, limit); - cleanClauses(solver.xorclauses, ClauseCleaner::xorclauses, limit); - cleanClauses(solver.learnts, ClauseCleaner::learnts, limit); -} - -} - -#endif //CLAUSECLEANER_H diff --git a/src/prop/cryptominisat/Solver/ClauseOffset.h b/src/prop/cryptominisat/Solver/ClauseOffset.h deleted file mode 100644 index 352cda45e..000000000 --- a/src/prop/cryptominisat/Solver/ClauseOffset.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef CLAUSEOFFSET_H -#define CLAUSEOFFSET_H - -#ifdef _MSC_VER -#include <msvc/stdint.h> -#else -#include <stdint.h> -#endif //_MSC_VER - -namespace CMSat { - -typedef uint32_t ClauseOffset; - -} - -#endif //CLAUSEOFFSET_H diff --git a/src/prop/cryptominisat/Solver/ClauseVivifier.cpp b/src/prop/cryptominisat/Solver/ClauseVivifier.cpp deleted file mode 100644 index ebe745f10..000000000 --- a/src/prop/cryptominisat/Solver/ClauseVivifier.cpp +++ /dev/null @@ -1,342 +0,0 @@ -/************************************************************************** -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 "ClauseVivifier.h" -#include "ClauseCleaner.h" -#include "time_mem.h" -#include <iomanip> - -//#define ASSYM_DEBUG - -using namespace CMSat; - -ClauseVivifier::ClauseVivifier(Solver& _solver) : - lastTimeWentUntil(0) - , numCalls(0) - , solver(_solver) -{} - - -/** -@brief Performs clause vivification (by Hamadi et al.) - -This is the only thing that does not fit under the aegis of tryBoth(), since -it is not part of failed literal probing, really. However, it is here because -it seems to be a function that fits into the idology of failed literal probing. -Maybe I am off-course and it should be in another class, or a class of its own. -*/ -bool ClauseVivifier::vivifyClauses() -{ - assert(solver.ok); - #ifdef VERBOSE_DEBUG - std::cout << "c clauseVivifier started" << std::endl; - //solver.printAllClauses(); - #endif //VERBOSE_DEBUG - - - solver.clauseCleaner->cleanClauses(solver.clauses, ClauseCleaner::clauses); - numCalls++; - - if (solver.ok) { - if (!vivifyClauses2(solver.clauses)) return false; - if (!vivifyClauses2(solver.learnts)) return false; - } - - bool failed; - uint32_t effective = 0; - uint32_t effectiveLit = 0; - double myTime = cpuTime(); - uint64_t maxNumProps = 20*1000*1000; - if (solver.clauses_literals + solver.learnts_literals < 500000) - maxNumProps *=2; - uint64_t extraDiff = 0; - uint64_t oldProps = solver.propagations; - bool needToFinish = false; - uint32_t checkedClauses = 0; - uint32_t potentialClauses = solver.clauses.size(); - if (lastTimeWentUntil + 500 > solver.clauses.size()) - lastTimeWentUntil = 0; - uint32_t thisTimeWentUntil = 0; - vec<Lit> lits; - vec<Lit> unused; - - if (solver.clauses.size() < 1000000) { - //if too many clauses, random order will do perfectly well - std::sort(solver.clauses.getData(), solver.clauses.getDataEnd(), sortBySize()); - } - - uint32_t queueByBy = 2; - if (numCalls > 8 - && (solver.clauses_literals + solver.learnts_literals < 4000000) - && (solver.clauses.size() < 50000)) - queueByBy = 1; - - Clause **i, **j; - i = j = solver.clauses.getData(); - for (Clause **end = solver.clauses.getDataEnd(); i != end; i++) { - if (needToFinish || lastTimeWentUntil > 0) { - if (!needToFinish) { - lastTimeWentUntil--; - thisTimeWentUntil++; - } - *j++ = *i; - continue; - } - - //if done enough, stop doing it - if (solver.propagations-oldProps + extraDiff > maxNumProps) { - //std::cout << "Need to finish -- ran out of prop" << std::endl; - needToFinish = true; - } - - //if bad performance, stop doing it - /*if ((i-solver.clauses.getData() > 5000 && effectiveLit < 300)) { - std::cout << "Need to finish -- not effective" << std::endl; - needToFinish = true; - }*/ - - Clause& c = **i; - extraDiff += c.size(); - checkedClauses++; - thisTimeWentUntil++; - - assert(c.size() > 2); - assert(!c.learnt()); - - unused.clear(); - lits.clear(); - lits.growTo(c.size()); - memcpy(lits.getData(), c.getData(), c.size() * sizeof(Lit)); - - failed = false; - uint32_t done = 0; - solver.newDecisionLevel(); - for (; done < lits.size();) { - uint32_t i2 = 0; - for (; (i2 < queueByBy) && ((done+i2) < lits.size()); i2++) { - lbool val = solver.value(lits[done+i2]); - if (val == l_Undef) { - solver.uncheckedEnqueueLight(~lits[done+i2]); - } else if (val == l_False) { - unused.push(lits[done+i2]); - } - } - done += i2; - failed = (!solver.propagate<false>(false).isNULL()); - if (numCalls > 3 && failed) break; - } - solver.cancelUntilLight(); - assert(solver.ok); - - if (unused.size() > 0 || (failed && done < lits.size())) { - effective++; - uint32_t origSize = lits.size(); - #ifdef ASSYM_DEBUG - std::cout << "Assym branch effective." << std::endl; - std::cout << "-- Orig clause:"; c.plainPrint(); - #endif - solver.detachClause(c); - - lits.shrink(lits.size() - done); - for (uint32_t i2 = 0; i2 < unused.size(); i2++) { - remove(lits, unused[i2]); - } - - Clause *c2 = solver.addClauseInt(lits); - #ifdef ASSYM_DEBUG - std::cout << "-- Origsize:" << origSize << " newSize:" << (c2 == NULL ? 0 : c2->size()) << " toRemove:" << c.size() - done << " unused.size():" << unused.size() << std::endl; - #endif - extraDiff += 20; - //TODO cheating here: we don't detect a NULL return that is in fact a 2-long clause - effectiveLit += origSize - (c2 == NULL ? 0 : c2->size()); - solver.clauseAllocator.clauseFree(&c); - - if (c2 != NULL) { - #ifdef ASSYM_DEBUG - std::cout << "-- New clause:"; c2->plainPrint(); - #endif - *j++ = c2; - } - - if (!solver.ok) needToFinish = true; - } else { - *j++ = *i; - } - } - solver.clauses.shrink(i-j); - - lastTimeWentUntil = thisTimeWentUntil; - - if (solver.conf.verbosity >= 1) { - std::cout << "c asymm " - << " cl-useful: " << effective << "/" << checkedClauses << "/" << potentialClauses - << " lits-rem:" << effectiveLit - << " time: " << cpuTime() - myTime - << std::endl; - } - - return solver.ok; -} - - -bool ClauseVivifier::vivifyClauses2(vec<Clause*>& clauses) -{ - assert(solver.ok); - - vec<char> seen; - seen.growTo(solver.nVars()*2, 0); - vec<char> seen_subs; - seen_subs.growTo(solver.nVars()*2, 0); - - uint32_t litsRem = 0; - uint32_t clShrinked = 0; - uint64_t countTime = 0; - uint64_t maxCountTime = 800*1000*1000; - maxCountTime *= 6; - if (solver.clauses_literals + solver.learnts_literals < 500000) - maxCountTime *= 2; - uint32_t clTried = 0; - vec<Lit> lits; - bool needToFinish = false; - double myTime = cpuTime(); - uint32_t subsumed_tri_num = 0; - uint32_t subsumed_bin_num = 0; - - Clause** i = clauses.getData(); - Clause** j = i; - for (Clause** end = clauses.getDataEnd(); i != end; i++) { - if (needToFinish) { - *j++ = *i; - continue; - } - if (countTime > maxCountTime) - needToFinish = true; - - Clause& cl = **i; - countTime += cl.size()*2; - clTried++; - - bool subsumed = false; - const bool learnt = cl.learnt(); - for (uint32_t i2 = 0; i2 < cl.size(); i2++) { - seen[cl[i2].toInt()] = 1; //for strengthening - seen_subs[cl[i2].toInt()] = 1; //for subsumption - } - - for (const Lit *l = cl.getData(), *end = cl.getDataEnd(); l != end; l++) { - const Lit *l_other = l; - l_other++; - if (l_other != end) - __builtin_prefetch(solver.watches[(~*l_other).toInt()].getData()); - - const vec<Watched>& ws = solver.watches[(~*l).toInt()]; - countTime += ws.size()*2; - for(vec<Watched>::const_iterator it = ws.getData(), end = ws.getDataEnd(); it != end; it++) { - //Handle tri clause - if (it->isTriClause() && cl.size() > 3) - { - if (learnt //we cannot decide if TRI is learnt or not - && seen_subs[it->getOtherLit().toInt()] - && seen_subs[it->getOtherLit2().toInt()] - ) { - subsumed_tri_num++; - subsumed = true; - } - - if (seen[l->toInt()]) { //we may have removed it already - //one way - if (seen[(it->getOtherLit2()).toInt()]) - seen[(~it->getOtherLit()).toInt()] = 0; - - //other way - if (seen[(it->getOtherLit()).toInt()]) - seen[(~it->getOtherLit2()).toInt()] = 0; - } - } - - //Handle Binary clause - if (it->isBinary()) { - if (seen_subs[it->getOtherLit().toInt()]) - { - if (!learnt && it->getLearnt()) - makeNonLearntBin(*l, it->getOtherLit(), it->getLearnt()); - subsumed_bin_num++; - subsumed = true; - } - - if (seen[l->toInt()]) //we may have removed it already - seen[(~it->getOtherLit()).toInt()] = 0; - - } - } - - if (seen[l->toInt()] == 0) - continue; - - countTime += solver.transOTFCache[l->toInt()].lits.size(); - for (vector<Lit>::const_iterator it2 = solver.transOTFCache[l->toInt()].lits.begin() - , end2 = solver.transOTFCache[l->toInt()].lits.end(); it2 != end2; it2++) { - seen[(~(*it2)).toInt()] = 0; - } - } - - lits.clear(); - for (const Lit *it2 = cl.getData(), *end2 = cl.getDataEnd(); it2 != end2; it2++) { - if (seen[it2->toInt()]) lits.push(*it2); - else litsRem++; - seen[it2->toInt()] = 0; - seen_subs[it2->toInt()] = 0; - } - - if (subsumed) { - solver.removeClause(cl); - } else if (lits.size() < cl.size()) { - solver.detachClause(cl); - clShrinked++; - Clause* c2 = solver.addClauseInt(lits, cl.learnt(), cl.getGlue(), cl.getMiniSatAct()); - solver.clauseAllocator.clauseFree(&cl); - - if (c2 != NULL) *j++ = c2; - if (!solver.ok) needToFinish = true; - } else { - *j++ = *i; - } - } - - clauses.shrink(i-j); - - if (solver.conf.verbosity >= 1) { - std::cout << "c vivif2 -- " - << " cl tried " << std::setw(8) << clTried - << " cl rem " << std::setw(8) << (subsumed_bin_num + subsumed_tri_num) - << " cl shrink " << std::setw(8) << clShrinked - << " lits rem " << std::setw(10) << litsRem - << " time: " << cpuTime() - myTime - << std::endl; - } - - return solver.ok; -} - -void ClauseVivifier::makeNonLearntBin(const Lit lit1, const Lit lit2, const bool learnt) -{ - assert(learnt == true); - findWatchedOfBin(solver.watches, lit1 ,lit2, learnt).setLearnt(false); - findWatchedOfBin(solver.watches, lit2 ,lit1, learnt).setLearnt(false); - solver.learnts_literals -= 2; - solver.clauses_literals += 2; -} diff --git a/src/prop/cryptominisat/Solver/ClauseVivifier.h b/src/prop/cryptominisat/Solver/ClauseVivifier.h deleted file mode 100644 index 51a345e59..000000000 --- a/src/prop/cryptominisat/Solver/ClauseVivifier.h +++ /dev/null @@ -1,61 +0,0 @@ -/************************************************************************** -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 CLAUSEVIVIFIER_H -#define CLAUSEVIVIFIER_H - -#include "Solver.h" - -namespace CMSat { - -class ClauseVivifier { - public: - ClauseVivifier(Solver& solver); - bool vivifyClauses(); - bool vivifyClauses2(vec<Clause*>& clauses); - - private: - - /** - @brief Records data for asymmBranch() - - Clauses are ordered accurding to sze in asymmBranch() and then some are - checked if we could shorten them. This value records that between calls - to asymmBranch() where we stopped last time in the list - */ - uint32_t lastTimeWentUntil; - - /** - @brief Sort clauses according to size - */ - struct sortBySize - { - bool operator () (const Clause* x, const Clause* y) - { - return (x->size() > y->size()); - } - }; - - void makeNonLearntBin(const Lit lit1, const Lit lit2, const bool learnt); - - uint32_t numCalls; - Solver& solver; -}; - -} - -#endif //CLAUSEVIVIFIER_H diff --git a/src/prop/cryptominisat/Solver/CompleteDetachReattacher.cpp b/src/prop/cryptominisat/Solver/CompleteDetachReattacher.cpp deleted file mode 100644 index 833f13c63..000000000 --- a/src/prop/cryptominisat/Solver/CompleteDetachReattacher.cpp +++ /dev/null @@ -1,198 +0,0 @@ -/************************************************************************** -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 "CompleteDetachReattacher.h" -#include "VarReplacer.h" -#include "ClauseCleaner.h" - -using namespace CMSat; - -CompleteDetachReatacher::CompleteDetachReatacher(Solver& _solver) : - solver(_solver) -{ -} - -/** -@brief Completely detach all non-binary clauses -*/ -void CompleteDetachReatacher::detachNonBinsNonTris(const bool removeTri) -{ - uint32_t oldNumBins = solver.numBins; - ClausesStay stay; - - for (vec<Watched> *it = solver.watches.getData(), *end = solver.watches.getDataEnd(); it != end; it++) { - stay += clearWatchNotBinNotTri(*it, removeTri); - } - - solver.learnts_literals = stay.learntBins; - solver.clauses_literals = stay.nonLearntBins; - solver.numBins = (stay.learntBins + stay.nonLearntBins)/2; - release_assert(solver.numBins == oldNumBins); -} - -/** -@brief Helper function for detachPointerUsingClauses() -*/ -const CompleteDetachReatacher::ClausesStay CompleteDetachReatacher::clearWatchNotBinNotTri(vec<Watched>& ws, const bool removeTri) -{ - ClausesStay stay; - - vec<Watched>::iterator i = ws.getData(); - vec<Watched>::iterator j = i; - for (vec<Watched>::iterator end = ws.getDataEnd(); i != end; i++) { - if (i->isBinary()) { - if (i->getLearnt()) stay.learntBins++; - else stay.nonLearntBins++; - *j++ = *i; - } else if (!removeTri && i->isTriClause()) { - stay.tris++; - *j++ = *i; - } - } - ws.shrink_(i-j); - - return stay; -} - -/** -@brief Completely attach all clauses -*/ -bool CompleteDetachReatacher::reattachNonBins() -{ - assert(solver.ok); - - cleanAndAttachClauses(solver.clauses); - cleanAndAttachClauses(solver.learnts); - cleanAndAttachClauses(solver.xorclauses); - solver.clauseCleaner->removeSatisfiedBins(); - - if (solver.ok) solver.ok = (solver.propagate<false>().isNULL()); - - return solver.ok; -} - -/** -@brief Cleans clauses from failed literals/removes satisfied clauses from cs - -May change solver.ok to FALSE (!) -*/ -inline void CompleteDetachReatacher::cleanAndAttachClauses(vec<Clause*>& cs) -{ - Clause **i = cs.getData(); - Clause **j = i; - PolaritySorter sorter(solver.polarity); - for (Clause **end = cs.getDataEnd(); i != end; i++) { - std::sort((*i)->getData(), (*i)->getDataEnd(), sorter); - if (cleanClause(*i)) { - solver.attachClause(**i); - *j++ = *i; - } else { - solver.clauseAllocator.clauseFree(*i); - } - } - cs.shrink(i-j); -} - -/** -@brief Cleans clauses from failed literals/removes satisfied clauses from cs -*/ -inline void CompleteDetachReatacher::cleanAndAttachClauses(vec<XorClause*>& cs) -{ - XorClause **i = cs.getData(); - XorClause **j = i; - for (XorClause **end = cs.getDataEnd(); i != end; i++) { - if (cleanClause(**i)) { - solver.attachClause(**i); - *j++ = *i; - } else { - solver.clauseAllocator.clauseFree(*i); - } - } - cs.shrink(i-j); -} - -/** -@brief Not only cleans a clause from false literals, but if clause is satisfied, it reports it -*/ -inline bool CompleteDetachReatacher::cleanClause(Clause*& cl) -{ - Clause& ps = *cl; - assert(ps.size() > 2); - - 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); - - switch (ps.size()) { - case 0: - solver.ok = false; - return false; - case 1: - solver.uncheckedEnqueue(ps[0]); - return false; - - case 2: { - solver.attachBinClause(ps[0], ps[1], ps.learnt()); - return false; - } - - default:; - } - - return true; -} - -/** -@brief Not only cleans a clause from false literals, but if clause is satisfied, it reports it -*/ -inline bool CompleteDetachReatacher::cleanClause(XorClause& ps) -{ - 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); - - switch (ps.size()) { - case 0: - if (ps.xorEqualFalse() == false) solver.ok = false; - return false; - case 1: - solver.uncheckedEnqueue(Lit(ps[0].var(), ps.xorEqualFalse())); - return false; - - case 2: { - ps[0] = ps[0].unsign(); - ps[1] = ps[1].unsign(); - solver.varReplacer->replace(ps, ps.xorEqualFalse()); - return false; - } - - default:; - } - - return true; -} diff --git a/src/prop/cryptominisat/Solver/CompleteDetachReattacher.h b/src/prop/cryptominisat/Solver/CompleteDetachReattacher.h deleted file mode 100644 index 2d9dacfa0..000000000 --- a/src/prop/cryptominisat/Solver/CompleteDetachReattacher.h +++ /dev/null @@ -1,78 +0,0 @@ -/************************************************************************** -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 "Solver.h" - -namespace CMSat { - -/** -@brief Helper class to completely detaches all(or only non-native) clauses, and then re-attach all - -Used in classes that (may) do a lot of clause-changning, in which case -detaching&reattaching of clauses would be neccessary to do -individually, which is \b very slow - -A main use-case is the following: --# detach all clauses --# play around with all clauses as desired. Cannot call solver.propagate() here --# attach all clauses again - -A somewhat more complicated, but more interesting use-case is the following: --# detach only non-natively stored clauses from watchlists --# play around wil all clauses as desired. 2- and 3-long clauses can still -be propagated with solver.propagate() -- this is quite a nice trick, in fact --# detach all clauses (i.e. also native ones) --# attach all clauses -*/ -class CompleteDetachReatacher -{ - public: - CompleteDetachReatacher(Solver& solver); - bool reattachNonBins(); - void detachNonBinsNonTris(const bool removeTri); - - private: - class ClausesStay { - public: - ClausesStay() : - learntBins(0) - , nonLearntBins(0) - , tris(0) - {} - - ClausesStay& operator+=(const ClausesStay& other) { - learntBins += other.learntBins; - nonLearntBins += other.nonLearntBins; - tris += other.tris; - return *this; - } - - uint32_t learntBins; - uint32_t nonLearntBins; - uint32_t tris; - }; - const ClausesStay clearWatchNotBinNotTri(vec<Watched>& ws, const bool removeTri = false); - - void cleanAndAttachClauses(vec<Clause*>& cs); - void cleanAndAttachClauses(vec<XorClause*>& cs); - bool cleanClause(Clause*& ps); - bool cleanClause(XorClause& ps); - - Solver& solver; -}; - -} diff --git a/src/prop/cryptominisat/Solver/DataSync.cpp b/src/prop/cryptominisat/Solver/DataSync.cpp deleted file mode 100644 index 3e7956a19..000000000 --- a/src/prop/cryptominisat/Solver/DataSync.cpp +++ /dev/null @@ -1,216 +0,0 @@ -/***************************************************************************** -CryptoMiniSat -- Copyright (c) 2010 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 "DataSync.h" -#include "Subsumer.h" -#include "VarReplacer.h" -#include "XorSubsumer.h" -#include <iomanip> - -using namespace CMSat; - -DataSync::DataSync(Solver& _solver, SharedData* _sharedData) : - lastSyncConf(0) - , sentUnitData(0) - , recvUnitData(0) - , sharedData(_sharedData) - , solver(_solver) -{} - -void DataSync::newVar() -{ - syncFinish.push(0); - syncFinish.push(0); - seen.push(false); - seen.push(false); -} - -bool DataSync::syncData() -{ - if (sharedData == NULL - || lastSyncConf + SYNC_EVERY_CONFL >= solver.conflicts) return true; - - assert(sharedData != NULL); - assert(solver.decisionLevel() == 0); - - bool ok; - #pragma omp critical (unitData) - ok = shareUnitData(); - if (!ok) return false; - - #pragma omp critical (binData) - ok = shareBinData(); - if (!ok) return false; - - lastSyncConf = solver.conflicts; - - return true; -} - -bool DataSync::shareBinData() -{ - uint32_t oldRecvBinData = recvBinData; - uint32_t oldSentBinData = sentBinData; - - SharedData& shared = *sharedData; - if (shared.bins.size() != solver.nVars()*2) - shared.bins.resize(solver.nVars()*2); - - for (uint32_t wsLit = 0; wsLit < solver.nVars()*2; wsLit++) { - Lit lit1 = ~Lit::toLit(wsLit); - lit1 = solver.varReplacer->getReplaceTable()[lit1.var()] ^ lit1.sign(); - if (solver.subsumer->getVarElimed()[lit1.var()] - || solver.xorSubsumer->getVarElimed()[lit1.var()] - || solver.value(lit1.var()) != l_Undef - ) continue; - - vector<Lit>& bins = shared.bins[wsLit]; - vec<Watched>& ws = solver.watches[wsLit]; - - if (bins.size() > syncFinish[wsLit] - && !syncBinFromOthers(lit1, bins, syncFinish[wsLit], ws)) return false; - } - - syncBinToOthers(); - - if (solver.conf.verbosity >= 3) { - std::cout << "c got bins " << std::setw(10) << (recvBinData - oldRecvBinData) - << std::setw(10) << " sent bins " << (sentBinData - oldSentBinData) << std::endl; - } - - return true; -} - -bool DataSync::syncBinFromOthers(const Lit lit, const vector<Lit>& bins, uint32_t& finished, vec<Watched>& ws) -{ - assert(solver.varReplacer->getReplaceTable()[lit.var()].var() == lit.var()); - assert(solver.subsumer->getVarElimed()[lit.var()] == false); - assert(solver.xorSubsumer->getVarElimed()[lit.var()] == false); - - vec<Lit> addedToSeen; - for (vec<Watched>::iterator it = ws.getData(), end = ws.getDataEnd(); it != end; it++) { - if (it->isBinary()) { - addedToSeen.push(it->getOtherLit()); - seen[it->getOtherLit().toInt()] = true; - } - } - - vec<Lit> lits(2); - for (uint32_t i = finished; i < bins.size(); i++) { - if (!seen[bins[i].toInt()]) { - Lit otherLit = bins[i]; - otherLit = solver.varReplacer->getReplaceTable()[otherLit.var()] ^ otherLit.sign(); - if (solver.subsumer->getVarElimed()[otherLit.var()] - || solver.xorSubsumer->getVarElimed()[otherLit.var()] - || solver.value(otherLit.var()) != l_Undef - ) continue; - - recvBinData++; - lits[0] = lit; - lits[1] = otherLit; - solver.addClauseInt(lits, true, 2, 0, true); - lits.clear(); - lits.growTo(2); - if (!solver.ok) goto end; - } - } - finished = bins.size(); - - end: - for (uint32_t i = 0; i < addedToSeen.size(); i++) - seen[addedToSeen[i].toInt()] = false; - - return solver.ok; -} - -void DataSync::syncBinToOthers() -{ - for(vector<std::pair<Lit, Lit> >::const_iterator it = newBinClauses.begin(), end = newBinClauses.end(); it != end; it++) { - addOneBinToOthers(it->first, it->second); - } - - newBinClauses.clear(); -} - -void DataSync::addOneBinToOthers(const Lit lit1, const Lit lit2) -{ - assert(lit1.toInt() < lit2.toInt()); - - vector<Lit>& bins = sharedData->bins[(~lit1).toInt()]; - for (vector<Lit>::const_iterator it = bins.begin(), end = bins.end(); it != end; it++) { - if (*it == lit2) return; - } - - bins.push_back(lit2); - sentBinData++; -} - -bool DataSync::shareUnitData() -{ - uint32_t thisGotUnitData = 0; - uint32_t thisSentUnitData = 0; - - SharedData& shared = *sharedData; - shared.value.growTo(solver.nVars(), l_Undef); - for (uint32_t var = 0; var < solver.nVars(); var++) { - Lit thisLit = Lit(var, false); - thisLit = solver.varReplacer->getReplaceTable()[thisLit.var()] ^ thisLit.sign(); - const lbool thisVal = solver.value(thisLit); - const lbool otherVal = shared.value[var]; - - if (thisVal == l_Undef && otherVal == l_Undef) continue; - if (thisVal != l_Undef && otherVal != l_Undef) { - if (thisVal != otherVal) { - solver.ok = false; - return false; - } else { - continue; - } - } - - if (otherVal != l_Undef) { - assert(thisVal == l_Undef); - Lit litToEnqueue = thisLit ^ (otherVal == l_False); - if (solver.subsumer->getVarElimed()[litToEnqueue.var()] - || solver.xorSubsumer->getVarElimed()[litToEnqueue.var()] - ) continue; - - solver.uncheckedEnqueue(litToEnqueue); - solver.ok = solver.propagate<false>().isNULL(); - if (!solver.ok) return false; - thisGotUnitData++; - continue; - } - - if (thisVal != l_Undef) { - assert(otherVal == l_Undef); - shared.value[var] = thisVal; - thisSentUnitData++; - continue; - } - } - - if (solver.conf.verbosity >= 3 && (thisGotUnitData > 0 || thisSentUnitData > 0)) { - std::cout << "c got units " << std::setw(8) << thisGotUnitData - << " sent units " << std::setw(8) << thisSentUnitData << std::endl; - } - - recvUnitData += thisGotUnitData; - sentUnitData += thisSentUnitData; - - return true; -} diff --git a/src/prop/cryptominisat/Solver/DataSync.h b/src/prop/cryptominisat/Solver/DataSync.h deleted file mode 100644 index 96ac7a355..000000000 --- a/src/prop/cryptominisat/Solver/DataSync.h +++ /dev/null @@ -1,101 +0,0 @@ -/***************************************************************************** -CryptoMiniSat -- Copyright (c) 2010 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 "SharedData.h" -#include "Solver.h" - -namespace CMSat { - -class DataSync -{ - public: - DataSync(Solver& solver, SharedData* sharedData); - void newVar(); - bool syncData(); - - - template <class T> void signalNewBinClause(T& ps); - void signalNewBinClause(Lit lit1, Lit lit2); - - uint32_t getSentUnitData() const; - uint32_t getRecvUnitData() const; - uint32_t getSentBinData() const; - uint32_t getRecvBinData() const; - - private: - //functions - bool shareUnitData(); - bool syncBinFromOthers(const Lit lit, const vector<Lit>& bins, uint32_t& finished, vec<Watched>& ws); - void syncBinToOthers(); - void addOneBinToOthers(const Lit lit1, const Lit lit2); - bool shareBinData(); - - //stuff to sync - vector<std::pair<Lit, Lit> > newBinClauses; - - //stats - uint64_t lastSyncConf; - vec<uint32_t> syncFinish; - uint32_t sentUnitData; - uint32_t recvUnitData; - uint32_t sentBinData; - uint32_t recvBinData; - - //misc - vec<char> seen; - - //main data - SharedData* sharedData; - Solver& solver; -}; - -inline uint32_t DataSync::getSentUnitData() const -{ - return sentUnitData; -} - -inline uint32_t DataSync::getRecvUnitData() const -{ - return recvUnitData; -} - -inline uint32_t DataSync::getSentBinData() const -{ - return sentBinData; -} - -inline uint32_t DataSync::getRecvBinData() const -{ - return recvBinData; -} - -template <class T> -inline void DataSync::signalNewBinClause(T& ps) -{ - if (sharedData == NULL) return; - assert(ps.size() == 2); - signalNewBinClause(ps[0], ps[1]); -} - -inline void DataSync::signalNewBinClause(Lit lit1, Lit lit2) -{ - if (sharedData == NULL) return; - if (lit1.toInt() > lit2.toInt()) std::swap(lit1, lit2); - newBinClauses.push_back(std::make_pair(lit1, lit2)); -} - -} diff --git a/src/prop/cryptominisat/Solver/DimacsParser.cpp b/src/prop/cryptominisat/Solver/DimacsParser.cpp deleted file mode 100644 index 0fc4d9d74..000000000 --- a/src/prop/cryptominisat/Solver/DimacsParser.cpp +++ /dev/null @@ -1,490 +0,0 @@ -/***************************************************************************** -MiniSat -- Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson -CryptoMiniSat -- Copyright (c) 2009 Mate Soos - -Original code by MiniSat authors are under an MIT licence. -Modifications for CryptoMiniSat are under GPLv3 licence. -******************************************************************************/ - -#include "DimacsParser.h" -#include <sstream> -#include <iostream> -#include <iomanip> - -#include "Solver.h" - -#ifdef VERBOSE_DEBUG -#define DEBUG_COMMENT_PARSING -#endif //VERBOSE_DEBUG - -//#define DEBUG_COMMENT_PARSING - -using namespace CMSat; - -DimacsParseError::DimacsParseError(const std::string& arg) - : std::runtime_error(arg) { } - -DimacsParseError::~DimacsParseError() throw() { } - -DimacsParser::DimacsParser(Solver* _solver, const bool _debugLib, const bool _debugNewVar, const bool _grouping, const bool _addAsLearnt): - solver(_solver) - , debugLib(_debugLib) - , debugNewVar(_debugNewVar) - , grouping(_grouping) - , addAsLearnt(_addAsLearnt) -{} - -/** -@brief Skips all whitespaces -*/ -void DimacsParser::skipWhitespace(StreamBuffer& in) -{ - while ((*in >= 9 && *in <= 13 && *in != 10) || *in == 32) - ++in; -} - -/** -@brief Skips until the end of the line -*/ -void DimacsParser::skipLine(StreamBuffer& in) -{ - for (;;) { - if (*in == EOF || *in == '\0') return; - if (*in == '\n') { - ++in; - return; - } - ++in; - } -} - -/** -@brief Returns line until the end of line -*/ -std::string DimacsParser::untilEnd(StreamBuffer& in) -{ - std::string ret; - - while(*in != EOF && *in != '\0' && *in != '\n') { - ret += *in; - ++in; - } - - return ret; -} - -/** -@brief Parses in an integer -*/ -int32_t DimacsParser::parseInt(StreamBuffer& in, uint32_t& lenParsed) throw (DimacsParseError) -{ - lenParsed = 0; - int32_t val = 0; - bool neg = false; - skipWhitespace(in); - if (*in == '-') neg = true, ++in; - else if (*in == '+') ++in; - if (*in < '0' || *in > '9') { - std::ostringstream ostr; - ostr << "Unexpected char (parseInt): " << *in; - throw DimacsParseError(ostr.str()); - } - while (*in >= '0' && *in <= '9') { - lenParsed++; - val = val*10 + (*in - '0'), - ++in; - } - return neg ? -val : val; -} - -float DimacsParser::parseFloat(StreamBuffer& in) throw (DimacsParseError) -{ - uint32_t len; - uint32_t main = parseInt(in, len); - if (*in != '.') { - std::ostringstream ostr; - ostr << "Float does not contain a dot! Instead it contains: " << *in; - throw DimacsParseError(ostr.str()); - } - ++in; - uint32_t sub = parseInt(in, len); - - uint32_t exp = 1; - for (uint32_t i = 0;i < len; i++) exp *= 10; - return (float)main + ((float)sub/exp); -} - - -std::string DimacsParser::stringify(uint32_t x) -{ - std::ostringstream o; - o << x; - return o.str(); -} - -/** -@brief Parse a continious set of characters from "in" to "str". - -\todo EOF is not checked for!! -*/ -void DimacsParser::parseString(StreamBuffer& in, std::string& str) -{ - str.clear(); - skipWhitespace(in); - while (*in != ' ' && *in != '\n') { - str += *in; - ++in; - } -} - -/** -@brief Reads in a clause and puts it in lit -@p[out] lits -*/ -void DimacsParser::readClause(StreamBuffer& in, vec<Lit>& lits) throw (DimacsParseError) -{ - int32_t parsed_lit; - Var var; - uint32_t len; - lits.clear(); - for (;;) { - parsed_lit = parseInt(in, len); - if (parsed_lit == 0) break; - var = abs(parsed_lit)-1; - if (!debugNewVar) { - if (var >= ((uint32_t)1)<<25) { - std::ostringstream ostr; - ostr << "Variable requested is far too large: " << var; - throw DimacsParseError(ostr.str()); - } - while (var >= solver->nVars()) solver->newVar(); - } - lits.push( (parsed_lit > 0) ? Lit(var, false) : Lit(var, true) ); - } -} - -/** -@brief Matches parameter "str" to content in "in" -*/ -bool DimacsParser::match(StreamBuffer& in, const char* str) -{ - for (; *str != 0; ++str, ++in) - if (*str != *in) - return false; - return true; -} - -/** -@brief Prints the data in "p cnf VARS CLAUSES" header in DIMACS - -We don't actually do \b anything with these. It's just printed for user -happyness. However, I think it's useless to print it, since it might mislead -users to think that their headers are correct, even though a lot of headers are -completely wrong, thanks to MiniSat printing the header, but not checking it. -Not checking it is \b not a problem. The problem is printing it such that -people believe it's validated -*/ -void DimacsParser::printHeader(StreamBuffer& in) throw (DimacsParseError) -{ - uint32_t len; - - if (match(in, "p cnf")) { - int vars = parseInt(in, len); - int clauses = parseInt(in, len); - if (solver->conf.verbosity >= 1) { - std::cout << "c -- header says num vars: " << std::setw(12) << vars << std::endl; - std::cout << "c -- header says num clauses:" << std::setw(12) << clauses << std::endl; - } - } else { - std::ostringstream ostr; - ostr << "Unexpected char: " << *in; - throw DimacsParseError(ostr.str()); - } -} - -/** -@brief Parse up comment lines which could contain important information - -In CryptoMiniSat we save quite a bit of information in the comment lines. -These need to be parsed up. This function achieves that. Informations that -can be given: -\li "c Solver::newVar() called" -- we execute Solver::newVar() -\li "c Solver::solve() called" -- we execute Solver::solve() and dump the -solution to debugLibPartX.out, where X is a number that starts with 1 and -increases to N, where N is the number of solve() instructions -\li variable names in the form of "c var VARNUM NAME" -*/ -void DimacsParser::parseComments(StreamBuffer& in, const std::string str) throw (DimacsParseError) -{ - uint32_t len; - #ifdef DEBUG_COMMENT_PARSING - std::cout << "Parsing comments" << std::endl; - #endif //DEBUG_COMMENT_PARSING - - if (str == "v" || str == "var") { - int var = parseInt(in, len); - skipWhitespace(in); - if (var <= 0) - throw DimacsParseError("Var number must be a positive integer"); - std::string name = untilEnd(in); - //Don't do anythint with NAME, just forget it - - #ifdef DEBUG_COMMENT_PARSING - std::cout << "Parsed 'c var'" << std::endl; - #endif //DEBUG_COMMENT_PARSING - } else if (debugLib && str == "Solver::solve()") { - lbool ret = solver->solve(); - std::string s = "debugLibPart" + stringify(debugLibPart) +".output"; - FILE* res = fopen(s.c_str(), "w"); - if (ret == l_True) { - fprintf(res, "SAT\n"); - for (Var i = 0; i != solver->nVars(); i++) { - if (solver->model[i] != l_Undef) - fprintf(res, "%s%d ", (solver->model[i]==l_True)?"":"-", i+1); - } - fprintf(res, "0\n"); - } else if (ret == l_False) { - fprintf(res, "UNSAT\n"); - } else if (ret == l_Undef) { - assert(false); - } else { - assert(false); - } - fclose(res); - debugLibPart++; - - #ifdef DEBUG_COMMENT_PARSING - std::cout << "Parsed Solver::solve()" << std::endl; - #endif //DEBUG_COMMENT_PARSING - } else if (debugNewVar && str == "Solver::newVar()") { - solver->newVar(); - - #ifdef DEBUG_COMMENT_PARSING - std::cout << "Parsed Solver::newVar()" << std::endl; - #endif //DEBUG_COMMENT_PARSING - } else { - #ifdef DEBUG_COMMENT_PARSING - std::cout << "didn't understand in CNF file: 'c " << str << std::endl; - #endif //DEBUG_COMMENT_PARSING - } - skipLine(in); -} - -/** -@brief Parses clause parameters given as e.g. "c clause learnt yes glue 4 miniSatAct 5.2" -*/ -void DimacsParser::parseClauseParameters(StreamBuffer& in, bool& learnt, uint32_t& glue, float& miniSatAct) -{ - std::string str; - uint32_t len; - - //Parse in if we are a learnt clause or not - ++in; - parseString(in, str); - if (str != "learnt") goto addTheClause; - - ++in; - parseString(in, str); - if (str == "yes") learnt = true; - else if (str == "no") { - learnt = false; - goto addTheClause; - } - else { - std::cout << "parsed in instead of yes/no: '" << str << "'" << std::endl; - goto addTheClause; - } - - //Parse in Glue value - ++in; - parseString(in, str); - if (str != "glue") goto addTheClause; - ++in; - glue = parseInt(in, len); - - //Parse in MiniSat activity - ++in; - parseString(in, str); - if (str != "miniSatAct") goto addTheClause; - ++in; - miniSatAct = parseFloat(in); - - addTheClause: - skipLine(in); - return; -} - -/** -@brief Parses in a clause and its optional attributes - -We might have lines like: -\li "c clause learnt yes glue 4 miniSatAct 5.2" which we need to parse up and -make the clause learnt. -\li Also, groupings can be given with "c group NUM NAME" after the clause. -\li Furthermore, we need to take care, since comments might mean orders like -"c Solver::newVar() called", which needs to be parsed with parseComments() --- this, we delegate -*/ -void DimacsParser::readFullClause(StreamBuffer& in) throw (DimacsParseError) -{ - bool xor_clause = false; - bool learnt = false; - uint32_t glue = 100.0; - float miniSatAct = 10.0; - std::string name; - std::string str; - uint32_t len; - bool needToParseComments = false; - - //read in the actual clause - if ( *in == 'x') xor_clause = true, ++in; - readClause(in, lits); - skipLine(in); - - //now read in grouping information, etc. - if (grouping) { - if (*in != 'c') - throw DimacsParseError("Group must be present after each clause ('c' missing after clause line)"); - ++in; - - parseString(in, str); - if (str != "g" && str != "group") { - std::ostringstream ostr; - ostr << "Group must be present after each clause('group' missing)!" << std:: endl - << "Instead of 'group' there was: " << str; - throw DimacsParseError(ostr.str()); - } - - int groupId = parseInt(in, len); - groupId++; - //Don't do anything with grupId - - skipWhitespace(in); - name = untilEnd(in); - } - - //Parse comments or parse clause type (learnt, glue value, etc.) - if (*in == 'c') { - ++in; - parseString(in, str); - if (str == "clause") { - parseClauseParameters(in, learnt, glue, miniSatAct); - } else { - needToParseComments = true; - } - } - - if (xor_clause) { - bool xorEqualFalse = false; - for (uint32_t i = 0; i < lits.size(); i++) - xorEqualFalse ^= lits[i].sign(); - - solver->addXorClause(lits, xorEqualFalse); - numXorClauses++; - } else { - if (addAsLearnt || learnt) { - solver->addLearntClause(lits, glue, miniSatAct); - numLearntClauses++; - } else { - solver->addClause(lits); - numNormClauses++; - } - } - - if (needToParseComments) { - #ifdef DEBUG_COMMENT_PARSING - std::cout << "Need to parse comments:" << str << std::endl; - #endif //DEBUG_COMMENT_PARSING - parseComments(in, str); - } -} - -void DimacsParser::readBranchingOrder(StreamBuffer& in) -{ - skipWhitespace(in); - - while (1) { - int parsed_var; - uint32_t len; - - parsed_var = parseInt(in, len); - if (parsed_var == 0) - break; - - solver->addBranchingVariable(parsed_var - 1); - } -} - -/** -@brief The main function: parses in a full DIMACS file - -Parses in header, the clauses, and special comment lines that define clause -groups, clause group names, and variable names, plus it parses up special -comments that have to do with debugging Solver::newVar() and Solver::solve() -calls for library-debugging -*/ -void DimacsParser::parse_DIMACS_main(StreamBuffer& in) -{ - std::string str; - - for (;;) { - skipWhitespace(in); - switch (*in) { - case EOF: - return; - case 'p': - printHeader(in); - skipLine(in); - break; - case 'c': - ++in; - parseString(in, str); - parseComments(in, str); - break; - case 'b': - ++in; - readBranchingOrder(in); - break; - case '\n': - //Skipping empty line, even though empty lines are kind of out-of-spec - ++in; - break; - default: - readFullClause(in); - if (!solver->okay()) return; - break; - } - } -} - -template <class T> -void DimacsParser::parse_DIMACS(T input_stream) -{ - debugLibPart = 1; - numLearntClauses = 0; - numNormClauses = 0; - numXorClauses = 0; - uint32_t origNumVars = solver->nVars(); - - StreamBuffer in(input_stream); - parse_DIMACS_main(in); - - if (solver->conf.verbosity >= 1) { - std::cout << "c -- clauses added: " - << std::setw(12) << numLearntClauses - << " learnts, " - << std::setw(12) << numNormClauses - << " normals, " - << std::setw(12) << numXorClauses - << " xors" - << std::endl; - - std::cout << "c -- vars added " << std::setw(10) << (solver->nVars() - origNumVars) - << std::endl; - } -} - -#ifndef DISABLE_ZLIB -template void DimacsParser::parse_DIMACS(gzFile input_stream); -#endif -template void DimacsParser::parse_DIMACS(FILE* input_stream); diff --git a/src/prop/cryptominisat/Solver/DimacsParser.h b/src/prop/cryptominisat/Solver/DimacsParser.h deleted file mode 100644 index c149214ba..000000000 --- a/src/prop/cryptominisat/Solver/DimacsParser.h +++ /dev/null @@ -1,84 +0,0 @@ -/***************************************************************************** -MiniSat -- Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson -CryptoMiniSat -- Copyright (c) 2009 Mate Soos - -Original code by MiniSat authors are under an MIT licence. -Modifications for CryptoMiniSat are under GPLv3 licence. -******************************************************************************/ - -#ifndef DIMACSPARSER_H -#define DIMACSPARSER_H - -#include <stdexcept> -#include <string> -#include "SolverTypes.h" -#include "constants.h" -#include "StreamBuffer.h" -#include "Vec.h" - -#ifdef _MSC_VER -#include <msvc/stdint.h> -#else -#include <stdint.h> -#endif //_MSC_VER - -#ifndef DISABLE_ZLIB -#include <zlib.h> -#endif // DISABLE_ZLIB - -namespace CMSat { - -class Solver; - -class DimacsParseError : public std::runtime_error -{ - public: - explicit DimacsParseError(const std::string& arg); - virtual ~DimacsParseError() throw(); -}; - -/** -@brief Parses up a DIMACS file that my be zipped -*/ -class DimacsParser -{ - public: - DimacsParser(Solver* solver, const bool debugLib, const bool debugNewVar, const bool grouping, const bool addAsLearnt = false); - - template <class T> - void parse_DIMACS(T input_stream); - - private: - void parse_DIMACS_main(StreamBuffer& in); - void skipWhitespace(StreamBuffer& in); - void skipLine(StreamBuffer& in); - std::string untilEnd(StreamBuffer& in); - int32_t parseInt(StreamBuffer& in, uint32_t& len) throw (DimacsParseError); - float parseFloat(StreamBuffer& in) throw (DimacsParseError); - void parseString(StreamBuffer& in, std::string& str); - void readClause(StreamBuffer& in, vec<Lit>& lits) throw (DimacsParseError); - void parseClauseParameters(StreamBuffer& in, bool& learnt, uint32_t& glue, float& miniSatAct); - void readFullClause(StreamBuffer& in) throw (DimacsParseError); - void readBranchingOrder(StreamBuffer& in); - bool match(StreamBuffer& in, const char* str); - void printHeader(StreamBuffer& in) throw (DimacsParseError); - void parseComments(StreamBuffer& in, const std::string str) throw (DimacsParseError); - std::string stringify(uint32_t x); - - - Solver *solver; - const bool debugLib; - const bool debugNewVar; - const bool grouping; - const bool addAsLearnt; - - uint32_t debugLibPart; ///<printing partial solutions to debugLibPart1..N.output when "debugLib" is set to TRUE - vec<Lit> lits; ///<To reduce temporary creation overhead - uint32_t numLearntClauses; ///<Number of learnt non-xor clauses added - uint32_t numNormClauses; ///<Number of non-learnt, non-xor claues added - uint32_t numXorClauses; ///<Number of non-learnt xor clauses added -}; - -} - -#endif //DIMACSPARSER_H diff --git a/src/prop/cryptominisat/Solver/DoublePackedRow.h b/src/prop/cryptominisat/Solver/DoublePackedRow.h deleted file mode 100644 index cbeee2f71..000000000 --- a/src/prop/cryptominisat/Solver/DoublePackedRow.h +++ /dev/null @@ -1,173 +0,0 @@ -/*********************************************************************************** -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 CMSat -{ -using namespace CMSat; - -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/prop/cryptominisat/Solver/FailedLitSearcher.cpp b/src/prop/cryptominisat/Solver/FailedLitSearcher.cpp deleted file mode 100644 index a847c5e09..000000000 --- a/src/prop/cryptominisat/Solver/FailedLitSearcher.cpp +++ /dev/null @@ -1,768 +0,0 @@ -/************************************************************************** -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 "FailedLitSearcher.h" - -#include <iomanip> -#include <utility> -#include <set> - -#include "Solver.h" -#include "ClauseCleaner.h" -#include "time_mem.h" -#include "VarReplacer.h" -#include "ClauseCleaner.h" -#include "StateSaver.h" -#include "CompleteDetachReattacher.h" - -//#define VERBOSE_DEUBUG - -using namespace CMSat; -using std::make_pair; -using std::set; - -/** -@brief Sets up variables that are used between calls to search() -*/ -FailedLitSearcher::FailedLitSearcher(Solver& _solver): - solver(_solver) - , tmpPs(2) - , totalTime(0) - , numPropsMultiplier(1.0) - , lastTimeFoundTruths(0) - , numCalls(0) -{ - lastTimeStopped = solver.mtrand.randInt(solver.nVars()); -} - -/** -@brief Initialises datastructures for 2-long xor finding by shortening longer xors -*/ -void FailedLitSearcher::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)); - - 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); - } - } -} - -/** -@brief Remove the assinged vars from the xors added by addFromSolver() - -The thus shortened xors are then treated if they are 2-long and if they -appear twice: by propagating "var" and by propagating "~var" -*/ -inline void FailedLitSearcher::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); - } - } -} - -/** -@brief Undoes what removeVarFromXors() has done -*/ -inline void FailedLitSearcher::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]++; - } -} - -/** -@brief Returns the 2-long xor clause that has been made of the longer xor-clause under current assignement - -We KNOW that the xorclause "c" passed as a parameter must be 2-long. We just -need it so that we can work with it. We KNOW it's 2-long because of the -data structures and functions in place - -@p[in] c MUST be a 2-long xor clause under current assignement -*/ -FailedLitSearcher::TwoLongXor FailedLitSearcher::getTwoLongXor(const XorClause& c) -{ - TwoLongXor tmp; - uint32_t num = 0; - tmp.inverted = c.xorEqualFalse(); - - 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); - } - } - - #ifdef VERBOSE_DEUBUG - if (num != 2) { - std::cout << "Num:" << num << std::endl; - c.plainPrint(); - } - #endif - - std::sort(&tmp.var[0], &tmp.var[0]+2); - assert(num == 2); - return tmp; -} - -/** -@brief The main function. Initialises data and calls tryBoth() for heavy-lifting - -It sets up the ground for tryBoth() and calls it as many times as it sees fit. -One afther the other, the different optimisations' data structures are -initialised, and their limits are set. Then tryBoth is called in two different -forms: somewhat sequentially on varaibles x...z and then on randomly picked -variables. -*/ -bool FailedLitSearcher::search() -{ - assert(solver.decisionLevel() == 0); - if (solver.nVars() == 0) return solver.ok; - - uint64_t numProps = 130 * 1000000; - uint64_t numPropsDifferent = (double)numProps*2.0; - - solver.testAllClauseAttach(); - double myTime = cpuTime(); - uint32_t origHeapSize = solver.order_heap.size(); - StateSaver savedState(solver); - Heap<Solver::VarOrderLt> order_heap_copy(solver.order_heap); //for hyperbin - - //General Stats - numFailed = 0; - goodBothSame = 0; - numCalls++; - - //If failed var searching is going good, do successively more and more of it - if ((double)lastTimeFoundTruths > (double)solver.order_heap.size() * 0.10) numPropsMultiplier = std::max(numPropsMultiplier*1.3, 2.0); - else numPropsMultiplier = 1.0; - numProps = (uint64_t) ((double)numProps * numPropsMultiplier * solver.conf.failedLitMultiplier); - - //For BothSame - propagated.resize(solver.nVars(), 0); - propValue.resize(solver.nVars(), 0); - - //For calculating how many variables have really been set - origTrailSize = solver.trail.size(); - - //For 2-long xor (rule 6 of Equivalent literal propagation in the DLL procedure by Chu-Min Li) - toReplaceBefore = solver.varReplacer->getNewToReplaceVars(); - lastTrailSize = solver.trail.size(); - binXorFind = true; - twoLongXors.clear(); - if (solver.xorclauses.size() < 5 || - solver.xorclauses.size() > 30000 || - solver.order_heap.size() > 30000 || - solver.nClauses() > 100000) - binXorFind = false; - if (binXorFind) { - solver.clauseCleaner->cleanClauses(solver.xorclauses, ClauseCleaner::xorclauses); - addFromSolver(solver.xorclauses); - } - xorClauseTouched.resize(solver.xorclauses.size(), 0); - newBinXor = 0; - - //For 2-long xor through Le Berre paper - bothInvert = 0; - - //For HyperBin - addedBin = 0; - unPropagatedBin.resize(solver.nVars(), 0); - needToVisit.resize(solver.nVars(), 0); - dontRemoveAncestor.resize(solver.nVars(), 0); - hyperbinProps = 0; - maxHyperBinProps = numProps/4; - if (solver.order_heap.size() < 20000) - maxHyperBinProps*=2; - removedUselessLearnt = 0; - removedUselessNonLearnt = 0; - - //uint32_t fromBin; - origProps = solver.propagations; - uint32_t i; - for (i = 0; i < solver.nVars(); i++) { - Var var = (lastTimeStopped + i) % solver.nVars(); - if (solver.assigns[var] != l_Undef || !solver.decision_var[var]) - continue; - if (solver.propagations >= origProps + numProps) - break; - if (!tryBoth(Lit(var, false), Lit(var, true))) - goto end; - } - lastTimeStopped = (lastTimeStopped + i) % solver.nVars(); - - origProps = solver.propagations; - while (!order_heap_copy.empty()) { - Var var = order_heap_copy.removeMin(); - if (solver.assigns[var] != l_Undef || !solver.decision_var[var]) - continue; - if (solver.propagations >= origProps + numPropsDifferent) { - break; - } - if (!tryBoth(Lit(var, false), Lit(var, true))) - goto end; - } - - if (solver.conf.verbosity >= 1) printResults(myTime); - - -end: - solver.order_heap.filter(Solver::VarFilter(solver)); - - if (solver.ok && (numFailed || goodBothSame)) { - double time = cpuTime(); - if ((int)origHeapSize - (int)solver.order_heap.size() > (int)origHeapSize/15 && solver.nClauses() + solver.learnts.size() > 500000) { - CompleteDetachReatacher reattacher(solver); - reattacher.detachNonBinsNonTris(true); - const bool ret = reattacher.reattachNonBins(); - release_assert(ret == true); - } else { - solver.clauseCleaner->removeAndCleanAll(); - } - if (solver.conf.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::endl; - } - } - - lastTimeFoundTruths = solver.trail.size() - origTrailSize; - totalTime += cpuTime() - myTime; - - savedState.restore(); - - solver.testAllClauseAttach(); - return solver.ok; -} - - -/** -@brief Prints results of failed litaral probing - -Printed: -1) Num failed lits -2) Num lits that have been propagated by both "var" and "~var" -3) 2-long Xor clauses that have been found because when propagating "var" and - "~var", they have been produced by normal xor-clauses shortening to this xor - clause -4) If var1 propagates var2 and ~var1 propagates ~var2, then var=var2, and this - is a 2-long XOR clause -5) Number of propagations -6) Time in seconds -*/ -void FailedLitSearcher::printResults(const double myTime) const -{ - std::cout << "c Flit: "<< std::setw(5) << numFailed << - " Blit: " << std::setw(6) << goodBothSame << - " bXBeca: " << std::setw(4) << newBinXor << - " bXProp: " << std::setw(4) << bothInvert << - " Bins:" << std::setw(7) << addedBin << - " BRemL:" << std::setw(7) << removedUselessLearnt << - " BRemN:" << std::setw(7) << removedUselessNonLearnt << - " P: " << std::setw(4) << std::fixed << std::setprecision(1) << (double)(solver.propagations - origProps)/1000000.0 << "M" - " T: " << std::setw(5) << std::fixed << std::setprecision(2) << cpuTime() - myTime - << std::endl; -} - -/** -@brief The main function of search() doing almost everything in this class - -Tries to branch on both lit1 and lit2 and then both-propagates them, fail-lits -them, and hyper-bin resolves them, etc. It is imperative that from the -SAT point of view, EITHER lit1 or lit2 MUST hold. So, if lit1 = ~lit2, it's OK. -Also, if there is a binary clause 'lit1 or lit2' it's also OK. -*/ -bool FailedLitSearcher::tryBoth(const Lit lit1, const Lit lit2) -{ - 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.removeThese(propagatedBitSet); - #ifdef DEBUG_FAILEDLIT - assert(propagated.isZero()); - #endif - propagatedBitSet.clear(); - twoLongXors.clear(); - bothSame.clear(); - binXorToAdd.clear(); - #ifdef DEBUG_HYPERBIN - assert(propagatedVars.empty()); - assert(unPropagatedBin.isZero()); - #endif //DEBUG_HYPERBIN - #ifdef DEBUG_USELESS_LEARNT_BIN_REMOVAL - dontRemoveAncestor.isZero(); - assert(uselessBin.empty()); - #endif - - solver.newDecisionLevel(); - solver.uncheckedEnqueueLight(lit1); - failed = (!solver.propagate<false>(false).isNULL()); - if (failed) { - solver.cancelUntilLight(); - numFailed++; - solver.uncheckedEnqueue(~lit1); - solver.ok = (solver.propagate<false>(false).isNULL()); - if (!solver.ok) return false; - return true; - } - - assert(solver.decisionLevel() > 0); - Solver::TransCache& lit1OTFCache = solver.transOTFCache[(~lit1).toInt()]; - if (solver.conf.doCacheOTFSSR) { - lit1OTFCache.conflictLastUpdated = solver.conflicts; - lit1OTFCache.lits.clear(); - } - for (int c = solver.trail.size()-1; c >= (int)solver.trail_lim[0]; c--) { - Var x = solver.trail[c].var(); - propagated.setBit(x); - propagatedBitSet.push_back(x); - - if (solver.conf.doHyperBinRes) { - unPropagatedBin.setBit(x); - propagatedVars.push(x); - } - - if (solver.assigns[x].getBool()) propValue.setBit(x); - else propValue.clearBit(x); - - if (binXorFind) removeVarFromXors(x); - if (solver.conf.doCacheOTFSSR && c != (int)solver.trail_lim[0]) { - lit1OTFCache.lits.push_back(solver.trail[c]); - } - } - - if (binXorFind) { - for (uint32_t *it = investigateXor.getData(), *end = investigateXor.getDataEnd(); 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.cancelUntilLight(); - - //Hyper-binary resolution, and its accompanying data-structure cleaning - if (solver.conf.doHyperBinRes) { - if (hyperbinProps < maxHyperBinProps) hyperBinResolution(lit1); - unPropagatedBin.removeThese(propagatedVars); - propagatedVars.clear(); - } - - #ifdef DEBUG_HYPERBIN - assert(propagatedVars.empty()); - assert(unPropagatedBin.isZero()); - #endif //DEBUG_HYPERBIN - - solver.newDecisionLevel(); - solver.uncheckedEnqueueLight(lit2); - failed = (!solver.propagate<false>(false).isNULL()); - if (failed) { - solver.cancelUntilLight(); - numFailed++; - solver.uncheckedEnqueue(~lit2); - solver.ok = (solver.propagate<false>(false).isNULL()); - if (!solver.ok) return false; - return true; - } - - assert(solver.decisionLevel() > 0); - Solver::TransCache& lit2OTFCache = solver.transOTFCache[(~lit2).toInt()]; - if (solver.conf.doCacheOTFSSR) { - lit2OTFCache.conflictLastUpdated = solver.conflicts; - lit2OTFCache.lits.clear(); - } - for (int c = solver.trail.size()-1; c >= (int)solver.trail_lim[0]; c--) { - Var x = solver.trail[c].var(); - if (propagated[x]) { - if (propValue[x] == solver.assigns[x].getBool()) { - //they both imply the same - bothSame.push(Lit(x, !propValue[x])); - } else if (c != (int)solver.trail_lim[0]) { - bool invert; - if (lit1.var() == lit2.var()) { - assert(lit1.sign() == false && lit2.sign() == true); - tmpPs[0] = Lit(lit1.var(), false); - tmpPs[1] = Lit(x, false); - invert = propValue[x]; - } else { - tmpPs[0] = Lit(lit1.var(), false); - tmpPs[1] = Lit(lit2.var(), false); - invert = lit1.sign() ^ lit2.sign(); - } - binXorToAdd.push_back(BinXorToAdd(tmpPs[0], tmpPs[1], invert)); - bothInvert += solver.varReplacer->getNewToReplaceVars() - toReplaceBefore; - toReplaceBefore = solver.varReplacer->getNewToReplaceVars(); - } - } - - if (solver.conf.doHyperBinRes) { - unPropagatedBin.setBit(x); - propagatedVars.push(x); - } - - if (solver.assigns[x].getBool()) propValue.setBit(x); - else propValue.clearBit(x); - - if (binXorFind) removeVarFromXors(x); - if (solver.conf.doCacheOTFSSR && c != (int)solver.trail_lim[0]) { - lit2OTFCache.lits.push_back(solver.trail[c]); - } - } - - //We now add the two-long xors that have been found through longer - //xor-shortening - 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()) { - tmpPs[0] = Lit(tmp.var[0], false); - tmpPs[1] = Lit(tmp.var[1], false); - binXorToAdd.push_back(BinXorToAdd(tmpPs[0], tmpPs[1], tmp.inverted)); - newBinXor += solver.varReplacer->getNewToReplaceVars() - toReplaceBefore; - toReplaceBefore = solver.varReplacer->getNewToReplaceVars(); - } - } - } - } - for (int c = solver.trail.size()-1; c >= (int)solver.trail_lim[0]; c--) { - addVarFromXors(solver.trail[c].var()); - } - } - solver.cancelUntilLight(); - - if (solver.conf.doHyperBinRes) { - if (hyperbinProps < maxHyperBinProps) hyperBinResolution(lit2); - unPropagatedBin.removeThese(propagatedVars); - propagatedVars.clear(); - } - - for(uint32_t i = 0; i != bothSame.size(); i++) { - solver.uncheckedEnqueue(bothSame[i]); - } - goodBothSame += bothSame.size(); - solver.ok = (solver.propagate<false>(false).isNULL()); - if (!solver.ok) return false; - - if (solver.conf.doBXor) { - for (uint32_t i = 0; i < binXorToAdd.size(); i++) { - tmpPs[0] = binXorToAdd[i].lit1; - tmpPs[1] = binXorToAdd[i].lit2; - solver.addXorClauseInt(tmpPs, binXorToAdd[i].isEqualFalse); - tmpPs.clear(); - tmpPs.growTo(2); - if (!solver.ok) return false; - } - } - - return true; -} - -/** -@brief Adds hyper-binary clauses - -At this point, unPropagatedBin is set, and propagatedVars is filled with lits -that have been propagated. Here, we propagate ONLY at the binary level, -and compare with propagatedVars and unPropagatedBin. If they match, it's OK. If -not, then we add the relevant binary clauses at the right point. The "right" -point is the point which has the highest in-degree. We approximated the degrees -beforehand with orderLits() -*/ -void FailedLitSearcher::hyperBinResolution(const Lit lit) -{ - #ifdef VERBOSE_DEBUG - std::cout << "Checking one BTC vs UP" << std::endl; - #endif //VERBOSE_DEBUG - - #ifdef DEBUG_HYPERBIN - assert(needToVisit.isZero()); - #endif //DEBUG_HYPERBIN - - uint64_t oldProps = solver.propagations; - vec<Lit> toVisit; - uint64_t extraTime = 0; - - solver.newDecisionLevel(); - solver.uncheckedEnqueueLight2(lit, 0, lit_Undef, false); - failed = (!solver.propagateBin(uselessBin).isNULL()); - assert(!failed); - - if (solver.conf.doRemUselessLBins && !uselessBin.empty()) { - for (const Lit *it = uselessBin.getData(), *end = uselessBin.getDataEnd(); it != end; it++) { - if (dontRemoveAncestor[it->var()]) continue; - - extraTime += solver.watches[lit.toInt()].size()/2; - extraTime += solver.watches[(~*it).toInt()].size()/2; - if (findWBin(solver.watches, ~lit, *it, true)) { - removeWBin(solver.watches[lit.toInt()], *it, true); - removeWBin(solver.watches[(~*it).toInt()], ~lit, true); - solver.learnts_literals -= 2; - solver.numBins--; - removedUselessLearnt++; - } else if (!solver.binPropData[it->var()].learntLeadHere) { - removeWBin(solver.watches[lit.toInt()], *it, false); - removeWBin(solver.watches[(~*it).toInt()], ~lit, false); - solver.clauses_literals -= 2; - solver.numBins--; - removedUselessNonLearnt++; - } else { - continue; - } - - Var ancestorVar = solver.binPropData[it->var()].lev1Ancestor.var(); - dontRemoveAncestor.setBit(ancestorVar); - toClearDontRemoveAcestor.push(ancestorVar); - } - dontRemoveAncestor.removeThese(toClearDontRemoveAcestor); - toClearDontRemoveAcestor.clear(); - } - uselessBin.clear(); - #ifdef DEBUG_USELESS_LEARNT_BIN_REMOVAL - dontRemoveAncestor.isZero(); - uint64_t backupProps; - #endif - - assert(solver.decisionLevel() > 0); - int32_t difference = propagatedVars.size() - (solver.trail.size()-solver.trail_lim[0]); - #ifdef DEBUG_USELESS_LEARNT_BIN_REMOVAL - uint32_t propagated = solver.trail.size()-solver.trail_lim[0]; - #endif - assert(difference >= 0); - if (difference == 0) { - solver.cancelUntilLight(); - goto end; - } - for (int c = solver.trail.size()-1; c >= (int)solver.trail_lim[0]; c--) { - Lit x = solver.trail[c]; - unPropagatedBin.clearBit(x.var()); - toVisit.push(x); - needToVisit.setBit(x.var()); - } - std::sort(toVisit.getData(), toVisit.getDataEnd(), LitOrder2(solver.binPropData)); - solver.cancelUntilLight(); - - #ifdef DEBUG_USELESS_LEARNT_BIN_REMOVAL - backupProps = solver.propagations; - if (solver.conf.doRemUselessLBins) { - solver.newDecisionLevel(); - solver.uncheckedEnqueueLight2(lit, 0, lit_Undef, false); - failed = (!solver.propagateBin(uselessBin).isNULL()); - uselessBin.clear(); - for (int c = solver.trail.size()-1; c >= (int)solver.trail_lim[0]; c--) { - Lit x = solver.trail[c]; - } - assert(!failed); - assert(propagated == solver.trail.size()-solver.trail_lim[0]); - solver.cancelUntilLight(); - } - solver.propagations = backupProps; - #endif - - /************************* - //To check that the ordering is the right way - // --> i.e. to avoid mistake present in Glucose's ordering*/ - /*std::cout << "--------------------" << std::endl; - for (uint32_t i = 0; i < toVisit.size(); i++) { - std::cout << "i:" << std::setw(8) << i - << " level:" << std::setw(3) << solver.binPropData[toVisit[i].var()].lev - << " lit : " << toVisit[i] - << std::endl; - } - std::cout << "difference: " << difference << std::endl; - std::cout << "--------------------" << std::endl;*/ - /***************************/ - - //difference between UP and BTC is in unPropagatedBin - for (Lit *l = toVisit.getData(), *end = toVisit.getDataEnd(); l != end; l++) { - if (!needToVisit[l->var()]) continue; - if (!solver.binPropData[l->var()].hasChildren) continue; - fillImplies(*l); - //addMyImpliesSetAsBins(*l, difference); - for (const Var *var = myImpliesSet.getData(), *end2 = myImpliesSet.getDataEnd(); var != end2; var++) { - /*Lit otherLit = Lit(*var, !propValue[*var]); - std::cout << "adding Bin:" << (~*l) << " , " << otherLit << std::endl; - std::cout << PropByFull(solver.reason[otherLit.var()], solver.failBinLit, solver.clauseAllocator) << std::endl;*/ - - addBin(~*l, Lit(*var, !propValue[*var])); - unPropagatedBin.clearBit(*var); - difference--; - } - - - assert(difference >= 0); - myImpliesSet.clear(); - - if (difference == 0) { - needToVisit.removeTheseLit(toVisit); - break; - } - } - #ifdef DEBUG_HYPERBIN - assert(unPropagatedBin.isZero()); - assert(needToVisit.isZero()); - #endif //DEBUG_HYPERBIN - - end: - hyperbinProps += solver.propagations - oldProps + extraTime; -} - -/** -@brief Fills myimplies and myimpliesSet by propagating lit at a binary level - -Used to check which variables are propagated by a certain literal when -propagating it only at the binary level -@p[in] the literal to be propagated at the binary level -*/ -void FailedLitSearcher::fillImplies(const Lit lit) -{ - solver.newDecisionLevel(); - solver.uncheckedEnqueueLight(lit); - failed = (!solver.propagate<false>(false).isNULL()); - assert(!failed); - - assert(solver.decisionLevel() > 0); - for (int sublevel = solver.trail.size()-1; sublevel >= (int)solver.trail_lim[0]; sublevel--) { - Var x = solver.trail[sublevel].var(); - needToVisit.clearBit(x); - if (unPropagatedBin[x]) { - myImpliesSet.push(x); - } - } - solver.cancelUntilLight(); -} - -/*void FailedLitSearcher::addMyImpliesSetAsBins(Lit lit, int32_t& difference) -{ - if (myImpliesSet.size() == 0) return; - if (myImpliesSet.size() == 1) { - Var var = myImpliesSet[0]; - Lit l2 = Lit(var, !propValue[var]); - addBin(~lit, l2); - unPropagatedBin.clearBit(var); - difference--; - return; - } - - uint64_t backupProps = solver.propagations; - vector<BinAddData> litsAddedEach; - uint32_t i = 0; - for (const Var *var = myImpliesSet.getData(), *end2 = myImpliesSet.getDataEnd(); var != end2; var++, i++) { - Lit l2 = Lit(*var, !propValue[*var]); - solver.newDecisionLevel(); - solver.uncheckedEnqueueLight(l2); - failed = (!solver.propagateBin(uselessBin).isNULL()); - assert(!failed); - uselessBin.clear(); - - BinAddData addData; - addData.lit = l2; - assert(solver.decisionLevel() > 0); - for (int sublevel = solver.trail.size()-1; sublevel > (int)solver.trail_lim[0]; sublevel--) { - Lit x = solver.trail[sublevel]; - addData.lits.push_back(x); - } - solver.cancelUntilLight(); - litsAddedEach.push_back(addData); - } - std::sort(litsAddedEach.begin(), litsAddedEach.end(), BinAddDataSorter()); - - while(!litsAddedEach.empty()) { - assert(!litsAddedEach.empty()); - BinAddData b = *litsAddedEach.begin(); - litsAddedEach.erase(litsAddedEach.begin()); - - addBin(~lit, b.lit); - assert(unPropagatedBin[b.lit.var()]); - unPropagatedBin.clearBit(b.lit.var()); - difference--; - for (uint32_t i = 0; i < b.lits.size(); i++) { - Lit alsoAddedLit = b.lits[i]; - if (unPropagatedBin[alsoAddedLit.var()]) { - unPropagatedBin.clearBit(alsoAddedLit.var()); - difference--; - for (vector<BinAddData>::iterator it2 = litsAddedEach.begin(); it2 != litsAddedEach.end(); it2++) { - if (it2->lit == alsoAddedLit) { - litsAddedEach.erase(it2); - break; - } - } - } - } - } - assert(litsAddedEach.empty()); - solver.propagations = backupProps; -}*/ - - -/** -@brief Adds a learnt binary clause to the solver - -Used by hyperBinResolution() to add the newly discovered clauses -*/ -void FailedLitSearcher::addBin(const Lit lit1, const Lit lit2) -{ - #ifdef VERBOSE_DEBUG - std::cout << "Adding extra bin: " << lit1 << " " << lit2 << std::endl; - #endif //VERBOSE_DEBUG - - assert(solver.value(lit1) == l_Undef); - assert(solver.value(lit2) == l_Undef); - tmpPs[0] = lit1; - tmpPs[1] = lit2; - - solver.addClauseInt(tmpPs, true); - tmpPs.clear(); - tmpPs.growTo(2); - assert(solver.ok); - addedBin++; -} diff --git a/src/prop/cryptominisat/Solver/FailedLitSearcher.h b/src/prop/cryptominisat/Solver/FailedLitSearcher.h deleted file mode 100644 index e4bf5bd19..000000000 --- a/src/prop/cryptominisat/Solver/FailedLitSearcher.h +++ /dev/null @@ -1,246 +0,0 @@ -/*************************************************************************** -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 FAILEDLITSEARCHER_H -#define FAILEDLITSEARCHER_H - -#include <set> -#include <map> -#include <vector> - -#include "SolverTypes.h" -#include "Clause.h" -#include "BitArray.h" - -namespace CMSat { - -using std::set; -using std::map; -using std::vector; - -class Solver; - -/** -@brief Responsible for doing failed var searching and related algorithms - -Performs in seach(): -1) Failed lit searching -2) Searching for lits that have been propagated by both "var" and "~var" -3) 2-long Xor clauses that have been found because when propagating "var" and - "~var", they have been produced by normal xor-clauses shortening to this xor - clause -4) If var1 propagates var2 and ~var1 propagates ~var2, then var=var2, and this - is a 2-long XOR clause, this 2-long xor is added -5) Hyper-binary resolution - -Perfoms in asymmBranch(): asymmetric branching, heuristically. Best paper -on this is 'Vivifying Propositional Clausal Formulae', though we do it much -more heuristically -*/ -class FailedLitSearcher { - public: - FailedLitSearcher(Solver& _solver); - - bool search(); - double getTotalTime() const; - - private: - //Main - bool tryBoth(const Lit lit1, const Lit lit2); - bool tryAll(const Lit* begin, const Lit* end); - void printResults(const double myTime) const; - - Solver& solver; ///<The solver we are updating&working with - - bool failed; ///<For checking that a specific propagation failed (=conflict). It is used in many places - - //bothprop finding - vector<uint32_t> propagatedBitSet; - BitArray propagated; ///<These lits have been propagated by propagating the lit picked - BitArray propValue; ///<The value (0 or 1) of the lits propagated set in "propagated" - /** - @brief Lits that have been propagated to the same value both by "var" and "~var" - - value that the literal has been propagated to is available in propValue - */ - vec<Lit> bothSame; - - //2-long xor-finding - /** - @brief used to find 2-long xor by shortening longer xors to this size - - -# We propagate "var" and record all xors that become 2-long - -# We propagate "~var" and record all xors that become 2-long - -# if (1) and (2) have something in common, we add it as a variable - replacement instruction - - We must be able to order these 2-long xors, so that we can search - for matching couples fast. This class is used for that - */ - class TwoLongXor - { - public: - bool operator==(const TwoLongXor& other) const - { - if (var[0] == other.var[0] - && var[1] == other.var[1] - && inverted == other.inverted) - return true; - return false; - } - 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 BinXorToAdd - { - public: - BinXorToAdd(const Lit _lit1, const Lit _lit2, const bool _isEqualFalse) : - lit1(_lit1) - , lit2(_lit2) - , isEqualFalse(_isEqualFalse) - {} - Lit lit1; - Lit lit2; - bool isEqualFalse; - }; - TwoLongXor getTwoLongXor(const XorClause& c); - void addFromSolver(const vec<XorClause*>& cs); - void removeVarFromXors(const Var var); - void addVarFromXors(const Var var); - - uint32_t newBinXor; - vec<uint32_t> xorClauseSizes; - vector<vector<uint32_t> > occur; ///<Occurence list for XORs. Indexed by variables - BitArray xorClauseTouched; - vec<uint32_t> investigateXor; - std::set<TwoLongXor> twoLongXors; - bool binXorFind; - uint32_t lastTrailSize; - vector<BinXorToAdd> binXorToAdd; - - /** - @brief Num. 2-long xor-found through Le Berre paper - - In case: - -# (a->b, ~a->~b) -> a=b - -# binary clause (a,c) exists: (a->g, c->~g) -> a = ~c - */ - uint32_t bothInvert; - - //finding HyperBins - struct LitOrder2 - { - LitOrder2(const vec<BinPropData>& _binPropData) : - binPropData(_binPropData) - {} - - bool operator () (const Lit x, const Lit y) const - { - return binPropData[x.var()].lev > binPropData[y.var()].lev; - } - - const vec<BinPropData>& binPropData; - }; - struct BinAddData - { - vector<Lit> lits; - Lit lit; - }; - struct BinAddDataSorter - { - bool operator() (const BinAddData& a, const BinAddData& b) const - { - return (a.lits.size() > b.lits.size()); - } - }; - //void addMyImpliesSetAsBins(Lit lit, int32_t& difference); - - uint32_t addedBin; - void hyperBinResolution(const Lit lit); - BitArray unPropagatedBin; - BitArray needToVisit; - vec<Var> propagatedVars; - void addBin(const Lit lit1, const Lit lit2); - void fillImplies(const Lit lit); - vec<Var> myImpliesSet; ///<variables set in myimplies - uint64_t hyperbinProps; ///<Number of bogoprops done by the hyper-binary resolution function hyperBinResolution() - - //bin-removal within hyper-bin-res - vec<Lit> uselessBin; - uint32_t removedUselessLearnt; - uint32_t removedUselessNonLearnt; - BitArray dontRemoveAncestor; - vec<Var> toClearDontRemoveAcestor; - /** - @brief Controls hyper-binary resolution's time-usage - - Don't do more than this many propagations within hyperBinResolution() - */ - uint64_t maxHyperBinProps; - - //Temporaries - vec<Lit> tmpPs; - - //State for this run - /** - @brief Records num. var-replacement istructions between 2-long xor findings through longer xor shortening - - Finding 2-long xor claues by shortening is fine, but sometimes we find - the same thing, or find something that is trivially a consequence of - other 2-long xors that we already know. To filter out these bogus - "findigs" from the statistics reported, we save in this value the - real var-replacement insturctions before and after the 2-long xor - finding through longer xor-shortening, and then compare the changes - made - */ - uint32_t toReplaceBefore; - uint32_t origTrailSize; ///<Records num. of 0-depth assignments at the start-up of search() - uint64_t origProps; ///<Records num. of bogoprops at the start-up of search() - uint32_t numFailed; ///<Records num. of failed literals during search() - uint32_t goodBothSame; ///<Records num. of literals that have been propagated to the same value by both "var" and "~var" - - //State between runs - double totalTime; - double numPropsMultiplier; ///<If last time we called search() all went fine, then this is incremented, so we do more searching this time - uint32_t lastTimeFoundTruths; ///<Records how many unit clauses we found last time we called search() - uint32_t numCalls; ///<Number of times search() has been called - uint32_t lastTimeStopped; -}; - -inline double FailedLitSearcher::getTotalTime() const -{ - return totalTime; -} - -} - -#endif //FAILEDVARSEARCHER_H diff --git a/src/prop/cryptominisat/Solver/Gaussian.cpp b/src/prop/cryptominisat/Solver/Gaussian.cpp deleted file mode 100644 index e186d5849..000000000 --- a/src/prop/cryptominisat/Solver/Gaussian.cpp +++ /dev/null @@ -1,1147 +0,0 @@ -/*************************************************************************** -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 "Gaussian.h" - -#include <iostream> -#include <iomanip> -#include "Clause.h" -#include <algorithm> -#include "ClauseCleaner.h" -#include "VarReplacer.h" -#include "DataSync.h" - -//#define VERBOSE_DEBUG -//#define DEBUG_GAUSS - -#ifdef VERBOSE_DEBUG -#include <iterator> -#endif - -using namespace CMSat; -using std::ostream; -using std::cout; -using std::endl; - -static const uint16_t unassigned_col = std::numeric_limits<uint16_t>::max(); -static const Var unassigned_var = std::numeric_limits<Var>::max(); - -Gaussian::Gaussian(Solver& _solver, const GaussConf& _config, const uint32_t _matrix_no, const vector<XorClause*>& _xorclauses) : - solver(_solver) - , config(_config) - , matrix_no(_matrix_no) - , xorclauses(_xorclauses) - , messed_matrix_vars_since_reversal(true) - , gauss_last_level(0) - , disabled(false) - , useful_prop(0) - , useful_confl(0) - , called(0) - , unit_truths(0) -{ -} - -Gaussian::~Gaussian() -{ - for (uint32_t i = 0; i < clauses_toclear.size(); i++) - solver.clauseAllocator.clauseFree(clauses_toclear[i].first); -} - -inline void Gaussian::set_matrixset_to_cur() -{ - uint32_t level = solver.decisionLevel() / config.only_nth_gauss_save; - assert(level <= matrix_sets.size()); - - if (level == matrix_sets.size()) - matrix_sets.push_back(cur_matrixset); - else - matrix_sets[level] = cur_matrixset; -} - -bool Gaussian::full_init() -{ - assert(solver.ok); - assert(solver.decisionLevel() == 0); - - if (!should_init()) return true; - reset_stats(); - uint32_t last_trail_size = solver.trail.size(); - - bool do_again_gauss = true; - while (do_again_gauss) { - do_again_gauss = false; - solver.clauseCleaner->cleanClauses(solver.xorclauses, ClauseCleaner::xorclauses); - if (!solver.ok) return false; - init(); - PropBy confl; - gaussian_ret g = gaussian(confl); - switch (g) { - case unit_conflict: - case conflict: - #ifdef VERBOSE_DEBUG - cout << "(" << matrix_no << ")conflict at level 0" << std::endl; - #endif - solver.ok = false; - return false; - case unit_propagation: - case propagation: - unit_truths += last_trail_size - solver.trail.size(); - do_again_gauss = true; - solver.ok = (solver.propagate<true>().isNULL()); - if (!solver.ok) return false; - break; - case nothing: - break; - } - } - - return true; -} - -void Gaussian::init() -{ - assert(solver.decisionLevel() == 0); - - fill_matrix(cur_matrixset); - if (!cur_matrixset.num_rows || !cur_matrixset.num_cols) { - disabled = true; - badlevel = 0; - return; - } - - matrix_sets.clear(); - matrix_sets.push_back(cur_matrixset); - gauss_last_level = solver.trail.size(); - messed_matrix_vars_since_reversal = false; - badlevel = UINT_MAX; - - #ifdef VERBOSE_DEBUG - cout << "(" << matrix_no << ")Gaussian init finished." << endl; - #endif -} - -uint32_t Gaussian::select_columnorder(vector<uint16_t>& var_to_col, matrixset& origMat) -{ - var_to_col.resize(solver.nVars(), unassigned_col); - - uint32_t num_xorclauses = 0; - for (uint32_t i = 0; i != xorclauses.size(); i++) { - XorClause& c = *xorclauses[i]; - if (c.getRemoved()) continue; - num_xorclauses++; - - for (uint32_t i2 = 0; i2 < c.size(); i2++) { - assert(solver.assigns[c[i2].var()].isUndef()); - var_to_col[c[i2].var()] = unassigned_col - 1; - } - } - - uint32_t largest_used_var = 0; - for (uint32_t i = 0; i < var_to_col.size(); i++) - if (var_to_col[i] != unassigned_col) - largest_used_var = i; - var_to_col.resize(largest_used_var + 1); - - var_is_in.resize(var_to_col.size(), 0); - origMat.var_is_set.resize(var_to_col.size(), 0); - - origMat.col_to_var.clear(); - vector<Var> vars(solver.nVars()); - if (!config.orderCols) { - for (uint32_t i = 0; i < solver.nVars(); i++) { - vars.push_back(i); - } - std::random_shuffle(vars.begin(), vars.end()); - } - - Heap<Solver::VarOrderLt> order_heap(solver.order_heap); - uint32_t iterReduceIt = 0; - while ((config.orderCols && !order_heap.empty()) || (!config.orderCols && iterReduceIt < vars.size())) - { - Var v; - if (config.orderCols) v = order_heap.removeMin(); - else v = vars[iterReduceIt++]; - if (var_to_col[v] == 1) { - #ifdef DEBUG_GAUSS - vector<uint32_t>::iterator it = - std::find(origMat.col_to_var.begin(), origMat.col_to_var.end(), v); - assert(it == origMat.col_to_var.end()); - #endif - - origMat.col_to_var.push_back(v); - var_to_col[v] = origMat.col_to_var.size()-1; - var_is_in.setBit(v); - } - } - - //for the ones that were not in the order_heap, but are marked in var_to_col - for (uint32_t v = 0; v != var_to_col.size(); v++) { - if (var_to_col[v] == unassigned_col - 1) { - origMat.col_to_var.push_back(v); - var_to_col[v] = origMat.col_to_var.size() -1; - var_is_in.setBit(v); - } - } - - #ifdef VERBOSE_DEBUG_MORE - cout << "(" << matrix_no << ")col_to_var:"; - std::copy(origMat.col_to_var.begin(), origMat.col_to_var.end(), std::ostream_iterator<uint32_t>(cout, ",")); - cout << endl; - #endif - - return num_xorclauses; -} - -void Gaussian::fill_matrix(matrixset& origMat) -{ - #ifdef VERBOSE_DEBUG - cout << "(" << matrix_no << ")Filling matrix" << endl; - #endif - - vector<uint16_t> var_to_col; - origMat.num_rows = select_columnorder(var_to_col, origMat); - origMat.num_cols = origMat.col_to_var.size(); - col_to_var_original = origMat.col_to_var; - changed_rows.resize(origMat.num_rows); - memset(&changed_rows[0], 0, sizeof(unsigned char)*changed_rows.size()); - - origMat.last_one_in_col.resize(origMat.num_cols); - std::fill(origMat.last_one_in_col.begin(), origMat.last_one_in_col.end(), origMat.num_rows); - origMat.first_one_in_row.resize(origMat.num_rows); - - origMat.removeable_cols = 0; - origMat.least_column_changed = -1; - origMat.matrix.resize(origMat.num_rows, origMat.num_cols); - - #ifdef VERBOSE_DEBUG - cout << "(" << matrix_no << ")matrix size:" << origMat.num_rows << "," << origMat.num_cols << endl; - #endif - - uint32_t matrix_row = 0; - for (uint32_t i = 0; i != xorclauses.size(); i++) { - const XorClause& c = *xorclauses[i]; - if (c.getRemoved()) continue; - - 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); -} - -void Gaussian::update_matrix_col(matrixset& m, const Var var, const uint32_t col) -{ - #ifdef VERBOSE_DEBUG_MORE - cout << "(" << matrix_no << ")Updating matrix var " << var+1 << " (col " << col << ", m.last_one_in_col[col]: " << m.last_one_in_col[col] << ")" << endl; - cout << "m.num_rows:" << m.num_rows << endl; - #endif - - #ifdef DEBUG_GAUSS - assert(col < m.num_cols); - #endif - - m.least_column_changed = std::min(m.least_column_changed, (int)col); - PackedMatrix::iterator this_row = m.matrix.beginMatrix(); - uint32_t row_num = 0; - - if (solver.assigns[var].getBool()) { - for (uint32_t end = m.last_one_in_col[col]; row_num != end; ++this_row, row_num++) { - if ((*this_row)[col]) { - changed_rows[row_num] = true; - (*this_row).invert_is_true(); - (*this_row).clearBit(col); - } - } - } else { - for (uint32_t end = m.last_one_in_col[col]; row_num != end; ++this_row, row_num++) { - if ((*this_row)[col]) { - changed_rows[row_num] = true; - (*this_row).clearBit(col); - } - } - } - - #ifdef DEBUG_GAUSS - bool c = false; - for(PackedMatrix::iterator r = m.matrix.beginMatrix(), end = r + m.matrix.getSize(); r != end; ++r) - c |= (*r)[col]; - assert(!c); - #endif - - m.removeable_cols++; - m.col_to_var[col] = unassigned_var; - m.var_is_set.setBit(var); -} - -void Gaussian::update_matrix_by_col_all(matrixset& m) -{ - #ifdef VERBOSE_DEBUG - cout << "(" << matrix_no << ")Updating matrix." << endl; - #ifdef VERBOSE_DEBUG_MORE - print_matrix(m); - #endif - uint32_t num_updated = 0; - #endif - - #ifdef DEBUG_GAUSS - assert(nothing_to_propagate(cur_matrixset)); - assert(solver.decisionLevel() == 0 || check_last_one_in_cols(m)); - #endif - - memset(&changed_rows[0], 0, sizeof(unsigned char)*changed_rows.size()); - - uint32_t last = 0; - uint32_t col = 0; - for (const Var *it = &m.col_to_var[0], *end = it + m.num_cols; it != end; col++, it++) { - if (*it != unassigned_var && solver.assigns[*it].isDef()) { - update_matrix_col(m, *it, col); - last++; - #ifdef VERBOSE_DEBUG - num_updated++; - #endif - } else - last = 0; - } - m.num_cols -= last; - - #ifdef DEBUG_GAUSS - check_matrix_against_varset(m.matrix, m); - #endif - - #ifdef VERBOSE_DEBUG - cout << "Matrix update finished, updated " << num_updated << " cols" << endl; - #ifdef VERBOSE_DEBUG_MORE - print_matrix(m); - #endif - #endif - - /*cout << "num_rows:" << m.num_rows; - cout << " num_rows diff:" << origMat.num_rows - m.num_rows << endl; - cout << "num_cols:" << col_to_var_original.size(); - cout << " num_cols diff:" << col_to_var_original.size() - m.col_to_var.size() << endl; - cout << "removeable cols:" << m.removeable_cols << endl;*/ -} - -inline void Gaussian::update_last_one_in_col(matrixset& m) -{ - for (uint16_t* i = &m.last_one_in_col[0]+m.last_one_in_col.size()-1, *end = &m.last_one_in_col[0]-1; i != end && *i >= m.num_rows; i--) - *i = m.num_rows; -} - -Gaussian::gaussian_ret Gaussian::gaussian(PropBy& confl) -{ - if (solver.decisionLevel() >= badlevel) - return nothing; - - if (messed_matrix_vars_since_reversal) { - #ifdef VERBOSE_DEBUG - cout << "(" << matrix_no << ")matrix needs copy before update" << endl; - #endif - - const uint32_t level = solver.decisionLevel() / config.only_nth_gauss_save; - assert(level < matrix_sets.size()); - cur_matrixset = matrix_sets[level]; - } - update_last_one_in_col(cur_matrixset); - update_matrix_by_col_all(cur_matrixset); - - messed_matrix_vars_since_reversal = false; - gauss_last_level = solver.trail.size(); - badlevel = UINT_MAX; - - propagatable_rows.clear(); - uint32_t last_row = eliminate(cur_matrixset); - #ifdef DEBUG_GAUSS - check_matrix_against_varset(cur_matrixset.matrix, cur_matrixset); - #endif - - gaussian_ret ret; - //There is no early abort, so this is unneeded - /*if (conflict_row != UINT_MAX) { - uint32_t maxlevel = UINT_MAX; - uint32_t size = UINT_MAX; - uint32_t best_row = UINT_MAX; - analyse_confl(cur_matrixset, conflict_row, maxlevel, size, best_row); - ret = handle_matrix_confl(confl, cur_matrixset, size, maxlevel, best_row); - } else {*/ - ret = handle_matrix_prop_and_confl(cur_matrixset, last_row, confl); - //} - #ifdef DEBUG_GAUSS - assert(ret == conflict || ret == unit_conflict || nothing_to_propagate(cur_matrixset)); - #endif - - if (!cur_matrixset.num_cols || !cur_matrixset.num_rows) { - badlevel = solver.decisionLevel(); - return ret; - } - - if (ret == nothing && - solver.decisionLevel() % config.only_nth_gauss_save == 0) - set_matrixset_to_cur(); - - #ifdef VERBOSE_DEBUG - if (ret == nothing) - cout << "(" << matrix_no << ")Useless. "; - else - cout << "(" << matrix_no << ")Useful. "; - cout << "(" << matrix_no << ")Useful prop in " << ((double)useful_prop/(double)called)*100.0 << "%" << endl; - cout << "(" << matrix_no << ")Useful confl in " << ((double)useful_confl/(double)called)*100.0 << "%" << endl; - #endif - - return ret; -} - -uint32_t Gaussian::eliminate(matrixset& m) -{ - #ifdef VERBOSE_DEBUG - cout << "(" << matrix_no << ")"; - cout << "Starting elimination" << endl; - cout << "m.least_column_changed:" << m.least_column_changed << endl; - #ifdef VERBOSE_DEBUG_MORE - print_last_one_in_cols(m); - #endif - - uint32_t number_of_row_additions = 0; - uint32_t no_exchanged = 0; - #endif - - if (m.least_column_changed == INT_MAX) { - #ifdef VERBOSE_DEBUG - cout << "Nothing to eliminate" << endl; - #endif - - return m.num_rows; - } - - - #ifdef DEBUG_GAUSS - assert(solver.decisionLevel() == 0 || check_last_one_in_cols(m)); - #endif - - uint32_t i = 0; - uint32_t j = (config.iterativeReduce) ? m.least_column_changed + 1 : 0; - PackedMatrix::iterator beginIt = m.matrix.beginMatrix(); - PackedMatrix::iterator rowIt = m.matrix.beginMatrix(); - - #ifdef DEBUG_GAUSS - check_first_one_in_row(m, j); - #endif - - if (j) { - uint16_t until = std::min(m.last_one_in_col[m.least_column_changed] - 1, (int)m.num_rows); - if (j-1 > m.first_one_in_row[m.num_rows-1]) - until = m.num_rows; - for (;i != until; i++, ++rowIt) if (changed_rows[i] && (*rowIt).popcnt_is_one(m.first_one_in_row[i])) - propagatable_rows.push(i); - } - - #ifdef VERBOSE_DEBUG - cout << "At while() start: i,j = " << i << ", " << j << endl; - cout << "num_rows:" << m.num_rows << " num_cols:" << m.num_cols << endl; - #endif - - if (j > m.num_cols) { - #ifdef VERBOSE_DEBUG - cout << "Going straight to finish" << endl; - #endif - goto finish; - } - - #ifdef DEBUG_GAUSS - assert(i <= m.num_rows && j <= m.num_cols); - #endif - - while (i != m.num_rows && j != m.num_cols) { - //Find pivot in column j, starting in row i: - - if (m.col_to_var[j] == unassigned_var) { - j++; - continue; - } - - PackedMatrix::iterator this_matrix_row = rowIt; - PackedMatrix::iterator end = beginIt + m.last_one_in_col[j]; - for (; this_matrix_row != end; ++this_matrix_row) { - if ((*this_matrix_row)[j]) - break; - } - - if (this_matrix_row != end) { - - //swap rows i and maxi, but do not change the value of i; - if (this_matrix_row != rowIt) { - #ifdef VERBOSE_DEBUG - no_exchanged++; - #endif - - //Would early abort, but would not find the best conflict (and would be expensive) - //if (matrix_row_i.is_true() && matrix_row_i.isZero()) { - // conflict_row = i; - // return 0; - //} - (*rowIt).swapBoth(*this_matrix_row); - } - #ifdef DEBUG_GAUSS - assert(m.matrix.getMatrixAt(i).popcnt(j) == m.matrix.getMatrixAt(i).popcnt()); - assert(m.matrix.getMatrixAt(i)[j]); - #endif - - if ((*rowIt).popcnt_is_one(j)) - propagatable_rows.push(i); - - //Now A[i,j] will contain the old value of A[maxi,j]; - ++this_matrix_row; - for (; this_matrix_row != end; ++this_matrix_row) if ((*this_matrix_row)[j]) { - //subtract row i from row u; - //Now A[u,j] will be 0, since A[u,j] - A[i,j] = A[u,j] -1 = 0. - #ifdef VERBOSE_DEBUG - number_of_row_additions++; - #endif - - (*this_matrix_row).xorBoth(*rowIt); - //Would early abort, but would not find the best conflict (and would be expensive) - //if (it->is_true() &&it->isZero()) { - // conflict_row = i2; - // return 0; - //} - } - m.first_one_in_row[i] = j; - i++; - ++rowIt; - m.last_one_in_col[j] = i; - } else { - m.first_one_in_row[i] = j; - m.last_one_in_col[j] = i + 1; - } - j++; - } - - finish: - - m.least_column_changed = INT_MAX; - - #ifdef VERBOSE_DEBUG - cout << "Finished elimination" << endl; - cout << "Returning with i,j:" << i << ", " << j << "(" << m.num_rows << ", " << m.num_cols << ")" << endl; - #ifdef VERBOSE_DEBUG_MORE - print_matrix(m); - print_last_one_in_cols(m); - #endif - cout << "(" << matrix_no << ")Exchanged:" << no_exchanged << " row additions:" << number_of_row_additions << endl; - #endif - - #ifdef DEBUG_GAUSS - assert(check_last_one_in_cols(m)); - uint32_t row = 0; - uint32_t col = 0; - for (; col < m.num_cols && row < m.num_rows && row < i ; col++) { - assert(m.matrix.getMatrixAt(row).popcnt() == m.matrix.getMatrixAt(row).popcnt(col)); - assert(!(m.col_to_var[col] == unassigned_var && m.matrix.getMatrixAt(row)[col])); - if (m.col_to_var[col] == unassigned_var || !m.matrix.getMatrixAt(row)[col]) { - #ifdef VERBOSE_DEBUG_MORE - cout << "row:" << row << " col:" << col << " m.last_one_in_col[col]-1: " << m.last_one_in_col[col]-1 << endl; - #endif - assert(m.col_to_var[col] == unassigned_var || std::min((uint16_t)(m.last_one_in_col[col]-1), m.num_rows) == row); - continue; - } - row++; - } - #endif - - return i; -} - -Gaussian::gaussian_ret Gaussian::handle_matrix_confl(PropBy& confl, const matrixset& m, const uint32_t maxlevel, const uint32_t best_row) -{ - assert(best_row != UINT_MAX); - - const bool xorEqualFalse = !m.matrix.getVarsetAt(best_row).is_true(); - const bool wasUndef = m.matrix.getVarsetAt(best_row).fill(tmp_clause, solver.assigns, col_to_var_original); - release_assert(!wasUndef); - - #ifdef VERBOSE_DEBUG - cout << "(" << matrix_no << ")matrix confl clause:" - << tmp_clause << " , " - << "xorEqualFalse:" << xorEqualFalse << std::endl; - #endif - - if (tmp_clause.size() <= 1) { - if (!tmp_clause.empty()) { - confl = PropBy(tmp_clause[0]); - } else { - confl = PropBy(); - solver.ok = false; - } - return unit_conflict; - } - - if (maxlevel != solver.decisionLevel()) { - solver.cancelUntil(maxlevel); - } - const uint32_t curr_dec_level = solver.decisionLevel(); - assert(maxlevel == curr_dec_level); - - uint32_t maxsublevel = 0; - if (tmp_clause.size() == 2) { - Lit lit1 = tmp_clause[0]; - Lit lit2 = tmp_clause[1]; - - solver.watches[(~lit1).toInt()].push(Watched(lit2, true)); - solver.watches[(~lit2).toInt()].push(Watched(lit1, true)); - solver.numBins++; - solver.learnts_literals += 2; - solver.dataSync->signalNewBinClause(lit1, lit2); - - lit1 = ~lit1; - lit2 = ~lit2; - solver.watches[(~lit2).toInt()].push(Watched(lit1, true)); - solver.watches[(~lit1).toInt()].push(Watched(lit2, true)); - solver.numBins++; - solver.learnts_literals += 2; - solver.dataSync->signalNewBinClause(lit1, lit2); - - lit1 = ~lit1; - lit2 = ~lit2; - uint32_t sublevel1 = find_sublevel(lit1.var()); - uint32_t sublevel2 = find_sublevel(lit2.var()); - if (sublevel1 > sublevel2) { - maxsublevel = sublevel1; - std::swap(lit1, lit2); - } else { - maxsublevel = sublevel2; - } - - confl = PropBy(lit1); - solver.failBinLit = lit2; - } else { - Clause* conflPtr = (Clause*)solver.clauseAllocator.XorClause_new(tmp_clause, xorEqualFalse); - confl = solver.clauseAllocator.getOffset(conflPtr); - Clause& cla = *conflPtr; - - uint32_t maxsublevel_at = UINT_MAX; - for (uint32_t i = 0, size = cla.size(); i != size; i++) if (solver.level[cla[i].var()] == (int32_t)curr_dec_level) { - uint32_t tmp = find_sublevel(cla[i].var()); - if (tmp >= maxsublevel) { - maxsublevel = tmp; - maxsublevel_at = i; - } - } - #ifdef VERBOSE_DEBUG - cout << "(" << matrix_no << ") || Sublevel of confl: " << maxsublevel << " (due to var:" << cla[maxsublevel_at].var()-1 << ")" << endl; - #endif - - Lit tmp(cla[maxsublevel_at]); - cla[maxsublevel_at] = cla[1]; - cla[1] = tmp; - } - - cancel_until_sublevel(maxsublevel+1); - messed_matrix_vars_since_reversal = true; - - return conflict; -} - -Gaussian::gaussian_ret Gaussian::handle_matrix_prop_and_confl(matrixset& m, uint32_t last_row, PropBy& confl) -{ - int32_t maxlevel = std::numeric_limits<int32_t>::max(); - uint32_t size = UINT_MAX; - uint32_t best_row = UINT_MAX; - - for (uint32_t row = last_row; row != m.num_rows; row++) { - #ifdef DEBUG_GAUSS - assert(m.matrix.getMatrixAt(row).isZero()); - #endif - if (m.matrix.getMatrixAt(row).is_true()) - analyse_confl(m, row, maxlevel, size, best_row); - } - - if (maxlevel != std::numeric_limits<int32_t>::max()) - return handle_matrix_confl(confl, m, maxlevel, best_row); - - #ifdef DEBUG_GAUSS - assert(check_no_conflict(m)); - assert(last_row == 0 || !m.matrix.getMatrixAt(last_row-1).isZero()); - #endif - - #ifdef VERBOSE_DEBUG - cout << "Resizing matrix to num_rows = " << last_row << endl; - #endif - m.num_rows = last_row; - m.matrix.resizeNumRows(m.num_rows); - - gaussian_ret ret = nothing; - - uint32_t num_props = 0; - for (const uint32_t* prop_row = propagatable_rows.getData(), *end = prop_row + propagatable_rows.size(); prop_row != end; prop_row++ ) { - //this is a "000..1..0000000X" row. I.e. it indicates a propagation - ret = handle_matrix_prop(m, *prop_row); - num_props++; - if (ret == unit_propagation) { - #ifdef VERBOSE_DEBUG - cout << "(" << matrix_no << ")Unit prop! Breaking from prop examination" << endl; - #endif - return unit_propagation; - } - } - #ifdef VERBOSE_DEBUG - if (num_props > 0) cout << "(" << matrix_no << ")Number of props during gauss:" << num_props << endl; - #endif - - return ret; -} - -uint32_t Gaussian::find_sublevel(const Var v) const -{ - for (int i = solver.trail.size()-1; i >= 0; i --) - if (solver.trail[i].var() == v) return i; - - #ifdef VERBOSE_DEBUG - cout << "(" << matrix_no << ")Oooops! Var " << v+1 << " does not have a sublevel!! (so it must be undefined)" << endl; - #endif - - assert(false); - return 0; -} - -void Gaussian::cancel_until_sublevel(const uint32_t until_sublevel) -{ - #ifdef VERBOSE_DEBUG - cout << "(" << matrix_no << ")Canceling until sublevel " << until_sublevel << endl; - #endif - - for (vector<Gaussian*>::iterator gauss = solver.gauss_matrixes.begin(), end= solver.gauss_matrixes.end(); gauss != end; gauss++) - if (*gauss != this) (*gauss)->canceling(until_sublevel); - - for (int sublevel = solver.trail.size()-1; sublevel >= (int)until_sublevel; sublevel--) { - Var var = solver.trail[sublevel].var(); - #ifdef VERBOSE_DEBUG - cout << "(" << matrix_no << ")Canceling var " << var+1 << endl; - #endif - - solver.assigns[var] = l_Undef; - solver.insertVarOrder(var); - } - solver.trail.shrink(solver.trail.size() - until_sublevel); - - #ifdef VERBOSE_DEBUG - cout << "(" << matrix_no << ")Canceling sublevel finished." << endl; - #endif -} - -void Gaussian::analyse_confl(const matrixset& m, const uint32_t row, int32_t& maxlevel, uint32_t& size, uint32_t& best_row) const -{ - assert(row < m.num_rows); - - //this is a "000...00000001" row. I.e. it indicates we are on the wrong branch - #ifdef VERBOSE_DEBUG - cout << "(" << matrix_no << ")matrix conflict found!" << endl; - cout << "(" << matrix_no << ")conflict clause's vars: "; - #ifdef VERBOSE_DEBUG_MORE - print_matrix_row_with_assigns(m.matrix.getVarsetAt(row)); - cout << endl; - - cout << "(" << matrix_no << ")corresponding matrix's row (should be empty): "; - print_matrix_row(m.matrix.getMatrixAt(row)); - cout << endl; - #endif - #endif - - int32_t this_maxlevel = 0; - unsigned long int var = 0; - uint32_t this_size = 0; - while (true) { - var = m.matrix.getVarsetAt(row).scan(var); - if (var == ULONG_MAX) break; - - const Var real_var = col_to_var_original[var]; - assert(real_var < solver.nVars()); - - if (solver.level[real_var] > this_maxlevel) - this_maxlevel = solver.level[real_var]; - var++; - this_size++; - } - - //the maximum of all lit's level must be lower than the max. level of the current best clause (or this clause must be either empty or unit clause) - if (!( - (this_maxlevel < maxlevel) - || (this_maxlevel == maxlevel && this_size < size) - || (this_size <= 1) - )) { - assert(maxlevel != std::numeric_limits<int32_t>::max()); - - #ifdef VERBOSE_DEBUG - cout << "(" << matrix_no << ")Other found conflict just as good or better."; - cout << "(" << matrix_no << ") || Old maxlevel:" << maxlevel << " new maxlevel:" << this_maxlevel; - cout << "(" << matrix_no << ") || Old size:" << size << " new size:" << this_size << endl; - //assert(!(maxlevel != UINT_MAX && maxlevel != this_maxlevel)); //NOTE: only holds if gauss is executed at each level - #endif - - return; - } - - - #ifdef VERBOSE_DEBUG - if (maxlevel != std::numeric_limits<int32_t>::max()) - cout << "(" << matrix_no << ")Better conflict found."; - else - cout << "(" << matrix_no << ")Found a possible conflict."; - - cout << "(" << matrix_no << ") || Old maxlevel:" << maxlevel << " new maxlevel:" << this_maxlevel; - cout << "(" << matrix_no << ") || Old size:" << size << " new size:" << this_size << endl; - #endif - - maxlevel = this_maxlevel; - size = this_size; - best_row = row; -} - -Gaussian::gaussian_ret Gaussian::handle_matrix_prop(matrixset& m, const uint32_t row) -{ - #ifdef VERBOSE_DEBUG - cout << "(" << matrix_no << ")matrix prop" << endl; - #ifdef VERBOSE_DEBUG_MORE - cout << "(" << matrix_no << ")matrix row:" << m.matrix.getMatrixAt(row) << endl; - #endif - #endif - - bool xorEqualFalse = !m.matrix.getVarsetAt(row).is_true(); - m.matrix.getVarsetAt(row).fill(tmp_clause, solver.assigns, col_to_var_original); - #ifdef VERBOSE_DEBUG - cout << "(" << matrix_no << ")matrix prop clause: " << tmp_clause << std::endl; - cout << endl; - #endif - - switch(tmp_clause.size()) { - case 0: - //This would mean nothing, empty = true, always true in xors - assert(false); - break; - case 1: - solver.cancelUntil(0); - solver.uncheckedEnqueue(tmp_clause[0]); - return unit_propagation; - case 2: { - solver.cancelUntil(0); - tmp_clause[0] = tmp_clause[0].unsign(); - tmp_clause[1] = tmp_clause[1].unsign(); - XorClause* cl = solver.addXorClauseInt(tmp_clause, xorEqualFalse); - release_assert(cl == NULL); - release_assert(solver.ok); - return unit_propagation; - } - default: - if (solver.decisionLevel() == 0) { - solver.uncheckedEnqueue(tmp_clause[0]); - return unit_propagation; - } - Clause& cla = *(Clause*)solver.clauseAllocator.XorClause_new(tmp_clause, xorEqualFalse); - assert(m.matrix.getMatrixAt(row).is_true() == !cla[0].sign()); - assert(solver.assigns[cla[0].var()].isUndef()); - - clauses_toclear.push_back(std::make_pair(&cla, solver.trail.size()-1)); - solver.uncheckedEnqueue(cla[0], solver.clauseAllocator.getOffset(&cla)); - return propagation; - } - - return propagation; -} - -void Gaussian::disable_if_necessary() -{ - if (//nof_conflicts >= 0 - //&& conflictC >= nof_conflicts/8 - !config.dontDisable - && called > 50 - && useful_confl*2+useful_prop < (uint32_t)((double)called*0.05) ) - disabled = true; -} - -llbool Gaussian::find_truths(vec<Lit>& learnt_clause, uint64_t& conflictC) -{ - PropBy confl; - - disable_if_necessary(); - if (should_check_gauss(solver.decisionLevel())) { - called++; - gaussian_ret g = gaussian(confl); - - switch (g) { - case conflict: { - useful_confl++; - llbool ret = solver.handle_conflict(learnt_clause, confl, conflictC, true); - if (confl.isClause()) - solver.clauseAllocator.clauseFree(solver.clauseAllocator.getPointer(confl.getClause())); - - if (ret != l_Nothing) return ret; - return l_Continue; - } - case unit_propagation: - unit_truths++; - case propagation: - useful_prop++; - return l_Continue; - case unit_conflict: { - unit_truths++; - useful_confl++; - if (confl.isNULL()) { - #ifdef VERBOSE_DEBUG - std::cout << "(" << matrix_no << ")zero-length conflict. UNSAT" << std::endl; - #endif - solver.ok = false; - return l_False; - } - - Lit lit = confl.getOtherLit(); - solver.cancelUntil(0); - - #ifdef VERBOSE_DEBUG - std::cout << "(" << matrix_no << ")one-length conflict" << std::endl; - #endif - if (solver.value(lit) != l_Undef) { - assert(solver.value(lit) == l_False); - #ifdef VERBOSE_DEBUG - std::cout << "(" << matrix_no << ") -> UNSAT" << std::endl; - #endif - solver.ok = false; - return l_False; - } - #ifdef VERBOSE_DEBUG - std::cout << "(" << matrix_no << ") -> setting to correct value" << std::endl; - #endif - solver.uncheckedEnqueue(lit); - return l_Continue; - } - case nothing: - break; - } - } - - return l_Nothing; -} - -template<class T> -void Gaussian::print_matrix_row(const T& row) const -{ - unsigned long int var = 0; - while (true) { - var = row.scan(var); - if (var == ULONG_MAX) break; - - else cout << col_to_var_original[var]+1 << ", "; - var++; - } - cout << "final:" << row.is_true() << endl;; -} - -template<class T> -void Gaussian::print_matrix_row_with_assigns(const T& row) const -{ - unsigned long int col = 0; - while (true) { - col = row.scan(col); - if (col == ULONG_MAX) break; - - else { - Var var = col_to_var_original[col]; - cout << var+1 << "(" << lbool_to_string(solver.assigns[var]) << ")"; - cout << ", "; - } - col++; - } - if (!row.is_true()) cout << "xorEqualFalse"; -} - -string Gaussian::lbool_to_string(const lbool toprint) -{ - if (toprint == l_True) - return "true"; - if (toprint == l_False) - return "false"; - if (toprint == l_Undef) - return "undef"; - - assert(false); - return ""; -} - - -void Gaussian::print_stats() const -{ - if (called > 0) { - cout.setf(std::ios::fixed); - std::cout << " Gauss(" << matrix_no << ") useful"; - cout << " prop: " << std::setprecision(2) << std::setw(5) << ((double)useful_prop/(double)called)*100.0 << "% "; - cout << " confl: " << std::setprecision(2) << std::setw(5) << ((double)useful_confl/(double)called)*100.0 << "% "; - if (disabled) std::cout << "disabled"; - } else - std::cout << " Gauss(" << matrix_no << ") not called."; -} - -void Gaussian::print_matrix_stats() const -{ - cout << "matrix size: " << cur_matrixset.num_rows << " x " << cur_matrixset.num_cols << endl; -} - - -void Gaussian::reset_stats() -{ - useful_prop = 0; - useful_confl = 0; - called = 0; - disabled = false; -} - -bool Gaussian::check_no_conflict(matrixset& m) const -{ - uint32_t row = 0; - for(PackedMatrix::iterator r = m.matrix.beginMatrix(), end = m.matrix.endMatrix(); r != end; ++r, ++row) { - if ((*r).is_true() && (*r).isZero()) { - cout << "Conflict at row " << row << endl; - return false; - } - } - return true; -} - -void Gaussian::print_matrix(matrixset& m) const -{ - uint32_t row = 0; - for (PackedMatrix::iterator it = m.matrix.beginMatrix(); it != m.matrix.endMatrix(); ++it, row++) { - cout << *it << " -- row:" << row; - if (row >= m.num_rows) - cout << " (considered past the end)"; - cout << endl; - } -} - -void Gaussian::print_last_one_in_cols(matrixset& m) const -{ - for (uint32_t i = 0; i < m.num_cols; i++) { - cout << "last_one_in_col[" << i << "]-1 = " << m.last_one_in_col[i]-1 << endl; - } -} - -bool Gaussian::nothing_to_propagate(matrixset& m) const -{ - for(PackedMatrix::iterator r = m.matrix.beginMatrix(), end = m.matrix.endMatrix(); r != end; ++r) { - if ((*r).popcnt_is_one() - && solver.assigns[m.col_to_var[(*r).scan(0)]].isUndef()) { - #ifdef VERBOSE_DEBUG - std::cout << "row " << (*r) << " is a propagation, but we didn't catch it" << std::endl; - #endif - return false; - } - } - for(PackedMatrix::iterator r = m.matrix.beginMatrix(), end = m.matrix.endMatrix(); r != end; ++r) { - if ((*r).isZero() && (*r).is_true()) { - #ifdef VERBOSE_DEBUG - std::cout << "row " << (*r) << " is a conflict, but we didn't catch it" << std::endl; - #endif - return false; - } - } - return true; -} - -bool Gaussian::check_last_one_in_cols(matrixset& m) const -{ - for(uint32_t i = 0; i < m.num_cols; i++) { - const uint32_t last = std::min(m.last_one_in_col[i] - 1, (int)m.num_rows); - uint32_t real_last = 0; - uint32_t i2 = 0; - for (PackedMatrix::iterator it = m.matrix.beginMatrix(); it != m.matrix.endMatrix(); ++it, i2++) { - if ((*it)[i]) - real_last = i2; - } - if (real_last > last) - return false; - } - - return true; -} - -void Gaussian::check_matrix_against_varset(PackedMatrix& matrix, const matrixset& m) const -{ - for (uint32_t i = 0; i < matrix.getSize(); i++) { - const PackedRow mat_row = matrix.getMatrixAt(i); - const PackedRow var_row = matrix.getVarsetAt(i); - - unsigned long int col = 0; - bool final = false; - while (true) { - col = var_row.scan(col); - if (col == ULONG_MAX) break; - - const Var var = col_to_var_original[col]; - assert(var < solver.nVars()); - - if (solver.assigns[var] == l_True) { - assert(!mat_row[col]); - assert(m.col_to_var[col] == unassigned_var); - assert(m.var_is_set[var]); - final = !final; - } else if (solver.assigns[var] == l_False) { - assert(!mat_row[col]); - assert(m.col_to_var[col] == unassigned_var); - assert(m.var_is_set[var]); - } else if (solver.assigns[var] == l_Undef) { - assert(m.col_to_var[col] != unassigned_var); - assert(!m.var_is_set[var]); - assert(mat_row[col]); - } else assert(false); - - col++; - } - if ((final^!mat_row.is_true()) != !var_row.is_true()) { - cout << "problem with row:"; print_matrix_row_with_assigns(var_row); cout << endl; - assert(false); - } - } -} - -void Gaussian::check_first_one_in_row(matrixset& m, const uint32_t j) -{ - if (j) { - uint16_t until2 = std::min(m.last_one_in_col[m.least_column_changed] - 1, (int)m.num_rows); - if (j-1 > m.first_one_in_row[m.num_rows-1]) { - until2 = m.num_rows; - #ifdef VERBOSE_DEBUG - cout << "j-1 > m.first_one_in_row[m.num_rows-1]" << "j:" << j << " m.first_one_in_row[m.num_rows-1]:" << m.first_one_in_row[m.num_rows-1] << endl; - #endif - } - for (uint32_t i2 = 0; i2 != until2; i2++) { - #ifdef VERBOSE_DEBUG - cout << endl << "row " << i2 << " (num rows:" << m.num_rows << ")" << endl; - cout << m.matrix.getMatrixAt(i2) << endl; - cout << " m.first_one_in_row[m.num_rows-1]:" << m.first_one_in_row[m.num_rows-1] << endl; - cout << "first_one_in_row:" << m.first_one_in_row[i2] << endl; - cout << "num_cols:" << m.num_cols << endl; - cout << "popcnt:" << m.matrix.getMatrixAt(i2).popcnt() << endl; - cout << "popcnt_is_one():" << m.matrix.getMatrixAt(i2).popcnt_is_one() << endl; - cout << "popcnt_is_one("<< m.first_one_in_row[i2] <<"): " << m.matrix.getMatrixAt(i2).popcnt_is_one(m.first_one_in_row[i2]) << endl; - #endif - - for (uint32_t i3 = 0; i3 < m.first_one_in_row[i2]; i3++) { - assert(m.matrix.getMatrixAt(i2)[i3] == 0); - } - assert(m.matrix.getMatrixAt(i2)[m.first_one_in_row[i2]]); - assert(m.matrix.getMatrixAt(i2).popcnt_is_one() == - m.matrix.getMatrixAt(i2).popcnt_is_one(m.first_one_in_row[i2])); - } - } -} diff --git a/src/prop/cryptominisat/Solver/Gaussian.h b/src/prop/cryptominisat/Solver/Gaussian.h deleted file mode 100644 index 6e4151811..000000000 --- a/src/prop/cryptominisat/Solver/Gaussian.h +++ /dev/null @@ -1,243 +0,0 @@ -/*********************************************************************************** -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 GAUSSIAN_H -#define GAUSSIAN_H - -#include <vector> -#include <limits> -#include <string> -#include <utility> - -#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" - -//#define VERBOSE_DEBUG -//#define DEBUG_GAUSS - -namespace CMSat { - -using std::string; -using std::pair; -using std::vector; - -class Clause; - -class Gaussian -{ -public: - Gaussian(Solver& solver, const GaussConf& config, const uint32_t matrix_no, const vector<XorClause*>& xorclauses); - ~Gaussian(); - - bool full_init(); - llbool find_truths(vec<Lit>& learnt_clause, uint64_t& conflictC); - - //statistics - void print_stats() const; - void print_matrix_stats() const; - uint32_t get_called() const; - uint32_t get_useful_prop() const; - uint32_t get_useful_confl() const; - bool get_disabled() const; - uint32_t get_unit_truths() const; - void set_disabled(const bool toset); - - //functions used throughout the Solver - void canceling(const uint32_t sublevel); - - friend class ClauseAllocator; - -protected: - Solver& solver; - - //Gauss high-level configuration - const GaussConf& config; - const uint32_t matrix_no; - vector<XorClause*> xorclauses; - - enum gaussian_ret {conflict, unit_conflict, propagation, unit_propagation, nothing}; - gaussian_ret gaussian(PropBy& confl); - - vector<Var> col_to_var_original; //Matches columns to variables - BitArray var_is_in; //variable is part of the the matrix. var_is_in's size is _minimal_ so you should check whether var_is_in.getSize() < var before issuing var_is_in[var] - uint32_t badlevel; - - class matrixset - { - public: - PackedMatrix matrix; // The matrix, updated to reflect variable assignements - BitArray var_is_set; - vector<Var> col_to_var; // col_to_var[COL] tells which variable is at a given column in the matrix. Gives unassigned_var if the COL has been zeroed (i.e. the variable assigned) - uint16_t num_rows; // number of active rows in the matrix. Unactive rows are rows that contain only zeros (and if they are conflicting, then the conflict has been treated) - uint32_t num_cols; // number of active columns in the matrix. The columns at the end that have all be zeroed are no longer active - int least_column_changed; // when updating the matrix, this value contains the smallest column number that has been updated (Gauss elim. can start from here instead of from column 0) - vector<uint16_t> last_one_in_col; //last_one_in_col[COL] tells the last row+1 that has a '1' in that column. Used to reduce the burden of Gauss elim. (it only needs to look until that row) - vector<uint16_t> first_one_in_row; - uint32_t removeable_cols; // the number of columns that have been zeroed out (i.e. assigned) - }; - - //Saved states - vector<matrixset> matrix_sets; // The matrixsets for depths 'decision_from' + 0, 'decision_from' + only_nth_gaussian_save, 'decision_from' + 2*only_nth_gaussian_save, ... 'decision_from' + 'decision_until'. - matrixset cur_matrixset; // The current matrixset, i.e. the one we are working on, or the last one we worked on - - //Varibales to keep Gauss state - bool messed_matrix_vars_since_reversal; - int gauss_last_level; - vector<pair<Clause*, uint32_t> > clauses_toclear; - bool disabled; // Gauss is disabled - - //State of current elimnation - vec<uint32_t> propagatable_rows; //used to store which rows were deemed propagatable during elimination - vector<unsigned char> changed_rows; //used to store which rows were deemed propagatable during elimination - - //Statistics - uint32_t useful_prop; //how many times Gauss gave propagation as a result - uint32_t useful_confl; //how many times Gauss gave conflict as a result - uint32_t called; //how many times called the Gauss - uint32_t unit_truths; //how many unitary (i.e. decisionLevel 0) truths have been found - - //gauss init functions - void init(); // Initalise gauss state - void fill_matrix(matrixset& origMat); // Fills the origMat matrix - uint32_t select_columnorder(vector<uint16_t>& var_to_col, matrixset& origMat); // Fills var_to_col and col_to_var of the origMat matrix. - - //Main function - uint32_t eliminate(matrixset& matrix); //does the actual gaussian elimination - - //matrix update functions - void update_matrix_col(matrixset& matrix, const Var x, const uint32_t col); // Update one matrix column - void update_matrix_by_col_all(matrixset& m); // Update all columns, column-by-column (and not row-by-row) - void set_matrixset_to_cur(); // Save the current matrixset, the cur_matrixset to matrix_sets - //void update_matrix_by_row(matrixset& matrix) const; - //void update_matrix_by_col(matrixset& matrix, const uint32_t last_level) const; - - //conflict&propagation handling - gaussian_ret handle_matrix_prop_and_confl(matrixset& m, uint32_t row, PropBy& confl); - void analyse_confl(const matrixset& m, const uint32_t row, int32_t& maxlevel, uint32_t& size, uint32_t& best_row) const; // analyse conflcit to find the best conflict. Gets & returns the best one in 'maxlevel', 'size' and 'best row' (these are all UINT_MAX when calling this function first, i.e. when there is no other possible conflict to compare to the new in 'row') - gaussian_ret handle_matrix_confl(PropBy& confl, const matrixset& m, const uint32_t maxlevel, const uint32_t best_row); - gaussian_ret handle_matrix_prop(matrixset& m, const uint32_t row); // Handle matrix propagation at row 'row' - vec<Lit> tmp_clause; - - //propagation&conflict handling - void cancel_until_sublevel(const uint32_t until_sublevel); // cancels until sublevel 'until_sublevel'. The var 'until_sublevel' must NOT go over the current level. I.e. this function is ONLY for moving inside the current level - uint32_t find_sublevel(const Var v) const; // find the sublevel (i.e. trail[X]) of a given variable - - //helper functions - bool at_first_init() const; - bool should_init() const; - bool should_check_gauss(const uint32_t decisionlevel) const; - void disable_if_necessary(); - void reset_stats(); - void update_last_one_in_col(matrixset& m); - -private: - - //debug functions - bool check_no_conflict(matrixset& m) const; // Are there any conflicts that the matrixset 'm' causes? - bool nothing_to_propagate(matrixset& m) const; // Are there any conflicts of propagations that matrixset 'm' clauses? - template<class T> - 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; - void check_matrix_against_varset(PackedMatrix& matrix,const matrixset& m) const; - bool check_last_one_in_cols(matrixset& m) const; - void check_first_one_in_row(matrixset& m, const uint32_t j); - void print_matrix(matrixset& m) const; - void print_last_one_in_cols(matrixset& m) const; - static string lbool_to_string(const lbool toprint); -}; - -inline bool Gaussian::should_init() const -{ - return (config.decision_until > 0); -} - -inline bool Gaussian::should_check_gauss(const uint32_t decisionlevel) const -{ - return (!disabled - && decisionlevel < config.decision_until); -} - -inline void Gaussian::canceling(const uint32_t sublevel) -{ - if (disabled) - return; - uint32_t a = 0; - for (int i = clauses_toclear.size()-1; i >= 0 && clauses_toclear[i].second > sublevel; i--) { - solver.clauseAllocator.clauseFree(clauses_toclear[i].first); - a++; - } - clauses_toclear.resize(clauses_toclear.size()-a); - - if (messed_matrix_vars_since_reversal) - return; - int c = std::min((int)gauss_last_level, (int)(solver.trail.size())-1); - for (; c >= (int)sublevel; c--) { - Var var = solver.trail[c].var(); - if (var < var_is_in.getSize() - && var_is_in[var] - && cur_matrixset.var_is_set[var]) { - messed_matrix_vars_since_reversal = true; - return; - } - } -} - -inline uint32_t Gaussian::get_unit_truths() const -{ - return unit_truths; -} - -inline uint32_t Gaussian::get_called() const -{ - return called; -} - -inline uint32_t Gaussian::get_useful_prop() const -{ - return useful_prop; -} - -inline uint32_t Gaussian::get_useful_confl() const -{ - return useful_confl; -} - -inline bool Gaussian::get_disabled() const -{ - return disabled; -} - -inline void Gaussian::set_disabled(const bool toset) -{ - disabled = toset; -} - -//std::ostream& operator << (std::ostream& os, const vec<Lit>& v); - -} - -#endif //GAUSSIAN_H diff --git a/src/prop/cryptominisat/Solver/GaussianConfig.h b/src/prop/cryptominisat/Solver/GaussianConfig.h deleted file mode 100644 index afcdefbf1..000000000 --- a/src/prop/cryptominisat/Solver/GaussianConfig.h +++ /dev/null @@ -1,63 +0,0 @@ -/*********************************************************************************** -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 GAUSSIANCONFIG_H -#define GAUSSIANCONFIG_H - -#ifdef _MSC_VER -#include <msvc/stdint.h> -#else -#include <stdint.h> -#endif //_MSC_VER - -#include "PackedRow.h" - -namespace CMSat -{ - -class GaussConf -{ - public: - - GaussConf() : - only_nth_gauss_save(2) - , decision_until(0) - , dontDisable(false) - , noMatrixFind(false) - , orderCols(true) - , iterativeReduce(true) - , maxMatrixRows(1000) - , minMatrixRows(20) - , maxNumMatrixes(3) - { - } - - //tuneable gauss parameters - uint32_t only_nth_gauss_save; //save only every n-th gauss matrix - uint32_t decision_until; //do Gauss until this level - bool dontDisable; //If activated, gauss elimination is never disabled - bool noMatrixFind; //Put all xor-s into one matrix, don't find matrixes - bool orderCols; //Order columns according to activity - bool iterativeReduce; //Don't minimise matrix work - uint32_t maxMatrixRows; //The maximum matrix size -- no. of rows - uint32_t minMatrixRows; //The minimum matrix size -- no. of rows - uint32_t maxNumMatrixes; //Maximum number of matrixes -}; - -} - -#endif //GAUSSIANCONFIG_H diff --git a/src/prop/cryptominisat/Solver/Main.cpp b/src/prop/cryptominisat/Solver/Main.cpp deleted file mode 100644 index 111683ee8..000000000 --- a/src/prop/cryptominisat/Solver/Main.cpp +++ /dev/null @@ -1,974 +0,0 @@ -/***************************************************************************** -MiniSat -- Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson -CryptoMiniSat -- Copyright (c) 2009 Mate Soos - -Original code by MiniSat authors are under an MIT licence. -Modifications for CryptoMiniSat are under GPLv3 licence. -******************************************************************************/ - -/** -@mainpage CryptoMiniSat -@author Mate Soos, and collaborators - -CryptoMiniSat is an award-winning SAT solver based on MiniSat. It brings a -number of benefits relative to MiniSat, among them XOR clauses, extensive -failed literal probing, and better random search. - -The solver basically performs the following steps: - -1) parse CNF file into clause database - -2) run Conflict-Driven Clause-Learning DPLL on the clauses - -3) regularly run simplification passes on the clause-set - -4) display solution and if not used as a library, exit - -Here is a picture of of the above process in more detail: - -\image html "main_flowgraph.png" - -*/ - -#include <ctime> -#include <cstring> -#include <errno.h> -#include <string.h> -#include <sstream> -#include <iostream> -#include <iomanip> -#include <omp.h> -#include <map> -#include <set> -#include "constants.h" - -#include <signal.h> - -#include "time_mem.h" -#include "constants.h" -#include "DimacsParser.h" - -#if defined(__linux__) -#include <fpu_control.h> -#endif - -#include "Main.h" - -using namespace CMSat; - -Main::Main(int _argc, char** _argv) : - numThreads(1) - , grouping(false) - , debugLib (false) - , debugNewVar (false) - , printResult (true) - , max_nr_of_solutions (1) - , fileNamePresent (false) - , twoFileNamesPresent (false) - , argc(_argc) - , argv(_argv) -{ -} - -std::map<uint32_t, Solver*> solversToInterrupt; -std::set<uint32_t> finished; - -void Main::readInAFile(const std::string& filename, Solver& solver) -{ - #pragma omp single - if (solver.conf.verbosity >= 1) { - std::cout << "c Reading file '" << filename << "'" << std::endl; - } - #ifdef DISABLE_ZLIB - FILE * in = fopen(filename.c_str(), "rb"); - #else - gzFile in = gzopen(filename.c_str(), "rb"); - #endif // DISABLE_ZLIB - - #pragma omp single - if (in == NULL) { - std::cout << "ERROR! Could not open file '" << filename << "' for reading" << std::endl; - exit(1); - } - - DimacsParser parser(&solver, debugLib, debugNewVar, grouping); - parser.parse_DIMACS(in); - - #ifdef DISABLE_ZLIB - fclose(in); - #else - gzclose(in); - #endif // DISABLE_ZLIB -} - -void Main::readInStandardInput(Solver& solver) -{ - if (solver.conf.verbosity >= 1) { - std::cout << "c Reading from standard input... Use '-h' or '--help' for help." << std::endl; - } - #ifdef DISABLE_ZLIB - FILE * in = stdin; - #else - gzFile in = gzdopen(fileno(stdin), "rb"); - #endif // DISABLE_ZLIB - - if (in == NULL) { - std::cout << "ERROR! Could not open standard input for reading" << std::endl; - exit(1); - } - - DimacsParser parser(&solver, debugLib, debugNewVar, grouping); - parser.parse_DIMACS(in); - - #ifndef DISABLE_ZLIB - gzclose(in); - #endif // DISABLE_ZLIB -} - - - -void Main::parseInAllFiles(Solver& solver) -{ - double myTime = cpuTime(); - - //First read normal extra files - if ((debugLib || debugNewVar) && filesToRead.size() > 0) { - std::cout << "debugNewVar and debugLib must both be OFF to parse in extra files" << std::endl; - exit(-1); - } - for (uint32_t i = 0; i < filesToRead.size(); i++) { - readInAFile(filesToRead[i].c_str(), solver); - } - - //Then read the main file or standard input - if (!fileNamePresent) { - readInStandardInput(solver); - } else { - string filename = argv[(twoFileNamesPresent ? argc-2 : argc-1)]; - readInAFile(filename, solver); - } - - if (solver.conf.verbosity >= 1) { - std::cout << "c Parsing time: " - << std::fixed << std::setw(5) << std::setprecision(2) << (cpuTime() - myTime) - << " s" << std::endl; - } -} - - -void Main::printUsage(char** argv) -{ -#ifdef DISABLE_ZLIB - printf("USAGE: %s [options] <input-file> <result-output-file>\n\n where input is plain DIMACS.\n\n", argv[0]); -#else - printf("USAGE: %s [options] <input-file> <result-output-file>\n\n where input may be either in plain or gzipped DIMACS.\n\n", argv[0]); -#endif // DISABLE_ZLIB - printf("OPTIONS:\n\n"); - printf(" --polarity-mode = {true,false,rnd,auto} [default: auto]. Selects the default\n"); - printf(" polarity mode. Auto is the Jeroslow&Wang method\n"); - //printf(" -decay = <num> [ 0 - 1 ]\n"); - printf(" --rnd-freq = <num> [ 0 - 1 ]\n"); - printf(" --verbosity = {0,1,2}\n"); - printf(" --randomize = <seed> [0 - 2^32-1] Sets random seed, used for picking\n"); - printf(" decision variables (default = 0)\n"); - printf(" --restrict = <num> [1 - varnum] when picking random variables to branch\n"); - printf(" on, pick one that in the 'num' most active vars useful\n"); - printf(" for cryptographic problems, where the question is the key,\n"); - printf(" which is usually small (e.g. 80 bits)\n"); - printf(" --gaussuntil = <num> Depth until which Gaussian elimination is active.\n"); - printf(" Giving 0 switches off Gaussian elimination\n"); - printf(" --restarts = <num> [1 - 2^32-1] No more than the given number of\n"); - printf(" restarts will be performed during search\n"); - printf(" --nonormxorfind Don't find and collect >2-long xor-clauses from\n"); - printf(" regular clauses\n"); - printf(" --nobinxorfind Don't find and collect 2-long xor-clauses from\n"); - printf(" regular clauses\n"); - printf(" --noregbxorfind Don't regularly find and collect 2-long xor-clauses\n"); - printf(" from regular clauses\n"); - printf(" --doextendedscc Do strongly conn. comp. finding using non-exist. bins\n"); - printf(" --noconglomerate Don't conglomerate 2 xor clauses when one var is dependent\n"); - printf(" --nosimplify Don't do regular simplification rounds\n"); - printf(" --greedyunbound Greedily unbound variables that are not needed for SAT\n"); - printf(" --debuglib Solve at specific 'c Solver::solve()' points in the CNF\n"); - printf(" file. Used to debug file generated by Solver's\n"); - printf(" needLibraryCNFFile() function\n"); - printf(" --debugnewvar Add new vars at specific 'c Solver::newVar()' points in \n"); - printf(" the CNF file. Used to debug file generated by Solver's\n"); - printf(" needLibraryCNFFile() function.\n"); - printf(" --novarreplace Don't perform variable replacement. Needed for programmable\n"); - printf(" solver feature\n"); - printf(" --restart = {auto, static, dynamic} Which kind of restart strategy to\n"); - printf(" follow. Default is auto\n"); - printf(" --dumplearnts = <filename> If interrupted or reached restart limit, dump\n"); - printf(" the learnt clauses to the specified file. Maximum size of\n"); - printf(" dumped clauses can be specified with next option.\n"); - printf(" --maxdumplearnts = [0 - 2^32-1] When dumping the learnts to file, what\n"); - printf(" should be maximum length of the clause dumped. Useful\n"); - printf(" to make the resulting file smaller. Default is 2^32-1\n"); - printf(" note: 2-long XOR-s are always dumped.\n"); - printf(" --dumporig = <filename> If interrupted or reached restart limit, dump\n"); - printf(" the original problem instance, simplified to the\n"); - printf(" current point.\n"); - printf(" --alsoread = <filename> Also read this file in\n"); - printf(" Can be used to re-read dumped learnts, for example\n"); - printf(" --maxsolutions Search for given amount of solutions\n"); - printf(" Can only be used in single-threaded more (\"--threads=1\")\n"); - printf(" --pavgbranch Print average branch depth\n"); - printf(" --nofailedlit Don't search for failed literals, and don't search for lits\n"); - printf(" propagated both by 'varX' and '-varX'\n"); - printf(" --noheuleprocess Don't try to minimise XORs by XOR-ing them together.\n"); - printf(" Algo. as per global/local substitution in Heule's thesis\n"); - printf(" --nosatelite Don't do clause subsumption, clause strengthening and\n"); - printf(" variable elimination (implies -novarelim and -nosubsume1).\n"); - printf(" --noxorsubs Don't try to subsume xor-clauses.\n"); - printf(" --nosolprint Don't print the satisfying assignment if the solution\n"); - printf(" is SAT\n"); - printf(" --novarelim Don't perform variable elimination as per Een and Biere\n"); - printf(" --nosubsume1 Don't perform clause contraction through resolution\n"); -#ifdef USE_GAUSS - printf(" --nomatrixfind Don't find distinct matrixes. Put all xors into one\n"); - printf(" big matrix\n"); - printf(" --noordercol Don't order variables in the columns of Gaussian\n"); - printf(" elimination. Effectively disables iterative reduction\n"); - printf(" of the matrix\n"); - printf(" --noiterreduce Don't reduce iteratively the matrix that is updated\n"); - printf(" --maxmatrixrows [0 - 2^32-1] Set maximum no. of rows for gaussian matrix.\n"); - printf(" Too large matrixes should bee discarded for\n"); - printf(" reasons of efficiency. Default: %d\n", gaussconfig.maxMatrixRows); - printf(" --minmatrixrows = [0 - 2^32-1] Set minimum no. of rows for gaussian matrix.\n"); - printf(" Normally, too small matrixes are discarded for\n"); - printf(" reasons of efficiency. Default: %d\n", gaussconfig.minMatrixRows); - printf(" --savematrix = [0 - 2^32-1] Save matrix every Nth decision level.\n"); - printf(" Default: %d\n", gaussconfig.only_nth_gauss_save); - printf(" --maxnummatrixes = [0 - 2^32-1] Maximum number of matrixes to treat.\n"); - printf(" Default: %d\n", gaussconfig.maxNumMatrixes); -#endif //USE_GAUSS - //printf(" --addoldlearnts = Readd old learnts for failed variable searching.\n"); - //printf(" These learnts are usually deleted, but may help\n"); - printf(" --nohyperbinres Don't add binary clauses when doing failed lit probing.\n"); - printf(" --noremovebins Don't remove useless binary clauses\n"); - printf(" --noremlbins Don't remove useless learnt binary clauses\n"); - printf(" --nosubswithbins Don't subsume with binary clauses\n"); - printf(" --nosubswithnbins Don't subsume with non-existent binary clauses\n"); - printf(" --noclausevivif Don't do perform clause vivification\n"); - printf(" --nosortwatched Don't sort watches according to size: bin, tri, etc.\n"); - printf(" --nolfminim Don't do on-the-fly self-subsuming resolution\n"); - printf(" (called 'strong minimisation' in PrecoSat)\n"); - printf(" --nocalcreach Don't calculate reachability and interfere with\n"); - printf(" variable decisions accordingly\n"); - printf(" --nobxor Don't find equivalent lits during failed lit search\n"); - printf(" --norecotfssr Don't perform recursive/transitive OTF self-\n"); - printf(" subsuming resolution\n"); - printf(" --nocacheotfssr Don't cache 1-level equeue. Less memory used, but\n"); - printf(" disables trans OTFSSR, adv. clause vivifier, etc.\n"); - printf(" --nootfsubsume Don't do on-the-fly subsumption after conf. gen.\n"); - #ifdef ENABLE_UNWIND_GLUE - printf(" --maxgluedel Automatically delete clauses over max glue. See '--maxglue'\n"); - printf(" --maxglue = [0 - 2^%d-1] default: %d. Glue value above which we\n", MAX_GLUE_BITS, conf.maxGlue); - #endif //ENABLE_UNWIND_GLUE - printf(" throw the clause away on backtrack.\n"); - printf(" --threads = Num threads (default is 1)\n"); - printf(" --plain Get rid of all simplification algorithms\n"); - printf(" --maxconfl = [0..2^63-1] Maximum number of conflicts to do\n"); - printf("\n"); -} - - -const char* Main::hasPrefix(const char* str, const char* prefix) -{ - int len = strlen(prefix); - if (strncmp(str, prefix, len) == 0) - return str + len; - else - return NULL; -} - -void Main::printResultFunc(const Solver& S, const lbool ret, FILE* res) -{ - if (res != NULL) { - if (ret == l_True) { - std::cout << "c SAT" << std::endl; - fprintf(res, "SAT\n"); - if (printResult) { - for (Var var = 0; var != S.nVars(); var++) - if (S.model[var] != l_Undef) - fprintf(res, "%s%d ", (S.model[var] == l_True)? "" : "-", var+1); - fprintf(res, "0\n"); - } - } else if (ret == l_False) { - std::cout << "c UNSAT" << std::endl; - fprintf(res, "UNSAT\n"); - } else { - std::cout << "c INCONCLUSIVE" << std::endl; - fprintf(res, "INCONCLUSIVE\n"); - } - fclose(res); - } else { - if (ret == l_True) { - if (!printResult) std::cout << "c SATISFIABLE" << std::endl; - else std::cout << "s SATISFIABLE" << std::endl; - } else if (ret == l_False) { - if (!printResult) std::cout << "c UNSATISFIABLE" << std::endl; - else std::cout << "s UNSATISFIABLE" << std::endl; - } - - if(ret == l_True && printResult) { - std::stringstream toPrint; - toPrint << "v "; - for (Var var = 0; var != S.nVars(); var++) - if (S.model[var] != l_Undef) - toPrint << ((S.model[var] == l_True)? "" : "-") << var+1 << " "; - toPrint << "0" << std::endl; - std::cout << toPrint.str(); - } - } -} - -void Main::parseCommandLine() -{ - const char* value; - char tmpFilename[201]; - tmpFilename[0] = '\0'; - uint32_t unparsedOptions = 0; - bool needTwoFileNames = false; - conf.verbosity = 2; - - for (int i = 0; i < argc; i++) { - if ((value = hasPrefix(argv[i], "--polarity-mode="))) { - if (strcmp(value, "true") == 0) - conf.polarity_mode = polarity_true; - else if (strcmp(value, "false") == 0) - conf.polarity_mode = polarity_false; - else if (strcmp(value, "rnd") == 0) - conf.polarity_mode = polarity_rnd; - else if (strcmp(value, "auto") == 0) - conf.polarity_mode = polarity_auto; - else { - printf("ERROR! unknown polarity-mode %s\n", value); - exit(0); - } - - } else if ((value = hasPrefix(argv[i], "--rnd-freq="))) { - double rnd; - if (sscanf(value, "%lf", &rnd) <= 0 || rnd < 0 || rnd > 1) { - printf("ERROR! illegal rnRSE ERROR!d-freq constant %s\n", value); - exit(0); - } - conf.random_var_freq = rnd; - - /*} else if ((value = hasPrefix(argv[i], "--decay="))) { - double decay; - if (sscanf(value, "%lf", &decay) <= 0 || decay <= 0 || decay > 1) { - printf("ERROR! illegal decay constant %s\n", value); - exit(0); - } - conf.var_decay = 1 / decay;*/ - - } else if ((value = hasPrefix(argv[i], "--verbosity="))) { - int verbosity = (int)strtol(value, NULL, 10); - if (verbosity == EINVAL || verbosity == ERANGE) { - printf("ERROR! illegal verbosity level %s\n", value); - exit(0); - } - conf.verbosity = verbosity; - } else if ((value = hasPrefix(argv[i], "--randomize="))) { - int seed; - if (sscanf(value, "%d", &seed) < 0) { - printf("ERROR! illegal seed %s\n", value); - exit(0); - } - conf.origSeed = seed; - } else if ((value = hasPrefix(argv[i], "--restrict="))) { - int branchTo; - if (sscanf(value, "%d", &branchTo) < 0 || branchTo < 1) { - printf("ERROR! illegal restricted pick branch number %d\n", branchTo); - exit(0); - } - conf.restrictPickBranch = branchTo; - } else if ((value = hasPrefix(argv[i], "--gaussuntil="))) { - int until; - if (sscanf(value, "%d", &until) < 0) { - printf("ERROR! until %s\n", value); - exit(0); - } - gaussconfig.decision_until = until; - } else if ((value = hasPrefix(argv[i], "--restarts="))) { - int maxrest; - if (sscanf(value, "%d", &maxrest) < 0 || maxrest == 0) { - printf("ERROR! illegal maximum restart number %d\n", maxrest); - exit(0); - } - conf.maxRestarts = maxrest; - } else if ((value = hasPrefix(argv[i], "--dumplearnts="))) { - if (sscanf(value, "%200s", tmpFilename) < 0 || strlen(tmpFilename) == 0) { - printf("ERROR! wrong filename '%s'\n", tmpFilename); - exit(0); - } - conf.learntsFilename.assign(tmpFilename); - conf.needToDumpLearnts = true; - } else if ((value = hasPrefix(argv[i], "--dumporig="))) { - if (sscanf(value, "%200s", tmpFilename) < 0 || strlen(tmpFilename) == 0) { - printf("ERROR! wrong filename '%s'\n", tmpFilename); - exit(0); - } - conf.origFilename.assign(tmpFilename); - conf.needToDumpOrig = true; - } else if ((value = hasPrefix(argv[i], "--alsoread="))) { - if (sscanf(value, "%400s", tmpFilename) < 0 || strlen(tmpFilename) == 0) { - printf("ERROR! wrong filename '%s'\n", tmpFilename); - exit(0); - } - filesToRead.push_back(tmpFilename); - } else if ((value = hasPrefix(argv[i], "--maxdumplearnts="))) { - if (!conf.needToDumpLearnts) { - printf("ERROR! -dumplearnts=<filename> must be first activated before issuing -maxdumplearnts=<size>\n"); - exit(0); - } - int tmp; - if (sscanf(value, "%d", &tmp) < 0 || tmp < 0) { - std::cout << "ERROR! wrong maximum dumped learnt clause size is illegal: " << tmp << std::endl; - exit(0); - } - conf.maxDumpLearntsSize = (uint32_t)tmp; - } else if ((value = hasPrefix(argv[i], "--maxsolutions="))) { - int tmp; - if (sscanf(value, "%d", &tmp) < 0 || tmp < 0) { - std::cout << "ERROR! wrong maximum number of solutions is illegal: " << tmp << std::endl; - exit(0); - } - max_nr_of_solutions = (uint32_t)tmp; - - } else if ((value = hasPrefix(argv[i], "--pavgbranch"))) { - conf.doPrintAvgBranch = true; - } else if ((value = hasPrefix(argv[i], "--greedyunbound"))) { - conf.greedyUnbound = true; - } else if ((value = hasPrefix(argv[i], "--nonormxorfind"))) { - conf.doFindXors = false; - } else if ((value = hasPrefix(argv[i], "--nobinxorfind"))) { - conf.doFindEqLits = false; - } else if ((value = hasPrefix(argv[i], "--noregbxorfind"))) { - conf.doRegFindEqLits = false; - } else if ((value = hasPrefix(argv[i], "--doextendedscc"))) { - conf.doExtendedSCC = true; - } else if ((value = hasPrefix(argv[i], "--noconglomerate"))) { - conf.doConglXors = false; - } else if ((value = hasPrefix(argv[i], "--nosimplify"))) { - conf.doSchedSimp = false; - } else if ((value = hasPrefix(argv[i], "--debuglib"))) { - debugLib = true; - } else if ((value = hasPrefix(argv[i], "--debugnewvar"))) { - debugNewVar = true; - } else if ((value = hasPrefix(argv[i], "--novarreplace"))) { - conf.doReplace = false; - } else if ((value = hasPrefix(argv[i], "--nofailedlit"))) { - conf.doFailedLit = false; - } else if ((value = hasPrefix(argv[i], "--nodisablegauss"))) { - gaussconfig.dontDisable = true; - } else if ((value = hasPrefix(argv[i], "--maxnummatrixes="))) { - int maxNumMatrixes; - if (sscanf(value, "%d", &maxNumMatrixes) < 0) { - printf("ERROR! maxnummatrixes: %s\n", value); - exit(0); - } - gaussconfig.maxNumMatrixes = maxNumMatrixes; - } else if ((value = hasPrefix(argv[i], "--noheuleprocess"))) { - conf.doHeuleProcess = false; - } else if ((value = hasPrefix(argv[i], "--nosatelite"))) { - conf.doSatELite = false; - } else if ((value = hasPrefix(argv[i], "--noxorsubs"))) { - conf.doXorSubsumption = false; - } else if ((value = hasPrefix(argv[i], "--nohyperbinres"))) { - conf.doHyperBinRes = false; - } else if ((value = hasPrefix(argv[i], "--novarelim"))) { - conf.doVarElim = false; - } else if ((value = hasPrefix(argv[i], "--nosubsume1"))) { - conf.doSubsume1 = false; - } else if ((value = hasPrefix(argv[i], "--nomatrixfind"))) { - gaussconfig.noMatrixFind = true; - } else if ((value = hasPrefix(argv[i], "--noiterreduce"))) { - gaussconfig.iterativeReduce = false; - } else if ((value = hasPrefix(argv[i], "--noordercol"))) { - gaussconfig.orderCols = false; - } else if ((value = hasPrefix(argv[i], "--maxmatrixrows="))) { - int rows; - if (sscanf(value, "%d", &rows) < 0 || rows < 0) { - printf("ERROR! maxmatrixrows: %s\n", value); - exit(0); - } - gaussconfig.maxMatrixRows = (uint32_t)rows; - } else if ((value = hasPrefix(argv[i], "--minmatrixrows="))) { - int rows; - if (sscanf(value, "%d", &rows) < 0 || rows < 0) { - printf("ERROR! minmatrixrows: %s\n", value); - exit(0); - } - gaussconfig.minMatrixRows = rows; - } else if ((value = hasPrefix(argv[i], "--savematrix"))) { - int every; - if (sscanf(value, "%d", &every) < 0) { - printf("ERROR! savematrix: %s\n", value); - exit(0); - } - gaussconfig.only_nth_gauss_save = every; - } else if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "-help") == 0 || strcmp(argv[i], "--help") == 0) { - printUsage(argv); - exit(0); - } else if ((value = hasPrefix(argv[i], "--restart="))) { - if (strcmp(value, "auto") == 0) - conf.fixRestartType = auto_restart; - else if (strcmp(value, "static") == 0) - conf.fixRestartType = static_restart; - else if (strcmp(value, "dynamic") == 0) - conf.fixRestartType = dynamic_restart; - else { - printf("ERROR! unknown restart type %s\n", value); - exit(0); - } - } else if ((value = hasPrefix(argv[i], "--nosolprint"))) { - printResult = false; - //} else if ((value = hasPrefix(argv[i], "--addoldlearnts"))) { - // conf.readdOldLearnts = true; - } else if ((value = hasPrefix(argv[i], "--nohyperbinres"))) { - conf.doHyperBinRes= false; - } else if ((value = hasPrefix(argv[i], "--noremovebins"))) { - conf.doRemUselessBins = false; - } else if ((value = hasPrefix(argv[i], "--nosubswithnbins"))) { - conf.doSubsWNonExistBins = false; - } else if ((value = hasPrefix(argv[i], "--nosubswithbins"))) { - conf.doSubsWBins = false; - } else if ((value = hasPrefix(argv[i], "--noclausevivif"))) { - conf.doClausVivif = false; - } else if ((value = hasPrefix(argv[i], "--nosortwatched"))) { - conf.doSortWatched = false; - } else if ((value = hasPrefix(argv[i], "--nolfminim"))) { - conf.doMinimLearntMore = false; - } else if ((value = hasPrefix(argv[i], "--nocalcreach"))) { - conf.doCalcReach = false; - } else if ((value = hasPrefix(argv[i], "--norecotfssr"))) { - conf.doMinimLMoreRecur = false; - } else if ((value = hasPrefix(argv[i], "--nocacheotfssr"))) { - conf.doCacheOTFSSRSet = false; - conf.doCacheOTFSSR = false; - } else if ((value = hasPrefix(argv[i], "--nootfsubsume"))) { - conf.doOTFSubsume = false; - } else if ((value = hasPrefix(argv[i], "--noremlbins"))) { - conf.doRemUselessLBins = false; - } else if ((value = hasPrefix(argv[i], "--maxconfl="))) { - int maxconfl = 0; - if (sscanf(value, "%d", &maxconfl) < 0 || maxconfl < 2) { - printf("ERROR! max confl: %s\n", value); - exit(0); - } - conf.maxConfl = maxconfl; - } else if ((value = hasPrefix(argv[i], "--plain"))) { - conf.isPlain = true; - conf.doOTFSubsume = false; - conf.doFindXors = false; - conf.doFindEqLits = false; - conf.doRegFindEqLits = false; - conf.doExtendedSCC = false; - conf.doConglXors = false; - conf.doSchedSimp = false; - conf.doReplace = false; - conf.doFailedLit = false; - conf.doHeuleProcess = false; - conf.doSatELite = false; - conf.doXorSubsumption = false; - printResult = false; - conf.doVarElim = false; - //nomatrixfind - gaussconfig.orderCols = false; - gaussconfig.iterativeReduce = false; - conf.doHyperBinRes = false; - conf.doRemUselessBins = false; - conf.doRemUselessLBins = false; - conf.doSubsWBins = false; - conf.doSubsWNonExistBins = false; - conf.doClausVivif = false; - conf.doCalcReach = false; - conf.doBXor = false; - conf.doMinimLMoreRecur = false; - conf.doMinimLearntMore = false; - conf.doCacheOTFSSR = false; - } else if ((value = hasPrefix(argv[i], "--nobxor"))) { - conf.doBXor = false; - #ifdef ENABLE_UNWIND_GLUE - } else if ((value = hasPrefix(argv[i], "--maxglue="))) { - int glue = 0; - if (sscanf(value, "%d", &glue) < 0 || glue < 2) { - printf("ERROR! maxGlue: %s\n", value); - exit(0); - } - if (glue >= (1<< MAX_GLUE_BITS)-1) { - std::cout << "Due to memory-packing limitations, max glue cannot be more than " - << ((1<< MAX_GLUE_BITS)-2) << std::endl; - exit(-1); - } - conf.maxGlue = (uint32_t)glue; - } else if ((value = hasPrefix(argv[i], "--maxgluedel"))) { - conf.doMaxGlueDel = true; - #endif //ENABLE_UNWIND_GLUE - } else if ((value = hasPrefix(argv[i], "--threads="))) { - numThreads = 0; - if (sscanf(value, "%d", &numThreads) < 0 || numThreads < 1) { - printf("ERROR! numThreads: %s\n", value); - exit(0); - } - } else if (strncmp(argv[i], "-", 1) == 0 || strncmp(argv[i], "--", 2) == 0) { - printf("ERROR! unknown flag %s\n", argv[i]); - exit(0); - } else { - //std::std::cout << "argc:" << argc << " i:" << i << ", value:" << argv[i] << std::endl; - unparsedOptions++; - if (unparsedOptions == 2) { - if (!(argc <= i+2)) { - std::cout << "You must give the input file as either:" << std::endl; - std::cout << " -- last option if you want the output to the console" << std::endl; - std::cout << " -- or one before the last option" << std::endl; - std::cout << "It appears that you did neither. Maybe you forgot the '--' from an option?" << std::endl; - exit(-1); - } - fileNamePresent = true; - if (argc == i+2) needTwoFileNames = true; - } - if (unparsedOptions == 3) { - if (!(argc <= i+1)) { - std::cout << "You must give the output file as the last option. Exiting" << std::endl; - exit(-1); - } - twoFileNamesPresent = true; - } - if (unparsedOptions == 4) { - std::cout << "You gave more than two filenames as parameters." << std::endl; - std::cout << "The first one is interpreted as the input, the second is the output." << std::endl; - std::cout << "However, the third one I cannot do anything with. EXITING" << std::endl; - exit(-1); - } - } - } - if (conf.verbosity >= 1) { - if (twoFileNamesPresent) { - std::cout << "c Outputting solution to file: " << argv[argc-1] << std::endl; - } else { - std::cout << "c Outputting solution to console" << std::endl; - } - } - - if (unparsedOptions == 2 && needTwoFileNames == true) { - std::cout << "Command line wrong. You probably frogot to add "<< std::endl - << "the '--' in front of one of the options, or you started" << std::endl - << "your output file with a hyphen ('-'). Exiting." << std::endl; - exit(-1); - } - if (!debugLib) conf.libraryUsage = false; -} - -FILE* Main::openOutputFile() -{ - FILE* res = NULL; - if (twoFileNamesPresent) { - char* filename = argv[argc-1]; - res = fopen(filename, "wb"); - if (res == NULL) { - int backup_errno = errno; - printf("Cannot open %s for writing. Problem: %s", filename, strerror(backup_errno)); - exit(1); - } - } - - return res; -} - -void Main::setDoublePrecision(const uint32_t verbosity) -{ -#if defined(_FPU_EXTENDED) && defined(_FPU_DOUBLE) - fpu_control_t oldcw, newcw; - _FPU_GETCW(oldcw); - newcw = (oldcw & ~_FPU_EXTENDED) | _FPU_DOUBLE; - _FPU_SETCW(newcw); - #pragma omp single - if (verbosity >= 1) { - printf("c WARNING: for repeatability, setting FPU to use double precision\n"); - } -#endif -} - -void Main::printVersionInfo(const uint32_t verbosity) -{ -#pragma omp single - if (verbosity >= 1) { - printf("c This is CryptoMiniSat %s\n", VERSION); - #ifdef __GNUC__ - printf("c compiled with gcc version %s\n", __VERSION__); - #else - printf("c compiled with non-gcc compiler\n"); - #endif - } -} - -int Main::singleThreadSolve() -{ - Solver solver(conf, gaussconfig); - solversToInterrupt[0] = &solver; - - printVersionInfo(conf.verbosity); - setDoublePrecision(conf.verbosity); - - parseInAllFiles(solver); - FILE* res = openOutputFile(); - - unsigned long current_nr_of_solutions = 0; - lbool ret = l_True; - while(current_nr_of_solutions < max_nr_of_solutions && ret == l_True) { - ret = solver.solve(); - current_nr_of_solutions++; - - if (ret == l_True && current_nr_of_solutions < max_nr_of_solutions) { - if (conf.verbosity >= 1) std::cout << "c Prepare for next run..." << std::endl; - printResultFunc(solver, ret, res); - - vec<Lit> lits; - for (Var var = 0; var != solver.nVars(); var++) { - if (solver.model[var] != l_Undef) { - lits.push( Lit(var, (solver.model[var] == l_True)? true : false) ); - } - } - solver.addClause(lits); - } - } - - if (conf.needToDumpLearnts) { - if (solver.dumpSortedLearnts(conf.learntsFilename, conf.maxDumpLearntsSize)) - std::cout << "c Sorted learnt clauses dumped to file '" << conf.learntsFilename << "'" << std::endl; - else { - std::cout << "Error: Cannot open file '" << conf.learntsFilename << "' to write learnt clauses!" << std::endl;; - exit(-1); - } - } - if (conf.needToDumpOrig) { - if (ret == l_False && conf.origFilename == "stdout") { - std::cout << "p cnf 0 1" << std::endl; - std::cout << "0"; - } else if (ret == l_True && conf.origFilename == "stdout") { - std::cout << "p cnf " << solver.model.size() << " " << solver.model.size() << std::endl; - for (uint32_t i = 0; i < solver.model.size(); i++) { - std::cout << (solver.model[i] == l_True ? "" : "-") << i+1 << " 0" << std::endl; - } - } else { - if (!solver.dumpOrigClauses(conf.origFilename)) { - std::cout << "Error: Cannot open file '" << conf.origFilename << "' to write learnt clauses!" << std::endl; - exit(-1); - } - if (conf.verbosity >= 1) - std::cout << "c Simplified original clauses dumped to file '" - << conf.origFilename << "'" << std::endl; - } - } - if (ret == l_Undef && conf.verbosity >= 1) { - std::cout << "c Not finished running -- signal caught or maximum restart reached" << std::endl; - } - if (conf.verbosity >= 1) solver.printStats(); - - printResultFunc(solver, ret, res); - - return correctReturnValue(ret); -} - -int Main::correctReturnValue(const lbool ret) const -{ - int retval = -1; - if (ret == l_True) retval = 10; - else if (ret == l_False) retval = 20; - else if (ret == l_Undef) retval = 15; - else { - std::cerr << "Something is very wrong, output is neither l_Undef, nor l_False, nor l_True" << std::endl; - exit(-1); - } - - #ifdef NDEBUG - // (faster than "return", which will invoke the destructor for 'Solver') - exit(retval); - #endif - return retval; -} - -int Main::oneThreadSolve() -{ - int numThreads = omp_get_num_threads(); - SolverConf myConf = conf; - int num = omp_get_thread_num(); - myConf.origSeed = num; - if (num > 0) { - if (num % 4 == 3) myConf.fixRestartType = dynamic_restart; - if (num % 4 == 2) myConf.doCalcReach = false; - //else myConf.fixRestartType = static_restart; - myConf.simpBurstSConf *= 1 + num; - myConf.simpStartMult *= 1.0 + 0.2*(double)num; - myConf.simpStartMMult *= 1.0 + 0.2*(double)num; - if (num == numThreads-1) { - //myConf.doVarElim = false; - myConf.doPerformPreSimp = false; - myConf.polarity_mode = polarity_false; - } - } - if (num != 0) myConf.verbosity = 0; - - Solver solver(myConf, gaussconfig, &sharedData); - #pragma omp critical (solversToInterr) - { - solversToInterrupt[num] = &solver; - //std::cout << "Solver num " << num << " is to be interrupted " << std::endl; - } - - printVersionInfo(myConf.verbosity); - setDoublePrecision(myConf.verbosity); - - parseInAllFiles(solver); - lbool ret = solver.solve(); - #pragma omp critical (finished) - { - finished.insert(num); - } - - int retval = 0; - #pragma omp single - { - int numNeededInterrupt = 0; - while(numNeededInterrupt != numThreads-1) { - #pragma omp critical (solversToInterr) - { - for(int i = 0; i < numThreads; i++) { - if (i != num - && solversToInterrupt.find(i) != solversToInterrupt.end() - && solversToInterrupt[i]->needToInterrupt == false - ) { - solversToInterrupt[i]->needToInterrupt = true; - numNeededInterrupt++; - } - } - } - } - bool mustWait = true; - while (mustWait) { - #pragma omp critical (finished) - if (finished.size() == (unsigned)numThreads) mustWait = false; - } - if (conf.needToDumpLearnts) { - if (!solver.dumpSortedLearnts(conf.learntsFilename, conf.maxDumpLearntsSize)) { - std::cout << "Error: Cannot open file '" << conf.learntsFilename << "' to write learnt clauses!" << std::endl;; - exit(-1); - } - if (conf.verbosity >= 1) { - std::cout << "c Sorted learnt clauses dumped to file '" - << conf.learntsFilename << "'" << std::endl; - } - } - if (conf.needToDumpOrig) { - if (!solver.dumpOrigClauses(conf.origFilename)) { - std::cout << "Error: Cannot open file '" << conf.origFilename << "' to write learnt clauses!" << std::endl; - exit(-1); - } - if (conf.verbosity >= 1) - std::cout << "c Simplified original clauses dumped to file '" - << conf.origFilename << "'" << std::endl; - } - - FILE* res = openOutputFile(); - if (conf.verbosity >= 1) solver.printStats(); - printResultFunc(solver, ret, res); - - retval = correctReturnValue(ret); - exit(retval); - } - return retval; -} - -int Main::multiThreadSolve() -{ - bool exitHere = false; - if (max_nr_of_solutions > 1) { - std::cerr << "ERROR: When multi-threading, only one solution can be found" << std::endl; - exitHere = true; - } - if (debugLib) { - std::cerr << "ERROR: When multi-threading, --debuglib cannot be used" << std::endl; - exitHere = true; - } - if (exitHere) { - std::cerr << "libarary in this version of CryptoMS is not multi-threaded :(" << std::endl; - std::cerr << "Please set option '--threads=1' on the command line." << std::endl; - exit(-1); - } - - int finalRetVal; - if (numThreads != -1) { - assert(numThreads > 0); - omp_set_num_threads(numThreads); - } - #pragma omp parallel - { - #pragma omp single - { - if (conf.verbosity >= 1) - std::cout << "c Using " << omp_get_num_threads() - << " threads" << std::endl; - } - int retval = oneThreadSolve(); - - #pragma omp single - finalRetVal = retval; - } - - return finalRetVal; -} - -/** -@brief For correctly and gracefully exiting - -It can happen that the user requests a dump of the learnt clauses. In this case, -the program must wait until it gets to a state where the learnt clauses are in -a correct state, then dump these and quit normally. This interrupt hander -is used to achieve this -*/ -void SIGINT_handler(int) -{ - #pragma omp critical - { - Solver& solver = *solversToInterrupt.begin()->second; - printf("\n"); - std::cerr << "*** INTERRUPTED ***" << std::endl; - if (solver.conf.needToDumpLearnts || solver.conf.needToDumpOrig) { - solver.needToInterrupt = true; - std::cerr << "*** Please wait. We need to interrupt cleanly" << std::endl; - std::cerr << "*** This means we might need to finish some calculations" << std::endl; - } else { - if (solver.conf.verbosity >= 1) solver.printStats(); - exit(1); - } - } -} - -int main(int argc, char** argv) -{ - Main main(argc, argv); - main.parseCommandLine(); - signal(SIGINT, SIGINT_handler); - //signal(SIGHUP,SIGINT_handler); - - try { - if (main.numThreads == 1) - return main.singleThreadSolve(); - else - return main.multiThreadSolve(); - } catch (std::bad_alloc) { - std::cerr << "Memory manager cannot handle the load. Sorry. Exiting." << std::endl; - exit(-1); - } catch (std::out_of_range oor) { - std::cerr << oor.what() << std::endl; - exit(-1); - } catch (CMSat::DimacsParseError dpe) { - std::cerr << "PARSE ERROR!" << dpe.what() << std::endl; - exit(3); - } - return 0; -} diff --git a/src/prop/cryptominisat/Solver/Main.h b/src/prop/cryptominisat/Solver/Main.h deleted file mode 100644 index a2af6dc34..000000000 --- a/src/prop/cryptominisat/Solver/Main.h +++ /dev/null @@ -1,74 +0,0 @@ -/***************************************************************************** -MiniSat -- Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson -CryptoMiniSat -- Copyright (c) 2009 Mate Soos - -Original code by MiniSat authors are under an MIT licence. -Modifications for CryptoMiniSat are under GPLv3 licence. -******************************************************************************/ - -#ifndef MAIN_H -#define MAIN_H - -#include <string> -#include <vector> -#ifndef DISABLE_ZLIB -#include <zlib.h> -#endif // DISABLE_ZLIB - -#include "Solver.h" -#include "SharedData.h" - -namespace CMSat { - -using std::string; - -class Main -{ - public: - Main(int argc, char** argv); - - void parseCommandLine(); - - int singleThreadSolve(); - int oneThreadSolve(); - int multiThreadSolve(); - - int numThreads; - - private: - - void printUsage(char** argv); - const char* hasPrefix(const char* str, const char* prefix); - void printResultFunc(const Solver& S, const lbool ret, FILE* res); - - //File reading - void readInAFile(const std::string& filename, Solver& solver); - void readInStandardInput(Solver& solver); - void parseInAllFiles(Solver& solver); - FILE* openOutputFile(); - - void setDoublePrecision(const uint32_t verbosity); - void printVersionInfo(const uint32_t verbosity); - int correctReturnValue(const lbool ret) const; - - SolverConf conf; - GaussConf gaussconfig; - - bool grouping; - bool debugLib; - bool debugNewVar; - bool printResult; - uint32_t max_nr_of_solutions; - bool fileNamePresent; - bool twoFileNamesPresent; - std::vector<std::string> filesToRead; - - SharedData sharedData; - - int argc; - char** argv; -}; - -} - -#endif //MAIN_H diff --git a/src/prop/cryptominisat/Solver/Makefile.am b/src/prop/cryptominisat/Solver/Makefile.am deleted file mode 100644 index 72a0d2fab..000000000 --- a/src/prop/cryptominisat/Solver/Makefile.am +++ /dev/null @@ -1,33 +0,0 @@ -#noinst_LTLIBRARIES = libcryptominisat.la -lib_LTLIBRARIES = libcryptominisat.la - -libcryptominisat_la_LDFLAGS = -release 2.9.2 -no-undefined - -AM_CXXFLAGS = -Wall $(all_includes) -I$(srcdir) -I$(srcdir)/../MTRand -I$(srcdir)/../mtl $(OPENMP_CXXFLAGS) - -pkgincludesubdir = $(includedir)/cryptominisat/Solver -pkgincludesub_HEADERS = BitArray.h Clause.h CSet.h MatrixFinder.h Solver.h Subsumer.h Watched.h \ - BoundedQueue.h ClauseOffset.h DimacsParser.h GaussianConfig.h OnlyNonLearntBins.h SolverTypes.h \ - time_mem.h XorFinder.h ClauseAllocator.h CompleteDetachReattacher.h DoublePackedRow.h Gaussian.h PackedMatrix.h \ - PropBy.h StateSaver.h UselessBinRemover.h XorSubsumer.h ClauseCleaner.h constants.h FailedLitSearcher.h \ - PackedRow.h RestartTypeChooser.h StreamBuffer.h VarReplacer.h XSet.h BothCache.h SolverConf.h \ - SCCFinder.h SharedData.h ClauseVivifier.h DataSync.h Main.h \ - msvc/stdint.h - -libcryptominisat_la_SOURCES = \ - ClauseCleaner.cpp FailedLitSearcher.cpp \ - VarReplacer.cpp \ - MatrixFinder.cpp \ - Solver.cpp XorFinder.cpp \ - PackedRow.cpp Gaussian.cpp StateSaver.cpp \ - RestartTypeChooser.cpp Subsumer.cpp XorSubsumer.cpp \ - SolverMisc.cpp SolverDebug.cpp ClauseAllocator.cpp \ - UselessBinRemover.cpp SCCFinder.cpp ClauseVivifier.cpp \ - CompleteDetachReattacher.cpp DimacsParser.cpp \ - OnlyNonLearntBins.cpp SolverConf.cpp DataSync.cpp \ - BothCache.cpp - -bin_PROGRAMS = cryptominisat -cryptominisat_LDADD = libcryptominisat.la -cryptominisat_LDFLAGS = -static -lz $(OPENMP_CXXFLAGS) -cryptominisat_SOURCES = Main.cpp diff --git a/src/prop/cryptominisat/Solver/Makefile.in b/src/prop/cryptominisat/Solver/Makefile.in deleted file mode 100644 index dd524fba2..000000000 --- a/src/prop/cryptominisat/Solver/Makefile.in +++ /dev/null @@ -1,665 +0,0 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - - - -VPATH = @srcdir@ -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -bin_PROGRAMS = cryptominisat$(EXEEXT) -subdir = Solver -DIST_COMMON = $(pkgincludesub_HEADERS) $(srcdir)/Makefile.am \ - $(srcdir)/Makefile.in -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.in -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; -am__vpath_adj = case $$p in \ - $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ - *) f=$$p;; \ - esac; -am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; -am__install_max = 40 -am__nobase_strip_setup = \ - srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` -am__nobase_strip = \ - for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" -am__nobase_list = $(am__nobase_strip_setup); \ - for p in $$list; do echo "$$p $$p"; done | \ - sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ - $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ - if (++n[$$2] == $(am__install_max)) \ - { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ - END { for (dir in files) print dir, files[dir] }' -am__base_list = \ - sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ - sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \ - "$(DESTDIR)$(pkgincludesubdir)" -LTLIBRARIES = $(lib_LTLIBRARIES) -libcryptominisat_la_LIBADD = -am_libcryptominisat_la_OBJECTS = ClauseCleaner.lo FailedLitSearcher.lo \ - VarReplacer.lo MatrixFinder.lo Solver.lo XorFinder.lo \ - PackedRow.lo Gaussian.lo StateSaver.lo RestartTypeChooser.lo \ - Subsumer.lo XorSubsumer.lo SolverMisc.lo SolverDebug.lo \ - ClauseAllocator.lo UselessBinRemover.lo SCCFinder.lo \ - ClauseVivifier.lo CompleteDetachReattacher.lo DimacsParser.lo \ - OnlyNonLearntBins.lo SolverConf.lo DataSync.lo BothCache.lo -libcryptominisat_la_OBJECTS = $(am_libcryptominisat_la_OBJECTS) -libcryptominisat_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ - $(CXXFLAGS) $(libcryptominisat_la_LDFLAGS) $(LDFLAGS) -o $@ -PROGRAMS = $(bin_PROGRAMS) -am_cryptominisat_OBJECTS = Main.$(OBJEXT) -cryptominisat_OBJECTS = $(am_cryptominisat_OBJECTS) -cryptominisat_DEPENDENCIES = libcryptominisat.la -cryptominisat_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ - $(CXXFLAGS) $(cryptominisat_LDFLAGS) $(LDFLAGS) -o $@ -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__depfiles_maybe = depfiles -am__mv = mv -f -CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -CXXLD = $(CXX) -CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ - $(LDFLAGS) -o $@ -SOURCES = $(libcryptominisat_la_SOURCES) $(cryptominisat_SOURCES) -DIST_SOURCES = $(libcryptominisat_la_SOURCES) $(cryptominisat_SOURCES) -HEADERS = $(pkgincludesub_HEADERS) -ETAGS = etags -CTAGS = ctags -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CXX = @CXX@ -CXXCPP = @CXXCPP@ -CXXDEPMODE = @CXXDEPMODE@ -CXXFLAGS = @CXXFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DLLTOOL = @DLLTOOL@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MKDIR_P = @MKDIR_P@ -NM = @NM@ -NMEDIT = @NMEDIT@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OPENMP_CXXFLAGS = @OPENMP_CXXFLAGS@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -RANLIB = @RANLIB@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -VERSION = @VERSION@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_CXX = @ac_ct_CXX@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ - -#noinst_LTLIBRARIES = libcryptominisat.la -lib_LTLIBRARIES = libcryptominisat.la -libcryptominisat_la_LDFLAGS = -release 2.9.2 -no-undefined -AM_CXXFLAGS = -Wall $(all_includes) -I$(srcdir) -I$(srcdir)/../MTRand -I$(srcdir)/../mtl $(OPENMP_CXXFLAGS) -pkgincludesubdir = $(includedir)/cryptominisat/Solver -pkgincludesub_HEADERS = BitArray.h Clause.h CSet.h MatrixFinder.h Solver.h Subsumer.h Watched.h \ - BoundedQueue.h ClauseOffset.h DimacsParser.h GaussianConfig.h OnlyNonLearntBins.h SolverTypes.h \ - time_mem.h XorFinder.h ClauseAllocator.h CompleteDetachReattacher.h DoublePackedRow.h Gaussian.h PackedMatrix.h \ - PropBy.h StateSaver.h UselessBinRemover.h XorSubsumer.h ClauseCleaner.h constants.h FailedLitSearcher.h \ - PackedRow.h RestartTypeChooser.h StreamBuffer.h VarReplacer.h XSet.h BothCache.h SolverConf.h \ - SCCFinder.h SharedData.h ClauseVivifier.h DataSync.h Main.h \ - msvc/stdint.h - -libcryptominisat_la_SOURCES = \ - ClauseCleaner.cpp FailedLitSearcher.cpp \ - VarReplacer.cpp \ - MatrixFinder.cpp \ - Solver.cpp XorFinder.cpp \ - PackedRow.cpp Gaussian.cpp StateSaver.cpp \ - RestartTypeChooser.cpp Subsumer.cpp XorSubsumer.cpp \ - SolverMisc.cpp SolverDebug.cpp ClauseAllocator.cpp \ - UselessBinRemover.cpp SCCFinder.cpp ClauseVivifier.cpp \ - CompleteDetachReattacher.cpp DimacsParser.cpp \ - OnlyNonLearntBins.cpp SolverConf.cpp DataSync.cpp \ - BothCache.cpp - -cryptominisat_LDADD = libcryptominisat.la -cryptominisat_LDFLAGS = -static -lz $(OPENMP_CXXFLAGS) -cryptominisat_SOURCES = Main.cpp -all: all-am - -.SUFFIXES: -.SUFFIXES: .cpp .lo .o .obj -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Solver/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu Solver/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): -install-libLTLIBRARIES: $(lib_LTLIBRARIES) - @$(NORMAL_INSTALL) - test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" - @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ - list2=; for p in $$list; do \ - if test -f $$p; then \ - list2="$$list2 $$p"; \ - else :; fi; \ - done; \ - test -z "$$list2" || { \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ - } - -uninstall-libLTLIBRARIES: - @$(NORMAL_UNINSTALL) - @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ - for p in $$list; do \ - $(am__strip_dir) \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ - done - -clean-libLTLIBRARIES: - -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) - @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ - dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ - test "$$dir" != "$$p" || dir=.; \ - echo "rm -f \"$${dir}/so_locations\""; \ - rm -f "$${dir}/so_locations"; \ - done -libcryptominisat.la: $(libcryptominisat_la_OBJECTS) $(libcryptominisat_la_DEPENDENCIES) - $(libcryptominisat_la_LINK) -rpath $(libdir) $(libcryptominisat_la_OBJECTS) $(libcryptominisat_la_LIBADD) $(LIBS) -install-binPROGRAMS: $(bin_PROGRAMS) - @$(NORMAL_INSTALL) - test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" - @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ - for p in $$list; do echo "$$p $$p"; done | \ - sed 's/$(EXEEXT)$$//' | \ - while read p p1; do if test -f $$p || test -f $$p1; \ - then echo "$$p"; echo "$$p"; else :; fi; \ - done | \ - sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ - -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ - sed 'N;N;N;s,\n, ,g' | \ - $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ - { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ - if ($$2 == $$4) files[d] = files[d] " " $$1; \ - else { print "f", $$3 "/" $$4, $$1; } } \ - END { for (d in files) print "f", d, files[d] }' | \ - while read type dir files; do \ - if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ - test -z "$$files" || { \ - echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ - $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ - } \ - ; done - -uninstall-binPROGRAMS: - @$(NORMAL_UNINSTALL) - @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ - files=`for p in $$list; do echo "$$p"; done | \ - sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ - -e 's/$$/$(EXEEXT)/' `; \ - test -n "$$list" || exit 0; \ - echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(bindir)" && rm -f $$files - -clean-binPROGRAMS: - @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ - echo " rm -f" $$list; \ - rm -f $$list || exit $$?; \ - test -n "$(EXEEXT)" || exit 0; \ - list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ - echo " rm -f" $$list; \ - rm -f $$list -cryptominisat$(EXEEXT): $(cryptominisat_OBJECTS) $(cryptominisat_DEPENDENCIES) - @rm -f cryptominisat$(EXEEXT) - $(cryptominisat_LINK) $(cryptominisat_OBJECTS) $(cryptominisat_LDADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BothCache.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ClauseAllocator.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ClauseCleaner.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ClauseVivifier.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CompleteDetachReattacher.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DataSync.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DimacsParser.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FailedLitSearcher.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Gaussian.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Main.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MatrixFinder.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OnlyNonLearntBins.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PackedRow.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RestartTypeChooser.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SCCFinder.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Solver.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SolverConf.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SolverDebug.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SolverMisc.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StateSaver.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Subsumer.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UselessBinRemover.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/VarReplacer.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/XorFinder.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/XorSubsumer.Plo@am__quote@ - -.cpp.o: -@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< - -.cpp.obj: -@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` - -.cpp.lo: -@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs -install-pkgincludesubHEADERS: $(pkgincludesub_HEADERS) - @$(NORMAL_INSTALL) - test -z "$(pkgincludesubdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgincludesubdir)" - @list='$(pkgincludesub_HEADERS)'; test -n "$(pkgincludesubdir)" || list=; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkgincludesubdir)'"; \ - $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludesubdir)" || exit $$?; \ - done - -uninstall-pkgincludesubHEADERS: - @$(NORMAL_UNINSTALL) - @list='$(pkgincludesub_HEADERS)'; test -n "$(pkgincludesubdir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - test -n "$$files" || exit 0; \ - echo " ( cd '$(DESTDIR)$(pkgincludesubdir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(pkgincludesubdir)" && rm -f $$files - -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - set x; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(HEADERS) -install-binPROGRAMS: install-libLTLIBRARIES - -installdirs: - for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgincludesubdir)"; do \ - test -z "$$dir" || $(MKDIR_P) "$$dir"; \ - done -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \ - clean-libtool mostlyclean-am - -distclean: distclean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: install-pkgincludesubHEADERS - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: install-binPROGRAMS install-libLTLIBRARIES - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: uninstall-binPROGRAMS uninstall-libLTLIBRARIES \ - uninstall-pkgincludesubHEADERS - -.MAKE: install-am install-strip - -.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ - clean-generic clean-libLTLIBRARIES clean-libtool ctags \ - distclean distclean-compile distclean-generic \ - distclean-libtool distclean-tags distdir dvi dvi-am html \ - html-am info info-am install install-am install-binPROGRAMS \ - install-data install-data-am install-dvi install-dvi-am \ - install-exec install-exec-am install-html install-html-am \ - install-info install-info-am install-libLTLIBRARIES \ - install-man install-pdf install-pdf-am \ - install-pkgincludesubHEADERS install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ - pdf pdf-am ps ps-am tags uninstall uninstall-am \ - uninstall-binPROGRAMS uninstall-libLTLIBRARIES \ - uninstall-pkgincludesubHEADERS - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/src/prop/cryptominisat/Solver/MatrixFinder.cpp b/src/prop/cryptominisat/Solver/MatrixFinder.cpp deleted file mode 100644 index 4a1522d80..000000000 --- a/src/prop/cryptominisat/Solver/MatrixFinder.cpp +++ /dev/null @@ -1,248 +0,0 @@ -/*********************************************************************************** -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 "MatrixFinder.h" - -#include "Solver.h" -#include "Gaussian.h" -#include "GaussianConfig.h" -#include "ClauseCleaner.h" -#include "time_mem.h" - -#include <set> -#include <map> -#include <iomanip> -#include <math.h> - -//#define VERBOSE_DEBUG -//#define PART_FINDING - -using namespace CMSat; - -using std::set; -using std::map; - -MatrixFinder::MatrixFinder(Solver& _solver) : - solver(_solver) -{ -} - -inline Var MatrixFinder::fingerprint(const XorClause& c) const -{ - Var fingerprint = 0; - - for (const Lit* a = &c[0], *end = a + c.size(); a != end; a++) - fingerprint |= a->var(); - - return fingerprint; -} - -inline bool MatrixFinder::firstPartOfSecond(const XorClause& c1, const XorClause& c2) const -{ - uint32_t i1, i2; - for (i1 = 0, i2 = 0; i1 < c1.size() && i2 < c2.size();) { - if (c1[i1].var() != c2[i2].var()) - i2++; - else { - i1++; - i2++; - } - } - - return (i1 == c1.size()); -} - -bool MatrixFinder::findMatrixes() -{ - assert(solver.decisionLevel() == 0); - assert(solver.ok); - - table.clear(); - table.resize(solver.nVars(), var_Undef); - reverseTable.clear(); - matrix_no = 0; - double myTime = cpuTime(); - - if (solver.xorclauses.size() < MIN_GAUSS_XOR_CLAUSES || - solver.gaussconfig.decision_until <= 0 || - solver.xorclauses.size() > MAX_GAUSS_XOR_CLAUSES - ) { - return true; - } - - solver.clauseCleaner->cleanClauses(solver.xorclauses, ClauseCleaner::xorclauses); - if (!solver.ok) return false; - - if (solver.gaussconfig.noMatrixFind) { - if (solver.conf.verbosity >=1) - std::cout << "c Matrix finding disabled through switch. Putting all xors into matrix." << std::endl; - vector<XorClause*> xorclauses; - xorclauses.reserve(solver.xorclauses.size()); - for (uint32_t i = 0; i < solver.xorclauses.size(); i++) - xorclauses.push_back(solver.xorclauses[i]); - solver.gauss_matrixes.push_back(new Gaussian(solver, solver.gaussconfig, 0, xorclauses)); - return true; - } - - for (XorClause** c = solver.xorclauses.getData(), **end = c + solver.xorclauses.size(); c != end; c++) { - set<uint32_t> tomerge; - vector<Var> newSet; - for (Lit *l = &(**c)[0], *end2 = l + (**c).size(); l != end2; l++) { - if (table[l->var()] != var_Undef) - tomerge.insert(table[l->var()]); - else - newSet.push_back(l->var()); - } - if (tomerge.size() == 1) { - const uint32_t into = *tomerge.begin(); - map<uint32_t, vector<Var> >::iterator intoReverse = reverseTable.find(into); - for (uint32_t i = 0; i < newSet.size(); i++) { - intoReverse->second.push_back(newSet[i]); - table[newSet[i]] = into; - } - continue; - } - - for (set<uint32_t>::iterator it = tomerge.begin(); it != tomerge.end(); it++) { - newSet.insert(newSet.end(), reverseTable[*it].begin(), reverseTable[*it].end()); - reverseTable.erase(*it); - } - for (uint32_t i = 0; i < newSet.size(); i++) - table[newSet[i]] = matrix_no; - reverseTable[matrix_no] = newSet; - matrix_no++; - } - - #ifdef VERBOSE_DEBUG - for (map<uint32_t, vector<Var> >::iterator it = reverseTable.begin(), end = reverseTable.end(); it != end; it++) { - std::cout << "-- set begin --" << std::endl; - for (vector<Var>::iterator it2 = it->second.begin(), end2 = it->second.end(); it2 != end2; it2++) { - std::cout << *it2 << ", "; - } - std::cout << "-------" << std::endl; - } - #endif - - uint32_t numMatrixes = setMatrixes(); - - if (solver.conf.verbosity >=1) - std::cout << "c Finding matrixes : " << cpuTime() - myTime - << " s (found " << numMatrixes << ")" - << std::endl; - - for (vector<Gaussian*>::iterator gauss = solver.gauss_matrixes.begin(), end = solver.gauss_matrixes.end(); gauss != end; gauss++) { - if (!(*gauss)->full_init()) return false; - } - - return true; -} - -uint32_t MatrixFinder::setMatrixes() -{ - vector<pair<uint32_t, uint32_t> > numXorInMatrix; - for (uint32_t i = 0; i < matrix_no; i++) - numXorInMatrix.push_back(std::make_pair(i, 0)); - - vector<uint32_t> sumXorSizeInMatrix(matrix_no, 0); - vector<vector<uint32_t> > xorSizesInMatrix(matrix_no); - vector<vector<XorClause*> > xorsInMatrix(matrix_no); - - #ifdef PART_FINDING - vector<vector<Var> > xorFingerprintInMatrix(matrix_no); - #endif - - for (XorClause** c = solver.xorclauses.getData(), **end = c + solver.xorclauses.size(); c != end; c++) { - XorClause& x = **c; - const uint32_t matrix = table[x[0].var()]; - assert(matrix < matrix_no); - - //for stats - numXorInMatrix[matrix].second++; - sumXorSizeInMatrix[matrix] += x.size(); - xorSizesInMatrix[matrix].push_back(x.size()); - xorsInMatrix[matrix].push_back(&x); - - #ifdef PART_FINDING - xorFingerprintInMatrix[matrix].push_back(fingerprint(x)); - #endif //PART_FINDING - } - - std::sort(numXorInMatrix.begin(), numXorInMatrix.end(), mysorter()); - - #ifdef PART_FINDING - for (uint32_t i = 0; i < matrix_no; i++) - findParts(xorFingerprintInMatrix[i], xorsInMatrix[i]); - #endif //PART_FINDING - - uint32_t realMatrixNum = 0; - for (int a = matrix_no-1; a != -1; a--) { - uint32_t i = numXorInMatrix[a].first; - - if (numXorInMatrix[a].second < 3) - continue; - - const uint32_t totalSize = reverseTable[i].size()*numXorInMatrix[a].second; - const double density = (double)sumXorSizeInMatrix[i]/(double)totalSize*100.0; - double avg = (double)sumXorSizeInMatrix[i]/(double)numXorInMatrix[a].second; - double variance = 0.0; - for (uint32_t i2 = 0; i2 < xorSizesInMatrix[i].size(); i2++) - variance += pow((double)xorSizesInMatrix[i][i2]-avg, 2); - variance /= (double)xorSizesInMatrix.size(); - const double stdDeviation = sqrt(variance); - - if (numXorInMatrix[a].second >= solver.gaussconfig.minMatrixRows - && numXorInMatrix[a].second <= solver.gaussconfig.maxMatrixRows - && realMatrixNum <= solver.gaussconfig.maxNumMatrixes) - { - if (solver.conf.verbosity >=1) - std::cout << "c Matrix no " << std::setw(2) << realMatrixNum; - solver.gauss_matrixes.push_back(new Gaussian(solver, solver.gaussconfig, realMatrixNum, xorsInMatrix[i])); - realMatrixNum++; - - } else { - if (solver.conf.verbosity >=1 /*&& numXorInMatrix[a].second >= 20*/) - std::cout << "c Unused Matrix "; - } - if (solver.conf.verbosity >=1 /*&& numXorInMatrix[a].second >= 20*/) { - std::cout << std::setw(7) << numXorInMatrix[a].second << " x" << std::setw(5) << reverseTable[i].size(); - std::cout << " density:" << std::setw(5) << std::fixed << std::setprecision(1) << density << "%"; - std::cout << " xorlen avg:" << std::setw(5) << std::fixed << std::setprecision(2) << avg; - std::cout << " stdev:" << std::setw(6) << std::fixed << std::setprecision(2) << stdDeviation << std::endl; - } - } - - return realMatrixNum; -} - -void MatrixFinder::findParts(vector<Var>& xorFingerprintInMatrix, vector<XorClause*>& xorsInMatrix) -{ - uint32_t ai = 0; - for (XorClause **a = &xorsInMatrix[0], **end = a + xorsInMatrix.size(); a != end; a++, ai++) { - const Var fingerprint = xorFingerprintInMatrix[ai]; - uint32_t ai2 = 0; - for (XorClause **a2 = &xorsInMatrix[0]; a2 != end; a2++, ai2++) { - if (ai == ai2) continue; - const Var fingerprint2 = xorFingerprintInMatrix[ai2]; - if (((fingerprint & fingerprint2) == fingerprint) && firstPartOfSecond(**a, **a2)) { - std::cout << "First part of second:" << std::endl; - (*a)->plainPrint(); - (*a2)->plainPrint(); - std::cout << "END" << std::endl; - } - } - } -} diff --git a/src/prop/cryptominisat/Solver/MatrixFinder.h b/src/prop/cryptominisat/Solver/MatrixFinder.h deleted file mode 100644 index 21210b0f7..000000000 --- a/src/prop/cryptominisat/Solver/MatrixFinder.h +++ /dev/null @@ -1,70 +0,0 @@ -/*********************************************************************************** -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 MATRIXFINDER_H -#define MATRIXFINDER_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 CMSat { - -class Solver; - -using std::map; -using std::vector; -using std::pair; - -class MatrixFinder { - - public: - MatrixFinder(Solver& solver); - bool findMatrixes(); - - private: - uint32_t setMatrixes(); - - struct mysorter - { - bool operator () (const pair<uint32_t, uint32_t>& left, const pair<uint32_t, uint32_t>& right) - { - return left.second < right.second; - } - }; - - void findParts(vector<Var>& xorFingerprintInMatrix, vector<XorClause*>& xorsInMatrix); - inline Var fingerprint(const XorClause& c) const; - inline bool firstPartOfSecond(const XorClause& c1, const XorClause& c2) const; - - map<uint32_t, vector<Var> > reverseTable; //matrix -> vars - vector<Var> table; //var -> matrix - uint32_t matrix_no; - - Solver& solver; -}; - -} - -#endif //MATRIXFINDER_H diff --git a/src/prop/cryptominisat/Solver/OnlyNonLearntBins.cpp b/src/prop/cryptominisat/Solver/OnlyNonLearntBins.cpp deleted file mode 100644 index 021178b08..000000000 --- a/src/prop/cryptominisat/Solver/OnlyNonLearntBins.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/*********************************************************************** -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 "OnlyNonLearntBins.h" - -#include <iomanip> -#include "Solver.h" -#include "Clause.h" -#include "VarReplacer.h" -#include "ClauseCleaner.h" -#include "time_mem.h" - -using namespace CMSat; - -OnlyNonLearntBins::OnlyNonLearntBins(Solver& _solver) : - solver(_solver) -{} - -/** -@brief Propagate recursively on non-learnt binaries -*/ -bool OnlyNonLearntBins::propagate() -{ - while (solver.qhead < solver.trail.size()) { - Lit p = solver.trail[solver.qhead++]; - vec<WatchedBin> & wbin = binwatches[p.toInt()]; - solver.propagations += wbin.size()/2 + 2; - for(WatchedBin *k = wbin.getData(), *end = wbin.getDataEnd(); k != end; k++) { - lbool val = solver.value(k->impliedLit); - if (val.isUndef()) { - solver.uncheckedEnqueueLight(k->impliedLit); - } else if (val == l_False) { - return false; - } - } - } - - return true; -} - -/** -@brief Fill internal watchlists with non-binary clauses -*/ -bool OnlyNonLearntBins::fill() -{ - uint32_t numBins = 0; - double myTime = cpuTime(); - binwatches.growTo(solver.nVars()*2); - - uint32_t wsLit = 0; - for (const vec<Watched> *it = solver.watches.getData(), *end = solver.watches.getDataEnd(); it != end; it++, wsLit++) { - const vec<Watched>& ws = *it; - for (vec<Watched>::const_iterator it2 = ws.getData(), end2 = ws.getDataEnd(); it2 != end2; it2++) { - if (it2->isBinary() && !it2->getLearnt()) { - binwatches[wsLit].push(WatchedBin(it2->getOtherLit())); - numBins++; - } - } - } - - if (solver.conf.verbosity >= 3) { - std::cout << "c Time to fill non-learnt binary watchlists:" - << std::fixed << std::setprecision(2) << std::setw(5) - << cpuTime() - myTime << " s" - << " num non-learnt bins: " << std::setw(10) << numBins - << std::endl; - } - - return true; -} diff --git a/src/prop/cryptominisat/Solver/OnlyNonLearntBins.h b/src/prop/cryptominisat/Solver/OnlyNonLearntBins.h deleted file mode 100644 index 7092331e6..000000000 --- a/src/prop/cryptominisat/Solver/OnlyNonLearntBins.h +++ /dev/null @@ -1,72 +0,0 @@ -/*********************************************************************** -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 ONLYNONLEARNTBINS_H -#define ONLYNONLEARNTBINS_H - -#include "Solver.h" - -namespace CMSat { - -/** -@brief Handles propagation, addition&removal of non-learnt binary clauses - -It takes a snapshot of Solver's non-learnt binary clauses, builds its own -watchlists, and does everything itself.*/ -class OnlyNonLearntBins -{ - public: - OnlyNonLearntBins(Solver& solver); - - /** - @brief For storing a binary clause - */ - class WatchedBin { - public: - WatchedBin(Lit _impliedLit) : impliedLit(_impliedLit) {}; - Lit impliedLit; - }; - - //propagation - bool propagate(); - - //Management of clauses - bool fill(); - - //helper - inline uint32_t getWatchSize(const Lit lit) const; - inline const vec<vec<WatchedBin> >& getBinWatches() const; - - private: - vec<vec<WatchedBin> > binwatches; ///<Internal wathclists for non-learnt binary clauses - - Solver& solver; -}; - -inline uint32_t OnlyNonLearntBins::getWatchSize(const Lit lit) const -{ - return binwatches[lit.toInt()].size(); -} - -inline const vec<vec<OnlyNonLearntBins::WatchedBin> >& OnlyNonLearntBins::getBinWatches() const -{ - return binwatches; -} - -} - -#endif //ONLYNONLEARNTBINS_H diff --git a/src/prop/cryptominisat/Solver/PackedMatrix.h b/src/prop/cryptominisat/Solver/PackedMatrix.h deleted file mode 100644 index 2879a4b45..000000000 --- a/src/prop/cryptominisat/Solver/PackedMatrix.h +++ /dev/null @@ -1,221 +0,0 @@ -/*********************************************************************************** -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 PACKEDMATRIX_H -#define PACKEDMATRIX_H - -#include <algorithm> -#ifdef _MSC_VER -#include <msvc/stdint.h> -#else -#include <stdint.h> -#endif //_MSC_VER - -#include "PackedRow.h" - -//#define DEBUG_MATRIX - -namespace CMSat { - -class PackedMatrix -{ -public: - PackedMatrix() : - mp(NULL) - , numRows(0) - , numCols(0) - { - } - - PackedMatrix(const PackedMatrix& b) : - numRows(b.numRows) - , numCols(b.numCols) - { - #ifdef DEBUG_MATRIX - assert(b.numRows > 0 && b.numCols > 0); - #endif - - mp = new uint64_t[numRows*2*(numCols+1)]; - memcpy(mp, b.mp, sizeof(uint64_t)*numRows*2*(numCols+1)); - } - - ~PackedMatrix() - { - delete[] mp; - } - - void resize(const uint32_t num_rows, uint32_t num_cols) - { - num_cols = num_cols / 64 + (bool)(num_cols % 64); - if (numRows*2*(numCols+1) < num_rows*2*(num_cols+1)) { - delete[] mp; - mp = new uint64_t[num_rows*2*(num_cols+1)]; - } - numRows = num_rows; - numCols = num_cols; - } - - void resizeNumRows(const uint32_t num_rows) - { - #ifdef DEBUG_MATRIX - assert(num_rows <= numRows); - #endif - - numRows = num_rows; - } - - PackedMatrix& operator=(const PackedMatrix& b) - { - #ifdef DEBUG_MATRIX - //assert(b.numRows > 0 && b.numCols > 0); - #endif - - if (numRows*2*(numCols+1) < b.numRows*2*(b.numCols+1)) { - delete[] mp; - mp = new uint64_t[b.numRows*2*(b.numCols+1)]; - } - - numRows = b.numRows; - numCols = b.numCols; - memcpy(mp, b.mp, sizeof(uint64_t)*numRows*2*(numCols+1)); - - return *this; - } - - inline PackedRow getMatrixAt(const uint32_t i) - { - #ifdef DEBUG_MATRIX - assert(i <= numRows); - #endif - - return PackedRow(numCols, mp+i*2*(numCols+1)); - } - inline PackedRow getVarsetAt(const uint32_t i) - { - #ifdef DEBUG_MATRIX - assert(i <= numRows); - #endif - - return PackedRow(numCols, mp+i*2*(numCols+1)+(numCols+1)); - } - - inline PackedRow getMatrixAt(const uint32_t i) const - { - #ifdef DEBUG_MATRIX - assert(i <= numRows); - #endif - - return PackedRow(numCols, mp+i*2*(numCols+1)); - } - - inline PackedRow getVarsetAt(const uint32_t i) const - { - #ifdef DEBUG_MATRIX - assert(i <= numRows); - #endif - - return PackedRow(numCols, mp+i*2*(numCols+1)+(numCols+1)); - } - - class iterator - { - public: - friend class PackedMatrix; - - PackedRow operator*() - { - return PackedRow(numCols, mp); - } - - iterator& operator++() - { - mp += 2*(numCols+1); - return *this; - } - - iterator operator+(const uint32_t num) const - { - iterator ret(*this); - ret.mp += 2*(numCols+1)*num; - return ret; - } - - uint32_t operator-(const iterator& b) const - { - return (mp - b.mp)/(2*(numCols+1)); - } - - void operator+=(const uint32_t num) - { - mp += 2*(numCols+1)*num; - } - - bool operator!=(const iterator& it) const - { - return mp != it.mp; - } - - bool operator==(const iterator& it) const - { - return mp == it.mp; - } - - private: - iterator(uint64_t* _mp, const uint32_t _numCols) : - mp(_mp) - , numCols(_numCols) - {} - - uint64_t* mp; - const uint32_t numCols; - }; - - inline iterator beginMatrix() - { - return iterator(mp, numCols); - } - - inline iterator endMatrix() - { - return iterator(mp+numRows*2*(numCols+1), numCols); - } - - inline iterator beginVarset() - { - return iterator(mp+(numCols+1), numCols); - } - - inline iterator endVarset() - { - return iterator(mp+(numCols+1)+numRows*2*(numCols+1), numCols); - } - - inline uint32_t getSize() const - { - return numRows; - } - -private: - - uint64_t* mp; - uint32_t numRows; - uint32_t numCols; -}; - -} - -#endif //PACKEDMATRIX_H diff --git a/src/prop/cryptominisat/Solver/PackedRow.cpp b/src/prop/cryptominisat/Solver/PackedRow.cpp deleted file mode 100644 index 8fd72dc25..000000000 --- a/src/prop/cryptominisat/Solver/PackedRow.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/*********************************************************************************** -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 "PackedRow.h" - -using namespace CMSat; - -bool PackedRow::operator ==(const PackedRow& b) const -{ - #ifdef DEBUG_ROW - assert(size > 0); - assert(b.size > 0); - assert(size == b.size); - #endif - - return (std::equal(b.mp-1, b.mp+size, mp-1)); -} - -bool PackedRow::operator !=(const PackedRow& b) const -{ - #ifdef DEBUG_ROW - assert(size > 0); - assert(b.size > 0); - assert(size == b.size); - #endif - - return (!std::equal(b.mp-1, b.mp+size, mp-1)); -} - -uint32_t PackedRow::popcnt() const -{ - uint32_t popcnt = 0; - for (uint32_t i = 0; i < size; i++) if (mp[i]) { - uint64_t tmp = mp[i]; - for (uint32_t i2 = 0; i2 < 64; i2++) { - popcnt += (tmp & 1); - tmp >>= 1; - } - } - return popcnt; -} - -uint32_t PackedRow::popcnt(const uint32_t from) const -{ - uint32_t popcnt = 0; - for (uint32_t i = from/64; i != size; i++) if (mp[i]) { - uint64_t tmp = mp[i]; - uint32_t i2; - if (i == from/64) { - i2 = from%64; - tmp >>= i2; - } else - i2 = 0; - for (; i2 < 64; i2++) { - popcnt += (tmp & 1); - tmp >>= 1; - } - } - return popcnt; -} - -bool PackedRow::fill(vec<Lit>& tmp_clause, const vec<lbool>& assigns, const vector<Var>& col_to_var_original) const -{ - bool final = !is_true_internal; - - tmp_clause.clear(); - uint32_t col = 0; - bool wasundef = false; - for (uint32_t i = 0; i < size; i++) for (uint32_t i2 = 0; i2 < 64; i2++) { - if ((mp[i] >> i2) &1) { - 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(); - tmp_clause.push(Lit(var, val_bool)); - final ^= val_bool; - if (val.isUndef()) { - assert(!wasundef); - Lit tmp(tmp_clause[0]); - tmp_clause[0] = tmp_clause.last(); - tmp_clause.last() = tmp; - wasundef = true; - } - } - col++; - } - if (wasundef) { - tmp_clause[0] ^= final; - //assert(ps != ps_first+1); - } else - assert(!final); - - return wasundef; -} diff --git a/src/prop/cryptominisat/Solver/PackedRow.h b/src/prop/cryptominisat/Solver/PackedRow.h deleted file mode 100644 index a9d2d7134..000000000 --- a/src/prop/cryptominisat/Solver/PackedRow.h +++ /dev/null @@ -1,252 +0,0 @@ -/*********************************************************************************** -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 PACKEDROW_H -#define PACKEDROW_H - -//#define DEBUG_ROW - -#include <vector> -#ifdef _MSC_VER -#include <msvc/stdint.h> -#else -#include <stdint.h> -#endif //_MSC_VER - -#include "SolverTypes.h" -#include "Vec.h" -#include <string.h> -#include <iostream> -#include <algorithm> -#include <limits> - -namespace CMSat { - -using std::vector; - -class PackedMatrix; - -class PackedRow -{ -public: - bool operator ==(const PackedRow& b) const; - bool operator !=(const PackedRow& b) const; - - PackedRow& operator=(const PackedRow& b) - { - #ifdef DEBUG_ROW - assert(size > 0); - assert(b.size > 0); - assert(size == b.size); - #endif - - memcpy(mp-1, b.mp-1, size+1); - return *this; - } - - PackedRow& operator^=(const PackedRow& b) - { - #ifdef DEBUG_ROW - assert(size > 0); - assert(b.size > 0); - assert(b.size == size); - #endif - - for (uint32_t i = 0; i != size; i++) { - *(mp + i) ^= *(b.mp + i); - } - - is_true_internal ^= b.is_true_internal; - return *this; - } - - void xorBoth(const PackedRow& b) - { - #ifdef DEBUG_ROW - assert(size > 0); - assert(b.size > 0); - assert(b.size == size); - #endif - - for (uint32_t i = 0; i != 2*size+1; i++) { - *(mp + i) ^= *(b.mp + i); - } - - is_true_internal ^= b.is_true_internal; - } - - - uint32_t popcnt() const; - uint32_t popcnt(uint32_t from) const; - - bool popcnt_is_one() const - { - #if __GNUC__ >= 4 - int ret = 0; - for (uint32_t i = 0; i != size; i++) { - ret += __builtin_popcount(mp[i]&0xffffffff); - ret += __builtin_popcount(mp[i]>>32); - if (ret > 1) return false; - } - return ret == 1; - #else - uint32_t popcount = 0; - for (uint32_t i = 0; i != size; i++) { - uint64_t tmp = mp[i]; - while(tmp) { - popcount += tmp & 1; - tmp >>= 1; - } - } - return popcount == 1; - #endif - } - - bool popcnt_is_one(uint32_t from) const - { - from++; - - uint64_t tmp = mp[from/64]; - tmp >>= from%64; - if (tmp) return false; - - for (uint32_t i = from/64+1; i != size; i++) - if (mp[i]) return false; - return true; - } - - inline const uint64_t& is_true() const - { - return is_true_internal; - } - - inline bool isZero() const - { - for (uint32_t i = 0; i != size; i++) { - if (mp[i]) return false; - } - return true; - } - - inline void setZero() - { - memset(mp, 0, sizeof(uint64_t)*size); - } - - 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 ^= (uint64_t)b; - } - - inline void setBit(const uint32_t i) - { - mp[i/64] |= ((uint64_t)1 << (i%64)); - } - - void swapBoth(PackedRow b) - { - #ifdef DEBUG_ROW - assert(size > 0); - assert(b.size > 0); - assert(b.size == size); - #endif - - uint64_t * __restrict mp1 = mp-1; - uint64_t * __restrict mp2 = b.mp-1; - - uint32_t i = 2*(size+1); - - while(i != 0) { - std::swap(*mp1, *mp2); - mp1++; - mp2++; - i--; - } - } - - inline bool operator[](const uint32_t& i) const - { - #ifdef DEBUG_ROW - assert(size*64 > i); - #endif - - return (mp[i/64] >> (i%64)) & 1; - } - - template<class T> - 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 (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); - } - - is_true_internal = !v.xorEqualFalse(); - } - - bool fill(vec<Lit>& tmp_clause, const vec<lbool>& assigns, const vector<Var>& col_to_var_original) const; - - inline unsigned long int scan(const unsigned long int var) const - { - #ifdef DEBUG_ROW - assert(size > 0); - #endif - - for(uint32_t i = var; i != size*64; i++) { - if (this->operator[](i)) return i; - } - - return std::numeric_limits<unsigned long int>::max(); - } - -private: - friend class PackedMatrix; - friend std::ostream& operator << (std::ostream& os, const PackedRow& m); - - PackedRow(const uint32_t _size, uint64_t* const _mp) : - mp(_mp+1) - , is_true_internal(*_mp) - , size(_size) - {} - - uint64_t* __restrict const mp; - uint64_t& is_true_internal; - const uint32_t size; -}; - -inline std::ostream& operator << (std::ostream& os, const PackedRow& m) -{ - for(uint32_t i = 0; i < m.size*64; i++) { - os << m[i]; - } - os << " -- xor: " << m.is_true(); - return os; -} - -} - -#endif //PACKEDROW_H diff --git a/src/prop/cryptominisat/Solver/PropBy.h b/src/prop/cryptominisat/Solver/PropBy.h deleted file mode 100644 index 11e35cf2d..000000000 --- a/src/prop/cryptominisat/Solver/PropBy.h +++ /dev/null @@ -1,257 +0,0 @@ -/*********************************************************************** -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 PROPBY_H -#define PROPBY_H - -#include "SolverTypes.h" -#include "Clause.h" -#ifdef _MSC_VER -#include <msvc/stdint.h> -#else -#include <stdint.h> -#endif //_MSC_VER -#include <stdio.h> - -//#define DEBUG_PROPAGATEFROM - -#include "ClauseOffset.h" -#include "ClauseAllocator.h" - -namespace CMSat { - -class PropBy -{ - private: - uint64_t propType:2; - //0: clause, NULL - //1: clause, non-null - //2: binary - //3: tertiary - uint64_t data1:30; - uint64_t data2:32; - - public: - PropBy() : - propType(0) - , data1(0) - , data2(0) - {} - - PropBy(ClauseOffset offset) : - propType(1) - , data2(offset) - { - } - - PropBy(const Lit lit) : - propType(2) - , data1(lit.toInt()) - { - } - - PropBy(const Lit lit1, const Lit lit2) : - propType(3) - , data1(lit1.toInt()) - , data2(lit2.toInt()) - { - } - - bool isClause() const - { - return ((propType&2) == 0); - } - - bool isBinary() const - { - return (propType == 2); - } - - bool isTri() const - { - return (propType == 3); - } - - Lit getOtherLit() const - { - #ifdef DEBUG_PROPAGATEFROM - assert(isBinary() || isTri()); - #endif - return Lit::toLit(data1); - } - - Lit getOtherLit2() const - { - #ifdef DEBUG_PROPAGATEFROM - assert(isTri()); - #endif - return Lit::toLit(data2); - } - - ClauseOffset getClause() const - { - #ifdef DEBUG_PROPAGATEFROM - assert(isClause()); - #endif - return data2; - } - - ClauseOffset getClause() - { - #ifdef DEBUG_PROPAGATEFROM - assert(isClause()); - #endif - return data2; - } - - bool isNULL() const - { - if (!isClause()) return false; - return propType == 0; - } -}; - -inline std::ostream& operator<<(std::ostream& os, const PropBy& pb) -{ - if (pb.isBinary()) { - os << " binary, other lit= " << pb.getOtherLit(); - } else if (pb.isClause()) { - os << " clause, num= " << pb.getClause(); - } else if (pb.isNULL()) { - os << " NULL"; - } else if (pb.isTri()) { - os << " tri, other 2 lits= " << pb.getOtherLit() << " , "<< pb.getOtherLit2(); - } - return os; -} - -class PropByFull -{ - private: - uint32_t type; - Clause* clause; - Lit lits[3]; - - public: - PropByFull(PropBy orig, Lit otherLit, ClauseAllocator& alloc) : - type(10) - , clause(NULL) - { - if (orig.isBinary() || orig.isTri()) { - lits[0] = otherLit; - lits[1] = orig.getOtherLit(); - if (orig.isTri()) { - lits[2] = orig.getOtherLit2(); - type = 2; - } else { - type = 1; - } - } - if (orig.isClause()) { - type = 0; - if (orig.isNULL()) { - clause = NULL; - } else { - clause = alloc.getPointer(orig.getClause()); - } - } - } - - PropByFull() : - type(10) - {} - - PropByFull(const PropByFull& other) : - type(other.type) - , clause(other.clause) - { - memcpy(lits, other.lits, sizeof(Lit)*3); - } - - uint32_t size() const - { - switch (type) { - case 0 : return clause->size(); - case 1 : return 2; - case 2 : return 3; - default: - assert(false); - return 0; - } - } - - bool isNULL() const - { - return type == 0 && clause == NULL; - } - - bool isClause() const - { - return type == 0; - } - - bool isBinary() const - { - return type == 1; - } - - bool isTri() const - { - return type == 2; - } - - const Clause* getClause() const - { - return clause; - } - - Clause* getClause() - { - return clause; - } - - Lit operator[](const uint32_t i) const - { - switch (type) { - case 0: { - assert(clause != NULL); - return (*clause)[i]; - } - default : { - return lits[i]; - } - } - } -}; - -inline std::ostream& operator<<(std::ostream& cout, const PropByFull& propByFull) -{ - - if (propByFull.isBinary()) { - cout << "binary: " << " ? , " << propByFull[1]; - } else if (propByFull.isTri()) { - cout << "tri: " << " ? , " <<propByFull[1] << " , " << propByFull[2]; - } else if (propByFull.isClause()) { - if (propByFull.isNULL()) cout << "null clause"; - else cout << "clause:" << *propByFull.getClause(); - } - return cout; -} - -} - -#endif //PROPBY_H diff --git a/src/prop/cryptominisat/Solver/RestartTypeChooser.cpp b/src/prop/cryptominisat/Solver/RestartTypeChooser.cpp deleted file mode 100644 index 9432c374a..000000000 --- a/src/prop/cryptominisat/Solver/RestartTypeChooser.cpp +++ /dev/null @@ -1,181 +0,0 @@ -/**************************************************************************** -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 "RestartTypeChooser.h" - -#include <utility> -#include "Solver.h" - -//#define VERBOSE_DEBUG -//#define PRINT_VARS - -using namespace CMSat; - -using std::pair; - -RestartTypeChooser::RestartTypeChooser(const Solver& s) : - solver(s) - , topX(100) - , limit(40) -{ -} - -/** -@brief Adds info at the end of a restart to the internal datastructures - -It is called a number of times after a full restart has been done, to -accumulate data. Finally, choose() is called to choose the restart type -*/ -void RestartTypeChooser::addInfo() -{ - firstVarsOld = firstVars; - calcHeap(); - uint32_t sameIn = 0; - if (!firstVarsOld.empty()) { - uint32_t thisTopX = std::min(firstVarsOld.size(), (size_t)topX); - for (uint32_t i = 0; i != thisTopX; i++) { - if (std::find(firstVars.begin(), firstVars.end(), firstVarsOld[i]) != firstVars.end()) - sameIn++; - } - #ifdef VERBOSE_DEBUG - std::cout << " Same vars in first&second first 100: " << sameIn << std::endl; - #endif - sameIns.push_back(sameIn); - } - - #ifdef VERBOSE_DEBUG - std::cout << "Avg same vars in first&second first 100: " << avg() << " standard Deviation:" << stdDeviation(sameIns) <<std::endl; - #endif -} - -/** -@brief After accumulation of data, this function finally decides which type to choose -*/ -RestartType RestartTypeChooser::choose() -{ - pair<double, double> mypair = countVarsDegreeStDev(); - if ((mypair.second < 80 && - (avg() > (double)limit || ((avg() > (double)(limit*0.9) && stdDeviation(sameIns) < 5)))) - || - (mypair.second < 80 && (double)solver.xorclauses.size() > (double)solver.nClauses()*0.1)) - return static_restart; - else - return dynamic_restart; -} - -/** -@brief Calculates average for topx variable activity changes -*/ -double RestartTypeChooser::avg() const -{ - double sum = 0.0; - for (uint32_t i = 0; i != sameIns.size(); i++) - sum += sameIns[i]; - return (sum/(double)sameIns.size()); -} - -/** -@brief Calculates standard deviation for topx variable activity changes -*/ -double RestartTypeChooser::stdDeviation(vector<uint32_t>& measure) const -{ - double average = avg(); - double variance = 0.0; - for (uint32_t 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 PRINT_VARS - std::cout << "First vars:" << std::endl; - #endif - Heap<Solver::VarOrderLt> tmp(solver.order_heap); - uint32_t thisTopX = std::min(tmp.size(), topX); - for (uint32_t i = 0; i != thisTopX; i++) { - #ifdef PRINT_VARS - std::cout << tmp.removeMin()+1 << ", "; - #endif - firstVars.push_back(tmp.removeMin()); - } - #ifdef PRINT_VARS - std::cout << std::endl; - #endif -} - -std::pair<double, double> RestartTypeChooser::countVarsDegreeStDev() const -{ - vector<uint32_t> degrees; - degrees.resize(solver.nVars(), 0); - addDegrees(solver.clauses, degrees); - addDegreesBin(degrees); - addDegrees(solver.xorclauses, degrees); - uint32_t sum = 0; - uint32_t *i = °rees[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; - -void RestartTypeChooser::addDegreesBin(vector<uint32_t>& degrees) const -{ - uint32_t wsLit = 0; - for (const vec<Watched> *it = solver.watches.getData(), *end = solver.watches.getDataEnd(); it != end; it++, wsLit++) { - Lit lit = ~Lit::toLit(wsLit); - const vec<Watched>& ws = *it; - for (vec<Watched>::const_iterator it2 = ws.getData(), end2 = ws.getDataEnd(); it2 != end2; it2++) { - if (it2->isBinary() && lit.toInt() < it2->getOtherLit().toInt()) { - degrees[lit.var()]++; - degrees[it2->getOtherLit().var()]++; - } - } - } -} diff --git a/src/prop/cryptominisat/Solver/RestartTypeChooser.h b/src/prop/cryptominisat/Solver/RestartTypeChooser.h deleted file mode 100644 index 6279b07a5..000000000 --- a/src/prop/cryptominisat/Solver/RestartTypeChooser.h +++ /dev/null @@ -1,81 +0,0 @@ -/*********************************************************************************** -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 RESTARTTYPECHOOSER_H -#define RESTARTTYPECHOOSER_H - -#include "Solver.h" -#include <vector> -#ifdef _MSC_VER -#include <msvc/stdint.h> -#else -#include <stdint.h> -#endif //_MSC_VER - -#include "SolverTypes.h" - -namespace CMSat { - -using std::vector; - -class Solver; - -/** -@brief Chooses between MiniSat and GLUCOSE restart types&learnt clause evaluation - -MiniSat style restart is geometric, and glucose-type is dynamic. MiniSat-type -learnt clause staistic is activity-based, glucose-type is glue-based. This -class takes as input a number of MiniSat restart's end results, computes some -statistics on them, and at the end, tells if we should use one type or the -other. Basically, it masures variable activity stability, number of xors -in the problem, and variable degrees. -*/ -class RestartTypeChooser -{ - public: - RestartTypeChooser(const Solver& s); - void addInfo(); - RestartType choose(); - void reset(); - - private: - void calcHeap(); - double avg() const; - std::pair<double, double> countVarsDegreeStDev() const; - double stdDeviation(vector<uint32_t>& measure) const; - - template<class T> - void addDegrees(const vec<T*>& cs, vector<uint32_t>& degrees) const; - void addDegreesBin(vector<uint32_t>& degrees) const; - - const Solver& solver; - uint32_t topX; ///<The how many is the top X? 100 is default - uint32_t limit; ///<If top x contains on average this many common varables, we select MiniSat-type - vector<Var> sameIns; - - vector<Var> firstVars; ///<The top x variables (in terms of var activity) - vector<Var> firstVarsOld; ///<The previous top x variables (in terms of var activity) -}; - -inline void RestartTypeChooser::reset() -{ - sameIns.clear(); -} - -} - -#endif //RESTARTTYPECHOOSER_H diff --git a/src/prop/cryptominisat/Solver/SCCFinder.cpp b/src/prop/cryptominisat/Solver/SCCFinder.cpp deleted file mode 100644 index 896566cad..000000000 --- a/src/prop/cryptominisat/Solver/SCCFinder.cpp +++ /dev/null @@ -1,142 +0,0 @@ -/***************************************************************************** -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 <iostream> -#include <vector> -#include "../Solver/SolverTypes.h" -#include "SCCFinder.h" -#include "VarReplacer.h" -#include <iomanip> -#include "time_mem.h" -#include "Subsumer.h" -#include "XorSubsumer.h" - -using namespace CMSat; - -SCCFinder::SCCFinder(Solver& _solver) : - solver(_solver) - , varElimed1(_solver.subsumer->getVarElimed()) - , varElimed2(_solver.xorSubsumer->getVarElimed()) - , replaceTable(_solver.varReplacer->getReplaceTable()) - , totalTime(0.0) -{} - -bool SCCFinder::find2LongXors() -{ - double myTime = cpuTime(); - uint32_t oldNumReplace = solver.varReplacer->getNewToReplaceVars(); - - globalIndex = 0; - index.clear(); - index.resize(solver.nVars()*2, std::numeric_limits<uint32_t>::max()); - lowlink.clear(); - lowlink.resize(solver.nVars()*2, std::numeric_limits<uint32_t>::max()); - stackIndicator.clear(); - stackIndicator.growTo(solver.nVars()*2, false); - assert(stack.empty()); - - for (uint32_t vertex = 0; vertex < solver.nVars()*2; vertex++) { - //Start a DFS at each node we haven't visited yet - if (index[vertex] == std::numeric_limits<uint32_t>::max()) { - recurDepth = 0; - tarjan(vertex); - assert(stack.empty()); - } - } - - if (solver.conf.verbosity >= 3 || (solver.conflicts == 0 && solver.conf.verbosity >= 1)) { - std::cout << "c Finding binary XORs T: " - << std::fixed << std::setprecision(2) << std::setw(8) << (cpuTime() - myTime) << " s" - << " found: " << std::setw(7) << solver.varReplacer->getNewToReplaceVars() - oldNumReplace - << std::endl; - } - totalTime += (cpuTime() - myTime); - - return solver.ok; -} - -void SCCFinder::tarjan(const uint32_t vertex) -{ - recurDepth++; - index[vertex] = globalIndex; // Set the depth index for v - lowlink[vertex] = globalIndex; - globalIndex++; - stack.push(vertex); // Push v on the stack - stackIndicator[vertex] = true; - - Var vertexVar = Lit::toLit(vertex).var(); - if (!varElimed1[vertexVar] && !varElimed2[vertexVar]) { - const vec<Watched>& ws = solver.watches[vertex]; - for (vec<Watched>::const_iterator it = ws.getData(), end = ws.getDataEnd(); it != end; it++) { - if (!it->isBinary()) continue; - const Lit lit = it->getOtherLit(); - - doit(lit, vertex); - } - - if (solver.conf.doExtendedSCC) { - Lit vertLit = Lit::toLit(vertex); - vector<Lit>& transCache = solver.transOTFCache[(~Lit::toLit(vertex)).toInt()].lits; - vector<Lit>::iterator it = transCache.begin(); - vector<Lit>::iterator it2 = it; - uint32_t newSize = 0; - Lit prevLit = lit_Error; - for (vector<Lit>::iterator end = transCache.end(); it != end; it++) { - Lit lit = *it; - lit = replaceTable[lit.var()] ^ lit.sign(); - if (lit == prevLit || lit == vertLit || varElimed1[lit.var()] || varElimed2[lit.var()]) - continue; - - *it2++ = lit; - prevLit = lit; - newSize++; - - doit(lit, vertex); - } - transCache.resize(newSize); - } - } - - // Is v the root of an SCC? - if (lowlink[vertex] == index[vertex]) { - uint32_t vprime; - tmp.clear(); - do { - assert(!stack.empty()); - vprime = stack.top(); - stack.pop(); - stackIndicator[vprime] = false; - tmp.push(vprime); - } while (vprime != vertex); - if (tmp.size() >= 2) { - for (uint32_t i = 1; i < tmp.size(); i++) { - if (!solver.ok) break; - vec<Lit> lits(2); - lits[0] = Lit::toLit(tmp[0]).unsign(); - lits[1] = Lit::toLit(tmp[i]).unsign(); - const bool xorEqualsFalse = Lit::toLit(tmp[0]).sign() - ^ Lit::toLit(tmp[i]).sign() - ^ true; - if (solver.value(lits[0]) == l_Undef && solver.value(lits[1]) == l_Undef) { - //Cannot add to watchlists, because we are going THROUGH the watchlists (in a higher frame) - //so it might end up kicking the chair under ourselves - solver.varReplacer->replace(lits, xorEqualsFalse, true, false); - } - } - } - } -}
\ No newline at end of file diff --git a/src/prop/cryptominisat/Solver/SCCFinder.h b/src/prop/cryptominisat/Solver/SCCFinder.h deleted file mode 100644 index c1d876e2c..000000000 --- a/src/prop/cryptominisat/Solver/SCCFinder.h +++ /dev/null @@ -1,72 +0,0 @@ -/***************************************************************************** -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 SCCFINDER_H -#define SCCFINDER_H - -#include "Vec.h" -#include "Clause.h" -#include "Solver.h" -#include <stack> - -namespace CMSat { - -class SCCFinder { - public: - SCCFinder(Solver& solver); - bool find2LongXors(); - double getTotalTime() const; - - private: - void tarjan(const uint32_t vertex); - void doit(const Lit lit, const uint32_t vertex); - - uint32_t globalIndex; - vector<uint32_t> index; - vector<uint32_t> lowlink; - std::stack<uint32_t> stack; - vec<char> stackIndicator; - vec<uint32_t> tmp; - - uint32_t recurDepth; - - Solver& solver; - const vec<char>& varElimed1; - const vec<char>& varElimed2; - const vector<Lit>& replaceTable; - double totalTime; -}; - -inline void SCCFinder::doit(const Lit lit, const uint32_t vertex) { - // Was successor v' visited? - if (index[lit.toInt()] == std::numeric_limits<uint32_t>::max()) { - tarjan(lit.toInt()); - recurDepth--; - lowlink[vertex] = std::min(lowlink[vertex], lowlink[lit.toInt()]); - } else if (stackIndicator[lit.toInt()]) { - lowlink[vertex] = std::min(lowlink[vertex], lowlink[lit.toInt()]); - } -} - -inline double SCCFinder::getTotalTime() const -{ - return totalTime; -} - -} - -#endif //SCCFINDER_H diff --git a/src/prop/cryptominisat/Solver/SharedData.h b/src/prop/cryptominisat/Solver/SharedData.h deleted file mode 100644 index 394b517f7..000000000 --- a/src/prop/cryptominisat/Solver/SharedData.h +++ /dev/null @@ -1,37 +0,0 @@ -/************************************************************************** -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 SHARED_DATA_H -#define SHARED_DATA_H - -#include "Vec.h" -#include "SolverTypes.h" - -#include <vector> - -namespace CMSat { - -class SharedData -{ - public: - vec<lbool> value; - std::vector<std::vector<Lit> > bins; -}; - -} - -#endif //SHARED_DATA_H diff --git a/src/prop/cryptominisat/Solver/Solver.cpp b/src/prop/cryptominisat/Solver/Solver.cpp deleted file mode 100644 index f73d6166e..000000000 --- a/src/prop/cryptominisat/Solver/Solver.cpp +++ /dev/null @@ -1,2924 +0,0 @@ -/***************************************************************************** -MiniSat -- Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson -glucose -- Gilles Audemard, Laurent Simon (2008) -CryptoMiniSat -- Copyright (c) 2009 Mate Soos - -Original code by MiniSat and glucose authors are under an MIT licence. -Modifications for CryptoMiniSat are under GPLv3 licence. -******************************************************************************/ - -#include "Solver.h" -#include <cmath> -#include <string.h> -#include <algorithm> -#include <limits.h> -#include <vector> -#include <iomanip> -#include <algorithm> - -#include "Clause.h" -#include "time_mem.h" - -#include "VarReplacer.h" -#include "XorFinder.h" -#include "ClauseCleaner.h" -#include "RestartTypeChooser.h" -#include "FailedLitSearcher.h" -#include "Subsumer.h" -#include "XorSubsumer.h" -#include "StateSaver.h" -#include "SCCFinder.h" -#include "SharedData.h" -#include "ClauseVivifier.h" -#include "Gaussian.h" -#include "MatrixFinder.h" -#include "DataSync.h" -#include "BothCache.h" - -#ifdef VERBOSE_DEBUG -#define UNWINDING_DEBUG -#endif - -//#define DEBUG_UNCHECKEDENQUEUE_LEVEL0 -//#define VERBOSE_DEBUG_POLARITIES -//#define DEBUG_DYNAMIC_RESTART -//#define UNWINDING_DEBUG - -//********************************** -// Constructor/Destructor: -//********************************** - -using namespace CMSat; - -/** -@brief Sets a sane default config and allocates handler classes -*/ -Solver::Solver(const SolverConf& _conf, const GaussConf& _gaussconfig, SharedData* sharedData) : - // Parameters: (formerly in 'SearchParams') - conf(_conf) - , gaussconfig(_gaussconfig) - , needToInterrupt (false) - #ifdef USE_GAUSS - , sum_gauss_called (0) - , sum_gauss_confl (0) - , sum_gauss_prop (0) - , sum_gauss_unit_truths (0) - #endif //USE_GAUSS - - // Stats - , 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) - , nbGlue2(0), numNewBin(0), lastNbBin(0), lastSearchForBinaryXor(0), nbReduceDB(0) - , improvedClauseNo(0), improvedClauseSize(0) - , numShrinkedClause(0), numShrinkedClauseLits(0) - , moreRecurMinLDo(0) - , updateTransCache(0) - , nbClOverMaxGlue(0) - - , ok (true) - , numBins (0) - , cla_inc (1) - , qhead (0) - , mtrand ((unsigned long int)0) - - //variables - , order_heap (VarOrderLt(activity)) - , var_inc (128) - - //learnts - , numCleanedLearnts(1) - , nbClBeforeRed (NBCLAUSESBEFOREREDUCE) - , nbCompensateSubsumer (0) - , libraryCNFFile (NULL) - , restartType (static_restart) - , lastSelectedRestartType (static_restart) - , simplifying (false) - , totalSimplifyTime(0.0) - , simpDB_assigns (-1) - , simpDB_props (0) -{ - mtrand.seed(conf.origSeed); - #ifdef ENABLE_UNWIND_GLUE - assert(conf.maxGlue < MAX_THEORETICAL_GLUE); - #endif //ENABLE_UNWIND_GLUE - varReplacer = new VarReplacer(*this); - clauseCleaner = new ClauseCleaner(*this); - failedLitSearcher = new FailedLitSearcher(*this); - subsumer = new Subsumer(*this); - xorSubsumer = new XorSubsumer(*this); - restartTypeChooser = new RestartTypeChooser(*this); - sCCFinder = new SCCFinder(*this); - clauseVivifier = new ClauseVivifier(*this); - matrixFinder = new MatrixFinder(*this); - dataSync = new DataSync(*this, sharedData); - -} - -/** -@brief Frees clauses and frees all allocated hander classes -*/ -Solver::~Solver() -{ - clearGaussMatrixes(); - delete matrixFinder; - delete varReplacer; - delete clauseCleaner; - delete failedLitSearcher; - delete subsumer; - delete xorSubsumer; - delete restartTypeChooser; - - if (libraryCNFFile) - fclose(libraryCNFFile); -} - -//********************************** -// Minor methods -//********************************** - -/** -@brief Creates a new SAT variable in the solver - -This entails making the datastructures large enough to fit the new variable -in all internal datastructures as well as all datastructures used in -classes used inside Solver - -@p dvar The new variable should be used as a decision variable? - NOTE: this has effects on the meaning of a SATISFIABLE result -*/ -Var Solver::newVar(bool dvar) throw (std::out_of_range) -{ - Var v = nVars(); - if (v >= 1<<30) - throw std::out_of_range("ERROR! Variable requested is far too large"); - - watches .push(); // (list for positive literal) - watches .push(); // (list for negative literal) - reason .push(PropBy()); - assigns .push(l_Undef); - level .push(-1); - binPropData.push(); - activity .push(0); - seen .push_back(0); - seen .push_back(0); - #ifdef ENABLE_UNWIND_GLUE - unWindGlue.push(NULL); - #endif //ENABLE_UNWIND_GLUE - - //Transitive OTF self-subsuming resolution - seen2 .push_back(0); - seen2 .push_back(0); - transOTFCache.push_back(TransCache()); - transOTFCache.push_back(TransCache()); - litReachable.push_back(LitReachData()); - litReachable.push_back(LitReachData()); - - polarity .push_back(defaultPolarity()); - - decision_var.push_back(dvar); - insertVarOrder(v); - - varReplacer->newVar(); - subsumer->newVar(); - xorSubsumer->newVar(); - dataSync->newVar(); - - insertVarOrder(v); - - if (libraryCNFFile) - fprintf(libraryCNFFile, "c Solver::newVar() called\n"); - - return v; -} - -/** -@brief Adds an xor clause to the problem - -Should ONLY be called from internally. This is different from the extenal -xor clause-adding function addXorClause() in that it assumes that the variables -inside are decision variables, have not been replaced, eliminated, etc. -*/ -template<class T> -XorClause* Solver::addXorClauseInt(T& ps, bool xorEqualFalse, const bool learnt) throw (std::out_of_range) -{ - assert(qhead == trail.size()); - assert(decisionLevel() == 0); - - if (ps.size() > (0x01UL << 18)) - throw std::out_of_range("Too long clause!"); - std::sort(ps.getData(), ps.getDataEnd()); - Lit p; - uint32_t i, j; - for (i = j = 0, p = lit_Undef; i != ps.size(); i++) { - if (ps[i].var() == p.var()) { - //added, but easily removed - j--; - p = lit_Undef; - if (!assigns[ps[i].var()].isUndef()) - xorEqualFalse ^= assigns[ps[i].var()].getBool(); - } else if (assigns[ps[i].var()].isUndef()) { //just add - ps[j++] = p = ps[i]; - assert(!subsumer->getVarElimed()[p.var()]); - assert(!xorSubsumer->getVarElimed()[p.var()]); - } else //modify xorEqualFalse instead of adding - xorEqualFalse ^= (assigns[ps[i].var()].getBool()); - } - ps.shrink(i - j); - - switch(ps.size()) { - case 0: { - if (!xorEqualFalse) ok = false; - return NULL; - } - case 1: { - uncheckedEnqueue(Lit(ps[0].var(), xorEqualFalse)); - ok = (propagate<false>().isNULL()); - return NULL; - } - case 2: { - #ifdef VERBOSE_DEBUG - cout << "--> xor is 2-long, replacing var " << ps[0].var()+1 << " with " << (!xorEqualFalse ? "-" : "") << ps[1].var()+1 << endl; - #endif - - ps[0] = ps[0].unsign(); - ps[1] = ps[1].unsign(); - varReplacer->replace(ps, xorEqualFalse, learnt); - return NULL; - } - default: { - assert(!learnt); - XorClause* c = clauseAllocator.XorClause_new(ps, xorEqualFalse); - attachClause(*c); - return c; - } - } -} - -template XorClause* Solver::addXorClauseInt(vec<Lit>& ps, bool xorEqualFalse, const bool learnt); -template XorClause* Solver::addXorClauseInt(XorClause& ps, bool xorEqualFalse, const bool learnt); - -/** -@brief Adds an xor clause to the problem - -Calls addXorClauseInt() for the heavy-lifting. Basically, this does a bit -of debug-related stuff (see "libraryCNFFile"), and then checks if any of the -variables have been eliminated, replaced, etc. If so, it treats it correctly, -and then calls addXorClauseInt() to actually add the xor clause. - -@p ps[inout] The VARIABLES in the xor clause. Beware, there must be NO signs - here: ALL must be unsigned (.sign() == false). Values passed here - WILL be changed, ordered, removed, etc! -@p xorEqualFalse The xor must be equal to TRUE or false? -*/ -template<class T> -bool Solver::addXorClause(T& ps, bool xorEqualFalse) throw (std::out_of_range) -{ - assert(decisionLevel() == 0); - if (ps.size() > (0x01UL << 18)) - throw std::out_of_range("Too long clause!"); - - if (libraryCNFFile) { - fprintf(libraryCNFFile, "x"); - for (uint32_t i = 0; i < ps.size(); i++) ps[i].print(libraryCNFFile); - fprintf(libraryCNFFile, "0\n"); - } - - if (!ok) - return false; - assert(qhead == trail.size()); - #ifndef NDEBUG - for (Lit *l = ps.getData(), *end = ps.getDataEnd(); l != end; l++) { - assert(l->var() < nVars() && "Clause inserted, but variable inside has not been declared with newVar()!"); - } - #endif - - if (varReplacer->getNumLastReplacedVars() || subsumer->getNumElimed() || xorSubsumer->getNumElimed()) { - for (uint32_t i = 0; i != ps.size(); i++) { - Lit otherLit = varReplacer->getReplaceTable()[ps[i].var()]; - if (otherLit.var() != ps[i].var()) { - ps[i] = Lit(otherLit.var(), false); - xorEqualFalse ^= otherLit.sign(); - } - if (subsumer->getVarElimed()[ps[i].var()] && !subsumer->unEliminate(ps[i].var())) - return false; - else if (xorSubsumer->getVarElimed()[ps[i].var()] && !xorSubsumer->unEliminate(ps[i].var())) - return false; - } - } - - XorClause* c = addXorClauseInt(ps, xorEqualFalse); - if (c != NULL) xorclauses.push(c); - - return ok; -} - -template bool Solver::addXorClause(vec<Lit>& ps, bool xorEqualFalse); -template bool Solver::addXorClause(XorClause& ps, bool xorEqualFalse); - -/** -@brief Adds a clause to the problem. Should ONLY be called internally - -This code is very specific in that it must NOT be called with varibles in -"ps" that have been replaced, eliminated, etc. Also, it must not be called -when the solver is in an UNSAT (!ok) state, for example. Use it carefully, -and only internally -*/ -template <class T> -Clause* Solver::addClauseInt(T& ps - , const bool learnt, const uint32_t glue, const float miniSatActivity - , const bool inOriginalInput) -{ - assert(ok); -#ifdef VERBOSE_DEBUG - std::cout << "Adding new clause: " << std::endl; - for(size_t i = 0; i< ps.size(); i++) { - printLit(ps[i]); - std::cout << " "; - } - std::cout << std::endl; -#endif //VERBOSE_DEBUG - - std::sort(ps.getData(), ps.getDataEnd()); - Lit p = lit_Undef; - uint32_t i, j; - for (i = j = 0; i != ps.size(); i++) { - if (value(ps[i]).getBool() || ps[i] == ~p) - return NULL; - else if (value(ps[i]) != l_False && ps[i] != p) { - ps[j++] = p = ps[i]; - assert(!subsumer->getVarElimed()[p.var()]); - assert(!xorSubsumer->getVarElimed()[p.var()]); - } - } - ps.shrink(i - j); - - if (ps.size() == 0) { - ok = false; - return NULL; - } else if (ps.size() == 1) { - uncheckedEnqueue(ps[0]); - ok = (propagate<false>().isNULL()); - return NULL; - } - - if (ps.size() > 2) { - Clause* c = clauseAllocator.Clause_new(ps); - if (learnt) c->makeLearnt(glue, miniSatActivity); - attachClause(*c); - return c; - } else { - attachBinClause(ps[0], ps[1], learnt); - if (!inOriginalInput) dataSync->signalNewBinClause(ps); - numNewBin++; - return NULL; - } -} - -template Clause* Solver::addClauseInt(Clause& ps, const bool learnt, const uint32_t glue, const float miniSatActivity, const bool inOriginalInput); -template Clause* Solver::addClauseInt(vec<Lit>& ps, const bool learnt, const uint32_t glue, const float miniSatActivity, const bool inOriginalInput); - -template<class T> bool Solver::addClauseHelper(T& ps) throw (std::out_of_range) -{ - assert(decisionLevel() == 0); - if (ps.size() > (0x01UL << 18)) - throw std::out_of_range("Too long clause!"); - - if (libraryCNFFile) { - for (uint32_t i = 0; i != ps.size(); i++) ps[i].print(libraryCNFFile); - fprintf(libraryCNFFile, "0\n"); - } - - if (!ok) return false; - assert(qhead == trail.size()); - #ifndef NDEBUG - for (Lit *l = ps.getData(), *end = ps.getDataEnd(); l != end; l++) { - assert(l->var() < nVars() && "Clause inserted, but variable inside has not been declared with Solver::newVar() !"); - } - #endif - - // Check if clause is satisfied and remove false/duplicate literals: - if (varReplacer->getNumLastReplacedVars() || subsumer->getNumElimed() || xorSubsumer->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; - if (xorSubsumer->getVarElimed()[ps[i].var()] && !xorSubsumer->unEliminate(ps[i].var())) - return false; - } - } - - for (uint32_t i = 0; i < ps.size(); i++) { - std::swap(ps[i], ps[(mtrand.randInt() % (ps.size()-i)) + i]); - } - - return true; -} - - -/** -@brief Adds a clause to the problem. Calls addClauseInt() for heavy-lifting - -Does some debug-related stuff (see "libraryCNFFile"), and checks whether the -variables of the literals in "ps" have been eliminated/replaced etc. If so, -it acts on them such that they are correct, and calls addClauseInt() to do -the heavy-lifting -*/ -template<class T> -bool Solver::addClause(T& ps) -{ - #ifdef VERBOSE_DEBUG - std::cout << "addClause() called with new clause: " << ps << std::endl; - #endif //VERBOSE_DEBUG - if (!addClauseHelper(ps)) return false; - Clause* c = addClauseInt(ps, false, 0, 0, true); - if (c != NULL) clauses.push(c); - - return ok; -} - -template bool Solver::addClause(vec<Lit>& ps); -template bool Solver::addClause(Clause& ps); - - -template<class T> -bool Solver::addLearntClause(T& ps, const uint32_t glue, const float miniSatActivity) -{ - if (!addClauseHelper(ps)) return false; - Clause* c = addClauseInt(ps, true, glue, miniSatActivity, true); - if (c != NULL) learnts.push(c); - - return ok; -} - -template bool Solver::addLearntClause(vec<Lit>& ps, const uint32_t glue, const float miniSatActivity); -template bool Solver::addLearntClause(Clause& ps, const uint32_t glue, const float miniSatActivity); - - -/** -@brief Attaches an xor clause to the watchlists - -The xor clause must be larger than 2, since a 2-long XOR clause is a varible -replacement instruction, really. -*/ -void Solver::attachClause(XorClause& c) -{ - assert(c.size() > 2); - #ifdef DEBUG_ATTACH - assert(assigns[c[0].var()] == l_Undef); - assert(assigns[c[1].var()] == l_Undef); - - for (uint32_t i = 0; i < c.size(); i++) { - assert(!subsumer->getVarElimed()[c[i].var()]); - assert(!xorSubsumer->getVarElimed()[c[i].var()]); - } - #endif //DEBUG_ATTACH - - watches[Lit(c[0].var(), false).toInt()].push(clauseAllocator.getOffset((Clause*)&c)); - watches[Lit(c[0].var(), true).toInt()].push(clauseAllocator.getOffset((Clause*)&c)); - watches[Lit(c[1].var(), false).toInt()].push(clauseAllocator.getOffset((Clause*)&c)); - watches[Lit(c[1].var(), true).toInt()].push(clauseAllocator.getOffset((Clause*)&c)); - - clauses_literals += c.size(); -} - -void Solver::attachBinClause(const Lit lit1, const Lit lit2, const bool learnt) -{ - #ifdef DEBUG_ATTACH - assert(lit1.var() != lit2.var()); - assert(assigns[lit1.var()] == l_Undef); - assert(value(lit2) == l_Undef || value(lit2) == l_False); - - assert(!subsumer->getVarElimed()[lit1.var()]); - assert(!subsumer->getVarElimed()[lit2.var()]); - - assert(!xorSubsumer->getVarElimed()[lit1.var()]); - assert(!xorSubsumer->getVarElimed()[lit2.var()]); - #endif //DEBUG_ATTACH - - watches[(~lit1).toInt()].push(Watched(lit2, learnt)); - watches[(~lit2).toInt()].push(Watched(lit1, learnt)); - - #ifdef DUMP_STATS_FULL - if (learnt) { - watches[(~lit1).toInt()].last().glue = 2; - watches[(~lit2).toInt()].last().glue = 2; - } else { - watches[(~lit1).toInt()].last().glue = -1; - watches[(~lit2).toInt()].last().glue = -1; - } - #endif - - numBins++; - if (learnt) learnts_literals += 2; - else clauses_literals += 2; -} - -/** -@brief Attach normal a clause to the watchlists - -Handles 2, 3 and >3 clause sizes differently and specially -*/ -void Solver::attachClause(Clause& c) -{ - assert(c.size() > 2); - #ifdef DEBUG_ATTACH - assert(c[0].var() != c[1].var()); - assert(assigns[c[0].var()] == l_Undef); - assert(value(c[1]) == l_Undef || value(c[1]) == l_False); - - for (uint32_t i = 0; i < c.size(); i++) { - assert(!subsumer->getVarElimed()[c[i].var()]); - assert(!xorSubsumer->getVarElimed()[c[i].var()]); - } - #endif //DEBUG_ATTACH - - if (c.size() == 3) { - watches[(~c[0]).toInt()].push(Watched(c[1], c[2])); - watches[(~c[1]).toInt()].push(Watched(c[0], c[2])); - watches[(~c[2]).toInt()].push(Watched(c[0], c[1])); - - #ifdef DUMP_STATS_FULL - if (c.learnt()) { - watches[(~c[0]).toInt()].last().glue = 2; - watches[(~c[1]).toInt()].last().glue = 2; - watches[(~c[2]).toInt()].last().glue = 2; - } else { - watches[(~c[0]).toInt()].last().glue = -1; - watches[(~c[1]).toInt()].last().glue = -1; - watches[(~c[2]).toInt()].last().glue = -1; - } - #endif - - } else { - ClauseOffset offset = clauseAllocator.getOffset(&c); - watches[(~c[0]).toInt()].push(Watched(offset, c[c.size()/2])); - watches[(~c[1]).toInt()].push(Watched(offset, c[c.size()/2])); - } - - if (c.learnt()) - learnts_literals += c.size(); - else - clauses_literals += c.size(); -} - -/** -@brief Calls detachModifiedClause to do the heavy-lifting -*/ -void Solver::detachClause(const XorClause& c) -{ - detachModifiedClause(c[0].var(), c[1].var(), c.size(), &c); -} - -/** -@brief Calls detachModifiedClause to do the heavy-lifting -*/ -void Solver::detachClause(const Clause& c) -{ - detachModifiedClause(c[0], c[1], (c.size() == 3) ? c[2] : lit_Undef, c.size(), &c); -} - -/** -@brief Detaches a (potentially) modified clause - -The first two literals might have chaned through modification, so they are -passed along as arguments -- they are needed to find the correct place where -the clause is -*/ -void Solver::detachModifiedClause(const Lit lit1, const Lit lit2, const Lit lit3, const uint32_t origSize, const Clause* address) -{ - assert(origSize > 2); - - ClauseOffset offset = clauseAllocator.getOffset(address); - if (origSize == 3) { - //The clause might have been longer, and has only recently - //became 3-long. Check, and detach accordingly - if (findWCl(watches[(~lit1).toInt()], offset)) goto fullClause; - - removeWTri(watches[(~lit1).toInt()], lit2, lit3); - removeWTri(watches[(~lit2).toInt()], lit1, lit3); - removeWTri(watches[(~lit3).toInt()], lit1, lit2); - - } else { - fullClause: - removeWCl(watches[(~lit1).toInt()], offset); - removeWCl(watches[(~lit2).toInt()], offset); - - } - - if (address->learnt()) - learnts_literals -= origSize; - else - clauses_literals -= origSize; -} - -/** -@brief Detaches a (potentially) modified xor clause - -The first two vars might have chaned through modification, so they are passed -along as arguments. -*/ -void Solver::detachModifiedClause(const Var var1, const Var var2, const uint32_t origSize, const XorClause* address) -{ - assert(origSize > 2); - - ClauseOffset offset = clauseAllocator.getOffset(address); - assert(findWXCl(watches[Lit(var1, false).toInt()], offset)); - assert(findWXCl(watches[Lit(var1, true).toInt()], offset)); - assert(findWXCl(watches[Lit(var2, false).toInt()], offset)); - assert(findWXCl(watches[Lit(var2, true).toInt()], offset)); - - removeWXCl(watches[Lit(var1, false).toInt()], offset); - removeWXCl(watches[Lit(var1, true).toInt()], offset); - removeWXCl(watches[Lit(var2, false).toInt()], offset); - removeWXCl(watches[Lit(var2, true).toInt()], offset); - - assert(!address->learnt()); - clauses_literals -= origSize; -} - -/** -@brief Revert to the state at given level - -Also reverts all stuff in Gass-elimination -*/ -void Solver::cancelUntil(int level) -{ - #ifdef VERBOSE_DEBUG - cout << "Canceling until level " << level; - if (level > 0) cout << " sublevel: " << trail_lim[level]; - cout << endl; - #endif - - if ((int)decisionLevel() > level) { - - #ifdef USE_GAUSS - for (vector<Gaussian*>::iterator gauss = gauss_matrixes.begin(), end= gauss_matrixes.end(); gauss != end; gauss++) - (*gauss)->canceling(trail_lim[level]); - #endif //USE_GAUSS - - for (int sublevel = trail.size()-1; sublevel >= (int)trail_lim[level]; sublevel--) { - Var var = trail[sublevel].var(); - #ifdef VERBOSE_DEBUG - cout << "Canceling var " << var+1 << " sublevel: " << sublevel << endl; - #endif - assigns[var] = l_Undef; - #ifdef ANIMATE3D - fprintf(stderr, "u %u\n", var); - #endif - insertVarOrder(var); - #ifdef ENABLE_UNWIND_GLUE - if (unWindGlue[var] != NULL) { - #ifdef UNWINDING_DEBUG - std::cout << "unwind, var:" << var - << " sublevel:" << sublevel - << " coming from:" << (trail.size()-1) - << " going until:" << (int)trail_lim[level] - << std::endl; - unWindGlue[var]->plainPrint(); - #endif //UNWINDING_DEBUG - - Clause*& clauseToFree = unWindGlue[var]; - detachClause(*clauseToFree); - clauseAllocator.clauseFree(clauseToFree); - clauseToFree = NULL; - } - #endif //ENABLE_UNWIND_GLUE - } - qhead = trail_lim[level]; - trail.shrink_(trail.size() - trail_lim[level]); - trail_lim.shrink_(trail_lim.size() - level); - } - - #ifdef VERBOSE_DEBUG - cout << "Canceling finished. (now at level: " << decisionLevel() << " sublevel: " << trail.size()-1 << ")" << endl; - #endif -} - -void Solver::cancelUntilLight() -{ - assert((int)decisionLevel() > 0); - - for (int sublevel = trail.size()-1; sublevel >= (int)trail_lim[0]; sublevel--) { - Var var = trail[sublevel].var(); - assigns[var] = l_Undef; - } - qhead = trail_lim[0]; - trail.shrink_(trail.size() - trail_lim[0]); - trail_lim.clear(); -} - -bool Solver::clearGaussMatrixes() -{ - assert(decisionLevel() == 0); - #ifdef USE_GAUSS - bool ret = gauss_matrixes.size() > 0; - for (uint32_t i = 0; i < gauss_matrixes.size(); i++) - delete gauss_matrixes[i]; - gauss_matrixes.clear(); - - for (uint32_t i = 0; i != freeLater.size(); i++) - clauseAllocator.clauseFree(freeLater[i]); - freeLater.clear(); - - return ret; - #endif //USE_GAUSS - return false; -} - -/** -@brief Returns what polarity[] should be set as default based on polarity_mode - -since polarity is filled with Lit::sign() , "true" here means an inverted -signed-ness, i.e. a FALSE default value. And vice-versa -*/ -inline bool Solver::defaultPolarity() -{ - switch(conf.polarity_mode) { - case polarity_false: - return true; - case polarity_true: - return false; - case polarity_rnd: - return mtrand.randInt(1); - case polarity_auto: - return true; - default: - assert(false); - } - - return true; -} - -/** -@brief Tally votes for a default TRUE or FALSE value for the variable using the Jeroslow-Wang method - -@p votes[inout] Votes are tallied at this place for each variable -@p cs The clause to tally votes for -*/ -void Solver::tallyVotes(const vec<Clause*>& cs, vec<double>& votes) const -{ - 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.getData(), *end2 = c.getDataEnd(); it2 != end2; it2++) { - if (it2->sign()) votes[it2->var()] += divider; - else votes[it2->var()] -= divider; - } - } -} - -void Solver::tallyVotesBin(vec<double>& votes) const -{ - uint32_t wsLit = 0; - for (const vec<Watched> *it = watches.getData(), *end = watches.getDataEnd(); it != end; it++, wsLit++) { - Lit lit = ~Lit::toLit(wsLit); - const vec<Watched>& ws = *it; - for (vec<Watched>::const_iterator it2 = ws.getData(), end2 = ws.getDataEnd(); it2 != end2; it2++) { - if (it2->isBinary() && lit.toInt() < it2->getOtherLit().toInt()) { - if (!it2->getLearnt()) { - if (lit.sign()) votes[lit.var()] += 0.5; - else votes[lit.var()] -= 0.5; - - Lit lit2 = it2->getOtherLit(); - if (lit2.sign()) votes[lit2.var()] += 0.5; - else votes[lit2.var()] -= 0.5; - } - } - } - } -} - -/** -@brief Tally votes a default TRUE or FALSE value for the variable using the Jeroslow-Wang method - -For XOR clause, we simply add some weight for a FALSE default, i.e. being in -xor clauses makes the variabe more likely to be FALSE by default -*/ -void Solver::tallyVotes(const vec<XorClause*>& cs, vec<double>& votes) const -{ - 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.getData(), *end2 = c.getDataEnd(); it2 != end2; it2++) { - votes[it2->var()] += divider; - } - } -} - -/** -@brief Tallies votes for a TRUE/FALSE default polarity using Jeroslow-Wang - -Voting is only used if polarity_mode is "polarity_auto". This is the default. -Uses the tallyVotes() functions to tally the votes -*/ -void Solver::calculateDefaultPolarities() -{ - #ifdef VERBOSE_DEBUG_POLARITIES - std::cout << "Default polarities: " << std::endl; - #endif - - assert(decisionLevel() == 0); - if (conf.polarity_mode == polarity_auto) { - double myTime = cpuTime(); - - vec<double> votes(nVars(), 0.0); - - tallyVotes(clauses, votes); - tallyVotesBin(votes); - tallyVotes(xorclauses, votes); - - Var i = 0; - uint32_t posPolars = 0; - uint32_t undecidedPolars = 0; - for (const double *it = votes.getData(), *end = votes.getDataEnd(); it != end; it++, i++) { - polarity[i] = (*it >= 0.0); - posPolars += (*it < 0.0); - undecidedPolars += (*it == 0.0); - #ifdef VERBOSE_DEBUG_POLARITIES - std::cout << !defaultPolarities[i] << ", "; - #endif //VERBOSE_DEBUG_POLARITIES - } - - if (conf.verbosity >= 2) { - std::cout << "c Calc default polars - " - << " time: " << std::fixed << std::setw(6) << std::setprecision(2) << (cpuTime() - myTime) << " s" - << " pos: " << std::setw(7) << posPolars - << " undec: " << std::setw(7) << undecidedPolars - << " neg: " << std::setw(7) << nVars()- undecidedPolars - posPolars - << std:: endl; - } - } else { - for (uint32_t i = 0; i < polarity.size(); i++) { - polarity[i] = defaultPolarity(); - } - } - - #ifdef VERBOSE_DEBUG_POLARITIES - std::cout << std::endl; - #endif //VERBOSE_DEBUG_POLARITIES -} - -void Solver::calcReachability() -{ - double myTime = cpuTime(); - - for (uint32_t i = 0; i < nVars()*2; i++) { - litReachable[i] = LitReachData(); - } - - for (uint32_t i = 0; i < order_heap.size(); i++) for (uint32_t sig1 = 0; sig1 < 2; sig1++) { - Lit lit = Lit(order_heap[i], sig1); - if (value(lit.var()) != l_Undef - || subsumer->getVarElimed()[lit.var()] - || xorSubsumer->getVarElimed()[lit.var()] - || !decision_var[lit.var()]) - continue; - - vector<Lit>& cache = transOTFCache[(~lit).toInt()].lits; - uint32_t cacheSize = cache.size(); - for (vector<Lit>::const_iterator it = cache.begin(), end = cache.end(); it != end; it++) { - /*if (solver.value(it->var()) != l_Undef - || solver.subsumer->getVarElimed()[it->var()] - || solver.xorSubsumer->getVarElimed()[it->var()]) - continue;*/ - if ((*it == lit) || (*it == ~lit)) continue; - if (litReachable[it->toInt()].lit == lit_Undef || litReachable[it->toInt()].numInCache < cacheSize) { - litReachable[it->toInt()].lit = lit; - litReachable[it->toInt()].numInCache = cacheSize; - } - } - } - - /*for (uint32_t i = 0; i < nVars()*2; i++) { - std::sort(litReachable[i].begin(), litReachable[i].end(), MySorterX(transOTFCache)); - }*/ - - /*for (uint32_t i = 0; i < nVars()*2; i++) { - vector<Lit>& myset = litReachable[i]; - for (uint32_t i2 = 0; i2 < myset.size(); i2++) { - std::cout << transOTFCache[myset[i2].toInt()].lits.size() << " , "; - } - std::cout << std::endl; - }*/ - - if (conf.verbosity >= 1) { - std::cout << "c calculated reachability. Time: " << (cpuTime() - myTime) << std::endl; - } -} - -void Solver::saveOTFData() -{ - assert(decisionLevel() == 1); - - Lit lev0Lit = trail[trail_lim[0]]; - Solver::TransCache& oTFCache = transOTFCache[(~lev0Lit).toInt()]; - oTFCache.conflictLastUpdated = conflicts; - oTFCache.lits.clear(); - - for (int sublevel = trail.size()-1; sublevel > (int)trail_lim[0]; sublevel--) { - Lit lit = trail[sublevel]; - oTFCache.lits.push_back(lit); - } -} - -//********************************** -// Major methods: -//********************************** - -/** -@brief Picks a branching variable and its value (True/False) - -We do three things here: --# Try to do random decision (rare, less than 2%) --# Try acitivity-based decision - -Then, we pick a sign (True/False): -\li If we are in search-burst mode ("simplifying" is set), we pick a sign -totally randomly -\li Otherwise, we simply take the saved polarity -*/ -Lit Solver::pickBranchLit() -{ - #ifdef VERBOSE_DEBUG - cout << "decision level: " << decisionLevel() << " "; - #endif - - Var next = var_Undef; - - /* Skip variables which have already been defined (this will usually happen - * because of propagations/implicit assignments) */ - for (unsigned int i = decisionLevel(); i < branching_variables.size(); ++i) { - Var v = branching_variables[i]; - if (v < nVars() - && !subsumer->getVarElimed()[v] - && !xorSubsumer->getVarElimed()[v] - && assigns[v] == l_Undef) { - next = v; - break; - } - } - - bool random = mtrand.randDblExc() < conf.random_var_freq; - - // Random decision: - if (next == var_Undef && random && !order_heap.empty()) { - if (conf.restrictPickBranch == 0) - next = order_heap[mtrand.randInt(order_heap.size()-1)]; - else - next = order_heap[mtrand.randInt(std::min((uint32_t)order_heap.size()-1, conf.restrictPickBranch))]; - - if (assigns[next] == l_Undef && decision_var[next]) - rnd_decisions++; - } - - bool signSet = false; - bool signSetTo = false; - // Activity based decision: - while (next == var_Undef - || assigns[next] != l_Undef - || !decision_var[next]) { - if (order_heap.empty()) { - next = var_Undef; - break; - } - - next = order_heap.removeMin(); - if (!simplifying && value(next) == l_Undef && decision_var[next]) { - signSet = true; - if (avgBranchDepth.isvalid()) - signSetTo = polarity[next] ^ (mtrand.randInt(avgBranchDepth.getAvgUInt() * ((lastSelectedRestartType == static_restart) ? 2 : 1) ) == 1); - else - signSetTo = polarity[next]; - Lit nextLit = Lit(next, signSetTo); - Lit lit2 = litReachable[nextLit.toInt()].lit; - if (lit2 != lit_Undef && value(lit2.var()) == l_Undef && decision_var[lit2.var()] && mtrand.randInt(1) == 1) { - insertVarOrder(next); - next = litReachable[nextLit.toInt()].lit.var(); - signSetTo = litReachable[nextLit.toInt()].lit.sign(); - } - } - } - - //if "simplifying" is set, i.e. if we are in a burst-search mode, then - //randomly pick a sign. Otherwise, if RANDOM_LOOKAROUND_SEARCHSPACE is - //defined, we check the default polarity, and we may change it a bit - //randomly based on the average branch depth. Otherwise, we just go for the - //polarity that has been saved - bool sign; - if (next != var_Undef) { - if (signSet) { - sign = signSetTo; - } else { - if (simplifying && random) - sign = mtrand.randInt(1); - else if (avgBranchDepth.isvalid()) - sign = polarity[next] ^ (mtrand.randInt(avgBranchDepth.getAvgUInt() * ((lastSelectedRestartType == static_restart) ? 2 : 1) ) == 1); - else - sign = polarity[next]; - } - } - - assert(next == var_Undef || value(next) == l_Undef); - - if (next == var_Undef) { - #ifdef VERBOSE_DEBUG - cout << "SAT!" << endl; - #endif - return lit_Undef; - } else { - Lit lit(next,sign); - #ifdef VERBOSE_DEBUG - assert(decision_var[lit.var()]); - cout << "decided on: " << lit.var()+1 << " to set:" << !lit.sign() << endl; - #endif - return lit; - } -} - -/** -@brief Checks subsumption. Used in on-the-fly subsumption code - -Assumes 'seen' is cleared (will leave it cleared) -*/ -template<class T1, class T2> -bool subset(const T1& A, const T2& B, vector<char>& seen) -{ - for (uint32_t i = 0; i != B.size(); i++) - seen[B[i].toInt()] = 1; - for (uint32_t i = 0; i != A.size(); i++) { - if (!seen[A[i].toInt()]) { - for (uint32_t i = 0; i != B.size(); i++) - seen[B[i].toInt()] = 0; - return false; - } - } - for (uint32_t i = 0; i != B.size(); i++) - seen[B[i].toInt()] = 0; - return true; -} - - -/** -@brief Analyze conflict and produce a reason clause. - -Pre-conditions: -\li 'out_learnt' is assumed to be cleared. -\li Current decision level must be greater than root level. - -Post-conditions: -\li 'out_learnt[0]' is the asserting literal at level 'out_btlevel'. - -Effect: Will undo part of the trail, upto but not beyond the assumption of the -current decision level. - -@return NULL if the conflict doesn't on-the-fly subsume the last clause, and -the pointer of the clause if it does -*/ -Clause* Solver::analyze(PropBy conflHalf, vec<Lit>& out_learnt, int& out_btlevel, uint32_t &glue, const bool update) -{ - int pathC = 0; - Lit p = lit_Undef; - - // Generate conflict clause: - // - out_learnt.push(); // (leave room for the asserting literal) - int index = trail.size() - 1; - out_btlevel = 0; - - PropByFull confl(conflHalf, failBinLit, clauseAllocator); - PropByFull oldConfl; - - do { - assert(!confl.isNULL()); // (otherwise should be UIP) - - if (update && restartType == static_restart && confl.isClause() && confl.getClause()->learnt()) - claBumpActivity(*confl.getClause()); - - for (uint32_t j = (p == lit_Undef) ? 0 : 1, size = confl.size(); j != size; j++) { - Lit q = confl[j]; - const Var my_var = q.var(); - - if (!seen[my_var] && level[my_var] > 0) { - varBumpActivity(my_var); - seen[my_var] = 1; - assert(level[my_var] <= (int)decisionLevel()); - if (level[my_var] >= (int)decisionLevel()) { - pathC++; - if (lastSelectedRestartType == dynamic_restart - && reason[q.var()].isClause() - && !reason[q.var()].isNULL() - && clauseAllocator.getPointer(reason[q.var()].getClause())->learnt()) - lastDecisionLevel.push(q.var()); - } else { - out_learnt.push(q); - if (level[my_var] > out_btlevel) - out_btlevel = level[my_var]; - } - } - } - - // Select next clause to look at: - while (!seen[trail[index--].var()]); - p = trail[index+1]; - oldConfl = confl; - confl = PropByFull(reason[p.var()], failBinLit, clauseAllocator); - if (confl.isClause()) __builtin_prefetch(confl.getClause()); - seen[p.var()] = 0; - pathC--; - - } while (pathC > 0); - assert(pathC == 0); - out_learnt[0] = ~p; - - // Simplify conflict clause: - // - uint32_t i, j; - if (conf.expensive_ccmin) { - uint32_t abstract_level = 0; - for (i = 1; i < out_learnt.size(); i++) - abstract_level |= abstractLevel(out_learnt[i].var()); // (maintain an abstraction of levels involved in conflict) - - out_learnt.copyTo(analyze_toclear); - for (i = j = 1; i < out_learnt.size(); i++) - if (reason[out_learnt[i].var()].isNULL() || !litRedundant(out_learnt[i], abstract_level)) - out_learnt[j++] = out_learnt[i]; - } else { - out_learnt.copyTo(analyze_toclear); - for (i = j = 1; i < out_learnt.size(); i++) { - PropByFull c(reason[out_learnt[i].var()], failBinLit, clauseAllocator); - - for (uint32_t k = 1, size = c.size(); k < size; k++) { - if (!seen[c[k].var()] && level[c[k].var()] > 0) { - out_learnt[j++] = out_learnt[i]; - break; - } - } - } - } - max_literals += out_learnt.size(); - out_learnt.shrink(i - j); - for (uint32_t j = 0; j != analyze_toclear.size(); j++) - seen[analyze_toclear[j].var()] = 0; // ('seen[]' is now cleared) - - if (conf.doMinimLearntMore && out_learnt.size() > 1) - minimiseLeartFurther(out_learnt, calcNBLevels(out_learnt)); - - glue = calcNBLevels(out_learnt); - tot_literals += out_learnt.size(); - - // Find correct backtrack level: - // - if (out_learnt.size() == 1) - out_btlevel = 0; - else { - uint32_t max_i = 1; - for (uint32_t i = 2; i < out_learnt.size(); i++) - if (level[out_learnt[i].var()] > level[out_learnt[max_i].var()]) - max_i = i; - std::swap(out_learnt[max_i], out_learnt[1]); - out_btlevel = level[out_learnt[1].var()]; - } - - if (lastSelectedRestartType == dynamic_restart) { - #ifdef UPDATE_VAR_ACTIVITY_BASED_ON_GLUE - for(uint32_t i = 0; i != lastDecisionLevel.size(); i++) { - PropBy cl = reason[lastDecisionLevel[i]]; - if (cl.isClause() && clauseAllocator.getPointer(cl.getClause())->getGlue() < glue) - varBumpActivity(lastDecisionLevel[i]); - } - lastDecisionLevel.clear(); - #endif - } - - //We can only on-the-fly subsume clauses that are not 2- or 3-long - //furthermore, we cannot subsume a clause that is marked for deletion - //due to its high glue value - if (!conf.doOTFSubsume - || out_learnt.size() == 1 - || !oldConfl.isClause() - || oldConfl.getClause()->isXor() - #ifdef ENABLE_UNWIND_GLUE - || (conf.doMaxGlueDel && oldConfl.getClause()->getGlue() > conf.maxGlue) - #endif //ENABLE_UNWIND_GLUE - || out_learnt.size() >= oldConfl.getClause()->size()) return NULL; - - if (!subset(out_learnt, *oldConfl.getClause(), seen)) return NULL; - - improvedClauseNo++; - improvedClauseSize += oldConfl.getClause()->size() - out_learnt.size(); - return oldConfl.getClause(); -} - -/** -@brief Performs on-the-fly self-subsuming resolution - -Only uses binary and tertiary clauses already in the watchlists in native -form to carry out the forward-self-subsuming resolution -*/ -void Solver::minimiseLeartFurther(vec<Lit>& cl, const uint32_t glue) -{ - //80 million is kind of a hack. It seems that the longer the solving - //the slower this operation gets. So, limiting the "time" with total - //number of conflict literals is maybe a good way of doing this - bool clDoMinLRec = false; - if (conf.doCacheOTFSSR && conf.doMinimLMoreRecur) { - switch(lastSelectedRestartType) { - case dynamic_restart : - clDoMinLRec |= glue < 0.6*glueHistory.getAvgAllDouble(); - //NOTE: No "break;" here on purpose - case static_restart : - clDoMinLRec |= cl.size() < 0.6*conflSizeHist.getAvgDouble(); - break; - default : - assert(false); - } - } - - if (clDoMinLRec) moreRecurMinLDo++; - uint64_t thisUpdateTransOTFSSCache = UPDATE_TRANSOTFSSR_CACHE; - if (tot_literals > 80000000) thisUpdateTransOTFSSCache *= 2; - - //To count the "amount of time" invested in doing transitive on-the-fly - //self-subsuming resolution - uint32_t moreRecurProp = 0; - - for (uint32_t i = 0; i < cl.size(); i++) seen[cl[i].toInt()] = 1; - for (Lit *l = cl.getData(), *end = cl.getDataEnd(); l != end; l++) { - if (seen[l->toInt()] == 0) continue; - Lit lit = *l; - - if (clDoMinLRec) { - if (moreRecurProp > 450 - || (transOTFCache[l->toInt()].conflictLastUpdated != std::numeric_limits<uint64_t>::max() - && (transOTFCache[l->toInt()].conflictLastUpdated + thisUpdateTransOTFSSCache >= conflicts)) - ) { - for (vector<Lit>::const_iterator it = transOTFCache[l->toInt()].lits.begin(), end2 = transOTFCache[l->toInt()].lits.end(); it != end2; it++) { - seen[(~(*it)).toInt()] = 0; - } - } else { - updateTransCache++; - transMinimAndUpdateCache(lit, moreRecurProp); - } - } - - //watched is messed: lit is in watched[~lit] - vec<Watched>& ws = watches[(~lit).toInt()]; - for (vec<Watched>::iterator i = ws.getData(), end = ws.getDataEnd(); i != end; i++) { - if (i->isBinary()) { - seen[(~i->getOtherLit()).toInt()] = 0; - continue; - } - - if (i->isTriClause()) { - if (seen[(~i->getOtherLit()).toInt()] && seen[i->getOtherLit2().toInt()]) { - seen[(~i->getOtherLit()).toInt()] = 0; - } - if (seen[(~i->getOtherLit2()).toInt()] && seen[i->getOtherLit().toInt()]) { - seen[(~i->getOtherLit2()).toInt()] = 0; - } - continue; - } - - //watches are mostly sorted, so it's more-or-less OK to break - // if non-bi or non-tri is encountered - break; - } - } - - uint32_t removedLits = 0; - Lit *i = cl.getData(); - Lit *j= i; - //never remove the 0th literal - seen[cl[0].toInt()] = 1; - for (Lit* end = cl.getDataEnd(); i != end; i++) { - if (seen[i->toInt()]) *j++ = *i; - else removedLits++; - seen[i->toInt()] = 0; - } - numShrinkedClause += (removedLits > 0); - numShrinkedClauseLits += removedLits; - cl.shrink_(i-j); - - #ifdef VERBOSE_DEBUG - std::cout << "c Removed further " << removedLits << " lits" << std::endl; - #endif -} - -void Solver::transMinimAndUpdateCache(const Lit lit, uint32_t& moreRecurProp) -{ - vector<Lit>& allAddedToSeen2 = transOTFCache[lit.toInt()].lits; - allAddedToSeen2.clear(); - - toRecursiveProp.push(lit); - while(!toRecursiveProp.empty()) { - Lit thisLit = toRecursiveProp.top(); - toRecursiveProp.pop(); - //watched is messed: lit is in watched[~lit] - vec<Watched>& ws = watches[(~thisLit).toInt()]; - moreRecurProp += ws.size() +10; - for (vec<Watched>::iterator i = ws.getData(), end = ws.getDataEnd(); i != end; i++) { - if (i->isBinary()) { - moreRecurProp += 5; - Lit otherLit = i->getOtherLit(); - //don't do indefinite recursion, and don't remove "a" when doing self-subsuming-resolution with 'a OR b' - if (seen2[otherLit.toInt()] != 0 || otherLit == ~lit) break; - seen2[otherLit.toInt()] = 1; - allAddedToSeen2.push_back(otherLit); - toRecursiveProp.push(~otherLit); - } else { - break; - } - } - } - assert(toRecursiveProp.empty()); - - for (vector<Lit>::const_iterator it = allAddedToSeen2.begin(), end = allAddedToSeen2.end(); it != end; it++) { - seen[(~(*it)).toInt()] = 0; - seen2[it->toInt()] = 0; - } - - transOTFCache[lit.toInt()].conflictLastUpdated = conflicts; -} - -/** -@brief Check if 'p' can be removed from a learnt clause - -'abstract_levels' is used to abort early if the algorithm is -visiting literals at levels that cannot be removed later. -*/ -bool Solver::litRedundant(Lit p, uint32_t abstract_levels) -{ - analyze_stack.clear(); - analyze_stack.push(p); - int top = analyze_toclear.size(); - while (analyze_stack.size() > 0) { - assert(!reason[analyze_stack.last().var()].isNULL()); - PropByFull c(reason[analyze_stack.last().var()], failBinLit, clauseAllocator); - - analyze_stack.pop(); - - for (uint32_t i = 1, size = c.size(); i < size; i++) { - Lit p = c[i]; - if (!seen[p.var()] && level[p.var()] > 0) { - if (!reason[p.var()].isNULL() && (abstractLevel(p.var()) & abstract_levels) != 0) { - seen[p.var()] = 1; - analyze_stack.push(p); - analyze_toclear.push(p); - } else { - for (uint32_t j = top; j != analyze_toclear.size(); j++) - seen[analyze_toclear[j].var()] = 0; - analyze_toclear.shrink(analyze_toclear.size() - top); - return false; - } - } - } - } - - return true; -} - - -/*_________________________________________________________________________________________________ -| -| analyzeFinal : (p : Lit) -> [void] -| -| Description: -| Specialized analysis procedure to express the final conflict in terms of assumptions. -| Calculates the (possibly empty) set of assumptions that led to the assignment of 'p', and -| stores the result in 'out_conflict'. -|________________________________________________________________________________________________@*/ -void Solver::analyzeFinal(Lit p, vec<Lit>& out_conflict) -{ - out_conflict.clear(); - out_conflict.push(p); - - if (decisionLevel() == 0) - return; - - seen[p.var()] = 1; - - for (int32_t i = (int32_t)trail.size()-1; i >= (int32_t)trail_lim[0]; i--) { - Var x = trail[i].var(); - if (seen[x]) { - if (reason[x].isNULL()) { - assert(level[x] > 0); - out_conflict.push(~trail[i]); - } else { - PropByFull c(reason[x], failBinLit, clauseAllocator); - for (uint32_t j = 1, size = c.size(); j < size; j++) - if (level[c[j].var()] > 0) - seen[c[j].var()] = 1; - } - seen[x] = 0; - } - } - - seen[p.var()] = 0; -} - -/*_________________________________________________________________________________________________ -| -| propagate : [void] -> [Clause*] -| -| Description: -| Propagates all enqueued facts. If a conflict arises, the conflicting clause is returned, -| otherwise NULL. -| -| Post-conditions: -| * the propagation queue is empty, even if there was a conflict. -|________________________________________________________________________________________________@*/ -/** -@brief Propagates a binary clause - -Need to be somewhat tricky if the clause indicates that current assignement -is incorrect (i.e. both literals evaluate to FALSE). If conflict if found, -sets failBinLit -*/ -template<bool full> -inline bool Solver::propBinaryClause(vec<Watched>::iterator &i, const Lit p, PropBy& confl) -{ - lbool val = value(i->getOtherLit()); - if (val.isUndef()) { - if (full) uncheckedEnqueue(i->getOtherLit(), PropBy(p)); - else uncheckedEnqueueLight(i->getOtherLit()); - #ifdef DUMP_STATS_FULL - assert(((i->glue > 0) == i->getLearnt())); - if (full && i->glue > 0 && !simplifying) { - std::cout << "Prop by learnt size: " << 2 << std::endl; - std::cout << "Prop by learnt glue: " << i->glue << std::endl; - } - #endif //DUMP_STATS_FULL - } else if (val == l_False) { - confl = PropBy(p); - failBinLit = i->getOtherLit(); - qhead = trail.size(); - #ifdef DUMP_STATS_FULL - assert(((i->glue > 0) == i->getLearnt())); - if (full && i->glue > 0 && !simplifying) { - std::cout << "Confl by learnt size: " << 2 << std::endl; - std::cout << "Confl by learnt glue: " << i->glue << std::endl; - } - #endif //DUMP_STATS_FULL - - return false; - } - - return true; -} - -/** -@brief Propagates a tertiary (3-long) clause - -Need to be somewhat tricky if the clause indicates that current assignement -is incorrect (i.e. all 3 literals evaluate to FALSE). If conflict is found, -sets failBinLit -*/ -template<bool full> -inline bool Solver::propTriClause(vec<Watched>::iterator &i, const Lit p, PropBy& confl) -{ - lbool val = value(i->getOtherLit()); - if (val == l_True) return true; - - lbool val2 = value(i->getOtherLit2()); - if (val.isUndef() && val2 == l_False) { - if (full) uncheckedEnqueue(i->getOtherLit(), PropBy(p, i->getOtherLit2())); - else uncheckedEnqueueLight(i->getOtherLit()); - #ifdef DUMP_STATS_FULL - assert(conf.isPlain); - if (full && i->glue > 0 && !simplifying) { - std::cout << "Prop by learnt size: " << 3 << std::endl; - std::cout << "Prop by learnt glue: " << i->glue << std::endl; - } - #endif //DUMP_STATS_FULL - } else if (val == l_False && val2.isUndef()) { - if (full) uncheckedEnqueue(i->getOtherLit2(), PropBy(p, i->getOtherLit())); - else uncheckedEnqueueLight(i->getOtherLit2()); - #ifdef DUMP_STATS_FULL - assert(conf.isPlain); - if (full && i->glue > 0 && !simplifying) { - std::cout << "Prop by learnt size: " << 3 << std::endl; - std::cout << "Prop by learnt glue: " << i->glue << std::endl; - } - #endif //DUMP_STATS_FULL - } else if (val == l_False && val2 == l_False) { - confl = PropBy(p, i->getOtherLit2()); - failBinLit = i->getOtherLit(); - qhead = trail.size(); - #ifdef DUMP_STATS_FULL - assert(conf.isPlain); - if (full && i->glue > 0 && !simplifying) { - std::cout << "Confl by learnt size: " << 3 << std::endl; - std::cout << "Confl by learnt glue: " << i->glue << std::endl; - } - #endif //DUMP_STATS_FULL - - return false; - } - - return true; -} - -/** -@brief Propagates a tertiary (3-long) clause - -We have blocked literals in this case in the watchlist. That must be checked -and updated. -*/ -template<bool full> -inline bool Solver::propNormalClause(vec<Watched>::iterator &i, vec<Watched>::iterator &j, const Lit p, PropBy& confl, const bool update) -{ - if (value(i->getBlockedLit()).getBool()) { - // Clause is sat - *j++ = *i; - return true; - } - const uint32_t offset = i->getNormOffset(); - Clause& c = *clauseAllocator.getPointer(offset); - - // Make sure the false literal is data[1]: - if (c[0] == ~p) { - std::swap(c[0], c[1]); - } - - assert(c[1] == ~p); - - // If 0th watch is true, then clause is already satisfied. - if (value(c[0]).getBool()) { - *j = Watched(offset, c[0]); - j++; - return true; - } - // Look for new watch: - for (Lit *k = c.getData() + 2, *end2 = c.getDataEnd(); k != end2; k++) { - if (value(*k) != l_False) { - c[1] = *k; - *k = ~p; - watches[(~c[1]).toInt()].push(Watched(offset, c[0])); - return true; - } - } - - // Did not find watch -- clause is unit under assignment: - *j++ = *i; - if (value(c[0]) == l_False) { - #ifdef DUMP_STATS_FULL - if (full && c.learnt() && !simplifying) { - std::cout << "Confl by learnt size: " << c.size() << std::endl; - std::cout << "Confl by learnt glue: " << c.getGlue() << std::endl; - assert(!conf.isPlain || c.getGlue() > 1); - } - #endif //DUMP_STATS_FULL - confl = PropBy(offset); - qhead = trail.size(); - return false; - } else { - #ifdef DUMP_STATS_FULL - if (full && c.learnt() && !simplifying) { - std::cout << "Prop by learnt size: " << c.size() << std::endl; - std::cout << "Prop by learnt glue: " << c.getGlue() << std::endl; - assert(!conf.isPlain || c.getGlue() > 1); - } - #endif //DUMP_STATS_FULL - - if (full) uncheckedEnqueue(c[0], offset); - else uncheckedEnqueueLight(c[0]); - #ifdef DYNAMICALLY_UPDATE_GLUE - if (update && full && c.learnt() && c.getGlue() > 2) { - uint32_t glue = calcNBLevels(c); - if (glue+1 < c.getGlue()) { - //c.setGlue(std::min(nbLevels, MAX_THEORETICAL_GLUE); - c.setGlue(glue); - } - } - #endif - } - - return true; -} - -/** -@brief Propagates a tertiary (3-long) clause - -Strangely enough, we need to have 4 literals in the wathclists: -for the first two varialbles, BOTH negations (v and ~v). This means quite some -pain, since we need to remove v when moving ~v and vica-versa. However, it means -better memory-accesses since the watchlist is already in the memory... - -\todo maybe not worth it, and a variable-based watchlist should be used -*/ -template<bool full> -inline bool Solver::propXorClause(vec<Watched>::iterator &i, vec<Watched>::iterator &j, const Lit p, PropBy& confl) -{ - ClauseOffset offset = i->getXorOffset(); - XorClause& c = *(XorClause*)clauseAllocator.getPointer(offset); - - // Make sure the false literal is data[1]: - if (c[0].var() == p.var()) { - Lit tmp(c[0]); - c[0] = c[1]; - c[1] = tmp; - } - assert(c[1].var() == p.var()); - - bool final = c.xorEqualFalse(); - 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]); - c[1] = c[k]; - c[k] = tmp; - removeWXCl(watches[(~p).toInt()], offset); - watches[Lit(c[1].var(), false).toInt()].push(offset); - watches[Lit(c[1].var(), true).toInt()].push(offset); - return true; - } - - c[k] = c[k].unsign() ^ val.getBool(); - final ^= val.getBool(); - } - - // Did not find watch -- clause is unit under assignment: - *j++ = *i; - - if (assigns[c[0].var()].isUndef()) { - c[0] = c[0].unsign()^final; - if (full) uncheckedEnqueue(c[0], offset); - else uncheckedEnqueueLight(c[0]); - } else if (!final) { - confl = PropBy(offset); - qhead = trail.size(); - return false; - } else { - Lit tmp(c[0]); - c[0] = c[1]; - c[1] = tmp; - } - - return true; -} - -/** -@brief Does the propagation - -Basically, it goes through the watchlists recursively, and calls the appropirate -propagaton function -*/ -template<bool full> -PropBy Solver::propagate(const bool update) -{ - PropBy confl; - uint32_t num_props = 0; - - #ifdef VERBOSE_DEBUG - cout << "Propagation started" << endl; - #endif - - while (qhead < trail.size()) { - Lit p = trail[qhead++]; // 'p' is enqueued fact to propagate. - vec<Watched>& ws = watches[p.toInt()]; - num_props += ws.size()/2 + 2; - - #ifdef VERBOSE_DEBUG - cout << "Propagating lit " << p << endl; - cout << "ws origSize: "<< ws.size() << endl; - #endif - - vec<Watched>::iterator i = ws.getData(); - vec<Watched>::iterator j = i; - - vec<Watched>::iterator end = ws.getDataEnd(); - for (; i != end; i++) { - if (i->isBinary()) { - *j++ = *i; - if (!propBinaryClause<full>(i, p, confl)) break; - else continue; - } //end BINARY - - if (i->isTriClause()) { - *j++ = *i; - if (!propTriClause<full>(i, p, confl)) break; - else continue; - } //end TRICLAUSE - - if (i->isClause()) { - num_props += 4; - if (!propNormalClause<full>(i, j, p, confl, update)) break; - else continue; - } //end CLAUSE - - if (i->isXorClause()) { - num_props += 10; - if (!propXorClause<full>(i, j, p, confl)) break; - else continue; - } //end XORCLAUSE - } - if (i != end) { - i++; - //copy remaining watches - vec<Watched>::iterator j2 = i; - vec<Watched>::iterator i2 = j; - for(i2 = i, j2 = j; i2 != end; i2++) { - *j2++ = *i2; - } - //memmove(j, i, sizeof(Watched)*(end-i)); - } - //assert(i >= j); - ws.shrink_(i-j); - } - propagations += num_props; - simpDB_props -= num_props; - - #ifdef VERBOSE_DEBUG - cout << "Propagation ended." << endl; - #endif - - return confl; -} -template PropBy Solver::propagate<true>(const bool update); -template PropBy Solver::propagate<false>(const bool update); - -PropBy Solver::propagateBin(vec<Lit>& uselessBin) -{ - #ifdef DEBUG_USELESS_LEARNT_BIN_REMOVAL - assert(uselessBin.empty()); - #endif - - while (qhead < trail.size()) { - Lit p = trail[qhead++]; - - //setting up binPropData - uint32_t lev = binPropData[p.var()].lev; - Lit lev1Ancestor; - switch (lev) { - case 0 : - lev1Ancestor = lit_Undef; - break; - case 1: - lev1Ancestor = p; - break; - default: - lev1Ancestor = binPropData[p.var()].lev1Ancestor; - } - lev++; - const bool learntLeadHere = binPropData[p.var()].learntLeadHere; - bool& hasChildren = binPropData[p.var()].hasChildren; - hasChildren = false; - - //std::cout << "lev: " << lev << " ~p: " << ~p << std::endl; - const vec<Watched> & ws = watches[p.toInt()]; - propagations += 2; - for(vec<Watched>::const_iterator k = ws.getData(), end = ws.getDataEnd(); k != end; k++) { - hasChildren = true; - if (!k->isBinary()) continue; - - //std::cout << (~p) << ", " << k->getOtherLit() << " learnt: " << k->getLearnt() << std::endl; - lbool val = value(k->getOtherLit()); - if (val.isUndef()) { - uncheckedEnqueueLight2(k->getOtherLit(), lev, lev1Ancestor, learntLeadHere || k->getLearnt()); - } else if (val == l_False) { - return PropBy(p); - } else { - assert(val == l_True); - Lit lit2 = k->getOtherLit(); - if (lev > 1 - && level[lit2.var()] != 0 - && binPropData[lit2.var()].lev == 1 - && lev1Ancestor != lit2) { - //Was propagated at level 1, and again here, original level 1 binary clause is useless - binPropData[lit2.var()].lev = lev; - binPropData[lit2.var()].lev1Ancestor = lev1Ancestor; - binPropData[lit2.var()].learntLeadHere = learntLeadHere || k->getLearnt(); - uselessBin.push(lit2); - } - } - } - } - //std::cout << " -----------" << std::endl; - - return PropBy(); -} - -/** -@brief Only propagates binary clauses - -This is used in special algorithms outside the main Solver class -*/ -PropBy Solver::propagateNonLearntBin() -{ - multiLevelProp = false; - uint32_t origQhead = qhead + 1; - - while (qhead < trail.size()) { - Lit p = trail[qhead++]; - const vec<Watched> & ws = watches[p.toInt()]; - propagations += ws.size()/2 + 2; - for(vec<Watched>::const_iterator k = ws.getData(), end = ws.getDataEnd(); k != end; k++) { - if (!k->isNonLearntBinary()) break; - - lbool val = value(k->getOtherLit()); - if (val.isUndef()) { - if (qhead != origQhead) multiLevelProp = true; - uncheckedEnqueueLight(k->getOtherLit()); - } else if (val == l_False) { - return PropBy(p); - } - } - } - - return PropBy(); -} - -/** -@brief Propagate recursively on non-learnt binaries, but do not propagate exceptLit if we reach it -*/ -bool Solver::propagateBinExcept(const Lit exceptLit) -{ - while (qhead < trail.size()) { - Lit p = trail[qhead++]; - const vec<Watched> & ws = watches[p.toInt()]; - propagations += ws.size()/2 + 2; - for(vec<Watched>::const_iterator i = ws.getData(), end = ws.getDataEnd(); i != end; i++) { - if (!i->isNonLearntBinary()) break; - - lbool val = value(i->getOtherLit()); - if (val.isUndef() && i->getOtherLit() != exceptLit) { - uncheckedEnqueueLight(i->getOtherLit()); - } else if (val == l_False) { - return false; - } - } - } - - return true; -} - -/** -@brief Propagate only for one hop(=non-recursively) on non-learnt bins -*/ -bool Solver::propagateBinOneLevel() -{ - Lit p = trail[qhead]; - const vec<Watched> & ws = watches[p.toInt()]; - propagations += ws.size()/2 + 2; - for(vec<Watched>::const_iterator i = ws.getData(), end = ws.getDataEnd(); i != end; i++) { - if (!i->isNonLearntBinary()) break; - - lbool val = value(i->getOtherLit()); - if (val.isUndef()) { - uncheckedEnqueueLight(i->getOtherLit()); - } else if (val == l_False) { - return false; - } - } - - return true; -} - -struct LevelSorter -{ - LevelSorter(const vec<int32_t>& _level) : - level(_level) - {} - - bool operator()(const Lit lit1, const Lit lit2) const { - return level[lit1.var()] < level[lit2.var()]; - } - - const vec<int32_t>& level; -}; - -/** -@brief Calculates the glue of a clause - -Used to calculate the Glue of a new clause, or to update the glue of an -existing clause. Only used if the glue-based activity heuristic is enabled, -i.e. if we are in GLUCOSE mode (not MiniSat mode) -*/ -template<class T> -inline uint32_t Solver::calcNBLevels(const T& ps) -{ - uint32_t nbLevels = 0; - for(const Lit *l = ps.getData(), *end = ps.getDataEnd(); l != end; l++) { - int32_t lev = level[l->var()]; - if (!seen[lev]) { - nbLevels++; - seen[lev] = 1; - } - } - for(const Lit *l = ps.getData(), *end = ps.getDataEnd(); l != end; l++) { - int32_t lev = level[l->var()]; - seen[lev] = 0; - } - return nbLevels; -} - -/*_________________________________________________________________________________________________ -| -| reduceDB : () -> [void] -| -| Description: -| Remove half of the learnt clauses, minus the clauses locked by the current assignment. Locked -| clauses are clauses that are reason to some assignment. Binary clauses are never removed. -|________________________________________________________________________________________________@*/ -bool reduceDB_ltMiniSat::operator () (const Clause* x, const Clause* y) { - const uint32_t xsize = x->size(); - const uint32_t ysize = y->size(); - - assert(xsize > 2 && ysize > 2); - if (x->getMiniSatAct() == y->getMiniSatAct()) - return xsize > ysize; - else return x->getMiniSatAct() < y->getMiniSatAct(); -} - -bool reduceDB_ltGlucose::operator () (const Clause* x, const Clause* y) { - const uint32_t xsize = x->size(); - const uint32_t ysize = y->size(); - - assert(xsize > 2 && ysize > 2); - if (x->getGlue() > y->getGlue()) return 1; - if (x->getGlue() < y->getGlue()) return 0; - return xsize > ysize; -} - -/** -@brief Removes learnt clauses that have been found not to be too good - -Either based on glue or MiniSat-style learnt clause activities, the clauses are -sorted and then removed -*/ -void Solver::reduceDB() -{ - uint32_t i, j; - - nbReduceDB++; - if (lastSelectedRestartType == dynamic_restart) - std::sort(learnts.getData(), learnts.getDataEnd(), reduceDB_ltGlucose()); - else - std::sort(learnts.getData(), learnts.getDataEnd(), reduceDB_ltMiniSat()); - - #ifdef VERBOSE_DEBUG - std::cout << "Cleaning clauses" << std::endl; - for (uint32_t i = 0; i != learnts.size(); i++) { - std::cout << "activity:" << learnts[i]->getGlue() - << " \toldActivity:" << learnts[i]->getMiniSatAct() - << " \tsize:" << learnts[i]->size() << std::endl; - } - #endif - - - const uint32_t removeNum = (double)learnts.size() * (double)RATIOREMOVECLAUSES; - uint32_t totalNumRemoved = 0; - uint32_t totalNumNonRemoved = 0; - uint64_t totalGlueOfRemoved = 0; - uint64_t totalSizeOfRemoved = 0; - uint64_t totalGlueOfNonRemoved = 0; - uint64_t totalSizeOfNonRemoved = 0; - for (i = j = 0; i != removeNum; i++){ - if (i+1 < removeNum) __builtin_prefetch(learnts[i+1]); - assert(learnts[i]->size() > 2); - if (!locked(*learnts[i]) - && (lastSelectedRestartType == static_restart || learnts[i]->getGlue() > 2) - && learnts[i]->size() > 3) { //we cannot update activity of 3-longs because of wathclists - - totalGlueOfRemoved += learnts[i]->getGlue(); - totalSizeOfRemoved += learnts[i]->size(); - totalNumRemoved++; - removeClause(*learnts[i]); - } else { - totalGlueOfNonRemoved += learnts[i]->getGlue(); - totalSizeOfNonRemoved += learnts[i]->size(); - totalNumNonRemoved++; - learnts[j++] = learnts[i]; - } - } - for (; i < learnts.size(); i++) { - totalGlueOfNonRemoved += learnts[i]->getGlue(); - totalSizeOfNonRemoved += learnts[i]->size(); - totalNumNonRemoved++; - learnts[j++] = learnts[i]; - } - learnts.shrink_(i - j); - - if (conf.verbosity >= 3) { - std::cout << "c rem-learnts " << std::setw(6) << totalNumRemoved - << " avgGlue " - << std::fixed << std::setw(5) << std::setprecision(2) << ((double)totalGlueOfRemoved/(double)totalNumRemoved) - << " avgSize " - << std::fixed << std::setw(6) << std::setprecision(2) << ((double)totalSizeOfRemoved/(double)totalNumRemoved) - << " || remain " << std::setw(6) << totalNumNonRemoved - << " avgGlue " - << std::fixed << std::setw(5) << std::setprecision(2) << ((double)totalGlueOfNonRemoved/(double)totalNumNonRemoved) - << " avgSize " - << std::fixed << std::setw(6) << std::setprecision(2) << ((double)totalSizeOfNonRemoved/(double)totalNumNonRemoved) - << std::endl; - } - - clauseAllocator.consolidate(this); -} - -inline int64_t abs64(int64_t a) -{ - if (a < 0) return -a; - return a; -} - -/** -@brief Simplify the clause database according to the current top-level assigment. - -We remove satisfied clauses, clean clauses from assigned literals, find -binary xor-clauses and replace variables with one another. Heuristics are -used to check if we need to find binary xor clauses or not. -*/ -bool Solver::simplify() -{ - testAllClauseAttach(); - assert(decisionLevel() == 0); - - if (!ok || !propagate<false>().isNULL()) { - ok = false; - return false; - } - - if (simpDB_props > 0) { - return true; - } - double myTime = cpuTime(); - - double slowdown = (100000.0/((double)numBins * 30000.0/((double)order_heap.size()))); - slowdown = std::min(1.5, slowdown); - slowdown = std::max(0.01, slowdown); - - double speedup = 200000000.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 (conf.doFindEqLits && conf.doRegFindEqLits && - (((double)abs64((int64_t)numNewBin - (int64_t)lastNbBin)/BINARY_TO_XOR_APPROX) * slowdown) > - ((double)order_heap.size() * PERCENTAGEPERFORMREPLACE * speedup)) { - lastSearchForBinaryXor = propagations; - - clauseCleaner->cleanClauses(clauses, ClauseCleaner::clauses); - clauseCleaner->cleanClauses(learnts, ClauseCleaner::learnts); - clauseCleaner->removeSatisfiedBins(); - if (!ok) return false; - - if (!sCCFinder->find2LongXors()) return false; - - lastNbBin = numNewBin; - } - - // Remove satisfied clauses: - clauseCleaner->removeAndCleanAll(); - if (!ok) return false; - - if (conf.doReplace && !varReplacer->performReplace()) - return false; - - // Remove fixed variables from the variable heap: - order_heap.filter(VarFilter(*this)); - - #ifdef USE_GAUSS - for (vector<Gaussian*>::iterator gauss = gauss_matrixes.begin(), end = gauss_matrixes.end(); gauss != end; gauss++) { - if (!(*gauss)->full_init()) return false; - } - #endif //USE_GAUSS - - simpDB_assigns = nAssigns(); - simpDB_props = std::min((uint64_t)80000000, 4*clauses_literals + 4*learnts_literals); //at most 6 sec wait - simpDB_props = std::max((int64_t)30000000, simpDB_props); //at least 2 sec wait - totalSimplifyTime += cpuTime() - myTime; - - testAllClauseAttach(); - return true; -} - -/** -@brief Search for a model - -Limits: must be below the specified number of conflicts and must keep the -number of learnt clauses below the provided limit - -Use negative value for 'nof_conflicts' or 'nof_learnts' to indicate infinity. - -Output: 'l_True' if a partial assigment that is consistent with respect to the -clauseset is found. If all variables are decision variables, this means -that the clause set is satisfiable. 'l_False' if the clause set is -unsatisfiable. 'l_Undef' if the bound on number of conflicts is reached. -*/ -lbool Solver::search(const uint64_t nof_conflicts, const uint64_t nof_conflicts_fullrestart, const bool update) -{ - assert(ok); - uint64_t conflictC = 0; - vec<Lit> learnt_clause; - llbool ret; - - if (!simplifying && update) { - starts++; - if (restartType == static_restart) staticStarts++; - else dynStarts++; - } - glueHistory.fastclear(); - - #ifdef USE_GAUSS - for (vector<Gaussian*>::iterator gauss = gauss_matrixes.begin(), end = gauss_matrixes.end(); gauss != end; gauss++) { - if (!(*gauss)->full_init()) - return l_False; - } - #endif //USE_GAUSS - - testAllClauseAttach(); - findAllAttach(); - #ifdef VERBOSE_DEBUG - std::cout << "c started Solver::search()" << std::endl; - //printAllClauses(); - #endif //VERBOSE_DEBUG - for (;;) { - assert(ok); - PropBy confl = propagate<true>(update); - #ifdef VERBOSE_DEBUG - std::cout << "c Solver::search() has finished propagation" << std::endl; - //printAllClauses(); - #endif //VERBOSE_DEBUG - - if (conflicts > conf.maxConfl) { - if (conf.verbosity >= 0) { - std::cout << "c Interrupting: limit on number of conflicts, " - << conf.maxConfl - << " reached! " << std::endl; - } - needToInterrupt = true; - return l_Undef; - } - - if (!confl.isNULL()) { - ret = handle_conflict(learnt_clause, confl, conflictC, update); - if (ret != l_Nothing) return ret; - } else { - #ifdef USE_GAUSS - bool at_least_one_continue = false; - 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; - #endif //USE_GAUSS - - assert(ok); - if (conf.doCacheOTFSSR && decisionLevel() == 1) saveOTFData(); - ret = new_decision(nof_conflicts, nof_conflicts_fullrestart, conflictC); - if (ret != l_Nothing) return ret; - } - } -} - -/** -@brief Picks a new decision variable to branch on - -@returns l_Undef if it should restart instead. l_False if it reached UNSAT - (through simplification) -*/ -llbool Solver::new_decision(const uint64_t nof_conflicts, const uint64_t nof_conflicts_fullrestart, const uint64_t conflictC) -{ - - if (conflicts >= nof_conflicts_fullrestart || needToInterrupt) { - cancelUntil(0); - return l_Undef; - } - - // Reached bound on number of conflicts? - switch (restartType) { - case dynamic_restart: - if (glueHistory.isvalid() && - 0.95*glueHistory.getAvgDouble() > glueHistory.getAvgAllDouble()) { - - #ifdef DEBUG_DYNAMIC_RESTART - if (glueHistory.isvalid()) { - std::cout << "glueHistory.getavg():" << glueHistory.getavg() <<std::endl; - std::cout << "totalSumOfGlue:" << totalSumOfGlue << std::endl; - std::cout << "conflicts:" << conflicts<< std::endl; - std::cout << "compTotSumGlue:" << compTotSumGlue << std::endl; - std::cout << "conflicts-compTotSumGlue:" << conflicts-compTotSumGlue<< std::endl; - } - #endif - - cancelUntil(0); - return l_Undef; - } - break; - case static_restart: - if (conflictC >= nof_conflicts) { - cancelUntil(0); - return l_Undef; - } - break; - case auto_restart: - assert(false); - break; - } - - // Simplify the set of problem clauses: - if (decisionLevel() == 0) { - if (!dataSync->syncData()) return l_False; - if (!simplify()) return l_False; - } - - // Reduce the set of learnt clauses: - if (conflicts >= numCleanedLearnts * nbClBeforeRed + nbCompensateSubsumer) { - numCleanedLearnts ++; - reduceDB(); - nbClBeforeRed += 500; - } - - Lit next = lit_Undef; - while (decisionLevel() < assumptions.size()) { - // Perform user provided assumption: - Lit p = assumptions[decisionLevel()]; - if (value(p) == l_True) { - // Dummy decision level: - newDecisionLevel(); - } else if (value(p) == l_False) { - analyzeFinal(~p, conflict); - return l_False; - } else { - next = p; - break; - } - } - - if (next == lit_Undef) { - // New variable decision: - decisions++; - next = pickBranchLit(); - - if (next == lit_Undef) - return l_True; - } - - // Increase decision level and enqueue 'next' - assert(value(next) == l_Undef); - newDecisionLevel(); - uncheckedEnqueue(next); - - return l_Nothing; -} - -/** -@brief Handles a conflict that we reached through propagation - -Handles on-the-fly subsumption: the OTF subsumption check is done in -conflict analysis, but this is the code that actually replaces the original -clause with that of the shorter one -@returns l_False if UNSAT -*/ -llbool Solver::handle_conflict(vec<Lit>& learnt_clause, PropBy confl, uint64_t& conflictC, const bool update) -{ - #ifdef VERBOSE_DEBUG - cout << "Handling conflict: "; - for (uint32_t i = 0; i < learnt_clause.size(); i++) - cout << learnt_clause[i].var()+1 << ","; - cout << endl; - #endif - - int backtrack_level; - uint32_t glue; - - conflicts++; - conflictC++; - if (decisionLevel() == 0) - return l_False; - learnt_clause.clear(); - Clause* c = analyze(confl, learnt_clause, backtrack_level, glue, update); - if (update) { - avgBranchDepth.push(decisionLevel()); - if (restartType == dynamic_restart) glueHistory.push(glue); - conflSizeHist.push(learnt_clause.size()); - } - cancelUntil(backtrack_level); - #ifdef DUMP_STATS - std::cout << "Learnt clause: " << learnt_clause - << " glue: " << glue - << " declevel: " << decisionLevel() - << " traillen: " << trail.size() - << " abst: " << calcAbstraction(learnt_clause) - << std::endl; - assert(learnt_clause.size() == 1 || glue > 1); - #endif //#ifdef DUMP_STATS - - #ifdef VERBOSE_DEBUG - cout << "Learning:"; - for (uint32_t i = 0; i < learnt_clause.size(); i++) printLit(learnt_clause[i]), cout << " "; - cout << endl; - cout << "reverting var " << learnt_clause[0].var()+1 << " to " << !learnt_clause[0].sign() << endl; - #endif - - assert(value(learnt_clause[0]) == l_Undef); - //Unitary learnt - if (learnt_clause.size() == 1) { - uncheckedEnqueue(learnt_clause[0]); - assert(backtrack_level == 0 && "Unit clause learnt, so must cancel until level 0, right?"); - - #ifdef VERBOSE_DEBUG - cout << "Unit clause learnt." << endl; - #endif - //Normal learnt - } else { - if (learnt_clause.size() == 2) { - attachBinClause(learnt_clause[0], learnt_clause[1], true); - numNewBin++; - dataSync->signalNewBinClause(learnt_clause); - uncheckedEnqueue(learnt_clause[0], PropBy(learnt_clause[1])); - goto end; - } - - if (learnt_clause.size() > 3) { - std::sort(learnt_clause.getData()+1, learnt_clause.getDataEnd(), PolaritySorter(polarity)); - } - if (c) { //On-the-fly subsumption - uint32_t origSize = c->size(); - detachClause(*c); - for (uint32_t i = 0; i != learnt_clause.size(); i++) - (*c)[i] = learnt_clause[i]; - c->shrink(origSize - learnt_clause.size()); - if (c->learnt() && c->getGlue() > glue) - c->setGlue(glue); // LS - attachClause(*c); - uncheckedEnqueue(learnt_clause[0], clauseAllocator.getOffset(c)); - } else { //no on-the-fly subsumption - c = clauseAllocator.Clause_new(learnt_clause, true); - #ifdef ENABLE_UNWIND_GLUE - if (conf.doMaxGlueDel && glue > conf.maxGlue) { - nbClOverMaxGlue++; - nbCompensateSubsumer++; - unWindGlue[learnt_clause[0].var()] = c; - #ifdef UNWINDING_DEBUG - std::cout << "unwind, var:" << learnt_clause[0].var() << std::endl; - c->plainPrint(); - #endif //VERBOSE_DEBUG - } else { - #endif //ENABLE_UNWIND_GLUE - learnts.push(c); - #ifdef ENABLE_UNWIND_GLUE - } - #endif //ENABLE_UNWIND_GLUE - c->setGlue(std::min(glue, MAX_THEORETICAL_GLUE)); - attachClause(*c); - uncheckedEnqueue(learnt_clause[0], clauseAllocator.getOffset(c)); - } - end:; - } - - varDecayActivity(); - if (update && restartType == static_restart) claDecayActivity(); - - return l_Nothing; -} - -/** -@brief After a full restart, determines which restar type to use - -Uses class RestartTypeChooser to do the heavy-lifting -*/ -bool Solver::chooseRestartType(const uint32_t& lastFullRestart) -{ - uint32_t relativeStart = starts - lastFullRestart; - - if (relativeStart > RESTART_TYPE_DECIDER_FROM && relativeStart < RESTART_TYPE_DECIDER_UNTIL) { - if (conf.fixRestartType == auto_restart) - restartTypeChooser->addInfo(); - - if (relativeStart == (RESTART_TYPE_DECIDER_UNTIL-1)) { - RestartType tmp; - if (conf.fixRestartType == auto_restart) - tmp = restartTypeChooser->choose(); - else - tmp = conf.fixRestartType; - - if (tmp == dynamic_restart) { - glueHistory.fastclear(); - if (conf.verbosity >= 3) - std::cout << "c Decided on dynamic restart strategy" - << std::endl; - } else { - if (conf.verbosity >= 1) - std::cout << "c Decided on static restart strategy" - << std::endl; - - if (!matrixFinder->findMatrixes()) return false; - } - lastSelectedRestartType = tmp; - restartType = tmp; - restartTypeChooser->reset(); - } - } - - return true; -} - -inline void Solver::setDefaultRestartType() -{ - if (conf.fixRestartType != auto_restart) restartType = conf.fixRestartType; - else restartType = static_restart; - - glueHistory.clear(); - glueHistory.initSize(MIN_GLUE_RESTART); - conflSizeHist.clear(); - conflSizeHist.initSize(1000); - - lastSelectedRestartType = restartType; -} - -/** -@brief The function that brings together almost all CNF-simplifications - -It burst-searches for given number of conflicts, then it tries all sorts of -things like variable elimination, subsumption, failed literal probing, etc. -to try to simplifcy the problem at hand. -*/ -lbool Solver::simplifyProblem(const uint32_t numConfls) -{ - testAllClauseAttach(); - bool gaussWasCleared = clearGaussMatrixes(); - - StateSaver savedState(*this);; - - #ifdef BURST_SEARCH - if (conf.verbosity >= 3) - std::cout << "c " << std::setw(24) << " " - << "Simplifying problem for " << std::setw(8) << numConfls << " confls" - << std::endl; - conf.random_var_freq = 1; - simplifying = true; - uint64_t origConflicts = conflicts; - #endif //BURST_SEARCH - - lbool status = l_Undef; - - #ifdef BURST_SEARCH - restartType = static_restart; - - printRestartStat("S"); - while(status == l_Undef && conflicts-origConflicts < numConfls && needToInterrupt == false) { - status = search(100, std::numeric_limits<uint64_t>::max(), false); - } - if (needToInterrupt) return l_Undef; - printRestartStat("S"); - if (status != l_Undef) goto end; - #endif //BURST_SEARCH - - if (conf.doXorSubsumption && !xorSubsumer->simplifyBySubsumption()) goto end; - - if (conf.doFailedLit && conf.doCacheOTFSSR) { - BothCache both(*this); - if (!both.tryBoth()) goto end; - } - if (conf.doCacheOTFSSR) cleanCache(); - if (conf.doClausVivif && !clauseVivifier->vivifyClauses()) goto end; - - if (conf.doCacheOTFSSRSet && order_heap.size() < 200000) { - if (conf.doCacheOTFSSR == false && conf.verbosity > 0) { - std::cout << "c turning cache ON because the number of active variables is lower now" << std::endl; - } - conf.doCacheOTFSSR = true; - } - if (conf.doFailedLit && !failedLitSearcher->search()) goto end; - - if (conf.doSatELite && !subsumer->simplifyBySubsumption()) goto end; - - /*if (findNormalXors && xorclauses.size() > 200 && clauses.size() < MAX_CLAUSENUM_XORFIND/8) { - XorFinder xorFinder(*this, clauses, ClauseCleaner::clauses); - if (!xorFinder.doNoPart(3, 7)) { - status = l_False; - goto end; - } - } else*/ if (xorclauses.size() <= 200 && xorclauses.size() > 0 && nClauses() > 10000) { - XorFinder x(*this, clauses); - x.addAllXorAsNorm(); - } - - if (conf.doClausVivif && !clauseVivifier->vivifyClauses()) goto end; - - //addSymmBreakClauses(); - - if (conf.doSortWatched) sortWatched(); - if (conf.doCacheOTFSSR && conf.doCalcReach) calcReachability(); - -end: - #ifdef BURST_SEARCH - if (conf.verbosity >= 3) - std::cout << "c Simplifying finished" << std::endl; - #endif //#ifdef BURST_SEARCH - - savedState.restore(); - simplifying = false; - - if (status == l_Undef && ok && gaussWasCleared && !matrixFinder->findMatrixes()) - status = l_False; - - testAllClauseAttach(); - - if (!ok) return l_False; - return status; -} - -/** -@brief Should we perform a full restart? - -If so, we also do the things to be done if the full restart is effected. -*/ -bool Solver::checkFullRestart(uint64_t& nof_conflicts, uint64_t& nof_conflicts_fullrestart, uint32_t& lastFullRestart) -{ - if (nof_conflicts_fullrestart > 0 && conflicts >= nof_conflicts_fullrestart) { - #ifdef USE_GAUSS - clearGaussMatrixes(); - #endif //USE_GAUSS - nof_conflicts = conf.restart_first + (double)conf.restart_first*conf.restart_inc; - nof_conflicts_fullrestart = (double)nof_conflicts_fullrestart * FULLRESTART_MULTIPLIER_MULTIPLIER; - restartType = static_restart; - lastFullRestart = starts; - - if (conf.verbosity >= 3) - std::cout << "c Fully restarting" << std::endl; - printRestartStat("F"); - - /*if (findNormalXors && clauses.size() < MAX_CLAUSENUM_XORFIND) { - XorFinder xorFinder(this, clauses, ClauseCleaner::clauses); - if (!xorFinder.doNoPart(3, 10)) - return false; - }*/ - - //calculateDefaultPolarities(); - if (conf.polarity_mode != polarity_auto) { - for (uint32_t i = 0; i < polarity.size(); i++) { - polarity[i] = defaultPolarity(); - } - } - - fullStarts++; - } - - return true; -} - -/** -@brief Performs a set of pre-optimisations before the beggining of solving - -This is somewhat different than the set of optimisations carried out during -solving in simplifyProblem(). For instance, binary xors are searched fully -here, while there, no search for them is carried out. Also, the ordering -is different. - -\todo experiment to use simplifyProblem() instead of this, with the only -addition of binary clause search. Maybe it will do just as good (or better). -*/ -void Solver::performStepsBeforeSolve() -{ - assert(qhead == trail.size()); - testAllClauseAttach(); - - printRestartStat(); - if (conf.doReplace && !varReplacer->performReplace()) return; - - order_heap.filter(Solver::VarFilter(*this)); - if (order_heap.size() > 300000) { - if (conf.verbosity > 0) { - std::cout << "c turning cache OFF because there are too many active variables" << std::endl; - } - conf.doCacheOTFSSR = false; - } - - bool saveDoHyperBin = conf.doHyperBinRes; - conf.doHyperBinRes = false; - clauseAllocator.consolidate(this, true); - if (conf.doFailedLit && !failedLitSearcher->search()) return; - conf.doHyperBinRes = saveDoHyperBin; - if (conf.doClausVivif && !conf.libraryUsage - && !clauseVivifier->vivifyClauses()) return; - - #ifdef VERBOSE_DEBUG - printAllClauses(); - #endif //VERBOSE_DEBUG - if (conf.doSatELite - && !conf.libraryUsage - && clauses.size() < 4800000 - && !subsumer->simplifyBySubsumption()) - return; - - if (conf.doFindEqLits) { - if (!sCCFinder->find2LongXors()) return; - lastNbBin = numNewBin; - if (conf.doReplace && !varReplacer->performReplace(true)) return; - } - - if (conf.doFindXors && clauses.size() < MAX_CLAUSENUM_XORFIND) { - XorFinder xorFinder(*this, clauses); - if (!xorFinder.fullFindXors(3, 7)) return; - } - - if (xorclauses.size() > 1) { - if (conf.doXorSubsumption && !xorSubsumer->simplifyBySubsumption()) - return; - - if (conf.doReplace && !varReplacer->performReplace()) - return; - } - - if (conf.doSortWatched) sortWatched(); - if (conf.doCacheOTFSSR && conf.doCalcReach) calcReachability(); - - testAllClauseAttach(); -} - -/** -@brief Initialises model, restarts, learnt cluause cleaning, burst-search, etc. -*/ -void Solver::initialiseSolver() -{ - //Clear up previous stuff like model, final conflict, matrixes - model.clear(); - conflict.clear(); - clearGaussMatrixes(); - - //Initialise restarts & dynamic restart datastructures - setDefaultRestartType(); - - //Initialise avg. branch depth - avgBranchDepth.clear(); - avgBranchDepth.initSize(500); - - //Initialise number of restarts&full restarts - starts = 0; - fullStarts = 0; - - if (nClauses() * conf.learntsize_factor < nbClBeforeRed) { - if (nClauses() * conf.learntsize_factor < nbClBeforeRed/2) - nbClBeforeRed /= 4; - else - nbClBeforeRed = (nClauses() * conf.learntsize_factor)/2; - } - - testAllClauseAttach(); - findAllAttach(); -} - -/** -@brief The main solve loop that glues everything together - -We clear everything needed, pre-simplify the problem, calculate default -polarities, and start the loop. Finally, we either report UNSAT or extend the -found solution with all the intermediary simplifications (e.g. variable -elimination, etc.) and output the solution. -*/ -lbool Solver::solve(const vec<Lit>& assumps) -{ - #ifdef VERBOSE_DEBUG - std::cout << "Solver::solve() called" << std::endl; - #endif - if (!ok) return l_False; - assert(qhead == trail.size()); - assert(subsumer->checkElimedUnassigned()); - assert(xorSubsumer->checkElimedUnassigned()); - - if (libraryCNFFile) - fprintf(libraryCNFFile, "c Solver::solve() called\n"); - - assumps.copyTo(assumptions); - initialiseSolver(); - uint64_t nof_conflicts = conf.restart_first; //Geometric restart policy, start with this many - uint64_t nof_conflicts_fullrestart = conf.restart_first * FULLRESTART_MULTIPLIER + conflicts; //at this point, do a full restart - uint32_t lastFullRestart = starts; //last time a full restart was made was at this number of restarts - lbool status = l_Undef; //Current status - uint64_t nextSimplify = conf.restart_first * conf.simpStartMult + conflicts; //Do simplifyProblem() at this number of conflicts - if (!conf.doSchedSimp) nextSimplify = std::numeric_limits<uint64_t>::max(); - - if (conflicts == 0) { - if (conf.doPerformPreSimp) performStepsBeforeSolve(); - if (!ok) return l_False; - - calculateDefaultPolarities(); - } - - printStatHeader(); - printRestartStat("B"); - uint64_t lastConflPrint = conflicts; - // Search: - while (status == l_Undef && starts < conf.maxRestarts) { - #ifdef DEBUG_VARELIM - assert(subsumer->checkElimedUnassigned()); - assert(xorSubsumer->checkElimedUnassigned()); - #endif //DEBUG_VARELIM - - if ((conflicts - lastConflPrint) > std::min(std::max(conflicts/100*6, (uint64_t)4000), (uint64_t)20000)) { - printRestartStat("N"); - lastConflPrint = conflicts; - } - - if (conf.doSchedSimp && conflicts >= nextSimplify) { - status = simplifyProblem(conf.simpBurstSConf); - printRestartStat(); - lastConflPrint = conflicts; - nextSimplify = std::min((uint64_t)((double)conflicts * conf.simpStartMMult), conflicts + MAX_CONFL_BETWEEN_SIMPLIFY); - if (status != l_Undef) break; - } - - status = search(nof_conflicts, std::min(nof_conflicts_fullrestart, nextSimplify)); - if (needToInterrupt) { - cancelUntil(0); - return l_Undef; - } - - nof_conflicts = (double)nof_conflicts * conf.restart_inc; - if (status != l_Undef) break; - if (!checkFullRestart(nof_conflicts, nof_conflicts_fullrestart , lastFullRestart)) - return l_False; - if (!chooseRestartType(lastFullRestart)) - return l_False; - } - printEndSearchStat(); - - #ifdef VERBOSE_DEBUG - if (status == l_True) - std::cout << "Solution is SAT" << std::endl; - else if (status == l_False) - std::cout << "Solution is UNSAT" << std::endl; - else - std::cout << "Solutions is UNKNOWN" << std::endl; - #endif //VERBOSE_DEBUG - - if (status == l_True) handleSATSolution(); - else if (status == l_False) handleUNSATSolution(); - - cancelUntil(0); - restartTypeChooser->reset(); - if (status == l_Undef) clauseCleaner->removeAndCleanAll(true); - - #ifdef VERBOSE_DEBUG - std::cout << "Solver::solve() finished" << std::endl; - #endif - return status; -} - -/** -@brief Extends a SAT solution to the full solution - -variable elimination, variable replacement, sub-part solving, etc. all need to -be handled correctly to arrive at a solution that is a solution to ALL of the -original problem, not just of what remained of it at the end inside this class -(i.e. we need to combine things from the helper classes) -*/ -void Solver::handleSATSolution() -{ - - /*if (greedyUnbound) { - double time = cpuTime(); - FindUndef finder(*this); - const uint32_t unbounded = finder.unRoll(); - if (conf.verbosity >= 1) - printf("c Greedy unbounding :%5.2lf s, unbounded: %7d vars\n", cpuTime()-time, unbounded); - }*/ - assert(subsumer->checkElimedUnassigned()); - assert(xorSubsumer->checkElimedUnassigned()); - - varReplacer->extendModelPossible(); - checkSolution(); - - if (subsumer->getNumElimed() || xorSubsumer->getNumElimed()) { - if (conf.verbosity >= 1) { - std::cout << "c Solution needs extension. Extending." << std::endl; - } - Solver s; - s.conf = conf; - s.conf.doSatELite = false; - s.conf.doReplace = false; - s.conf.doFindEqLits = false; - s.conf.doRegFindEqLits = false; - s.conf.doFailedLit= false; - s.conf.doConglXors = false; - s.conf.doSubsWNonExistBins = false; - s.conf.doRemUselessBins = false; - s.conf.doClausVivif = false; - s.conf.doSortWatched = false; - s.conf.verbosity = 0; - - vec<Lit> tmp; - for (Var var = 0; var < nVars(); var++) { - s.newVar(decision_var[var] - || subsumer->getVarElimed()[var] - || varReplacer->varHasBeenReplaced(var) - || xorSubsumer->getVarElimed()[var] - ); - - //assert(!(xorSubsumer->getVarElimed()[var] && (decision_var[var] || subsumer->getVarElimed()[var] || varReplacer->varHasBeenReplaced(var)))); - - if (value(var) != l_Undef) { - #ifdef VERBOSE_DEBUG - std::cout << "Setting var " << var + 1 - << " in extend-solver to " << value(var) << std::endl; - #endif - tmp.clear(); - tmp.push(Lit(var, value(var) == l_False)); - s.addClause(tmp); - } - } - varReplacer->extendModelImpossible(s); - subsumer->extendModel(s); - xorSubsumer->extendModel(s); - - lbool status = s.solve(); - release_assert(status == l_True && "c ERROR! Extension of model failed!"); -#ifdef VERBOSE_DEBUG - std::cout << "Solution extending finished. Enqueuing results" << std::endl; -#endif - //need to start new decision level, otherwise uncheckedEnqueue will - //enqueue to decision level 0 in certain cases :S - newDecisionLevel(); - for (Var var = 0; var < nVars(); var++) { - if (assigns[var] == l_Undef && s.model[var] != l_Undef) - uncheckedEnqueue(Lit(var, s.model[var] == l_False)); - } - ok = (propagate<false>().isNULL()); - release_assert(ok && "c ERROR! Extension of model failed!"); - } - checkSolution(); - //Copy model: - model.growTo(nVars()); - for (Var var = 0; var != nVars(); var++) model[var] = value(var); -} - -/** -@brief When problem is decided to be UNSAT, this is called - -There is basically nothing to be handled for the moment, but this could be -made extensible -*/ -void Solver::handleUNSATSolution() -{ - if (conflict.size() == 0) - ok = false; -} - -void Solver::cleanCache() -{ - for(uint32_t i = 0; i < nVars(); i++) { - if (subsumer->getVarElimed()[i] || value(i) != l_Undef) { - vector<Lit> tmp1; - transOTFCache[Lit(i, false).toInt()].lits.swap(tmp1); - vector<Lit> tmp2; - transOTFCache[Lit(i, true).toInt()].lits.swap(tmp2); - continue; - } - - for(int which = 0; which < 2; which++) { - cleanCachePart(Lit(i, which)); - - } - } -} - -void Solver::cleanCachePart(const Lit vertLit) -{ - vector<Lit>& transCache = transOTFCache[(~vertLit).toInt()].lits; - assert(seen_vec.empty()); - - vector<Lit>::iterator it = transCache.begin(); - vector<Lit>::iterator it2 = it; - - size_t newSize = 0; - for (vector<Lit>::iterator end = transCache.end(); it != end; it++) { - Lit lit = *it; - lit = varReplacer->getReplaceTable()[lit.var()] ^ lit.sign(); - if (lit == vertLit - || seen[lit.toInt()] - || subsumer->getVarElimed()[lit.var()] - || subsumer->getVarElimed()[lit.var()] - ) continue; - - *it2++ = lit; - - //Don't allow the same value to be in the cache twice - seen[lit.toInt()] = 1; - seen_vec.push_back(lit); - - //Increase valid size - newSize++; - } - transCache.resize(newSize); - - //Clear up seen - for(vector<Lit>::const_iterator it = seen_vec.begin(), end = seen_vec.end(); it != end; it++) { - seen[it->toInt()] = 0; - } - seen_vec.clear(); -} diff --git a/src/prop/cryptominisat/Solver/Solver.h b/src/prop/cryptominisat/Solver/Solver.h deleted file mode 100644 index 9276823dd..000000000 --- a/src/prop/cryptominisat/Solver/Solver.h +++ /dev/null @@ -1,859 +0,0 @@ -/****************************************************************************************[Solver.h] -MiniSat -- Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson -CryptoMiniSat -- Copyright (c) 2009 Mate Soos -glucose -- Gilles Audemard, Laurent Simon (2008) - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or -substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -**************************************************************************************************/ - -#ifndef SOLVER_H -#define SOLVER_H - -#include <cstdio> -#include <string.h> -#include <stdio.h> -#include <stack> -#include <stdexcept> - -//#define ANIMATE3D - -#include "PropBy.h" -#include "Vec.h" -#include "Heap.h" -#include "Alg.h" -#include "MersenneTwister.h" -#include "SolverTypes.h" -#include "Clause.h" -#include "constants.h" -#include "BoundedQueue.h" -#include "GaussianConfig.h" -#include "ClauseAllocator.h" -#include "SolverConf.h" - -namespace CMSat { - -class Gaussian; -class MatrixFinder; -class Conglomerate; -class VarReplacer; -class XorFinder; -class FindUndef; -class ClauseCleaner; -class FailedLitSearcher; -class Subsumer; -class XorSubsumer; -class RestartTypeChooser; -class StateSaver; -class UselessBinRemover; -class SCCFinder; -class ClauseVivifier; -class SharedData; -class DataSync; -class BothCache; - -#ifdef VERBOSE_DEBUG -#define DEBUG_UNCHECKEDENQUEUE_LEVEL0 -using std::cout; -using std::endl; -#endif - -struct reduceDB_ltMiniSat -{ - bool operator () (const Clause* x, const Clause* y); -}; - -struct reduceDB_ltGlucose -{ - bool operator () (const Clause* x, const Clause* y); -}; - -struct PolaritySorter -{ - PolaritySorter(vector<char>& polarity) : - pol(polarity) - {} - - bool operator()(const Lit lit1, const Lit lit2) const - { - return (((((bool)pol[lit1.var()])^(lit1.sign())) == false) - && ((((bool)pol[lit2.var()])^(lit2.sign())) == true)); - } - vector<char>& pol; -}; - -/** -@brief The main solver class - -This class creates and manages all the others. It is here that settings must -be set, and it is here that all data enter and leaves the system. The basic -use is to add normal and XOR clauses, and then solve(). The solver will then -solve the problem, and return with either a SAT solution with corresponding -variable settings, or report that the problem in UNSATisfiable. - -The prolbem-solving can be interrupted with the "interrupt" varible, and can -also be pre-set to stop after a certain number of restarts. The data until the -interruption can be dumped by previously setting parameters like -dumpSortedLearnts -*/ -class Solver -{ -public: - - // Constructor/Destructor: - // - Solver(const SolverConf& conf = SolverConf(), const GaussConf& _gaussconfig = GaussConf(), SharedData* sharedUnitData = NULL); - ~Solver(); - - // Problem specification: - // - Var newVar (bool dvar = true) throw (std::out_of_range); // Add a new variable with parameters specifying variable mode. - template<class T> - bool addClause (T& ps); // Add a clause to the solver. NOTE! 'ps' may be shrunk by this method! - template<class T> - bool addLearntClause(T& ps, const uint32_t glue = 10, const float miniSatActivity = 10.0); - template<class T> - bool addXorClause (T& ps, bool xorEqualFalse) throw (std::out_of_range); // Add a xor-clause to the solver. NOTE! 'ps' may be shrunk by this method! - - // Solving: - // - lbool solve (const vec<Lit>& assumps); ///<Search for a model that respects a given set of assumptions. - lbool solve (); ///<Search without assumptions. - void handleSATSolution(); ///<Extends model, if needed, and fills "model" - void handleUNSATSolution(); ///<If conflict really was zero-length, sets OK to false - bool okay () const; ///<FALSE means solver is in a conflicting state - - // Variable mode: - // - void setDecisionVar (Var v, bool b); ///<Declare if a variable should be eligible for selection in the decision heuristic. - void addBranchingVariable (Var v); - - // Read state: - // - lbool value (const Var x) const; ///<The current value of a variable. - lbool value (const Lit p) const; ///<The current value of a literal. - 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. - - // Extra results: (read-only member variable) - // - vec<lbool> model; ///<If problem is satisfiable, this vector contains the model (if any). - vec<Lit> conflict; ///<If problem is unsatisfiable (possibly under assumptions), this vector represent the final conflict clause expressed in the assumptions. - - // Mode of operation: - // - SolverConf conf; - GaussConf gaussconfig; ///<Configuration for the gaussian elimination can be set here - bool needToInterrupt; ///<Used internally mostly. If set to TRUE, we will interrupt cleanly ASAP. The important thing is "cleanly", since we need to wait until a point when all datastructures are in a sane state (i.e. not in the middle of some algorithm) - - //Logging - void needStats(); // Prepares the solver to output statistics - void needProofGraph(); // Prepares the solver to output proof graphs during solving - const vec<Clause*>& get_sorted_learnts(); //return the set of learned clauses, sorted according to the logic used in MiniSat to distinguish between 'good' and 'bad' clauses - const vec<Clause*>& get_learnts() const; //Get all learnt clauses that are >1 long - vector<Lit> get_unitary_learnts() const; //return the set of unitary learnt clauses - uint32_t get_unitary_learnts_num() const; //return the number of unitary learnt clauses - bool dumpSortedLearnts(const std::string& fileName, const uint32_t maxSize); // Dumps all learnt clauses (including unitary ones) into the file; returns true for success, false for failure - bool needLibraryCNFFile(const std::string& fileName); //creates file in current directory with the filename indicated, and puts all calls from the library into the file. - bool dumpOrigClauses(const std::string& fileName) const; - void printBinClause(const Lit litP1, const Lit litP2, FILE* outfile) const; - - uint32_t get_sum_gauss_called() const; - uint32_t get_sum_gauss_confl() const; - uint32_t get_sum_gauss_prop() const; - uint32_t get_sum_gauss_unit_truths() const; - - //Printing statistics - void printStats(); - uint32_t getNumElimSubsume() const; ///<Get number of variables eliminated - uint32_t getNumElimXorSubsume() const; ///<Get number of variables eliminated with xor-magic - uint32_t getNumXorTrees() const; ///<Get the number of trees built from 2-long XOR-s. This is effectively the number of variables that replace other variables - uint32_t getNumXorTreesCrownSize() const; ///<Get the number of variables being replaced by other variables - /** - @brief Get total time spent in Subsumer. - - This includes: subsumption, self-subsuming resolution, variable elimination, - blocked clause elimination, subsumption and self-subsuming resolution - using non-existent binary clauses. - */ - double getTotalTimeSubsumer() const; - double getTotalTimeFailedLitSearcher() const; - double getTotalTimeSCC() const; - - /** - @brief Get total time spent in XorSubsumer. - - This included subsumption, variable elimination through XOR, and local - substitution (see Heule's Thesis) - */ - double getTotalTimeXorSubsumer() const; - -protected: - //gauss - bool clearGaussMatrixes(); - vector<Gaussian*> gauss_matrixes; - void print_gauss_sum_stats(); - uint32_t sum_gauss_called; - uint32_t sum_gauss_confl; - uint32_t sum_gauss_prop; - uint32_t sum_gauss_unit_truths; - - // Statistics - // - template<class T, class T2> - void printStatsLine(std::string left, T value, T2 value2, std::string extra); - template<class T> - void printStatsLine(std::string left, T value, std::string extra = ""); - uint64_t starts; ///<Num restarts - uint64_t dynStarts; ///<Num dynamic restarts - uint64_t staticStarts; ///<Num static restarts: note that after full restart, we do a couple of static restarts always - /** - @brief Num full restarts - - Full restarts are restarts that are made always, no matter what, after - a certan number of conflicts have passed. The problem will tried to be - decomposed into multiple parts, and then there will be a couple of static - restarts made. Finally, the problem will be determined to be MiniSat-type - or Glucose-type. - - NOTE: I belive there is a point in having full restarts even if the - glue-clause vs. MiniSat clause can be fully resolved - */ - uint64_t fullStarts; ///<Number of full restarts made - uint64_t decisions; ///<Number of decisions made - uint64_t rnd_decisions; ///<Numer of random decisions made - /** - @brief An approximation of accumulated propagation difficulty - - It does not hold the number of propagations made. Rather, it holds a - value that is approximate of the difficulty of the propagations made - This makes sense, since it is not at all the same difficulty to proapgate - a 2-long clause than to propagate a 20-long clause. In certain algorihtms, - there is a need to know how difficult the propagation part was. This value - can be used in these algorihms. However, the reported "statistic" will be - bogus. - */ - uint64_t propagations; - uint64_t conflicts; ///<Num conflicts - uint64_t clauses_literals, learnts_literals, max_literals, tot_literals; - uint64_t nbGlue2; ///<Num learnt clauses that had a glue of 2 when created - uint64_t numNewBin; ///<new binary clauses that have been found through some form of resolution (shrinking, conflicts, etc.) - uint64_t lastNbBin; ///<Last time we seached for SCCs, numBins was this much - uint64_t lastSearchForBinaryXor; ///<Last time we looked for binary xors, this many bogoprops(=propagations) has been done - uint64_t nbReduceDB; ///<Number of times learnt clause have been cleaned - uint64_t improvedClauseNo; ///<Num clauses improved using on-the-fly subsumption - uint64_t improvedClauseSize; ///<Num literals removed using on-the-fly subsumption - uint64_t numShrinkedClause; ///<Num clauses improved using on-the-fly self-subsuming resolution - uint64_t numShrinkedClauseLits; ///<Num literals removed by on-the-fly self-subsuming resolution - uint64_t moreRecurMinLDo; ///<Decided to carry out transitive on-the-fly self-subsuming resolution on this many clauses - uint64_t updateTransCache; ///<Number of times the transitive OTF-reduction cache has been updated - uint64_t nbClOverMaxGlue; ///<Number or clauses over maximum glue defined in maxGlue - - //Multi-threading - DataSync* dataSync; - - // Helper structures: - // - struct VarOrderLt { - const vec<uint32_t>& activity; - bool operator () (Var x, Var y) const { - return activity[x] > activity[y]; - } - VarOrderLt(const vec<uint32_t>& act) : activity(act) { } - }; - - struct VarFilter { - const Solver& s; - VarFilter(const Solver& _s) : s(_s) {} - bool operator()(Var v) const { - return s.assigns[v].isUndef() && s.decision_var[v]; - } - }; - - // Solver state: - // - bool ok; ///< If FALSE, the constraints are already unsatisfiable. No part of the solver state may be used! - ClauseAllocator clauseAllocator; ///< Handles memory allocation for claues - vec<Clause*> clauses; ///< List of problem clauses that are normally larger than 2. Sometimes, due to on-the-fly self-subsuming resoulution, clauses here become 2-long. They are never purposfully put here such that they are long - vec<XorClause*> xorclauses; ///< List of problem xor-clauses. Will be freed - vec<Clause*> learnts; ///< List of learnt clauses. - uint32_t numBins; - vec<XorClause*> freeLater; ///< xor clauses that need to be freed later (this is needed due to Gauss) \todo Get rid of this - float cla_inc; ///< Amount to bump learnt clause oldActivity with - vec<vec<Watched> > watches; ///< 'watches[lit]' is a list of constraints watching 'lit' (will go there if literal becomes true). - vec<lbool> assigns; ///< The current assignments - vector<char> 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<PropBy> 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<BinPropData> binPropData; - uint32_t qhead; ///< Head of queue (as index into the trail) - Lit failBinLit; ///< Used to store which watches[~lit] we were looking through when conflict occured - vec<Lit> assumptions; ///< Current set of assumptions provided to solve by the user. - bqueue<uint32_t> avgBranchDepth; ///< Avg branch depth. We collect this, and use it to do random look-around in the searchspace during simplifyProblem() - MTRand mtrand; ///< random number generator - vector<Var> branching_variables; - - ///////////////// - // Variable activities - ///////////////// - Heap<VarOrderLt> order_heap; ///< A priority queue of variables ordered with respect to the variable activity. All variables here MUST be decision variables. If you changed the decision variables, you MUST filter this - vec<uint32_t> activity; ///< A heuristic measurement of the activity of a variable. - uint32_t var_inc; ///< Amount to bump next variable with. - - ///////////////// - // Learnt clause cleaning - ///////////////// - uint64_t numCleanedLearnts; ///< Number of times learnt clauses have been removed through simplify() up until now - uint32_t nbClBeforeRed; ///< Number of learnt clauses before learnt-clause cleaning - uint32_t nbCompensateSubsumer; ///< Number of learnt clauses that subsumed normal clauses last time subs. was executed (used to delay learnt clause-cleaning) - - ///////////////////////// - // For glue calculation & dynamic restarts - ///////////////////////// - //uint64_t MYFLAG; ///<For glue calculation - template<class T> - uint32_t calcNBLevels(const T& ps); - //vec<uint64_t> permDiff; ///<permDiff[var] is used to count the number of different decision level variables in learnt clause (filled with data from MYFLAG ) - vec<Var> lastDecisionLevel; - bqueue<uint32_t> glueHistory; ///< Set of last decision levels in (glue of) conflict clauses. Used for dynamic restarting - #ifdef ENABLE_UNWIND_GLUE - vec<Clause*> unWindGlue; - #endif //ENABLE_UNWIND_GLUE - - // 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. - // - vector<char> seen; ///<Used in multiple places. Contains 2 * numVars() elements, all zeroed out - vector<Lit> seen_vec; - vec<Lit> analyze_stack; - vec<Lit> analyze_toclear; - - //////////// - // Transitive on-the-fly self-subsuming resolution - /////////// - class TransCache { - public: - TransCache() : - conflictLastUpdated(std::numeric_limits<uint64_t>::max()) - {}; - - vector<Lit> lits; - uint64_t conflictLastUpdated; - }; - class LitReachData { - public: - LitReachData() : - lit(lit_Undef) - , numInCache(0) - {} - Lit lit; - uint32_t numInCache; - }; - vector<char> seen2; ///<To reduce temoprary data creation overhead. Used in minimiseLeartFurther(). contains 2 * numVars() elements, all zeroed out - vec<Lit> allAddedToSeen2; ///<To reduce temoprary data creation overhead. Used in minimiseLeartFurther() - std::stack<Lit> toRecursiveProp; ///<To reduce temoprary data creation overhead. Used in minimiseLeartFurther() - vector<TransCache> transOTFCache; - bqueue<uint32_t> conflSizeHist; - void minimiseLeartFurther(vec<Lit>& cl, const uint32_t glue); - void transMinimAndUpdateCache(const Lit lit, uint32_t& moreRecurProp); - void saveOTFData(); - vector<LitReachData>litReachable; - void calcReachability(); - void cleanCache(); - void cleanCachePart(const Lit vertLit); - - //////////// - //Logging - /////////// - FILE *libraryCNFFile; //The file that all calls from the library are logged - - ///////////////// - // Propagating - //////////////// - Lit pickBranchLit (); // Return the next decision variable. - void newDecisionLevel (); // Begins a new decision level. - void uncheckedEnqueue (const Lit p, const PropBy& from = PropBy()); // Enqueue a literal. Assumes value of literal is undefined. - void uncheckedEnqueueLight (const Lit p); - void uncheckedEnqueueLight2(const Lit p, const uint32_t binPropDatael, const Lit lev1Ancestor, const bool learntLeadHere); - PropBy propagateBin(vec<Lit>& uselessBin); - PropBy propagateNonLearntBin(); - bool multiLevelProp; - bool propagateBinExcept(const Lit exceptLit); - bool propagateBinOneLevel(); - template<bool full> - PropBy propagate(const bool update = true); // Perform unit propagation. Returns possibly conflicting clause. - template<bool full> - bool propTriClause (vec<Watched>::iterator &i, const Lit p, PropBy& confl); - template<bool full> - bool propBinaryClause(vec<Watched>::iterator &i, const Lit p, PropBy& confl); - template<bool full> - bool propNormalClause(vec<Watched>::iterator &i, vec<Watched>::iterator &j, const Lit p, PropBy& confl, const bool update); - template<bool full> - bool propXorClause (vec<Watched>::iterator &i, vec<Watched>::iterator &j, const Lit p, PropBy& confl); - void sortWatched(); - - /////////////// - // Conflicting - /////////////// - void cancelUntil (int level); // Backtrack until a certain level. - void cancelUntilLight(); - Clause* analyze (PropBy confl, vec<Lit>& out_learnt, int& out_btlevel, uint32_t &nblevels, const bool update); - 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()') - void insertVarOrder (Var x); // Insert a variable in the decision order priority queue. - - ///////////////// - // Searching - ///////////////// - lbool search (const uint64_t nof_conflicts, const uint64_t nof_conflicts_fullrestart, const bool update = true); // Search for a given number of conflicts. - llbool handle_conflict (vec<Lit>& learnt_clause, PropBy confl, uint64_t& conflictC, const bool update);// Handles the conflict clause - llbool new_decision (const uint64_t nof_conflicts, const uint64_t nof_conflicts_fullrestart, const uint64_t conflictC); // Handles the case when all propagations have been made, and now a decision must be made - - ///////////////// - // Maintaining Variable/Clause activity: - ///////////////// - void claBumpActivity (Clause& c); - void varDecayActivity (); // Decay all variables with the specified factor. Implemented by increasing the 'bump' value instead. - void varBumpActivity (Var v); // Increase a variable with the current 'bump' value. - void claDecayActivity (); // Decay all clauses with the specified factor. Implemented by increasing the 'bump' value instead. - - ///////////////// - // Operations on clauses: - ///////////////// - template<class T> bool addClauseHelper(T& ps) throw (std::out_of_range); - template <class T> - Clause* addClauseInt(T& ps, const bool learnt = false, const uint32_t glue = 10, const float miniSatActivity = 10.0, const bool inOriginalInput = false); - template<class T> - XorClause* addXorClauseInt(T& ps, bool xorEqualFalse, const bool learnt = false) throw (std::out_of_range); - void attachBinClause(const Lit lit1, const Lit lit2, const bool learnt); - void attachClause (XorClause& c); - void attachClause (Clause& c); // Attach a clause to watcher lists. - void detachClause (const XorClause& c); - void detachClause (const Clause& c); // Detach a clause to watcher lists. - void detachModifiedClause(const Lit lit1, const Lit lit2, const Lit lit3, const uint32_t origSize, const Clause* address); - void detachModifiedClause(const Var var1, const Var var2, const uint32_t origSize, const XorClause* address); - template<class T> - void removeClause(T& c); // Detach and free a clause. - bool locked (const Clause& c) const; // Returns TRUE if a clause is a reason for some implication in the current state. - - /////////////////////////// - // Debug clause attachment - /////////////////////////// - void testAllClauseAttach() const; - void findAllAttach() const; - bool findClause(XorClause* c) const; - bool findClause(Clause* c) const; - bool xorClauseIsAttached(const XorClause& c) const; - bool normClauseIsAttached(const Clause& c) const; - - // Misc: - // - uint32_t decisionLevel () const; // Gives the current decisionlevel. - uint32_t abstractLevel (const Var x) const; // Used to represent an abstraction of sets of decision levels. - - ///////////////////////// - //Classes that must be friends, since they accomplish things on our datastructures - ///////////////////////// - friend class VarFilter; - friend class Gaussian; - friend class FindUndef; - friend class XorFinder; - friend class Conglomerate; - friend class MatrixFinder; - friend class VarReplacer; - friend class ClauseCleaner; - friend class RestartTypeChooser; - friend class FailedLitSearcher; - friend class Subsumer; - friend class XorSubsumer; - friend class StateSaver; - friend class UselessBinRemover; - friend class OnlyNonLearntBins; - friend class ClauseAllocator; - friend class CompleteDetachReatacher; - friend class SCCFinder; - friend class ClauseVivifier; - friend class DataSync; - friend class BothCache; - Conglomerate* conglomerate; - VarReplacer* varReplacer; - ClauseCleaner* clauseCleaner; - FailedLitSearcher* failedLitSearcher; - Subsumer* subsumer; - XorSubsumer* xorSubsumer; - RestartTypeChooser* restartTypeChooser; - MatrixFinder* matrixFinder; - SCCFinder* sCCFinder; - ClauseVivifier* clauseVivifier; - - ///////////////////////// - // Restart type handling - ///////////////////////// - bool chooseRestartType(const uint32_t& lastFullRestart); - void setDefaultRestartType(); - bool checkFullRestart(uint64_t& nof_conflicts, uint64_t& nof_conflicts_fullrestart, uint32_t& lastFullRestart); - RestartType restartType; ///<Used internally to determine which restart strategy is currently in use - RestartType lastSelectedRestartType; ///<The last selected restart type. Used when we are just after a full restart, and need to know how to really act - - ////////////////////////// - // Problem simplification - ////////////////////////// - void performStepsBeforeSolve(); - lbool simplifyProblem(const uint32_t numConfls); - void reduceDB(); // Reduce the set of learnt clauses. - bool simplify(); // Removes satisfied clauses and finds binary xors - bool simplifying; ///<We are currently doing burst search - double totalSimplifyTime; - 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()'. - - ///////////////////////////// - // SAT solution verification - ///////////////////////////// - void checkSolution (); - bool verifyModel () const; - bool verifyBinClauses() const; - bool verifyClauses (const vec<Clause*>& cs) const; - bool verifyXorClauses () const; - - // Debug & etc: - void printAllClauses(); - void printLit (const Lit l) const; - void checkLiteralCount(); - void printStatHeader () const; - void printRestartStat (const char* type = "N"); - void printEndSearchStat(); - void addSymmBreakClauses(); - void initialiseSolver(); - - //Misc related binary clauses - void dumpBinClauses(const bool alsoLearnt, const bool alsoNonLearnt, FILE* outfile) const; - uint32_t countNumBinClauses(const bool alsoLearnt, const bool alsoNonLearnt) const; - uint32_t getBinWatchSize(const bool alsoLearnt, const Lit lit); - void printStrangeBinLit(const Lit lit) const; - - ///////////////////// - // Polarity chooser - ///////////////////// - void 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 tallyVotesBin(vec<double>& votes) const; - void tallyVotes(const vec<Clause*>& cs, vec<double>& votes) const; - void tallyVotes(const vec<XorClause*>& cs, vec<double>& votes) const; - void setPolarity(Var v, bool b); // Declare which polarity the decision heuristic should use for a variable. Requires mode 'polarity_user'. - vector<char> polarity; // The preferred polarity of each variable. -}; - - - -//********************************** -// Implementation of inline methods -//********************************** - -inline void Solver::insertVarOrder(Var x) -{ - if (!order_heap.inHeap(x) && decision_var[x]) order_heap.insert(x); -} - -inline void Solver::varDecayActivity() -{ - var_inc *= 11; - var_inc /= 10; -} -inline void Solver::varBumpActivity(Var v) -{ - if ( (activity[v] += var_inc) > (0x1U) << 24 ) { - //printf("RESCALE!!!!!!\n"); - //std::cout << "var_inc: " << var_inc << std::endl; - // Rescale: - for (Var var = 0; var != nVars(); var++) { - activity[var] >>= 14; - } - var_inc >>= 14; - //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: - if (order_heap.inHeap(v)) - order_heap.decrease(v); -} - -inline void Solver::claBumpActivity (Clause& c) -{ - if ( (c.getMiniSatAct() += cla_inc) > 1e20 ) { - // Rescale: - for (uint32_t i = 0; i < learnts.size(); i++) - learnts[i]->getMiniSatAct() *= 1e-17; - cla_inc *= 1e-20; - } -} - -inline void Solver::claDecayActivity() -{ - //cla_inc *= clause_decay; -} - -inline bool Solver::locked(const Clause& c) const -{ - if (c.size() <= 3) return true; //we don't know in this case :I - PropBy from(reason[c[0].var()]); - return from.isClause() && !from.isNULL() && from.getClause() == clauseAllocator.getOffset(&c) && value(c[0]) == l_True; -} - -inline void Solver::newDecisionLevel() -{ - trail_lim.push(trail.size()); - #ifdef VERBOSE_DEBUG - cout << "New decision level: " << trail_lim.size() << endl; - #endif -} -/*inline int Solver::nbPropagated(int level) { - if (level == decisionLevel()) - return trail.size() - trail_lim[level-1] - 1; - return trail_lim[level] - trail_lim[level-1] - 1; -}*/ -inline uint32_t Solver::decisionLevel () const -{ - return trail_lim.size(); -} -inline uint32_t Solver::abstractLevel (const Var x) const -{ - return 1 << (level[x] & 31); -} -inline lbool Solver::value (const Var x) const -{ - return assigns[x]; -} -inline lbool Solver::value (const Lit p) const -{ - return assigns[p.var()] ^ p.sign(); -} -inline lbool Solver::modelValue (const Lit p) const -{ - return model[p.var()] ^ p.sign(); -} -inline uint32_t Solver::nAssigns () const -{ - return trail.size(); -} -inline uint32_t Solver::nClauses () const -{ - return clauses.size() + xorclauses.size(); -} -inline uint32_t Solver::nLiterals () const -{ - return clauses_literals + learnts_literals; -} -inline uint32_t Solver::nLearnts () const -{ - return learnts.size(); -} -inline uint32_t Solver::nVars () const -{ - return assigns.size(); -} -inline void Solver::setPolarity (Var v, bool b) -{ - polarity [v] = (char)b; -} -inline void Solver::setDecisionVar(Var v, bool b) -{ - decision_var[v] = b; - if (b) { - insertVarOrder(v); - } -} -inline void Solver::addBranchingVariable(Var v) -{ - branching_variables.push_back(v); -} -inline lbool Solver::solve () -{ - vec<Lit> tmp; - return solve(tmp); -} -inline bool Solver::okay () const -{ - return ok; -} - -inline uint32_t Solver::get_sum_gauss_unit_truths() const -{ - return sum_gauss_unit_truths; -} - -inline uint32_t Solver::get_sum_gauss_called() const -{ - return sum_gauss_called; -} - -inline uint32_t Solver::get_sum_gauss_confl() const -{ - return sum_gauss_confl; -} - -inline uint32_t Solver::get_sum_gauss_prop() const -{ - return sum_gauss_prop; -} - -inline uint32_t Solver::get_unitary_learnts_num() const -{ - if (decisionLevel() > 0) - return trail_lim[0]; - else - return trail.size(); -} - -template<class T> -inline void Solver::removeClause(T& c) -{ - detachClause(c); - clauseAllocator.clauseFree(&c); -} - -//********************************** -// Debug + etc: -//********************************** - -static inline void logLit(FILE* f, Lit l) -{ - fprintf(f, "%sx%d", l.sign() ? "~" : "", l.var()+1); -} - -static inline void logLits(FILE* f, const vec<Lit>& ls) -{ - fprintf(f, "[ "); - if (ls.size() > 0) { - logLit(f, ls[0]); - for (uint32_t i = 1; i < ls.size(); i++) { - fprintf(f, ", "); - logLit(f, ls[i]); - } - } - fprintf(f, "] "); -} - -#ifndef DEBUG_ATTACH_FULL -inline void Solver::testAllClauseAttach() const -{ - return; -} -inline void Solver::findAllAttach() const -{ - return; -} -#endif //DEBUG_ATTACH_FULL - -inline void Solver::uncheckedEnqueueLight(const Lit p) -{ - assert(value(p.var()) == l_Undef); - #if WATCHED_CACHE_NUM > 0 - __builtin_prefetch(watches.getData() + p.toInt()); - #else - if (watches[p.toInt()].size() > 0) __builtin_prefetch(watches[p.toInt()].getData()); - #endif - - assigns [p.var()] = boolToLBool(!p.sign());//lbool(!sign(p)); // <<== abstract but not uttermost effecient - trail.push(p); - if (decisionLevel() == 0) { - level[p.var()] = 0; - #ifdef ANIMATE3D - fprintf(stderr, "s %u %d\n", p.var(), p.sign()); - #endif - } -} - -inline void Solver::uncheckedEnqueueLight2(const Lit p, const uint32_t binSubLevel, const Lit lev1Ancestor, const bool learntLeadHere) -{ - assert(value(p.var()) == l_Undef); - #if WATCHED_CACHE_NUM > 0 - __builtin_prefetch(watches.getData() + p.toInt()); - #else - if (watches[p.toInt()].size() > 0) __builtin_prefetch(watches[p.toInt()].getData()); - #endif - - assigns [p.var()] = boolToLBool(!p.sign());//lbool(!sign(p)); // <<== abstract but not uttermost effecient - trail.push(p); - binPropData[p.var()].lev = binSubLevel; - binPropData[p.var()].lev1Ancestor = lev1Ancestor; - binPropData[p.var()].learntLeadHere = learntLeadHere; -} - -/** -@brief Enqueues&sets a new fact that has been found - -Call this when a fact has been found. Sets the value, enqueues it for -propagation, sets its level, sets why it was propagated, saves the polarity, -and does some logging if logging is enabled. - -@p p the fact to enqueue -@p from Why was it propagated (binary clause, tertiary clause, normal clause) -*/ -inline void Solver::uncheckedEnqueue(const Lit p, const PropBy& from) -{ - #ifdef DEBUG_UNCHECKEDENQUEUE_LEVEL0 - #ifndef VERBOSE_DEBUG - if (decisionLevel() == 0) - #endif //VERBOSE_DEBUG - - std::cout << "uncheckedEnqueue var " << p.var()+1 - << " to val " << !p.sign() - << " level: " << decisionLevel() - << " sublevel: " << trail.size() - << " by: " << from << std::endl; - - if (from.isClause() && !from.isNULL()) { - std::cout << "by clause: " << *clauseAllocator.getPointer(from.getClause()) << std::endl; - } - #endif //DEBUG_UNCHECKEDENQUEUE_LEVEL0 - - //assert(decisionLevel() == 0 || !subsumer->getVarElimed()[p.var()]); - - const Var v = p.var(); - assert(value(v).isUndef()); - #if WATCHED_CACHE_NUM > 0 - __builtin_prefetch(watches.getData() + p.toInt()); - #else - if (watches[p.toInt()].size() > 0) __builtin_prefetch(watches[p.toInt()].getData()); - #endif - - assigns [v] = boolToLBool(!p.sign()); - #ifdef ANIMATE3D - fprintf(stderr, "s %u %d\n", v, p.sign()); - #endif - level [v] = decisionLevel(); - reason [v] = from; - polarity[v] = p.sign(); - trail.push(p); -} - -} - -#endif //SOLVER_H diff --git a/src/prop/cryptominisat/Solver/SolverConf.cpp b/src/prop/cryptominisat/Solver/SolverConf.cpp deleted file mode 100644 index e7a5cfafa..000000000 --- a/src/prop/cryptominisat/Solver/SolverConf.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/***************************************************************************** -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 "SolverConf.h" -#include <limits> - -using namespace CMSat; - -SolverConf::SolverConf() : - random_var_freq(0.001) - , clause_decay (1 / 0.999) - , restart_first(100) - , restart_inc(1.5) - , learntsize_factor((double)1/(double)3) - - , expensive_ccmin (true) - , polarity_mode (polarity_auto) - , verbosity (0) - , restrictPickBranch(0) - - //Simplification - , simpBurstSConf(NUM_CONFL_BURST_SEARCH) - , simpStartMult(SIMPLIFY_MULTIPLIER) - , simpStartMMult(SIMPLIFY_MULTIPLIER_MULTIPLIER) - - , doPerformPreSimp (true) - , failedLitMultiplier(2.0) - - //optimisations to do - , doFindXors (true) - , doFindEqLits (true) - , doRegFindEqLits (true) - , doReplace (true) - , doConglXors (true) - , doHeuleProcess (true) - , doSchedSimp (true) - , doSatELite (true) - , doXorSubsumption (true) - , doHyperBinRes (true) - , doBlockedClause (false) - , doVarElim (true) - , doSubsume1 (true) - , doClausVivif (true) - , doSortWatched (true) - , doMinimLearntMore(true) - , doMinimLMoreRecur(true) - , doFailedLit (true) - , doRemUselessBins (true) - , doSubsWBins (true) - , doSubsWNonExistBins(true) - , doRemUselessLBins(true) - #ifdef ENABLE_UNWIND_GLUE - , doMaxGlueDel (false) - #endif //ENABLE_UNWIND_GLUE - , doPrintAvgBranch (false) - , doCacheOTFSSR (true) - , doCacheOTFSSRSet (true) - , doExtendedSCC (false) - , doCalcReach (true) - , doBXor (true) - , doOTFSubsume (true) - , maxConfl (std::numeric_limits<uint64_t>::max()) - , isPlain (false) - - , maxRestarts (std::numeric_limits<uint32_t>::max()) - , needToDumpLearnts(false) - , needToDumpOrig (false) - , maxDumpLearntsSize(std::numeric_limits<uint32_t>::max()) - , libraryUsage (true) - , greedyUnbound (false) - #ifdef ENABLE_UNWIND_GLUE - , maxGlue (DEFAULT_MAX_GLUE) - #endif //ENABLE_UNWIND_GLUE - , fixRestartType (auto_restart) - , origSeed(0) -{ -} diff --git a/src/prop/cryptominisat/Solver/SolverConf.h b/src/prop/cryptominisat/Solver/SolverConf.h deleted file mode 100644 index 0edaf3745..000000000 --- a/src/prop/cryptominisat/Solver/SolverConf.h +++ /dev/null @@ -1,102 +0,0 @@ -/***************************************************************************** -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 SOLVERCONF_H -#define SOLVERCONF_H - -#include "SolverTypes.h" -#include "constants.h" - -namespace CMSat { - -class SolverConf -{ - public: - SolverConf(); - - double random_var_freq; ///<The frequency with which the decision heuristic tries to choose a random variable. (default 0.02) NOTE: This is really strange. If the number of variables set is large, then the random chance is in fact _far_ lower than this value. This is because the algorithm tries to set one variable randomly, but if that variable is already set, then it _silently_ fails, and moves on (doing non-random flip)! - double clause_decay; ///<Inverse of the clause activity decay factor. Only applies if using MiniSat-style clause activities (default: 1 / 0.999) - int restart_first; ///<The initial restart limit. (default 100) - double restart_inc; ///<The factor with which the restart limit is multiplied in each restart. (default 1.5) - double learntsize_factor; ///<The intitial limit for learnt clauses is a factor of the original clauses. (default 1 / 3) - double learntsize_inc; ///<The limit for learnt clauses is multiplied with this factor each restart. (default 1.1) - bool expensive_ccmin; ///<Should clause minimisation by Sorensson&Biere be used? (default TRUE) - int polarity_mode; ///<Controls which polarity the decision heuristic chooses. Auto means Jeroslow-Wang (default: polarity_auto) - int verbosity; ///<Verbosity level. 0=silent, 1=some progress report, 2=lots of report, 3 = all report (default 2) - Var restrictPickBranch; ///<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]) - uint32_t simpBurstSConf; - double simpStartMult; - double simpStartMMult; - bool doPerformPreSimp; - double failedLitMultiplier; - - //Optimisations to do - bool doFindXors; ///<Automatically find non-binary xor clauses and convert them to xor clauses - bool doFindEqLits; ///<Automatically find binary xor clauses (i.e. variable equi- and antivalences) - bool doRegFindEqLits; ///<Regularly find binary xor clauses (i.e. variable equi- and antivalences) - bool doReplace; ///<Should var-replacing be performed? If set to FALSE, equi- and antivalent variables will not be replaced with one another. NOTE: This precludes using a lot of the algorithms! - bool doConglXors; ///<Do variable elimination at the XOR-level (xor-ing 2 xor clauses thereby removing a variable) - bool doHeuleProcess; ///<Perform local subsitutuion as per Heule's theis - bool doSchedSimp; ///<Should simplifyProblem() be scheduled regularly? (if set to FALSE, a lot of opmitisations are disabled) - bool doSatELite; ///<Should try to subsume & self-subsuming resolve & variable-eliminate & block-clause eliminate? - bool doXorSubsumption; ///<Should try to subsume & local-subsitute xor clauses - bool doHyperBinRes; ///<Should try carry out hyper-binary resolution - bool doBlockedClause; ///<Should try to remove blocked clauses - bool doVarElim; ///<Perform variable elimination - bool doSubsume1; ///<Perform self-subsuming resolution - bool doClausVivif; ///<Perform asymmetric branching at the beginning of the solving - bool doSortWatched; ///<Sort watchlists according to size&type: binary, tertiary, normal (>3-long), xor clauses - bool doMinimLearntMore; ///<Perform learnt-clause minimisation using watchists' binary and tertiary clauses? ("strong minimization" in PrecoSat) - bool doMinimLMoreRecur; ///<Always perform recursive/transitive on-the-fly self self-subsuming resolution --> an enhancement of "strong minimization" of PrecoSat - bool doFailedLit; ///<Carry out Failed literal probing + doubly propagated literal detection + 2-long xor clause detection during failed literal probing + hyper-binary resoolution - bool doRemUselessBins; ///<Should try to remove useless binary clauses at the beginning of solving? - bool doSubsWBins; - bool doSubsWNonExistBins; ///<Try to do subsumption and self-subsuming resolution with non-existent binary clauses (i.e. binary clauses that don't exist but COULD exists) - bool doRemUselessLBins; ///<Try to remove useless learnt binary clauses - #ifdef ENABLE_UNWIND_GLUE - bool doMaxGlueDel; - #endif //ENABLE_UNWIND_GLUE - bool doPrintAvgBranch; - bool doCacheOTFSSR; - bool doCacheOTFSSRSet; - bool doExtendedSCC; - bool doCalcReach; ///<Calculate reachability, and influence variable decisions with that - bool doBXor; - bool doOTFSubsume; ///On-the-fly subsumption - uint64_t maxConfl; - bool isPlain; ///<We are in 'plain' mode: glues can never be 1 - - //interrupting & dumping - uint32_t maxRestarts; - bool needToDumpLearnts; ///<If set to TRUE, learnt clauses will be dumped to the file speified by "learntsFilename" - bool needToDumpOrig; ///<If set to TRUE, a simplified version of the original clause-set will be dumped to the file speified by "origFilename". The solution to this file should perfectly satisfy the problem - std::string learntsFilename; ///<Dump sorted learnt clauses to this file. Only active if "needToDumpLearnts" is set to TRUE - std::string origFilename; ///<Dump simplified original problem CNF to this file. Only active if "needToDumpOrig" is set to TRUE - uint32_t maxDumpLearntsSize; ///<When dumping the learnt clauses, this is the maximum clause size that should be dumped - bool libraryUsage; ///<Set to true if not used as a library. In fact, this is TRUE by default, and Main.cpp sets it to "FALSE". Disables some simplifications at the beginning of solving (mostly performStepsBeforeSolve() ) - bool greedyUnbound; ///<If set, then variables will be greedily unbounded (set to l_Undef). This is EXPERIMENTAL - #ifdef ENABLE_UNWIND_GLUE - uint32_t maxGlue; ///< Learnt clauses (when doing dynamic restarts) with glue above this value will be removed immediately on backtracking - #endif //ENABLE_UNWIND_GLUE - RestartType fixRestartType; ///<If set, the solver will always choose the given restart strategy instead of automatically trying to guess a strategy. Note that even if set to dynamic_restart, there will be a few restarts made statically after each full restart. - - uint32_t origSeed; -}; - -} - -#endif //SOLVERCONF_H diff --git a/src/prop/cryptominisat/Solver/SolverDebug.cpp b/src/prop/cryptominisat/Solver/SolverDebug.cpp deleted file mode 100644 index a831a2779..000000000 --- a/src/prop/cryptominisat/Solver/SolverDebug.cpp +++ /dev/null @@ -1,253 +0,0 @@ -/*************************************************************************** -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 "Solver.h" -#include "VarReplacer.h" - -using namespace CMSat; - -#ifdef DEBUG_ATTACH_FULL -void Solver::testAllClauseAttach() const -{ - for (Clause *const*it = clauses.getData(), *const*end = clauses.getDataEnd(); it != end; it++) { - const Clause& c = **it; - assert(normClauseIsAttached(c)); - } - - for (XorClause *const*it = xorclauses.getData(), *const*end = xorclauses.getDataEnd(); it != end; it++) { - const XorClause& c = **it; - assert(xorClauseIsAttached(c)); - } -} - -bool Solver::normClauseIsAttached(const Clause& c) const -{ - bool attached = true; - assert(c.size() > 2); - - ClauseOffset offset = clauseAllocator.getOffset(&c); - if (c.size() == 3) { - //The clause might have been longer, and has only recently - //became 3-long. Check, and detach accordingly - if (findWCl(watches[(~c[0]).toInt()], offset)) goto fullClause; - - Lit lit1 = c[0]; - Lit lit2 = c[1]; - Lit lit3 = c[2]; - attached &= findWTri(watches[(~lit1).toInt()], lit2, lit3); - attached &= findWTri(watches[(~lit2).toInt()], lit1, lit3); - attached &= findWTri(watches[(~lit3).toInt()], lit1, lit2); - } else { - fullClause: - attached &= findWCl(watches[(~c[0]).toInt()], offset); - attached &= findWCl(watches[(~c[1]).toInt()], offset); - } - - return attached; -} - -bool Solver::xorClauseIsAttached(const XorClause& c) const -{ - ClauseOffset offset = clauseAllocator.getOffset(&c); - bool attached = true; - attached &= findWXCl(watches[(c[0]).toInt()], offset); - attached &= findWXCl(watches[(~c[0]).toInt()], offset); - attached &= findWXCl(watches[(c[1]).toInt()], offset); - attached &= findWXCl(watches[(~c[1]).toInt()], offset); - - return attached; -} - -void Solver::findAllAttach() const -{ - for (uint32_t i = 0; i < watches.size(); i++) { - for (uint32_t i2 = 0; i2 < watches[i].size(); i2++) { - const Watched& w = watches[i][i2]; - if (w.isClause()) findClause(clauseAllocator.getPointer(w.getNormOffset())); - if (w.isXorClause()) findClause(clauseAllocator.getPointer(w.getXorOffset())); - } - } -} - -bool Solver::findClause(XorClause* c) const -{ - for (uint32_t i = 0; i < xorclauses.size(); i++) { - if (xorclauses[i] == c) return true; - } - return false; -} - -bool Solver::findClause(Clause* c) const -{ - for (uint32_t i = 0; i < clauses.size(); i++) { - if (clauses[i] == c) return true; - } - for (uint32_t i = 0; i < learnts.size(); i++) { - if (learnts[i] == c) return true; - } - - return false; -} -#endif //DEBUG_ATTACH_FULL - -void Solver::checkSolution() -{ - model.growTo(nVars()); - for (Var var = 0; var != nVars(); var++) model[var] = value(var); - release_assert(verifyModel()); - model.clear(); -} - -bool Solver::verifyXorClauses() const -{ - #ifdef VERBOSE_DEBUG - cout << "Checking xor-clauses whether they have been properly satisfied." << endl;; - #endif - - bool verificationOK = true; - - for (uint32_t i = 0; i != xorclauses.size(); i++) { - XorClause& c = *xorclauses[i]; - bool final = c.xorEqualFalse(); - - #ifdef VERBOSE_DEBUG - std::cout << "verifying xor clause: " << c << std::endl; - #endif - - for (uint32_t j = 0; j < c.size(); j++) { - assert(modelValue(c[j].unsign()) != l_Undef); - final ^= (modelValue(c[j].unsign()) == l_True); - } - if (!final) { - printf("unsatisfied clause: "); - xorclauses[i]->plainPrint(); - verificationOK = false; - } - } - - return verificationOK; -} - -bool Solver::verifyBinClauses() const -{ - uint32_t wsLit = 0; - for (const vec<Watched> *it = watches.getData(), *end = watches.getDataEnd(); it != end; it++, wsLit++) { - Lit lit = ~Lit::toLit(wsLit); - const vec<Watched>& ws = *it; - - for (vec<Watched>::const_iterator i = ws.getData(), end = ws.getDataEnd() ; i != end; i++) { - if (i->isBinary() - && value(lit) != l_True - && value(i->getOtherLit()) != l_True - ) { - std::cout << "bin clause: " << lit << " , " << i->getOtherLit() << " not satisfied!" << std::endl; - std::cout << "value of unsat bin clause: " << value(lit) << " , " << value(i->getOtherLit()) << std::endl; - return false; - } - } - } - - return true; -} - -bool Solver::verifyClauses(const vec<Clause*>& cs) const -{ - #ifdef VERBOSE_DEBUG - cout << "Checking clauses whether they have been properly satisfied." << endl;; - #endif - - bool verificationOK = true; - - for (uint32_t i = 0; i != cs.size(); i++) { - Clause& c = *cs[i]; - for (uint32_t j = 0; j < c.size(); j++) - if (modelValue(c[j]) == l_True) - goto next; - - printf("unsatisfied clause: "); - cs[i]->plainPrint(); - verificationOK = false; - next: - ; - } - - return verificationOK; -} - -bool Solver::verifyModel() const -{ - bool verificationOK = true; - verificationOK &= verifyClauses(clauses); - verificationOK &= verifyClauses(learnts); - verificationOK &= verifyBinClauses(); - verificationOK &= verifyXorClauses(); - - if (conf.verbosity >=1 && verificationOK) - printf("c Verified %d clauses.\n", clauses.size() + xorclauses.size()); - - return verificationOK; -} - - -void Solver::checkLiteralCount() -{ - // Check that sizes are calculated correctly: - int cnt = 0; - for (uint32_t i = 0; i != clauses.size(); i++) - cnt += clauses[i]->size(); - - for (uint32_t i = 0; i != xorclauses.size(); i++) - cnt += xorclauses[i]->size(); - - if ((int)clauses_literals != cnt) { - fprintf(stderr, "literal count: %d, real value = %d\n", (int)clauses_literals, cnt); - assert((int)clauses_literals == cnt); - } -} - -void Solver::printAllClauses() -{ - for (uint32_t i = 0; i < clauses.size(); i++) { - std::cout << "Normal clause num " << clauseAllocator.getOffset(clauses[i]) << " cl: " << *clauses[i] << std::endl; - } - - for (uint32_t i = 0; i < xorclauses.size(); i++) { - std::cout << "xorclause num " << *xorclauses[i] << std::endl; - } - - uint32_t wsLit = 0; - for (vec<Watched> *it = watches.getData(), *end = watches.getDataEnd(); it != end; it++, wsLit++) { - Lit lit = ~Lit::toLit(wsLit); - const vec<Watched>& ws = *it; - std::cout << "watches[" << lit << "]" << std::endl; - for (vec<Watched>::const_iterator it2 = ws.getData(), end2 = ws.getDataEnd(); it2 != end2; it2++) { - if (it2->isBinary()) { - std::cout << "Binary clause part: " << lit << " , " << it2->getOtherLit() << std::endl; - } else if (it2->isClause()) { - std::cout << "Normal clause num " << it2->getNormOffset() << std::endl; - } else if (it2->isXorClause()) { - std::cout << "Xor clause num " << it2->getXorOffset() << std::endl; - } else if (it2->isTriClause()) { - std::cout << "Tri clause:" - << lit << " , " - << it2->getOtherLit() << " , " - << it2->getOtherLit2() << std::endl; - } - } - } - -} diff --git a/src/prop/cryptominisat/Solver/SolverMisc.cpp b/src/prop/cryptominisat/Solver/SolverMisc.cpp deleted file mode 100644 index c2007af2e..000000000 --- a/src/prop/cryptominisat/Solver/SolverMisc.cpp +++ /dev/null @@ -1,713 +0,0 @@ -/*************************************************************************** -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 "Solver.h" -#include "VarReplacer.h" -#include "Subsumer.h" -#include "XorSubsumer.h" -#include "time_mem.h" -#include "DimacsParser.h" -#include "FailedLitSearcher.h" -#include "DataSync.h" -#include "SCCFinder.h" -#include <iomanip> -#include <omp.h> - -#ifdef USE_GAUSS -#include "Gaussian.h" -#endif - -#ifndef _MSC_VER -#include <sys/time.h> -#include <sys/resource.h> -#endif - -using namespace CMSat; - -static const int space = 10; - -bool Solver::dumpSortedLearnts(const std::string& fileName, const uint32_t maxSize) -{ - FILE* outfile = fopen(fileName.c_str(), "w"); - if (!outfile) - return false; - - fprintf(outfile, "c \nc ---------\n"); - fprintf(outfile, "c unitaries\n"); - fprintf(outfile, "c ---------\n"); - for (uint32_t i = 0, end = (trail_lim.size() > 0) ? trail_lim[0] : trail.size() ; i < end; i++) { - trail[i].printFull(outfile); - } - - fprintf(outfile, "c conflicts %lu\n", (unsigned long)conflicts); - if (maxSize == 1) goto end; - - fprintf(outfile, "c \nc ---------------------------------\n"); - fprintf(outfile, "c learnt binary clauses (extracted from watchlists)\n"); - fprintf(outfile, "c ---------------------------------\n"); - dumpBinClauses(true, false, outfile); - - fprintf(outfile, "c \nc ---------------------------------------\n"); - fprintf(outfile, "c clauses representing 2-long XOR clauses\n"); - fprintf(outfile, "c ---------------------------------------\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); - } - } - fprintf(outfile, "c \nc --------------------\n"); - fprintf(outfile, "c clauses from learnts\n"); - fprintf(outfile, "c --------------------\n"); - if (lastSelectedRestartType == dynamic_restart) - std::sort(learnts.getData(), learnts.getData()+learnts.size(), reduceDB_ltGlucose()); - else - std::sort(learnts.getData(), learnts.getData()+learnts.size(), reduceDB_ltMiniSat()); - for (int i = learnts.size()-1; i >= 0 ; i--) { - if (learnts[i]->size() <= maxSize) { - learnts[i]->print(outfile); - } - } - - end: - - fclose(outfile); - return true; -} - -void Solver::printStrangeBinLit(const Lit lit) const -{ - const vec<Watched>& ws = watches[(~lit).toInt()]; - for (vec<Watched>::const_iterator it2 = ws.getData(), end2 = ws.getDataEnd(); it2 != end2; it2++) { - if (it2->isBinary()) { - std::cout << "bin: " << lit << " , " << it2->getOtherLit() << " learnt : " << (it2->getLearnt()) << std::endl; - } else if (it2->isTriClause()) { - std::cout << "tri: " << lit << " , " << it2->getOtherLit() << " , " << (it2->getOtherLit2()) << std::endl; - } else if (it2->isClause()) { - std::cout << "cla:" << it2->getNormOffset() << std::endl; - } else { - assert(it2->isXorClause()); - std::cout << "xor:" << it2->getXorOffset() << std::endl; - } - } -} - -uint32_t Solver::countNumBinClauses(const bool alsoLearnt, const bool alsoNonLearnt) const -{ - uint32_t num = 0; - - uint32_t wsLit = 0; - for (const vec<Watched> *it = watches.getData(), *end = watches.getDataEnd(); it != end; it++, wsLit++) { - const vec<Watched>& ws = *it; - for (vec<Watched>::const_iterator it2 = ws.getData(), end2 = ws.getDataEnd(); it2 != end2; it2++) { - if (it2->isBinary()) { - if (it2->getLearnt()) num += alsoLearnt; - else num+= alsoNonLearnt; - } - } - } - - assert(num % 2 == 0); - return num/2; -} - -void Solver::dumpBinClauses(const bool alsoLearnt, const bool alsoNonLearnt, FILE* outfile) const -{ - uint32_t wsLit = 0; - for (const vec<Watched> *it = watches.getData(), *end = watches.getDataEnd(); it != end; it++, wsLit++) { - Lit lit = ~Lit::toLit(wsLit); - const vec<Watched>& ws = *it; - for (vec<Watched>::const_iterator it2 = ws.getData(), end2 = ws.getDataEnd(); it2 != end2; it2++) { - if (it2->isBinary() && lit.toInt() < it2->getOtherLit().toInt()) { - bool toDump = false; - if (it2->getLearnt() && alsoLearnt) toDump = true; - if (!it2->getLearnt() && alsoNonLearnt) toDump = true; - - if (toDump) it2->dump(outfile, lit); - } - } - } -} - -uint32_t Solver::getBinWatchSize(const bool alsoLearnt, const Lit lit) -{ - uint32_t num = 0; - const vec<Watched>& ws = watches[lit.toInt()]; - for (vec<Watched>::const_iterator it2 = ws.getData(), end2 = ws.getDataEnd(); it2 != end2; it2++) { - if (it2->isBinary() && (alsoLearnt || !it2->getLearnt())) { - num++; - } - } - - return num; -} - -void Solver::printBinClause(const Lit litP1, const Lit litP2, FILE* outfile) const -{ - if (value(litP1) == l_True) { - litP1.printFull(outfile); - } else if (value(litP1) == l_False) { - litP2.printFull(outfile); - } else if (value(litP2) == l_True) { - litP2.printFull(outfile); - } else if (value(litP2) == l_False) { - litP1.printFull(outfile); - } else { - litP1.print(outfile); - litP2.printFull(outfile); - } -} - -bool Solver::dumpOrigClauses(const std::string& fileName) const -{ - FILE* outfile; - if (fileName != std::string("stdout")) { - outfile = fopen(fileName.c_str(), "w"); - if (!outfile) - return false; - } else { - outfile = stdout; - } - - uint32_t numClauses = 0; - //unitary clauses - for (uint32_t i = 0, end = (trail_lim.size() > 0) ? trail_lim[0] : trail.size() ; i < end; i++) - numClauses++; - - //binary XOR clauses - const vector<Lit>& table = varReplacer->getReplaceTable(); - for (Var var = 0; var != table.size(); var++) { - Lit lit = table[var]; - if (lit.var() == var) - continue; - numClauses += 2; - } - - //binary normal clauses - numClauses += countNumBinClauses(false, true); - - //normal clauses - numClauses += clauses.size(); - - //xor clauses - numClauses += xorclauses.size(); - - //previously eliminated clauses - const map<Var, vector<vector<Lit> > >& elimedOutVar = subsumer->getElimedOutVar(); - for (map<Var, vector<vector<Lit> > >::const_iterator it = elimedOutVar.begin(); it != elimedOutVar.end(); it++) { - const vector<vector<Lit> >& cs = it->second; - numClauses += cs.size(); - } - const map<Var, vector<std::pair<Lit, Lit> > >& elimedOutVarBin = subsumer->getElimedOutVarBin(); - for (map<Var, vector<std::pair<Lit, Lit> > >::const_iterator it = elimedOutVarBin.begin(); it != elimedOutVarBin.end(); it++) { - numClauses += it->second.size(); - } - - const map<Var, vector<XorSubsumer::XorElimedClause> >& xorElimedOutVar = xorSubsumer->getElimedOutVar(); - for (map<Var, vector<XorSubsumer::XorElimedClause> >::const_iterator it = xorElimedOutVar.begin(); it != xorElimedOutVar.end(); it++) { - const vector<XorSubsumer::XorElimedClause>& cs = it->second; - numClauses += cs.size(); - } - - fprintf(outfile, "p cnf %d %d\n", nVars(), numClauses); - - //////////////////////////////////////////////////////////////////// - - fprintf(outfile, "c \nc ---------\n"); - fprintf(outfile, "c unitaries\n"); - fprintf(outfile, "c ---------\n"); - for (uint32_t i = 0, end = (trail_lim.size() > 0) ? trail_lim[0] : trail.size() ; i < end; i++) { - trail[i].printFull(outfile); - } - - fprintf(outfile, "c \nc ---------------------------------------\n"); - fprintf(outfile, "c clauses representing 2-long XOR clauses\n"); - fprintf(outfile, "c ---------------------------------------\n"); - for (Var var = 0; var != table.size(); var++) { - Lit lit = table[var]; - if (lit.var() == var) - continue; - - Lit litP1 = ~lit; - Lit litP2 = Lit(var, false); - printBinClause(litP1, litP2, outfile); - printBinClause(~litP1, ~litP2, outfile); - } - - fprintf(outfile, "c \nc ------------\n"); - fprintf(outfile, "c binary clauses\n"); - fprintf(outfile, "c ---------------\n"); - dumpBinClauses(false, true, outfile); - - fprintf(outfile, "c \nc ------------\n"); - fprintf(outfile, "c normal clauses\n"); - fprintf(outfile, "c ---------------\n"); - for (Clause *const *i = clauses.getData(); i != clauses.getDataEnd(); i++) { - assert(!(*i)->learnt()); - (*i)->print(outfile); - } - - fprintf(outfile, "c \nc ------------\n"); - fprintf(outfile, "c xor clauses\n"); - fprintf(outfile, "c ---------------\n"); - for (XorClause *const *i = xorclauses.getData(); i != xorclauses.getDataEnd(); i++) { - assert(!(*i)->learnt()); - (*i)->print(outfile); - } - - fprintf(outfile, "c -------------------------------\n"); - fprintf(outfile, "c previously eliminated variables\n"); - fprintf(outfile, "c -------------------------------\n"); - for (map<Var, vector<vector<Lit> > >::const_iterator it = elimedOutVar.begin(); it != elimedOutVar.end(); it++) { - fprintf(outfile, "c ########### cls for eliminated var %d ### start\n", it->first + 1); - const vector<vector<Lit> >& cs = it->second; - for (vector<vector<Lit> >::const_iterator it2 = cs.begin(); it2 != cs.end(); it2++) { - printClause(outfile, *it2); - } - fprintf(outfile, "c ########### cls for eliminated var %d ### finish\n", it->first + 1); - } - for (map<Var, vector<std::pair<Lit, Lit> > >::const_iterator it = elimedOutVarBin.begin(); it != elimedOutVarBin.end(); it++) { - for (uint32_t i = 0; i < it->second.size(); i++) { - it->second[i].first.print(outfile); - it->second[i].second.printFull(outfile); - } - } - - fprintf(outfile, "c -------------------------------\n"); - fprintf(outfile, "c previously xor-eliminated variables\n"); - fprintf(outfile, "c -------------------------------\n"); - for (map<Var, vector<XorSubsumer::XorElimedClause> >::const_iterator it = xorElimedOutVar.begin(); it != xorElimedOutVar.end(); it++) { - for (vector<XorSubsumer::XorElimedClause>::const_iterator it2 = it->second.begin(), end2 = it->second.end(); it2 != end2; it2++) { - it2->plainPrint(outfile); - } - } - - if (fileName != "stdout") fclose(outfile); - return true; -} - -vector<Lit> Solver::get_unitary_learnts() const -{ - vector<Lit> unitaries; - if (decisionLevel() > 0) { - for (uint32_t i = 0; i != trail_lim[0]; i++) { - unitaries.push_back(trail[i]); - } - } - - return unitaries; -} - -const vec<Clause*>& Solver::get_learnts() const -{ - return learnts; -} - -const vec<Clause*>& Solver::get_sorted_learnts() -{ - if (lastSelectedRestartType == dynamic_restart) - std::sort(learnts.getData(), learnts.getData()+learnts.size(), reduceDB_ltGlucose()); - else - std::sort(learnts.getData(), learnts.getData()+learnts.size(), reduceDB_ltMiniSat()); - return learnts; -} - -uint32_t Solver::getNumElimSubsume() const -{ - return subsumer->getNumElimed(); -} - -uint32_t Solver::getNumElimXorSubsume() const -{ - return xorSubsumer->getNumElimed(); -} - -uint32_t Solver::getNumXorTrees() const -{ - return varReplacer->getNumTrees(); -} - -uint32_t Solver::getNumXorTreesCrownSize() const -{ - return varReplacer->getNumReplacedVars(); -} - -double Solver::getTotalTimeSubsumer() const -{ - return subsumer->getTotalTime(); -} - -double Solver::getTotalTimeFailedLitSearcher() const -{ - return failedLitSearcher->getTotalTime(); -} - -double Solver::getTotalTimeXorSubsumer() const -{ - return xorSubsumer->getTotalTime(); -} - -double Solver::getTotalTimeSCC() const -{ - return sCCFinder->getTotalTime(); -} - -void Solver::printStatHeader() const -{ - if (conf.verbosity >= 2) { - std::cout << "c " - << "=========================================================================================" - << std::endl; - std::cout << "c" - << " types(t): F = full restart, N = normal restart" << std::endl; - std::cout << "c" - << " types(t): S = simplification begin/end, E = solution found" << std::endl; - std::cout << "c" - << " restart types(rt): st = static, dy = dynamic" << std::endl; - - std::cout << "c " - << std::setw(2) << "t" - << std::setw(3) << "rt" - << std::setw(6) << "Rest" - << std::setw(space) << "Confl" - << std::setw(space) << "Vars" - << std::setw(space) << "NormCls" - << std::setw(space) << "XorCls" - << std::setw(space) << "BinCls" - << std::setw(space) << "Learnts" - << std::setw(space) << "ClLits" - << std::setw(space) << "LtLits" - << std::setw(space) << "LGlueHist" - << std::setw(space) << "SGlueHist" - << std::endl; - } -} - -void Solver::printRestartStat(const char* type) -{ - if (conf.verbosity >= 2) { - //printf("c | %9d | %7d %8d %8d | %8d %8d %6.0f |", (int)conflicts, (int)order_heap.size(), (int)(nClauses()-nbBin), (int)clauses_literals, (int)(nbclausesbeforereduce*curRestart+nbCompensateSubsumer), (int)(nLearnts()+nbBin), (double)learnts_literals/(double)(nLearnts()+nbBin)); - - std::cout << "c " - << std::setw(2) << type - << std::setw(3) << ((restartType == static_restart) ? "st" : "dy") - << std::setw(6) << starts - << std::setw(space) << conflicts - << std::setw(space) << order_heap.size() - << std::setw(space) << clauses.size() - << std::setw(space) << xorclauses.size() - << std::setw(space) << numBins - << std::setw(space) << learnts.size() - << std::setw(space) << clauses_literals - << std::setw(space) << learnts_literals; - - if (glueHistory.getTotalNumeElems() > 0) { - std::cout << std::setw(space) << std::fixed << std::setprecision(2) << glueHistory.getAvgAllDouble(); - } else { - std::cout << std::setw(space) << "no data"; - } - if (glueHistory.isvalid()) { - std::cout << std::setw(space) << std::fixed << std::setprecision(2) << glueHistory.getAvgDouble(); - } else { - std::cout << std::setw(space) << "no data"; - } - - #ifdef RANDOM_LOOKAROUND_SEARCHSPACE - if (conf.doPrintAvgBranch) { - if (avgBranchDepth.isvalid()) - std::cout << std::setw(space) << avgBranchDepth.getAvgUInt(); - else - std::cout << std::setw(space) << "no data"; - } - #endif //RANDOM_LOOKAROUND_SEARCHSPACE - - #ifdef USE_GAUSS - print_gauss_sum_stats(); - #endif //USE_GAUSS - - std::cout << std::endl; - } -} - -void Solver::printEndSearchStat() -{ - if (conf.verbosity >= 1) { - printRestartStat("E"); - } -} - -#ifdef USE_GAUSS -void Solver::print_gauss_sum_stats() -{ - if (gauss_matrixes.size() == 0 && conf.verbosity >= 2) { - std::cout << " --"; - return; - } - - uint32_t called = 0; - uint32_t useful_prop = 0; - uint32_t useful_confl = 0; - uint32_t disabled = 0; - 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(); - useful_confl += (*gauss)->get_useful_confl(); - sum_gauss_unit_truths += (*gauss)->get_unit_truths(); - //gauss->print_stats(); - //gauss->print_matrix_stats(); - } - sum_gauss_called += called; - sum_gauss_confl += useful_confl; - sum_gauss_prop += useful_prop; - - if (conf.verbosity >= 2) { - if (called == 0) { - std::cout << " --"; - } else { - std::cout << " " - << std::fixed << std::setprecision(1) << std::setw(5) - << ((double)useful_prop/(double)called*100.0) << "% " - << std::fixed << std::setprecision(1) << std::setw(5) - << ((double)useful_confl/(double)called*100.0) << "% " - << std::fixed << std::setprecision(1) << std::setw(5) - << (100.0-(double)disabled/(double)gauss_matrixes.size()*100.0) << "%"; - } - } -} -#endif //USE_GAUSS - -/** -@brief Sorts the watchlists' clauses as: binary, tertiary, normal, xor -*/ -void Solver::sortWatched() -{ - #ifdef VERBOSE_DEBUG - std::cout << "Sorting watchlists:" << std::endl; - #endif - double myTime = cpuTime(); - for (vec<Watched> *i = watches.getData(), *end = watches.getDataEnd(); i != end; i++) { - if (i->size() == 0) continue; - #ifdef VERBOSE_DEBUG - vec<Watched>& ws = *i; - std::cout << "Before sorting:" << std::endl; - for (uint32_t i2 = 0; i2 < ws.size(); i2++) { - if (ws[i2].isBinary()) std::cout << "Binary,"; - if (ws[i2].isTriClause()) std::cout << "Tri,"; - if (ws[i2].isClause()) std::cout << "Normal,"; - if (ws[i2].isXorClause()) std::cout << "Xor,"; - } - std::cout << std::endl; - #endif //VERBOSE_DEBUG - - std::sort(i->getData(), i->getDataEnd(), WatchedSorter()); - - #ifdef VERBOSE_DEBUG - std::cout << "After sorting:" << std::endl; - for (uint32_t i2 = 0; i2 < ws.size(); i2++) { - if (ws[i2].isBinary()) std::cout << "Binary,"; - if (ws[i2].isTriClause()) std::cout << "Tri,"; - if (ws[i2].isClause()) std::cout << "Normal,"; - if (ws[i2].isXorClause()) std::cout << "Xor,"; - } - std::cout << std::endl; - #endif //VERBOSE_DEBUG - } - - if (conf.verbosity >= 3) { - std::cout << "c watched " - << "sorting time: " << cpuTime() - myTime - << std::endl; - } -} - -void Solver::addSymmBreakClauses() -{ - if (xorclauses.size() > 0) { - std::cout << "c xor clauses present -> no saucy" << std::endl; - return; - } - double myTime = cpuTime(); - std::cout << "c Doing saucy" << std::endl; - dumpOrigClauses("origProblem.cnf"); - - int rvalue; - rvalue= system("grep -v \"^c\" origProblem.cnf > origProblem2.cnf"); - if (rvalue >= 2) { // unsuccessful grep in POSIX standard - std::cout << "c impossible to complete saucy" << std::endl; - return; - } - rvalue= system("python saucyReader.py origProblem2.cnf > output"); - if (rvalue != 0) { // unsuccessful saucyReader.py - std::cout << "c impossible to complete saucy" << std::endl; - return; - } - - - DimacsParser parser(this, false, false, false, true); - - #ifdef DISABLE_ZLIB - FILE * in = fopen("output", "rb"); - #else - gzFile in = gzopen("output", "rb"); - #endif // DISABLE_ZLIB - parser.parse_DIMACS(in); - #ifdef DISABLE_ZLIB - fclose(in); - #else - gzclose(in); - #endif // DISABLE_ZLIB - std::cout << "c Finished saucy, time: " << (cpuTime() - myTime) << std::endl; -} - -/** -@brief Pretty-prints a literal -*/ -void Solver::printLit(const Lit l) const -{ - printf("%s%d:%c", l.sign() ? "-" : "", l.var()+1, value(l) == l_True ? '1' : (value(l) == l_False ? '0' : 'X')); -} - -/** -@brief Sets that we need a CNF file that documents all commands - -newVar() and addClause(), addXorClause() commands are logged to this CNF -file and then can be re-read with special arguments to the main program. This -can help simulate a segfaulting library-call -*/ -bool Solver::needLibraryCNFFile(const std::string& fileName) -{ - libraryCNFFile = fopen(fileName.c_str(), "w"); - return libraryCNFFile != NULL; -} - -template<class T, class T2> -void Solver::printStatsLine(std::string left, T value, T2 value2, std::string extra) -{ - std::cout << std::fixed << std::left << std::setw(27) << left << ": " << std::setw(11) << std::setprecision(2) << value << " (" << std::left << std::setw(9) << std::setprecision(2) << value2 << " " << extra << ")" << std::endl; -} - -template<class T> -void Solver::printStatsLine(std::string left, T value, std::string extra) -{ - std::cout << std::fixed << std::left << std::setw(27) << left << ": " << std::setw(11) << std::setprecision(2) << value << extra << std::endl; -} - -/** -@brief prints the statistics line at the end of solving - -Prints all sorts of statistics, like number of restarts, time spent in -SatELite-type simplification, number of unit claues found, etc. -*/ -void Solver::printStats() -{ - double cpu_time = cpuTime(); - uint64_t mem_used = memUsed(); - - int numThreads = omp_get_num_threads(); - if (numThreads > 1) { - std::cout << "c Following stats are for *FIRST FINISHED THREAD ONLY*" << std::endl; - #if !defined(_MSC_VER) && !defined(RUSAGE_THREAD) - std::cout << "c There is no platform-independent way to measure time per thread" << std::endl; - std::cout << "c All times indicated are sum of ALL threads" << std::endl; - std::cout << "c Use a utilty provided by your platform to get total thread time, etc." << std::endl; - #endif - } - printStatsLine("c num threads" , numThreads); - - //Restarts stats - printStatsLine("c restarts", starts); - printStatsLine("c dynamic restarts", dynStarts); - printStatsLine("c static restarts", staticStarts); - printStatsLine("c full restarts", fullStarts); - printStatsLine("c total simplify time", totalSimplifyTime); - - //Learnts stats - printStatsLine("c learnts DL2", nbGlue2); - printStatsLine("c learnts size 2", numNewBin); - printStatsLine("c learnts size 1", get_unitary_learnts_num(), (double)get_unitary_learnts_num()/(double)nVars()*100.0, "% of vars"); - printStatsLine("c filedLit time", getTotalTimeFailedLitSearcher(), getTotalTimeFailedLitSearcher()/cpu_time*100.0, "% time"); - - //Subsumer stats - printStatsLine("c v-elim SatELite", getNumElimSubsume(), (double)getNumElimSubsume()/(double)nVars()*100.0, "% vars"); - printStatsLine("c SatELite time", getTotalTimeSubsumer(), getTotalTimeSubsumer()/cpu_time*100.0, "% time"); - - //XorSubsumer stats - printStatsLine("c v-elim xor", getNumElimXorSubsume(), (double)getNumElimXorSubsume()/(double)nVars()*100.0, "% vars"); - printStatsLine("c xor elim time", getTotalTimeXorSubsumer(), getTotalTimeXorSubsumer()/cpu_time*100.0, "% time"); - - //VarReplacer stats - printStatsLine("c num binary xor trees", getNumXorTrees()); - printStatsLine("c binxor trees' crown", getNumXorTreesCrownSize(), (double)getNumXorTreesCrownSize()/(double)getNumXorTrees(), "leafs/tree"); - printStatsLine("c bin xor find time", getTotalTimeSCC()); - - //OTF clause improvement stats - printStatsLine("c OTF clause improved", improvedClauseNo, (double)improvedClauseNo/(double)conflicts, "clauses/conflict"); - printStatsLine("c OTF impr. size diff", improvedClauseSize, (double)improvedClauseSize/(double)improvedClauseNo, " lits/clause"); - - //Clause-shrinking through watchlists - printStatsLine("c OTF cl watch-shrink", numShrinkedClause, (double)numShrinkedClause/(double)conflicts, "clauses/conflict"); - printStatsLine("c OTF cl watch-sh-lit", numShrinkedClauseLits, (double)numShrinkedClauseLits/(double)numShrinkedClause, " lits/clause"); - printStatsLine("c tried to recurMin cls", moreRecurMinLDo, (double)moreRecurMinLDo/(double)conflicts*100.0, " % of conflicts"); - printStatsLine("c updated cache", updateTransCache, updateTransCache/(double)moreRecurMinLDo, " lits/tried recurMin"); - - //Multi-threading - if (numThreads > 1) { - printStatsLine("c unit cls received", dataSync->getRecvUnitData(), (double)dataSync->getRecvUnitData()/(double)get_unitary_learnts_num()*100.0, "% of units"); - printStatsLine("c unit cls sent", dataSync->getSentUnitData(), (double)dataSync->getSentUnitData()/(double)get_unitary_learnts_num()*100.0, "% of units"); - printStatsLine("c bin cls received", dataSync->getRecvBinData()); - printStatsLine("c bin cls sent", dataSync->getSentBinData()); - } - - #ifdef USE_GAUSS - if (gaussconfig.decision_until > 0) { - std::cout << "c " << std::endl; - printStatsLine("c gauss unit truths ", get_sum_gauss_unit_truths()); - printStatsLine("c gauss called", get_sum_gauss_called()); - printStatsLine("c gauss conflicts ", get_sum_gauss_confl(), (double)get_sum_gauss_confl() / (double)get_sum_gauss_called() * 100.0, " %"); - printStatsLine("c gauss propagations ", get_sum_gauss_prop(), (double)get_sum_gauss_prop() / (double)get_sum_gauss_called() * 100.0, " %"); - printStatsLine("c gauss useful", ((double)get_sum_gauss_prop() + (double)get_sum_gauss_confl())/ (double)get_sum_gauss_called() * 100.0, " %"); - std::cout << "c " << std::endl; - } - #endif - - printStatsLine("c clauses over max glue", nbClOverMaxGlue, (double)nbClOverMaxGlue/(double)conflicts*100.0, "% of all clauses"); - - //Search stats - printStatsLine("c conflicts", conflicts, (double)conflicts/cpu_time, "/ sec"); - printStatsLine("c decisions", decisions, (double)rnd_decisions*100.0/(double)decisions, "% random"); - printStatsLine("c bogo-props", propagations, (double)propagations/cpu_time, "/ sec"); - printStatsLine("c conflict literals", tot_literals, (double)(max_literals - tot_literals)*100.0/ (double)max_literals, "% deleted"); - - //General stats - printStatsLine("c Memory used", (double)mem_used / 1048576.0, " MB"); - if (numThreads > 1) { - #if !defined(_MSC_VER) && defined(RUSAGE_THREAD) - printStatsLine("c single-thread CPU time", cpu_time, " s"); - printStatsLine("c all-threads sum CPU time", cpuTimeTotal(), " s"); - #else - printStatsLine("c all-threads sum CPU time", cpu_time, " s"); - #endif - } else { - printStatsLine("c CPU time", cpu_time, " s"); - } -} diff --git a/src/prop/cryptominisat/Solver/SolverTypes.h b/src/prop/cryptominisat/Solver/SolverTypes.h deleted file mode 100644 index 4228ba06a..000000000 --- a/src/prop/cryptominisat/Solver/SolverTypes.h +++ /dev/null @@ -1,244 +0,0 @@ -/***************************************************************************** -MiniSat -- Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson -glucose -- Gilles Audemard, Laurent Simon (2008) -CryptoMiniSat -- Copyright (c) 2009 Mate Soos - -Original code by MiniSat and glucose authors are under an MIT licence. -Modifications for CryptoMiniSat are under GPLv3 licence. -******************************************************************************/ - -#ifndef __SOLVERTYPES_H__ -#define __SOLVERTYPES_H__ - -#include <cassert> -#include <iostream> -#include <Vec.h> -#ifdef _MSC_VER -#include <msvc/stdint.h> -#else -#include <stdint.h> -#endif //_MSC_VER - -#include <stdio.h> -#include <vector> -#include "constants.h" - -//********************************** -// Variables, literals, lifted booleans, clauses: -//********************************** - -// NOTE! Variables are just integers. No abstraction here. They should be chosen from 0..N, -// so that they can be used as array indices. - -namespace CMSat { - -typedef uint32_t Var; -static const uint32_t var_Undef = 0xffffffffU >>1; -enum RestartType {dynamic_restart, static_restart, auto_restart}; - -/** -@brief A Literal, i.e. a variable with a sign -*/ -class Lit -{ - uint32_t x; - explicit Lit(uint32_t i) : x(i) { }; -public: - Lit() : x(2*var_Undef) {} // (lit_Undef) - explicit Lit(Var var, bool sign) : x((var+var) + (int)sign) { } - - const uint32_t& toInt() const { // Guarantees small, positive integers suitable for array indexing. - return x; - } - Lit operator~() const { - return Lit(x ^ 1); - } - Lit operator^(const bool b) const { - return Lit(x ^ (uint32_t)b); - } - Lit& operator^=(const bool b) { - x ^= (uint32_t)b; - return *this; - } - bool sign() const { - return x & 1; - } - Var var() const { - return x >> 1; - } - Lit unsign() const { - return Lit(x & ~1); - } - bool operator==(const Lit& p) const { - return x == p.x; - } - bool operator!= (const Lit& p) const { - return x != p.x; - } - /** - @brief ONLY to be used for ordering such as: a, b, ~b, etc. - */ - bool operator < (const Lit& p) const { - return x < p.x; // '<' guarantees that p, ~p are adjacent in the ordering. - } - inline void print(FILE* outfile = stdout) const - { - fprintf(outfile,"%s%d ", sign() ? "-" : "", var()+1); - } - inline void printFull(FILE* outfile = stdout) const - { - fprintf(outfile,"%s%d 0\n", sign() ? "-" : "", var()+1); - } - static Lit toLit(uint32_t data) - { - return Lit(data); - } -}; - -static const Lit lit_Undef(var_Undef, false); // Useful special constants. -static const Lit lit_Error(var_Undef, true ); // - -inline std::ostream& operator<<(std::ostream& cout, const Lit& lit) -{ - cout << (lit.sign() ? "-" : "") << (lit.var() + 1); - return cout; -} - -inline std::ostream& operator<<(std::ostream& cout, const vec<Lit>& lits) -{ - for (uint32_t i = 0; i < lits.size(); i++) { - cout << lits[i] << " "; - } - return cout; -} - -inline void printClause(FILE* outFile, const std::vector<Lit>& clause) -{ - for (size_t i = 0; i < clause.size(); i++) { - fprintf(outFile,"%s%d ", clause[i].sign() ? "-" : "", clause[i].var()+1); - } - fprintf(outFile, "0\n"); -} - -inline void printClause(FILE* outFile, const vec<Lit>& clause) -{ - for (uint32_t i = 0; i < clause.size(); i++) { - fprintf(outFile,"%s%d ", clause[i].sign() ? "-" : "", clause[i].var()+1); - } - fprintf(outFile, "0\n"); -} - -//********************************** -// Lifted booleans -//********************************** - -class llbool; - -class lbool -{ - char value; - explicit lbool(char v) : value(v) { } - -public: - lbool() : value(0) { }; - inline char getchar() const { - return value; - } - inline lbool(llbool b); - - inline bool isUndef() const { - return !value; - } - inline bool isDef() const { - return value; - } - inline bool getBool() const { - return value == 1; - } - inline bool operator==(lbool b) const { - return value == b.value; - } - inline bool operator!=(lbool b) const { - return value != b.value; - } - lbool operator^(const bool b) const { - return b ? lbool(-value) : lbool(value); - } - - friend lbool toLbool(const char v); - friend lbool boolToLBool(const bool b); - friend class llbool; -}; -inline lbool toLbool(const char v) -{ - return lbool(v); -} -inline lbool boolToLBool(const bool b) -{ - return lbool(2*b-1); -} - -const lbool l_True = toLbool( 1); -const lbool l_False = toLbool(-1); -const lbool l_Undef = toLbool( 0); - -inline std::ostream& operator<<(std::ostream& cout, const lbool val) -{ - if (val == l_True) cout << "l_True"; - if (val == l_False) cout << "l_False"; - if (val == l_Undef) cout << "l_Undef"; - return cout; -} - - -/** -@brief A very hackish lbool that also supports l_Nothing and l_Continue -*/ -class llbool -{ - char value; - -public: - llbool(): value(0) {}; - llbool(lbool v) : - value(v.value) {}; - llbool(char a) : - value(a) {} - - inline bool operator!=(const llbool& v) const { - return (v.value != value); - } - - inline bool operator==(const llbool& v) const { - return (v.value == value); - } - - friend class lbool; -}; -const llbool l_Nothing = toLbool(2); -const llbool l_Continue = toLbool(3); - -lbool::lbool(llbool b) : value(b.value) {} - -inline std::ostream& operator<<(std::ostream& os, const llbool val) -{ - if (val == l_True) os << "l_True"; - if (val == l_False) os << "l_False"; - if (val == l_Undef) os << "l_Undef"; - if (val == l_Nothing) os << "l_Nothing"; - if (val == l_Continue) os << "l_Continue"; - return os; -} - -enum { polarity_true = 0, polarity_false = 1, polarity_rnd = 3, polarity_auto = 4}; - -struct BinPropData { - uint32_t lev; - Lit lev1Ancestor; - bool learntLeadHere; - bool hasChildren; -}; - -} - -#endif //SOLVERTYPES_H diff --git a/src/prop/cryptominisat/Solver/StateSaver.cpp b/src/prop/cryptominisat/Solver/StateSaver.cpp deleted file mode 100644 index 379fec2c4..000000000 --- a/src/prop/cryptominisat/Solver/StateSaver.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/*********************************************************************************** -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 "StateSaver.h" - -using namespace CMSat; - -StateSaver::StateSaver(Solver& _solver) : - solver(_solver) - , backup_order_heap(Solver::VarOrderLt(solver.activity)) -{ - //Saving Solver state - backup_var_inc = solver.var_inc; - backup_activity.growTo(solver.activity.size()); - std::copy(solver.activity.getData(), solver.activity.getDataEnd(), backup_activity.getData()); - backup_order_heap = solver.order_heap; - backup_polarities = solver.polarity; - backup_restartType = solver.restartType; - backup_propagations = solver.propagations; - backup_random_var_freq = solver.conf.random_var_freq; -} - -void StateSaver::restore() -{ - //Restore Solver state - 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.restartType = backup_restartType; - solver.propagations = backup_propagations; - solver.conf.random_var_freq = backup_random_var_freq; - - //Finally, clear the order_heap from variables set/non-decisionned - solver.order_heap.filter(Solver::VarFilter(solver)); -} diff --git a/src/prop/cryptominisat/Solver/StateSaver.h b/src/prop/cryptominisat/Solver/StateSaver.h deleted file mode 100644 index 3450a2364..000000000 --- a/src/prop/cryptominisat/Solver/StateSaver.h +++ /dev/null @@ -1,44 +0,0 @@ -/*********************************************************************************** -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 STATESAVER__H -#define STATESAVER__H - -#include "Solver.h" - -namespace CMSat { - -class StateSaver -{ - public: - StateSaver(Solver& _solver); - void restore(); - - private: - Solver& solver; - Heap<Solver::VarOrderLt> backup_order_heap; - vector<char> backup_polarities; - vec<uint32_t> backup_activity; - uint32_t backup_var_inc; - RestartType backup_restartType; - double backup_random_var_freq; - uint64_t backup_propagations; -}; - -} - -#endif //STATESAVER__H diff --git a/src/prop/cryptominisat/Solver/StreamBuffer.h b/src/prop/cryptominisat/Solver/StreamBuffer.h deleted file mode 100644 index 6dc390415..000000000 --- a/src/prop/cryptominisat/Solver/StreamBuffer.h +++ /dev/null @@ -1,78 +0,0 @@ -/******************************************************************************************[Main.C] -MiniSat -- Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or -substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -**************************************************************************************************/ - -#ifndef STREAMBUFFER_H -#define STREAMBUFFER_H - -#define CHUNK_LIMIT 1048576 - -#ifndef DISABLE_ZLIB -#include <zlib.h> -#endif // DISABLE_ZLIB - -namespace CMSat -{ - -class StreamBuffer -{ - #ifdef DISABLE_ZLIB - FILE * in; - #else - gzFile in; - #endif // DISABLE_ZLIB - char buf[CHUNK_LIMIT]; - int pos; - int size; - - void assureLookahead() { - if (pos >= size) { - pos = 0; - #ifdef DISABLE_ZLIB - #ifdef VERBOSE_DEBUG - printf("buf = %08X\n", buf); - printf("sizeof(buf) = %u\n", sizeof(buf)); - #endif //VERBOSE_DEBUG - size = fread(buf, 1, sizeof(buf), in); - #else - size = gzread(in, buf, sizeof(buf)); - #endif // DISABLE_ZLIB - } - } - -public: - #ifdef DISABLE_ZLIB - StreamBuffer(FILE * i) : in(i), pos(0), size(0) { - #else - StreamBuffer(gzFile i) : in(i), pos(0), size(0) { - #endif // DISABLE_ZLIB - assureLookahead(); - } - - int operator * () { - return (pos >= size) ? EOF : buf[pos]; - } - void operator ++ () { - pos++; - assureLookahead(); - } -}; - -} - -#endif //STREAMBUFFER_H diff --git a/src/prop/cryptominisat/Solver/Subsumer.cpp b/src/prop/cryptominisat/Solver/Subsumer.cpp deleted file mode 100644 index 4b7eb4b2d..000000000 --- a/src/prop/cryptominisat/Solver/Subsumer.cpp +++ /dev/null @@ -1,2141 +0,0 @@ -/***************************************************************************** -SatELite -- (C) Niklas Een, Niklas Sorensson, 2004 -CryptoMiniSat -- Copyright (c) 2009 Mate Soos - -Original code by SatELite authors are under an MIT licence. -Modifications for CryptoMiniSat are under GPLv3 licence. -******************************************************************************/ - -#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 "XorFinder.h" -#include "CompleteDetachReattacher.h" -#include "OnlyNonLearntBins.h" -#include "UselessBinRemover.h" -#include "DataSync.h" -#include "constants.h" -#include "ClauseVivifier.h" - -//#define VERBOSE_DEBUG -#ifdef VERBOSE_DEBUG -#define BIT_MORE_VERBOSITY -#endif - -//#define BIT_MORE_VERBOSITY - -using namespace CMSat; - -Subsumer::Subsumer(Solver& s): - solver(s) - , totalTime(0.0) - , numElimed(0) - , numCalls(1) -{ -} - -/** -@brief Extends the model to include eliminated variables - -Adds the clauses to the parameter solver2, and then relies on the -caller to call solver2.solve(). - -@p solver2 The external solver the variables' clauses are added to -*/ -void Subsumer::extendModel(Solver& solver2) -{ - #ifdef VERBOSE_DEBUG - std::cout << "Subsumer::extendModel(Solver& solver2) called" << std::endl; - #endif - - assert(checkElimedUnassigned()); - vec<Lit> tmp; - typedef map<Var, vector<vector<Lit> > > elimType; - for (elimType::iterator it = elimedOutVar.begin(), end = elimedOutVar.end(); it != end; it++) { - #ifndef NDEBUG - Var var = it->first; - #ifdef VERBOSE_DEBUG - std::cout << "Reinserting elimed var: " << var+1 << std::endl; - #endif - assert(!solver.decision_var[var]); - assert(solver.assigns[var] == l_Undef); - assert(!solver.order_heap.inHeap(var)); - #endif - - for (vector<vector<Lit> >::const_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 elimed clause: " << tmp << std::endl;; - #endif - - solver2.addClause(tmp); - assert(solver2.ok); - } - } - - typedef map<Var, vector<std::pair<Lit, Lit> > > elimType2; - for (elimType2::iterator it = elimedOutVarBin.begin(), end = elimedOutVarBin.end(); it != end; it++) { - #ifndef NDEBUG - Var var = it->first; - #ifdef VERBOSE_DEBUG - std::cout << "Reinserting elimed var: " << var+1 << std::endl; - #endif - assert(!solver.decision_var[var]); - assert(solver.assigns[var] == l_Undef); - assert(!solver.order_heap.inHeap(var)); - #endif - - for (vector<std::pair<Lit, Lit> >::iterator it2 = it->second.begin(), end2 = it->second.end(); it2 != end2; it2++) { - tmp.clear(); - tmp.growTo(2); - tmp[0] = it2->first; - tmp[1] = it2->second; - - #ifdef VERBOSE_DEBUG - std::cout << "Reinserting bin clause: " << it2->first << " , " << it2->second << std::endl; - #endif - - solver2.addClause(tmp); - assert(solver2.ok); - } - } -} - -/** -@brief Adds to the solver the clauses representing variable var - -This function is useful if a variable was eliminated, but now needs to be -added back again. - -@p var The variable to be added back again -*/ -bool Subsumer::unEliminate(const Var var) -{ - assert(var_elimed[var]); - vec<Lit> tmp; - typedef map<Var, vector<vector<Lit> > > elimType; - typedef map<Var, vector<std::pair<Lit, Lit> > > elimType2; - elimType::iterator it = elimedOutVar.find(var); - elimType2::iterator it2 = elimedOutVarBin.find(var); - - //it MUST have been decision var, otherwise we would - //never have removed it - solver.setDecisionVar(var, true); - var_elimed[var] = false; - numElimed--; - #ifdef VERBOSE_DEBUG - std::cout << "Reinserting normal (non-xor) elimed var: " << var+1 << std::endl; - #endif - - //If the variable was removed because of - //pure literal removal (by blocked clause - //elimination, there are no clauses to re-insert - if (it == elimedOutVar.end() && it2 == elimedOutVarBin.end()) { - return solver.ok; - } - - FILE* backup_libraryCNFfile = solver.libraryCNFFile; - solver.libraryCNFFile = NULL; - - if (it == elimedOutVar.end()) goto next; - for (vector<vector<Lit> >::iterator itt = it->second.begin(), end2 = it->second.end(); itt != end2; itt++) { - #ifdef VERBOSE_DEBUG - std::cout << "Reinserting elimed clause: "; - for (uint32_t i = 0; i < itt->size(); i++) { - std::cout << (*itt)[i] << " , "; - } - std::cout << std::endl; - #endif - tmp.clear(); - tmp.growTo(itt->size()); - std::copy(itt->begin(), itt->end(), tmp.getData()); - solver.addClause(tmp); - } - elimedOutVar.erase(it); - - next: - if (it2 == elimedOutVarBin.end()) goto next2; - for (vector<std::pair<Lit, Lit> >::iterator itt = it2->second.begin(), end2 = it2->second.end(); itt != end2; itt++) { - tmp.clear(); - tmp.growTo(2); - tmp[0] = itt->first; - tmp[1] = itt->second; - #ifdef VERBOSE_DEBUG - std::cout << "Reinserting bin clause: " << itt->first << " , " << itt->second << std::endl; - #endif - solver.addClause(tmp); - } - elimedOutVarBin.erase(it2); - - next2: - solver.libraryCNFFile = backup_libraryCNFfile; - - return solver.ok; -} - -/** -@brief Backward-subsumption using given clause: helper function - -Checks all clauses in the occurrence lists if they are subsumed by ps or not. - -The input clause can be learnt. In that case, if it subsumes non-learnt clauses, -it will become non-learnt. - -Handles it well if the subsumed clause has a higher activity than the subsuming -clause (will take the max() of the two) - -@p ps The clause to use - -*/ -void Subsumer::subsume0(Clause& ps) -{ - #ifdef VERBOSE_DEBUG - cout << "subsume0-ing with clause: "; - ps.plainPrint(); - #endif - subsume0Happened ret = subsume0Orig(ps, ps.getAbst()); - - if (ps.learnt()) { - if (!ret.subsumedNonLearnt) { - if (ps.getGlue() > ret.glue) - ps.setGlue(ret.glue); - if (ps.getMiniSatAct() < ret.act) - ps.setMiniSatAct(ret.act); - } else { - solver.nbCompensateSubsumer++; - ps.makeNonLearnt(); - } - } -} - -/** -@brief Backward-subsumption using given clause - -@note Use helper function - -@param ps The clause to use to backward-subsume -@param[in] abs The abstraction of the clause -@return Subsumed anything? If so, what was the max activity? Was it non-learnt? -*/ -template<class T> -Subsumer::subsume0Happened Subsumer::subsume0Orig(const T& ps, uint32_t abs) -{ - subsume0Happened ret; - ret.subsumedNonLearnt = false; - ret.glue = std::numeric_limits<uint32_t>::max(); - ret.act = std::numeric_limits< float >::min(); - - vec<ClauseSimp> subs; - findSubsumed(ps, abs, subs); - for (uint32_t i = 0; i < subs.size(); i++){ - #ifdef VERBOSE_DEBUG - cout << "-> subsume0 removing:"; - subs[i].clause->plainPrint(); - #endif - - Clause* tmp = subs[i].clause; - if (tmp->learnt()) { - ret.glue = std::min(ret.glue, tmp->getGlue()); - ret.act = std::max(ret.act, tmp->getMiniSatAct()); - } else { - ret.subsumedNonLearnt = true; - } - unlinkClause(subs[i]); - } - - return ret; -} - -/** -@brief Backward subsumption and self-subsuming resolution - -Performs backward subsumption AND -self-subsuming resolution using backward-subsumption - -@param[in] ps The clause to use for backw-subsumption and self-subs. resolution -*/ -void Subsumer::subsume1(Clause& ps) -{ - vec<ClauseSimp> subs; - vec<Lit> subsLits; - #ifdef VERBOSE_DEBUG - cout << "subsume1-ing with clause:"; - ps.plainPrint(); - #endif - - findSubsumed1(ps, ps.getAbst(), subs, subsLits); - for (uint32_t j = 0; j < subs.size(); j++) { - if (subs[j].clause == NULL) continue; - ClauseSimp c = subs[j]; - if (subsLits[j] == lit_Undef) { - if (ps.learnt()) { - if (c.clause->learnt()) ps.takeMaxOfStats(*c.clause); - else { - solver.nbCompensateSubsumer++; - ps.makeNonLearnt(); - } - } - unlinkClause(c); - } else { - strenghten(c, subsLits[j]); - if (!solver.ok) return; - } - } -} - -bool Subsumer::subsume1(vec<Lit>& ps, const bool wasLearnt) -{ - vec<ClauseSimp> subs; - vec<Lit> subsLits; - bool toMakeNonLearnt = false; - - findSubsumed1(ps, calcAbstraction(ps), subs, subsLits); - for (uint32_t j = 0; j < subs.size(); j++) { - if (subs[j].clause == NULL) continue; - ClauseSimp c = subs[j]; - if (subsLits[j] == lit_Undef) { - if (wasLearnt && !c.clause->learnt()) toMakeNonLearnt = true; - unlinkClause(c); - } else { - strenghten(c, subsLits[j]); - if (!solver.ok) return false; - } - } - - return toMakeNonLearnt; -} - -/** -@brief Removes&free-s a clause from everywhere - -Removes clause from occurence lists, from Subsumer::clauses, and iter_sets. - -If clause is to be removed because the variable in it is eliminated, the clause -is saved in elimedOutVar[] before it is fully removed. - -@param[in] c The clause to remove -@param[in] elim If the clause is removed because of variable elmination, this -parameter is different from var_Undef. -*/ -void Subsumer::unlinkClause(ClauseSimp c, const Var elim) -{ - Clause& cl = *c.clause; - - for (uint32_t i = 0; i < cl.size(); i++) { - if (elim != var_Undef) numMaxElim -= occur[cl[i].toInt()].size()/2; - else { - numMaxSubsume0 -= occur[cl[i].toInt()].size()/2; - numMaxSubsume1 -= occur[cl[i].toInt()].size()/2; - } - maybeRemove(occur[cl[i].toInt()], &cl); - touchedVars.touch(cl[i], cl.learnt()); - } - - // Remove from iterator vectors/sets: - for (uint32_t i = 0; i < iter_sets.size(); i++) { - CSet& cs = *iter_sets[i]; - cs.exclude(c); - } - - // Remove clause from clause touched set: - cl_touched.exclude(c); - - //Compensate if removing learnt - if (cl.learnt()) solver.nbCompensateSubsumer++; - - if (elim != var_Undef) { - assert(!cl.learnt()); - #ifdef VERBOSE_DEBUG - std::cout << "Eliminating non-bin clause: " << *c.clause << std::endl; - std::cout << "On variable: " << elim+1 << std::endl; - #endif //VERBOSE_DEBUG - vector<Lit> lits(c.clause->size()); - std::copy(c.clause->getData(), c.clause->getDataEnd(), lits.begin()); - elimedOutVar[elim].push_back(lits); - } else { - clauses_subsumed++; - } - solver.clauseAllocator.clauseFree(c.clause); - - clauses[c.index].clause = NULL; -} - - -/** -@brief Cleans clause from false literals - -This does NOT re-implement the feature of ClauseCleaner because -here we need to remove the literals from the occurrence lists as well. Further- -more, we need propagate if needed, which is never assumed to be a need in -ClauseCleaner since there the clauses are always attached to the watch- -lists. - -@param ps Clause to be cleaned -*/ -bool Subsumer::cleanClause(Clause& ps) -{ - bool retval = false; - - Lit *i = ps.getData(); - Lit *j = i; - for (Lit *end = ps.getDataEnd(); i != end; i++) { - lbool val = solver.value(*i); - if (val == l_Undef) { - *j++ = *i; - continue; - } - if (val == l_False) { - removeW(occur[i->toInt()], &ps); - numMaxSubsume1 -= occur[i->toInt()].size()/2; - touchedVars.touch(*i, ps.learnt()); - continue; - } - if (val == l_True) { - *j++ = *i; - retval = true; - continue; - } - assert(false); - } - ps.shrink(i-j); - - return retval; -} - -bool Subsumer::cleanClause(vec<Lit>& ps) const -{ - bool retval = false; - - Lit *i = ps.getData(); - Lit *j = i; - for (Lit *end = ps.getDataEnd(); i != end; i++) { - lbool val = solver.value(*i); - if (val == l_Undef) { - *j++ = *i; - continue; - } - if (val == l_False) - continue; - if (val == l_True) { - *j++ = *i; - retval = true; - continue; - } - assert(false); - } - ps.shrink(i-j); - - return retval; -} - -/** -@brief Removes a literal from a clause - -May return with solver.ok being FALSE, and may set&propagate variable values. - -@param c Clause to be cleaned of the literal -@param[in] toRemoveLit The literal to be removed from the clause -*/ -void Subsumer::strenghten(ClauseSimp& c, const Lit toRemoveLit) -{ - #ifdef VERBOSE_DEBUG - cout << "-> Strenghtening clause :"; - c.clause->plainPrint(); - cout << " with lit: " << toRemoveLit << std::endl; - #endif - - literals_removed++; - c.clause->strengthen(toRemoveLit); - removeW(occur[toRemoveLit.toInt()], c.clause); - numMaxSubsume1 -= occur[toRemoveLit.toInt()].size()/2; - touchedVars.touch(toRemoveLit, c.clause->learnt()); - - if (cleanClause(*c.clause)) { - unlinkClause(c); - c.clause = NULL; - return; - } - - switch (c.clause->size()) { - case 0: - #ifdef VERBOSE_DEBUG - std::cout << "Strenghtened clause to 0-size -> UNSAT"<< std::endl; - #endif //VERBOSE_DEBUG - solver.ok = false; - break; - case 1: { - handleSize1Clause((*c.clause)[0]); - unlinkClause(c); - c.clause = NULL; - break; - } - case 2: { - solver.attachBinClause((*c.clause)[0], (*c.clause)[1], (*c.clause).learnt()); - solver.numNewBin++; - solver.dataSync->signalNewBinClause(*c.clause); - clBinTouched.push_back(NewBinaryClause((*c.clause)[0], (*c.clause)[1], (*c.clause).learnt())); - unlinkClause(c); - c.clause = NULL; - break; - } - default: - cl_touched.add(c); - } -} - -bool Subsumer::handleClBinTouched() -{ - assert(solver.ok); - uint32_t clauses_subsumed_before = clauses_subsumed; - uint32_t literals_removed_before = literals_removed; - uint32_t clBinSize = 0; - - vec<Lit> lits(2); - for (list<NewBinaryClause>::const_iterator it = clBinTouched.begin(); it != clBinTouched.end(); it++) { - lits[0] = it->lit1; - lits[1] = it->lit2; - const bool learnt = it->learnt; - - if (subsume1(lits, learnt)) { - //if we can't find it, that must be because it has been made non-learnt - //note: if it has been removed through elimination, it must't - //be able to subsume any non-learnt clauses, so we never enter here - if (findWBin(solver.watches, lits[0], lits[1], true)) { - findWatchedOfBin(solver.watches, lits[0], lits[1], learnt).setLearnt(false); - findWatchedOfBin(solver.watches, lits[1], lits[0], learnt).setLearnt(false); - } - } - if (!solver.ok) return false; - clBinSize++; - } - clBinTouched.clear(); - - if (solver.conf.verbosity >= 3) { - std::cout << "c subs-w-newbins " << clauses_subsumed - clauses_subsumed_before - << " lits rem " << literals_removed - literals_removed_before - << " went through: " << clBinSize << std::endl; - } - - return true; -} - -/** -@brief Handles if a clause became 1-long (unitary) - -Either sets&propagates the value, ignores the value (if already set), -or sets solver.ok = FALSE - -@param[in] lit The single literal the clause has -*/ -inline void Subsumer::handleSize1Clause(const Lit lit) -{ - if (solver.value(lit) == l_False) { - solver.ok = false; - } else if (solver.value(lit) == l_Undef) { - solver.uncheckedEnqueue(lit); - solver.ok = solver.propagate<false>().isNULL(); - } else { - assert(solver.value(lit) == l_True); - } -} - -/** -@brief Executes subsume1() recursively on all clauses - -This function requires cl_touched to have been set. Then, it manages cl_touched. -The clauses are called to perform subsume1() or subsume0() when appropriate, and -when there is enough numMaxSubume1 and numMaxSubume0 is available. -*/ -bool Subsumer::subsume0AndSubsume1() -{ - CSet s0, s1; - - uint32_t clTouchedTodo = 2000; - if (addedClauseLits > 3000000) clTouchedTodo /= 2; - if (addedClauseLits > 10000000) clTouchedTodo /= 4; - - registerIteration(s0); - registerIteration(s1); - vec<ClauseSimp> remClTouched; - - // Fixed-point for 1-subsumption: - #ifdef BIT_MORE_VERBOSITY - std::cout << "c cl_touched.nElems() = " << cl_touched.nElems() << std::endl; - #endif - while ((cl_touched.nElems() > 10) && numMaxSubsume0 > 0) { - #ifdef VERBOSE_DEBUG - std::cout << "c -- subsume0AndSubsume1() round --" << std::endl; - std::cout << "c cl_touched.nElems() = " << cl_touched.nElems() << std::endl; - std::cout << "c clauses.size() = " << clauses.size() << std::endl; - std::cout << "c numMaxSubsume0:" << numMaxSubsume0 << std::endl; - std::cout << "c numMaxSubsume1:" << numMaxSubsume1 << std::endl; - std::cout << "c numMaxElim:" << numMaxElim << std::endl; - #endif //VERBOSE_DEBUG - - uint32_t s1Added = 0; - const bool doSubs1Next = (numMaxSubsume1 > 0); - for (CSet::iterator it = cl_touched.begin(), end = cl_touched.end(); it != end; ++it) { - if (it->clause == NULL) continue; - Clause& cl = *it->clause; - - if (s1Added >= clTouchedTodo) { - break; - } - - s0.add(*it); - s1Added += s1.add(*it); - bool unset = true; - - for (uint32_t j = 0; j < cl.size(); j++) { - if (!ol_seenPos[cl[j].toInt()]) { - vec<ClauseSimp>& occs = occur[(cl[j]).toInt()]; - for (uint32_t k = 0; k < occs.size(); k++) { - if (s1Added >= clTouchedTodo) { - unset = false; - break; - } - s0.add(occs[k]); - } - } - ol_seenPos[cl[j].toInt()] = 1; - - if (s1Added >= clTouchedTodo) { - unset = false; - break; - } - - if (!ol_seenNeg[(~cl[j]).toInt()]) { - vec<ClauseSimp>& occs = occur[(~cl[j]).toInt()]; - for (uint32_t k = 0; k < occs.size(); k++) { - if (s1Added >= clTouchedTodo) { - unset = false; - break; - } - - s1Added += s1.add(occs[k]); - } - } - ol_seenNeg[(~cl[j]).toInt()] = 1; - - if (s1Added >= clTouchedTodo) { - unset = false; - break; - } - } - - remClTouched.push(*it); - if (doSubs1Next && unset) - it->clause->unsetChanged(); - } - //std::cout << "s0.nElems(): " << s0.nElems() << std::endl; - //std::cout << "s1.nElems(): " << s1.nElems() << std::endl; - - for (uint32_t i = 0; i < remClTouched.size(); i++) { - cl_touched.exclude(remClTouched[i]); - } - remClTouched.clear(); - - for (CSet::iterator it = s0.begin(), end = s0.end(); it != end; ++it) { - if (it->clause == NULL) continue; - subsume0(*it->clause); - } - s0.clear(); - - if (doSubs1Next) { - for (CSet::iterator it = s1.begin(), end = s1.end(); it != end; ++it) { - if (it->clause == NULL) continue; - subsume1(*it->clause); - if (!solver.ok) goto end; - } - s1.clear(); - } - - if (!handleClBinTouched()) goto end; - } - cl_touched.clear(); - end: - - unregisterIteration(s1); - unregisterIteration(s0); - - return solver.ok; -} - -/** -@brief Links in a clause into the occurrence lists and the clauses[] - -Increments clauseID - -@param[in] cl The clause to link in -*/ -ClauseSimp Subsumer::linkInClause(Clause& cl) -{ - ClauseSimp c(&cl, clauseID++); - clauses.push(c); - for (uint32_t i = 0; i < cl.size(); i++) { - occur[cl[i].toInt()].push(c); - touchedVars.touch(cl[i], cl.learnt()); - if (cl.getChanged()) { - ol_seenPos[cl[i].toInt()] = 0; - ol_seenNeg[(~cl[i]).toInt()] = 0; - } - } - if (cl.getChanged()) - cl_touched.add(c); - - return c; -} - -/** -@brief Adds clauses from the solver to here, and removes them from the solver - -Which clauses are needed can be controlled by the parameters - -@param[in] cs The clause-set to use, e.g. solver.binaryClauses, solver.learnts -@param[in] alsoLearnt Also add learnt clauses? -@param[in] addBinAndAddToCL If set to FALSE, binary clauses are not added, and -clauses are never added to the cl_touched set. -*/ -uint64_t Subsumer::addFromSolver(vec<Clause*>& cs) -{ - uint64_t numLitsAdded = 0; - Clause **i = cs.getData(); - Clause **j = i; - for (Clause **end = i + cs.size(); i != end; i++) { - if (i+1 != end) __builtin_prefetch(*(i+1)); - - linkInClause(**i); - numLitsAdded += (*i)->size(); - } - cs.shrink(i-j); - - return numLitsAdded; -} - -/** -@brief Frees memory occupied by occurrence lists -*/ -void Subsumer::freeMemory() -{ - for (uint32_t i = 0; i < occur.size(); i++) { - occur[i].clear(true); - } -} - -/** -@brief Adds clauses from here, back to the solver -*/ -void Subsumer::addBackToSolver() -{ - assert(solver.clauses.size() == 0); - for (uint32_t i = 0; i < clauses.size(); i++) { - if (clauses[i].clause == NULL) continue; - assert(clauses[i].clause->size() > 2); - - if (clauses[i].clause->learnt()) - solver.learnts.push(clauses[i].clause); - else - solver.clauses.push(clauses[i].clause); - } -} - -/** -@brief Remove clauses from input that contain eliminated variables - -Used to remove learnt clauses that still reference a variable that has been -eliminated. -*/ -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); - solver.clauseAllocator.clauseFree(&c); - break; - } - } - if (!remove) - *j++ = *i; - } - cs.shrink(i-j); -} - -void Subsumer::removeWrongBinsAndAllTris() -{ - uint32_t numRemovedHalfLearnt = 0; - uint32_t wsLit = 0; - for (vec<Watched> *it = solver.watches.getData(), *end = solver.watches.getDataEnd(); it != end; it++, wsLit++) { - Lit lit = ~Lit::toLit(wsLit); - vec<Watched>& ws = *it; - - vec<Watched>::iterator i = ws.getData(); - vec<Watched>::iterator j = i; - for (vec<Watched>::iterator end2 = ws.getDataEnd(); i != end2; i++) { - if (i->isTriClause()) continue; - - if (i->isBinary() - && (var_elimed[lit.var()] || var_elimed[i->getOtherLit().var()]) - ) { - assert(i->getLearnt()); - numRemovedHalfLearnt++; - } else { - *j++ = *i; - } - } - ws.shrink_(i - j); - } - - assert(numRemovedHalfLearnt % 2 == 0); - solver.learnts_literals -= numRemovedHalfLearnt; - solver.numBins -= numRemovedHalfLearnt/2; -} - -/** -@brief Fills the vector cannot_eliminate - -Variables that are: -* also present in XOR-clauses, or -* have been replaced -cannot be eliminated. This is enforced by the vector cannot_elimnate -*/ -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; - } - - for (Var var = 0; var < solver.nVars(); var++) { - cannot_eliminate[var] |= solver.varReplacer->cannot_eliminate[var]; - } - - #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 -} - -/** -@brief Subsumes&strenghtens normal clauses with (non-existing) binary clauses - -First, it backward-subsumes and performs self-subsuming resolution using binary -clauses on non-binary clauses. Then, it generates non-existing binary clauses -(that could exist, but would be redundant), and performs self-subsuming -resolution with them on the normal clauses using \function subsume0BIN(). -*/ -/*bool Subsumer::subsumeWithBinTri() -{ - assert(solver.ok); - - double mytime = cpuTime(); - uint32_t subsumed_bin = 0; - uint32_t subsumed_tri = 0; - uint32_t lit_rem_bin = 0; - uint32_t lit_rem_tri = 0; - if (!subsumeWithBinTri(solver.clauses, false, subsumed_bin, subsumed_tri, lit_rem_bin, lit_rem_tri)) - return false; - - if (!subsumeWithBinTri(solver.learnts, true, subsumed_bin, subsumed_tri, lit_rem_bin, lit_rem_tri)) - return false; - - if (solver.conf.verbosity > 0) { - std::cout - << "c subs-w-b: " << subsumed_bin - << " subs-w-t: " << subsumed_tri - << " lit-rem-w-b: " << lit_rem_bin - << " lit-rem-w-t: " << lit_rem_tri - << " T: " << std::fixed << std::setprecision(2) << (cpuTime() - mytime) - << std::endl; - } - return true; -} - -bool Subsumer::subsumeWithBinTri( - vec<Clause*>& cls - , bool learnt - , uint32_t& subsumed_bin_num - , uint32_t& subsumed_tri_num - , uint32_t& lit_rem_bin - , uint32_t& lit_rem_tri -) { - //Temporaries - vector<Lit> lits_set; - vector<char> seen_tmp2; - seen_tmp2.resize(solver.nVars()*2); - uint32_t to_remove_bin = 0; - uint32_t to_remove_tri = 0; - - Clause** cit = cls.getData(); - Clause** cit2 = cit; - Clause** cend = cls.getDataEnd(); - - for(; cit2 != cend; cit2++) { - Clause& c = **cit2; - - //Set up seen_tmp - lits_set.resize(c.size()); - for(size_t i = 0; i < c.size(); i++) { - seen_tmp[c[i].toInt()] = 1; - seen_tmp2[c[i].toInt()] = 1; - lits_set[i] = c[i]; - } - - bool subsumed = false; - - - if (subsumed) { -#ifdef VERBOSE_DEBUG - std::cout << "Removing: "; - c.plainPrint(); -#endif - solver.removeClause(c); - } else if (to_remove_bin > 0 || to_remove_tri > 0) { - lit_rem_bin += to_remove_bin; - lit_rem_tri += to_remove_tri; - solver.detachClause(c); - -#ifdef VERBOSE_DEBUG - std::cout << "Detached clause: (ptr: " << (&c) << " ) "; - c.plainPrint();; -#endif - - vec<Lit> lits; - for(size_t i = 0; i < c.size(); i++) { - if (seen_tmp2[c[i].toInt()]) - lits.push(c[i]); - } - - Clause *c2 = solver.addClauseInt(lits, c.learnt(), c.getGlue(), c.getMiniSatAct()); - solver.clauseAllocator.clauseFree(&c); - if (c2 != NULL) { - *cit++ = c2; - } - - if (!solver.ok) { - break; - } - } else { - *cit++ = *cit2; - } - - for(vector<Lit>::const_iterator it = lits_set.begin(), end = lits_set.end(); it != end; it++) { - seen_tmp[it->toInt()] = 0; - seen_tmp2[it->toInt()] = 0; - } - lits_set.clear(); - to_remove_bin = 0; - to_remove_tri = 0; - } - cls.shrink(cit2-cit); - - return solver.ok; -}*/ - -/** -@brief Clears and deletes (almost) everything in this class - -Clears touchlists, occurrance lists, clauses, and variable touched lists -*/ -void Subsumer::clearAll() -{ - touchedVars.clear(); - clauses.clear(); - cl_touched.clear(); - addedClauseLits = 0; - for (Var var = 0; var < solver.nVars(); var++) { - occur[2*var].clear(); - occur[2*var+1].clear(); - ol_seenNeg[2*var ] = 1; - ol_seenNeg[2*var + 1] = 1; - ol_seenPos[2*var ] = 1; - ol_seenPos[2*var + 1] = 1; - } -} - -bool Subsumer::eliminateVars() -{ - #ifdef BIT_MORE_VERBOSITY - std::cout << "c VARIABLE ELIMINIATION -- touchedVars size:" << touchedVars.size() << std::endl; - #endif - - uint32_t vars_elimed = 0; - - vec<Var> order; - orderVarsForElim(order); - - #ifdef VERBOSE_DEBUG - std::cout << "c #order size:" << order.size() << std::endl; - #endif - - uint32_t numtry = 0; - for (uint32_t i = 0; i < order.size() && numMaxElim > 0 && numMaxElimVars > 0; i++) { - Var var = order[i]; - if (!cannot_eliminate[var] && solver.decision_var[var]) { - numtry++; - if (maybeEliminate(order[i])) { - if (!solver.ok) return false; - vars_elimed++; - numMaxElimVars--; - } - } - } - numVarsElimed += vars_elimed; - - #ifdef BIT_MORE_VERBOSITY - std::cout << "c #try to eliminate: " << numtry << std::endl; - std::cout << "c #var-elim: " << vars_elimed << std::endl; - #endif - - return true; -} - -void Subsumer::subsumeBinsWithBins() -{ - double myTime = cpuTime(); - uint32_t numBinsBefore = solver.numBins; - - uint32_t wsLit = 0; - for (vec<Watched> *it = solver.watches.getData(), *end = solver.watches.getDataEnd(); it != end; it++, wsLit++) { - vec<Watched>& ws = *it; - Lit lit = ~Lit::toLit(wsLit); - if (ws.size() < 2) continue; - - std::sort(ws.getData(), ws.getDataEnd(), BinSorter()); - - vec<Watched>::iterator i = ws.getData(); - vec<Watched>::iterator j = i; - - Lit lastLit = lit_Undef; - bool lastLearnt = false; - for (vec<Watched>::iterator end = ws.getDataEnd(); i != end; i++) { - if (!i->isBinary()) { - *j++ = *i; - continue; - } - if (i->getOtherLit() == lastLit) { - //The sorting algorithm prefers non-learnt to learnt, so it is - //impossible to have non-learnt before learnt - assert(!(i->getLearnt() == false && lastLearnt == true)); - - assert(i->getOtherLit().var() != lit.var()); - removeWBin(solver.watches[(~(i->getOtherLit())).toInt()], lit, i->getLearnt()); - if (i->getLearnt()) solver.learnts_literals -= 2; - else { - solver.clauses_literals -= 2; - touchedVars.touch(lit, i->getLearnt()); - touchedVars.touch(i->getOtherLit(), i->getLearnt()); - } - solver.numBins--; - } else { - lastLit = i->getOtherLit(); - lastLearnt = i->getLearnt(); - *j++ = *i; - } - } - ws.shrink_(i-j); - } - - if (solver.conf.verbosity >= 1) { - std::cout << "c bin-w-bin subsume rem " - << std::setw(10) << (numBinsBefore - solver.numBins) << " bins " - << " time: " - << std::fixed << std::setprecision(2) << std::setw(5) << (cpuTime() - myTime) - << " s" << std::endl; - } - totalTime += cpuTime() - myTime; - clauses_subsumed += (numBinsBefore - solver.numBins); -} - -/** -@brief Main function in this class - -Performs, recursively: -* backward-subsumption -* self-subsuming resolution -* variable elimination - -*/ -bool Subsumer::simplifyBySubsumption() -{ - if (solver.nClauses() > 50000000 - || solver.clauses_literals > 500000000) return true; - - double myTime = cpuTime(); - clauseID = 0; - clearAll(); - - //touch all variables - for (Var var = 0; var < solver.nVars(); var++) { - if (solver.decision_var[var] && solver.assigns[var] == l_Undef) touchedVars.touch(var); - } - - if (solver.conf.doReplace && !solver.varReplacer->performReplace(true)) - return false; - /*if (solver.conf.doSubsWBins && !subsumeWithBinTri()) - return false;*/ - - fillCannotEliminate(); - - uint32_t expected_size = solver.clauses.size() + solver.learnts.size(); - if (expected_size > 10000000) return solver.ok; - - clauses.reserve(expected_size); - cl_touched.reserve(expected_size); - - solver.clauseCleaner->cleanClauses(solver.clauses, ClauseCleaner::clauses); - solver.clauseCleaner->cleanClauses(solver.learnts, ClauseCleaner::learnts); - - if (solver.clauses.size() < 10000000) - std::sort(solver.clauses.getData(), solver.clauses.getDataEnd(), sortBySize()); - addedClauseLits += addFromSolver(solver.clauses); - - if (solver.learnts.size() < 300000) - std::sort(solver.learnts.getData(), solver.learnts.getDataEnd(), sortBySize()); - addedClauseLits += addFromSolver(solver.learnts); - - CompleteDetachReatacher reattacher(solver); - reattacher.detachNonBinsNonTris(false); - totalTime += myTime - cpuTime(); - - //Do stuff with binaries - subsumeBinsWithBins(); - numMaxSubsume1 = 500*1000*1000; - if ((solver.conf.doBlockedClause) - && solver.conf.doVarElim) { - numMaxBlockToVisit = (int64_t)800*1000*1000; - blockedClauseRemoval(); - } - - numMaxSubsume1 = 2*1000*1000*1000; - //if (solver.conf.doSubsWNonExistBins && !subsWNonExitsBinsFullFull()) return false; - if (!handleClBinTouched()) return false; - - if (solver.conf.doReplace && solver.conf.doRemUselessBins) { - UselessBinRemover uselessBinRemover(solver); - if (!uselessBinRemover.removeUslessBinFull()) return false; - } - - myTime = cpuTime(); - setLimits(); - clauses_subsumed = 0; - literals_removed = 0; - numVarsElimed = 0; - uint32_t origTrailSize = solver.trail.size(); - - #ifdef BIT_MORE_VERBOSITY - std::cout << "c time until pre-subsume0 clauses and subsume1 2-learnts:" << cpuTime()-myTime << std::endl; - std::cout << "c pre-subsumed:" << clauses_subsumed << std::endl; - std::cout << "c cl_touched:" << cl_touched.nElems() << std::endl; - std::cout << "c clauses:" << clauses.size() << std::endl; - std::cout << "c numMaxSubsume0:" << numMaxSubsume0 << std::endl; - std::cout << "c numMaxSubsume1:" << numMaxSubsume1 << std::endl; - std::cout << "c numMaxElim:" << numMaxElim << std::endl; - #endif - - do { - if (!subsume0AndSubsume1()) return false; - - if (!solver.conf.doVarElim) break; - - if (!eliminateVars()) return false; - - //subsumeBinsWithBins(); - solver.clauseCleaner->removeSatisfiedBins(); - } while (cl_touched.nElems() > 10); - - if (!solver.ok) return false; - - assert(verifyIntegrity()); - - removeWrong(solver.learnts); - removeWrongBinsAndAllTris(); - removeAssignedVarsFromEliminated(); - - solver.order_heap.filter(Solver::VarFilter(solver)); - - addBackToSolver(); - if (!reattacher.reattachNonBins()) return false; - - if (solver.conf.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; - } - totalTime += cpuTime() - myTime; - - solver.testAllClauseAttach(); - return true; -} - -/** -@brief Calculate limits for backw-subsumption, var elim, etc. - -It is important to have limits, otherwise the time taken to perfom these tasks -could be huge. Furthermore, it seems that there is a benefit in doing these -simplifications slowly, instead of trying to use them as much as possible -from the beginning. -*/ -void Subsumer::setLimits() -{ - numMaxSubsume0 = 300*1000*1000; - numMaxSubsume1 = 30*1000*1000; - - numMaxElim = 500*1000*1000; - numMaxElim *= 6; - - #ifdef BIT_MORE_VERBOSITY - std::cout << "c addedClauseLits: " << addedClauseLits << std::endl; - #endif - - if (addedClauseLits < 5000000) { - numMaxElim *= 2; - numMaxSubsume0 *= 2; - numMaxSubsume1 *= 2; - } - - if (addedClauseLits < 1000000) { - numMaxElim *= 2; - numMaxSubsume0 *= 2; - numMaxSubsume1 *= 2; - } - - numMaxElimVars = (uint64_t) (((double)solver.order_heap.size()*0.3) * sqrt((double)numCalls)); - - 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 (!solver.conf.doSubsume1) - numMaxSubsume1 = 0; - - - numCalls++; - - //For debugging - - //numMaxSubsume0 = 0; - //numMaxSubsume1 = 0; - //numMaxSubsume0 = std::numeric_limits<int64_t>::max(); - //numMaxSubsume1 = std::numeric_limits<int64_t>::max(); - //numMaxElimVars = std::numeric_limits<int32_t>::max(); - //numMaxElim = std::numeric_limits<int64_t>::max(); - - //numMaxBlockToVisit = std::numeric_limits<int64_t>::max(); - //numMaxBlockVars = std::numeric_limits<uint32_t>::max(); -} - -/*bool Subsumer::subsWNonExitsBinsFullFull() -{ - double myTime = cpuTime(); - clauses_subsumed = 0; - literals_removed = 0; - for (vec<Watched> *it = solver.watches.getData(), *end = solver.watches.getDataEnd(); it != end; it++) { - if (it->size() < 2) continue; - std::sort(it->getData(), it->getDataEnd(), BinSorter2()); - } - uint32_t oldTrailSize = solver.trail.size(); - if (!subsWNonExistBinsFull()) return false; - if (solver.conf.verbosity >= 1) { - std::cout << "c Subs w/ non-existent bins: " << std::setw(6) << clauses_subsumed - << " l-rem: " << std::setw(6) << literals_removed - << " v-fix: " << std::setw(5) << solver.trail.size() - oldTrailSize - << " done: " << std::setw(6) << doneNum - << " time: " << std::fixed << std::setprecision(2) << std::setw(5) << (cpuTime() - myTime) << " s" - << std::endl; - } - totalTime += cpuTime() - myTime; - return true; -} - -#define MAX_BINARY_PROP 60000000 - -bool Subsumer::subsWNonExistBinsFull() -{ - uint64_t oldProps = solver.propagations; - uint64_t maxProp = MAX_BINARY_PROP*7; - toVisitAll.clear(); - toVisitAll.growTo(solver.nVars()*2, false); - extraTimeNonExist = 0; - OnlyNonLearntBins* onlyNonLearntBins = NULL; - if (solver.clauses_literals < 10*1000*1000) { - onlyNonLearntBins = new OnlyNonLearntBins(solver); - onlyNonLearntBins->fill(); - solver.multiLevelProp = true; - } - - doneNum = 0; - uint32_t startFrom = solver.mtrand.randInt(solver.order_heap.size()); - for (uint32_t i = 0; i < solver.order_heap.size(); i++) { - Var var = solver.order_heap[(startFrom + i) % solver.order_heap.size()]; - if (solver.propagations + extraTimeNonExist*150 > oldProps + maxProp) break; - if (solver.assigns[var] != l_Undef || !solver.decision_var[var]) continue; - doneNum++; - extraTimeNonExist += 5; - - Lit lit(var, true); - if (onlyNonLearntBins != NULL && onlyNonLearntBins->getWatchSize(lit) == 0) goto next; - if (!subsWNonExistBins(lit, onlyNonLearntBins)) { - if (!solver.ok) return false; - solver.cancelUntilLight(); - solver.uncheckedEnqueue(~lit); - solver.ok = solver.propagate<false>().isNULL(); - if (!solver.ok) return false; - continue; - } - extraTimeNonExist += 10; - next: - - //in the meantime it could have got assigned - if (solver.assigns[var] != l_Undef) continue; - lit = ~lit; - if (onlyNonLearntBins != NULL && onlyNonLearntBins->getWatchSize(lit) == 0) continue; - if (!subsWNonExistBins(lit, onlyNonLearntBins)) { - if (!solver.ok) return false; - solver.cancelUntilLight(); - solver.uncheckedEnqueue(~lit); - solver.ok = solver.propagate<false>().isNULL(); - if (!solver.ok) return false; - continue; - } - extraTimeNonExist += 10; - } - - if (onlyNonLearntBins) delete onlyNonLearntBins; - - return true; -} - -bool Subsumer::subsWNonExistBins(const Lit& lit, OnlyNonLearntBins* onlyNonLearntBins) -{ - #ifdef VERBOSE_DEBUG - std::cout << "subsWNonExistBins called with lit " << lit << std::endl; - #endif //VERBOSE_DEBUG - toVisit.clear(); - solver.newDecisionLevel(); - solver.uncheckedEnqueueLight(lit); - bool failed; - if (onlyNonLearntBins == NULL) - failed = (!solver.propagateNonLearntBin().isNULL()); - else - failed = !onlyNonLearntBins->propagate(); - if (failed) return false; - uint32_t abst = 0; - - assert(solver.decisionLevel() > 0); - for (int sublevel = solver.trail.size()-1; sublevel > (int)solver.trail_lim[0]; sublevel--) { - Lit x = solver.trail[sublevel]; - toVisit.push(x); - abst |= 1 << (x.var() & 31); - toVisitAll[x.toInt()] = true; - } - solver.cancelUntilLight(); - subsume0BIN(~lit, toVisitAll, abst); - - for (uint32_t i = 0; i < toVisit.size(); i++) - toVisitAll[toVisit[i].toInt()] = false; - - return solver.ok; -} - -void Subsumer::subsume0BIN(const Lit lit1, const vec<char>& lits, const uint32_t abst) -{ - vec<ClauseSimp> subs; - vec<ClauseSimp> subs2; - vec<Lit> subs2Lit; - - vec<ClauseSimp>& cs = occur[lit1.toInt()]; - for (ClauseSimp *it = cs.getData(), *end = it + cs.size(); it != end; it++){ - if (it+1 != end) __builtin_prefetch((it+1)->clause); - if (it->clause == NULL) continue; - - Clause& c = *it->clause; - if ((c.getAbst() & abst) == 0) continue; - extraTimeNonExist += c.size()*2; - bool removed = false; - bool removedLit = false; - for (uint32_t i = 0; i < c.size(); i++) { - if (lits[c[i].toInt()]) { - subs.push(*it); - removed = true; - break; - } - - if (!removedLit && lits[(~c[i]).toInt()]) { - subs2.push(*it); - subs2Lit.push(c[i]); - removedLit = true; - } - } - - if (removed && removedLit) { - subs2.pop(); - subs2Lit.pop(); - } - } - - for (uint32_t i = 0; i < subs.size(); i++){ - unlinkClause(subs[i]); - } - - for (uint32_t i = 0; i < subs2.size(); i++) { - strenghten(subs2[i], subs2Lit[i]); - if (!solver.ok) break; - } - - #ifdef VERBOSE_DEBUG - if (!solver.ok) { - std::cout << "solver.ok is false when returning from subsume0BIN()" << std::endl; - } - #endif //VERBOSE_DEBUG -}*/ - - - -/** -@brief Remove variables from var_elimed if it has been set - -While doing, e.g. self-subsuming resolution, it might happen that the variable -that we JUST eliminated has been assigned a value. This could happen for example -if due to clause-cleaning some variable value got propagated that we just set. -Therefore, we must check at the very end if any variables that we eliminated -got set, and if so, the clauses linked to these variables can be fully removed -from elimedOutVar[]. -*/ -void Subsumer::removeAssignedVarsFromEliminated() -{ - for (Var var = 0; var < var_elimed.size(); var++) { - if (var_elimed[var] && solver.assigns[var] != l_Undef) { - var_elimed[var] = false; - solver.setDecisionVar(var, true); - numElimed--; - - map<Var, vector<vector<Lit> > >::iterator it = elimedOutVar.find(var); - if (it != elimedOutVar.end()) elimedOutVar.erase(it); - - map<Var, vector<std::pair<Lit, Lit> > >::iterator it2 = elimedOutVarBin.find(var); - if (it2 != elimedOutVarBin.end()) elimedOutVarBin.erase(it2); - } - } -} - -/** -@brief Finds clauses that are backward-subsumed by given clause - -Only handles backward-subsumption. Uses occurrence lists - -@param[in] ps The clause to backward-subsume with. -@param[in] abs Abstraction of the clause ps -@param[out] out_subsumed The set of clauses subsumed by this clause -*/ -template<class T> -void Subsumer::findSubsumed(const T& ps, uint32_t abs, vec<ClauseSimp>& out_subsumed) -{ - #ifdef VERBOSE_DEBUG - cout << "findSubsumed: " << ps << std::endl; - #endif - - for (uint32_t i = 0; i != ps.size(); i++) - seen_tmp[ps[i].toInt()] = 1; - - 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()]; - numMaxSubsume0 -= cs.size()*10 + 5; - for (ClauseSimp *it = cs.getData(), *end = it + cs.size(); it != end; it++){ - if (it+1 != end) __builtin_prefetch((it+1)->clause); - - if (it->clause != (Clause*)&ps - && subsetAbst(abs, it->clause->getAbst()) - && ps.size() <= it->clause->size()) { - numMaxSubsume0 -= (*it).clause->size() + ps.size(); - if (subset(ps.size(), *it->clause)) { - out_subsumed.push(*it); - #ifdef VERBOSE_DEBUG - cout << "subsumed: "; - it->clause->plainPrint(); - #endif - } - } - } - - for (uint32_t i = 0; i != ps.size(); i++) - seen_tmp[ps[i].toInt()] = 0; -} - -/** -@brief Checks if clauses are subsumed or could be strenghtened with given clause - -Checks if: -* any clause is subsumed with given clause -* the given clause could perform self-subsuming resolution on any other clause - -Only takes into consideration clauses that are in the occurrence lists. - -@param[in] ps The clause to perform the above listed algos with -@param[in] abs The abstraction of clause ps -@param[out] out_subsumed The clauses that could be modified by ps -@param[out] out_lits Defines HOW these clauses could be modified. By removing -literal, or by subsumption (in this case, there is lit_Undef here) -*/ -template<class T> -void Subsumer::findSubsumed1(const T& ps, uint32_t abs, vec<ClauseSimp>& out_subsumed, vec<Lit>& out_lits) -{ - #ifdef VERBOSE_DEBUG - cout << "findSubsumed1: " << ps << std::endl; - #endif - - Var minVar = var_Undef; - uint32_t bestSize = std::numeric_limits<uint32_t>::max(); - for (uint32_t i = 0; i < ps.size(); i++){ - uint32_t newSize = occur[ps[i].toInt()].size()+ occur[(~ps[i]).toInt()].size(); - if (newSize < bestSize) { - minVar = ps[i].var(); - bestSize = newSize; - } - } - assert(minVar != var_Undef); - - numMaxSubsume1 -= bestSize*10 + 10; - fillSubs(ps, abs, out_subsumed, out_lits, Lit(minVar, true)); - fillSubs(ps, abs, out_subsumed, out_lits, Lit(minVar, false)); -} - -/** -@brief Helper function for findSubsumed1 - -Used to avoid duplication of code -*/ -template<class T> -void inline Subsumer::fillSubs(const T& ps, uint32_t abs, vec<ClauseSimp>& out_subsumed, vec<Lit>& out_lits, const Lit lit) -{ - Lit litSub; - vec<ClauseSimp>& cs = occur[lit.toInt()]; - for (ClauseSimp *it = cs.getData(), *end = it + cs.size(); it != end; it++) { - if (it+1 != end) __builtin_prefetch((it+1)->clause); - - if (it->clause != (Clause*)&ps - && subsetAbst(abs, it->clause->getAbst()) - && ps.size() <= it->clause->size()) { - numMaxSubsume1 -= (*it).clause->size() + ps.size(); - litSub = subset1(ps, *it->clause); - if (litSub != lit_Error) { - out_subsumed.push(*it); - out_lits.push(litSub); - #ifdef VERBOSE_DEBUG - if (litSub == lit_Undef) cout << "subsume0-d: "; - else cout << "subsume1-ed (lit: " << litSub << "): "; - it->clause->plainPrint(); - #endif - } - } - } -} - - -void Subsumer::removeClausesHelper(vec<ClAndBin>& todo, const Var var, std::pair<uint32_t, uint32_t>& removed) -{ - pair<uint32_t, uint32_t> tmp; - for (uint32_t i = 0; i < todo.size(); i++) { - ClAndBin& c = todo[i]; - if (!c.isBin) { - unlinkClause(c.clsimp, var); - } else { - #ifdef VERBOSE_DEBUG - std::cout << "Eliminating bin clause: " << c.lit1 << " , " << c.lit2 << std::endl; - std::cout << "On variable: " << var+1 << std::endl; - #endif - assert(var == c.lit1.var() || var == c.lit2.var()); - tmp = removeWBinAll(solver.watches[(~c.lit1).toInt()], c.lit2); - //assert(tmp.first > 0 || tmp.second > 0); - removed.first += tmp.first; - removed.second += tmp.second; - - tmp = removeWBinAll(solver.watches[(~c.lit2).toInt()], c.lit1); - //assert(tmp.first > 0 || tmp.second > 0); - removed.first += tmp.first; - removed.second += tmp.second; - - elimedOutVarBin[var].push_back(std::make_pair(c.lit1, c.lit2)); - touchedVars.touch(c.lit1, false); - touchedVars.touch(c.lit2, false); - } - } -} - -/** -@brief Used for variable elimination - -Migrates clauses in poss to ps, and negs to ns -Also unlinks ass clauses is ps and ns. This is special unlinking, since it -actually saves the clauses for later re-use when extending the model, or re- -introducing the eliminated variables. - -@param[in] poss The occurrence list of var where it is positive -@param[in] negs The occurrence list of var where it is negavite -@param[out] ps Where thre clauses from poss have been moved -@param[out] ns Where thre clauses from negs have been moved -@param[in] var The variable that is being eliminated -*/ -void Subsumer::removeClauses(vec<ClAndBin>& posAll, vec<ClAndBin>& negAll, const Var var) -{ - pair<uint32_t, uint32_t> removed; - removed.first = 0; - removed.second = 0; - - removeClausesHelper(posAll, var, removed); - removeClausesHelper(negAll, var, removed); - - solver.learnts_literals -= removed.first; - solver.clauses_literals -= removed.second; - solver.numBins -= (removed.first + removed.second)/2; -} - -uint32_t Subsumer::numNonLearntBins(const Lit lit) const -{ - uint32_t num = 0; - const vec<Watched>& ws = solver.watches[(~lit).toInt()]; - for (vec<Watched>::const_iterator it = ws.getData(), end = ws.getDataEnd(); it != end; it++) { - if (it->isBinary() && !it->getLearnt()) num++; - } - - return num; -} - -void Subsumer::fillClAndBin(vec<ClAndBin>& all, vec<ClauseSimp>& cs, const Lit lit) -{ - for (uint32_t i = 0; i < cs.size(); i++) { - if (!cs[i].clause->learnt()) all.push(ClAndBin(cs[i])); - } - - const vec<Watched>& ws = solver.watches[(~lit).toInt()]; - for (vec<Watched>::const_iterator it = ws.getData(), end = ws.getDataEnd(); it != end; it++) { - if (it->isBinary() &&!it->getLearnt()) all.push(ClAndBin(lit, it->getOtherLit())); - } -} - -/** -@brief Tries to eliminate variable - -Tries to eliminate a variable. It uses heuristics to decide whether it's a good -idea to eliminate a variable or not. - -@param[in] var The variable that is being eliminated -@return TRUE if variable was eliminated -*/ -bool Subsumer::maybeEliminate(const Var var) -{ - assert(!var_elimed[var]); - assert(!cannot_eliminate[var]); - assert(solver.decision_var[var]); - if (solver.value(var) != l_Undef) return false; - - Lit lit = Lit(var, false); - - //Only exists in binary clauses -- don't delete it then - /*if (occur[lit.toInt()].size() == 0 && occur[(~lit).toInt()].size() == 0) - return false;*/ - - vec<ClauseSimp>& poss = occur[lit.toInt()]; - vec<ClauseSimp>& negs = occur[(~lit).toInt()]; - const uint32_t numNonLearntPos = numNonLearntBins(lit); - const uint32_t numNonLearntNeg = numNonLearntBins(~lit); - uint32_t before_literals = numNonLearntNeg*2 + numNonLearntPos*2; - - uint32_t posSize = 0; - for (uint32_t i = 0; i < poss.size(); i++) - if (!poss[i].clause->learnt()) { - posSize++; - before_literals += poss[i].clause->size(); - } - posSize += numNonLearntPos; - - uint32_t negSize = 0; - for (uint32_t i = 0; i < negs.size(); i++) - if (!negs[i].clause->learnt()) { - negSize++; - before_literals += negs[i].clause->size(); - } - negSize += numNonLearntNeg; - - numMaxElim -= posSize + negSize; - - // Heuristic CUT OFF: - if (posSize >= 10 && negSize >= 10) return false; - - // Heuristic CUT OFF2: - if ((posSize >= 3 && negSize >= 3 && before_literals > 300) - && clauses.size() > 700000) - return false; - if ((posSize >= 5 && negSize >= 5 && before_literals > 400) - && clauses.size() <= 700000 && clauses.size() > 100000) - return false; - if ((posSize >= 8 && negSize >= 8 && before_literals > 700) - && clauses.size() <= 100000) - return false; - - vec<ClAndBin> posAll, negAll; - fillClAndBin(posAll, poss, lit); - fillClAndBin(negAll, negs, ~lit); - - // Count clauses/literals after elimination: - uint32_t before_clauses = posSize + negSize; - uint32_t after_clauses = 0; - vec<Lit> dummy; //to reduce temporary data allocation - for (uint32_t i = 0; i < posAll.size(); i++) for (uint32_t j = 0; j < negAll.size(); j++){ - // Merge clauses. If 'y' and '~y' exist, clause will not be created. - dummy.clear(); - const bool ok = merge(posAll[i], negAll[j], lit, ~lit, dummy); - if (ok){ - after_clauses++; - if (after_clauses > before_clauses) - return false; - } - } - - //Eliminate - //removing clauses (both non-learnt and learnt) - vec<ClauseSimp> tmp1 = poss; - poss.clear(); - for (uint32_t i = 0; i < tmp1.size(); i++) { - if (tmp1[i].clause->learnt()) unlinkClause(tmp1[i]); - } - vec<ClauseSimp> tmp2 = negs; - negs.clear(); - for (uint32_t i = 0; i < tmp2.size(); i++) { - if (tmp2[i].clause->learnt()) unlinkClause(tmp2[i]); - } - - removeClauses(posAll, negAll, var); - - //check watchlists - #ifndef NDEBUG - const vec<Watched>& ws1 = solver.watches[lit.toInt()]; - for (vec<Watched>::const_iterator i = ws1.getData(), end = ws1.getDataEnd(); i != end; i++) { - assert(i->isTriClause() || (i->isBinary() && i->getLearnt())); - } - const vec<Watched>& ws2 = solver.watches[(~lit).toInt()]; - for (vec<Watched>::const_iterator i = ws2.getData(), end = ws2.getDataEnd(); i != end; i++) { - assert(i->isTriClause() || (i->isBinary() && i->getLearnt())); - } - #endif - - for (uint32_t i = 0; i < posAll.size(); i++) for (uint32_t j = 0; j < negAll.size(); j++){ - dummy.clear(); - bool ok = merge(posAll[i], negAll[j], lit, ~lit, dummy); - if (!ok) continue; - - if (cleanClause(dummy)) - continue; - - #ifdef VERBOSE_DEBUG - std::cout << "Adding new clause due to varelim: " << dummy << std::endl; - #endif - switch (dummy.size()) { - case 0: - solver.ok = false; - break; - case 1: { - handleSize1Clause(dummy[0]); - break; - } - case 2: { - if (findWBin(solver.watches, dummy[0], dummy[1])) { - Watched& w = findWatchedOfBin(solver.watches, dummy[0], dummy[1]); - if (w.getLearnt()) { - w.setLearnt(false); - findWatchedOfBin(solver.watches, dummy[1], dummy[0], true).setLearnt(false); - solver.learnts_literals -= 2; - solver.clauses_literals += 2; - } - } else { - solver.attachBinClause(dummy[0], dummy[1], false); - solver.numNewBin++; - } - if (numMaxSubsume1 > 0) - subsume1(dummy, false); - break; - } - default: { - Clause* cl = solver.clauseAllocator.Clause_new(dummy); - ClauseSimp c = linkInClause(*cl); - if (numMaxSubsume1 > 0) subsume1(*c.clause); - else if (numMaxSubsume0) subsume0(*c.clause); - } - } - if (!solver.ok) return true; - } - - assert(occur[lit.toInt()].size() == 0 && occur[(~lit).toInt()].size() == 0); - var_elimed[var] = true; - numElimed++; - solver.setDecisionVar(var, false); - return true; -} - -/** -@brief Resolves two clauses on a variable - -Clause ps must contain without_p -Clause ps must contain without_q -And without_p = ~without_q - -@note: 'seen' is assumed to be cleared. - -@param[in] var The variable that is being eliminated -@return FALSE if clause is always satisfied ('out_clause' should not be used) -*/ -bool Subsumer::merge(const ClAndBin& ps, const ClAndBin& qs, const Lit without_p, const Lit without_q, vec<Lit>& out_clause) -{ - bool retval = true; - if (ps.isBin) { - numMaxElim -= 2; - assert(ps.lit1 == without_p); - assert(ps.lit2 != without_p); - - seen_tmp[ps.lit2.toInt()] = 1; - out_clause.push(ps.lit2); - } else { - Clause& c = *ps.clsimp.clause; - numMaxElim -= c.size()*5; - for (uint32_t i = 0; i < c.size(); i++){ - if (c[i] != without_p){ - seen_tmp[c[i].toInt()] = 1; - out_clause.push(c[i]); - } - } - } - - if (qs.isBin) { - numMaxElim -= 2; - assert(qs.lit1 == without_q); - assert(qs.lit2 != without_q); - - if (seen_tmp[(~qs.lit2).toInt()]) { - retval = false; - goto end; - } - if (!seen_tmp[qs.lit2.toInt()]) - out_clause.push(qs.lit2); - } else { - Clause& c = *qs.clsimp.clause; - numMaxElim -= c.size()*5; - for (uint32_t i = 0; i < c.size(); i++){ - if (c[i] != without_q) { - if (seen_tmp[(~c[i]).toInt()]) { - retval = false; - goto end; - } - if (!seen_tmp[c[i].toInt()]) - out_clause.push(c[i]); - } - } - } - - end: - if (ps.isBin) { - seen_tmp[ps.lit2.toInt()] = 0; - } else { - Clause& c = *ps.clsimp.clause; - for (uint32_t i = 0; i < c.size(); i++) - seen_tmp[c[i].toInt()] = 0; - } - - return retval; -} - -/** -@brief Orders variables for elimination - -Variables are ordered according to their occurrances. If a variable occurs far -less than others, it should be prioritised for elimination. The more difficult -variables are OK to try later. - -@note: Will untouch all variables. - -@param[out] order The order to try to eliminate the variables -*/ -void Subsumer::orderVarsForElim(vec<Var>& order) -{ - order.clear(); - vec<pair<int, Var> > cost_var; - for (vector<Var>::const_iterator it = touchedVars.begin(), end = touchedVars.end(); it != end ; it++){ - Lit x = Lit(*it, false); - - //Long non-learnt POS - uint32_t pos = 0; - const vec<ClauseSimp>& poss = occur[x.toInt()]; - for (uint32_t i = 0; i < poss.size(); i++) - if (!poss[i].clause->learnt()) pos++; - - //Long non-learnt NEG - uint32_t neg = 0; - const vec<ClauseSimp>& negs = occur[(~x).toInt()]; - for (uint32_t i = 0; i < negs.size(); i++) - if (!negs[i].clause->learnt()) neg++; - - //Short non-lerants - //uint32_t nNonLPos = numNonLearntBins(x); - //uint32_t nNonLNeg = numNonLearntBins(~x); - - //uint32_t cost = pos*neg/2 + nNonLPos*neg*2 + nNonLNeg*pos*2 + nNonLNeg*nNonLPos*6; - uint32_t cost = pos*neg * 2 + numNonLearntBins(x) * neg + numNonLearntBins(~x) * pos; - - cost_var.push(std::make_pair(cost, x.var())); - } - touchedVars.clear(); - - std::sort(cost_var.getData(), cost_var.getDataEnd(), myComp()); - for (uint32_t x = 0; x < cost_var.size(); x++) { - order.push(cost_var[x].second); - } -} - -/** -@brief Verifies that occurrence lists are OK - -Calculates how many occurences are of the varible in clauses[], and if that is -less than occur[var].size(), returns FALSE - -@return TRUE if they are OK -*/ -bool Subsumer::verifyIntegrity() -{ - vector<uint32_t> 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++) { - #ifdef VERBOSE_DEBUG - std::cout << "occurNum[i]:" << occurNum[i] - << " occur[i]:" << occur[i].size() - << " --- i:" << i << std::endl; - #endif //VERBOSE_DEBUG - - if (occurNum[i] != occur[i].size()) return false; - } - - return true; -} - -template<class T> -bool Subsumer::allTautology(const T& ps, const Lit lit) -{ - #ifdef VERBOSE_DEBUG - cout << "allTautology: " << ps << std::endl; - #endif - - numMaxBlockToVisit -= ps.size()*2; - for (const Lit *l = ps.getData(), *end = ps.getDataEnd(); l != end; l++) { - if (*l != ~lit) seen_tmp[l->toInt()] = true; - } - - bool allIsTautology = true; - const vec<ClauseSimp>& cs = occur[lit.toInt()]; - const vec<Watched>& ws = solver.watches[(~lit).toInt()]; - - for (const ClauseSimp *it = cs.getData(), *end = cs.getDataEnd(); it != end; it++){ - if (it+1 != end) __builtin_prefetch((it+1)->clause); - - const Clause& c = *it->clause; - numMaxBlockToVisit -= c.size(); - for (const Lit *l = c.getData(), *end2 = c.getDataEnd(); l != end2; l++) { - if (seen_tmp[(~(*l)).toInt()]) { - goto next; - } - } - allIsTautology = false; - break; - - next:; - } - if (!allIsTautology) goto end; - - numMaxBlockToVisit -= ws.size(); - for (vec<Watched>::const_iterator it = ws.getData(), end = ws.getDataEnd(); it != end; it++) { - if (!it->isNonLearntBinary()) continue; - if (seen_tmp[(~it->getOtherLit()).toInt()]) continue; - else { - allIsTautology = false; - break; - } - } - - end: - 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.empty()) return; - - double myTime = cpuTime(); - numblockedClauseRemoved = 0; - uint32_t numElimedBefore = numElimed; - - 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++) { - //if (solver.order_heap.size() < 1) break; - //touchBlockedVar(solver.order_heap[solver.mtrand.randInt(solver.order_heap.size()-1)]); - touchBlockedVar(solver.order_heap[i]); - } - - uint32_t triedToBlock = 0; - while (numMaxBlockToVisit > 0 && !touchedBlockedVars.empty()) { - VarOcc vo = touchedBlockedVars.top(); - touchedBlockedVars.pop(); - touchedBlockedVarsBool[vo.var] = false; - - if (solver.value(vo.var) != l_Undef - || !solver.decision_var[vo.var] - || cannot_eliminate[vo.var]) - continue; - - triedToBlock++; - Lit lit = Lit(vo.var, false); - - //if (!tryOneSetting(lit)) { - tryOneSetting(lit); - // } - } - - if (solver.conf.verbosity >= 1) { - std::cout - << "c spec. var-rem cls: " << std::setw(8) << numblockedClauseRemoved - << " vars: " << std::setw(6) << numElimed - numElimedBefore - << " tried: " << std::setw(11) << triedToBlock - << " T: " << std::fixed << std::setprecision(2) << std::setw(4) << cpuTime() - myTime - << " s" << std::endl; - } -} - -bool Subsumer::tryOneSetting(const Lit lit) -{ - numMaxBlockToVisit -= occur[lit.toInt()].size(); - for(ClauseSimp *it = occur[lit.toInt()].getData(), *end = occur[lit.toInt()].getDataEnd(); it != end; it++) { - if (!allTautology(*it->clause, ~lit)) { - return false; - } - } - - vec<Lit> lits(1); - const vec<Watched>& ws = solver.watches[(~lit).toInt()]; - numMaxBlockToVisit -= ws.size(); - for (vec<Watched>::const_iterator it = ws.getData(), end = ws.getDataEnd(); it != end; it++) { - if (!it->isNonLearntBinary()) continue; - lits[0] = it->getOtherLit(); - if (!allTautology(lits, ~lit)) return false; - } - - blockedClauseElimAll(lit); - blockedClauseElimAll(~lit); - - var_elimed[lit.var()] = true; - numElimed++; - numMaxElimVars--; - solver.setDecisionVar(lit.var(), false); - - return true; -} - -void Subsumer::blockedClauseElimAll(const Lit lit) -{ - vec<ClauseSimp> toRemove(occur[lit.toInt()]); - for (ClauseSimp *it = toRemove.getData(), *end = toRemove.getDataEnd(); it != end; it++) { - #ifdef VERBOSE_DEBUG - std::cout << "Next varelim because of block clause elim" << std::endl; - #endif //VERBOSE_DEBUG - unlinkClause(*it, lit.var()); - numblockedClauseRemoved++; - } - - uint32_t removedNum = 0; - vec<Watched>& ws = solver.watches[(~lit).toInt()]; - vec<Watched>::iterator i = ws.getData(); - vec<Watched>::iterator j = i; - for (vec<Watched>::iterator end = ws.getDataEnd(); i != end; i++) { - if (!i->isNonLearntBinary()) { - *j++ = *i; - continue; - } - assert(!i->getLearnt()); - removeWBin(solver.watches[(~i->getOtherLit()).toInt()], lit, false); - elimedOutVarBin[lit.var()].push_back(std::make_pair(lit, i->getOtherLit())); - touchedVars.touch(i->getOtherLit(), false); - removedNum++; - } - ws.shrink_(i-j); - - solver.clauses_literals -= removedNum*2; - solver.numBins -= removedNum; -} - -/** -@brief Checks if eliminated variables are unassigned - -If there is a variable that has been assigned even though it's been eliminated -that means that there were clauses that contained that variable, and where some- -how inserted into the watchlists. That would be a grave bug, since that would -mean that not all clauses containing the eliminated variable were removed during -the running of this class. - -@return TRUE if they are all unassigned -*/ -bool Subsumer::checkElimedUnassigned() const -{ - uint32_t checkNumElimed = 0; - for (uint32_t i = 0; i < var_elimed.size(); i++) { - if (var_elimed[i]) { - checkNumElimed++; - assert(solver.assigns[i] == l_Undef); - if (solver.assigns[i] != l_Undef) return false; - } - } - assert(numElimed == checkNumElimed); - - return true; -} diff --git a/src/prop/cryptominisat/Solver/Subsumer.h b/src/prop/cryptominisat/Solver/Subsumer.h deleted file mode 100644 index 24a7da927..000000000 --- a/src/prop/cryptominisat/Solver/Subsumer.h +++ /dev/null @@ -1,500 +0,0 @@ -/***************************************************************************** -SatELite -- (C) Niklas Een, Niklas Sorensson, 2004 -CryptoMiniSat -- Copyright (c) 2009 Mate Soos - -Original code by SatELite authors are under an MIT licence. -Modifications for CryptoMiniSat are under GPLv3. -******************************************************************************/ - -#ifndef SIMPLIFIER_H -#define SIMPLIFIER_H - -#include "Solver.h" -#include "CSet.h" -#include "BitArray.h" -#include <map> -#include <vector> -#include <list> -#include <queue> - -namespace CMSat { - -using std::vector; -using std::list; -using std::map; -using std::priority_queue; - -class ClauseCleaner; -class OnlyNonLearntBins; - -class TouchList -{ - public: - void resize(uint32_t size) - { - touched.resize(size, 0); - } - - void addOne(Var var) - { - assert(touched.size() == var); - touched.push_back(1); - touchedList.push_back(var); - } - - void touch(Lit lit, const bool learnt) - { - if (!learnt) touch(lit.var()); - } - - void touch(Var var) - { - if (!touched[var]) { - touchedList.push_back(var); - touched[var]= 1; - } - } - - void clear() - { - touchedList.clear(); - std::fill(touched.begin(), touched.end(), 0); - } - - uint32_t size() const - { - return touchedList.size(); - } - - vector<Var>::const_iterator begin() const - { - return touchedList.begin(); - } - - vector<Var>::const_iterator end() const - { - return touchedList.end(); - } - - private: - vector<Var> touchedList; - vector<char> touched; -}; - -/** -@brief Handles subsumption, self-subsuming resolution, variable elimination, and related algorithms - -There are two main functions in this class, simplifyBySubsumption() and subsumeWithBinaries(). -The first one is the most important of the two: it performs everything, except manipuation -with non-existing binary clauses. The second does self-subsuming resolution with existing binary -clauses, and then does self-subsuming resolution and subsumption with binary clauses that don't exist -and never will exist: they are temporarily "created" (memorised), and used by subsume0BIN(). -*/ -class Subsumer -{ -public: - - //Construct-destruct - Subsumer(Solver& S2); - - //Called from main - bool simplifyBySubsumption(); - void newVar(); - - //UnElimination - void extendModel(Solver& solver2); - bool unEliminate(const Var var); - - //Get-functions - const vec<char>& getVarElimed() const; - uint32_t getNumElimed() const; - bool checkElimedUnassigned() const; - double getTotalTime() const; - const map<Var, vector<vector<Lit> > >& getElimedOutVar() const; - const map<Var, vector<std::pair<Lit, Lit> > >& getElimedOutVarBin() const; - -private: - - /*bool subsumeWithBinTri(); - bool subsumeWithBinTri( - vec<Clause*>& cls - , bool learnt - , uint32_t& subsumed_bin_num - , uint32_t& subsumed_tri_num - , uint32_t& lit_rem_bin - , uint32_t& lit_rem_tri - );*/ - - friend class ClauseCleaner; - friend class ClauseAllocator; - - //Main - /** - @brief Clauses to be treated are moved here ClauseSimp::index refers to the index of the clause here - */ - vec<ClauseSimp> clauses; - TouchList touchedVars; ///<Is set to true when a variable is part of a removed clause. Also true initially (upon variable creation). - CSet cl_touched; ///<Clauses strengthened/added - vec<vec<ClauseSimp> > occur; ///<occur[index(lit)]' is a list of constraints containing 'lit'. - vec<CSet* > iter_sets; ///<Sets currently used in iterations. - vec<char> cannot_eliminate;///<Variables that cannot be eliminated due to, e.g. XOR-clauses - vec<char> seen_tmp; ///<Used in various places to help perform algorithms - - //Global stats - Solver& solver; ///<The solver this simplifier is connected to - vec<char> var_elimed; ///<Contains TRUE if var has been eliminated - double totalTime; ///<Total time spent in this class - uint32_t numElimed; ///<Total number of variables eliminated - map<Var, vector<vector<Lit> > > elimedOutVar; ///<Contains the clauses to use to uneliminate a variable - map<Var, vector<std::pair<Lit, Lit> > > elimedOutVarBin; ///<Contains the clauses to use to uneliminate a variable - - //Limits - uint64_t addedClauseLits; - uint32_t numVarsElimed; ///<Number of variables elimed in this run - int64_t numMaxSubsume1; ///<Max. number self-subsuming resolution tries to do this run - int64_t numMaxSubsume0; ///<Max. number backward-subsumption tries to do this run - int64_t numMaxElim; ///<Max. number of variable elimination tries to do this run - int32_t numMaxElimVars; - int64_t numMaxBlockToVisit; ///<Max. number variable-blocking clauses to visit to do this run - uint32_t numMaxBlockVars; ///<Max. number variable-blocking tries to do this run - - //Start-up - uint64_t addFromSolver(vec<Clause*>& cs); - void fillCannotEliminate(); - void clearAll(); - void setLimits(); - bool subsume0AndSubsume1(); - vec<char> ol_seenPos; - vec<char> ol_seenNeg; - - //Finish-up - void freeMemory(); - void addBackToSolver(); - void removeWrong(vec<Clause*>& cs); - void removeWrongBinsAndAllTris(); - void removeAssignedVarsFromEliminated(); - - //Iterations - void registerIteration (CSet& iter_set) { iter_sets.push(&iter_set); } - void unregisterIteration(CSet& iter_set) { remove(iter_sets, &iter_set); } - - //Used by cleaner - void unlinkClause(ClauseSimp cc, const Var elim = var_Undef); - ClauseSimp linkInClause(Clause& cl); - - //Findsubsumed - template<class T> - void findSubsumed(const T& ps, const uint32_t abst, vec<ClauseSimp>& out_subsumed); - template<class T> - void findSubsumed1(const T& ps, uint32_t abs, vec<ClauseSimp>& out_subsumed, vec<Lit>& out_lits); - template<class T> - void fillSubs(const T& ps, uint32_t abs, vec<ClauseSimp>& out_subsumed, vec<Lit>& out_lits, const Lit lit); - template<class T2> - bool subset(const uint32_t aSize, const T2& B); - template<class T1, class T2> - Lit subset1(const T1& A, const T2& B); - bool subsetAbst(uint32_t A, uint32_t B); - - //binary clause-subsumption - struct BinSorter { - bool operator()(const Watched& first, const Watched& second) - { - assert(first.isBinary() || first.isTriClause()); - assert(second.isBinary() || second.isTriClause()); - - if (first.isTriClause() && second.isTriClause()) return false; - if (first.isBinary() && second.isTriClause()) return true; - if (second.isBinary() && first.isTriClause()) return false; - - assert(first.isBinary() && second.isBinary()); - if (first.getOtherLit().toInt() < second.getOtherLit().toInt()) return true; - if (first.getOtherLit().toInt() > second.getOtherLit().toInt()) return false; - if (first.getLearnt() == second.getLearnt()) return false; - if (!first.getLearnt()) return true; - return false; - }; - }; - void subsumeBinsWithBins(); - - //subsume0 - struct subsume0Happened { - bool subsumedNonLearnt; - uint32_t glue; - float act; - }; - /** - @brief Sort clauses according to size - */ - struct sortBySize - { - bool operator () (const Clause* x, const Clause* y) - { - return (x->size() < y->size()); - } - }; - void subsume0(Clause& ps); - template<class T> - subsume0Happened subsume0Orig(const T& ps, uint32_t abs); - void subsume0Touched(); - - //subsume1 - class NewBinaryClause - { - public: - NewBinaryClause(const Lit _lit1, const Lit _lit2, const bool _learnt) : - lit1(_lit1), lit2(_lit2), learnt(_learnt) - {}; - - const Lit lit1; - const Lit lit2; - const bool learnt; - }; - list<NewBinaryClause> clBinTouched; ///<Binary clauses strengthened/added - bool handleClBinTouched(); - - void subsume1(Clause& ps); - bool subsume1(vec<Lit>& ps, const bool wasLearnt); - void strenghten(ClauseSimp& c, const Lit toRemoveLit); - bool cleanClause(Clause& ps); - bool cleanClause(vec<Lit>& ps) const; - void handleSize1Clause(const Lit lit); - - /*bool subsWNonExitsBinsFullFull(); - bool subsWNonExistBinsFull(); - bool subsWNonExistBins(const Lit& lit, OnlyNonLearntBins* OnlyNonLearntBins); - uint64_t extraTimeNonExist; - bool subsNonExistentFinish; - vec<Lit> toVisit; - vec<char> toVisitAll;*/ - - //Variable elimination - /** - @brief Struct used to compare variable elimination difficulties - - Used to order variables according to their difficulty of elimination. Used by - the std::sort() function. in \function orderVarsForElim() - */ - struct myComp { - bool operator () (const std::pair<int, Var>& x, const std::pair<int, Var>& y) { - return x.first < y.first; - } - }; - class ClAndBin { - public: - ClAndBin(ClauseSimp& cl) : - clsimp(cl) - , lit1(lit_Undef) - , lit2(lit_Undef) - , isBin(false) - {} - - ClAndBin(const Lit _lit1, const Lit _lit2) : - clsimp(NULL, 0) - , lit1(_lit1) - , lit2(_lit2) - , isBin(true) - {} - - ClauseSimp clsimp; - Lit lit1; - Lit lit2; - bool isBin; - }; - void orderVarsForElim(vec<Var>& order); - uint32_t numNonLearntBins(const Lit lit) const; - bool maybeEliminate(Var x); - void removeClauses(vec<ClAndBin>& posAll, vec<ClAndBin>& negAll, const Var var); - void removeClausesHelper(vec<ClAndBin>& todo, const Var var, std::pair<uint32_t, uint32_t>& removed); - bool merge(const ClAndBin& ps, const ClAndBin& qs, const Lit without_p, const Lit without_q, vec<Lit>& out_clause); - bool eliminateVars(); - void fillClAndBin(vec<ClAndBin>& all, vec<ClauseSimp>& cs, const Lit lit); - - //Subsume with Nonexistent Bins - struct BinSorter2 { - bool operator()(const Watched& first, const Watched& second) - { - assert(first.isBinary() || first.isTriClause()); - assert(second.isBinary() || second.isTriClause()); - - if (first.isTriClause() && second.isTriClause()) return false; - if (first.isBinary() && second.isTriClause()) return true; - if (second.isBinary() && first.isTriClause()) return false; - - assert(first.isBinary() && second.isBinary()); - if (first.getLearnt() && !second.getLearnt()) return true; - if (!first.getLearnt() && second.getLearnt()) return false; - return false; - }; - }; - void subsume0BIN(const Lit lit, const vec<char>& lits, const uint32_t abst); - uint32_t doneNum; - - //Blocked clause elimination - class VarOcc { - public: - VarOcc(const Var& v, const uint32_t num) : - var(v) - , occurnum(num) - {} - Var var; - uint32_t occurnum; - }; - struct MyComp { - bool operator() (const VarOcc& l1, const VarOcc& l2) const { - return l1.occurnum > l2.occurnum; - } - }; - void blockedClauseRemoval(); - template<class T> - bool allTautology(const T& ps, const Lit lit); - uint32_t numblockedClauseRemoved; - bool tryOneSetting(const Lit lit); - priority_queue<VarOcc, vector<VarOcc>, MyComp> touchedBlockedVars; - vec<char> touchedBlockedVarsBool; - void touchBlockedVar(const Var x); - void blockedClauseElimAll(const Lit lit); - - - //validity checking - bool verifyIntegrity(); - - uint32_t clauses_subsumed; ///<Number of clauses subsumed in this run - uint32_t literals_removed; ///<Number of literals removed from clauses through self-subsuming resolution in this run - uint32_t numCalls; ///<Number of times simplifyBySubsumption() has been called - uint32_t clauseID; ///<We need to have clauseIDs since clauses don't natively have them. The ClauseID is stored by ClauseSimp, which also stores a pointer to the clause -}; - -template <class T, class T2> -void maybeRemove(vec<T>& ws, const T2& elem) -{ - if (ws.size() > 0) - removeW(ws, elem); -} - -/** -@brief Put varible in touchedBlockedVars - -call it when the number of occurrences of this variable changed. -*/ -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; - } -} - -/** -@brief Decides only using abstraction if clause A could subsume clause B - -@note: It can give false positives. Never gives false negatives. - -For A to subsume B, everything that is in A MUST be in B. So, if (A & ~B) -contains even one bit, it means that A contains something that B doesn't. So -A may be a subset of B only if (A & ~B) == 0 -*/ -inline bool Subsumer::subsetAbst(const uint32_t A, const uint32_t B) -{ - return !(A & ~B); -} - -//A subsumes B (A is <= B) -template<class T2> -bool Subsumer::subset(const uint32_t aSize, const T2& B) -{ - uint32_t num = 0; - for (uint32_t i = 0; i != B.size(); i++) { - num += seen_tmp[B[i].toInt()]; - } - return num == aSize; -} - - -/** -@brief Decides if A subsumes B, or if not, if A could strenghten B - -@note: Assumes 'seen' is cleared (will leave it cleared) - -Helper function findSubsumed1. Does two things in one go: -1) decides if clause A could subsume clause B -1) decides if clause A could be used to perform self-subsuming resoltuion on -clause B - -@return lit_Error, if neither (1) or (2) is true. Returns lit_Undef (1) is true, -and returns the literal to remove if (2) is true -*/ -template<class T1, class T2> -Lit Subsumer::subset1(const T1& A, const T2& B) -{ - Lit retLit = lit_Undef; - - 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()]) { - if (retLit == lit_Undef && seen_tmp[(~A[i]).toInt()]) - retLit = ~A[i]; - else { - retLit = lit_Error; - goto end; - } - } - } - - end: - for (uint32_t i = 0; i != B.size(); i++) - seen_tmp[B[i].toInt()] = 0; - return retLit; -} - -/** -@brief New var has been added to the solver - -@note: MUST be called if a new var has been added to the solver - -Adds occurrence list places, increments seen_tmp, etc. -*/ -inline void Subsumer::newVar() -{ - occur .push(); - occur .push(); - seen_tmp .push(0); // (one for each polarity) - seen_tmp .push(0); - touchedVars .addOne(solver.nVars()-1); - var_elimed .push(0); - touchedBlockedVarsBool.push(0); - cannot_eliminate.push(0); - ol_seenPos.push(1); - ol_seenPos.push(1); - ol_seenNeg.push(1); - ol_seenNeg.push(1); -} - -inline const map<Var, vector<vector<Lit> > >& Subsumer::getElimedOutVar() const -{ - return elimedOutVar; -} - -inline const map<Var, vector<std::pair<Lit, Lit> > >& Subsumer::getElimedOutVarBin() const -{ - return elimedOutVarBin; -} - -inline const vec<char>& Subsumer::getVarElimed() const -{ - return var_elimed; -} - -inline uint32_t Subsumer::getNumElimed() const -{ - return numElimed; -} - -inline double Subsumer::getTotalTime() const -{ - return totalTime; -} - -} - -#endif //SIMPLIFIER_H diff --git a/src/prop/cryptominisat/Solver/UselessBinRemover.cpp b/src/prop/cryptominisat/Solver/UselessBinRemover.cpp deleted file mode 100644 index 1d848116e..000000000 --- a/src/prop/cryptominisat/Solver/UselessBinRemover.cpp +++ /dev/null @@ -1,228 +0,0 @@ -/*************************************************************************** -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 <iomanip> -#include "UselessBinRemover.h" -#include "VarReplacer.h" -#include "ClauseCleaner.h" -#include "time_mem.h" - -//#define VERBOSE_DEBUG - -using namespace CMSat; - -UselessBinRemover::UselessBinRemover(Solver& _solver) : - solver(_solver) -{ -} - -/** -@brief Time limiting -*/ -#define MAX_REMOVE_BIN_FULL_PROPS 20000000 -/** -@brief We measure time in (bogo)propagations and "extra" time, time not accountable in (bogo)props -*/ -#define EXTRATIME_DIVIDER 3 - -/** -@brief Removes useless binary non-learnt clauses. See definiton of class for details - -We pick variables starting randomly at a place and going on until we stop: -we limit ourselves in time using (bogo)propagations and "extratime" -*/ -bool UselessBinRemover::removeUslessBinFull() -{ - double myTime = cpuTime(); - toDeleteSet.clear(); - toDeleteSet.growTo(solver.nVars()*2, 0); - uint32_t origHeapSize = solver.order_heap.size(); - uint64_t origProps = solver.propagations; - bool fixed = false; - uint32_t extraTime = 0; - uint32_t numBinsBefore = solver.numBins; - solver.sortWatched(); //VERY important - - uint32_t startFrom = solver.mtrand.randInt(solver.order_heap.size()); - for (uint32_t i = 0; i != solver.order_heap.size(); i++) { - Var var = solver.order_heap[(i+startFrom)%solver.order_heap.size()]; - if (solver.propagations - origProps + extraTime > MAX_REMOVE_BIN_FULL_PROPS) break; - if (solver.assigns[var] != l_Undef || !solver.decision_var[var]) continue; - - Lit lit(var, true); - if (!removeUselessBinaries(lit)) { - fixed = true; - solver.cancelUntilLight(); - solver.uncheckedEnqueue(~lit); - solver.ok = (solver.propagate<false>().isNULL()); - if (!solver.ok) return false; - continue; - } - - lit = ~lit; - if (!removeUselessBinaries(lit)) { - fixed = true; - solver.cancelUntilLight(); - solver.uncheckedEnqueue(~lit); - solver.ok = (solver.propagate<false>().isNULL()); - if (!solver.ok) return false; - continue; - } - } - - if (fixed) solver.order_heap.filter(Solver::VarFilter(solver)); - - if (solver.conf.verbosity >= 1) { - std::cout - << "c Removed useless bin:" << std::setw(8) << (numBinsBefore - solver.numBins) - << " fixed: " << std::setw(5) << (origHeapSize - solver.order_heap.size()) - << " props: " << std::fixed << std::setprecision(2) << std::setw(6) << (double)(solver.propagations - origProps)/1000000.0 << "M" - << " time: " << std::fixed << std::setprecision(2) << std::setw(5) << cpuTime() - myTime << " s" - << std::endl; - } - - return true; -} - -/** -@brief Removes useless binaries of the graph portion that starts with lit - -We try binary-space propagation on lit. Then, we check that we cannot reach any -of its one-hop neighboours from any of its other one-hope neighbours. If we can, -we remove the one-hop neighbour from the neightbours (i.e. remove the binary -clause). Example: - -\li a->b, a->c, b->c -\li In claues: (-a V b), (-a V c), (-b V c) - -One-hop neighbours of a: b, c. But c can be reached through b! So, we remove -a->c, the one-hop neighbour that is useless. -*/ -bool UselessBinRemover::removeUselessBinaries(const Lit lit) -{ - solver.newDecisionLevel(); - solver.uncheckedEnqueueLight(lit); - //Propagate only one hop - failed = !solver.propagateBinOneLevel(); - if (failed) return false; - bool ret = true; - - oneHopAway.clear(); - assert(solver.decisionLevel() > 0); - int c; - if (solver.trail.size()-solver.trail_lim[0] == 0) { - solver.cancelUntilLight(); - goto end; - } - //Fill oneHopAway and toDeleteSet with lits that are 1 hop away - extraTime += (solver.trail.size() - solver.trail_lim[0]) / EXTRATIME_DIVIDER; - for (c = solver.trail.size()-1; c > (int)solver.trail_lim[0]; c--) { - Lit x = solver.trail[c]; - toDeleteSet[x.toInt()] = true; - oneHopAway.push(x); - solver.assigns[x.var()] = l_Undef; - } - solver.assigns[solver.trail[c].var()] = l_Undef; - - solver.qhead = solver.trail_lim[0]; - solver.trail.shrink_(solver.trail.size() - solver.trail_lim[0]); - solver.trail_lim.clear(); - //solver.cancelUntil(0); - - wrong.clear(); - //We now try to reach the one-hop-away nodes from other one-hop-away - //nodes, but this time we propagate all the way - for(uint32_t i = 0; i < oneHopAway.size(); i++) { - //no need to visit it if it already queued for removal - //basically, we check if it's in 'wrong' - if (toDeleteSet[oneHopAway[i].toInt()]) { - if (!fillBinImpliesMinusLast(lit, oneHopAway[i], wrong)) { - ret = false; - goto end; - } - } - } - - for (uint32_t i = 0; i < wrong.size(); i++) { - removeBin(~lit, wrong[i]); - } - - end: - for(uint32_t i = 0; i < oneHopAway.size(); i++) { - toDeleteSet[oneHopAway[i].toInt()] = false; - } - - return ret; -} - -/** -@brief Removes a binary clause (lit1 V lit2) - -The binary clause might be in twice, three times, etc. Take care to remove -all instances of it. -*/ -void UselessBinRemover::removeBin(const Lit lit1, const Lit lit2) -{ - #ifdef VERBOSE_DEBUG - std::cout << "Removing useless bin: " << lit1 << " " << lit2 << std::endl; - #endif //VERBOSE_DEBUG - - std::pair<uint32_t, uint32_t> removed1 = removeWBinAll(solver.watches[(~lit1).toInt()], lit2); - std::pair<uint32_t, uint32_t> removed2 = removeWBinAll(solver.watches[(~lit2).toInt()], lit1); - assert(removed1 == removed2); - - assert((removed1.first + removed2.first) % 2 == 0); - assert((removed1.second + removed2.second) % 2 == 0); - solver.learnts_literals -= (removed1.first + removed2.first); - solver.clauses_literals -= (removed1.second + removed2.second); - solver.numBins -= (removed1.first + removed2.first + removed1.second + removed2.second)/2; -} - -/** -@brief Propagates all the way lit, but doesn't propagate origLit - -Removes adds to "wrong" the set of one-hop lits that can be reached from -lit AND are one-hop away from origLit. These later need to be removed -*/ -bool UselessBinRemover::fillBinImpliesMinusLast(const Lit origLit, const Lit lit, vec<Lit>& wrong) -{ - solver.newDecisionLevel(); - solver.uncheckedEnqueueLight(lit); - //if it's a cycle, it doesn't work, so don't propagate origLit - failed = !solver.propagateBinExcept(origLit); - if (failed) return false; - - assert(solver.decisionLevel() > 0); - int c; - extraTime += (solver.trail.size() - solver.trail_lim[0]) / EXTRATIME_DIVIDER; - for (c = solver.trail.size()-1; c > (int)solver.trail_lim[0]; c--) { - Lit x = solver.trail[c]; - if (toDeleteSet[x.toInt()]) { - wrong.push(x); - toDeleteSet[x.toInt()] = false; - }; - solver.assigns[x.var()] = l_Undef; - } - solver.assigns[solver.trail[c].var()] = l_Undef; - - solver.qhead = solver.trail_lim[0]; - solver.trail.shrink_(solver.trail.size() - solver.trail_lim[0]); - solver.trail_lim.clear(); - //solver.cancelUntil(0); - - return true; -} diff --git a/src/prop/cryptominisat/Solver/UselessBinRemover.h b/src/prop/cryptominisat/Solver/UselessBinRemover.h deleted file mode 100644 index 37944b431..000000000 --- a/src/prop/cryptominisat/Solver/UselessBinRemover.h +++ /dev/null @@ -1,85 +0,0 @@ -/*********************************************************************************** -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 USELESSBINREMOVER_H -#define USELESSBINREMOVER_H - -#include "Vec.h" -#include "Solver.h" -#ifdef _MSC_VER -#include <msvc/stdint.h> -#else -#include <stdint.h> -#endif //_MSC_VER - -namespace CMSat { - -/** -@brief Removes binary clauses that are effectively useless to have - -These binary clauses are useless, because for example clauses: -a V b --b V c - -exist, so the binary clause: -a V c - -is useless in every possible way. Here, we remove such claues. Unfortunately, -currently we only remove useless non-learnt binary clauses. Learnt useless -binary clauses are not removed. - -\todo Extend such that it removes learnt useless binary clauses as well -*/ -class UselessBinRemover { - public: - UselessBinRemover(Solver& solver); - bool removeUslessBinFull(); - - private: - bool failed; ///<Has the previous propagation failed? (=conflict) - uint32_t extraTime; ///<Time that cannot be meausured in bogoprops (~propagation time) - - //Remove useless binaries - bool fillBinImpliesMinusLast(const Lit origLit, const Lit lit, vec<Lit>& wrong); - bool removeUselessBinaries(const Lit lit); - void removeBin(const Lit lit1, const Lit lit2); - /** - @brief Don't delete the same binary twice, and don't assume that deleted binaries still exist - - Not deleting the same binary twice is easy to understand. He hard part - is the second thought. Basically, once we set "a->b" to be deleted, for - instance, we should not check whether any one-hop neighbours of "a" can - be reached from "b", since the binary clause leading to "b" has already - been deleted (and, by the way, checked, since the place where we can - reach "b" from already checked for all places we can visit from "b") - */ - vec<char> toDeleteSet; - vec<Lit> oneHopAway; ///<Lits that are one hop away from selected lit (sometimes called origLit) - /** - @brief Binary clauses to be removed are gathered here - - We only gather the second lit, the one we can reach from selected lit - (calld origLit some places) see fillBinImpliesMinusLast() for details - */ - vec<Lit> wrong; - - Solver& solver; ///<The solver class e want to remove useless binary clauses from -}; - -} - -#endif //USELESSBINREMOVER_H diff --git a/src/prop/cryptominisat/Solver/VarReplacer.cpp b/src/prop/cryptominisat/Solver/VarReplacer.cpp deleted file mode 100644 index e89e66c51..000000000 --- a/src/prop/cryptominisat/Solver/VarReplacer.cpp +++ /dev/null @@ -1,731 +0,0 @@ -/***************************************************************************** -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 "VarReplacer.h" -#include <iostream> -#include <iomanip> -#include <set> - -#include "ClauseCleaner.h" -#include "time_mem.h" -#include "DataSync.h" - -//#define VERBOSE_DEBUG -//#define DEBUG_REPLACER -//#define REPLACE_STATISTICS -//#define DEBUG_BIN_REPLACER - -using namespace CMSat; - -VarReplacer::VarReplacer(Solver& _solver) : - replacedLits(0) - , replacedVars(0) - , lastReplacedVars(0) - , solver(_solver) -{ -} - -VarReplacer::~VarReplacer() -{ -} - -/** -@brief Replaces variables, clears internal clauses, and reports stats - -When replacing, it is imperative not to make variables decision variables -which have been removed by other methods: -\li variable removal at the xor-sphere -\li disconnected component finding and solving -\li variable elimination - -NOTE: If any new such algoirhtms are added, this part MUST be updated such -that problems don't creep up -*/ -bool VarReplacer::performReplaceInternal() -{ - #ifdef VERBOSE_DEBUG - cout << "PerformReplacInternal started." << endl; - //solver.printAllClauses(); - #endif - double time = cpuTime(); - - #ifdef REPLACE_STATISTICS - uint32_t numRedir = 0; - for (uint32_t 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; - #endif //REPLACE_STATISTICS - - solver.clauseCleaner->removeAndCleanAll(true); - if (!solver.ok) return false; - solver.testAllClauseAttach(); - std::fill(cannot_eliminate.getData(), cannot_eliminate.getDataEnd(), false); - - #ifdef VERBOSE_DEBUG - { - uint32_t i = 0; - for (vector<Lit>::const_iterator it = table.begin(); it != table.end(); it++, i++) { - if (it->var() == i) continue; - cout << "Replacing var " << i+1 << " with Lit " << *it << endl; - } - } - #endif - - Var var = 0; - const vec<char>& removedVars = solver.xorSubsumer->getVarElimed(); - 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()] - || removedVars3[it->var()] - ) continue; - #ifdef VERBOSE_DEBUG - cout << "Setting var " << var+1 << " to a non-decision var" << endl; - #endif - bool wasDecisionVar = solver.decision_var[var]; - solver.setDecisionVar(var, false); - //cannot_eliminate[var] = true; - solver.setDecisionVar(it->var(), true); - assert(!removedVars[var]); - assert(!removedVars3[var]); - - uint32_t& activity1 = solver.activity[var]; - uint32_t& activity2 = solver.activity[it->var()]; - if (wasDecisionVar && activity1 > activity2) { - activity2 = activity1; - solver.order_heap.update(it->var()); - solver.polarity[it->var()] = ((bool)solver.polarity[var]) ^ it->sign(); - } - - activity1 = 0.0; - solver.order_heap.update(var); - } - assert(solver.order_heap.heapProperty()); - - uint32_t thisTimeReplaced = replacedVars -lastReplacedVars; - lastReplacedVars = replacedVars; - - solver.testAllClauseAttach(); - assert(solver.qhead == solver.trail.size()); - - solver.countNumBinClauses(true, false); - solver.countNumBinClauses(false, true); - - if (!replaceBins()) goto end; - if (!replace_set(solver.clauses)) goto end; - if (!replace_set(solver.learnts)) goto end; - if (!replace_set(solver.xorclauses)) goto end; - solver.testAllClauseAttach(); - -end: - assert(solver.qhead == solver.trail.size() || !solver.ok); - - if (solver.conf.verbosity >= 3) { - std::cout << "c Replacing " - << std::setw(8) << thisTimeReplaced << " vars" - << " Replaced " << std::setw(8) << replacedLits<< " lits" - << " Time: " << std::setw(8) << std::fixed << std::setprecision(2) - << cpuTime()-time << " s " - << std::endl; - } - - replacedLits = 0; - - solver.order_heap.filter(Solver::VarFilter(solver)); - - return solver.ok; -} - -/** -@brief Replaces vars in xorclauses -*/ -bool VarReplacer::replace_set(vec<XorClause*>& cs) -{ - XorClause **a = cs.getData(); - XorClause **r = a; - for (XorClause **end = a + cs.size(); r != end; r++) { - XorClause& c = **r; - - bool changed = false; - Var origVar1 = c[0].var(); - Var origVar2 = c[1].var(); - - for (Lit *l = &c[0], *end2 = l + c.size(); l != end2; l++) { - Lit newlit = table[l->var()]; - if (newlit.var() != l->var()) { - changed = true; - *l = Lit(newlit.var(), false); - c.invert(newlit.sign()); - replacedLits++; - } - } - - if (changed && handleUpdatedClause(c, origVar1, origVar2)) { - if (!solver.ok) { - #ifdef VERBOSE_DEBUG - cout << "contradiction while replacing lits in xor clause" << std::endl; - #endif - for(;r != end; r++) solver.clauseAllocator.clauseFree(*r); - cs.shrink(r-a); - return false; - } - //solver.clauseAllocator.clauseFree(&c); - c.setRemoved(); - solver.freeLater.push(&c); - } else { - #ifdef SILENT_DEBUG - uint32_t numUndef = 0; - for (uint32_t i = 0; i < c.size(); i++) { - if (solver.value(c[i]) == l_Undef) numUndef++; - } - assert(numUndef >= 2 || numUndef == 0); - #endif - *a++ = *r; - } - } - cs.shrink(r-a); - - return solver.ok; -} - -/** -@brief Helper function for replace_set() -*/ -bool VarReplacer::handleUpdatedClause(XorClause& c, const Var origVar1, const Var origVar2) -{ - uint32_t origSize = c.size(); - std::sort(c.getData(), c.getDataEnd()); - Lit p; - uint32_t i, j; - for (i = j = 0, p = lit_Undef; i != c.size(); i++) { - if (c[i].var() == p.var()) { - //added, but easily removed - j--; - p = lit_Undef; - if (!solver.assigns[c[i].var()].isUndef()) - c.invert(solver.assigns[c[i].var()].getBool()); - } else if (solver.assigns[c[i].var()].isUndef()) //just add - c[j++] = p = c[i]; - else c.invert(solver.assigns[c[i].var()].getBool()); //modify xorEqualFalse instead of adding - } - c.shrink(i - j); - - //Even if i==j, the clause *has* changed - c.setChanged(); - - #ifdef VERBOSE_DEBUG - cout << "xor-clause after replacing: "; - c.plainPrint(); - #endif - - switch (c.size()) { - case 0: - solver.detachModifiedClause(origVar1, origVar2, origSize, &c); - if (!c.xorEqualFalse()) { - solver.ok = false; - } - return true; - case 1: - solver.detachModifiedClause(origVar1, origVar2, origSize, &c); - solver.uncheckedEnqueue(Lit(c[0].var(), c.xorEqualFalse())); - solver.ok = (solver.propagate<false>().isNULL()); - return true; - case 2: { - solver.detachModifiedClause(origVar1, origVar2, origSize, &c); - c[0] = c[0].unsign() ^ c.xorEqualFalse(); - c[1] = c[1].unsign(); - addBinaryXorClause(c[0], c[1]); - return true; - } - default: - solver.detachModifiedClause(origVar1, origVar2, origSize, &c); - solver.attachClause(c); - return false; - } - - assert(false); - return false; -} - -bool VarReplacer::replaceBins() -{ - #ifdef DEBUG_BIN_REPLACER - vec<uint32_t> removed(solver.nVars()*2, 0); - uint32_t replacedLitsBefore = replacedLits; - #endif - - uint32_t removedLearnt = 0; - uint32_t removedNonLearnt = 0; - uint32_t wsLit = 0; - for (vec<Watched> *it = solver.watches.getData(), *end = solver.watches.getDataEnd(); it != end; it++, wsLit++) { - Lit lit1 = ~Lit::toLit(wsLit); - vec<Watched>& ws = *it; - - vec<Watched>::iterator i = ws.getData(); - vec<Watched>::iterator j = i; - for (vec<Watched>::iterator end2 = ws.getDataEnd(); i != end2; i++) { - if (!i->isBinary()) { - *j++ = *i; - continue; - } - //std::cout << "bin: " << lit1 << " , " << i->getOtherLit() << " learnt : " << (i->isLearnt()) << std::endl; - Lit thisLit1 = lit1; - Lit lit2 = i->getOtherLit(); - assert(thisLit1.var() != lit2.var()); - - if (table[lit2.var()].var() != lit2.var()) { - lit2 = table[lit2.var()] ^ lit2.sign(); - i->setOtherLit(lit2); - replacedLits++; - } - - bool changedMain = false; - if (table[thisLit1.var()].var() != thisLit1.var()) { - thisLit1 = table[thisLit1.var()] ^ thisLit1.sign(); - replacedLits++; - changedMain = true; - } - - if (thisLit1 == lit2) { - if (solver.value(lit2) == l_Undef) { - solver.uncheckedEnqueue(lit2); - } else if (solver.value(lit2) == l_False) { - #ifdef VERBOSE_DEBUG - std::cout << "Contradiction during replacement of lits in binary clause" << std::endl; - #endif - solver.ok = false; - } - #ifdef DEBUG_BIN_REPLACER - removed[lit1.toInt()]++; - removed[origLit2.toInt()]++; - #endif - - if (i->getLearnt()) removedLearnt++; - else removedNonLearnt++; - continue; - } - - if (thisLit1 == ~lit2) { - #ifdef DEBUG_BIN_REPLACER - removed[lit1.toInt()]++; - removed[origLit2.toInt()]++; - #endif - - if (i->getLearnt()) removedLearnt++; - else removedNonLearnt++; - continue; - } - - if (changedMain) { - solver.watches[(~thisLit1).toInt()].push(*i); - } else { - *j++ = *i; - } - } - ws.shrink_(i-j); - } - - #ifdef DEBUG_BIN_REPLACER - for (uint32_t i = 0; i < removed.size(); i++) { - if (removed[i] % 2 != 0) { - std::cout << "suspicious: " << Lit::toLit(i) << std::endl; - std::cout << "num: " << removed[i] << std::endl; - } - } - std::cout << "replacedLitsdiff: " << replacedLits - replacedLitsBefore << std::endl; - std::cout << "removedLearnt: " << removedLearnt << std::endl; - std::cout << "removedNonLearnt: " << removedNonLearnt << std::endl; - #endif - - assert(removedLearnt % 2 == 0); - assert(removedNonLearnt % 2 == 0); - solver.learnts_literals -= removedLearnt; - solver.clauses_literals -= removedNonLearnt; - solver.numBins -= (removedLearnt + removedNonLearnt)/2; - - if (solver.ok) solver.ok = (solver.propagate<false>().isNULL()); - return solver.ok; -} - -/** -@brief Replaces variables in normal clauses -*/ -bool VarReplacer::replace_set(vec<Clause*>& cs) -{ - Clause **a = cs.getData(); - Clause **r = a; - for (Clause **end = a + cs.size(); r != end; r++) { - Clause& c = **r; - assert(c.size() > 2); - bool changed = false; - Lit origLit1 = c[0]; - Lit origLit2 = c[1]; - Lit origLit3 = (c.size() == 3) ? c[2] : lit_Undef; - for (Lit *l = c.getData(), *end2 = l + c.size(); l != end2; l++) { - if (table[l->var()].var() != l->var()) { - changed = true; - *l = table[l->var()] ^ l->sign(); - replacedLits++; - } - } - - if (changed && handleUpdatedClause(c, origLit1, origLit2, origLit3)) { - if (!solver.ok) { - #ifdef VERBOSE_DEBUG - cout << "contradiction while replacing lits in normal clause" << std::endl; - #endif - for(;r != end; r++) solver.clauseAllocator.clauseFree(*r); - cs.shrink(r-a); - return false; - } - } else { - *a++ = *r; - } - } - cs.shrink(r-a); - - return solver.ok; -} - -/** -@brief Helper function for replace_set() -*/ -bool VarReplacer::handleUpdatedClause(Clause& c, const Lit origLit1, const Lit origLit2, const Lit origLit3) -{ - bool satisfied = false; - std::sort(c.getData(), c.getData() + c.size()); - Lit p; - uint32_t i, j; - const uint32_t origSize = c.size(); - for (i = j = 0, p = lit_Undef; i != origSize; i++) { - if (solver.value(c[i]) == l_True || c[i] == ~p) { - satisfied = true; - break; - } - else if (solver.value(c[i]) != l_False && c[i] != p) - c[j++] = p = c[i]; - } - c.shrink(i - j); - c.setChanged(); - - solver.detachModifiedClause(origLit1, origLit2, origLit3, origSize, &c); - - #ifdef VERBOSE_DEBUG - cout << "clause after replacing: "; - c.plainPrint(); - #endif - - if (satisfied) return true; - - switch(c.size()) { - case 0: - solver.ok = false; - return true; - case 1 : - solver.uncheckedEnqueue(c[0]); - solver.ok = (solver.propagate<false>().isNULL()); - return true; - case 2: - solver.attachBinClause(c[0], c[1], c.learnt()); - solver.numNewBin++; - solver.dataSync->signalNewBinClause(c); - return true; - default: - solver.attachClause(c); - return false; - } - - assert(false); - return false; -} - -/** -@brief Returns variables that have been replaced -*/ -vector<Var> VarReplacer::getReplacingVars() const -{ - vector<Var> replacingVars; - - for(map<Var, vector<Var> >::const_iterator it = reverseTable.begin(), end = reverseTable.end(); it != end; it++) { - replacingVars.push_back(it->first); - } - - return replacingVars; -} - -/** -@brief Given a partial model, it tries to extend it to variables that have been replaced - -Cannot extend it fully, because it might be that a replaced d&f, but a was -later variable-eliminated. That's where extendModelImpossible() comes in -*/ -void VarReplacer::extendModelPossible() const -{ - #ifdef VERBOSE_DEBUG - std::cout << "extendModelPossible() called" << std::endl; - #endif //VERBOSE_DEBUG - uint32_t 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 "; solver.printLit(Lit(i, false)); - cout << " to "; solver.printLit(*it); - cout << endl; - #endif - - 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<false>().isNULL()); - assert(solver.ok); - } -} - -/** -@brief Used when a variable was eliminated, but it replaced some other variables - -This function will add to solver2 clauses that represent the relationship of -the variables to their replaced cousins. Then, calling solver2.solve() should -take care of everything -*/ -void VarReplacer::extendModelImpossible(Solver& solver2) const -{ - - #ifdef VERBOSE_DEBUG - std::cout << "extendModelImpossible() called" << std::endl; - #endif //VERBOSE_DEBUG - - vec<Lit> tmpClause; - uint32_t 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); - } - } -} - -/** -@brief Replaces two two vars in "ps" with one another. xorEqualFalse defines anti/equivalence - -It can be tricky to do this. For example, if: - -\li a replaces: b, c -\li f replaces: f, h -\li we just realised that c = h -This is the most difficult case, but there are other cases, e.g. if we already -know that c=h, in which case we don't do anything - -@p ps must contain 2 variables(!), i.e literals with no sign -@p xorEqualFalse if True, the two variables are equivalent. Otherwise, they are antivalent -@p group of clause they have been inspired from. Sometimes makes no sense... -*/ -template<class T> -bool VarReplacer::replace(T& ps, const bool xorEqualFalse, const bool addBinAsLearnt, const bool addToWatchLists) -{ - #ifdef VERBOSE_DEBUG - std::cout << "replace() called with var " << ps[0].var()+1 << " and var " << ps[1].var()+1 << " with xorEqualFalse " << xorEqualFalse << std::endl; - #endif - - assert(solver.decisionLevel() == 0); - assert(ps.size() == 2); - assert(!ps[0].sign()); - assert(!ps[1].sign()); - #ifdef DEBUG_REPLACER - assert(solver.assigns[ps[0].var()].isUndef()); - assert(solver.assigns[ps[1].var()].isUndef()); - - assert(!solver.subsumer->getVarElimed()[ps[0].var()]); - assert(!solver.xorSubsumer->getVarElimed()[ps[0].var()]); - - assert(!solver.subsumer->getVarElimed()[ps[1].var()]); - assert(!solver.xorSubsumer->getVarElimed()[ps[1].var()]); - #endif - - //Detect circle - Lit lit1 = ps[0]; - lit1 = table[lit1.var()]; - Lit lit2 = ps[1]; - lit2 = table[lit2.var()] ^ !xorEqualFalse; - - //Already inside? - if (lit1.var() == lit2.var()) { - if (lit1.sign() != lit2.sign()) { - solver.ok = false; - return false; - } - return true; - } - - #ifdef DEBUG_REPLACER - assert(!solver.subsumer->getVarElimed()[lit1.var()]); - assert(!solver.xorSubsumer->getVarElimed()[lit1.var()]); - assert(!solver.subsumer->getVarElimed()[lit2.var()]); - assert(!solver.xorSubsumer->getVarElimed()[lit2.var()]); - #endif - - cannot_eliminate[lit1.var()] = true; - cannot_eliminate[lit2.var()] = true; - lbool val1 = solver.value(lit1); - lbool val2 = solver.value(lit2); - if (val1 != l_Undef && val2 != l_Undef) { - if (val1 != val2) { - solver.ok = false; - return false; - } - return true; - } - - if ((val1 != l_Undef && val2 == l_Undef) || (val2 != l_Undef && val1 == l_Undef)) { - //exactly one l_Undef, exectly one l_True/l_False - if (val1 != l_Undef) solver.uncheckedEnqueue(lit2 ^ (val1 == l_False)); - else solver.uncheckedEnqueue(lit1 ^ (val2 == l_False)); - - if (solver.ok) solver.ok = (solver.propagate<false>().isNULL()); - return solver.ok; - } - - #ifdef DEBUG_REPLACER - assert(val1 == l_Undef && val2 == l_Undef); - #endif //DEBUG_REPLACER - - if (addToWatchLists) - addBinaryXorClause(lit1, lit2 ^ true, addBinAsLearnt); - - if (reverseTable.find(lit1.var()) == reverseTable.end()) { - reverseTable[lit2.var()].push_back(lit1.var()); - table[lit1.var()] = lit2 ^ lit1.sign(); - replacedVars++; - return true; - } - - if (reverseTable.find(lit2.var()) == reverseTable.end()) { - reverseTable[lit1.var()].push_back(lit2.var()); - table[lit2.var()] = lit1 ^ lit2.sign(); - replacedVars++; - return true; - } - - //both have children - setAllThatPointsHereTo(lit1.var(), lit2 ^ lit1.sign()); //erases reverseTable[lit1.var()] - replacedVars++; - return true; -} - -template bool VarReplacer::replace(vec<Lit>& ps, const bool xorEqualFalse, const bool addBinAsLearnt, const bool addToWatchLists); -template bool VarReplacer::replace(XorClause& ps, const bool xorEqualFalse, const bool addBinAsLearnt, const bool addToWatchLists); - -/** -@brief Adds a binary xor to the internal/external clause set - -It is added externally ONLY if we are in the middle of replacing clauses, -and a new binary xor just came up. That is a very strange and unfortunate -experience, as we cannot change the datastructures in the middle of replacement -so we add this to the binary clauses of Solver, and we recover it next time. - -\todo Clean this messy internal/external thing using a better datastructure. -*/ -void VarReplacer::addBinaryXorClause(Lit lit1, Lit lit2, const bool addBinAsLearnt) -{ - solver.attachBinClause(lit1, lit2, addBinAsLearnt); - solver.dataSync->signalNewBinClause(lit1, lit2); - - lit1 ^= true; - lit2 ^= true; - solver.attachBinClause(lit1, lit2, addBinAsLearnt); - solver.dataSync->signalNewBinClause(lit1, lit2); -} - -/** -@brief Returns if we already know that var = lit - -Also checks if var = ~lit, in which it sets solver.ok = false -*/ -bool VarReplacer::alreadyIn(const Var var, const Lit lit) -{ - Lit lit2 = table[var]; - if (lit2.var() == lit.var()) { - if (lit2.sign() != lit.sign()) { - #ifdef VERBOSE_DEBUG - cout << "Inverted cycle in var-replacement -> UNSAT" << endl; - #endif - solver.ok = false; - } - return true; - } - - lit2 = table[lit.var()]; - if (lit2.var() == var) { - if (lit2.sign() != lit.sign()) { - #ifdef VERBOSE_DEBUG - cout << "Inverted cycle in var-replacement -> UNSAT" << endl; - #endif - solver.ok = false; - } - return true; - } - - return false; -} - -/** -@brief Changes internal graph to set everything that pointed to var to point to lit -*/ -void VarReplacer::setAllThatPointsHereTo(const Var var, const Lit lit) -{ - map<Var, vector<Var> >::iterator it = reverseTable.find(var); - 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); - } - table[var] = lit; - reverseTable[lit.var()].push_back(var); -} - -void VarReplacer::newVar() -{ - table.push_back(Lit(table.size(), false)); - cannot_eliminate.push(false); -} diff --git a/src/prop/cryptominisat/Solver/VarReplacer.h b/src/prop/cryptominisat/Solver/VarReplacer.h deleted file mode 100644 index db79aa3fe..000000000 --- a/src/prop/cryptominisat/Solver/VarReplacer.h +++ /dev/null @@ -1,153 +0,0 @@ -/*********************************************************************************** -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 VARREPLACER_H -#define VARREPLACER_H - -#ifdef _MSC_VER -#include <msvc/stdint.h> -#else -#include <stdint.h> -#endif //_MSC_VER - -#include <map> -#include <vector> - -#include "Solver.h" -#include "SolverTypes.h" -#include "Clause.h" -#include "Vec.h" - -namespace CMSat { - -using std::map; -using std::vector; - -/** -@brief Replaces variables with their anti/equivalents -*/ -class VarReplacer -{ - public: - VarReplacer(Solver& solver); - ~VarReplacer(); - bool performReplace(const bool always = false); - bool needsReplace(); - template<class T> - bool replace(T& ps, const bool xorEqualFalse, const bool addBinAsLearnt = false, const bool addToWatchLists = true); - - void extendModelPossible() const; - void extendModelImpossible(Solver& solver2) const; - - uint32_t getNumReplacedLits() const; - uint32_t getNumReplacedVars() const; - uint32_t getNumLastReplacedVars() const; - uint32_t getNewToReplaceVars() const; - uint32_t getNumTrees() const; - vector<Var> getReplacingVars() const; - const vector<Lit>& getReplaceTable() const; - bool varHasBeenReplaced(const Var var) const; - bool replacingVar(const Var var) const; - void newVar(); - - vec<char> cannot_eliminate; - - //No need to update, only stores binary clauses, that - //have been allocated within pool - //friend class ClauseAllocator; - - private: - bool performReplaceInternal(); - - bool replace_set(vec<Clause*>& cs); - bool replaceBins(); - bool replace_set(vec<XorClause*>& cs); - bool handleUpdatedClause(Clause& c, const Lit origLit1, const Lit origLit2, const Lit origLit3); - bool handleUpdatedClause(XorClause& c, const Var origVar1, const Var origVar2); - void addBinaryXorClause(Lit lit1, Lit lit2, const bool addBinAsLearnt = false); - - void setAllThatPointsHereTo(const Var var, const Lit lit); - bool alreadyIn(const Var var, const Lit lit); - - vector<Lit> table; ///<Stores which variables have been replaced by which literals. Index by: table[VAR] - map<Var, vector<Var> > reverseTable; ///<mapping of variable to set of variables it replaces - - uint32_t replacedLits; ///<Num literals replaced during var-replacement - uint32_t replacedVars; ///<Num vars replaced during var-replacement - uint32_t lastReplacedVars; ///<Last time performReplace() was called, "replacedVars" contained this - Solver& solver; ///<The solver we are working with -}; - -inline 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 bool VarReplacer::needsReplace() -{ - uint32_t limit = (uint32_t)((double)solver.order_heap.size()*PERCENTAGEPERFORMREPLACE); - return (getNewToReplaceVars() > limit); -} - -inline uint32_t VarReplacer::getNumReplacedLits() const -{ - return replacedLits; -} - -inline uint32_t VarReplacer::getNumReplacedVars() const -{ - return replacedVars; -} - -inline uint32_t VarReplacer::getNumLastReplacedVars() const -{ - return lastReplacedVars; -} - -inline uint32_t VarReplacer::getNewToReplaceVars() const -{ - return replacedVars-lastReplacedVars; -} - -inline const vector<Lit>& VarReplacer::getReplaceTable() const -{ - return table; -} - -inline bool VarReplacer::varHasBeenReplaced(const Var var) const -{ - return table[var].var() != var; -} - -inline bool VarReplacer::replacingVar(const Var var) const -{ - return (reverseTable.find(var) != reverseTable.end()); -} - -inline uint32_t VarReplacer::getNumTrees() const -{ - return reverseTable.size(); -} - -} - -#endif //VARREPLACER_H diff --git a/src/prop/cryptominisat/Solver/Watched.h b/src/prop/cryptominisat/Solver/Watched.h deleted file mode 100644 index 72075b56a..000000000 --- a/src/prop/cryptominisat/Solver/Watched.h +++ /dev/null @@ -1,278 +0,0 @@ -/*************************************************************************** -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 WATCHED_H -#define WATCHED_H - -#ifdef _MSC_VER -#include <msvc/stdint.h> -#else -#include <stdint.h> -#endif //_MSC_VER - -//#define DEBUG_WATCHED - -#include "ClauseOffset.h" -#include "SolverTypes.h" -#include <stdio.h> -#include <limits> -#include "constants.h" - -namespace CMSat { - -/** -@brief An element in the watchlist. Natively contains 2- and 3-long clauses, others are referenced by pointer - -This class contains two 32-bit datapieces. They are either used as: -\li One literal, in the case of binary clauses -\li Two literals, in the case of tertiary clauses -\li One blocking literal (i.e. an example literal from the clause) and a clause -offset (as per ClauseAllocator ), in the case of normal clauses -\li A clause offset (as per ClauseAllocator) for xor clauses -*/ -class Watched { - public: - /** - @brief Constructor for a long normal clause - */ - Watched(const ClauseOffset offset, Lit blockedLit) - { - data1 = blockedLit.toInt(); - data2 = (uint32_t)1 + ((uint32_t)offset << 2); - } - - Watched() : - data1 (std::numeric_limits<uint32_t>::max()) - , data2(std::numeric_limits<uint32_t>::max()) - {} - - /** - @brief Constructor for an xor-clause - */ - Watched(const ClauseOffset offset) - { - data1 = (uint32_t)offset; - data2 = (uint32_t)2; - } - - /** - @brief Constructor for a binary clause - */ - Watched(const Lit lit, const bool learnt) - { - data1 = lit.toInt(); - data2 = (uint32_t)0 + (((uint32_t)learnt) << 2); - } - - /** - @brief Constructor for a 3-long, non-xor clause - */ - Watched(const Lit lit1, const Lit lit2) - { - data1 = lit1.toInt(); - data2 = (uint32_t)3 + (lit2.toInt()<< 2); - } - - void setNormOffset(const ClauseOffset offset) - { - #ifdef DEBUG_WATCHED - assert(isClause()); - #endif - data2 = (uint32_t)1 + ((uint32_t)offset << 2); - } - - void setXorOffset(const ClauseOffset offset) - { - #ifdef DEBUG_WATCHED - assert(isXorClause()); - #endif - data1 = (uint32_t)offset; - } - - /** - @brief To update the example literal (blocked literal) of a >3-long normal clause - */ - void setBlockedLit(const Lit lit) - { - #ifdef DEBUG_WATCHED - assert(isClause()); - #endif - data1 = lit.toInt(); - } - - bool isBinary() const - { - return ((data2&3) == 0); - } - - bool isNonLearntBinary() const - { - return (data2 == 0); - } - - bool isClause() const - { - return ((data2&3) == 1); - } - - bool isXorClause() const - { - return ((data2&3) == 2); - } - - bool isTriClause() const - { - return ((data2&3) == 3); - } - - /** - @brief Get the sole other lit of the binary clause, or get lit2 of the tertiary clause - */ - Lit getOtherLit() const - { - #ifdef DEBUG_WATCHED - assert(isBinary() || isTriClause()); - #endif - return data1AsLit(); - } - - /** - @brief Set the sole other lit of the binary clause - */ - void setOtherLit(const Lit lit) - { - #ifdef DEBUG_WATCHED - assert(isBinary() || isTriClause()); - #endif - data1 = lit.toInt(); - } - - bool getLearnt() const - { - #ifdef DEBUG_WATCHED - assert(isBinary()); - #endif - return (bool)(data2 >> 2); - } - - void setLearnt(const bool learnt) - { - #ifdef DEBUG_WATCHED - assert(isBinary()); - assert(learnt == false); - #endif - data2 = (uint32_t)0 + (((uint32_t)learnt) << 2); - } - - /** - @brief Get the 3rd literal of a 3-long clause - */ - Lit getOtherLit2() const - { - #ifdef DEBUG_WATCHED - assert(isTriClause()); - #endif - return data2AsLit(); - } - - /** - @brief Get example literal (blocked lit) of a normal >3-long clause - */ - Lit getBlockedLit() const - { - #ifdef DEBUG_WATCHED - assert(isClause()); - #endif - return data1AsLit(); - } - - /** - @brief Get offset of a >3-long normal clause or of an xor clause (which may be 3-long) - */ - ClauseOffset getNormOffset() const - { - #ifdef DEBUG_WATCHED - assert(isClause()); - #endif - return (ClauseOffset)(data2 >> 2); - } - - ClauseOffset getXorOffset() const - { - #ifdef DEBUG_WATCHED - assert(isXorClause()); - #endif - return (ClauseOffset)(data1); - } - - void dump(FILE* outfile, const Lit lit) const - { - assert(isBinary()); - lit.print(outfile); - getOtherLit().printFull(outfile); - } - - void setNormClause() - { - data2 = 1; - } - - #ifdef DUMP_STATS_FULL - int glue; - #endif - - private: - Lit data1AsLit() const - { - return (Lit::toLit(data1)); - } - - Lit data2AsLit() const - { - return (Lit::toLit(data2>>2)); - } - - uint32_t data1; - uint32_t data2; -}; - -/** -@brief Orders the watchlists such that the order is binary, tertiary, normal, xor -*/ -struct WatchedSorter -{ - bool operator () (const Watched& x, const Watched& y); -}; - -inline bool WatchedSorter::operator () (const Watched& x, const Watched& y) -{ - if (y.isBinary()) return false; - //y is not binary, but x is, so x must be first - if (x.isBinary()) return true; - - //from now on, none is binary. - if (y.isTriClause()) return false; - if (x.isTriClause()) return true; - - //from now on, none is binary or tertiary - //don't bother sorting these - return false; -} - -} - -#endif //WATCHED_H diff --git a/src/prop/cryptominisat/Solver/XSet.h b/src/prop/cryptominisat/Solver/XSet.h deleted file mode 100644 index ab1cd00d1..000000000 --- a/src/prop/cryptominisat/Solver/XSet.h +++ /dev/null @@ -1,134 +0,0 @@ -/************************************************************************************************** -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 CMSat { - -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++; - } - - 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()); - } -}; - -#endif //XSET_H - -} diff --git a/src/prop/cryptominisat/Solver/XorFinder.cpp b/src/prop/cryptominisat/Solver/XorFinder.cpp deleted file mode 100644 index 1b82430e9..000000000 --- a/src/prop/cryptominisat/Solver/XorFinder.cpp +++ /dev/null @@ -1,462 +0,0 @@ -/*********************************************************************************** -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 "XorFinder.h" - -#include <algorithm> -#include <utility> -#include <iostream> -#include "Solver.h" -#include "VarReplacer.h" -#include "ClauseCleaner.h" -#include "time_mem.h" - -//#define VERBOSE_DEBUG - -using namespace CMSat; -using std::make_pair; - -XorFinder::XorFinder(Solver& _solver, vec<Clause*>& _cls) : - cls(_cls) - , solver(_solver) -{ -} - -bool XorFinder::fullFindXors(const uint32_t minSize, const uint32_t maxSize) -{ - uint32_t sumLengths = 0; - double time = cpuTime(); - foundXors = 0; - solver.clauseCleaner->cleanClauses(solver.clauses, ClauseCleaner::clauses); - if (!solver.ok) return false; - - toRemove.clear(); - toRemove.resize(cls.size(), false); - toLeaveInPlace.clear(); - toLeaveInPlace.resize(cls.size(), false); - - table.clear(); - table.reserve(cls.size()); - - for (Clause **it = cls.getData(), **end = cls.getDataEnd(); it != end; it ++) { - if (it+1 != end) __builtin_prefetch(*(it+1)); - Clause& c = (**it); - assert((*it)->size() > 2); - bool sorted = true; - for (uint32_t i = 0, size = c.size(); i+1 < size ; i++) { - sorted = (c[i].var() <= c[i+1].var()); - if (!sorted) break; - } - if (!sorted) { - solver.detachClause(c); - std::sort(c.getData(), c.getDataEnd()); - solver.attachClause(c); - } - } - - uint32_t i = 0; - for (Clause **it = cls.getData(), **end = cls.getDataEnd(); it != end; it++, i++) { - const uint32_t size = (*it)->size(); - if ( size > maxSize || size < minSize) { - toLeaveInPlace[i] = true; - continue; - } - table.push_back(make_pair(*it, i)); - } - std::sort(table.begin(), table.end(), clause_sorter_primary()); - - if (!findXors(sumLengths)) goto end; - solver.ok = (solver.propagate<true>().isNULL()); - -end: - - if (solver.conf.verbosity >= 1 || (solver.conf.verbosity >= 1 && foundXors > 0)) { - printf("c Finding non-binary XORs: %5.2f s (found: %7d, avg size: %3.1f)\n", cpuTime()-time, foundXors, (double)sumLengths/(double)foundXors); - } - - i = 0; - uint32_t j = 0; - uint32_t toSkip = 0; - for (uint32_t end = cls.size(); i != end; i++) { - if (toLeaveInPlace[i]) { - cls[j] = cls[i]; - j++; - toSkip++; - continue; - } - if (!toRemove[table[i-toSkip].second]) { - cls[j] = table[i-toSkip].first; - j++; - } - } - cls.shrink(i-j); - - return solver.ok; -} - - -/** -@brief Finds xors in clauseTable -- datastructures must already be set up - -Identifies sets of clauses of the same length and variable content, and then -tries to merge them into an XOR. -*/ -bool XorFinder::findXors(uint32_t& sumLengths) -{ - #ifdef VERBOSE_DEBUG - cout << "Finding Xors started" << endl; - #endif - - sumLengths = 0; - - ClauseTable::iterator begin = table.begin(); - ClauseTable::iterator end = table.begin(); - vec<Lit> lits; - bool impair; - while (getNextXor(begin, end, impair)) { - const Clause& c = *(begin->first); - lits.clear(); - for (const Lit *it = &c[0], *cend = it+c.size() ; it != cend; it++) { - lits.push(Lit(it->var(), false)); - } - - #ifdef VERBOSE_DEBUG - cout << "- Found clauses:" << endl; - #endif - - for (ClauseTable::iterator it = begin; it != end; it++) { - //This clause belongs to the xor we found? - //(i.e. does it have the correct number of inverted literals?) - if (impairSigns(*it->first) == impair){ - #ifdef VERBOSE_DEBUG - it->first->plainPrint(); - #endif - toRemove[it->second] = true; - solver.removeClause(*it->first); - } - } - - assert(lits.size() > 2); - XorClause* x = solver.addXorClauseInt(lits, impair); - if (x != NULL) solver.xorclauses.push(x); - if (!solver.ok) return false; - - #ifdef VERBOSE_DEBUG - cout << "- Final xor-clause: " << x << std::endl;; - #endif - - foundXors++; - sumLengths += lits.size(); - } - - return solver.ok; -} - -/** -@brief Moves to the next set of begin&end pointers that contain an xor - -@p begin[inout] start searching here in XorFinder::table -@p end[inout] end iterator of XorFinder::table until which the xor spans -*/ -bool XorFinder::getNextXor(ClauseTable::iterator& begin, ClauseTable::iterator& end, bool& impair) -{ - ClauseTable::iterator tableEnd = table.end(); - - while(begin != tableEnd && end != tableEnd) { - begin = end; - end++; - uint32_t size = (end == tableEnd ? 0:1); - while(end != tableEnd && clause_vareq(begin->first, end->first)) { - size++; - end++; - } - if (size > 0 && isXor(size, begin, end, impair)) - return true; - } - - return false; -} - -/** -@brief Returns if the two clauses are equal - -NOTE: assumes that the clauses are of equal lenght AND contain the same -variables (but the invertedness of the literals might differ) -*/ -bool XorFinder::clauseEqual(const Clause& c1, const Clause& c2) const -{ - assert(c1.size() == c2.size()); - for (uint32_t i = 0, size = c1.size(); i < size; i++) - if (c1[i].sign() != c2[i].sign()) return false; - - return true; -} - -/** -@brief Returns whether the number of inverted literals in the clause is pair or impair -*/ -bool XorFinder::impairSigns(const Clause& c) const -{ - uint32_t num = 0; - for (const Lit *it = &c[0], *end = it + c.size(); it != end; it++) - num += it->sign(); - - return num % 2; -} - -/** -@brief Gets as input a set of clauses of equal size and variable content, decides if there is an XOR in them - -@param impair If there is an XOR, this tells if that XOR contains an impair -number of inverted literal or not -@return True, if ther is an XOR, and False if not -*/ -bool XorFinder::isXor(const uint32_t size, const ClauseTable::iterator& begin, const ClauseTable::iterator& end, bool& impair) -{ - const uint32_t requiredSize = 1 << (begin->first->size()-1); - - //Note: "size" can be larger than requiredSize, since there might be - //a mix of imparied and paired num. inverted literals, and furthermore, - //clauses might be repeated - if (size < requiredSize) return false; - - #ifdef DEBUG_XORFIND2 - { - vec<Var> vars; - Clause& c = *begin->first; - for (uint32_t i = 0; i < c.size(); i++) - vars.push(c[i].var()); - for (ClauseTable::iterator it = begin; it != end; it++) { - Clause& c = *it->first; - for (uint32_t 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 - - //We now sort them according to literal content - std::sort(begin, end, clause_sorter_secondary()); - - uint32_t numPair = 0; - uint32_t numImpair = 0; - countImpairs(begin, end, numImpair, numPair); - - //if there are two XORs with equal variable sets, but different invertedness - //that leads to direct UNSAT result. - if (numImpair == requiredSize && numPair == requiredSize) { - solver.ok = false; - impair = true; - return true; - } - - if (numImpair == requiredSize) { - impair = true; - return true; - } - - if (numPair == requiredSize) { - impair = false; - return true; - } - - return false; -} - -/** -@brief Counts number of negations in the literals in clauses between begin&end, and returns the number of clauses with pair, and impair literals -*/ -void XorFinder::countImpairs(const ClauseTable::iterator& begin, const ClauseTable::iterator& end, uint32_t& numImpair, uint32_t& numPair) const -{ - numImpair = 0; - numPair = 0; - - ClauseTable::const_iterator it = begin; - ClauseTable::const_iterator it2 = begin; - it2++; - - bool impair = impairSigns(*it->first); - numImpair += impair; - numPair += !impair; - - for (; it2 != end;) { - if (!clauseEqual(*it->first, *it2->first)) { - bool impair = impairSigns(*it2->first); - numImpair += impair; - numPair += !impair; - } - it++; - it2++; - } -} - -/** -@brief Converts all xor clauses to normal clauses - -Sometimes it's not worth the hassle of having xor clauses and normal clauses. -This function converts xor clauses to normal clauses, and removes the normal -clauses. - -\todo It currently only works for 3- and 4-long clauses. Larger clauses should -also be handled. -*/ -void XorFinder::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); - if (solver.conf.verbosity >= 1) { - std::cout << "c Added XOR as norm:" << added << std::endl; - } -} - -/** -@brief Utility function for addAllXorAsNorm() for converting 3-long xor clauses to normal clauses - -\todo clean this up, it's ugly -*/ -void XorFinder::addXorAsNormal3(XorClause& c) -{ - assert(c.size() == 3); - Clause *tmp; - vec<Var> vars; - const bool inverted = c.xorEqualFalse(); - - for (uint32_t i = 0; i < c.size(); i++) { - vars.push(c[i].var()); - } - - vec<Lit> vars2; - vars2.growTo(3); - 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); - if (tmp) solver.clauses.push(tmp); - - vars2.growTo(3); - 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); - if (tmp) solver.clauses.push(tmp); - - vars2.growTo(3); - 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); - if (tmp) solver.clauses.push(tmp); - - vars2.growTo(3); - 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); - if (tmp) solver.clauses.push(tmp); -} - -/** -@brief Utility function for addAllXorAsNorm() for converting 4-long xor clauses to normal clauses - -\todo clean this up, it's ugly -*/ -void XorFinder::addXorAsNormal4(XorClause& c) -{ - assert(c.size() == 4); - Clause *tmp; - vec<Var> vars; - vec<Lit> vars2(c.size()); - const bool inverted = !c.xorEqualFalse(); - - 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); - 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); - 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); - 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); - 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); - 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); - 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); - 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); - if (tmp) solver.clauses.push(tmp); -} diff --git a/src/prop/cryptominisat/Solver/XorFinder.h b/src/prop/cryptominisat/Solver/XorFinder.h deleted file mode 100644 index 418dd00e3..000000000 --- a/src/prop/cryptominisat/Solver/XorFinder.h +++ /dev/null @@ -1,157 +0,0 @@ -/*********************************************************************************** -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 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 "VarReplacer.h" -#include "ClauseCleaner.h" - -namespace CMSat { - -class Solver; - -using std::pair; - -/** -@brief Finds xors given a set of clauses - -It basically sorts clauses' literals, sorts clauses according to size and -variable content, then idetifies continious reagions that could be an XOR -clause, finds the xor clause by counting the number of unique negation -permutations of the literals, then removes the clauses, and inserts the xor -clause -*/ -class XorFinder -{ - public: - XorFinder(Solver& _solver, vec<Clause*>& cls); - bool fullFindXors(const uint32_t minSize, const uint32_t maxSize); - void addAllXorAsNorm(); - - private: - typedef vector<pair<Clause*, uint32_t> > ClauseTable; - - bool findXors(uint32_t& sumLengths); - bool getNextXor(ClauseTable::iterator& begin, ClauseTable::iterator& end, bool& impair); - - /** - @brief For sorting clauses according to their size&their var content. Clauses' variables must already be sorted - */ - struct clause_sorter_primary { - bool operator()(const pair<Clause*, uint32_t>& c11, const pair<Clause*, uint32_t>& c22) - { - if (c11.first->size() != c22.first->size()) - return (c11.first->size() < c22.first->size()); - - #ifdef DEBUG_XORFIND2 - Clause& c1 = *c11.first; - for (uint32_t i = 0; i+1 < c1.size(); i++) - assert(c1[i].var() <= c1[i+1].var()); - - Clause& c2 = *c22.first; - for (uint32_t 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 = c11.first->getDataEnd(); a != end; a++, b++) { - if (a->var() != b->var()) - return (a->var() > b->var()); - } - - return false; - } - - Lit const *a; - Lit const *b; - Lit const *end; - }; - - /** - @brief Sorts clauses with equal length and variable content according to their literals' signs - - NOTE: the length and variable content of c11 and c22 MUST be the same - - Used to avoid the problem of having 2 clauses with exactly the same - content being counted as two different clauses (when counting the - (im)pairedness of XOR being searched) - */ - struct clause_sorter_secondary { - bool operator()(const pair<Clause*, uint32_t>& c11, const pair<Clause*, uint32_t>& c22) const - { - const Clause& c1 = *(c11.first); - const Clause& c2 = *(c22.first); - assert(c1.size() == c2.size()); - - for (uint32_t i = 0, size = c1.size(); i < size; i++) { - assert(c1[i].var() == c2[i].var()); - if (c1[i].sign() != c2[i].sign()) - return c1[i].sign(); - } - - return false; - } - }; - - /** - @brief Returns whether vars in clauses are the same -- clauses' literals must be identically sorted - */ - bool clause_vareq(const Clause* c1, const Clause* c2) const - { - if (c1->size() != c2->size()) - return false; - - for (uint32_t i = 0, size = c1->size(); i < size; i++) - if ((*c1)[i].var() != (*c2)[i].var()) - return false; - - return true; - } - - ClauseTable table; - vector<bool> toRemove; - vector<bool> toLeaveInPlace; - void clearToRemove(); - uint32_t foundXors; - - //For adding xor clause as normal clause - void addXorAsNormal3(XorClause& c); - void addXorAsNormal4(XorClause& c); - - vec<Clause*>& cls; - - 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, uint32_t& numImpair, uint32_t& numPair) const; - bool isXor(const uint32_t size, const ClauseTable::iterator& begin, const ClauseTable::iterator& end, bool& impair); - - Solver& solver; -}; - -} - -#endif //XORFINDER_H diff --git a/src/prop/cryptominisat/Solver/XorSubsumer.cpp b/src/prop/cryptominisat/Solver/XorSubsumer.cpp deleted file mode 100644 index f6776428e..000000000 --- a/src/prop/cryptominisat/Solver/XorSubsumer.cpp +++ /dev/null @@ -1,622 +0,0 @@ -/***************************************************************************** -SatELite -- (C) Niklas Een, Niklas Sorensson, 2004 -CryptoMiniSat -- Copyright (c) 2009 Mate Soos - -Original code by SatELite authors are under an MIT licence. -Modifications for CryptoMiniSat are under GPLv3. -******************************************************************************/ - -#include "Solver.h" -#include "XorSubsumer.h" -#include "ClauseCleaner.h" -#include "time_mem.h" -#include "assert.h" -#include <iomanip> -#include "VarReplacer.h" - -//#define VERBOSE_DEBUG -#ifdef VERBOSE_DEBUG -#define VERBOSE_DEBUGSUBSUME0 -#define BIT_MORE_VERBOSITY -#endif - -using namespace CMSat; - -XorSubsumer::XorSubsumer(Solver& s): - solver(s) - , totalTime(0.0) - , numElimed(0) - , localSubstituteUseful(0) -{ -} - -// Will put NULL in 'cs' if clause removed. -void XorSubsumer::subsume0(XorClauseSimp ps) -{ - #ifdef VERBOSE_DEBUGSUBSUME0 - cout << "subsume0 orig clause:"; - ps.clause->plainPrint(); - #endif - - vec<Lit> unmatchedPart; - vec<XorClauseSimp> subs; - - findSubsumed(*ps.clause, subs); - for (uint32_t i = 0; i < subs.size(); i++){ - XorClause* tmp = subs[i].clause; - findUnMatched(*ps.clause, *tmp, unmatchedPart); - if (unmatchedPart.size() == 0) { - #ifdef VERBOSE_DEBUGSUBSUME0 - cout << "subsume0 removing:"; - subs[i].clause->plainPrint(); - #endif - clauses_subsumed++; - assert(tmp->size() == ps.clause->size()); - if (ps.clause->xorEqualFalse() == tmp->xorEqualFalse()) { - unlinkClause(subs[i]); - } else { - solver.ok = false; - return; - } - } else { - assert(unmatchedPart.size() > 0); - clauses_cut++; - #ifdef VERBOSE_DEBUG - std::cout << "Cutting xor-clause:"; - subs[i].clause->plainPrint(); - #endif //VERBOSE_DEBUG - XorClause *c = solver.addXorClauseInt(unmatchedPart, tmp->xorEqualFalse() ^ !ps.clause->xorEqualFalse()); - if (c != NULL) - linkInClause(*c); - unlinkClause(subs[i]); - if (!solver.ok) return; - } - unmatchedPart.clear(); - } -} - -template<class T> -void XorSubsumer::findUnMatched(const T& A, const T& 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, const Var elim) -{ - XorClause& cl = *c.clause; - - for (uint32_t i = 0; i < cl.size(); i++) { - removeW(occur[cl[i].var()], &cl); - } - - if (elim != var_Undef) { - XorElimedClause data; - for (Lit *it = cl.getData(), *end = cl.getDataEnd(); it != end; it++) { - data.lits.push_back(it->unsign()); - } - data.xorEqualFalse = cl.xorEqualFalse(); - elimedOutVar[elim].push_back(data); - } - solver.detachClause(cl); - solver.clauseAllocator.clauseFree(c.clause); - - clauses[c.index].clause = NULL; -} - -void XorSubsumer::unlinkModifiedClause(vec<Lit>& origClause, XorClauseSimp c) -{ - for (uint32_t i = 0; i < origClause.size(); i++) { - removeW(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++) { - removeW(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) -{ - clauseID = 0; - clauses.clear(); - XorClause **i = cs.getData(); - for (XorClause **end = i + cs.size(); i != end; i++) { - if (i+1 != end) __builtin_prefetch(*(i+1)); - - linkInClause(**i); - } - cs.clear(); - cs.push(NULL); //HACK --to force xor-propagation -} - -void XorSubsumer::addBackToSolver() -{ - solver.xorclauses.pop(); //HACK --to force xor-propagation - for (uint32_t i = 0; i < clauses.size(); i++) { - if (clauses[i].clause != NULL) { - solver.xorclauses.push(clauses[i].clause); - clauses[i].clause->unsetChanged(); - } - } - for (Var var = 0; var < solver.nVars(); var++) { - occur[var].clear(); - } - clauses.clear(); - clauseID = 0; -} - -void XorSubsumer::fillCannotEliminate() -{ - std::fill(cannot_eliminate.getData(), cannot_eliminate.getDataEnd(), false); - for (uint32_t i = 0; i < solver.clauses.size(); i++) - addToCannotEliminate(solver.clauses[i]); - - uint32_t wsLit = 0; - for (const vec<Watched> *it = solver.watches.getData(), *end = solver.watches.getDataEnd(); it != end; it++, wsLit++) { - Lit lit = ~Lit::toLit(wsLit); - const vec<Watched>& ws = *it; - for (vec<Watched>::const_iterator it2 = ws.getData(), end2 = ws.getDataEnd(); it2 != end2; it2++) { - if (it2->isBinary() && !it2->getLearnt()) { - cannot_eliminate[lit.var()] = true; - cannot_eliminate[it2->getOtherLit().var()] = true; - } - } - } - - for (Var var = 0; var < solver.nVars(); var++) { - cannot_eliminate[var] |= solver.varReplacer->cannot_eliminate[var]; - } - - #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 XorSubsumer::extendModel(Solver& solver2) -{ - #ifdef VERBOSE_DEBUG - std::cout << "XorSubsumer::extendModel(Solver& solver2) called" << std::endl; - #endif - - assert(checkElimedUnassigned()); - vec<Lit> tmp; - typedef map<Var, vector<XorElimedClause> > elimType; - for (elimType::iterator it = elimedOutVar.begin(), end = elimedOutVar.end(); it != end; it++) { - #ifdef VERBOSE_DEBUG - Var var = it->first; - std::cout << "Reinserting elimed var: " << var+1 << std::endl; - #endif - - for (vector<XorElimedClause>::iterator it2 = it->second.begin(), end2 = it->second.end(); it2 != end2; it2++) { - XorElimedClause& c = *it2; - #ifdef VERBOSE_DEBUG - std::cout << "Reinserting Clause: "; - c.plainPrint(); - #endif - tmp.clear(); - tmp.growTo(c.lits.size()); - std::copy(c.lits.begin(), c.lits.end(), tmp.getData()); - solver2.addXorClause(tmp, c.xorEqualFalse); - assert(solver2.ok); - } - } -} - -bool XorSubsumer::localSubstitute() -{ - vec<Lit> tmp; - for (Var var = 0; var < occur.size(); var++) { - vec<XorClauseSimp>& occ = occur[var]; - - if (occ.size() <= 1) continue; - for (uint32_t i = 0; i < occ.size(); i++) { - XorClause& c1 = *occ[i].clause; - for (uint32_t i2 = i+1; i2 < occ.size(); i2++) { - XorClause& c2 = *occ[i2].clause; - tmp.clear(); - xorTwoClauses(c1, c2, tmp); - if (tmp.size() <= 2) { - #ifdef VERBOSE_DEBUG - std::cout << "Local substiuting. Clause1:"; c1.plainPrint(); - std::cout << "Clause 2:"; c2.plainPrint(); - #endif //VERBOSE_DEBUG - localSubstituteUseful++; - XorClause* ret = solver.addXorClauseInt(tmp, c1.xorEqualFalse() ^ !c2.xorEqualFalse()); - release_assert(ret == NULL); - if (!solver.ok) { - #ifdef VERBOSE_DEBUG - std::cout << "solver.ok is false after local substitution" << std::endl; - #endif //VERBOSE_DEBUG - return false; - } - } - } - } - } - - return true; -} - -template<class T> -void XorSubsumer::xorTwoClauses(const T& c1, const T& c2, vec<Lit>& xored) -{ - for (uint32_t i = 0; i != c1.size(); i++) - seen_tmp[c1[i].var()] = 1; - for (uint32_t i = 0; i != c2.size(); i++) - seen_tmp[c2[i].var()] ^= 1; - - for (uint32_t i = 0; i != c1.size(); i++) { - if (seen_tmp[c1[i].var()] == 1) { - xored.push(Lit(c1[i].var(), false)); - seen_tmp[c1[i].var()] = 0; - } - } - for (uint32_t i = 0; i != c2.size(); i++) { - if (seen_tmp[c2[i].var()] == 1) { - xored.push(Lit(c2[i].var(), false)); - seen_tmp[c2[i].var()] = 0; - } - } -} - -void XorSubsumer::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); - solver.clauseAllocator.clauseFree(&c); - break; - } - } - if (!remove) - *j++ = *i; - } - cs.shrink(i-j); -} - -void XorSubsumer::removeWrongBins() -{ - uint32_t numRemovedHalfLearnt = 0; - uint32_t wsLit = 0; - for (vec<Watched> *it = solver.watches.getData(), *end = solver.watches.getDataEnd(); it != end; it++, wsLit++) { - Lit lit = ~Lit::toLit(wsLit); - vec<Watched>& ws = *it; - - vec<Watched>::iterator i = ws.getData(); - vec<Watched>::iterator j = i; - for (vec<Watched>::iterator end2 = ws.getDataEnd(); i != end2; i++) { - if (i->isBinary() - && i->getLearnt() - && (var_elimed[lit.var()] || var_elimed[i->getOtherLit().var()]) - ) { - numRemovedHalfLearnt++; - } else { - assert(!i->isBinary() - || (!var_elimed[lit.var()] && !var_elimed[i->getOtherLit().var()])); - *j++ = *i; - } - } - ws.shrink_(i - j); - } - - assert(numRemovedHalfLearnt % 2 == 0); - solver.learnts_literals -= numRemovedHalfLearnt; - solver.numBins -= numRemovedHalfLearnt/2; -} - - -bool XorSubsumer::removeDependent() -{ - for (Var var = 0; var < occur.size(); var++) { - if (cannot_eliminate[var] || !solver.decision_var[var] || solver.assigns[var] != l_Undef) continue; - vec<XorClauseSimp>& occ = occur[var]; - - if (occ.size() == 1) { - #ifdef VERBOSE_DEBUG - std::cout << "Eliminating dependent var " << var + 1 << std::endl; - std::cout << "-> Removing dependent clause "; occ[0].clause->plainPrint(); - #endif //VERBOSE_DEBUG - unlinkClause(occ[0], var); - solver.setDecisionVar(var, false); - var_elimed[var] = true; - numElimed++; - } else if (occ.size() == 2) { - vec<Lit> lits; - XorClause& c1 = *(occ[0].clause); - lits.growTo(c1.size()); - std::copy(c1.getData(), c1.getDataEnd(), lits.getData()); - bool inverted = c1.xorEqualFalse(); - - XorClause& c2 = *(occ[1].clause); - lits.growTo(lits.size() + c2.size()); - std::copy(c2.getData(), c2.getDataEnd(), lits.getData() + c1.size()); - inverted ^= !c2.xorEqualFalse(); - uint32_t ret = removeAll(lits, var); - release_assert(ret == 2); - - #ifdef VERBOSE_DEBUG - std::cout << "Eliminating var " << var + 1 << " present in 2 xor-clauses" << std::endl; - std::cout << "-> Removing xor clause "; occ[0].clause->plainPrint(); - std::cout << "-> Removing xor clause "; occ[1].clause->plainPrint(); - #endif //VERBOSE_DEBUG - XorClauseSimp toUnlink0 = occ[0]; - XorClauseSimp toUnlink1 = occ[1]; - unlinkClause(toUnlink0); - unlinkClause(toUnlink1, var); - solver.setDecisionVar(var, false); - var_elimed[var] = true; - numElimed++; - - for (uint32_t i = 0; i < lits.size(); i++) - cannot_eliminate[lits[i].var()] = true; - XorClause* c = solver.addXorClauseInt(lits, inverted); - #ifdef VERBOSE_DEBUG - if (c != NULL) { - std::cout << "-> Added combined xor clause:"; c->plainPrint(); - } else - std::cout << "-> Combined xor clause is NULL" << std::endl; - #endif - if (c != NULL) linkInClause(*c); - if (!solver.ok) { - #ifdef VERBOSE_DEBUG - std::cout << "solver.ok is false after var-elim through xor" << std::endl; - #endif //VERBOSE_DEBUG - return false; - } - } - } - - return true; -} - -inline void XorSubsumer::addToCannotEliminate(Clause* it) -{ - const Clause& c = *it; - for (uint32_t i2 = 0; i2 < c.size(); i2++) - cannot_eliminate[c[i2].var()] = true; -} - -bool XorSubsumer::unEliminate(const Var var) -{ - assert(var_elimed[var]); - vec<Lit> tmp; - typedef map<Var, vector<XorElimedClause> > elimType; - elimType::iterator it = elimedOutVar.find(var); - - //MUST set to decision, since it would never have been eliminated - //had it not been decision var - solver.setDecisionVar(var, true); - var_elimed[var] = false; - numElimed--; - assert(it != elimedOutVar.end()); - #ifdef VERBOSE_DEBUG - std::cout << "Reinserting xor elimed var: " << var+1 << std::endl; - #endif - - FILE* backup_libraryCNFfile = solver.libraryCNFFile; - solver.libraryCNFFile = NULL; - for (vector<XorElimedClause>::iterator it2 = it->second.begin(), end2 = it->second.end(); it2 != end2; it2++) { - XorElimedClause& c = *it2; - tmp.clear(); - tmp.growTo(c.lits.size()); - std::copy(c.lits.begin(), c.lits.end(), tmp.getData()); - #ifdef VERBOSE_DEBUG - std::cout << "Reinserting elimed clause: " << tmp << std::endl;; - #endif - solver.addXorClause(tmp, c.xorEqualFalse); - } - solver.libraryCNFFile = backup_libraryCNFfile; - elimedOutVar.erase(it); - - return solver.ok; -} - - -bool XorSubsumer::simplifyBySubsumption() -{ - double myTime = cpuTime(); - uint32_t origTrailSize = solver.trail.size(); - clauses_subsumed = 0; - clauses_cut = 0; - clauseID = 0; - uint32_t lastNumElimed = numElimed; - localSubstituteUseful = 0; - while (solver.conf.doReplace && solver.varReplacer->needsReplace()) { - if (!solver.varReplacer->performReplace()) - return false; - } - - for (Var var = 0; var < solver.nVars(); var++) { - occur[var].clear(); - } - solver.findAllAttach(); - - 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) { - addBackToSolver(); - return false; - } - } - } - - propagated = (solver.qhead != solver.trail.size()); - solver.ok = (solver.propagate<false>().isNULL()); - if (!solver.ok) { - return false; - } - if (!solver.ok) return false; - - fillCannotEliminate(); - if (solver.conf.doConglXors && !removeDependent()) { - addBackToSolver(); - return false; - } - - if (solver.conf.doHeuleProcess && !localSubstitute()) { - addBackToSolver(); - return false; - } - - /*if (solver.doReplace && solver.varReplacer->needsReplace()) { - addBackToSolver(); - while (solver.doReplace && solver.varReplacer->needsReplace()) { - replaced = true; - if (!solver.varReplacer->performReplace()) - return false; - } - addFromSolver(solver.xorclauses); - }*/ - } - - solver.order_heap.filter(Solver::VarFilter(solver)); - - removeWrong(solver.learnts); - removeWrongBins(); - addBackToSolver(); - removeAssignedVarsFromEliminated(); - - if (solver.conf.verbosity >= 1) { - std::cout << "c x-sub: " << std::setw(5) << clauses_subsumed - << " x-cut: " << std::setw(6) << clauses_cut - << " vfix: " << std::setw(6) <<solver.trail.size() - origTrailSize - << " v-elim: " <<std::setw(6) << numElimed - lastNumElimed - << " locsubst:" << std::setw(6) << localSubstituteUseful - << " time: " << std::setw(6) << std::setprecision(2) << (cpuTime() - myTime) - << std::endl; - } - totalTime += cpuTime() - myTime; - - solver.testAllClauseAttach(); - return true; -} - -void XorSubsumer::findSubsumed(XorClause& ps, vec<XorClauseSimp>& out_subsumed) -{ - #ifdef VERBOSE_DEBUGSUBSUME0 - 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); - - 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_DEBUGSUBSUME0 - cout << "subsumed: "; - it->clause->plainPrint(); - #endif - } - } -} - -bool XorSubsumer::checkElimedUnassigned() const -{ - uint32_t checkNumElimed = 0; - for (uint32_t i = 0; i < var_elimed.size(); i++) { - if (var_elimed[i]) { - checkNumElimed++; - assert(solver.assigns[i] == l_Undef); - if (solver.assigns[i] != l_Undef) return false; - } - } - assert(numElimed == checkNumElimed); - - return true; -} - -void XorSubsumer::removeAssignedVarsFromEliminated() -{ - for (Var var = 0; var < var_elimed.size(); var++) { - if (var_elimed[var] && solver.assigns[var] != l_Undef) { - var_elimed[var] = false; - solver.setDecisionVar(var, true); - numElimed--; - map<Var, vector<XorElimedClause> >::iterator it = elimedOutVar.find(var); - if (it != elimedOutVar.end()) elimedOutVar.erase(it); - } - } -} diff --git a/src/prop/cryptominisat/Solver/XorSubsumer.h b/src/prop/cryptominisat/Solver/XorSubsumer.h deleted file mode 100644 index 67f9c6dd4..000000000 --- a/src/prop/cryptominisat/Solver/XorSubsumer.h +++ /dev/null @@ -1,185 +0,0 @@ -/***************************************************************************** -SatELite -- (C) Niklas Een, Niklas Sorensson, 2004 -CryptoMiniSat -- Copyright (c) 2009 Mate Soos - -Original code by SatELite authors are under an MIT licence. -Modifications for CryptoMiniSat are under GPLv3. -******************************************************************************/ - -#ifndef XORSIMPLIFIER_H -#define XORSIMPLIFIER_H - -#include "Solver.h" -#include "Vec.h" -#include "XSet.h" - -namespace CMSat { - -class ClauseCleaner; - -/** -@brief Handles xor-subsumption and variable elimination at the XOR level - -This class achieves three things: - -1) it removes variables though XOR-ing of two xors thereby removing their common -variable. If that variable is not used anywere else, the variable is now removed -from the problem - -2) It tries to XOR clauses together to get 1-long or 2-long XOR clauses. These -force variables to certain values or replace variables with other variables, -respectively - -3) It tries to subsume XOR clauses with other XOR clauses (making 2 XOR clauses -in the process, but one of them is going to be much smaller than it was originally) -*/ -class XorSubsumer -{ -public: - - XorSubsumer(Solver& S2); - bool simplifyBySubsumption(); - void unlinkModifiedClause(vec<Lit>& origClause, XorClauseSimp c); - void unlinkModifiedClauseNoDetachNoNULL(vec<Lit>& origClause, XorClauseSimp c); - void unlinkClause(XorClauseSimp cc, Var elim = var_Undef); - XorClauseSimp linkInClause(XorClause& cl); - void linkInAlreadyClause(XorClauseSimp& c); - void newVar(); - void extendModel(Solver& solver2); - - uint32_t getNumElimed() const; - const vec<char>& getVarElimed() const; - bool unEliminate(const Var var); - bool checkElimedUnassigned() const; - double getTotalTime() const; - - struct XorElimedClause - { - vector<Lit> lits; - bool xorEqualFalse; - - void plainPrint(FILE* to = stdout) const - { - fprintf(to, "x"); - if (xorEqualFalse) fprintf(to, "-"); - for (size_t i = 0; i < lits.size(); i++) { - assert(!lits[i].sign()); - fprintf(to, "%d ", lits[i].var() + 1); - } - fprintf(to, "0\n"); - } - }; - const map<Var, vector<XorElimedClause> >& getElimedOutVar() const; - -private: - - friend class ClauseCleaner; - friend class ClauseAllocator; - - //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); - template<class T> - void findUnMatched(const T& A, const T& B, vec<Lit>& unmatchedPart); - - //helper - void testAllClauseAttach() const; - - //dependent removal - bool removeDependent(); - void fillCannotEliminate(); - vec<char> cannot_eliminate; - void addToCannotEliminate(Clause* it); - void removeWrong(vec<Clause*>& cs); - void removeWrongBins(); - void removeAssignedVarsFromEliminated(); - - //Global stats - double totalTime; - map<Var, vector<XorElimedClause> > elimedOutVar; - vec<char> var_elimed; - uint32_t numElimed; - - //Heule-process - template<class T> - void xorTwoClauses(const T& c1, const T& c2, vec<Lit>& xored); - bool localSubstitute(); - uint32_t localSubstituteUseful; - - 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); - cannot_eliminate.push(0); - var_elimed.push(0); -} - -inline const vec<char>& XorSubsumer::getVarElimed() const -{ - return var_elimed; -} - -inline uint32_t XorSubsumer::getNumElimed() const -{ - return numElimed; -} - -inline double XorSubsumer::getTotalTime() const -{ - return totalTime; -} - -inline const map<Var, vector<XorSubsumer::XorElimedClause> >& XorSubsumer::getElimedOutVar() const -{ - return elimedOutVar; -} - -} - -#endif //XORSIMPLIFIER_H diff --git a/src/prop/cryptominisat/Solver/constants.h b/src/prop/cryptominisat/Solver/constants.h deleted file mode 100644 index e8f63bde2..000000000 --- a/src/prop/cryptominisat/Solver/constants.h +++ /dev/null @@ -1,137 +0,0 @@ -/****************************************************************************************[Solver.h] -MiniSat -- Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson -glucose -- Gilles Audemard, Laurent Simon (2008) - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or -substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -**************************************************************************************************/ - -#define release_assert(a) \ - do { \ - if (!(a)) {\ - fprintf(stderr, "*** ASSERTION FAILURE in %s() [%s:%d]: %s\n", \ - __FUNCTION__, __FILE__, __LINE__, #a); \ - abort(); \ - } \ - } while (0) - -/////////////////// -// Settings (magic constants) -/////////////////// - -//#define DUMP_STATS_FULL -//#define DUMP_STATS - -//#define DEBUG_UNCHECKEDENQUEUE_LEVEL0 - -#ifdef DUMP_STATS_FULL -#define DUMP_STATS -#endif //DUMP_STATS_FULL - -//Parameters for learnt-clause cleaning -#define RATIOREMOVECLAUSES 1.0/2.0 -#define NBCLAUSESBEFOREREDUCE 20000 - -#define FIXCLEANREPLACE 30U -#define PERCENTAGEPERFORMREPLACE 0.003 -#define PERCENTAGECLEANCLAUSES 0.01 - -//Parameters for xor-finding (binary and non-binary) -#define MAX_CLAUSENUM_XORFIND 1500000 -#define BINARY_TO_XOR_APPROX 6.0 - -#define UPDATE_TRANSOTFSSR_CACHE 200000 - -//Parameters controlling simplification rounds -#define SIMPLIFY_MULTIPLIER 300 -#define SIMPLIFY_MULTIPLIER_MULTIPLIER 1.5 -#define MAX_CONFL_BETWEEN_SIMPLIFY 500000 -#define BURST_SEARCH -#define NUM_CONFL_BURST_SEARCH 500 - -//Parameters controlling full restarts -#define FULLRESTART_MULTIPLIER 250 -#define FULLRESTART_MULTIPLIER_MULTIPLIER 3.5 -#define RESTART_TYPE_DECIDER_FROM 2 -#define RESTART_TYPE_DECIDER_UNTIL 7 - -//Gaussian elimination parameters -#define MIN_GAUSS_XOR_CLAUSES 5 -#define MAX_GAUSS_XOR_CLAUSES 30000 - -//Parameters regarding glues -#define DEFAULT_MAX_GLUE 24 -#define MAX_GLUE_BITS 7 -#define MAX_THEORETICAL_GLUE ((uint32_t)((1 << MAX_GLUE_BITS)-1)) -#define MIN_GLUE_RESTART 100 - -#ifndef DUMP_STATS_FULL -#define DYNAMICALLY_UPDATE_GLUE -#endif //DUMP_STATS_FULL - -//#define ENABLE_UNWIND_GLUE - -//Parameters for syncing between threads -#define SYNC_EVERY_CONFL 6000 - -/////////////////// -// Verbose Debug -/////////////////// - -//#define VERBOSE_DEBUG_XOR -//#define VERBOSE_DEBUG -#ifdef VERBOSE_DEBUG -#define SILENT_DEBUG -#define DEBUG_USELESS_LEARNT_BIN_REMOVAL -#define DEBUG_ATTACH_FULL -#endif - - -/////////////////// -// Silent Debug -/////////////////// - -#ifndef NDEBUG -#define SILENT_DEBUG -#endif - -#ifdef SILENT_DEBUG -#define DEBUG_VARELIM -#define DEBUG_PROPAGATEFROM -#define DEBUG_WATCHED -#define DEBUG_ATTACH -#define DEBUG_REPLACER -//#define DEBUG_USELESS_LEARNT_BIN_REMOVAL -#endif - -//#define MORE_DEBUG - -#ifdef MORE_DEBUG -#define DEBUG_ATTACH_FULL -#define DEBUG_FAILEDLIT -#define DEBUG_HYPERBIN -#endif - -/////////////////// -// For Automake tools -/////////////////// - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif //HAVE_CONFIG_H - -#ifdef _MSC_VER -#define __builtin_prefetch -#endif //_MSC_VER diff --git a/src/prop/cryptominisat/Solver/msvc/stdint.h b/src/prop/cryptominisat/Solver/msvc/stdint.h deleted file mode 100644 index c8399d3de..000000000 --- a/src/prop/cryptominisat/Solver/msvc/stdint.h +++ /dev/null @@ -1,246 +0,0 @@ -// 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 ] - -#endif // _MSC_STDINT_H_ ] diff --git a/src/prop/cryptominisat/Solver/time_mem.h b/src/prop/cryptominisat/Solver/time_mem.h deleted file mode 100644 index c615eb33a..000000000 --- a/src/prop/cryptominisat/Solver/time_mem.h +++ /dev/null @@ -1,102 +0,0 @@ -/****************************************************************************************[Solver.h] -MiniSat -- Copyright (c) 2003-2006, Niklas Een, Niklas Sorensson -CryptoMiniSat -- Copyright (c) 2009 Mate Soos - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, publish, distribute, -sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or -substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT -NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT -OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -**************************************************************************************************/ - -#ifndef TIME_MEM_H -#define TIME_MEM_H - -#ifdef _MSC_VER -#include <msvc/stdint.h> -#else -#include <stdint.h> -#endif //_MSC_VER - -#if defined (_MSC_VER) || defined(CROSS_COMPILE) -#include <ctime> - -static inline double cpuTime(void) -{ - return (double)clock() / CLOCKS_PER_SEC; -} -#else //_MSC_VER -#include <sys/time.h> -#include <sys/resource.h> -#include <unistd.h> - -static inline double cpuTime(void) -{ - struct rusage ru; - #ifdef RUSAGE_THREAD - getrusage(RUSAGE_THREAD, &ru); - #else - getrusage(RUSAGE_SELF, &ru); - #endif - return (double)ru.ru_utime.tv_sec + (double)ru.ru_utime.tv_usec / 1000000.0; -} - -static inline double cpuTimeTotal(void) -{ - struct rusage ru; - getrusage(RUSAGE_SELF, &ru); - return (double)ru.ru_utime.tv_sec + (double)ru.ru_utime.tv_usec / 1000000.0; -} -#endif //CROSS_COMPILE - - -#if defined(__linux__) -#include <stdio.h> -static inline int memReadStat(int field) -{ - char name[256]; - pid_t pid = getpid(); - sprintf(name, "/proc/%d/statm", pid); - FILE* in = fopen(name, "rb"); - if (in == NULL) return 0; - int value; - - int rvalue= 1; - for (; (field >= 0) && (rvalue == 1); field--) - rvalue = fscanf(in, "%d", &value); - - fclose(in); - return value; -} -static inline uint64_t memUsed() -{ - return (uint64_t)memReadStat(0) * (uint64_t)getpagesize(); -} - - -#elif defined(__FreeBSD__) -static inline uint64_t memUsed(void) -{ - struct rusage ru; - getrusage(RUSAGE_SELF, &ru); - return ru.ru_maxrss*1024; -} - - -#else -static inline uint64_t memUsed() -{ - return 0; -} -#endif - -#endif //TIME_MEM_H |