dlvhex  2.5.0
src/Interpretation.cpp
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 #ifdef HAVE_CONFIG_H
00035 #include "config.h"
00036 #endif                           // HAVE_CONFIG_H
00037 
00038 #include "dlvhex2/Interpretation.h"
00039 #include "dlvhex2/Logger.h"
00040 #include "dlvhex2/Printer.h"
00041 #include "dlvhex2/Benchmarking.h"
00042 #include <boost/functional/hash.hpp>
00043 
00044 DLVHEX_NAMESPACE_BEGIN
00045 
00046 std::size_t hash_value(const Interpretation& intr)
00047 {
00048     std::size_t seed = 0;
00049     Interpretation::Storage bits= intr.getStorage();
00050     Interpretation::Storage::enumerator it = bits.first();
00051     while ( it != bits.end() ) {
00052         boost::hash_combine(seed, *it);
00053         it++;
00054     }
00055     return seed;
00056 }
00057 
00058 
00059 Interpretation::Interpretation(RegistryPtr registry):
00060 registry(registry),
00061 bits()
00062 {
00063 }
00064 
00065 
00066 Interpretation::~Interpretation()
00067 {
00068 }
00069 
00070 
00071 unsigned Interpretation::filter(FilterCallback cb)
00072 {
00073     // simply enumerating and clearing bits does not work,
00074     // as modifying bits invalidates iterators (even the end iterator)
00075     // so we collect all things to filter out in a separate bitset
00076 
00077     Storage resetThose;
00078 
00079     // go through one-bits
00080     for(Storage::enumerator it = bits.first();
00081     it != bits.end(); ++it) {
00082         if( !cb(*it) ) {
00083             resetThose.set(*it);
00084         }
00085     }
00086 
00087     for(Storage::enumerator it = resetThose.first();
00088     it != resetThose.end(); ++it) {
00089         // now clear bits
00090         clearFact(*it);
00091     }
00092 
00093     return resetThose.count();
00094 }
00095 
00096 
00097 std::ostream& Interpretation::print(std::ostream& o) const
00098 {
00099     return print(o, "{", ",", "}");
00100 }
00101 
00102 
00103 std::ostream& Interpretation::printWithoutPrefix(std::ostream& o) const
00104 {
00105     return printWithoutPrefix(o, "{", ",", "}");
00106 }
00107 
00108 
00109 std::ostream& Interpretation::printAsNumber(std::ostream& o) const
00110 {
00111     return printAsNumber(o, "{", ",", "}");
00112 }
00113 
00114 
00115 std::ostream& Interpretation::printAsFacts(std::ostream& o) const
00116 {
00117     print(o, "", ".", "");
00118     // make sure the last fact (if any fact exists) gets a dot
00119     if( bits.first() != bits.end() )
00120         o << ".";
00121     return o;
00122 }
00123 
00124 
00125 std::ostream& Interpretation::print(
00126 std::ostream& o,
00127 const char* first, const char* sep, const char* last) const
00128 {
00129     Storage::enumerator it = bits.first();
00130     o << first;
00131     RawPrinter printer(o, registry);
00132     if( it != bits.end() ) {
00133         printer.print(ID(ID::MAINKIND_ATOM | ID::SUBKIND_ATOM_ORDINARYG, *it));
00134         it++;
00135         for(; it != bits.end(); ++it) {
00136             o << sep;
00137             printer.print(ID(ID::MAINKIND_ATOM | ID::SUBKIND_ATOM_ORDINARYG, *it));
00138         }
00139     }
00140     return o << last;
00141 }
00142 
00143 
00144 std::ostream& Interpretation::printWithoutPrefix(
00145 std::ostream& o,
00146 const char* first, const char* sep, const char* last) const
00147 {
00148     Storage::enumerator it = bits.first();
00149     o << first;
00150     RawPrinter printer(o, registry);
00151     if( it != bits.end() ) {
00152         printer.printWithoutPrefix(ID(ID::MAINKIND_ATOM | ID::SUBKIND_ATOM_ORDINARYG, *it));
00153         it++;
00154         for(; it != bits.end(); ++it) {
00155             o << sep;
00156             printer.printWithoutPrefix(ID(ID::MAINKIND_ATOM | ID::SUBKIND_ATOM_ORDINARYG, *it));
00157         }
00158     }
00159     return o << last;
00160 }
00161 
00162 
00163 std::ostream& Interpretation::printAsNumber(
00164 std::ostream& o,
00165 const char* first, const char* sep, const char* last) const
00166 {
00167     Storage::enumerator it = bits.first();
00168     o << first;
00169     if( it != bits.end() ) {
00170         o << *it;
00171         it++;
00172         for(; it != bits.end(); ++it) {
00173             o << sep;
00174             o << *it;
00175         }
00176     }
00177     return o << last;
00178 }
00179 
00180 
00181 void Interpretation::add(const Interpretation& other)
00182 {
00183     bits |= other.bits;
00184     hashUpdated = false;
00185 }
00186 
00187 
00188 void Interpretation::bit_and(const Interpretation& other)
00189 {
00190     bits &= other.bits;
00191     hashUpdated = false;
00192 }
00193 
00194 
00195 InterpretationPtr Interpretation::getInterpretationWithoutExternalAtomAuxiliaries() const
00196 {
00197 
00198     // create interpretation without aux bits, but otherwise equivalent to this one
00199     InterpretationPtr out = InterpretationPtr(new Interpretation(registry));
00200 
00201     bm::bvector<>::enumerator en = getStorage().first();
00202     bm::bvector<>::enumerator en_end = getStorage().end();
00203     while (en < en_end) {
00204         if (!registry->ogatoms.getIDByAddress(*en).isExternalAuxiliary()) {
00205             out->setFact(*en);
00206         }
00207         en++;
00208     }
00209     return out;
00210 }
00211 
00212 
00213 bool Interpretation::operator==(const Interpretation& other) const
00214 {
00215     return bits == other.bits;
00216     return getHash() == other.getHash() && bits == other.bits;
00217 }
00218 
00219 
00220 bool Interpretation::operator!=(const Interpretation& other) const
00221 {
00222     return  bits != other.bits;
00223     return getHash() != other.getHash() || bits != other.bits;
00224 }
00225 
00226 
00227 bool Interpretation::operator<(const Interpretation& other) const
00228 {
00229     return bits < other.bits;
00230 }
00231 
00232 std::size_t Interpretation::getHash() const {
00233     if (!hashUpdated) {
00234         DLVHEX_BENCHMARK_REGISTER_AND_SCOPE(sidconstruct, "Interpretation update hash");
00235         myHash = hash_value(*this);
00236         hashUpdated = true;
00237     }
00238     return myHash;
00239 }
00240 
00241 DLVHEX_NAMESPACE_END
00242 
00243 // vim:expandtab:ts=4:sw=4:
00244 // mode: C++
00245 // End: