00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef CLASP_SATELITE_H_INCLUDED
00021 #define CLASP_SATELITE_H_INCLUDED
00022
00023 #ifdef _MSC_VER
00024 #pragma once
00025 #endif
00026
00027 #include <clasp/solver.h>
00028 #include <clasp/util/indexed_priority_queue.h>
00029 #include <ctime>
00030
00031 namespace Clasp { namespace SatElite {
00032
00034
00044 class SatElite : public Clasp::SatPreprocessor {
00045 public:
00046 SatElite();
00047 ~SatElite();
00048 Clasp::SatPreprocessor* clone();
00049 struct Progress : public Event_t<Progress> {
00050 enum EventOp { event_algorithm = '*', event_bce = 'B', event_var_elim = 'E', event_subsumption = 'S', };
00051 Progress(SatElite* p, EventOp o, uint32 i, uint32 m) : Event_t<Progress>(Event::subsystem_prepare, Event::verbosity_high), self(p), cur(i), max(m) {
00052 op = (uint32)o;
00053 }
00054 SatElite* self;
00055 uint32 cur;
00056 uint32 max;
00057 };
00058 protected:
00059 bool initPreprocess(Options& opts);
00060 void reportProgress(Progress::EventOp, uint32 curr, uint32 max);
00061 bool doPreprocess();
00062 void doExtendModel(ValueVec& m, LitVec& open);
00063 void doCleanUp();
00064 private:
00065 typedef PodVector<uint8>::type TouchedList;
00066 typedef bk_lib::left_right_sequence<Literal, Var,0> ClWList;
00067 typedef ClWList::left_iterator ClIter;
00068 typedef ClWList::right_iterator WIter;
00069 typedef std::pair<ClIter, ClIter> ClRange;
00070 SatElite(const SatElite&);
00071 const SatElite& operator=(const SatElite&);
00072
00073 struct OccurList {
00074 OccurList() : pos(0), bce(0), dirty(0), neg(0), litMark(0) {}
00075 ClWList refs;
00076
00077 uint32 pos:30;
00078 uint32 bce:1;
00079 uint32 dirty:1;
00080 uint32 neg:30;
00081 uint32 litMark:2;
00082 uint32 numOcc() const { return pos + neg; }
00083 uint32 cost() const { return pos * neg; }
00084 ClRange clauseRange() const { return ClRange(const_cast<ClWList&>(refs).left_begin(), const_cast<ClWList&>(refs).left_end()); }
00085 void clear() {
00086 this->~OccurList();
00087 new (this) OccurList();
00088 }
00089 void addWatch(uint32 clId) { refs.push_right(clId); }
00090 void removeWatch(uint32 clId) { refs.erase_right(std::find(refs.right_begin(), refs.right_end(), clId)); }
00091 void add(uint32 id, bool sign){
00092 pos += uint32(!sign);
00093 neg += uint32(sign);
00094 refs.push_left(Literal(id, sign));
00095 }
00096 void remove(uint32 id, bool sign, bool updateClauseList) {
00097 pos -= uint32(!sign);
00098 neg -= uint32(sign);
00099 if (updateClauseList) {
00100 refs.erase_left(std::find(refs.left_begin(), refs.left_end(), Literal(id, sign)));
00101 }
00102 else { dirty = 1; }
00103 }
00104
00105 bool marked(bool sign) const { return (litMark & (1+sign)) != 0; }
00106 void mark(bool sign) { litMark = (1+sign); }
00107 void unmark() { litMark = 0; }
00108 };
00109 struct LessOccCost {
00110 explicit LessOccCost(OccurList*& occ) : occ_(occ) {}
00111 bool operator()(Var v1, Var v2) const { return occ_[v1].cost() < occ_[v2].cost(); }
00112 private:
00113 const LessOccCost& operator=(LessOccCost&);
00114 OccurList*& occ_;
00115 };
00116 typedef bk_lib::indexed_priority_queue<LessOccCost> ElimHeap;
00117 Clause* peekSubQueue() const {
00118 assert(qFront_ < queue_.size());
00119 return (Clause*)clause( queue_[qFront_] );
00120 }
00121 inline Clause* popSubQueue();
00122 inline void addToSubQueue(uint32 clauseId);
00123 void updateHeap(Var v) {
00124 assert(ctx_);
00125 if (!ctx_->varInfo(v).frozen() && !ctx_->eliminated(v)) {
00126 elimHeap_.update(v);
00127 if (occurs_[v].bce == 0 && occurs_[0].bce != 0) {
00128 occurs_[0].addWatch(v);
00129 occurs_[v].bce = 1;
00130 }
00131 }
00132 }
00133 inline uint32 findUnmarkedLit(const Clause& c, uint32 x) const;
00134 void attach(uint32 cId, bool initialClause);
00135 void detach(uint32 cId);
00136 void bceVeRemove(uint32 cId, bool freeId, Var v, bool blocked);
00137 bool propagateFacts();
00138 bool backwardSubsume();
00139 Literal subsumes(const Clause& c, const Clause& other, Literal res) const;
00140 bool strengthenClause(uint32 clauseId, Literal p);
00141 bool subsumed(LitVec& cl);
00142 bool eliminateVars();
00143 bool bce();
00144 bool bceVe(Var v, uint32 maxCnt);
00145 ClRange splitOcc(Var v, bool mark);
00146 bool trivialResolvent(const Clause& c2, Var v) const;
00147 void markAll(const Literal* lits, uint32 size) const;
00148 void unmarkAll(const Literal* lits, uint32 size) const;
00149 bool addResolvent(uint32 newId, const Clause& c1, const Clause& c2);
00150 bool cutoff(Var v) const {
00151 return opts_->occLimit(occurs_[v].pos, occurs_[v].neg)
00152 || (occurs_[v].cost() == 0 && opts_->mode == Options::prepro_preserve_models);
00153 }
00154 bool timeout() const { return time(0) > timeout_; }
00155 const Options*opts_;
00156 OccurList* occurs_;
00157 ElimHeap elimHeap_;
00158 VarVec posT_, negT_;
00159 ClauseList resCands_;
00160 LitVec resolvent_;
00161 VarVec queue_;
00162 uint32 qFront_;
00163 uint32 facts_;
00164 std::time_t timeout_;
00165 };
00166 }}
00167 #endif