dlvhex  2.5.0
src/ExternalAtomVerificationTree.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
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: