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 00037 00038 #include <fstream> 00039 00040 #include "dlvhex2/ExternalAtomVerificationTree.h" 00041 #include "dlvhex2/Logger.h" 00042 #include "dlvhex2/Registry.h" 00043 #include "dlvhex2/Printer.h" 00044 #include "dlvhex2/Interpretation.h" 00045 #include "dlvhex2/Benchmarking.h" 00046 00047 #include <bm/bmalgo.h> 00048 00049 #include <boost/foreach.hpp> 00050 #include <boost/unordered_map.hpp> 00051 #include <boost/property_map/property_map.hpp> 00052 #include <boost/graph/breadth_first_search.hpp> 00053 #include <boost/graph/visitors.hpp> 00054 #include <boost/graph/depth_first_search.hpp> 00055 #include <boost/graph/properties.hpp> 00056 #include <boost/scoped_ptr.hpp> 00057 00058 DLVHEX_NAMESPACE_BEGIN 00059 00060 ExternalAtomVerificationTree::ExternalAtomVerificationTree() : root(NodePtr(new Node())){ 00061 } 00062 00063 void ExternalAtomVerificationTree::addNogood(const Nogood& iong, RegistryPtr reg, bool includeNegated){ 00064 00065 DLVHEX_BENCHMARK_REGISTER_AND_SCOPE(sideavaddnogood, "ExternalAtomVerificationTree::addNogood"); 00066 00067 // Navigate to the right part in the tree part 00068 ID aux = ID_FAIL; 00069 NodePtr currentNode = root; 00070 BOOST_FOREACH (ID lit, iong) { 00071 ID mlit = reg->ogatoms.getIDByAddress(lit.address); 00072 if (lit.isNaf()) mlit.kind |= ID::NAF_MASK; 00073 if (mlit.isExternalAuxiliary()) { 00074 if (aux != ID_FAIL) { 00075 // not an IO-nogood 00076 return; 00077 } 00078 aux = mlit; 00079 }else{ 00080 // check if the current literal already matches with a child node 00081 bool match = false; 00082 BOOST_FOREACH (NodePtr childNode, currentNode->childNodes) { 00083 if (childNode->label == mlit) { 00084 currentNode = childNode; 00085 match = true; 00086 break; 00087 } 00088 } 00089 if (!match) { 00090 // create new node 00091 currentNode->childNodes.push_back(NodePtr(new Node())); 00092 currentNode->childNodes[currentNode->childNodes.size() - 1]->label = mlit; 00093 currentNode = currentNode->childNodes[currentNode->childNodes.size() - 1]; 00094 } 00095 } 00096 } 00097 00098 // insert auxiliary to verify 00099 if (aux == ID_FAIL) { 00100 // not an IO-nogood 00101 return; 00102 }else{ 00103 if (!currentNode->verified){ 00104 currentNode->verified.reset(new Interpretation(reg)); 00105 } 00106 currentNode->verified->setFact(aux.address); 00107 if (includeNegated) currentNode->verified->setFact(reg->swapExternalAtomAuxiliaryAtom(aux).address); 00108 } 00109 } 00110 00111 std::string ExternalAtomVerificationTree::toString(RegistryPtr reg, int indent, NodePtr root){ 00112 std::stringstream ss; 00113 if (!root){ 00114 ss << toString(reg, indent, this->root); 00115 return ss.str(); 00116 } 00117 00118 for (int i = 0; i < indent; ++i) ss << " "; 00119 if (root->label != ID_FAIL) { 00120 ss << "[" << (root->label.isNaf() ? "-" : "") << printToString<RawPrinter>(root->label, reg) << "]; "; 00121 }else{ 00122 ss << "[ROOT]; "; 00123 } 00124 ss << "verified:"; 00125 if (!!root->verified) { 00126 bm::bvector<>::enumerator en = root->verified->getStorage().first(); 00127 bm::bvector<>::enumerator en_end = root->verified->getStorage().end(); 00128 while (en < en_end) { 00129 ss << " " << (reg->ogatoms.getIDByAddress(*en).isNaf() ? "-" : "") << printToString<RawPrinter>(reg->ogatoms.getIDByAddress(*en), reg); 00130 en++; 00131 } 00132 }else{ 00133 ss << " none"; 00134 } 00135 ss << std::endl; 00136 BOOST_FOREACH (NodePtr child, root->childNodes) ss << toString(reg, indent + 1, child); 00137 return ss.str(); 00138 } 00139 00140 InterpretationConstPtr ExternalAtomVerificationTree::getVerifiedAuxiliaries(InterpretationConstPtr partialInterpretation, InterpretationConstPtr assigned, RegistryPtr reg){ 00141 00142 InterpretationPtr verified(new Interpretation(reg)); 00143 getVerifiedAuxiliaries(root, verified, partialInterpretation, assigned, reg); 00144 DBGLOG(DBG, "Verification tree returns " << verified->getStorage().count() << " verified auxiliaries"); 00145 return verified; 00146 } 00147 00148 void ExternalAtomVerificationTree::getVerifiedAuxiliaries(NodePtr current, InterpretationPtr output, InterpretationConstPtr partialInterpretation, InterpretationConstPtr assigned, RegistryPtr reg){ 00149 00150 // add the auxiliaries verified in the current node 00151 if (!!current->verified) { 00152 DBGLOG(DBG, "Adding " << current->verified->getStorage().count() << " auxiliaries to verified ones"); 00153 output->add(*current->verified); 00154 } 00155 00156 // Recursively navigate through the tree. 00157 // Since this is not a search tree, we have to invesigate all pathes which match! 00158 BOOST_FOREACH (NodePtr child, current->childNodes) { 00159 if ( (!assigned || assigned->getFact(child->label.address)) && partialInterpretation->getFact(child->label.address) != child->label.isNaf() ) { 00160 // match: go to this node 00161 getVerifiedAuxiliaries (child, output, partialInterpretation, assigned, reg); 00162 } 00163 } 00164 } 00165 00166 00167 DLVHEX_NAMESPACE_END 00168 00169 00170 // vim:expandtab:ts=4:sw=4: 00171 // mode: C++ 00172 // End: