dlvhex  2.5.0
src/ProgramCtx.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                           // 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