dlvhex  2.5.0
include/dlvhex2/CDNLSolver.h
Go to the documentation of this file.
00001 /* dlvhex -- Answer-Set Programming with external interfaces.
00002  * Copyright (C) 2005-2007 Roman Schindlauer
00003  * Copyright (C) 2006-2015 Thomas Krennwallner
00004  * Copyright (C) 2009-2016 Peter Schüller
00005  * Copyright (C) 2011-2016 Christoph Redl
00006  * Copyright (C) 2015-2016 Tobias Kaminski
00007  * Copyright (C) 2015-2016 Antonius Weinzierl
00008  *
00009  * This file is part of dlvhex.
00010  *
00011  * dlvhex is free software; you can redistribute it and/or modify it
00012  * under the terms of the GNU Lesser General Public License as
00013  * published by the Free Software Foundation; either version 2.1 of
00014  * the License, or (at your option) any later version.
00015  *
00016  * dlvhex is distributed in the hope that it will be useful, but
00017  * WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019  * Lesser General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU Lesser General Public
00022  * License along with dlvhex; if not, write to the Free Software
00023  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
00024  * 02110-1301 USA.
00025  */
00026 
00034 #ifndef CDNLSOLVER_HPP_INCLUDED__09122011
00035 #define CDNLSOLVER_HPP_INCLUDED__09122011
00036 
00037 #include "dlvhex2/ID.h"
00038 #include "dlvhex2/Interpretation.h"
00039 #include <vector>
00040 #include <set>
00041 #include <map>
00042 #include <boost/foreach.hpp>
00043 #include "dlvhex2/Printhelpers.h"
00044 #include <boost/foreach.hpp>
00045 #include "dlvhex2/Set.h"
00046 #include "dlvhex2/DynamicVector.h"
00047 #include "dlvhex2/Nogood.h"
00048 #include "dlvhex2/SATSolver.h"
00049 #include <boost/shared_ptr.hpp>
00050 #include <boost/unordered_map.hpp>
00051 
00052 DLVHEX_NAMESPACE_BEGIN
00053 
00054 // forward declaration
00055 class PropagatorCallback;
00056 
00057 class CDNLSolver : virtual public NogoodContainer, virtual public SATSolver
00058 {
00059     protected:
00061         struct SimpleHashIDAddress : public std::unary_function<IDAddress, std::size_t>
00062         {
00063             inline std::size_t operator()(IDAddress const& ida) const
00064             {
00065                 return ida;
00066             }
00067         };
00069         struct SimpleHashID : public std::unary_function<ID, std::size_t>
00070         {
00071             inline std::size_t operator()(ID const& id) const
00072             {
00073                 if (id.isNaf()) return id.address * 2 + 1;
00074                 else    return id.address * 2;
00075             }
00076         };
00077 
00078         // instance information
00080         NogoodSet nogoodset;
00082         Set<IDAddress> allAtoms;
00084         ProgramCtx& ctx;
00086         SimpleNogoodContainer nogoodsToAdd;
00087 
00088         // solver state information
00090         InterpretationPtr interpretation;
00092         InterpretationPtr assignedAtoms;
00094         DynamicVector<IDAddress, int> decisionlevel;
00096         DynamicVector<IDAddress, int> flipped;
00098         boost::unordered_map<IDAddress, int, SimpleHashIDAddress> cause;
00100         int currentDL;
00102         OrderedSet<IDAddress, SimpleHashIDAddress> assignmentOrder;
00104         DynamicVector<int, std::vector<IDAddress> > factsOnDecisionLevel;
00105 
00108         int exhaustedDL;
00110         DynamicVector<int, ID> decisionLiteralOfDecisionLevel;
00111 
00112         // watching data structures for efficient unit propagation
00114         boost::unordered_map<IDAddress, Set<int>, SimpleHashIDAddress > nogoodsOfPosLiteral;
00116         boost::unordered_map<IDAddress, Set<int>, SimpleHashIDAddress > nogoodsOfNegLiteral;
00118         boost::unordered_map<IDAddress, Set<int>, SimpleHashIDAddress > watchingNogoodsOfPosLiteral;
00120         boost::unordered_map<IDAddress, Set<int>, SimpleHashIDAddress > watchingNogoodsOfNegLiteral;
00122         std::vector<Set<ID> > watchedLiteralsOfNogood;
00124         Set<int> unitNogoods;
00126         Set<int> contradictoryNogoods;
00127 
00128         // variable selection heuristics
00130         int conflicts;
00132         boost::unordered_map<IDAddress, int, SimpleHashIDAddress> varCounterPos;
00134         boost::unordered_map<IDAddress, int, SimpleHashIDAddress> varCounterNeg;
00136         std::vector<int> recentConflicts;
00137 
00138         // statistics
00140         long cntAssignments;
00142         long cntGuesses;
00144         long cntBacktracks;
00146         long cntResSteps;
00148         long cntDetectedConflicts;
00149 
00151         Set<ID> tmpWatched;
00152 
00153         // members
00157         inline bool assigned(IDAddress litadr) {
00158             return assignedAtoms->getFact(litadr);
00159         }
00160 
00164         inline bool satisfied(ID lit) {
00165             // fact must have been set
00166             if (!assigned(lit.address)) return false;
00167             // truth value must be the same
00168             return interpretation->getFact(lit.address) == !lit.isNaf();
00169         }
00170 
00174         inline bool falsified(ID lit) {
00175             // fact must have been set
00176             if (!assigned(lit.address)) return false;
00177             // truth value must be negated
00178             return interpretation->getFact(lit.address) != !lit.isNaf();
00179         }
00180 
00184         inline ID negation(ID lit) {
00185             return ID(lit.kind ^ ID::NAF_MASK, lit.address);
00186         }
00187 
00190         inline bool complete() {
00191             return assignedAtoms->getStorage().count() == allAtoms.size();
00192         }
00193 
00194         // reasoning members
00195         bool unitPropagation(Nogood& violatedNogood);
00196         void loadAddedNogoods();
00197         void analysis(Nogood& violatedNogood, Nogood& learnedNogood, int& backtrackDL);
00198         Nogood resolve(Nogood& ng1, Nogood& ng2, IDAddress litadr);
00199         virtual void setFact(ID fact, int dl, int cause);
00200         virtual void clearFact(IDAddress litadr);
00201         void backtrack(int dl);
00202         ID getGuess();
00203         bool handlePreviousModel();
00204         void flipDecisionLiteral();
00205 
00206         // members for maintaining the watching data structures
00208         void initWatchingStructures();
00211         void updateWatchingStructuresAfterAddNogood(int index);
00214         void updateWatchingStructuresAfterRemoveNogood(int index);
00217         void updateWatchingStructuresAfterSetFact(ID lit);
00220         void updateWatchingStructuresAfterClearFact(ID lit);
00223         void inactivateNogood(int nogoodNr);
00227         void stopWatching(int nogoodNr, ID lit);
00231         void startWatching(int nogoodNr, ID lit);
00232 
00233         // members for variable selection heuristics
00236         void touchVarsInNogood(Nogood& ng);
00237 
00238         // external learning
00240         InterpretationPtr changedAtoms;
00242         Set<PropagatorCallback*> propagator;
00243 
00244         // initialization members
00246         void initListOfAllAtoms();
00248         virtual void resizeVectors();
00249 
00250         // helper members
00254         static std::string litToString(ID lit);
00259         template <typename T>
00260         inline bool contains(const std::vector<T>& s, T el) {
00261             return std::find(s.begin(), s.end(), el) != s.end();
00262         }
00267         template <typename T>
00268         inline std::vector<T> intersect(const std::vector<T>& a, const std::vector<T>& b) {
00269             std::vector<T> i;
00270             BOOST_FOREACH (T el, a) {
00271                 if (contains(b, el)) i.push_back(el);
00272             }
00273             return i;
00274         }
00275 
00279         long getAssignmentOrderIndex(IDAddress adr) {
00280             if (!assigned(adr)) return -1;
00281             return assignmentOrder.getInsertionIndex(adr);
00282         }
00283 
00287         int addNogoodAndUpdateWatchingStructures(Nogood ng);
00288 
00291         std::vector<Nogood> getContradictoryNogoods();
00295         inline bool isDecisionLiteral(IDAddress litaddr) {
00296             if (cause[litaddr] == -1) {
00297                 return true;
00298             }
00299             else {
00300                 return false;
00301             }
00302         }
00306         Nogood getCause(IDAddress adr);
00307     public:
00315         CDNLSolver(ProgramCtx& ctx, NogoodSet ns);
00316 
00317         virtual void restartWithAssumptions(const std::vector<ID>& assumptions);
00318         virtual void addPropagator(PropagatorCallback* pb);
00319         virtual void removePropagator(PropagatorCallback* pb);
00320         virtual InterpretationPtr getNextModel();
00321         virtual Nogood getInconsistencyCause(InterpretationConstPtr explanationAtoms);
00322         virtual void addNogoodSet(const NogoodSet& ns, InterpretationConstPtr frozen = InterpretationConstPtr());
00323         virtual void addNogood(Nogood ng);
00324 
00331         virtual std::string getStatistics();
00332 
00333         typedef boost::shared_ptr<CDNLSolver> Ptr;
00334         typedef boost::shared_ptr<const CDNLSolver> ConstPtr;
00335 };
00336 
00337 typedef CDNLSolver::Ptr CDNLSolverPtr;
00338 typedef CDNLSolver::ConstPtr CDNLSolverConstPtr;
00339 
00340 DLVHEX_NAMESPACE_END
00341 #endif
00342 
00343 // vim:expandtab:ts=4:sw=4:
00344 // mode: C++
00345 // End: