logic_program.h
Go to the documentation of this file.
00001 // 
00002 // Copyright (c) 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_H_INCLUDED
00022 #define CLASP_LOGIC_PROGRAM_H_INCLUDED
00023 
00024 #ifdef _MSC_VER
00025 #pragma once
00026 #endif
00027 
00028 #include <clasp/logic_program_types.h>
00029 #include <clasp/program_builder.h>
00030 #include <clasp/util/misc_types.h>
00031 #include <map>
00032 
00033 namespace Clasp { namespace Asp {
00035 class LpStats {
00036 public:
00037         typedef std::pair<uint32, uint32> RPair;
00038         LpStats() { reset(); }
00039         void   reset();
00040         uint32 eqs()             const { return eqs(Var_t::atom_var) + eqs(Var_t::body_var) + eqs(Var_t::atom_body_var); }
00041         uint32 eqs(VarType t)    const { return eqs_[t-1]; }
00042         uint32 rules()           const;
00043         RPair  rules(RuleType t) const { return rules_[ruleIndex(t)]; }
00044         RPair& rules(RuleType t)       { return rules_[ruleIndex(t)]; }
00045         bool   tr()              const { return rules_[0].first != rules_[0].second; }
00046         void   incEqs(VarType t)       { ++eqs_[t-1]; }
00047         void   upRule(RuleType t,  int32 i) { RPair& x = rules_[ruleIndex(t)]; x.first += i; x.second += i; }
00048         void   trRule(RuleType t, uint32 i) { --rules_[ruleIndex(t)].second; rules_[0].first -= i; }
00049         void   accu(const LpStats& o);
00050         double operator[](const char* key) const;
00051         static const char* keys(const char* path); 
00052         uint32 bodies;          
00053         uint32 atoms;           
00054         uint32 auxAtoms;        
00055         uint32 sccs;            
00056         uint32 nonHcfs;         
00057         uint32 gammas;          
00058         uint32 ufsNodes;        
00059 private:
00060         uint32 eqs_[3];         
00061         RPair  rules_[NUM_RULE_TYPES]; 
00062 };
00064 class RedefinitionError : public std::logic_error {
00065 public:
00066         explicit RedefinitionError(unsigned atomId, const char* atomName = "");
00067         unsigned atom() const { return atomId_; }
00068 private:
00069         unsigned atomId_;
00070 };
00071 
00073 
00077 class LogicProgram : public ProgramBuilder {
00078 public:
00079         LogicProgram();
00080         ~LogicProgram();
00082         enum ExtendedRuleMode {
00083                 mode_native           = 0, 
00084                 mode_transform        = 1, 
00085                 mode_transform_choice = 2, 
00086                 mode_transform_card   = 3, 
00087                 mode_transform_weight = 4, 
00088                 mode_transform_scc    = 5, 
00089                 mode_transform_nhcf   = 6, 
00090                 mode_transform_integ  = 7, 
00091                 mode_transform_dynamic= 8  
00092         };
00093 
00095         struct AspOptions {
00096                 static const uint32 MAX_EQ_ITERS = static_cast<uint32>( (1u<<26)-1 );
00097                 AspOptions() : erMode(mode_native), iters(5), noSCC(0), dfOrder(0), backprop(0), normalize(0), suppMod(0), noGamma(0) {}
00098                 AspOptions& iterations(uint32 it)   { iters   = it;return *this;}
00099                 AspOptions& depthFirst()            { dfOrder = 1; return *this;}
00100                 AspOptions& backpropagate()         { backprop= 1; return *this;}
00101                 AspOptions& noScc()                 { noSCC   = 1; return *this;}
00102                 AspOptions& noEq()                  { iters   = 0; return *this;}
00103                 AspOptions& disableGamma()          { noGamma = 1; return *this;}
00104                 AspOptions& ext(ExtendedRuleMode m) { erMode = m;  return *this;}
00105                 AspOptions& supportedModels()       { suppMod = 1; noEq(); return noScc(); }
00106                 ExtendedRuleMode erMode;       
00107                 uint32           iters    : 26;
00108                 uint32           noSCC    :  1;
00109                 uint32           dfOrder  :  1;
00110                 uint32           backprop :  1;
00111                 uint32           normalize:  1;
00112                 uint32           suppMod  :  1;
00113                 uint32           noGamma  :  1;
00114         };
00119         
00121         LogicProgram& start(SharedContext& ctx, const AspOptions& opts = AspOptions()) {
00122                 startProgram(ctx);
00123                 setOptions(opts);
00124                 return *this;
00125         }
00127         void setExtendedRuleMode(ExtendedRuleMode m) { opts_.ext(m); }
00129         void setOptions(const AspOptions& opts);
00131         void setNonHcfConfiguration(Configuration* c){ nonHcfCfg_ = c; }
00132         
00134 
00148         bool update() { return updateProgram(); }
00149 
00151 
00165         bool end() { return endProgram(); }
00166 
00168         void write(std::ostream& os);
00169         
00171 
00176         void dispose(bool forceFullDispose);
00177 
00179         /*
00180          * \pre The program is currently frozen.
00181          */
00182         bool clone(SharedContext& ctx, bool shareSymbols = false);
00183 
00185 
00195 
00197 
00200         Var newAtom();
00201 
00203 
00216         LogicProgram& setAtomName(Var atomId, const char* name);
00217 
00219 
00226         LogicProgram& setCompute(Var atomId, bool value);
00227 
00229 
00235         LogicProgram& freeze(Var atomId, ValueRep value = value_false);
00236 
00238 
00246         LogicProgram& unfreeze(Var atomId);
00247 
00249 
00263         LogicProgram& addRule(const Rule& r);
00264         
00266 
00277 
00279 
00286         LogicProgram& startRule(RuleType t = BASICRULE, weight_t bound = -1) {
00287                 rule_.clear();
00288                 rule_.setType(t);
00289                 if ((t == CONSTRAINTRULE || t == WEIGHTRULE) && bound > 0) {
00290                         rule_.setBound(bound);
00291                 }
00292                 return *this;
00293         }
00294 
00296 
00300         LogicProgram& setBound(weight_t bound) { // only valid for CONSTRAINT and WEIGHTRULES
00301                 rule_.setBound(bound);
00302                 return *this;
00303         }
00304 
00306         LogicProgram& addHead(Var atomId) {
00307                 assert(atomId > 0);
00308                 rule_.addHead(atomId);
00309                 return *this;
00310         }
00311         
00313 
00320         LogicProgram& addToBody(Var atomId, bool pos, weight_t weight = 1) {
00321                 rule_.addToBody(atomId, pos, weight);
00322                 return *this;
00323         }
00324         
00326 
00329         LogicProgram& endRule() {
00330                 return addRule(rule_);
00331         }
00332         
00334 
00342 
00343         bool   hasMinimize()     const { return minimize_ != 0; }
00345         uint32 numAtoms()        const { return (uint32)atoms_.size()-1; }
00347         uint32 numBodies()       const { return (uint32)bodies_.size(); }
00349         uint32 numDisjunctions() const { return (uint32)disjunctions_.size(); }
00351         Var    startAtom()       const { return incData_?incData_->startAtom:1; }
00353 
00360         Literal getLiteral(Var atomId) const;
00361         LpStats  stats;
00362         LpStats* accu;
00364 
00371         typedef VarVec::const_iterator                VarIter;
00372         typedef PrgHead*const*                        HeadIter;
00373         typedef std::pair<EdgeIterator, EdgeIterator> EdgeRange;
00374         typedef std::pair<HeadIter, HeadIter>         HeadRange;
00375         const AspOptions& options()    const { return opts_; }
00376         bool       hasConflict()       const { return getFalseAtom()->literal() == posLit(0); }
00377         bool       ok()                const { return !hasConflict() && ProgramBuilder::ok(); }
00378         PrgAtom*   getAtom(Var atomId) const { return atoms_[atomId]; }
00379         PrgHead*   getHead(PrgEdge it) const { return it.isAtom() ? (PrgHead*)getAtom(it.node()) : (PrgHead*)getDisj(it.node()); }
00380         PrgNode*   getSupp(PrgEdge it) const { return it.isBody() ? (PrgNode*)getBody(it.node()) : (PrgNode*)getDisj(it.node()); }
00381         Var        getEqAtom(Var a)    const { return getEqNode(atoms_, a); }
00382         PrgBody*   getBody(Var bodyId) const { return bodies_[bodyId]; }
00383         Var        getEqBody(Var b)    const { return getEqNode(bodies_, b); }
00384         PrgDisj*   getDisj(Var disjId) const { return disjunctions_[disjId]; }
00385         bool       isFact(PrgAtom* a)  const { return a->value() == value_true && opts_.noSCC == false; }
00386         HeadIter   disj_begin()        const { return disjunctions_.empty() ? 0 : reinterpret_cast<HeadIter>(&disjunctions_[0]); }
00387         HeadIter   disj_end()          const { return disj_begin() + numDisjunctions(); }
00388         HeadIter   atom_begin()        const { return reinterpret_cast<HeadIter>(&atoms_[0]); }
00389         HeadIter   atom_end()          const { return atom_begin() + (numAtoms()+1); }
00390         VarIter    unfreeze_begin()    const { return incData_?incData_->update.begin() : activeHead_.end(); }
00391         VarIter    unfreeze_end()      const { return incData_?incData_->update.end()   : activeHead_.end(); }
00392         const char*getAtomName(Var id) const;
00393         RuleType   simplifyRule(const Rule& r, VarVec& head, BodyInfo& info);
00394         VarVec&    getSupportedBodies(bool sorted);
00395         uint32     update(PrgBody* b, uint32 oldHash, uint32 newHash);
00396         bool       assignValue(PrgAtom* a, ValueRep v);
00397         bool       assignValue(PrgHead* h, ValueRep v);
00398         bool       propagate(bool backprop);
00399         PrgAtom*   mergeEqAtoms(PrgAtom* a, Var rootAtom);
00400         PrgBody*   mergeEqBodies(PrgBody* b, Var rootBody, bool hashEq, bool atomsAssigned);
00401         bool       propagate()               { return propagate(options().backprop); }
00402         void       setConflict()             { getFalseAtom()->setLiteral(posLit(0)); }
00403         RuleState& ruleState()               { return ruleState_; }
00404         void       addMinimize();
00405         // ------------------------------------------------------------------------
00406         // Statistics
00407         void      upRules(RuleType r, int i) { stats.upRule(r, i);  }
00408         void      incTr(RuleType r, uint32 n){ stats.trRule(r, n);  }
00409         void      incTrAux(uint32 n)         { stats.auxAtoms += n; }
00410         void      incEqs(VarType t)          { stats.incEqs(t);     }
00411         // ------------------------------------------------------------------------
00413 private:
00414         LogicProgram(const LogicProgram&);
00415         LogicProgram& operator=(const LogicProgram&);   
00416         typedef PodVector<Rule*>::type RuleList;
00417         typedef std::multimap<uint32, uint32>   IndexMap; // hash -> vec[offset]
00418         typedef IndexMap::iterator              IndexIter;
00419         typedef std::pair<IndexIter, IndexIter> IndexRange;
00420         typedef PodVector<uint8>::type          SccMap;
00421         struct MinimizeRule;
00422         // ------------------------------------------------------------------------
00423         // virtual overrides
00424         bool doStartProgram();
00425         bool doUpdateProgram();
00426         bool doEndProgram();
00427         void doGetAssumptions(LitVec& out) const;
00428         bool doParse(StreamSource& prg);
00429         int  doType() const { return Problem_t::ASP; }
00430         // ------------------------------------------------------------------------
00431         // Program definition
00432         PrgAtom* resize(Var atomId);
00433         void     addRuleImpl(RuleType t,    const VarVec& head, BodyInfo& body);
00434         bool     handleNatively(RuleType t, const BodyInfo& i) const;
00435         bool     transformNoAux(RuleType t, const BodyInfo& i) const;
00436         void     transformExtended();
00437         void     transformIntegrity(uint32 maxAux);
00438         PrgBody* getBodyFor(BodyInfo& body, bool addDeps = true);
00439         PrgDisj* getDisjFor(const VarVec& heads, uint32 headHash);
00440         PrgBody* assignBodyFor(BodyInfo& body, EdgeType x, bool strongSimp);
00441         uint32   findEqBody(PrgBody* b, uint32 hash);
00442         uint32   equalBody(const IndexRange& range, BodyInfo& info) const;
00443         RuleType simplifyBody(const Rule& r, BodyInfo& info);
00444         uint32   removeBody(PrgBody* b, uint32 oldHash);
00445         Literal  getEqAtomLit(Literal lit, const BodyList& supports, Preprocessor& p, const SccMap& x);
00446         bool     positiveLoopSafe(PrgBody* b, PrgBody* root) const;
00447         void     updateFrozenAtoms();
00448         void     normalize();
00449         template <class C>
00450         Var getEqNode(C& vec, Var id)  const {
00451                 if (!vec[id]->eq()) return id;
00452                 typedef typename C::value_type NodeType;
00453                 NodeType n = vec[id];
00454                 NodeType r;
00455                 Var root   = n->id();
00456                 for (r = vec[root]; r->eq(); r = vec[root]) {
00457                         // if n == r and r == r' -> n == r'
00458                         n->setEq(root = r->id());
00459                 }
00460                 return root;
00461         }
00462         // ------------------------------------------------------------------------
00463         // Nogood creation
00464         void prepareProgram(bool checkSccs);
00465         void finalizeDisjunctions(Preprocessor& p, uint32 numSccs);
00466         void prepareComponents();
00467         void simplifyMinimize();
00468         bool addConstraints();
00469         // ------------------------------------------------------------------------
00470         void writeBody(const BodyInfo& body, std::ostream&) const;
00471         bool transform(const PrgBody& body, BodyInfo& out)  const;
00472         void transform(const MinimizeRule&, BodyInfo& out)  const;
00473         Var      getFalseId()      const { return 0; }
00474         PrgAtom* getFalseAtom()    const { return atoms_[0]; }
00475         Var      findLpFalseAtom() const;
00476         Rule           rule_;        // active rule
00477         BodyInfo       activeBody_;  // simplified body of active rule
00478         VarVec         activeHead_;  // simplified head of active rule
00479         RuleState      ruleState_;   // which atoms appear in the active rule?
00480         RuleList       extended_;    // extended rules to be translated
00481         IndexMap       bodyIndex_;   // hash -> body
00482         IndexMap       disjIndex_;   // hash -> disjunction
00483         BodyList       bodies_;      // all bodies
00484         AtomList       atoms_;       // all atoms
00485         AtomList       sccAtoms_;    // atoms that are strongly connected
00486         DisjList       disjunctions_;// all (head) disjunctions
00487         VarVec         initialSupp_; // bodies that are (initially) supported
00488         VarVec         propQ_;       // assigned atoms
00489         NonHcfSet      nonHcfs_;     // set of non-hcf sccs
00490         Configuration* nonHcfCfg_;   // optional configuration second level solvers
00491         struct MinimizeRule {
00492                 WeightLitVec lits_;
00493                 MinimizeRule* next_;
00494         }*             minimize_;    // list of minimize-rules
00495         struct Incremental  {
00496                 Incremental();
00497                 uint32  startAtom;// first atom of current iteration
00498                 uint32  startAux; // first aux atom of current iteration
00499                 uint32  startScc; // first valid scc number in this iteration
00500                 VarVec  frozen;   // list of frozen atoms
00501                 VarVec  update;   // list of atoms to be updated (freeze/unfreeze) in this step
00502         }*             incData_;// additional state to handle incrementally defined programs 
00503         AspOptions     opts_;   // preprocessing 
00504 };
00505 } } // end namespace Asp
00506 #endif


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