dlvhex
2.5.0
|
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: