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 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: