00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
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_;
00189 RuleType type_;
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;
00258 uint32 hash;
00259 private:
00260 weight_t bound_;
00261 uint32 posSize_:30;
00262 uint32 type_ : 2;
00263 };
00264
00266
00269 class RuleState {
00270 public:
00271 static const uint8 pos_flag = 0x1u;
00272 static const uint8 neg_flag = 0x2u;
00273 static const uint8 head_flag = 0x1u << 2u;
00274 static const uint8 choice_flag = 0x1u << 3u;
00275 static const uint8 disj_flag = 0x1u << 4u;
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;
00381 uint32 noScc_ : 1;
00382 uint32 id_ : 28;
00383 uint32 val_ : 2;
00384 uint32 eq_ : 1;
00385 uint32 seen_ : 1;
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_;
00442 uint32 data_ : 27;
00443 uint32 upper_ : 1;
00444 uint32 dirty_ : 1;
00445 uint32 state_ : 2;
00446 uint32 isAtom_: 1;
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_;
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 );
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_;
00630 uint32 size_ : 26;
00631 uint32 extHead_ : 2;
00632 uint32 type_ : 2;
00633 uint32 sBody_ : 1;
00634 uint32 sHead_ : 1;
00635 weight_t unsupp_;
00636 struct { union {
00637 uint32 lits[0];
00638 SumExtra* ext[0]; };
00639 } data_;
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];
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