dlvhex  2.5.0
include/dlvhex2/Nogood.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 NOGOOD_HPP_INCLUDED__09122011
00035 #define NOGOOD_HPP_INCLUDED__09122011
00036 
00037 #include <vector>
00038 #include <set>
00039 #include <map>
00040 #include <boost/foreach.hpp>
00041 #include <boost/foreach.hpp>
00042 #include <boost/unordered_map.hpp>
00043 
00044 #include "dlvhex2/ID.h"
00045 #include "dlvhex2/Printhelpers.h"
00046 #include "dlvhex2/Set.h"
00047 #include "dlvhex2/Registry.h"
00048 #include "dlvhex2/Interpretation.h"
00049 
00050 DLVHEX_NAMESPACE_BEGIN
00051 
00072 class DLVHEX_EXPORT Nogood : public Set<ID>, public ostream_printable<Nogood>
00073 {
00074     private:
00076         std::size_t hashValue;
00077 
00079         bool ground;
00080 
00081     public:
00085         Nogood();
00086 
00093         Nogood(InterpretationConstPtr assigned, InterpretationConstPtr interpretation);
00094 
00098         void recomputeHash();
00099 
00104         size_t getHash();
00105 
00111         const Nogood& operator=(const Nogood& other);
00112 
00118         bool operator==(const Nogood& ng2) const;
00119 
00125         bool operator!=(const Nogood& ng2) const;
00126 
00132         std::ostream& print(std::ostream& o) const;
00133 
00139         std::string getStringRepresentation(RegistryPtr reg) const;
00140 
00147         Nogood resolve(const Nogood& ng2, IDAddress groundlitadr);
00148 
00155         Nogood resolve(const Nogood& ng2, ID lit);
00156 
00162         void applyVariableSubstitution(RegistryPtr reg, const std::map<ID, ID>& subst);
00163 
00168         void heuristicNormalization(RegistryPtr reg);
00169 
00177         void insert(ID lit);
00178         template <class InputIterator> void insert(InputIterator begin, InputIterator end) {
00179             for (InputIterator it = begin; it != end; ++it) {
00180                 insert(*it);
00181             }
00182         }
00183 
00188         bool isGround() const;
00189 
00197         bool match(RegistryPtr reg, ID atomID, Nogood& instance) const;
00198 
00199     #ifndef NDEBUG
00200         // saves the nogood as string or loads it back (for debug purposes)
00201         std::string dbgsave() const;
00202         void dbgload(std::string str);
00203     #endif
00204 };
00205 
00209 class DLVHEX_EXPORT NogoodSet : private ostream_printable<NogoodSet>
00210 {
00211     private:
00213         std::vector<Nogood> nogoods;
00215         std::vector<int> addCount;
00217         Set<int> freeIndices;
00219         boost::unordered_map<size_t, Set<int> > nogoodsWithHash;
00220 
00221     public:
00223         void defragment();
00224 
00230         const NogoodSet& operator=(const NogoodSet& other);
00231 
00237         int addNogood(Nogood ng);
00238 
00243         void removeNogood(int nogoodIndex);
00244 
00249         void removeNogood(Nogood ng);
00250 
00256         Nogood& getNogood(int index);
00257 
00263         const Nogood& getNogood(int index) const;
00264 
00269         int getNogoodCount() const;
00270 
00274         void forgetLeastFrequentlyAdded();
00275 
00281         std::ostream& print(std::ostream& o) const;
00282 
00288         std::string getStringRepresentation(RegistryPtr reg) const;
00289 };
00290 
00294 class DLVHEX_EXPORT NogoodContainer
00295 {
00296     public:
00301         virtual void addNogood(Nogood ng) = 0;
00302 
00311         static inline ID createLiteral(ID lit) {
00312             if (lit.isOrdinaryGroundAtom()) {
00313                 return ID(ID::MAINKIND_LITERAL | ID::SUBKIND_ATOM_ORDINARYG | (lit.isNaf() ? ID::NAF_MASK : 0), lit.address);
00314             }
00315             else {
00316                 return ID(ID::MAINKIND_LITERAL | ID::SUBKIND_ATOM_ORDINARYN | (lit.isNaf() ? ID::NAF_MASK : 0), lit.address);
00317             }
00318         }
00319 
00328         static inline ID createLiteral(IDAddress litadr, bool truthValue = true, bool ground = true) {
00329             if (ground) {
00330                 return ID(ID::MAINKIND_LITERAL | ID::SUBKIND_ATOM_ORDINARYG | (truthValue ? 0 : ID::NAF_MASK), litadr);
00331             }
00332             else {
00333                 return ID(ID::MAINKIND_LITERAL | ID::SUBKIND_ATOM_ORDINARYN | (truthValue ? 0 : ID::NAF_MASK), litadr);
00334             }
00335         }
00336 
00337         typedef boost::shared_ptr<NogoodContainer> Ptr;
00338         typedef boost::shared_ptr<const NogoodContainer> ConstPtr;
00339 };
00340 
00341 typedef NogoodContainer::Ptr NogoodContainerPtr;
00342 typedef NogoodContainer::ConstPtr NogoodContainerConstPtr;
00343 
00347 class DLVHEX_EXPORT SimpleNogoodContainer : public NogoodContainer
00348 {
00349     private:
00351         boost::mutex mutex;
00352 
00354         NogoodSet ngg;
00355     public:
00356         void addNogood(Nogood ng);
00357         void removeNogood(Nogood ng);
00358         Nogood& getNogood(int index);
00359         int getNogoodCount();
00360         void clear();
00361         void addAllResolvents(RegistryPtr reg, int maxSize = -1);
00362 
00363         void forgetLeastFrequentlyAdded();
00364         void defragment();
00365 
00366         typedef boost::shared_ptr<SimpleNogoodContainer> Ptr;
00367         typedef boost::shared_ptr<const SimpleNogoodContainer> ConstPtr;
00368 };
00369 
00370 typedef SimpleNogoodContainer::Ptr SimpleNogoodContainerPtr;
00371 typedef SimpleNogoodContainer::ConstPtr SimpleNogoodContainerConstPtr;
00372 
00373 DLVHEX_NAMESPACE_END
00374 #endif
00375 
00376 // vim:expandtab:ts=4:sw=4:
00377 // mode: C++
00378 // End: