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 #ifdef HAVE_CONFIG_H 00035 #include "config.h" 00036 #endif // HAVE_CONFIG_H 00037 00038 #define DLVHEX_BENCHMARK 00039 00040 #include "dlvhex2/PlainModelGenerator.h" 00041 #include "dlvhex2/Logger.h" 00042 #include "dlvhex2/Registry.h" 00043 #include "dlvhex2/Printer.h" 00044 #include "dlvhex2/ASPSolver.h" 00045 #include "dlvhex2/ProgramCtx.h" 00046 #include "dlvhex2/PluginInterface.h" 00047 #include "dlvhex2/Benchmarking.h" 00048 00049 #include <boost/foreach.hpp> 00050 00051 DLVHEX_NAMESPACE_BEGIN 00052 00053 PlainModelGeneratorFactory::PlainModelGeneratorFactory( 00054 ProgramCtx& ctx, 00055 const ComponentInfo& ci, 00056 ASPSolverManager::SoftwareConfigurationPtr externalEvalConfig): 00057 BaseModelGeneratorFactory(), 00058 externalEvalConfig(externalEvalConfig), 00059 ctx(ctx), 00060 eatoms(ci.outerEatoms), 00061 idb(), 00062 xidb() 00063 { 00064 RegistryPtr reg = ctx.registry(); 00065 00066 // this model generator can handle: 00067 // components with outer eatoms 00068 // components with inner rules 00069 // components with inner constraints 00070 // this model generator CANNOT handle: 00071 // components with inner eatoms 00072 00073 assert(ci.innerEatoms.empty()); 00074 00075 // copy rules and constraints to idb 00076 // TODO we do not need this except for debugging 00077 idb.reserve(ci.innerRules.size() + ci.innerConstraints.size()); 00078 idb.insert(idb.end(), ci.innerRules.begin(), ci.innerRules.end()); 00079 idb.insert(idb.end(), ci.innerConstraints.begin(), ci.innerConstraints.end()); 00080 00081 // transform original innerRules and innerConstraints 00082 // to xidb with only auxiliaries 00083 xidb.reserve(ci.innerRules.size() + ci.innerConstraints.size()); 00084 std::back_insert_iterator<std::vector<ID> > inserter(xidb); 00085 std::transform(ci.innerRules.begin(), ci.innerRules.end(), 00086 inserter, boost::bind( 00087 &PlainModelGeneratorFactory::convertRule, this, ctx, _1)); 00088 std::transform(ci.innerConstraints.begin(), ci.innerConstraints.end(), 00089 inserter, boost::bind( 00090 &PlainModelGeneratorFactory::convertRule, this, ctx, _1)); 00091 00092 #ifndef NDEBUG 00093 { 00094 { 00095 std::ostringstream s; 00096 RawPrinter printer(s,ctx.registry()); 00097 printer.printmany(idb," "); 00098 DBGLOG(DBG,"PlainModelGeneratorFactory got idb " << s.str()); 00099 } 00100 { 00101 std::ostringstream s; 00102 RawPrinter printer(s,ctx.registry()); 00103 printer.printmany(xidb," "); 00104 DBGLOG(DBG,"PlainModelGeneratorFactory got xidb " << s.str()); 00105 } 00106 } 00107 #endif 00108 } 00109 00110 00111 std::ostream& PlainModelGeneratorFactory::print( 00112 std::ostream& o) const 00113 { 00114 RawPrinter printer(o, ctx.registry()); 00115 o << "outer eatoms:" << std::endl; 00116 if( !eatoms.empty() ) { 00117 printer.printmany(eatoms,"\n"); 00118 } 00119 o << "xidb:" << std::endl; 00120 if( !xidb.empty() ) { 00121 printer.printmany(xidb,"\n"); 00122 } 00123 return o; 00124 } 00125 00126 00127 PlainModelGenerator::PlainModelGenerator( 00128 Factory& factory, 00129 InterpretationConstPtr input): 00130 BaseModelGenerator(input), 00131 factory(factory) 00132 { 00133 } 00134 00135 00136 PlainModelGenerator::InterpretationPtr 00137 PlainModelGenerator::generateNextModel() 00138 { 00139 RegistryPtr reg = factory.ctx.registry(); 00140 if( currentResults == 0 ) { 00141 do { // breakout possibility 00142 // we need to create currentResults 00143 00144 // create new interpretation as copy 00145 Interpretation::Ptr newint; 00146 if( input == 0 ) { 00147 // empty construction 00148 newint.reset(new Interpretation(reg)); 00149 } 00150 else { 00151 // copy construction 00152 newint.reset(new Interpretation(*input)); 00153 } 00154 00155 // augment input with edb 00156 newint->add(*factory.ctx.edb); 00157 00158 // remember facts so far (we have to remove these from any output) 00159 InterpretationConstPtr mask(new Interpretation(*newint)); 00160 00161 // manage outer external atoms 00162 if( !factory.eatoms.empty() ) { 00163 // augment input with result of external atom evaluation 00164 // use newint as input and as output interpretation 00165 IntegrateExternalAnswerIntoInterpretationCB cb(newint); 00166 evaluateExternalAtoms(factory.ctx, factory.eatoms, newint, cb); 00167 DLVHEX_BENCHMARK_REGISTER(sidcountexternalanswersets, 00168 "outer eatom computations"); 00169 DLVHEX_BENCHMARK_COUNT(sidcountexternalanswersets,1); 00170 00171 if( factory.xidb.empty() ) { 00172 // we only have eatoms -> return singular result 00173 00174 // remove EDB and direct input from newint 00175 // (keep local models as small as possible) 00176 newint->getStorage() -= mask->getStorage(); 00177 00178 PreparedResults* pr = new PreparedResults; 00179 currentResults.reset(pr); 00180 pr->add(AnswerSetPtr(new AnswerSet(newint))); 00181 break; 00182 } 00183 } 00184 00185 // store in model generator and store as const 00186 postprocessedInput = newint; 00187 00188 DLVHEX_BENCHMARK_REGISTER_AND_START(sidaspsolve, 00189 "initiating external solver"); 00190 OrdinaryASPProgram program(reg, 00191 factory.xidb, postprocessedInput, factory.ctx.maxint, mask); 00192 ASPSolverManager mgr; 00193 currentResults = mgr.solve(*factory.externalEvalConfig, program); 00194 DLVHEX_BENCHMARK_STOP(sidaspsolve); 00195 } 00196 while(false); // end of breakout possibility 00197 } 00198 00199 assert(currentResults != 0); 00200 AnswerSet::Ptr ret = currentResults->getNextAnswerSet(); 00201 if( ret == 0 ) { 00202 currentResults.reset(); 00203 // the following is just for freeing memory early 00204 postprocessedInput.reset(); 00205 return InterpretationPtr(); 00206 } 00207 DLVHEX_BENCHMARK_REGISTER(sidcountplainanswersets, "PlainMG answer sets"); 00208 DLVHEX_BENCHMARK_COUNT(sidcountplainanswersets,1); 00209 00210 return ret->interpretation; 00211 } 00212 00213 00214 DLVHEX_NAMESPACE_END 00215 00216 // vim:expandtab:ts=4:sw=4: 00217 // mode: C++ 00218 // End: