knowrob  2.1.0
A Knowledge Base System for Cognition-enabled Robots
GoalDrivenReasoner.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of KnowRob, please consult
3  * https://github.com/knowrob/knowrob for license details.
4  */
5 
6 #include "knowrob/reasoner/GoalDrivenReasoner.h"
7 #include "knowrob/integration/python/utils.h"
8 #include "knowrob/integration/python/gil.h"
9 #include "knowrob/reasoner/RDFGoalReasoner.h"
10 
11 using namespace knowrob;
12 
14  return (features_ & static_cast<int>(feature)) != 0;
15 }
16 
18  features_ = features_ | static_cast<int>(feature);
19 }
20 
22  return definedRelations_.count(indicator) > 0;
23 }
24 
25 bool GoalDrivenReasoner::isClassDefined(const std::string_view &iri) {
26  return definedClasses_.find(PredicateIndicator(iri, 1)) != definedClasses_.end();
27 }
28 
30  KB_DEBUG("Defining relation {} with arity {} in reasoner {}",
31  *indicator.functor(), indicator.arity(), *reasonerName());
32  definedRelations_.insert(indicator);
33 }
34 
36  KB_DEBUG("Defining relation {} with arity 2 in reasoner {}",
37  iri->stringForm(), *reasonerName());
38  definedRelations_.insert(PredicateIndicator(iri->stringForm(), 2));
39 }
40 
42  KB_DEBUG("Undefining relation {} with arity {} in reasoner {}",
43  *indicator.functor(), indicator.arity(), *reasonerName());
44  definedRelations_.erase(indicator);
45 }
46 
48  KB_DEBUG("Defining class {} in reasoner {}",
49  iri->stringForm(), *reasonerName());
50  definedClasses_.insert(PredicateIndicator(iri->stringForm(), 1));
51 }
52 
54  KB_DEBUG("Undefining class {} in reasoner {}",
55  iri->stringForm(), *reasonerName());
56  definedClasses_.erase(PredicateIndicator(iri->stringForm(), 1));
57 }
58 
60  if (reasoner->reasonerLanguage() == PluginLanguage::PYTHON) {
61  // If the reasoner uses Python code, then we must make sure that the GIL is acquired
62  // in the current thread before calling the reasoner.
63  // Note that due to Python's GIL, only one thread can execute Python code at a time
64  // but Python should do switching between threads automatically.
65  py::gil_lock acquire;
66  run_();
67  } else {
68  run_();
69  }
70 }
71 
72 void ReasonerRunner::run_() {
73  if (!reasoner->evaluate(query)) {
74  KB_WARN("Reasoner {} produced 'false' in query evaluation for query: {}",
75  *reasoner->reasonerName(), *query->formula());
76  }
77  query->finish();
78 }
79 
80 namespace knowrob::py {
81  // this struct is needed because Reasoner has pure virtual methods
82  struct GoalDrivenReasonerWrap : public GoalDrivenReasoner, boost::python::wrapper<GoalDrivenReasoner> {
83  explicit GoalDrivenReasonerWrap(PyObject *p) : GoalDrivenReasoner(), self(p) {}
84 
85  bool initializeReasoner(const PropertyTree &config) override {
86  return call_method<bool>(self, "initializeReasoner", config);
87  }
88 
89  bool evaluate(GoalPtr query) override {
90  return call_method<bool>(self, "evaluate", query);
91  }
92 
93  private:
94  PyObject *self;
95  };
96 
97  template<>
99  using namespace boost::python;
100 
101  using Define1 = void (GoalDrivenReasoner::*)(const PredicateIndicator &);
102  using Define2 = void (GoalDrivenReasoner::*)(const IRIAtomPtr &);
103 
104  // export the GoalDrivenReasonerFeature enum
105  enum_<GoalDrivenReasonerFeature>("GoalDrivenReasonerFeature")
106  .value("SupportsSimpleConjunctions", GoalDrivenReasonerFeature::SupportsSimpleConjunctions)
107  .value("SupportsExtensionalGrounding", GoalDrivenReasonerFeature::SupportsExtensionalGrounding);
108 
109  // export the GoalDrivenReasoner class
110  class_<GoalDrivenReasoner, std::shared_ptr<GoalDrivenReasonerWrap>, bases<Reasoner>, boost::noncopyable>
111  ("GoalDrivenReasoner", init<>())
112  .def("hasFeature", &GoalDrivenReasoner::hasFeature)
113  .def("enableFeature", &GoalDrivenReasoner::enableFeature)
114  .def("isRelationDefined", &GoalDrivenReasoner::isRelationDefined)
115  .def("isClassDefined", &GoalDrivenReasoner::isClassDefined)
116  .def("defineRelation", static_cast<Define1>(&GoalDrivenReasoner::defineRelation))
117  .def("defineRelation", static_cast<Define2>(&GoalDrivenReasoner::defineRelation))
118  .def("defineClass", &GoalDrivenReasoner::defineClass)
119  .def("undefineRelation", &GoalDrivenReasoner::undefineRelation)
120  .def("undefineClass", &GoalDrivenReasoner::undefineClass)
121  // methods that must be implemented by reasoner plugins
122  .def("evaluate", &GoalDrivenReasonerWrap::evaluate);
123 
124  // export sub-types
127  }
128 }
#define KB_DEBUG
Definition: Logger.h:25
#define KB_WARN
Definition: Logger.h:27
bool isRelationDefined(const PredicateIndicator &indicator)
void undefineRelation(const PredicateIndicator &indicator)
void undefineClass(const IRIAtomPtr &iri)
std::set< PredicateIndicator > definedRelations_
void enableFeature(GoalDrivenReasonerFeature feature)
bool isClassDefined(const std::string_view &iri)
bool hasFeature(GoalDrivenReasonerFeature feature) const
std::set< PredicateIndicator > definedClasses_
void defineClass(const IRIAtomPtr &iri)
void defineRelation(const PredicateIndicator &indicator)
auto & reasonerName() const
Definition: Reasoner.h:37
std::shared_ptr< GoalDrivenReasoner > reasoner
std::shared_ptr< Goal > query
void createType< GoalDrivenReasoner >()
void createType< RDFGoalReasoner >()
void createType< Goal >()
Definition: Goal.cpp:91
IRIAtomPtr iri(std::string_view ns, std::string_view name)
Definition: IRIAtom.cpp:62
std::shared_ptr< IRIAtom > IRIAtomPtr
Definition: IRIAtom.h:57
std::shared_ptr< Goal > GoalPtr
Definition: Goal.h:84