6 #include "knowrob/Logger.h"
7 #include "knowrob/reasoner/ReasonerManager.h"
8 #include "knowrob/reasoner/ReasonerError.h"
15 backendManager_(backendManager) {
21 x.second->value()->unload();
23 x.second->value()->setReasonerManager(
nullptr);
29 const std::shared_ptr<Storage> &dataBackend) {
32 plugin->value()->setStorage(dataBackend);
34 plugin->value()->setStorage(dataBackend);
36 reasonerBackends_[plugin->value()->reasonerName()->stringForm()] = dataBackend;
40 auto it = reasonerBackends_.find(reasoner->name());
41 if (it != reasonerBackends_.end()) {
49 std::vector<DefiningReasoner> reasoners;
51 if (indicator.
arity() == 1) {
54 auto rdfClass = kb_->
vocabulary()->getDefinedClass(indicator.
functor()->stringForm());
56 for (
auto &x: goalDriven_) {
57 for (
auto &definedClassIndicator : x.second->definedClasses()) {
58 auto definedClass = kb_->
vocabulary()->getDefinedClass(definedClassIndicator.functor()->stringForm());
59 if(definedClass && definedClass->isSubClassOf(rdfClass)) {
60 reasoners.push_back({x.second, definedClass->iriAtom()});
69 if (indicator.
arity() == 2) {
72 auto rdfProperty = kb_->
vocabulary()->getDefinedProperty(indicator.
functor()->stringForm());
74 for (
auto &x: goalDriven_) {
75 for (
auto &definedPropertyIndicator : x.second->definedRelations()) {
76 auto definedProperty = kb_->
vocabulary()->getDefinedProperty(definedPropertyIndicator.functor()->stringForm());
77 if ( definedProperty && definedProperty->isSubPropertyOf(rdfProperty) ) {
78 reasoners.push_back({x.second, definedProperty->iriAtom()});
87 for (
auto &x: goalDriven_) {
88 if (x.second->isRelationDefined(indicator) || (indicator.
arity()==1 && x.second->isClassDefined(indicator.
functor()->stringForm()))) {
89 reasoners.push_back({x.second, indicator.
functor()});
97 std::shared_ptr<ReasonerFactory> factory =
findFactory(config);
99 if (!factory)
throw ReasonerError(
"failed to load a reasoner.");
102 KB_INFO(
"Using reasoner `{}` with type `{}`.", reasonerID, factory->name());
105 auto reasoner = factory->create(reasonerID);
108 reasoner->value()->setReasonerManager(
this);
109 reasoner->value()->setReasonerName(reasonerID);
111 auto backendName = config.get_optional<
std::string>(
"data-backend");
112 if (backendName.has_value()) {
113 auto definedBackend = backendManager_->getPluginWithID(backendName.value());
114 if (definedBackend) {
115 setReasonerStorage(reasoner, definedBackend->value());
117 throw ReasonerError(
"Reasoner `{}` refers to unknown data-backend `{}`.", reasonerID, backendName.value());
121 auto backend = std::dynamic_pointer_cast<Storage>(reasoner->value());
123 setReasonerStorage(reasoner, backend);
124 backendManager_->addPlugin(reasonerID, reasoner->language(), backend);
126 throw ReasonerError(
"Reasoner `{}` has no 'data-backend' configured.", reasonerID);
129 auto definedReasoner =
addPlugin(reasonerID, reasoner->language(), reasoner->value());
131 PropertyTree pluginConfig(std::make_shared<boost::property_tree::ptree>(config));
132 if (!initializeReasoner(reasoner, pluginConfig)) {
133 KB_WARN(
"Reasoner `{}` failed to loadConfig.", reasonerID);
136 for (
auto &dataSource: pluginConfig.
dataSources()) {
137 if (!reasoner->value()->loadDataSource(dataSource)) {
138 KB_WARN(
"Reasoner `{}` failed to load data source {}.", reasonerID, dataSource->uri());
143 return definedReasoner;
146 std::shared_ptr<NamedReasoner>
149 KB_WARN(
"overwriting reasoner with name '{}'", reasonerID);
151 auto managedReasoner = std::make_shared<NamedReasoner>(reasonerID, language, reasoner);
152 pluginPool_.emplace(managedReasoner->name(), managedReasoner);
153 reasoner->setReasonerManager(
this);
154 reasoner->setReasonerName(reasonerID);
155 initPlugin(managedReasoner);
157 backendManager_->vocabulary()->importHierarchy()->addDirectImport(
158 backendManager_->vocabulary()->importHierarchy()->ORIGIN_REASONER, reasonerID);
161 auto backend = std::dynamic_pointer_cast<Storage>(reasoner);
163 setReasonerStorage(managedReasoner, backend);
164 backendManager_->addPlugin(reasonerID, language, backend);
167 return managedReasoner;
170 bool ReasonerManager::initializeReasoner(
const std::shared_ptr<NamedReasoner> &namedReasoner,
PropertyTree &config) {
173 return namedReasoner->value()->initializeReasoner(config);
175 return namedReasoner->value()->initializeReasoner(config);
179 void ReasonerManager::initPlugin(
const std::shared_ptr<NamedReasoner> &namedReasoner) {
181 namedReasoner->value()->setReasonerLanguage(namedReasoner->language());
183 auto dataDriven = std::dynamic_pointer_cast<DataDrivenReasoner>(namedReasoner->value());
185 KB_INFO(
"Using data-driven reasoner with id '{}'.", namedReasoner->name());
186 dataDriven_[namedReasoner->name()] =
dataDriven;
189 auto goalDriven = std::dynamic_pointer_cast<GoalDrivenReasoner>(namedReasoner->value());
191 KB_INFO(
"Using goal-driven reasoner with id '{}'.", namedReasoner->name());
192 goalDriven_[namedReasoner->name()] =
goalDriven;
198 const std::vector<FirstOrderLiteralPtr> &literals,
200 auto reasonerRunner = std::make_shared<ReasonerRunner>();
201 reasonerRunner->reasoner = reasoner;
202 if(literals.size()>1) {
203 auto conjunction = std::make_shared<SimpleConjunction>(literals);
204 reasonerRunner->query = std::make_shared<Goal>(conjunction, ctx);
205 }
else if (literals.size() == 1) {
206 reasonerRunner->query = std::make_shared<Goal>(literals[0], ctx);
208 throw ReasonerError(
"Reasoner {} received an empty query.", *reasoner->reasonerName());
210 KB_DEBUG(
"Evaluating query `{}` with reasoner \"{}\"",
211 *reasonerRunner->query->formula(), *reasoner->reasonerName());
214 auto reasonerRunnerPtr = reasonerRunner.get();
218 [reasonerRunnerPtr](
const std::exception &exc) {
219 KB_ERROR(
"Reasoner {} produced an error in query evaluation. {} [{}]",
220 *reasonerRunnerPtr->reasoner->reasonerName(), exc.what(), *reasonerRunnerPtr->query->formula());
221 reasonerRunnerPtr->query->finish();
224 return reasonerRunner->query->answerBuffer();
auto & vocabulary() const
std::shared_ptr< PluginFactory< Reasoner > > findFactory(const boost::property_tree::ptree &config)
std::string getPluginID(const std::shared_ptr< PluginFactory< Reasoner >> &factory, const boost::property_tree::ptree &config)
std::map< std::string_view, std::shared_ptr< NamedPlugin< Reasoner > >, std::less<> > pluginPool_
auto & dataSources() const
std::shared_ptr< NamedReasoner > loadPlugin(const boost::property_tree::ptree &config) override
std::vector< DefiningReasoner > findDefiningReasoner(const PredicateIndicator &indicator) const
~ReasonerManager() override
auto & dataDriven() const
auto & goalDriven() const
ReasonerManager(KnowledgeBase *kb, const std::shared_ptr< StorageManager > &backendManager)
std::shared_ptr< Storage > getReasonerStorage(const std::shared_ptr< NamedReasoner > &reasoner)
std::shared_ptr< NamedReasoner > addPlugin(std::string_view reasonerID, PluginLanguage language, const std::shared_ptr< Reasoner > &reasoner) override
static TokenBufferPtr evaluateQuery(const GoalDrivenReasonerPtr &reasoner, const std::vector< FirstOrderLiteralPtr > &literals, const QueryContextPtr &ctx)
std::shared_ptr< TokenBuffer > TokenBufferPtr
std::shared_ptr< ThreadPool > DefaultThreadPool()
std::shared_ptr< const QueryContext > QueryContextPtr
std::shared_ptr< GoalDrivenReasoner > GoalDrivenReasonerPtr