Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef CLASP_LOOKAHEAD_H_INCLUDED
00021 #define CLASP_LOOKAHEAD_H_INCLUDED
00022
00023 #ifdef _MSC_VER
00024 #pragma once
00025 #endif
00026
00034 #include <clasp/solver.h>
00035 #include <clasp/constraint.h>
00036 namespace Clasp {
00037
00039 struct VarScore {
00040 VarScore() { clear(); }
00041 void clear() { std::memset(this, 0, sizeof(VarScore)); }
00043 void setSeen( Literal p ) { seen_ |= uint32(p.sign()) + 1; }
00045 bool seen(Literal p) const { return (seen_ & (uint32(p.sign())+1)) != 0; }
00047 bool seen() const { return seen_ != 0; }
00049 void setTested( Literal p ) { tested_ |= uint32(p.sign()) + 1; }
00051 bool tested(Literal p) const { return (tested_ & (uint32(p.sign())+1)) != 0; }
00053 bool tested() const { return tested_ != 0; }
00055 bool testedBoth() const { return tested_ == 3; }
00056
00058 void setScore(Literal p, LitVec::size_type value) {
00059 if (value > (1U<<14)-1) value = (1U<<14)-1;
00060 if (p.sign()) nVal_ = uint32(value);
00061 else pVal_ = uint32(value);
00062 setTested(p);
00063 }
00065 void setDepScore(Literal p, uint32 sc) {
00066 if (!seen(p) || score(p) > sc) {
00067 if (sc > (1U<<14)-1) sc = (1U<<14)-1;
00068 if (p.sign()) nVal_ = std::min(uint32(nVal_-(nVal_==0)), sc);
00069 else pVal_ = std::min(uint32(pVal_-(pVal_==0)), sc);
00070 }
00071 }
00073 uint32 score(Literal p) const { return p.sign() ? nVal_ : pVal_; }
00075
00079 void score(uint32& mx, uint32& mn) const {
00080 if (nVal_ > pVal_) {
00081 mx = nVal_;
00082 mn = pVal_;
00083 }
00084 else {
00085 mx = pVal_;
00086 mn = nVal_;
00087 }
00088 }
00090 bool prefSign() const { return nVal_ > pVal_; }
00091
00092 uint32 nVal() const { return nVal_; }
00093 uint32 pVal() const { return pVal_; }
00094 private:
00095 uint32 pVal_ : 14;
00096 uint32 nVal_ : 14;
00097 uint32 seen_ : 2;
00098 uint32 tested_: 2;
00099 };
00100
00102 struct ScoreLook {
00103 enum Mode { score_max, score_max_min };
00104 typedef PodVector<VarScore>::type VarScores;
00105 ScoreLook() : best(0), mode(score_max), addDeps(true), nant(false) {}
00106 bool validVar(Var v) const { return v < score.size(); }
00107 void scoreLits(const Solver& s, const Literal* b, const Literal *e);
00108 void clearDeps();
00109 uint32 countNant(const Solver& s, const Literal* b, const Literal *e) const;
00110 bool greater(Var lhs, Var rhs)const;
00111 bool greaterMax(Var x, uint32 max) const {
00112 return score[x].nVal() > max || score[x].pVal() > max;
00113 }
00114 bool greaterMaxMin(Var lhs, uint32 max, uint32 min) const {
00115 uint32 lhsMin, lhsMax;
00116 score[lhs].score(lhsMax, lhsMin);
00117 return lhsMin > min || (lhsMin == min && lhsMax > max);
00118 }
00119 VarScores score;
00120 VarVec deps;
00121 VarType types;
00122 Var best;
00123 Mode mode;
00124 bool addDeps;
00125 bool nant;
00126 };
00127
00128 class UnitHeuristic;
00129
00131
00138 class Lookahead : public PostPropagator {
00139 public:
00141 enum Type {
00142 no_lookahead=0,
00143 atom_lookahead,
00144 body_lookahead,
00145 hybrid_lookahead,
00146 };
00147 struct Params {
00148 Params(Type t = atom_lookahead) : type(t), topLevelImps(true), restrictNant(false) {}
00149 Params& lookahead(Type t){ type = t; return *this; }
00150 Params& addImps(bool b) { topLevelImps = b; return *this; }
00151 Params& nant(bool b) { restrictNant = b; return *this; }
00152 Type type;
00153 bool topLevelImps;
00154 bool restrictNant;
00155 };
00156 static bool isType(uint32 t) { return t != 0 && t <= hybrid_lookahead; }
00160 explicit Lookahead(const Params& p);
00161 ~Lookahead();
00162
00163 bool init(Solver& s);
00165 void clear();
00167 bool empty() const { return head()->next == head_id; }
00169 void append(Literal p, bool testBoth);
00171 bool propagateFixpoint(Solver& s, PostPropagator*);
00173 uint32 priority() const;
00174 void destroy(Solver* s, bool detach);
00176 ScoreLook score;
00178 Literal heuristic(Solver& s);
00179
00180 void setLimit(UnitHeuristic* n);
00181 protected:
00182 bool propagateLevel(Solver& s);
00183 void undoLevel(Solver& s);
00184 bool test(Solver& s, Literal p);
00185 private:
00186 typedef uint32 NodeId;
00187 enum { head_id = NodeId(0), undo_id = NodeId(1) };
00188 struct LitNode {
00189 LitNode(Literal x) : lit(x), next(UINT32_MAX) {}
00190 Literal lit;
00191 NodeId next;
00192 };
00193 typedef PodVector<NodeId>::type UndoStack;
00194 typedef PodVector<LitNode>::type LookList;
00195 typedef UnitHeuristic* HeuPtr;
00196 void splice(NodeId n);
00197 LitNode* node(NodeId n) { return &nodes_[n]; }
00198 LitNode* head() { return &nodes_[head_id]; }
00199 LitNode* undo() { return &nodes_[undo_id]; }
00200 bool checkImps(Solver& s, Literal p);
00201 const LitNode* head() const { return &nodes_[head_id]; }
00202 LookList nodes_;
00203 UndoStack saved_;
00204 LitVec imps_;
00205 NodeId last_;
00206 NodeId pos_;
00207 uint32 top_;
00208 HeuPtr limit_;
00209 };
00210
00212
00226 class UnitHeuristic : public DecisionHeuristic {
00227 public:
00231 explicit UnitHeuristic(const Lookahead::Params& p);
00233 static UnitHeuristic* restricted(const Lookahead::Params& p, uint32 numOps, DecisionHeuristic* other);
00234 void endInit(Solver& s);
00235 void updateVar(const Solver& s, Var v, uint32 n);
00236 Literal doSelect(Solver& s);
00237 virtual bool notify(Solver&) { return true; }
00238 protected:
00239 typedef SingleOwnerPtr<Lookahead> LookPtr;
00240 LookPtr look_;
00241 };
00242
00243 }
00244 #endif