dlvhex  2.5.0
src/ASPSolver.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 
00038 #ifdef HAVE_CONFIG_H
00039 #  include "config.h"
00040 #endif
00041 
00042 #include "dlvhex2/ASPSolver.h"
00043 #include "dlvhex2/PlatformDefinitions.h"
00044 #include "dlvhex2/Benchmarking.h"
00045 #include "dlvhex2/Printer.h"
00046 #include "dlvhex2/Registry.h"
00047 #include "dlvhex2/ProgramCtx.h"
00048 #include "dlvhex2/AnswerSet.h"
00049 
00050 #ifdef HAVE_LIBDLV
00051 # include "dlv.h"
00052 #endif
00053 
00054 #include <boost/thread.hpp>
00055 #include <boost/shared_ptr.hpp>
00056 #include <boost/foreach.hpp>
00057 #include <list>
00058 
00059 DLVHEX_NAMESPACE_BEGIN
00060 
00061 namespace ASPSolver
00062 {
00063 
00064     //
00065     // DLVLibSoftware (currently not in working condition, libdlv is not released)
00066     //
00067     #ifdef HAVE_LIBDLV
00068 
00069     // if this does not work, maybe the old other branch helps
00070     // (it was not fully working back then either, but maybe there are hints)
00071     // https://dlvhex.svn.sourceforge.net/svnroot/dlvhex/dlvhex/branches/dlvhex-libdlv-integration@2879
00072 
00073     struct DLVLibSoftware::Delegate::Impl
00074     {
00075         Options options;
00076         PROGRAM_HANDLER *ph;
00077         RegistryPtr reg;
00078 
00079         Impl(const Options& options):
00080         options(options),
00081         ph(create_program_handler()) {
00082             if( options.includeFacts )
00083                 ph->setOption(INCLUDE_FACTS, 1);
00084             else
00085                 ph->setOption(INCLUDE_FACTS, 0);
00086             BOOST_FOREACH(const std::string& arg, options.arguments) {
00087                 if( arg == "-silent" ) {
00088                     // do nothing?
00089                 }
00090                 else
00091                     throw std::runtime_error("dlv-lib commandline option not implemented: " + arg);
00092             }
00093         }
00094 
00095         ~Impl() {
00096             destroy_program_handler(ph);
00097         }
00098     };
00099 
00100     DLVLibSoftware::Delegate::Delegate(const Options& options):
00101     pimpl(new Impl(options)) {
00102     }
00103 
00104     DLVLibSoftware::Delegate::~Delegate() {
00105     }
00106 
00107     void
00108     DLVLibSoftware::Delegate::useASTInput(const OrdinaryASPProgram& program) {
00109         DLVHEX_BENCHMARK_REGISTER_AND_SCOPE(sid,"DLVLibSoftware::Delegate::useASTInput");
00110 
00111         // TODO HO checks
00112 
00113         try
00114         {
00115             pimpl->reg = program.registry;
00116             assert(pimpl->reg);
00117             if( program.maxint != 0 )
00118                 pimpl->ph->setMaxInt(program.maxint);
00119 
00120             pimpl->ph->clearProgram();
00121 
00122             // output program
00123             std::stringstream programStream;
00124             RawPrinter printer(programStream, program.registry);
00125             // TODO HO stuff
00126 
00127             if( program.edb != 0 ) {
00128                 // print edb interpretation as facts
00129                 program.edb->printAsFacts(programStream);
00130                 programStream << "\n";
00131                 programStream.flush();
00132             }
00133 
00134             printer.printmany(program.idb, "\n");
00135             programStream.flush();
00136 
00137             DBGLOG(DBG,"sending program to dlv-lib:===");
00138             DBGLOG(DBG,programStream.str());
00139             DBGLOG(DBG,"==============================");
00140             pimpl->ph->Parse(programStream);
00141             pimpl->ph->ResolveProgram(SYNCRONOUSLY);
00142         }
00143         catch(const std::exception& e) {
00144             LOG(ERROR,"EXCEPTION: " << e.what());
00145             throw;
00146         }
00147     }
00148 
00149     // reuse DLVResults class from above
00150 
00151     ASPSolverManager::ResultsPtr
00152     DLVLibSoftware::Delegate::getResults() {
00153         DLVHEX_BENCHMARK_REGISTER_AND_SCOPE(sid,"DLVLibSoftware::Delegate::getResults");
00154 
00155         //DBGLOG(DBG,"getting results");
00156         try
00157         {
00158             // for now, we parse all results and store them into the result container
00159             // later we should do kind of an online processing here
00160 
00161             boost::shared_ptr<DLVResults> ret(new DLVResults);
00162 
00163             // TODO really do incremental model fetching
00164             const std::vector<MODEL> *models = pimpl->ph->getAllModels();
00165             std::vector<MODEL>::const_iterator itm;
00166             // iterate over models
00167             for(itm = models->begin();
00168             itm != models->end(); ++itm) {
00169                 AnswerSet::Ptr as(new AnswerSet(pimpl->reg));
00170 
00171                 // iterate over atoms
00172                 for(MODEL_ATOMS::const_iterator ita = itm->begin();
00173                 ita != itm->end(); ++ita) {
00174                     const char* pname = ita->getName();
00175                     assert(pname);
00176 
00177                     // i have a hunch this might be the encoding
00178                     assert(pname[0] != '-');
00179 
00180                     typedef std::list<const char*> ParmList;
00181                     ParmList parms;
00182                     //DBGLOG(DBG,"creating predicate with first term '" << pname << "'");
00183                     parms.push_back(pname);
00184 
00185                     // TODO HO stuff
00186                     // TODO integer terms
00187 
00188                     for(MODEL_TERMS::const_iterator itt = ita->getParams().begin();
00189                     itt != ita->getParams().end(); ++itt) {
00190                         switch(itt->type) {
00191                             case 1:
00192                                 // string terms
00193                                 //std::cerr << "creating string term '" << itt->data.item << "'" << std::endl;
00194                                 parms.push_back(itt->data.item);
00195                                 break;
00196                             case 2:
00197                                 // int terms
00198                                 //std::cerr << "creating int term '" << itt->data.number << "'" << std::endl;
00199                                 assert(false);
00200                                 //ptuple.push_back(new dlvhex::Term(itt->data.number));
00201                                 break;
00202                             default:
00203                                 throw std::runtime_error("unknown term type!");
00204                         }
00205                     }
00206 
00207                     // for each param in parms: find id and put into tuple
00208                     WARNING("TODO create something like inline ID TermTable::getByStringOrRegister(const std::string& symbol, IDKind kind)")
00209                         Tuple ptuple;
00210                     ptuple.reserve(parms.size());
00211                     assert(pimpl->reg);
00212                     for(ParmList::const_iterator itp = parms.begin();
00213                     itp != parms.end(); ++itp) {
00214                         // constant term
00215                         ID id = pimpl->reg->terms.getIDByString(*itp);
00216                         if( id == ID_FAIL ) {
00217                             Term t(ID::MAINKIND_TERM  | ID::SUBKIND_TERM_CONSTANT, *itp);
00218                             id = pimpl->reg->terms.storeAndGetID(t);
00219                         }
00220                         assert(id != ID_FAIL);
00221                         DBGLOG(DBG,"got term " << *itp << " with id " << id);
00222                         ptuple.push_back(id);
00223                     }
00224 
00225                     // ogatom
00226                     ID fid = pimpl->reg->ogatoms.getIDByTuple(ptuple);
00227                     if( fid == ID_FAIL ) {
00228                         OrdinaryAtom a(ID::MAINKIND_ATOM | ID::SUBKIND_ATOM_ORDINARYG);
00229                         a.tuple.swap(ptuple);
00230                         {
00231                             WARNING("parsing efficiency problem see HexGrammarPTToASTConverter")
00232                                 std::stringstream ss;
00233                             RawPrinter printer(ss, pimpl->reg);
00234                             Tuple::const_iterator it = ptuple.begin();
00235                             printer.print(*it);
00236                             it++;
00237                             if( it != ptuple.end() ) {
00238                                 ss << "(";
00239                                 printer.print(*it);
00240                                 it++;
00241                                 while(it != ptuple.end()) {
00242                                     ss << ",";
00243                                     printer.print(*it);
00244                                     it++;
00245                                 }
00246                                 ss << ")";
00247                             }
00248                             a.text = ss.str();
00249                         }
00250                         fid = pimpl->reg->ogatoms.storeAndGetID(a);
00251                         DBGLOG(DBG,"added fact " << a << " with id " << fid);
00252                     }
00253                     DBGLOG(DBG,"got fact with id " << fid);
00254                     assert(fid != ID_FAIL);
00255                     as->interpretation->setFact(fid.address);
00256                 }
00257 
00258                 ret->add(as);
00259             }
00260 
00261             // TODO: is this necessary?
00262             // delete models;
00263 
00264             ASPSolverManager::ResultsPtr baseret(ret);
00265             return baseret;
00266         }
00267         catch(const std::exception& e) {
00268             LOG(ERROR,"EXCEPTION: " << e.what());
00269             throw;
00270         }
00271     }
00272     #endif                       // HAVE_LIBDLV
00273 
00274     WARNING("TODO reactivate dlvdb")
00275 
00276         #if 0
00277         #if defined(HAVE_DLVDB)
00278         DLVDBSoftware::Options::Options():
00279     DLVSoftware::Options(),
00280     typFile() {
00281     }
00282 
00283     DLVDBSoftware::Options::~Options() {
00284     }
00285 
00286     DLVDBSoftware::Delegate::Delegate(const Options& opt):
00287     DLVSoftware::Delegate(opt),
00288     options(opt) {
00289     }
00290 
00291     DLVDBSoftware::Delegate::~Delegate() {
00292     }
00293 
00294     void DLVDBSoftware::Delegate::setupProcess() {
00295         DLVSoftware::Delegate::setupProcess();
00296 
00297         proc.setPath(DLVDBPATH);
00298                                  // turn on database support
00299         proc.addOption("-DBSupport");
00300         proc.addOption("-ORdr-");// turn on rewriting of false body rules
00301         if( !options.typFile.empty() )
00302             proc.addOption(options.typFile);
00303 
00304     }
00305     #endif                       // defined(HAVE_DLVDB)
00306     #endif
00307 
00308 }                                // namespace ASPSolver
00309 
00310 
00311 DLVHEX_NAMESPACE_END
00312 
00313 
00314 // vim:expandtab:ts=4:sw=4:
00315 // mode: C++
00316 // End: