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 // HAVE_CONFIG_H 00041 00042 #include "dlvhex2/Benchmarking.h" 00043 #include "dlvhex2/ProgramCtx.h" 00044 #include "dlvhex2/Registry.h" 00045 #include "dlvhex2/PluginContainer.h" 00046 #include "dlvhex2/State.h" 00047 #include "dlvhex2/Printer.h" 00048 //#include "dlvhex2/DLVProcess.h" 00049 //#include "dlvhex2/EvalHeuristicEasy.h" 00050 00051 #include <boost/shared_ptr.hpp> 00052 00053 #include <sstream> 00054 #include <iostream> 00055 00056 DLVHEX_NAMESPACE_BEGIN 00057 00058 ProgramCtx::ProgramCtx(): 00059 maxint(0), currentOptimumRelevantLevels(0), terminationRequest(false) 00060 { 00061 config.setOption("AllowAggExtCycles",0); 00062 config.setOption("FLPDecisionCriterionHead", 1); 00063 config.setOption("FLPDecisionCriterionE", 1); 00064 config.setOption("FLPDecisionCriterionEM", 1); 00065 config.setOption("FLPDecisionCriterionEMI", 0); 00066 config.setOption("FLPCheck", 0); 00067 config.setOption("UFSCheck", 1); 00068 config.setOption("UFSCheckMonolithic", 0); 00069 config.setOption("UFSCheckAssumptionBased", 1); 00070 config.setOption("GenuineSolver", 0); 00071 config.setOption("ExternalLearning", 1); 00072 config.setOption("UFSLearning", 1); 00073 config.setOption("UFSLearnStrategy", 2); 00074 config.setOption("ExternalLearningIOBehavior", 1); 00075 config.setOption("ExternalLearningMonotonicity", 1); 00076 config.setOption("ExternalLearningFunctionality", 1); 00077 config.setOption("ExternalLearningLinearity", 1); 00078 config.setOption("ExternalLearningNeg", 1); 00079 config.setOption("ExternalLearningUser", 1); 00080 config.setOption("ExternalLearningGeneralize", 0); 00081 config.setOption("AlwaysEvaluateAllExternalAtoms", 0); 00082 config.setOption("NongroundNogoodInstantiation", 0); 00083 config.setOption("UFSCheckHeuristics", 0); 00084 config.setOption("ModelQueueSize", 5); 00085 config.setOption("Silent", 0); 00086 config.setOption("Verbose", 0); 00087 config.setOption("UseExtAtomCache",1); 00088 config.setOption("KeepNamespacePrefix",0); 00089 config.setOption("DumpDepGraph",0); 00090 config.setOption("DumpCyclicPredicateInputAnalysisGraph",0); 00091 config.setOption("DumpCompGraph",0); 00092 config.setOption("DumpEvalGraph",0); 00093 config.setOption("DumpModelGraph",0); 00094 config.setOption("DumpIModelGraph",0); 00095 config.setOption("DumpAttrGraph",0); 00096 config.setOption("KeepAuxiliaryPredicates",0); 00097 config.setOption("NoFacts",0); 00098 config.setOption("NumberOfModels",0); 00099 config.setOption("RepeatEvaluation",0); 00100 config.setOption("LegacyECycleDetection",0); 00101 config.setOption("NMLP", 0); 00102 config.setOption("MLP", 0); 00103 config.setOption("Forget", 0); 00104 config.setOption("Split", 0); 00105 config.setOption("SkipStrongSafetyCheck",0); 00106 config.setOption("LiberalSafety",1); 00107 config.setOption("IncludeAuxInputInAuxiliaries",0); 00108 config.setOption("DumpEvaluationPlan",0); 00109 config.setOption("DumpStats",0); 00110 // perhaps only temporary 00111 config.setOption("BenchmarkEAstderr",0); 00112 // perhaps only temporary 00113 config.setOption("ExplicitFLPUnshift",0); 00114 // perhaps only temporary 00115 config.setOption("PrintLearnedNogoods",0); 00116 // frumpy is the name of the failsafe clasp config option 00117 config.setStringOption("ClaspConfiguration","frumpy"); 00118 config.setOption("ClaspIncrementalInterpretationExtraction",1); 00119 config.setOption("ClaspSingletonLoopNogoods",0); 00120 config.setOption("ClaspInverseLiterals", 0); 00121 // propagate at least once per second, but also propagate all 10000 times we can propagate 00122 // TODO we should experiment with these 00123 config.setOption("ClaspDeferNPropagations", 10000); 00124 config.setOption("ClaspDeferMaxTMilliseconds",1000); 00125 // if 1, model generators will not register propagators for external atoms 00126 config.setOption("NoPropagator", 0); 00127 // see --help 00128 config.setOption("UseConstantSpace", 0); 00129 config.setOption("ClaspForceSingleThreaded", 0); 00130 config.setOption("LazyUFSCheckerInitialization", 0); 00131 config.setOption("SupportSets", 0); 00132 config.setOption("ExternalSourceInlining", 0); 00133 config.setOption("ForceGC", 0); 00134 config.setStringOption("PluginDirs", ""); 00135 config.setOption("IncrementalGrounding", 0); 00136 config.setOption("MinimizationSize", 10000); 00137 00138 // options related to WeakConstraintPlugin (we need to support this in the core for efficiency) 00139 // whether we handle answer set weights 00140 config.setOption("Optimization", 0); 00141 // whether we first find the optimum and then enumerate all optimal answer sets 00142 // this setting is used by the model builders: 00143 // if it is 0, enumeration finds models of same quality or better (the safe option) 00144 // (clasp MinimizeMode_t::Mode::optimize and currentOptimum is decreased by 1) 00145 // if it is 1, enumeration must find a better model 00146 // (clasp MinimizeMode_t::Mode::optimize and currentOptimum is used as it is) 00147 // if it is 2, enumeration finds all models of equal quality 00148 // (clasp MinimizeMode_t::Mode::enumOpt and currentOptimum is used as it is) 00149 // (if we use two step optimization, we use it with 1 to find the optimum and with 2 to enumerate optimal models) 00150 config.setOption("OptimizationTwoStep", 0); 00151 config.setOption("OptimizationByDlvhex", 0); 00152 config.setOption("OptimizationByBackend", 0); 00153 // if 1 then we only show optimal results, otherwise before getting optimal results we might get nonoptimal ones 00154 config.setOption("OptimizationFilterNonOptimal", 1); 00155 00156 config.setStringOption("DumpEANogoods", ""); 00157 config.setOption("MinimizeNogoods", 0); 00158 config.setOption("MinimizeNogoodsOpt", 0); 00159 config.setOption("MinimizeNogoodsOnConflict", 0); 00160 // forces all external atoms to be treated as inner 00161 config.setOption("NoOuterExternalAtoms", 0); 00162 config.setOption("UnitInconsistencyAnalysis", 0); 00163 config.setOption("UnitInconsistencyAnalysisDebug", 0); // analyze wrt. "explain" atoms 00164 config.setOption("TransUnitLearning", 0); 00165 config.setOption("ExternalAtomVerificationFromLearnedNogoods", 0); 00166 config.setOption("WaitOnModel", 0); 00167 00168 WARNING("TODO cleanup the setASPSoftware vs nGenuineSolver thing") 00169 // but if we have genuinegc, take genuinegc as default 00170 #if defined(HAVE_LIBGRINGO) && defined(HAVE_LIBCLASP) 00171 config.setOption("GenuineSolver", 4); 00172 #endif 00173 } 00174 00175 00176 ProgramCtx::~ProgramCtx() 00177 { 00178 DBGLOG(DBG,"resetting custom model generator provider"); 00179 if (!!customModelGeneratorProvider) customModelGeneratorProvider.reset(); 00180 00181 DBGLOG(DBG,"resetting state"); 00182 state.reset(); 00183 00184 DBGLOG(DBG,"resetting callbacks"); 00185 modelCallbacks.clear(); 00186 finalCallbacks.clear(); 00187 00188 DBGLOG(DBG,"resetting modelBuilder"); 00189 modelBuilder.reset(); 00190 00191 DBGLOG(DBG,"resetting parser"); 00192 parser.reset(); 00193 00194 DBGLOG(DBG,"resetting evalgraph"); 00195 evalgraph.reset(); 00196 00197 DBGLOG(DBG,"resetting compgraph"); 00198 compgraph.reset(); 00199 00200 DBGLOG(DBG,"resetting depgraph"); 00201 depgraph.reset(); 00202 00203 DBGLOG(DBG,"resetting edbList"); 00204 std::vector<InterpretationPtr>::iterator it = edbList.begin(); 00205 while ( it != edbList.end() ) { 00206 it->reset(); 00207 it++; 00208 } 00209 edb.reset(); 00210 00211 DBGLOG(DBG,"resetting inputProvider"); 00212 inputProvider.reset(); 00213 00214 DBGLOG(DBG,"resetting aspsoftware"); 00215 aspsoftware.reset(); 00216 00217 DBGLOG(DBG,"resetting pluginData"); 00218 pluginData.clear(); 00219 00220 DBGLOG(DBG,"resetting pluginEnvironment"); 00221 pluginEnvironment.clear(); 00222 00223 DBGLOG(DBG,"resetting registry, usage count was " << _registry.use_count() << " (it should be 2)"); 00224 // not printing, it creates too much clutter 00225 //if( Logger::Instance().shallPrint(Logger::DBG) ) 00226 // _registry->print(Logger::Instance().stream()) << std::endl; 00227 _registry.reset(); 00228 00229 DBGLOG(DBG,"resetting pluginAtoms"); 00230 pluginAtoms.clear(); 00231 00232 DBGLOG(DBG,"resetting pluginContainer, usage count was " << _pluginContainer.use_count() << " (it should be 1)"); 00233 _pluginContainer.reset(); 00234 } 00235 00236 00237 void 00238 ProgramCtx::changeState(const boost::shared_ptr<State>& s) 00239 { 00240 state = s; 00241 } 00242 00243 00244 // cannot change registry if something is already stored here 00245 void ProgramCtx::setupRegistry( 00246 RegistryPtr registry) 00247 { 00248 assert( 00249 ( 00250 !_registry || // allow to set from nothing 00251 // allow to change if empty 00252 (idb.empty() && !edb && idbList.size()==0 && edbList.size()==0 && pluginAtoms.empty()) 00253 ) 00254 && 00255 "cannot change registry once idb or edb or pluginAtoms contains data"); 00256 _registry = registry; 00257 _registry->setupAuxiliaryGroundAtomMask(); 00258 } 00259 00260 00261 void ProgramCtx::changeRegistry(RegistryPtr registry) 00262 { 00263 // clear everything that depends on IDs of registry 00264 idb.clear(); 00265 edb.reset(); 00266 idbList.clear(); 00267 edbList.clear(); 00268 pluginAtoms.clear(); 00269 00270 // setup new registry 00271 setupRegistry(registry); 00272 00273 // re-add plugin atoms (using new registry) 00274 addPluginAtomsFromPluginContainer(); 00275 } 00276 00277 00278 void ProgramCtx::setupPluginContainer( 00279 PluginContainerPtr pluginContainer) 00280 { 00281 assert( 00282 ( 00283 !_pluginContainer || // allow to set if unset 00284 pluginAtoms.empty() // allow to change if no atoms stored 00285 ) 00286 && 00287 "cannot change pluginContainer once pluginAtoms are used"); 00288 _pluginContainer = pluginContainer; 00289 WARNING("here we could reset the pointers in all ExternalAtoms if we unset the pluginContainer") 00290 } 00291 00292 00293 ASPSolverManager::SoftwareConfigurationPtr 00294 ProgramCtx::getASPSoftware() const 00295 { 00296 assert(aspsoftware != 0); 00297 return aspsoftware; 00298 } 00299 00300 00301 void ProgramCtx::setASPSoftware(ASPSolverManager::SoftwareConfigurationPtr software) 00302 { 00303 aspsoftware = software; 00304 } 00305 00306 00307 void ProgramCtx::showPlugins() { state->showPlugins(this); } 00308 void ProgramCtx::convert() { state->convert(this); } 00309 void ProgramCtx::parse() { state->parse(this); } 00310 void ProgramCtx::moduleSyntaxCheck() { state->moduleSyntaxCheck(this); } 00311 void ProgramCtx::mlpSolver() { state->mlpSolver(this); } 00312 void ProgramCtx::rewriteEDBIDB() { state->rewriteEDBIDB(this); } 00313 void ProgramCtx::safetyCheck() { state->safetyCheck(this); } 00314 void ProgramCtx::createDependencyGraph() { state->createDependencyGraph(this); } 00315 void ProgramCtx::liberalSafetyCheck() { state->checkLiberalSafety(this); } 00316 void ProgramCtx::optimizeEDBDependencyGraph() { state->optimizeEDBDependencyGraph(this); } 00317 void ProgramCtx::createComponentGraph() { state->createComponentGraph(this); } 00318 void ProgramCtx::strongSafetyCheck() { state->strongSafetyCheck(this); } 00319 void ProgramCtx::createEvalGraph() { state->createEvalGraph(this); } 00320 void ProgramCtx::setupProgramCtx() { state->setupProgramCtx(this); } 00321 void ProgramCtx::evaluate() { state->evaluate(this); } 00322 void ProgramCtx::postProcess() { state->postProcess(this); } 00323 00324 // ============================== subprogram handling ============================== 00325 00326 bool ProgramCtx::SubprogramAnswerSetCallback::operator()(AnswerSetPtr model) 00327 { 00328 answersets.push_back(model->interpretation); 00329 return true; 00330 } 00331 00332 00333 ProgramCtx::SubprogramAnswerSetCallback::~SubprogramAnswerSetCallback(){} 00334 00335 std::vector<InterpretationPtr> ProgramCtx::evaluateSubprogram(InterpretationConstPtr edb, std::vector<ID>& idb) 00336 { 00337 00338 ProgramCtx pc = *this; 00339 pc.idb = idb; 00340 pc.edb = InterpretationPtr(new Interpretation(*edb)); 00341 pc.currentOptimum.clear(); 00342 pc.currentOptimumRelevantLevels = 0; 00343 return evaluateSubprogram(pc, false); 00344 } 00345 00346 00347 std::vector<InterpretationPtr> ProgramCtx::evaluateSubprogram(InputProviderPtr& ip, InterpretationConstPtr addFacts) 00348 { 00349 00350 ProgramCtx pc = *this; 00351 pc.idb.clear(); 00352 pc.edb = InterpretationPtr(new Interpretation(this->registry())); 00353 pc.currentOptimum.clear(); 00354 pc.currentOptimumRelevantLevels = 0; 00355 pc.config.setOption("NumberOfModels",0); 00356 if( !!addFacts ) 00357 pc.edb->getStorage() |= addFacts->getStorage(); 00358 pc.inputProvider = ip; 00359 ip.reset(); 00360 00361 return evaluateSubprogram(pc, true); 00362 } 00363 00364 00365 std::vector<InterpretationPtr> ProgramCtx::evaluateSubprogram(ProgramCtx& pc, bool parse) 00366 { 00367 00368 DBGLOG(DBG, "Resetting context"); 00369 pc.state.reset(); 00370 pc.modelBuilder.reset(); 00371 pc.parser.reset(); 00372 pc.evalgraph.reset(); 00373 pc.compgraph.reset(); 00374 pc.depgraph.reset(); 00375 00376 pc.config.setOption("DumpDepGraph",0); 00377 pc.config.setOption("DumpCyclicPredicateInputAnalysisGraph",0); 00378 pc.config.setOption("DumpCompGraph",0); 00379 pc.config.setOption("DumpEvalGraph",0); 00380 pc.config.setOption("DumpModelGraph",0); 00381 pc.config.setOption("DumpIModelGraph",0); 00382 pc.config.setOption("DumpAttrGraph",0); 00383 00384 if( !pc.evalHeuristic ) { 00385 assert(false); 00386 throw GeneralError("No evaluation heuristics found"); 00387 } 00388 00389 DBGLOG(DBG, "Starting state pipeline " << (parse ? "with" : "without") << " parsing"); 00390 if (parse) { 00391 pc.changeState(StatePtr(new ConvertState)); 00392 } 00393 else { 00394 pc.changeState(StatePtr(new RewriteEDBIDBState)); 00395 } 00396 00397 if (parse) { 00398 pc.convert(); 00399 if( pc.terminationRequest ) throw GeneralError("Conversion of subprogram failed"); 00400 pc.parse(); 00401 if( pc.terminationRequest ) throw GeneralError("Parsing of subprogram failed"); 00402 } 00403 00404 DBGLOG(DBG, "Associate PluginAtom instances with ExternalAtom instances"); 00405 pc.associateExtAtomsWithPluginAtoms(pc.idb, true); 00406 if( pc.terminationRequest ) throw GeneralError("associateExtAtomsWithPluginAtoms(1) for subprogram failed"); 00407 pc.rewriteEDBIDB(); 00408 if( pc.terminationRequest ) throw GeneralError("rewrite EDBIDB for subprogram failed"); 00409 pc.associateExtAtomsWithPluginAtoms(pc.idb, true); 00410 if( pc.terminationRequest ) throw GeneralError("associateExtAtomsWithPluginAtoms(2) for subprogram failed"); 00411 pc.safetyCheck(); 00412 if( pc.terminationRequest ) throw GeneralError("Safety check for subprogram failed"); 00413 pc.liberalSafetyCheck(); 00414 if( pc.terminationRequest ) throw GeneralError("Liberal safety check for subprogram failed"); 00415 pc.createDependencyGraph(); 00416 if( pc.terminationRequest ) throw GeneralError("Create dependency graph for subprogram failed"); 00417 pc.optimizeEDBDependencyGraph(); 00418 if( pc.terminationRequest ) throw GeneralError("Optimize EDB dependency graph for subprogram failed"); 00419 pc.createComponentGraph(); 00420 if( pc.terminationRequest ) throw GeneralError("Create component graph for subprogram failed"); 00421 // use SCCs to do strong safety check 00422 if( !pc.config.getOption("SkipStrongSafetyCheck") ) { 00423 pc.strongSafetyCheck(); 00424 if( pc.terminationRequest ) GeneralError("Strong safety check for subprogram failed"); 00425 } 00426 pc.createEvalGraph(); 00427 if( pc.terminationRequest ) throw GeneralError("Create evaluation graph for subprogram failed"); 00428 pc.setupProgramCtx(); 00429 if( pc.terminationRequest ) throw GeneralError("Setup ProgramCtx for subprogram failed"); 00430 00431 DBGLOG(DBG, "Setting AnswerSetCallback"); 00432 pc.modelCallbacks.clear(); 00433 pc.finalCallbacks.clear(); 00434 SubprogramAnswerSetCallback* spasc = new SubprogramAnswerSetCallback(); 00435 ModelCallbackPtr spascp = ModelCallbackPtr(spasc); 00436 pc.modelCallbacks.push_back(spascp); 00437 00438 DBGLOG(DBG, "Evaluate subprogram"); 00439 pc.evaluate(); 00440 std::vector<InterpretationPtr> result; 00441 BOOST_FOREACH (InterpretationPtr intr, spasc->answersets) { 00442 result.push_back(intr); 00443 } 00444 00445 return result; 00446 } 00447 00448 00449 // ============================== end subprogram handling ============================== 00450 00451 #if 0 00452 PluginAtomPtr 00453 PluginContainer::getAtom(const std::string& name) const 00454 { 00455 PluginAtomMap::const_iterator pa = pluginAtoms.find(name); 00456 00457 if (pa == pluginAtoms.end()) 00458 return PluginAtomPtr(); 00459 00460 return pa->second; 00461 } 00462 #endif 00463 00464 void ProgramCtx::addPluginAtom(PluginAtomPtr atom) 00465 { 00466 assert(!!atom); 00467 assert(!!_registry); 00468 const std::string& predicate = atom->getPredicate(); 00469 LOG(PLUGIN,"adding PluginAtom '" << predicate << "'"); 00470 if( pluginAtoms.find(predicate) == pluginAtoms.end() ) { 00471 atom->setRegistry(_registry); 00472 pluginAtoms[predicate] = atom; 00473 } 00474 else { 00475 LOG(WARNING,"External atom " << predicate << " is already loaded (skipping)"); 00476 } 00477 } 00478 00479 00480 // call processOptions for each loaded plugin 00481 // (this is supposed to remove "recognized" options from pluginOptions) 00482 void ProgramCtx::processPluginOptions( 00483 std::list<const char*>& pluginOptions) 00484 { 00485 BOOST_FOREACH(PluginInterfacePtr plugin, pluginContainer()->getPlugins()) { 00486 LOG(DBG,"processing options for plugin " << plugin->getPluginName()); 00487 LOG(DBG,"currently have " << printrange(pluginOptions)); 00488 plugin->processOptions(pluginOptions, *this); 00489 } 00490 } 00491 00492 00493 void ProgramCtx::addPluginAtomsFromPluginContainer() 00494 { 00495 assert(!!pluginContainer()); 00496 assert(!!registry()); 00497 00498 BOOST_FOREACH(PluginInterfacePtr plugin, pluginContainer()->getPlugins()) { 00499 LOG(DBG,"adding plugin atoms from plugin " << plugin->getPluginName()); 00500 // always freshly create! (pluginatoms are linked to a registry, 00501 // so when using multiple registries, you have to create multiple pluginatoms) 00502 BOOST_FOREACH(PluginAtomPtr pap, plugin->createAtoms(*this)) { 00503 assert(!!pap); 00504 const std::string& pred = pap->getPredicate(); 00505 LOG(DBG," got plugin atom " << pred); 00506 if( pluginAtoms.count(pred) != 0 ) { 00507 LOG(WARNING,"warning: predicate '" << pred << "' already present in PluginAtomMap (skipping)"); 00508 } 00509 else { 00510 pap->setRegistry(registry()); 00511 pluginAtoms[pred] = pap; 00512 } 00513 } 00514 } 00515 } 00516 00517 00518 // associate plugins in container to external atoms in registry 00519 void ProgramCtx::associateExtAtomsWithPluginAtoms( 00520 const Tuple& idb, bool failOnUnknownAtom) 00521 { 00522 assert(!!_registry); 00523 DBGLOG_SCOPE(DBG,"aEAwPA",false); 00524 DBGLOG(DBG,"= associateExtAtomsWithPluginAtoms"); 00525 00526 Tuple eatoms; 00527 00528 // associate all rules 00529 for(Tuple::const_iterator it = idb.begin(); 00530 it != idb.end(); ++it) { 00531 assert(it->isRule()); 00532 // skip those without external atoms 00533 if( !it->doesRuleContainExtatoms() ) 00534 continue; 00535 00536 // associate all literals in rule body 00537 const Rule& rule = _registry->rules.getByID(*it); 00538 00539 // get external atoms (recursively) 00540 _registry->getExternalAtomsInTuple(rule.body, eatoms); 00541 } 00542 00543 // now associate 00544 for(Tuple::const_iterator it = eatoms.begin(); 00545 it != eatoms.end(); ++it) { 00546 assert(it->isExternalAtom()); 00547 00548 const ExternalAtom& eatom = _registry->eatoms.getByID(*it); 00549 00550 const std::string& predicate = _registry->getTermStringByID(eatom.predicate); 00551 // lookup pluginAtom to this eatom predicate 00552 PluginAtomMap::iterator itpa = pluginAtoms.find(predicate); 00553 if( itpa != pluginAtoms.end() ) { 00554 assert(!!itpa->second); 00555 // we store this as a POD pointer! 00556 eatom.pluginAtom = itpa->second.get(); 00557 eatom.prop |= itpa->second->getExtSourceProperties(); 00558 eatom.pluginAtom->setupProperties(eatom); 00559 if (!eatom.pluginAtom->checkOutputArity(eatom.getExtSourceProperties(), eatom.tuple.size())) { 00560 std::stringstream ss; 00561 ss << "External Atom " << RawPrinter::toString(_registry, *it) << " has a wrong output arity (should be " << eatom.pluginAtom->getOutputArity() << ")"; 00562 throw GeneralError(ss.str()); 00563 } 00564 } 00565 else { 00566 DBGLOG(DBG,"did not find plugin atom for predicate '" << predicate << "'"); 00567 if( failOnUnknownAtom ) { 00568 throw FatalError("did not find plugin atom " 00569 " for predicate '" + predicate + "'"); 00570 } 00571 } 00572 } 00573 } 00574 00575 00576 // setup this ProgramCtx (using setupProgramCtx() for of all plugins) 00577 void ProgramCtx::setupByPlugins() 00578 { 00579 BOOST_FOREACH(PluginInterfacePtr plugin, pluginContainer()->getPlugins()) { 00580 LOG(DBG,"setting up program ctx for plugin " << plugin->getPluginName()); 00581 plugin->setupProgramCtx(*this); 00582 } 00583 } 00584 00585 00586 // reset the cache of Plugins that use Environment 00587 void ProgramCtx::resetCacheOfPlugins(bool resetOnlyIfUsesEnvironment) 00588 { 00589 typedef std::pair<std::string, PluginAtomPtr> pairPluginAtomMap; 00590 BOOST_FOREACH(pairPluginAtomMap p, pluginAtoms) 00591 if( !resetOnlyIfUsesEnvironment || 00592 p.second->getExtSourceProperties().doesItUseEnvironment()) 00593 p.second->resetCache(); 00594 } 00595 00596 00597 DLVHEX_NAMESPACE_END 00598 00599 00600 // vim:expandtab:ts=4:sw=4: 00601 // mode: C++ 00602 // End: 00603 00604