dependency_graph.h
Go to the documentation of this file.
00001 // 
00002 // Copyright (c) 2010-2012, Benjamin Kaufmann
00003 // 
00004 // This file is part of Clasp. See http://www.cs.uni-potsdam.de/clasp/ 
00005 // 
00006 // Clasp is free software; you can redistribute it and/or modify
00007 // it under the terms of the GNU General Public License as published by
00008 // the Free Software Foundation; either version 2 of the License, or
00009 // (at your option) any later version.
00010 // 
00011 // Clasp is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 // 
00016 // You should have received a copy of the GNU General Public License
00017 // along with Clasp; if not, write to the Free Software
00018 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
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;     // -1: before test, 0: unstable, 1: stable
00039         uint32 scc     :31;// scc under test
00040         uint32 partial : 1;// partial test?
00041         uint64 confDelta;  // conflicts before test
00042         uint64 choiceDelta;// choices before test
00043         double time;       // time for test
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;       // literal of this node
00095                 uint32  scc   : 28;// scc of this node
00096                 uint32  data  :  4;// additional atom/body data 
00097                 NodeId* adj_;      // list of adjacent nodes
00098                 NodeId* sep_;      // separates successor/predecessor nodes
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


clasp
Author(s): Benjamin Kaufmann
autogenerated on Thu Aug 27 2015 12:41:39