dlvhex  2.5.0
include/dlvhex2/PluginInterface.h
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 
00209 #if !defined(_DLVHEX_PLUGININTERFACE_H)
00210 #define _DLVHEX_PLUGININTERFACE_H
00211 
00212 #include "dlvhex2/PlatformDefinitions.h"
00213 #include "dlvhex2/fwd.h"
00214 #include "dlvhex2/ID.h"
00215 #include "dlvhex2/Atoms.h"
00216 #include "dlvhex2/Error.h"
00217 #include "dlvhex2/CDNLSolver.h"
00218 #include "dlvhex2/ComponentGraph.h"
00219 #include "dlvhex2/ExtSourceProperties.h"
00220 #include "dlvhex2/ExternalAtomEvaluationHeuristicsInterface.h"
00221 
00222 #include <boost/shared_ptr.hpp>
00223 #include <boost/unordered_map.hpp>
00224 #include <boost/thread/mutex.hpp>
00225 
00226 #include <map>
00227 #include <string>
00228 #include <iosfwd>
00229 #include <algorithm>
00230 
00231 #include <boost/shared_ptr.hpp>
00232 #include <boost/unordered_map.hpp>
00233 
00259 #define PLUGINABIVERSIONFUNCTION getDlvhex2ABIVersion
00260 #define PLUGINABIVERSIONFUNCTIONSTRING "getDlvhex2ABIVersion"
00261 
00262 #define PLUGINVERSIONFUNCTION getDlvhexPluginVersion
00263 #define PLUGINVERSIONFUNCTIONSTRING "getDlvhexPluginVersion"
00264 #define PLUGINIMPORTFUNCTION importPlugin
00265 #define PLUGINIMPORTFUNCTIONSTRING "importPlugin"
00266 #define IMPLEMENT_PLUGINABIVERSIONFUNCTION \
00267     extern "C" DLVHEX_PLUGINEXPORT int PLUGINABIVERSIONFUNCTION() \
00268     { \
00269         return DLVHEX_ABI_VERSION_MAJOR*10000+\
00270         DLVHEX_ABI_VERSION_MINOR*100+\
00271         DLVHEX_ABI_VERSION_MICRO; \
00272     }
00273 
00274 DLVHEX_NAMESPACE_BEGIN
00275 
00313 class DLVHEX_EXPORT PluginInterface
00314 {
00315     protected:
00321         PluginInterface():
00322         pluginName(),
00323             versionMajor(0),
00324             versionMinor(0),
00325             versionMicro(0)
00326             { }
00327 
00328         std::string pluginName;
00329         unsigned versionMajor;
00330         unsigned versionMinor;
00331         unsigned versionMicro;
00332 
00346         void setNameVersion(
00347             const std::string& name, unsigned major,
00348         unsigned minor, unsigned micro) {
00349             pluginName = name;
00350             versionMajor = major;
00351             versionMinor = minor;
00352             versionMicro = micro;
00353         }
00354 
00355     public:
00356         virtual ~PluginInterface() {}
00357 
00389         virtual std::vector<PluginAtomPtr> createAtoms(ProgramCtx& ctx) const;
00390 
00394         virtual void printUsage(std::ostream& o) const;
00395 
00404         virtual void processOptions(std::list<const char*>& pluginOptions, ProgramCtx& ctx);
00405 
00414         virtual PluginConverterPtr createConverter(ProgramCtx&);
00415 
00424         virtual std::vector<PluginConverterPtr> createConverters(ProgramCtx& ctx);
00425 
00431         virtual bool providesCustomModelGeneratorFactory(ProgramCtx& ctx) const { return false; }
00432 
00437         virtual BaseModelGeneratorFactoryPtr getCustomModelGeneratorFactory(ProgramCtx& ctx, const ComponentGraph::ComponentInfo& ci) const
00438             { assert(false && "This plugin does not provide a custom model generator factory"); return BaseModelGeneratorFactoryPtr(); }
00439 
00450         virtual std::vector<HexParserModulePtr> createParserModules(ProgramCtx&);
00451 
00458         virtual HexParserPtr createParser(ProgramCtx&);
00459 
00468         virtual PluginRewriterPtr createRewriter(ProgramCtx&);
00469 
00473         virtual PluginOptimizerPtr createOptimizer(ProgramCtx&);
00474 
00483         virtual void setupProgramCtx(ProgramCtx&) {  }
00484 
00485         const std::string& getPluginName() const
00486             { return this->pluginName; }
00487         unsigned getVersionMajor() const
00488             { return this->versionMajor; }
00489         unsigned getVersionMinor() const
00490             { return this->versionMinor; }
00491         unsigned getVersionMicro() const
00492             { return this->versionMicro; }
00493 
00494 };
00495 // beware: most of the time this Ptr will have to be created with a "deleter" in the library
00496 typedef boost::shared_ptr<PluginInterface> PluginInterfacePtr;
00497 
00509 class PluginData
00510 {
00511     public:
00512         PluginData() {}
00513         virtual ~PluginData() {}
00514 };
00515 typedef boost::shared_ptr<PluginData> PluginDataPtr;
00516 
00526 class PluginEnvironment
00527 {
00528     public:
00529         PluginEnvironment() {}
00530         virtual ~PluginEnvironment() {}
00531 };
00532 typedef boost::shared_ptr<PluginEnvironment> PluginEnvironmentPtr;
00533 
00699 class DLVHEX_EXPORT PluginAtom
00700 {
00701     public:
00720         struct DLVHEX_EXPORT Query
00721         {
00725             const ProgramCtx* ctx;
00726 
00735             InterpretationConstPtr interpretation;
00736 
00748             InterpretationConstPtr assigned;
00749 
00759             InterpretationConstPtr changed;
00760 
00770             Tuple input;
00771 
00780             Tuple pattern;
00781 
00783             ID eatomID;
00784 
00786             InterpretationPtr predicateInputMask;
00787 
00798             Query(const ProgramCtx* ctx,
00799                 InterpretationConstPtr interpretation,
00800                 const Tuple& input,
00801                 const Tuple& pattern,
00802                 ID eatomID = ID_FAIL,
00803                 const InterpretationPtr predicateInputMask = InterpretationPtr(),
00804                 const InterpretationConstPtr assigned = InterpretationConstPtr(),
00805                 const InterpretationConstPtr changed = InterpretationConstPtr()):
00806             ctx(ctx),
00807                 interpretation(interpretation),
00808                 input(input),
00809                 pattern(pattern),
00810                 eatomID(eatomID),
00811                 predicateInputMask(predicateInputMask),
00812                 assigned(assigned),
00813             changed(changed) {
00814             }
00818             void assign(const Query& q2);
00822             bool operator==(const Query& other) const;
00823         };
00824 
00835         struct DLVHEX_EXPORT Answer
00836         {
00840             Answer();
00841 
00845             std::vector<Tuple>& get() { used = true; return *output; }
00846 
00850             const std::vector<Tuple>& get() const { return *output; }
00851 
00855             std::vector<Tuple>& getUnknown() { used = true; return *unknown; }
00856 
00860             const std::vector<Tuple>& getUnknown() const { return *unknown; }
00861 
00866             bool hasBeenUsed() const { return used; }
00867 
00874             void use() { used = true; }
00875 
00881             Answer& operator=(const Answer& other)
00882                 { output = other.output; unknown = other.unknown; used = true; return *this; }
00883 
00893             bool operator==(const Answer& other) const;
00894 
00895             private:
00896                 // \brief stores the positive output values; shared_ptr storage for have low-cost-copying of this object and for a more efficient query answer cache implementation.
00897                 boost::shared_ptr<std::vector<Tuple> > output;
00898                 // \brief stores the unknown output values (those neither in output nor in unknown are false); shared_ptr storage for have low-cost-copying of this object and for a more efficient query answer cache implementation.
00899                 boost::shared_ptr<std::vector<Tuple> > unknown;
00900                 // usage marker: true if this was default-constructed and never used
00901                 bool used;
00902         };
00903 
00914         typedef enum {
00917             PREDICATE,
00920             CONSTANT,
00925             TUPLE
00926         } InputType;
00927 
00928     protected:
00949         PluginAtom(const std::string& predicate, bool monotonic):
00950         predicate(predicate),
00951         allmonotonic(monotonic) {
00952             prop.pa = this;
00953         }
00954 
00955         // The following functions are to be used in the constructor only.
00956 
00965         void addInputPredicate(bool nameIsRelevant = false);
00966 
00972         void addInputConstant();
00973 
00979         void addInputTuple();
00980 
00990         void setOutputArity(unsigned arity);
00991 
00992     public:
00996         virtual ~PluginAtom() {}
00997 
01002         int getInputArity() const;
01003 
01008         int getOutputArity() const;
01009 
01018         bool checkInputArity(unsigned arity) const;
01019 
01025         bool checkOutputArity(const ExtSourceProperties& prop, unsigned arity) const;
01026 
01047         virtual void setupProperties(const ExternalAtom& eatom) {}
01048 
01060         virtual void guardSupportSet(bool& keep, Nogood& ng, const ID eaReplacement) { assert(ng.isGround()); keep = true; }
01061 
01079         bool retrieveFacade(const Query& query, Answer& answer, NogoodContainerPtr nogoods, bool useCache);
01080 
01094         virtual bool retrieveCached(const Query& query, Answer& answer, NogoodContainerPtr nogoods);
01095 
01117         virtual void retrieve(const Query& query, Answer& answer, NogoodContainerPtr nogoods);
01118 
01139         virtual void retrieve(const Query& query, Answer& answer);
01140 
01151         virtual void learnSupportSets(const Query& query, NogoodContainerPtr nogoods);
01152 
01160         virtual void generalizeNogood(Nogood ng, ProgramCtx* ctx, NogoodContainerPtr nogoods);
01161 
01174         virtual std::vector<Query> splitQuery(const Query& query, const ExtSourceProperties& prop);
01175 
01185         InputType getInputType(unsigned index) const;
01186 
01195         const std::vector<InputType>& getInputTypes() const
01196             { return inputType; }
01197 
01203         virtual bool providesCustomExternalAtomEvaluationHeuristicsFactory() const { return false; }
01204 
01210         virtual ExternalAtomEvaluationHeuristicsFactoryPtr getCustomExternalAtomEvaluationHeuristicsFactory() const
01211             { assert(false && "This plugin atom does not provide a custom external atom evaluation heuristics factory"); return ExternalAtomEvaluationHeuristicsFactoryPtr(); }
01212 
01216         const ExtSourceProperties& getExtSourceProperties() const
01217         {
01218             return prop;
01219         }
01220 
01221         // Associate plugin atom with registry pointer.
01222         // (This implicitly calculates the predicate ID.)
01223 
01241         virtual void setRegistry(RegistryPtr reg);
01242 
01254         RegistryPtr getRegistry() const
01255             { return registry; }
01256 
01264         ID getPredicateID() const
01265             { return predicateID; }
01266 
01274         const std::string& getPredicate() const
01275             { return predicate; }
01276 
01278         PredicateMaskPtr getReplacements(){ replacements->updateMask(); return replacements; }
01279 
01283         void resetCache() {
01284             queryAnswerNogoodCache.clear();
01285         }
01286 
01287     protected:
01288         // \brief Predicate of the atom as it appears in HEX programs (without leading &)
01289         //
01290         // This is not stored as ID, because plugins must be allowed to create
01291         // atoms without knowing the registry they will be used with.
01292         //
01293         // Calling setRegistry provides the predicate ID.
01294         std::string predicate;
01295 
01297         ID predicateID;
01298 
01300         bool allmonotonic;
01301 
01303         ExtSourceProperties prop;
01304 
01306         std::vector<InputType> inputType;
01307 
01309         unsigned outputSize;
01310 
01311         // Query/Answer cache
01313         typedef boost::unordered_map<const Query, std::pair<Answer, SimpleNogoodContainerPtr> > QueryAnswerNogoodCache;
01315         typedef boost::unordered_map<const Query, SimpleNogoodContainerPtr> QueryNogoodCache;
01317         QueryAnswerNogoodCache queryAnswerNogoodCache;
01319         boost::mutex cacheMutex;
01320 
01322         PredicateMaskPtr replacements;
01323 
01325         std::vector<Tuple> otuples;
01326 
01332         RegistryPtr registry;
01333 
01334     private:
01339         PluginAtom(const PluginAtom& pa){}
01340 
01346         const PluginAtom& operator=(const PluginAtom& pa){ return *this; }
01347 };
01348 
01349 typedef boost::shared_ptr<PluginAtom> PluginAtomPtr;
01350 typedef boost::weak_ptr<PluginAtom> PluginAtomWeakPtr;
01351 // hash function for QueryAnswerCache
01352 std::size_t hash_value(const PluginAtom::Query& q);
01353 
01369 class DLVHEX_EXPORT PluginConverter
01370 {
01371     public:
01372         virtual ~PluginConverter() { }
01373 
01382         virtual void convert(std::istream& i, std::ostream& o) = 0;
01383 };
01384 typedef boost::shared_ptr<PluginConverter> PluginConverterPtr;
01385 
01396 class ModelCallback:
01397 public std::unary_function<bool, AnswerSetPtr>
01398 {
01399     public:
01400         virtual ~ModelCallback() {}
01407         virtual bool operator()(AnswerSetPtr as) = 0;
01408 };
01409 typedef boost::shared_ptr<ModelCallback> ModelCallbackPtr;
01410 
01420 class FinalCallback
01421 {
01422     public:
01423         virtual ~FinalCallback() {}
01427         virtual void operator()() = 0;
01428 };
01429 typedef boost::shared_ptr<FinalCallback> FinalCallbackPtr;
01430 
01446 class DLVHEX_EXPORT PluginRewriter
01447 {
01448     protected:
01449         PluginRewriter() {}
01450 
01451     public:
01455         virtual ~PluginRewriter() {}
01456 
01466         virtual void rewrite(ProgramCtx& ctx) = 0;
01467 };
01468 typedef boost::shared_ptr<PluginRewriter> PluginRewriterPtr;
01469 
01482 class DLVHEX_EXPORT PluginOptimizer
01483 {
01484     public:
01485         virtual ~PluginOptimizer() {}
01486 
01492         virtual void optimize(InterpretationPtr edb, DependencyGraphPtr depgraph) = 0;
01493 };
01494 
01495 //
01496 // deleters
01497 //
01498 
01509 template<typename AllocatedT>
01510 struct PluginPtrDeleter
01511 {
01512     PluginPtrDeleter() {}
01517     inline void operator()(const AllocatedT* ptr) const
01518     {
01519         delete ptr;
01520     }
01521 };
01522 
01534 template<typename AllocatedT>
01535 struct PluginPtrNOPDeleter
01536 {
01537     PluginPtrNOPDeleter() {}
01542     inline void operator()(const AllocatedT* ptr) const
01543     {
01544         // NOP = do not delete
01545     }
01546 };
01547 
01548 DLVHEX_NAMESPACE_END
01549 #endif                           // _DLVHEX_PLUGININTERFACE_H
01550 
01551 
01552 // vim:expandtab:ts=4:sw=4:
01553 // mode: C++
01554 // End:
01555