logic_program_types.h
Go to the documentation of this file.
00001 // 
00002 // Copyright (c) 2006-2013, 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_LOGIC_PROGRAM_TYPES_H_INCLUDED
00022 #define CLASP_LOGIC_PROGRAM_TYPES_H_INCLUDED
00023 
00024 #ifdef _MSC_VER
00025 #pragma once
00026 #pragma warning (disable : 4200) // nonstandard extension used : zero-sized array
00027 #endif
00028 #include <clasp/claspfwd.h>
00029 #include <clasp/literal.h>
00030 #include <functional>
00031 namespace Clasp { 
00032 class ClauseCreator;
00033 namespace Asp {
00034 typedef PodVector<PrgAtom*>::type AtomList;
00035 typedef PodVector<PrgBody*>::type BodyList;
00036 typedef PodVector<PrgDisj*>::type DisjList;
00037 const   ValueRep value_weak_true = 3; 
00039 
00040 
00043 enum RuleType{
00044         ENDRULE         = 0,  
00045         BASICRULE       = 1,  
00046         CONSTRAINTRULE  = 2,  
00047         CHOICERULE      = 3,  
00048         WEIGHTRULE      = 5,  
00049         OPTIMIZERULE    = 6,  
00050         DISJUNCTIVERULE = 8,  
00051         NUM_RULE_TYPES  = 6   
00052 };
00053 inline uint32 ruleIndex(RuleType x) {
00054         switch(x) {
00055                 case BASICRULE:      return 0;
00056                 case CONSTRAINTRULE: return 1;
00057                 case CHOICERULE:     return 2;
00058                 case WEIGHTRULE:     return 3;
00059                 case OPTIMIZERULE:   return 4;
00060                 case DISJUNCTIVERULE:return 5;
00061                 default:             return NUM_RULE_TYPES;
00062         }
00063 }
00064 inline RuleType& operator++(RuleType& x) {
00065         switch(x) {
00066                 case BASICRULE:      return x = CONSTRAINTRULE;
00067                 case CONSTRAINTRULE: return x = CHOICERULE;
00068                 case CHOICERULE:     return x = WEIGHTRULE;
00069                 case WEIGHTRULE:     return x = OPTIMIZERULE;
00070                 case OPTIMIZERULE:   return x = DISJUNCTIVERULE;
00071                 case DISJUNCTIVERULE:return x = ENDRULE;
00072                 default:             return x = BASICRULE;
00073         }
00074 }
00075 
00077 
00086 struct PrgEdge {
00088         enum EdgeType{ NORMAL_EDGE = 0, GAMMA_EDGE = 1, CHOICE_EDGE = 2};
00090         enum NodeType{ BODY_NODE   = 0, ATOM_NODE  = 1, DISJ_NODE   = 2};
00091 
00092         static PrgEdge noEdge() { PrgEdge x; x.rep = UINT32_MAX; return x; }
00093         static PrgEdge newEdge(uint32 nodeId, EdgeType eType, NodeType nType) {
00094                 PrgEdge x;
00095                 x.rep = (nodeId << 4) | (nType<<2) | eType;
00096                 return x;
00097         }
00099         uint32   node()     const { return rep >> 4; }
00101         EdgeType type()     const { return EdgeType(rep & 3u); }
00103         NodeType nodeType() const { return NodeType((rep>>2) & 3u); }
00105         bool     isNormal() const { return (rep & 2u) == 0; }
00107         bool     isChoice() const { return (rep & 2u) != 0; }
00109         bool     isGamma()  const { return (rep & 1u) != 0; }
00111         bool     isBody()   const { return nodeType() == BODY_NODE; }
00113         bool     isAtom()   const { return nodeType() == ATOM_NODE; }
00115         bool     isDisj()   const { return nodeType() == DISJ_NODE; }   
00116         bool     operator< (PrgEdge rhs) const { return rep < rhs.rep; }
00117         bool     operator==(PrgEdge rhs) const { return rep == rhs.rep; }
00118         uint32 rep;
00119         struct Node : std::unary_function<PrgEdge, uint32>      { 
00120                 uint32 operator()(PrgEdge n) const { return n.node(); } 
00121         };
00122 };
00123 
00124 typedef PrgEdge::EdgeType           EdgeType;
00125 typedef PrgEdge::NodeType           NodeType;
00126 typedef const PrgEdge*              EdgeIterator;
00127 typedef bk_lib::pod_vector<PrgEdge> EdgeVec;
00128 
00129 
00131 
00135 class Rule {
00136 public:
00137         explicit Rule(RuleType t = ENDRULE) 
00138                 : bound_(0)
00139                 , type_(t) {
00140         }
00142         void clear();
00144         void swap(Rule& o) {
00145                 std::swap(heads, o.heads);
00146                 std::swap(body, o.body);
00147                 std::swap(bound_, o.bound_);
00148                 std::swap(type_, o.type_);
00149         }
00150         // logic
00152 
00155         Rule& setType(RuleType t) {
00156                 assert(t != ENDRULE && "Precondition violated\n");
00157                 type_ = t;
00158                 return *this;
00159         }
00161         RuleType type() const { return type_; }
00163 
00167         Rule& setBound(weight_t bound) {
00168                 assert(bound >= 0 && "Precondition violated!\n");
00169                 bound_ = bound;
00170                 return *this;
00171         }
00173         weight_t bound()          const { return bound_; }
00174 
00175         bool     bodyHasWeights() const { return type_ == WEIGHTRULE || type_ == OPTIMIZERULE;   }
00176         bool     bodyHasBound()   const { return type_ == WEIGHTRULE || type_ == CONSTRAINTRULE; }
00177         bool     bodyIsSet()      const { return type_ == BASICRULE  || type_ == CHOICERULE || type_ == DISJUNCTIVERULE; }
00178 
00180         Rule& addHead(Var v);
00182         Rule& addToBody(Var v, bool pos, weight_t w=1); 
00183         VarVec        heads; 
00184         WeightLitVec  body;  
00185 private:
00186         Rule(const Rule&);
00187         Rule& operator=(const Rule&);
00188         weight_t bound_; // lower bound (i.e. number/weight of lits that must be true before rule fires)
00189         RuleType type_;  // type of rule
00190 };
00191 
00192 class RuleTransform {
00193 public:
00194         struct ProgramAdapter {
00195         virtual Var newAtom() = 0;
00196         virtual void addRule(Rule& rule) = 0;
00197         protected: ~ProgramAdapter() {}
00198         };
00199         struct AdaptBuilder : public ProgramAdapter {
00200                 AdaptBuilder(LogicProgram& p) : prg_(&p) {}
00201                 Var newAtom();
00202                 void addRule(Rule& rule);
00203                 LogicProgram* prg_;
00204         };
00205         RuleTransform();
00206         uint32 transform(LogicProgram& prg, Rule& rule) {
00207                 AdaptBuilder x(prg);
00208                 return transform(x, rule);
00209         }
00210         uint32 transformNoAux(LogicProgram& prg, Rule& rule) {
00211                 AdaptBuilder x(prg);
00212                 return transformNoAux(x, rule);
00213         }
00214         uint32 transform(ProgramAdapter& prg, Rule& rule);
00215         uint32 transformNoAux(ProgramAdapter& prg, Rule& rule);
00216         static weight_t prepareRule(Rule& rule, weight_t* sumVec);
00217 private:
00218         RuleTransform(const RuleTransform&);
00219         RuleTransform& operator=(const RuleTransform&);
00220         uint32 transformChoiceRule(ProgramAdapter& prg, Rule& rule) const;
00221         uint32 transformDisjunctiveRule(ProgramAdapter& prg, Rule& rule) const;
00222         class Impl;
00223 };
00224 
00225 struct BodyInfo {
00226         enum BodyType { NORMAL_BODY = 0, COUNT_BODY = 1, SUM_BODY = 2};
00227         void     reset() {
00228                 lits.clear();
00229                 hash     = 0; 
00230                 bound_   = 0;
00231                 posSize_ = 0;
00232                 type_    = 0;
00233         }
00234         void     init(BodyType t, weight_t b, uint32 h, uint32 posSize) {
00235                 hash     = h;
00236                 bound_   = b;
00237                 posSize_ = posSize;
00238                 type_    = t;
00239         }
00240         void     init(RuleType t, weight_t b, uint32 h, uint32 posSize) {
00241                 BodyType bt = NORMAL_BODY;
00242                 if      (t == CONSTRAINTRULE)                  { bt = COUNT_BODY; }
00243                 else if (t == WEIGHTRULE || t == OPTIMIZERULE) { bt = SUM_BODY;   }
00244                 init(bt, b, h, posSize);
00245         }
00246         uint32   size()   const { return static_cast<uint32>(lits.size()); }
00247         uint32   posSize()const { return posSize_; }
00248         weight_t bound()  const { return bound_; }
00249         BodyType type()   const { return static_cast<BodyType>(type_); }
00250 
00251         const WeightLiteral& operator[](uint32 i) const { return lits[i]; }
00252         WeightLiteral&       operator[](uint32 i)       { return lits[i]; }
00253         weight_t             weight(Literal x)    const { return type() != SUM_BODY ? 1 : lits[findLit(x)].second; }
00254         uint32               findLit(Literal x)   const;
00255         weight_t             sum()                const;
00256         RuleType             ruleType()           const { const RuleType rt[3] = {BASICRULE, CONSTRAINTRULE, WEIGHTRULE}; return  rt[type()]; }
00257         WeightLitVec lits;    // literals of body
00258         uint32       hash;    // hash value of the rule body
00259 private:
00260         weight_t bound_;      // bound of body
00261         uint32   posSize_:30; // size of positive body
00262         uint32   type_   : 2; // type of body
00263 };
00264 
00266 
00269 class RuleState {
00270 public:
00271         static const uint8 pos_flag    = 0x1u;       // in B+
00272         static const uint8 neg_flag    = 0x2u;       // in B-
00273         static const uint8 head_flag   = 0x1u << 2u; // atom in normal head 
00274         static const uint8 choice_flag = 0x1u << 3u; // atom in choice head
00275         static const uint8 disj_flag   = 0x1u << 4u; // disjunctive head
00276         static const uint8 any_flag    = 0xFFu;
00277         RuleState() {}
00279         bool  inHead(PrgEdge t)         const { return isSet(t.node(), headFlag(t)); }
00281         bool  inBody(Literal p)         const { return isSet(p.var(), pos_flag+p.sign()); }
00282         bool  isSet(Var v, uint8 f)     const { return v < state_.size() && (state_[v] & f) != 0; }
00284         void  addToHead(Var v)                { set(v, head_flag); }
00285         void  addToHead(PrgEdge t)            { set(t.node(), headFlag(t)); }
00287         void  addToBody(Literal p)            { set(p.var(), pos_flag+p.sign()); }
00288         
00289         void  set(Var v, uint8 f)             { grow(v); state_[v] |= f; }
00290         void  clear(Var v, uint8 f)           { if (v < state_.size()) { state_[v] &= ~f; } }
00291         void  clear(Var v)                    { clear(v, static_cast<uint8>(-1)); }
00292         void  clearHead(PrgEdge t)            { clear(t.node(), headFlag(t)); }
00293         void  clearBody(Literal p)            { clear(p.var(), pos_flag+p.sign()); }
00294         void  clearAll()                      { StateVec().swap(state_); }
00295 
00296         bool  allMarked(const VarVec& vec, uint8 f) const {
00297                 for (VarVec::const_iterator it = vec.begin(), end = vec.end(); it != end; ++it) {
00298                         if (!isSet(*it, f)) return false;
00299                 }
00300                 return true;
00301         }
00302 private:
00303         typedef PodVector<uint8>::type StateVec;
00304         void  grow(Var v)                { if (v >= state_.size()) { state_.resize(v+1); } }
00305         uint8 headFlag(PrgEdge t) const  { return 1u << ((t.rep>>1) & 7u); }
00306         StateVec state_;
00307 };
00310 
00314 class PrgNode {
00315 public:
00316         static const uint32 noScc     = (1u << 27)-1;
00317         static const uint32 maxVertex = (1u << 28)-1;
00318         static const uint32 noIdx     = 1;
00320         explicit PrgNode(uint32 id, bool checkScc = true);
00322         bool relevant() const { return eq_ == 0; }
00324         bool removed()  const { return eq_ != 0 && id_ == maxVertex; }
00326         bool ignoreScc()const { return noScc_ != 0;  }
00328 
00333         bool eq()       const { return eq_ != 0 && id_ != maxVertex; }
00334         bool seen()     const { return seen_ != 0; }
00336         bool hasVar()   const { return litIdx_ != noIdx; }
00338         Var  var()      const { return litIdx_ >> 1; }
00340         Literal  literal()   const { return Literal::fromIndex(litIdx_); }
00342         ValueRep value()     const { return val_; }
00344         uint32   id()        const { return id_;  }
00346         Literal   trueLit()  const { 
00347                 return value() == value_free
00348                         ? posLit(0)
00349                         : literal() ^ (value() == value_false);
00350         }
00351 
00358         void    setLiteral(Literal x)   { litIdx_  = x.index(); }
00359         void    clearLiteral(bool clVal){ litIdx_  = noIdx; if (clVal) val_ = value_free; }
00360         void    setValue(ValueRep v)    { val_     = v; }
00361         void    setEq(uint32 eqId)      { id_      = eqId; eq_ = 1; seen_ = 1; }
00362         void    setIgnoreScc(bool b)    { noScc_   = (uint32)b; }
00363         void    markRemoved()           { if (!eq()) setEq(PrgNode::maxVertex); }
00364         void    markSeen(bool b)        { seen_    = uint32(b); }
00365         void    resetId(uint32 id, bool seen) { 
00366                 id_   = id; 
00367                 eq_   = 0; 
00368                 seen_ = (uint32)seen;
00369         }
00370         bool    assignValueImpl(ValueRep v, bool noWeak) {
00371                 if (v == value_weak_true && noWeak) { v = value_true; }
00372                 if (value() == value_free || v == value() || (value() == value_weak_true && v == value_true)) {
00373                         setValue(v);
00374                         return true;
00375                 }
00376                 return v == value_weak_true && value() == value_true; 
00377         }
00379 protected:
00380         uint32 litIdx_ : 31; // literal-idx in solver
00381         uint32 noScc_  :  1; // ignore during scc checks?
00382         uint32 id_     : 28; // own id/eq-id/root-id/ufs-id
00383         uint32 val_    :  2; // assigned value
00384         uint32 eq_     :  1; // removed or eq to some other node?
00385         uint32 seen_   :  1; // marked as seen?
00386 private:
00387         PrgNode(const PrgNode&);
00388         PrgNode& operator=(const PrgNode&);
00389 };
00390 
00392 
00396 class PrgHead : public PrgNode {
00397 public:
00398         enum Simplify { no_simplify = 0, force_simplify = 1 };
00399         enum State    { state_normal= 0u, state_in_flux = 1u, state_freeze = 2u, state_freeze_true = 3u };
00400         typedef EdgeIterator sup_iterator;
00401         
00403         bool         inUpper()    const  { return relevant() && upper_ != 0;  }
00405         bool         isAtom()     const  { return isAtom_ != 0; }
00407         uint32       supports()   const  { return supports_.size();  }
00408         sup_iterator supps_begin()const  { return supports_.begin(); }
00409         sup_iterator supps_end()  const  { return supports_.end();   }
00411         bool         frozen()     const  { return (state_ & uint32(state_freeze)) != 0; }
00413         bool         inFlux()     const  { return state_ == state_in_flux; }
00414         Literal      assumption() const  { return literal() ^ (state_ == state_freeze);}
00415         State        state()      const  { return static_cast<State>(state_);          }
00417         void         addSupport(PrgEdge r){ addSupport(r, force_simplify); }
00418         void         addSupport(PrgEdge r, Simplify s);
00420         void         removeSupport(PrgEdge r);
00421         void         clearSupports();
00422         void         clearSupports(EdgeVec& to) { to.swap(supports_); clearSupports(); }
00424         bool         simplifySupports(LogicProgram& prg, bool strong, uint32* numDiffSupps = 0);
00426         bool         assignValue(ValueRep v) { return assignValueImpl(v, ignoreScc() && !frozen()); }
00433         void         setInUpper(bool b)   { upper_ = (uint32)b; }
00434         void         markDirty()          { dirty_ = 1; }
00435         void         assignVar(LogicProgram& prg, PrgEdge it);  
00437 protected:
00439         explicit PrgHead(uint32 id, NodeType t, uint32 data = 0, bool checkScc = true);
00440         bool      backpropagate(LogicProgram& prg, ValueRep val, bool bpFull);
00441         EdgeVec supports_;  // possible supports (body or disjunction)
00442         uint32 data_  : 27; // number of atoms in disjunction or scc of atom
00443         uint32 upper_ :  1; // in (simplified) program?
00444         uint32 dirty_ :  1; // is list of supports dirty?
00445         uint32 state_ :  2; // current incremental state
00446         uint32 isAtom_:  1; // is this head an atom?
00447 };
00448 
00450 
00456 class PrgAtom : public PrgHead {
00457 public:
00458         enum    Dependency { dep_pos = 0, dep_neg = 1, dep_all = 2 };
00459         typedef LitVec::const_iterator      dep_iterator;
00460         explicit PrgAtom(uint32 id, bool checkScc = true);
00462         uint32       scc()                          const { return data_; }
00464         Literal      eqGoal(bool sign)              const;
00466         bool         inDisj()                       const;
00467         
00472         dep_iterator deps_begin()                   const { return deps_.begin(); }
00473         dep_iterator deps_end()                     const { return deps_.end();   }
00474         bool         hasDep(Dependency d)           const;
00475         void         addDep(Var bodyId, bool pos);
00476         void         removeDep(Var bodyId, bool pos);
00477         void         clearDeps(Dependency d);
00479         
00486         void         setEqGoal(Literal x);
00487         bool         propagateValue(LogicProgram& prg, bool backprop);
00488         bool         addConstraints(const LogicProgram& prg, ClauseCreator& c);
00489         void         setScc(uint32 scc) { data_ = scc; }
00490         void         setState(State s)  { state_ = static_cast<uint32>(s); }
00492 private:
00493         LitVec deps_; // bodies depending on this atom
00494 };
00495 
00497 class PrgBody : public PrgNode {
00498 public:
00499         typedef BodyInfo::BodyType BodyType;
00500         typedef EdgeIterator       head_iterator;
00501         
00503 
00509         static PrgBody* create(LogicProgram& prg, uint32 id, const BodyInfo& info, bool addDeps);
00510 
00512         void     destroy();
00513         BodyType type()  const { return BodyType(type_); }
00515         uint32   size()  const { return size_; }
00516         bool     noScc() const { return size() == 0 || goal(0).sign(); }
00518         weight_t bound() const { return static_cast<weight_t>(type() == BodyInfo::NORMAL_BODY ? (weight_t)size() : boundImpl()); }
00520         weight_t sumW()  const { return static_cast<weight_t>(type() != BodyInfo::SUM_BODY    ? (weight_t)size() : data_.ext[0]->sumW); }
00522         Literal  goal(uint32 idx)  const { assert(idx < size()); return *(goals_begin()+idx); }
00524         weight_t weight(uint32 idx)const { assert(idx < size()); return type() != BodyInfo::SUM_BODY ? 1 : data_.ext[0]->weights[idx]; }  
00526 
00531         bool          isSupported() const { return unsupp_ <= 0; }
00533         bool          hasHeads()    const { return extHead() ? !heads_.ext->empty()  : extHead_ != 0; }
00534         head_iterator heads_begin() const { return !extHead() ? heads_.simp          : heads_.ext->begin(); }
00535         head_iterator heads_end()   const { return !extHead() ? heads_.simp+extHead_ : heads_.ext->end(); }
00537 
00544         void     addHead(PrgHead* h, EdgeType t);
00546 
00555         bool     simplifyHeads(LogicProgram& prg, bool strong);
00556         bool     mergeHeads(LogicProgram& prg, PrgBody& heads, bool strong, bool simplify = true);
00557         void     removeHead(PrgHead* h, EdgeType t);
00559 
00574         bool     simplifyBody(LogicProgram& prg, bool strong, uint32* eqId = 0);
00576         bool     simplify(LogicProgram& prg, bool strong, uint32* eqId = 0) {
00577                 return simplifyBody(prg, strong, eqId) && simplifyHeads(prg, strong);
00578         }
00579         bool     eqLits(WeightLitVec& vec, bool& sorted) const;
00581 
00584         bool     propagateSupported(Var /* v */);
00586         bool     propagateAssigned(LogicProgram& prg, Literal p, ValueRep v);
00588         bool     propagateAssigned(LogicProgram& prg, PrgHead* h, EdgeType t);
00590         bool     propagateValue(LogicProgram& prg, bool backprop);
00591         bool     addConstraints(const LogicProgram& prg, ClauseCreator& c);
00592         void     markDirty()      { sBody_ = 1; }
00593         void     markHeadsDirty() { sHead_ = 1; }
00594         void     clearHeads();
00595         bool     resetSupported();
00596         void     assignVar(LogicProgram& prg);
00597         bool     assignValue(ValueRep v) { return assignValueImpl(v, noScc()); }
00598         uint32   scc(const LogicProgram& prg) const;
00599 private:
00600         static const uint32 maxSize = (1u<<26)-1;
00601         explicit PrgBody(LogicProgram& prg, uint32 id, const BodyInfo& info, bool addDep);
00602         ~PrgBody();
00603         uint32         findLit(const LogicProgram& prg, Literal p) const;
00604         bool           normalize(const LogicProgram& prg, weight_t bound, weight_t sumW, weight_t reachW, uint32& hashOut);
00605         void           prepareSimplifyHeads(LogicProgram& prg, RuleState& rs);
00606         bool           simplifyHeadsImpl(LogicProgram& prg, PrgBody& target, RuleState& rs, bool strong);
00607         bool           superfluousHead(const LogicProgram& prg, const PrgHead* head, PrgEdge it, const RuleState& rs) const;
00608         bool           blockedHead(PrgEdge it, const RuleState& rs) const;
00609         void           addHead(PrgEdge h);
00610         bool           eraseHead(PrgEdge h);
00611         bool           extHead()     const { return extHead_ == 3u; }
00612         bool           hasWeights()  const { return type() == BodyInfo::SUM_BODY; }
00613         weight_t       boundImpl()   const { return static_cast<weight_t>(!hasWeights() ? (weight_t)data_.lits[0] : data_.ext[0]->bound); }
00614         const Literal* goals_end()   const { return goals_begin() + size(); }
00615         const Literal* goals_begin() const { return const_cast<PrgBody*>(this)->goals_begin(); }
00616         Literal*       goals_end()         { return goals_begin() + size(); }
00617         Literal*       goals_begin()       { return reinterpret_cast<Literal*>( data_.lits + (type() == BodyInfo::NORMAL_BODY ? 0 : SumExtra::LIT_OFFSET) ); }
00618         struct SumExtra {
00619                 enum { LIT_OFFSET = sizeof(void*)/sizeof(uint32) };
00620                 static SumExtra* create(uint32 size);
00621                 void     destroy();
00622                 weight_t bound;
00623                 weight_t sumW;
00624                 weight_t weights[0];
00625         };
00626         union Head {
00627                 PrgEdge  simp[2];
00628                 EdgeVec* ext;
00629         }         heads_;         // successors of this body
00630         uint32    size_     : 26; // |B|
00631         uint32    extHead_  :  2; // simple or extended head?
00632         uint32    type_     :  2; // body type
00633         uint32    sBody_    :  1; // simplify body?
00634         uint32    sHead_    :  1; // simplify head?
00635         weight_t  unsupp_;        // <= 0 -> body is supported
00636         struct { union {
00637                 uint32    lits[0];
00638                 SumExtra* ext[0]; }; 
00639         }         data_;          // <ext>*?, B+: [0, posSize_), B-: [posSize_, size_)
00640 };
00641 
00643 class PrgDisj : public PrgHead {
00644 public:
00645         typedef EdgeIterator atom_iterator;
00647         static PrgDisj* create(uint32 id, const VarVec& heads);
00649         void          destroy();
00650         void          detach(LogicProgram& prg);
00652         uint32        size()               const { return data_; }
00653         atom_iterator begin()              const { return atoms_; }
00654         atom_iterator end()                const { return atoms_ + size(); }
00656         bool          propagateAssigned(LogicProgram& prg, PrgHead* at, EdgeType t);
00657 private:
00658         explicit PrgDisj(uint32 id, const VarVec& atoms);
00659         ~PrgDisj();
00660         PrgEdge atoms_[0]; // atoms in disjunction
00661 };
00662 
00663 template <class NT>
00664 bool mergeValue(NT* lhs, NT* rhs){
00665         if (lhs->value() != rhs->value()) {
00666                 if (lhs->value() == value_false || lhs->value() == value_true) {
00667                         return rhs->assignValue(lhs->value());
00668                 }
00669                 return rhs->value() != value_free 
00670                         ? lhs->assignValue(rhs->value())
00671                         : rhs->assignValue(lhs->value());
00672         }
00673         return true;
00674 }
00675 class SccChecker {
00676 public:
00677         SccChecker(LogicProgram& prg, AtomList& sccAtoms, uint32 startScc);
00678         uint32 sccs()              const { return sccs_; }
00679         void  visit(PrgBody* body)       { visitDfs(body, PrgEdge::BODY_NODE); }
00680         void  visit(PrgAtom* atom)       { visitDfs(atom, PrgEdge::ATOM_NODE); }
00681         void  visit(PrgDisj* disj)       { visitDfs(disj, PrgEdge::DISJ_NODE); }
00682 private:
00683         struct Call { 
00684                 uintp    node;
00685                 uint32   min;
00686                 uint32   next;
00687         };
00688         typedef PodVector<Call>::type  CallStack;
00689         typedef PodVector<uintp>::type NodeStack;
00690         static uintp    packNode(PrgNode* n, NodeType t)  { return reinterpret_cast<uintp>(n) + uintp(t); }
00691         static PrgNode* unpackNode(uintp n)               { return reinterpret_cast<PrgNode*>(n & ~uintp(3u));}
00692         static bool     isNode(uintp n, NodeType t)       { return (n & 3u) == uintp(t); }
00693         bool  doVisit(PrgNode* n, bool seen = true) const { return !n->ignoreScc() && n->relevant() && n->hasVar() && (!seen || !n->seen()); }
00694         void  visitDfs(PrgNode* n, NodeType t);
00695         bool  recurse(Call& c);
00696         bool  onNode(PrgNode* n, NodeType t, Call& c, uint32 data);
00697         void  addCall(PrgNode* n, NodeType t, uint32 next, uint32 min = 0) {
00698                 Call c = {packNode(n, t), min, next};
00699                 callStack_.push_back(c);
00700         }
00701         CallStack     callStack_;
00702         NodeStack     nodeStack_;
00703         LogicProgram* prg_;
00704         AtomList*     sccAtoms_;
00705         uint32        count_;
00706         uint32        sccs_;
00707 };
00708 
00709 struct NonHcfSet : private PodVector<uint32>::type {
00710 public:
00711         typedef PodVector<uint32>::type base_type;
00712         typedef base_type::const_iterator const_iterator;
00713         using base_type::begin;
00714         using base_type::end;
00715         using base_type::size;
00716         void add(uint32 scc) {
00717                 iterator it = std::lower_bound(begin(), end(), scc);
00718                 if (it == end() || *it != scc) { insert(it, scc); }
00719         }
00720         bool find(uint32 scc) const {
00721                 const_iterator it = scc != PrgNode::noScc ? std::lower_bound(begin(), end(), scc) : end();
00722                 return it != end() && *it == scc;
00723         }
00724 };
00725 
00726 } }
00727 #endif


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