00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef CLASP_DEPENDENCY_GRAPH_H_INCLUDED
00022 #define CLASP_DEPENDENCY_GRAPH_H_INCLUDED
00023
00024 #ifdef _MSC_VER
00025 #pragma once
00026 #endif
00027
00028 #include <clasp/logic_program.h>
00029 #include <clasp/solver_strategies.h>
00030 #include <algorithm>
00031 namespace Clasp {
00032 class Solver;
00033 class SharedContext;
00034 class SharedDependencyGraph;
00035 struct SolverStats;
00036 struct SolveTestEvent : SolveEvent<SolveTestEvent> {
00037 SolveTestEvent(const Solver& s, uint32 scc, bool partial);
00038 int result;
00039 uint32 scc :31;
00040 uint32 partial : 1;
00041 uint64 confDelta;
00042 uint64 choiceDelta;
00043 double time;
00044
00045 uint64 conflicts() const;
00046 uint64 choices() const;
00047 };
00048
00050
00058 class SharedDependencyGraph {
00059 public:
00060 SharedDependencyGraph(Configuration* nonHcfCfg = 0);
00061 ~SharedDependencyGraph();
00062 typedef uint32 NodeId;
00063 typedef Asp::PrgNode PrgNode;
00064 typedef Asp::PrgBody PrgBody;
00065 typedef Asp::PrgAtom PrgAtom;
00066 typedef Asp::PrgDisj PrgDisj;
00067 typedef Asp::LogicProgram LogicProgram;
00068 typedef Asp::NonHcfSet NonHcfSet;
00069 typedef Asp::AtomList AtomList;
00070
00072 class NonHcfComponent {
00073 public:
00074 explicit NonHcfComponent(const SharedDependencyGraph& dep, SharedContext& generator, uint32 scc, const VarVec& atoms, const VarVec& bodies);
00075 ~NonHcfComponent();
00076 void assumptionsFromAssignment(const Solver& generator, LitVec& assume) const;
00077 bool test(uint32 scc, const Solver& generator, const LitVec& assumptions, VarVec& unfoundedOut) const;
00078 const SharedContext& ctx() const { return *prg_; }
00079 void update(const SharedContext& generator);
00080 private:
00081 friend class SharedDependencyGraph;
00082 NonHcfComponent(const NonHcfComponent&);
00083 NonHcfComponent& operator=(const NonHcfComponent&);
00084 class ComponentMap;
00085 SharedContext* prg_;
00086 ComponentMap* comp_;
00087 };
00088 typedef std::pair<uint32, NonHcfComponent*> ComponentPair;
00089 typedef const ComponentPair* NonHcfIter;
00091 struct Node {
00092 Node(Literal l = Literal(0, false), uint32 sc = PrgNode::noScc)
00093 : lit(l), scc(sc), data(0), adj_(0), sep_(0) {}
00094 Literal lit;
00095 uint32 scc : 28;
00096 uint32 data : 4;
00097 NodeId* adj_;
00098 NodeId* sep_;
00099 };
00101
00106 struct AtomNode : public Node {
00107 enum Property { property_in_choice = 1u, property_in_disj = 2u, property_in_ext = 4u, property_in_non_hcf = 8u};
00108 AtomNode() {}
00109 void set(Property p) { data |= (uint32)p; }
00110 void setProperties(uint32 f) { assert(f < 8); data |= f; }
00112 bool inChoice() const { return (data & property_in_choice) != 0; }
00114 bool inDisjunctive()const { return (data & property_in_disj) != 0; }
00116 bool inExtended() const { return (data& property_in_ext) != 0; }
00118 bool inNonHcf() const { return (data & property_in_non_hcf) != 0; }
00120 const NodeId* bodies_begin() const { return adj_; }
00121 const NodeId* bodies_end() const { return sep_; }
00122 NodeId body(uint32 i) const { return bodies_begin()[i]; }
00124
00131 const NodeId* succs() const { return sep_; }
00133 template <class P>
00134 void visitSuccessors(const P& p) const {
00135 const NodeId* s = succs();
00136 for (; *s != idMax; ++s) { p(*s); }
00137 if (inExtended()) {
00138 for (++s; *s != idMax; s += 2) { p(*s, *(s+1)); }
00139 }
00140 }
00141 };
00142 enum { sentinel_atom = 0u };
00143
00145
00154 struct BodyNode : public Node {
00155 enum Type { type_normal = 0u, type_count = 1u, type_sum = 3u };
00156 enum Flag { flag_has_delta = 4u, flag_seen = 8u };
00157 explicit BodyNode(PrgBody* b, uint32 scc) : Node(b->literal(), scc) {
00158 if (scc == PrgNode::noScc || b->type() == Asp::BodyInfo::NORMAL_BODY) {
00159 data = type_normal;
00160 }
00161 else if (b->type() == Asp::BodyInfo::COUNT_BODY){ data = type_count; }
00162 else if (b->type() == Asp::BodyInfo::SUM_BODY) { data = type_sum; }
00163 else { assert("UNKNOWN BODY TYPE!\n"); }
00164 }
00165 bool seen() const { return (data & flag_seen) != 0; }
00166 void seen(bool b) { if (b) data |= flag_seen; else data &= ~uint32(flag_seen); }
00167
00169
00179 const NodeId* heads_begin() const { return adj_; }
00180 const NodeId* heads_end() const { return sep_ - extended(); }
00182 bool delta() const { return (data & flag_has_delta) != 0; }
00184
00190 const NodeId* preds() const { assert(scc != PrgNode::noScc); return sep_; }
00192 uint32 get_pred_idx(NodeId atomId) const {
00193 const uint32 inc = pred_inc();
00194 uint32 idx = 0;
00195 for (const NodeId* x = preds(); *x != idMax; x += inc, ++idx) {
00196 if (*x == atomId) return idx;
00197 }
00198 return idMax;
00199 }
00200 NodeId get_pred(uint32 idx) const { return *(preds() + (idx*pred_inc())); }
00202 uint32 pred_inc() const { return 1 + sum(); }
00204
00207 uint32 pred_weight(uint32 i, bool ext) const {
00208 return !sum()
00209 ? 1
00210 : *(preds() + (i*pred_inc()) + (1+ext));
00211 }
00213 uint32 num_preds() const {
00214 if (scc == PrgNode::noScc) return 0;
00215 uint32 p = 0;
00216 const NodeId* x = preds();
00217 const uint32 inc= pred_inc();
00218 for (; *x != idMax; x += inc) { ++p; }
00219 x += extended();
00220 for (; *x != idMax; x += inc) { ++p; }
00221 return p;
00222 }
00224 bool extended()const { return (data & type_count) != 0; }
00226 bool sum() const { return (data & type_sum) == type_sum; }
00228 weight_t ext_bound() const { return sep_[-1]; }
00229 };
00231
00236 void addSccs(LogicProgram& prg, const AtomList& sccAtoms, const NonHcfSet& nonHcfs);
00237
00239 uint32 numAtoms() const { return (uint32)atoms_.size(); }
00241 uint32 numBodies()const { return (uint32)bodies_.size(); }
00243 uint32 nodes() const { return numAtoms()+numBodies(); }
00244
00246 const AtomNode& getAtom(NodeId atomId) const {
00247 assert(atomId < atoms_.size());
00248 return atoms_[atomId];
00249 }
00250 NodeId id(const AtomNode& n) const { return static_cast<uint32>(&n - &atoms_[0]); }
00252 const BodyNode& getBody(NodeId bodyId) const {
00253 assert(bodyId < bodies_.size());
00254 return bodies_[bodyId];
00255 }
00257 template <class P>
00258 void visitBodyLiterals(const BodyNode& n, const P& p) {
00259 const NodeId* x = n.preds();
00260 const uint32 inc = n.pred_inc();
00261 uint32 i = 0;
00262 for (; *x != idMax; x += inc, ++i) { p(getAtom(*x).lit, i, false); }
00263 x += n.extended();
00264 for (; *x != idMax; x += inc, ++i) { p(Literal::fromRep(*x),i, true); }
00265 }
00266 NonHcfIter nonHcfBegin() const { return components_.empty() ? NonHcfIter(0) : &components_[0]; }
00267 NonHcfIter nonHcfEnd() const { return nonHcfBegin() + components_.size(); }
00268 uint32 numNonHcfs() const { return (uint32)components_.size(); }
00269 Configuration* nonHcfConfig()const { return config_; }
00270 void accuStats() const;
00271 private:
00272 typedef PodVector<AtomNode>::type AtomVec;
00273 typedef PodVector<BodyNode>::type BodyVec;
00274 typedef PodVector<ComponentPair>::type ComponentMap;
00275 SharedDependencyGraph(const SharedDependencyGraph&);
00276 SharedDependencyGraph& operator=(const SharedDependencyGraph&);
00277 inline bool relevantPrgAtom(const Solver& s, PrgAtom* a) const;
00278 inline bool relevantPrgBody(const Solver& s, PrgBody* b) const;
00279 NodeId createBody(PrgBody* b, uint32 bScc);
00280 NodeId createAtom(Literal lit, uint32 aScc);
00281 NodeId addBody(const LogicProgram& prg, PrgBody*);
00282 NodeId addDisj(const LogicProgram& prg, PrgDisj*);
00283 uint32 addHeads(const LogicProgram& prg, PrgBody*, VarVec& atoms) const;
00284 uint32 getAtoms(const LogicProgram& prg, PrgDisj*, VarVec& atoms) const;
00285 void addPreds(const LogicProgram& prg, PrgBody*, uint32 bScc, VarVec& preds) const;
00286 void initBody(uint32 id, const VarVec& preds, const VarVec& atHeads);
00287 void initAtom(uint32 id, uint32 prop, const VarVec& adj, uint32 preds);
00288 void addNonHcf(SharedContext& ctx, uint32 scc);
00289 AtomVec atoms_;
00290 BodyVec bodies_;
00291 ComponentMap components_;
00292 Configuration* config_;
00293 };
00294
00295 }
00296 #endif