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 #include "dlvhex2/AnswerSetPrinterCallback.h" 00035 00036 // activate benchmarking if activated by configure option --enable-debug 00037 #ifdef HAVE_CONFIG_H 00038 # include "config.h" 00039 #endif 00040 00041 #include "dlvhex2/Benchmarking.h" 00042 #include "dlvhex2/AnswerSet.h" 00043 #include "dlvhex2/Registry.h" 00044 #include "dlvhex2/Printer.h" 00045 #include "dlvhex2/ProgramCtx.h" 00046 #include "dlvhex2/PredicateMask.h" 00047 00048 DLVHEX_NAMESPACE_BEGIN 00049 00050 AnswerSetPrinterCallback::AnswerSetPrinterCallback(ProgramCtx& ctx) : ctx(ctx) 00051 { 00052 RegistryPtr reg = ctx.registry(); 00053 00054 if( !ctx.config.getFilters().empty() ) { 00055 filterpm.reset(new PredicateMask); 00056 00057 // setup mask with registry 00058 filterpm->setRegistry(reg); 00059 00060 // setup mask with predicates 00061 std::vector<std::string>::const_iterator it; 00062 for(it = ctx.config.getFilters().begin(); 00063 it != ctx.config.getFilters().end(); ++it) { 00064 // retrieve/register ID for this constant 00065 ID pred = reg->storeConstantTerm(*it); 00066 filterpm->addPredicate(pred); 00067 } 00068 } 00069 } 00070 00071 00072 bool AnswerSetPrinterCallback::operator()( 00073 AnswerSetPtr as) 00074 { 00075 DLVHEX_BENCHMARK_REGISTER_AND_SCOPE(sid,"AnswerSetPrinterCallback"); 00076 00077 // uses the Registry to print the interpretation, including 00078 // possible influence from AuxiliaryPrinter objects (if any are registered) 00079 00080 Interpretation::Storage::enumerator it, it_end; 00081 00082 RegistryPtr reg = as->interpretation->getRegistry(); 00083 // must be in this scope! 00084 Interpretation::Storage filteredbits; 00085 if( !filterpm ) { 00086 const Interpretation::Storage& bits = 00087 as->interpretation->getStorage(); 00088 it = bits.first(); 00089 it_end = bits.end(); 00090 } 00091 else { 00092 filterpm->updateMask(); 00093 filteredbits = 00094 as->interpretation->getStorage() & filterpm->mask()->getStorage(); 00095 it = filteredbits.first(); 00096 it_end = filteredbits.end(); 00097 } 00098 00099 std::ostream& o = std::cout; 00100 00101 WARNING("TODO think about more efficient printing") 00102 o << '{'; 00103 if( it != it_end ) { 00104 bool gotOutput = 00105 reg->printAtomForUser(o, *it); 00106 //DBGLOG(DBG,"printed with prefix '' and output " << gotOutput << " " << 00107 // printToString<RawPrinter>(ID(ID::MAINKIND_ATOM | ID::SUBKIND_ATOM_ORDINARYG, *it), reg)); 00108 it++; 00109 for(; it != it_end; ++it) { 00110 if( gotOutput ) { 00111 gotOutput |= 00112 reg->printAtomForUser(o, *it, ","); 00113 //DBGLOG(DBG,"printed with prefix ',' and output " << gotOutput << " " << 00114 // printToString<RawPrinter>(ID(ID::MAINKIND_ATOM | ID::SUBKIND_ATOM_ORDINARYG, *it), reg)); 00115 } 00116 else { 00117 gotOutput |= 00118 reg->printAtomForUser(o, *it); 00119 //DBGLOG(DBG,"printed with prefix '' and output " << gotOutput << " " << 00120 // printToString<RawPrinter>(ID(ID::MAINKIND_ATOM | ID::SUBKIND_ATOM_ORDINARYG, *it), reg)); 00121 } 00122 } 00123 } 00124 o << '}'; 00125 as->printWeightVector(o); 00126 o << std::endl; 00127 00128 if (ctx.config.getOption("WaitOnModel")) { 00129 std::cerr << "<waiting>" << std::endl; 00130 std::string line; 00131 std::getline(std::cin, line); 00132 } 00133 00134 // never abort 00135 return true; 00136 } 00137 00138 CSVAnswerSetPrinterCallback::CSVAnswerSetPrinterCallback(ProgramCtx& ctx, const std::string& predicate) : firstas(true) 00139 { 00140 RegistryPtr reg = ctx.registry(); 00141 00142 filterpm.reset(new PredicateMask); 00143 00144 // setup mask with registry 00145 filterpm->setRegistry(reg); 00146 00147 // setup mask with predicates 00148 ID pred = reg->storeConstantTerm(predicate); 00149 filterpm->addPredicate(pred); 00150 } 00151 00152 bool CSVAnswerSetPrinterCallback::operator()( 00153 AnswerSetPtr as) 00154 { 00155 DLVHEX_BENCHMARK_REGISTER_AND_SCOPE(sid,"AnswerSetPrinterCallback"); 00156 00157 // uses the Registry to print the interpretation, including 00158 // possible influence from AuxiliaryPrinter objects (if any are registered) 00159 00160 Interpretation::Storage::enumerator it, it_end; 00161 00162 RegistryPtr reg = as->interpretation->getRegistry(); 00163 // must be in this scope! 00164 Interpretation::Storage filteredbits; 00165 assert( !!filterpm && "filter must always be defined in CSV format" ); 00166 00167 filterpm->updateMask(); 00168 filteredbits = 00169 as->interpretation->getStorage() & filterpm->mask()->getStorage(); 00170 it = filteredbits.first(); 00171 it_end = filteredbits.end(); 00172 00173 std::ostream& o = std::cout; 00174 if (!firstas) o << std::endl; 00175 firstas = false; 00176 00177 typedef std::pair<IDAddress, IDAddress> OT; 00178 std::vector<OT> output; 00179 while( it != it_end ) { 00180 const OrdinaryAtom& oatom = reg->ogatoms.getByAddress(*it); 00181 if (oatom.tuple.size() < 3) throw GeneralError("Atoms which define CSV output must have an arity of 2 or greater."); 00182 output.push_back(OT(oatom.tuple[1].address, *it)); 00183 ++it; 00184 } 00185 std::sort(output.begin(), output.end()); 00186 bool first = true; 00187 BOOST_FOREACH (OT outputElement, output){ 00188 const OrdinaryAtom& oatom = reg->ogatoms.getByAddress(outputElement.second); 00189 if (!first) o << std::endl; 00190 first = false; 00191 for (int i = 2; i < oatom.tuple.size(); ++i) { 00192 o << (i > 2 ? ";" : ""); 00193 if (oatom.tuple[i].isIntegerTerm()) o << oatom.tuple[i].address; 00194 else o << reg->terms.getByID(oatom.tuple[i]).getUnquotedString(); 00195 } 00196 } 00197 00198 o << std::endl; 00199 00200 // never abort 00201 return true; 00202 } 00203 00204 DLVHEX_NAMESPACE_END 00205 00206 // vim:expandtab:ts=4:sw=4: 00207 // mode: C++ 00208 // End: