00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef CLASP_HEURISTICS_H_INCLUDED
00021 #define CLASP_HEURISTICS_H_INCLUDED
00022
00023 #ifdef _MSC_VER
00024 #pragma once
00025 #endif
00026
00033 #include <clasp/solver.h>
00034 #include <clasp/pod_vector.h>
00035 #include <clasp/util/indexed_priority_queue.h>
00036 #include <list>
00037 namespace Clasp {
00038
00039
00040
00042 uint32 momsScore(const Solver& s, Var v);
00043
00044 struct HeuParams {
00045 HeuParams() : initScore(0), otherScore(0), resScore(0) {}
00046 HeuParams& other(uint32 x) { otherScore = static_cast<uint8>(x); return *this; }
00047 HeuParams& init(uint32 moms) { initScore = static_cast<uint8>(moms); return *this; }
00048 HeuParams& score(uint32 x) { resScore = static_cast<uint8>(x); return *this; }
00049 uint8 initScore;
00050 uint8 otherScore;
00051 uint8 resScore;
00052 };
00053
00055
00066 class ClaspBerkmin : public DecisionHeuristic {
00067 public:
00072 explicit ClaspBerkmin(uint32 maxBerk = 0, const HeuParams& params = HeuParams(), bool berkHuang = false);
00073 void startInit(const Solver& s);
00074 void endInit(Solver& s);
00075 void newConstraint(const Solver& s, const Literal* first, LitVec::size_type size, ConstraintType t);
00076 void updateReason(const Solver& s, const LitVec& lits, Literal resolveLit);
00077 bool bump(const Solver& s, const WeightLitVec& lits, double adj);
00078 void undoUntil(const Solver&, LitVec::size_type);
00079 void updateVar(const Solver& s, Var v, uint32 n);
00080 protected:
00081 Literal doSelect(Solver& s);
00082 private:
00083 Literal selectLiteral(Solver& s, Var v, bool vsids) const;
00084 Literal selectRange(Solver& s, const Literal* first, const Literal* last);
00085 bool initHuang() const { return order_.score[0].occ == 1; }
00086 void initHuang(bool b) { order_.score[0].occ = b; }
00087 bool hasActivities() const { return order_.score[0].act != 0; }
00088 void hasActivities(bool b) { order_.score[0].act = b; }
00089 Var getMostActiveFreeVar(const Solver& s);
00090 Var getTopMoms(const Solver& s);
00091 bool hasTopUnsat(Solver& s);
00092
00093 struct HScore {
00094 HScore(uint32 d = 0) : occ(0), act(0), dec(uint16(d)) {}
00095 void incAct(uint32 gd, bool h, bool sign) {
00096 occ += h * (1 - (2*sign));
00097 decay(gd, h);
00098 ++act;
00099 }
00100 void incOcc(bool sign) { occ += 1 - (2*sign); }
00101 uint32 decay(uint32 gd, bool h) {
00102 if (uint32 x = (gd-dec)) {
00103
00104
00105
00106
00107 act >>= x;
00108 dec = uint16(gd);
00109 occ /= (1<<(x*h));
00110 }
00111 return act;
00112 }
00113 int32 occ;
00114 uint16 act;
00115 uint16 dec;
00116 };
00117 typedef PodVector<HScore>::type Scores;
00118 typedef VarVec::iterator Pos;
00119
00120 struct Order {
00121 explicit Order(bool scoreHuang, bool scoreOnce) : decay(0), huang(scoreHuang), once(scoreOnce) {}
00122 struct Compare {
00123 explicit Compare(Order* o) : self(o) {}
00124 bool operator()(Var v1, Var v2) const {
00125 return self->decayedScore(v1) > self->decayedScore(v2)
00126 || (self->score[v1].act == self->score[v2].act && v1 < v2);
00127 }
00128 Order* self;
00129 };
00130 uint32 decayedScore(Var v) { return score[v].decay(decay, huang); }
00131 int32 occ(Var v) const { return score[v].occ; }
00132 void inc(Literal p) { score[p.var()].incAct(decay, huang, p.sign()); }
00133 void inc(Literal p, uint16 f) { if (f) { score[p.var()].decay(decay, huang); score[p.var()].act += f; } }
00134 void incOcc(Literal p) {
00135 if (!huang)score[p.var()].incOcc(p.sign());
00136 else score[p.var()].incAct(decay, true, p.sign());
00137 }
00138 int compare(Var v1, Var v2) {
00139 return int(decayedScore(v1)) - int(decayedScore(v2));
00140 }
00141 void resetDecay();
00142 Scores score;
00143 uint32 decay;
00144 bool huang;
00145 bool once;
00146 private:
00147 Order(const Order&);
00148 Order& operator=(const Order&);
00149 } order_;
00150 VarVec cache_;
00151 LitVec freeLits_;
00152 LitVec freeOtherLits_;
00153 uint32 topConflict_;
00154 uint32 topOther_;
00155 Var front_;
00156 Pos cacheFront_;
00157 uint32 cacheSize_;
00158 uint32 numVsids_;
00159 uint32 maxBerkmin_;
00160 TypeSet types_;
00161 RNG rng_;
00162 };
00163
00165
00174 class ClaspVmtf : public DecisionHeuristic {
00175 public:
00179 explicit ClaspVmtf(LitVec::size_type mtf = 8, const HeuParams& params = HeuParams());
00180 void startInit(const Solver& s);
00181 void endInit(Solver&);
00182 void newConstraint(const Solver& s, const Literal* first, LitVec::size_type size, ConstraintType t);
00183 void updateReason(const Solver& s, const LitVec& lits, Literal resolveLit);
00184 bool bump(const Solver& s, const WeightLitVec& lits, double adj);
00185 void simplify(const Solver&, LitVec::size_type);
00186 void undoUntil(const Solver&, LitVec::size_type);
00187 void updateVar(const Solver& s, Var v, uint32 n);
00188 protected:
00189 Literal doSelect(Solver& s);
00190 private:
00191 Literal selectRange(Solver& s, const Literal* first, const Literal* last);
00192 typedef std::list<Var> VarList;
00193 typedef VarList::iterator VarPos;
00194 struct VarInfo {
00195 VarInfo(VarPos it) : pos_(it), activity_(0), occ_(0), decay_(0) { }
00196 VarPos pos_;
00197 uint32 activity_;
00198 int32 occ_;
00199 uint32 decay_;
00200 uint32& activity(uint32 globalDecay) {
00201 if (uint32 x = (globalDecay - decay_)) {
00202 activity_ >>= (x<<1);
00203 decay_ = globalDecay;
00204 }
00205 return activity_;
00206 }
00207 };
00208 typedef PodVector<VarInfo>::type Score;
00209
00210 struct LessLevel {
00211 LessLevel(const Solver& s, const Score& sc) : s_(s), sc_(sc) {}
00212 bool operator()(Var v1, Var v2) const {
00213 return s_.level(v1) < s_.level(v2)
00214 || (s_.level(v1) == s_.level(v2) && sc_[v1].activity_ > sc_[v2].activity_);
00215 }
00216 bool operator()(Literal l1, Literal l2) const {
00217 return (*this)(l1.var(), l2.var());
00218 }
00219 private:
00220 LessLevel& operator=(const LessLevel&);
00221 const Solver& s_;
00222 const Score& sc_;
00223 };
00224 Score score_;
00225 VarList vars_;
00226 VarVec mtf_;
00227 VarPos front_;
00228 uint32 decay_;
00229 TypeSet types_;
00230 const LitVec::size_type MOVE_TO_FRONT;
00231 };
00232
00234
00237 struct VsidsScore {
00238 typedef VsidsScore SC;
00239 VsidsScore() : value(0.0) {}
00240 double get() const { return value; }
00241 bool operator>(const SC& o) const { return value > o.value; }
00242 double inc(double f) { return (value += f); }
00243 void set(double f) { value = f; }
00244 double value;
00245 };
00246
00248
00259 template <class ScoreType>
00260 class ClaspVsids_t : public DecisionHeuristic {
00261 public:
00265 explicit ClaspVsids_t(double d = 0.95, const HeuParams& params = HeuParams());
00266 void startInit(const Solver& s);
00267 void endInit(Solver&);
00268 void newConstraint(const Solver& s, const Literal* first, LitVec::size_type size, ConstraintType t);
00269 void updateReason(const Solver& s, const LitVec& lits, Literal resolveLit);
00270 bool bump(const Solver& s, const WeightLitVec& lits, double adj);
00271 void undoUntil(const Solver&, LitVec::size_type);
00272 void simplify(const Solver&, LitVec::size_type);
00273 void updateVar(const Solver& s, Var v, uint32 n);
00274 protected:
00275 Literal doSelect(Solver& s);
00276 virtual void initScores(Solver& s, bool moms);
00277 typedef typename PodVector<ScoreType>::type ScoreVec;
00278 typedef PodVector<int32>::type OccVec;
00279 Literal selectRange(Solver& s, const Literal* first, const Literal* last);
00280 void updateVarActivity(Var v, double f = 1.0) {
00281 double old = score_[v].get(), n = score_[v].inc((inc_*f));
00282 if (n > 1e100) { normalize(); }
00283 if (vars_.is_in_queue(v)) {
00284 if (n >= old) { vars_.increase(v); }
00285 else { vars_.decrease(v); }
00286 }
00287 }
00288 void incOcc(Literal p) { occ_[p.var()] += 1 - (int(p.sign()) << 1); }
00289 int occ(Var v) const { return occ_[v]; }
00290 void normalize();
00291 struct CmpScore {
00292 explicit CmpScore(const ScoreVec& s) : sc_(s) {}
00293 bool operator()(Var v1, Var v2) const { return sc_[v1] > sc_[v2]; }
00294 private:
00295 CmpScore& operator=(const CmpScore&);
00296 const ScoreVec& sc_;
00297 };
00298 typedef bk_lib::indexed_priority_queue<CmpScore> VarOrder;
00299 ScoreVec score_;
00300 OccVec occ_;
00301 VarOrder vars_;
00302 const double decay_;
00303 double inc_;
00304 TypeSet types_;
00305 };
00306 typedef ClaspVsids_t<VsidsScore> ClaspVsids;
00307
00309
00312 struct DomScore {
00313 typedef DomScore SC;
00314 DomScore() : value(0.0), level(0), factor(1), domKey(UINT32_MAX) {}
00315 double get() const { return value; }
00316 bool operator>(const SC& o) const { return (level > o.level) || (level == o.level && value > o.value); }
00317 bool isDom() const { return domKey != UINT32_MAX; }
00318 void setDom(uint32 key) { domKey = key; }
00319 double inc(double f) { return (value += (f*factor)); }
00320 void set(double f) { value = f; }
00321 double value;
00322 int16 level;
00323 int16 factor;
00324 uint32 domKey;
00325 };
00326
00328
00335 class DomainHeuristic : public ClaspVsids_t<DomScore>
00336 , private Constraint {
00337 public:
00338 typedef ClaspVsids_t<DomScore> BaseType;
00339 enum GlobalPreference { gpref_atom = 1, gpref_scc = 2, gpref_hcc = 4, gpref_disj = 8, gpref_min = 16, gpref_show = 32 };
00340 enum GlobalModifier { gmod_level = 1, gmod_spos = 2, gmod_true = 3, gmod_sneg = 4, gmod_false = 5, gmod_max_value };
00341 explicit DomainHeuristic(double d = 0.95, const HeuParams& params = HeuParams());
00342 ~DomainHeuristic();
00343 virtual void startInit(const Solver& s);
00344 using BaseType::endInit;
00345 protected:
00346
00347 virtual Literal doSelect(Solver& s);
00348 virtual void initScores(Solver& s, bool moms);
00349
00350 virtual Constraint* cloneAttach(Solver&) { return 0; }
00351 virtual void reason(Solver&, Literal, LitVec&){}
00352 virtual PropResult propagate(Solver&, Literal, uint32&);
00353 virtual void undoLevel(Solver& s);
00354
00355 void detach();
00356 private:
00357
00358 typedef SymbolTable::symbol_type SymbolType;
00359 typedef PodVector<SymbolType>::type SymbolMap;
00360 class DomMinimize;
00361 struct CmpSymbol;
00362 struct DomEntry {
00363 enum Modifier { mod_factor = 0, mod_level = 1, mod_sign = 2, mod_tf = 3, mod_init = 4 };
00364 DomEntry(const SymbolType* s, Modifier m = mod_init) : sym(s), mod(m), val(0), prio(0), sign(0) {}
00365 bool parse(const char*& mod);
00366 ValueRep signValue() const {
00367 if (mod == mod_sign) { return ValueRep(val); }
00368 if (mod == mod_tf) { return ValueRep(value_true + sign); }
00369 return value_free;
00370 }
00371 const SymbolType* sym;
00372 Modifier mod;
00373 int16 val;
00374 uint16 prio:15;
00375 uint16 sign: 1;
00376 };
00377 struct DomAction {
00378 uint32 var:29;
00379 uint32 mod: 2;
00380 uint32 comp:1;
00381 uint32 undo;
00382 int16 val;
00383 uint16 prio;
00384 };
00385 struct DomPrio {
00386 void clear() { prio[0] = prio[1] = prio[2] = 0; }
00387 uint16 operator[](unsigned i) const { return prio[i]; }
00388 uint16& operator[](unsigned i) { return prio[i]; }
00389 uint16 prio[3];
00390 };
00391 struct Frame {
00392 Frame(uint32 lev, uint32 h) : dl(lev), head(h) {}
00393 uint32 dl;
00394 uint32 head;
00395 };
00396 typedef PodVector<DomAction>::type ActionVec;
00397 typedef PodVector<DomPrio>::type PrioVec;
00398 typedef PodVector<Frame>::type FrameVec;
00399 static const char* const domKey_s;
00400 static const char* const domEnd_s;
00401 static bool match(const char*& in, const char* match);
00402 static bool matchDom(const char*& in, std::string& out);
00403 static bool matchInt(const char*& in, int& out);
00404 void addAction(Solver& s, const SymbolType& pre, const DomEntry& e);
00405 void addAction(Solver& s, Literal x, uint32 modf, int16 levVal);
00406 void endInit(const DomEntry& e, const DomPrio& prio) {
00407 Var v = e.sym->lit.var();
00408 if (e.val) { score_[v].value += e.val; }
00409 if (score_[v].domKey < dPrios_.size()){ dPrios_[score_[v].domKey] = prio; }
00410 }
00411 void pushUndo(Solver& s, uint32 actionId);
00412 void applyAction(Solver& s, DomAction& act, uint16& oldPrio);
00413 Solver* solver_;
00414 LitVec* minLits_;
00415 ActionVec actions_;
00416 PrioVec dPrios_;
00417 FrameVec frames_;
00418 };
00419 }
00420 #endif