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