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