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);
28 const std::shared_ptr<Storage> &dataBackend) {
31 plugin->value()->setStorage(dataBackend);
33 plugin->value()->setStorage(dataBackend);
35 reasonerBackends_[plugin->value()->reasonerName()->stringForm()] = dataBackend;
39 auto it = reasonerBackends_.find(reasoner->name());
40 if (it != reasonerBackends_.end()) {
48 std::vector<DefiningReasoner> reasoners;
50 if (indicator.
arity() == 1) {
53 auto rdfClass = kb_->
vocabulary()->getDefinedClass(indicator.
functor()->stringForm());
55 for (
auto &x: goalDriven_) {
56 for (
auto &definedClassIndicator : x.second->definedClasses()) {
57 auto definedClass = kb_->
vocabulary()->getDefinedClass(definedClassIndicator.functor()->stringForm());
58 if(definedClass && definedClass->isSubClassOf(rdfClass)) {
59 reasoners.push_back({x.second, definedClass->iriAtom()});
68 if (indicator.
arity() == 2) {
71 auto rdfProperty = kb_->
vocabulary()->getDefinedProperty(indicator.
functor()->stringForm());
73 for (
auto &x: goalDriven_) {
74 for (
auto &definedPropertyIndicator : x.second->definedRelations()) {
75 auto definedProperty = kb_->
vocabulary()->getDefinedProperty(definedPropertyIndicator.functor()->stringForm());
76 if ( definedProperty && definedProperty->isSubPropertyOf(rdfProperty) ) {
77 reasoners.push_back({x.second, definedProperty->iriAtom()});
86 for (
auto &x: goalDriven_) {
87 if (x.second->isRelationDefined(indicator) || (indicator.
arity()==1 && x.second->isClassDefined(indicator.
functor()->stringForm()))) {
88 reasoners.push_back({x.second, indicator.
functor()});
96 std::shared_ptr<ReasonerFactory> factory =
findFactory(config);
98 if (!factory)
throw ReasonerError(
"failed to load a reasoner.");
101 KB_INFO(
"Using reasoner `{}` with type `{}`.", reasonerID, factory->name());
104 auto reasoner = factory->create(reasonerID);
107 reasoner->value()->setReasonerManager(
this);
108 reasoner->value()->setReasonerName(reasonerID);
110 auto backendName = config.get_optional<
std::string>(
"data-backend");
111 if (backendName.has_value()) {
112 auto definedBackend = backendManager_->getPluginWithID(backendName.value());
113 if (definedBackend) {
114 setReasonerStorage(reasoner, definedBackend->value());
116 throw ReasonerError(
"Reasoner `{}` refers to unknown data-backend `{}`.", reasonerID, backendName.value());
120 auto backend = std::dynamic_pointer_cast<Storage>(reasoner->value());
122 setReasonerStorage(reasoner, backend);
123 backendManager_->addPlugin(reasonerID, reasoner->language(), backend);
125 throw ReasonerError(
"Reasoner `{}` has no 'data-backend' configured.", reasonerID);
128 auto definedReasoner =
addPlugin(reasonerID, reasoner->language(), reasoner->value());
130 PropertyTree pluginConfig(std::make_shared<boost::property_tree::ptree>(config));
131 if (!initializeReasoner(reasoner, pluginConfig)) {
132 KB_WARN(
"Reasoner `{}` failed to loadConfig.", reasonerID);
135 for (
auto &dataSource: pluginConfig.
dataSources()) {
136 if (!reasoner->value()->loadDataSource(dataSource)) {
137 KB_WARN(
"Reasoner `{}` failed to load data source {}.", reasonerID, dataSource->uri());
142 return definedReasoner;
145 std::shared_ptr<NamedReasoner>
148 KB_WARN(
"overwriting reasoner with name '{}'", reasonerID);
150 auto managedReasoner = std::make_shared<NamedReasoner>(reasonerID, language, reasoner);
151 pluginPool_.emplace(managedReasoner->name(), managedReasoner);
152 reasoner->setReasonerManager(
this);
153 reasoner->setReasonerName(reasonerID);
154 initPlugin(managedReasoner);
156 backendManager_->vocabulary()->importHierarchy()->addDirectImport(
157 backendManager_->vocabulary()->importHierarchy()->ORIGIN_REASONER, reasonerID);
160 auto backend = std::dynamic_pointer_cast<Storage>(reasoner);
162 setReasonerStorage(managedReasoner, backend);
163 backendManager_->addPlugin(reasonerID, language, backend);
166 return managedReasoner;
169 bool ReasonerManager::initializeReasoner(
const std::shared_ptr<NamedReasoner> &namedReasoner,
PropertyTree &config) {
172 return namedReasoner->value()->initializeReasoner(config);
174 return namedReasoner->value()->initializeReasoner(config);
178 void ReasonerManager::initPlugin(
const std::shared_ptr<NamedReasoner> &namedReasoner) {
180 namedReasoner->value()->setReasonerLanguage(namedReasoner->language());
182 auto dataDriven = std::dynamic_pointer_cast<DataDrivenReasoner>(namedReasoner->value());
184 KB_INFO(
"Using data-driven reasoner with id '{}'.", namedReasoner->name());
185 dataDriven_[namedReasoner->name()] =
dataDriven;
188 auto goalDriven = std::dynamic_pointer_cast<GoalDrivenReasoner>(namedReasoner->value());
190 KB_INFO(
"Using goal-driven reasoner with id '{}'.", namedReasoner->name());
191 goalDriven_[namedReasoner->name()] =
goalDriven;
197 const std::vector<FirstOrderLiteralPtr> &literals,
199 auto reasonerRunner = std::make_shared<ReasonerRunner>();
200 reasonerRunner->reasoner = reasoner;
201 if(literals.size()>1) {
202 auto conjunction = std::make_shared<SimpleConjunction>(literals);
203 reasonerRunner->query = std::make_shared<Goal>(conjunction, ctx);
204 }
else if (literals.size() == 1) {
205 reasonerRunner->query = std::make_shared<Goal>(literals[0], ctx);
207 throw ReasonerError(
"Reasoner {} received an empty query.", *reasoner->reasonerName());
209 KB_DEBUG(
"Evaluating query `{}` with reasoner \"{}\"",
210 *reasonerRunner->query->formula(), *reasoner->reasonerName());
213 auto reasonerRunnerPtr = reasonerRunner.get();
217 [reasonerRunnerPtr](
const std::exception &exc) {
218 KB_ERROR(
"Reasoner {} produced an error in query evaluation. {} [{}]",
219 *reasonerRunnerPtr->reasoner->reasonerName(), exc.what(), *reasonerRunnerPtr->query->formula());
220 reasonerRunnerPtr->query->finish();
223 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