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 #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: