knowrob  2.1.0
A Knowledge Base System for Cognition-enabled Robots
knowrob::PrologReasoner Class Reference

#include <PrologReasoner.h>

Inheritance diagram for knowrob::PrologReasoner:
Collaboration diagram for knowrob::PrologReasoner:

Public Member Functions

 PrologReasoner ()
 
 ~PrologReasoner () override
 
 PrologReasoner (const PrologReasoner &)=delete
 
bool setReasonerSetting (const TermPtr &key, const TermPtr &valueString)
 
bool consult (const std::filesystem::path &uri, const char *module={}, bool doTransformQuery=true)
 
bool load_rdf_xml (const std::filesystem::path &rdfFile)
 
virtual std::string_view callFunctor ()
 
PrologTerm transformGoal (const PrologTerm &goal)
 
std::list< TermPtrrunTests (const std::string &target)
 
bool initializeReasoner (const PropertyTree &cfg) override
 
bool evaluate (GoalPtr query) override
 
void unload () override
 
 PrologReasoner ()
 
 ~PrologReasoner () override
 
 PrologReasoner (const PrologReasoner &)=delete
 
bool setReasonerSetting (const TermPtr &key, const TermPtr &valueString)
 
bool consult (const std::filesystem::path &uri, const char *module={}, bool doTransformQuery=true)
 
bool load_rdf_xml (const std::filesystem::path &rdfFile)
 
virtual std::string_view callFunctor ()
 
PrologTerm transformGoal (const PrologTerm &goal)
 
std::list< TermPtrrunTests (const std::string &target)
 
bool initializeReasoner (const PropertyTree &cfg) override
 
bool evaluate (GoalPtr query) override
 
void unload () override
 
- Public Member Functions inherited from knowrob::GoalDrivenReasoner
 GoalDrivenReasoner ()
 
bool hasFeature (GoalDrivenReasonerFeature feature) const
 
void enableFeature (GoalDrivenReasonerFeature feature)
 
bool isRelationDefined (const PredicateIndicator &indicator)
 
bool isClassDefined (const std::string_view &iri)
 
void defineRelation (const PredicateIndicator &indicator)
 
void defineRelation (const IRIAtomPtr &iri)
 
void undefineRelation (const PredicateIndicator &indicator)
 
void defineClass (const IRIAtomPtr &iri)
 
void undefineClass (const IRIAtomPtr &iri)
 
const auto & definedRelations () const
 
const auto & definedClasses () const
 
 GoalDrivenReasoner ()
 
bool hasFeature (GoalDrivenReasonerFeature feature) const
 
void enableFeature (GoalDrivenReasonerFeature feature)
 
bool isRelationDefined (const PredicateIndicator &indicator)
 
bool isClassDefined (const std::string_view &iri)
 
void defineRelation (const PredicateIndicator &indicator)
 
void defineRelation (const IRIAtomPtr &iri)
 
void undefineRelation (const PredicateIndicator &indicator)
 
void defineClass (const IRIAtomPtr &iri)
 
void undefineClass (const IRIAtomPtr &iri)
 
const auto & definedRelations () const
 
const auto & definedClasses () const
 
- Public Member Functions inherited from knowrob::Reasoner
 Reasoner ()
 
virtual ~Reasoner ()=default
 
auto & reasonerName () const
 
auto reasonerLanguage () const
 
auto storage () const
 
template<class T >
std::shared_ptr< T > getTypedStorage () const
 
ReasonerManagerreasonerManager () const
 
void pushWork (const std::function< void(void)> &fn)
 
void setStorage (const StoragePtr &storage)
 
 Reasoner ()
 
virtual ~Reasoner ()=default
 
auto & reasonerName () const
 
auto reasonerLanguage () const
 
auto storage () const
 
template<class T >
std::shared_ptr< T > getTypedStorage () const
 
ReasonerManagerreasonerManager () const
 
void pushWork (const std::function< void(void)> &fn)
 
void setStorage (const StoragePtr &storage)
 
- Public Member Functions inherited from knowrob::DataSourceHandler
 DataSourceHandler ()=default
 
virtual ~DataSourceHandler ()=default
 
void addDataHandler (const std::string &format, const DataSourceLoader &fn)
 
bool loadDataSource (const DataSourcePtr &dataSource)
 
bool hasDataHandler (const DataSourcePtr &dataSource) const
 
 DataSourceHandler ()=default
 
virtual ~DataSourceHandler ()=default
 
void addDataHandler (const std::string &format, const DataSourceLoader &fn)
 
bool loadDataSource (const DataSourcePtr &dataSource)
 
bool hasDataHandler (const DataSourcePtr &dataSource) const
 

Static Public Member Functions

static std::shared_ptr< NamedReasonergetDefinedReasoner (const term_t &t_reasonerManager, const term_t &t_reasonerModule)
 
static std::shared_ptr< NamedReasonergetDefinedReasoner (const term_t &t_reasonerManager, const term_t &t_reasonerModule)
 

Protected Member Functions

virtual bool initializeGlobalPackages ()
 
virtual bool initializeDefaultPackages ()
 
virtual void initializeReasonerStorage ()
 
bool loadDataSourceWithUnknownFormat (const DataSourcePtr &dataFile) override
 
AnswerYesPtr yes (const GoalPtr &query, const PrologTerm &rdfGoal, const PrologTerm &frameTerm)
 
AnswerNoPtr no (const GoalPtr &query)
 
PrologTerm getReasonerQuery (const PrologTerm &goal)
 
virtual bool initializeGlobalPackages ()
 
virtual bool initializeDefaultPackages ()
 
virtual void initializeReasonerStorage ()
 
bool loadDataSourceWithUnknownFormat (const DataSourcePtr &dataFile) override
 
AnswerYesPtr yes (const GoalPtr &query, const PrologTerm &rdfGoal, const PrologTerm &frameTerm)
 
AnswerNoPtr no (const GoalPtr &query)
 
PrologTerm getReasonerQuery (const PrologTerm &goal)
 

Static Protected Member Functions

static bool putQueryFrame (PrologTerm &frameTerm, const GraphSelector &frame)
 
static std::shared_ptr< GraphSelectorcreateAnswerFrame (const PrologTerm &plTerm)
 
static bool putQueryFrame (PrologTerm &frameTerm, const GraphSelector &frame)
 
static std::shared_ptr< GraphSelectorcreateAnswerFrame (const PrologTerm &plTerm)
 

Protected Attributes

std::shared_ptr< PrologBackendknowledgeGraph_
 
- Protected Attributes inherited from knowrob::GoalDrivenReasoner
std::set< PredicateIndicatordefinedRelations_
 
std::set< PredicateIndicatordefinedClasses_
 
int features_
 
- Protected Attributes inherited from knowrob::DataSourceHandler
std::map< std::string, DataSourceLoaderdataSourceHandler_
 

Static Protected Attributes

static bool isKnowRobInitialized_ = false
 

Detailed Description

A Prolog reasoner that answers queries using SWI Prolog.

Definition at line 30 of file PrologReasoner.h.

Constructor & Destructor Documentation

◆ PrologReasoner() [1/4]

PrologReasoner::PrologReasoner ( )

Definition at line 84 of file PrologReasoner.cpp.

84  : GoalDrivenReasoner() {
85  // enable goal-driven reasoning features
88  // add data handler for prolog files
89  addDataHandler("prolog", [this]
90  (const DataSourcePtr &dataFile) { return consult(dataFile->uri()); });
91 }
void addDataHandler(const std::string &format, const DataSourceLoader &fn)
void enableFeature(GoalDrivenReasonerFeature feature)
bool consult(const std::filesystem::path &uri, const char *module={}, bool doTransformQuery=true)
std::shared_ptr< DataSource > DataSourcePtr
Definition: DataSource.h:107

◆ ~PrologReasoner() [1/2]

PrologReasoner::~PrologReasoner ( )
overridedefault

◆ PrologReasoner() [2/4]

knowrob::PrologReasoner::PrologReasoner ( const PrologReasoner )
delete

Cannot be copy-assigned.

◆ PrologReasoner() [3/4]

knowrob::PrologReasoner::PrologReasoner ( )

◆ ~PrologReasoner() [2/2]

knowrob::PrologReasoner::~PrologReasoner ( )
override

◆ PrologReasoner() [4/4]

knowrob::PrologReasoner::PrologReasoner ( const PrologReasoner )
delete

Cannot be copy-assigned.

Member Function Documentation

◆ callFunctor() [1/2]

std::string_view PrologReasoner::callFunctor ( )
virtual

Reimplemented in knowrob::MongologReasoner, and knowrob::MongologReasoner.

Definition at line 100 of file PrologReasoner.cpp.

100  {
101  static const auto reasoner_call_f = "reasoner_call";
102  return reasoner_call_f;
103 }

◆ callFunctor() [2/2]

virtual std::string_view knowrob::PrologReasoner::callFunctor ( )
virtual

◆ consult() [1/2]

bool PrologReasoner::consult ( const std::filesystem::path &  uri,
const char *  module = {},
bool  doTransformQuery = true 
)

Consults a Prolog file, i.e. loads facts and rules and executed directives in the file. May throw an exception if there is no valid Prolog file at the given path.

Parameters
urithe local path to the file.
modulethe module to consult the file into.
doTransformQueryif true, then the file is transformed into a query.
Returns
true on success

Definition at line 187 of file PrologReasoner.cpp.

187  {
188  static auto consult_f = "consult";
189  auto path = PrologEngine::getPrologPath(uri);
190 
191  return PrologEngine::eval([&]() {
192  PrologTerm plTerm(consult_f, path.native());
193  if (module) plTerm.setModule(module);
194  return getReasonerQuery(doTransformQuery ? transformGoal(plTerm) : plTerm);
195  });
196 }
static std::filesystem::path getPrologPath(const std::filesystem::path &filename)
static bool eval(const GoalFactory &goalFactory)
PrologTerm transformGoal(const PrologTerm &goal)
PrologTerm getReasonerQuery(const PrologTerm &goal)

◆ consult() [2/2]

bool knowrob::PrologReasoner::consult ( const std::filesystem::path &  uri,
const char *  module = {},
bool  doTransformQuery = true 
)

Consults a Prolog file, i.e. loads facts and rules and executed directives in the file. May throw an exception if there is no valid Prolog file at the given path.

Parameters
urithe local path to the file.
modulethe module to consult the file into.
doTransformQueryif true, then the file is transformed into a query.
Returns
true on success

◆ createAnswerFrame() [1/2]

std::shared_ptr< GraphSelector > PrologReasoner::createAnswerFrame ( const PrologTerm plTerm)
staticprotected

Definition at line 377 of file PrologReasoner.cpp.

377  {
378  std::shared_ptr<GraphSelector> frame;
379 
380  if (PL_is_variable(plTerm())) {
381  // reasoner did not specify a solution scope
382  return {};
383  } else if (PL_is_dict(plTerm())) {
384  // the solution scope was generated as a Prolog dictionary
385  auto scope_val = PL_new_term_ref();
386 
387  frame = std::make_shared<GraphSelector>();
388 
389  // read "time" key, the value is expected to be a predicate `range(Since,Until)`
390  static const auto time_key = PL_new_atom("time");
391  if (PL_get_dict_key(time_key, plTerm(), scope_val)) {
392  term_t arg = PL_new_term_ref();
393  std::optional<TimePoint> v_since, v_until;
394  double val = 0.0;
395 
396  if (PL_get_arg(1, scope_val, arg) &&
397  PL_term_type(arg) == PL_FLOAT &&
398  PL_get_float(arg, &val) &&
399  val > 0.001) { frame->begin = val; }
400 
401  if (PL_get_arg(2, scope_val, arg) &&
402  PL_term_type(arg) == PL_FLOAT &&
403  PL_get_float(arg, &val)) { frame->end = val; }
404  }
405 
406  static const auto uncertain_key = PL_new_atom("uncertain");
407  if (PL_get_dict_key(uncertain_key, plTerm(), scope_val)) {
408  atom_t flagAtom;
409  if (PL_term_type(scope_val) == PL_ATOM && PL_get_atom(scope_val, &flagAtom)) {
410  if (flagAtom == PrologTerm::ATOM_true()) {
411  frame->uncertain = true;
412  }
413  }
414  }
415 
416  static const auto confidence_key = PL_new_atom("confidence");
417  if (PL_get_dict_key(confidence_key, plTerm(), scope_val)) {
418  double confidenceValue = 1.0;
419  if (PL_term_type(scope_val) == PL_FLOAT && PL_get_float(scope_val, &confidenceValue)) {
420  frame->confidence = confidenceValue;
421  if (confidenceValue > 0.999) {
422  frame->uncertain = false;
423  } else {
424  frame->uncertain = true;
425  }
426  }
427  }
428 
429  static const auto occasional_key = PL_new_atom("occasional");
430  if (PL_get_dict_key(occasional_key, plTerm(), scope_val)) {
431  atom_t flagAtom;
432  if (PL_term_type(scope_val) == PL_ATOM && PL_get_atom(scope_val, &flagAtom)) {
433  frame->occasional = (flagAtom == PrologTerm::ATOM_true());
434  }
435  }
436 
437  static const auto agent_key = PL_new_atom("agent");
438  if (PL_get_dict_key(agent_key, plTerm(), scope_val)) {
439  atom_t agentAtom;
440  if (PL_term_type(scope_val) == PL_ATOM && PL_get_atom(scope_val, &agentAtom)) {
441  frame->perspective = Perspective::get(PL_atom_chars(agentAtom));
442  }
443  }
444 
445  PL_reset_term_refs(scope_val);
446  } else {
447  KB_WARN("solution scope has an unexpected type (should be dict).");
448  }
449 
450  if (frame) {
451  return frame;
452  } else {
453  return {};
454  }
455 }
#define KB_WARN
Definition: Logger.h:27
static std::shared_ptr< Perspective > get(std::string_view iri)
Definition: Perspective.cpp:31
static const atom_t & ATOM_true()
Definition: PrologTerm.cpp:881

◆ createAnswerFrame() [2/2]

static std::shared_ptr<GraphSelector> knowrob::PrologReasoner::createAnswerFrame ( const PrologTerm plTerm)
staticprotected

◆ evaluate() [1/2]

bool PrologReasoner::evaluate ( GoalPtr  query)
overridevirtual

Evaluate a query with a reasoner. The query is represented by a formula, a context and an answer queue where results of the reasoning process can be added. The evaluation of the query must be performed synchronously, i.e. the answer queue must be filled before the function returns. A reasoner may instead throw an exception if the query cannot be evaluated, or return false to also indicate an error status.

Parameters
querythe query to evaluate.
Returns
true on success, false otherwise.

Implements knowrob::GoalDrivenReasoner.

Definition at line 204 of file PrologReasoner.cpp.

204  {
205  // context term options:
206  static const auto query_scope_f = "query_scope";
207  static const auto solution_scope_f = "solution_scope";
208 
209  // create runner that evaluates the goal in a thread with a Prolog engine.
210  // Note that this is needed because the current thread might not have
211  // a Prolog engine associated with it.
212  auto runner = std::make_shared<ThreadPool::LambdaRunner>(
213  [this, &query](const ThreadPool::LambdaRunner::StopChecker &hasStopRequest) {
214  PrologTerm queryFrame, answerFrame;
215  putQueryFrame(queryFrame, query->ctx()->selector);
216 
217  PrologTerm goal(query->formula());
218  // :- ContextTerm = [query_scope(...), solution_scope(Variable)]
219  PrologList contextTerm({
220  PrologTerm(query_scope_f, queryFrame),
221  PrologTerm(solution_scope_f, answerFrame)
222  });
223  // :- QueryGoal = ( b_setval(reasoner_module, reasonerName()),
224  // b_setval(reasoner_manager, managerID),
225  // reasoner_call(Goal, ContextTerm) ).
226  PrologTerm queryGoal = getReasonerQuery(
227  PrologTerm(callFunctor(), goal, contextTerm));
228 
229  auto qid = queryGoal.openQuery(prologQueryFlags);
230  bool hasSolution = false;
231  while (!hasStopRequest() && knowrob::PrologTerm::nextSolution(qid)) {
232  query->push(yes(query, goal, answerFrame));
233  hasSolution = true;
234  if (query->ctx()->queryFlags & QUERY_FLAG_ONE_SOLUTION) break;
235  }
236  PL_close_query(qid);
237  if (!hasSolution) query->push(no(query));
238  });
239 
240  // push goal and return
241  PrologEngine::pushGoal(runner, [query](const std::exception &e) {
242  KB_WARN("an exception occurred for prolog query ({}): {}.", *query->formula(), e.what());
243  throw;
244  });
245 
246  // evaluateQuery must be blocking -> wait on Prolog runner to finish
247  runner->join();
248 
249  return true;
250 }
static void pushGoal(const std::shared_ptr< ThreadPool::Runner > &goal, const ErrorHandler &errHandler)
AnswerNoPtr no(const GoalPtr &query)
virtual std::string_view callFunctor()
AnswerYesPtr yes(const GoalPtr &query, const PrologTerm &rdfGoal, const PrologTerm &frameTerm)
static bool putQueryFrame(PrologTerm &frameTerm, const GraphSelector &frame)
static bool nextSolution(qid_t qid)
Definition: PrologTerm.cpp:163
std::function< bool()> StopChecker
Definition: ThreadPool.h:152
@ QUERY_FLAG_ONE_SOLUTION
Definition: QueryFlag.h:17

◆ evaluate() [2/2]

bool knowrob::PrologReasoner::evaluate ( GoalPtr  query)
overridevirtual

Evaluate a query with a reasoner. The query is represented by a formula, a context and an answer queue where results of the reasoning process can be added. The evaluation of the query must be performed synchronously, i.e. the answer queue must be filled before the function returns. A reasoner may instead throw an exception if the query cannot be evaluated, or return false to also indicate an error status.

Parameters
querythe query to evaluate.
Returns
true on success, false otherwise.

Implements knowrob::GoalDrivenReasoner.

◆ getDefinedReasoner() [1/2]

std::shared_ptr< NamedReasoner > PrologReasoner::getDefinedReasoner ( const term_t &  t_reasonerManager,
const term_t &  t_reasonerModule 
)
static

Definition at line 167 of file PrologReasoner.cpp.

168  {
169  int i_reasonerManager;
170  if (!PL_get_integer(t_reasonerManager, &i_reasonerManager)) return {};
171  auto reasonerManager = ReasonerManager::getManager(i_reasonerManager);
172  if (!reasonerManager) return {};
173 
174  char *reasonerModule;
175  if (PL_get_atom_chars(t_reasonerModule, &reasonerModule)) {
176  // remove "reasoner_" prefix from module name.
177  // the prefix is used to avoid name clashes.
178  if (strncmp(reasonerModule, "Reasoner_", 9) == 0) {
179  reasonerModule += 9;
180  }
181  return reasonerManager->getPluginWithID(reasonerModule);
182  } else {
183  return {};
184  }
185 }
static PluginManager< Reasoner > * getManager(uint32_t managerID)
Definition: PluginManager.h:63
std::shared_ptr< NamedPlugin< T > > getPluginWithID(std::string_view pluginID)
Definition: PluginManager.h:76
ReasonerManager & reasonerManager() const
Definition: Reasoner.cpp:24

◆ getDefinedReasoner() [2/2]

static std::shared_ptr<NamedReasoner> knowrob::PrologReasoner::getDefinedReasoner ( const term_t &  t_reasonerManager,
const term_t &  t_reasonerModule 
)
static

◆ getReasonerQuery() [1/2]

PrologTerm PrologReasoner::getReasonerQuery ( const PrologTerm goal)
protected

Definition at line 157 of file PrologReasoner.cpp.

157  {
158  static const auto b_setval_f = "b_setval";
159  static const auto reasoner_module_a = "reasoner_module";
160  static const auto reasoner_manager_a = "reasoner_manager";
161  auto managerID = std::make_shared<Integer>(reasonerManager().managerID());
162  return PrologTerm(b_setval_f, reasoner_module_a, reasonerName()) &
163  PrologTerm(b_setval_f, reasoner_manager_a, managerID) &
164  goal;
165 }
auto & reasonerName() const
Definition: Reasoner.h:37

◆ getReasonerQuery() [2/2]

PrologTerm knowrob::PrologReasoner::getReasonerQuery ( const PrologTerm goal)
protected

◆ initializeDefaultPackages() [1/2]

virtual bool knowrob::PrologReasoner::initializeDefaultPackages ( )
inlineprotectedvirtual

◆ initializeDefaultPackages() [2/2]

virtual bool knowrob::PrologReasoner::initializeDefaultPackages ( )
inlineprotectedvirtual

◆ initializeGlobalPackages() [1/2]

virtual bool knowrob::PrologReasoner::initializeGlobalPackages ( )
inlineprotectedvirtual

Definition at line 89 of file PrologReasoner.h.

89 { return true; }

◆ initializeGlobalPackages() [2/2]

virtual bool knowrob::PrologReasoner::initializeGlobalPackages ( )
inlineprotectedvirtual

Definition at line 89 of file PrologReasoner.h.

89 { return true; }

◆ initializeReasoner() [1/2]

bool PrologReasoner::initializeReasoner ( const PropertyTree ptree)
overridevirtual

Initialize a reasoner by configuring it with a property tree.

Parameters
ptreea PropertyTree object.

Implements knowrob::Reasoner.

Reimplemented in knowrob::MongologReasoner.

Definition at line 109 of file PrologReasoner.cpp.

109  {
110  // call PL_initialize
113 
114  if (!isKnowRobInitialized_) {
115  isKnowRobInitialized_ = true;
116 
117  PL_register_foreign("reasoner_define_relation_cpp", 4, (pl_function_t) prolog::reasoner_define_relation4, 0);
118  PL_register_foreign("reasoner_define_class_cpp", 3, (pl_function_t) prolog::reasoner_define_class3, 0);
119 
120  // auto-load some files into "user" module
122 
123  // load init file from reasoner directory
124  consult(std::filesystem::path("reasoner") / "prolog" / "__init__.pl", "user", false);
125 
126  // register RDF namespaces with Prolog.
127  // in particular the ones specified in settings are globally registered with PrefixRegistry.
128  static const auto register_prefix_i = "rdf_register_prefix";
129  for (auto &pair: PrefixRegistry::get()) {
130  const auto &uri = pair.first;
131  const auto &alias = pair.second;
132  PROLOG_REASONER_EVAL(PrologTerm(register_prefix_i, alias, uri));
133  }
134  }
135 
136  // load properties into the reasoner module.
137  // this is needed mainly for `reasoner_setting/2` that provides reasoner instance specific settings.
138  for (auto &pair: cfg) {
139  auto key_t = cfg.createKeyTerm(pair.first);
140  setReasonerSetting(key_t, pair.second);
141  }
142  // load reasoner default packages. this is usually the code that implements the reasoner.
144 
145  // this is needed to assert triple/3 predicate in the reasoner module
146  static auto reasoner_rdf_init_f = "reasoner_rdf_init";
147  PROLOG_REASONER_EVAL(PrologTerm(reasoner_rdf_init_f));
148 
149  return true;
150 }
#define PROLOG_REASONER_EVAL(goal)
static PrefixRegistry & get()
static void initializeProlog()
virtual void initializeReasonerStorage()
bool setReasonerSetting(const TermPtr &key, const TermPtr &valueString)
virtual bool initializeGlobalPackages()
static bool isKnowRobInitialized_
virtual bool initializeDefaultPackages()

◆ initializeReasoner() [2/2]

bool knowrob::PrologReasoner::initializeReasoner ( const PropertyTree ptree)
overridevirtual

Initialize a reasoner by configuring it with a property tree.

Parameters
ptreea PropertyTree object.

Implements knowrob::Reasoner.

◆ initializeReasonerStorage() [1/2]

virtual void knowrob::PrologReasoner::initializeReasonerStorage ( )
inlineprotectedvirtual

Reimplemented in knowrob::MongologReasoner, and knowrob::MongologReasoner.

Definition at line 93 of file PrologReasoner.h.

93 { knowledgeGraph_ = getTypedStorage<PrologBackend>(); }
std::shared_ptr< PrologBackend > knowledgeGraph_

◆ initializeReasonerStorage() [2/2]

virtual void knowrob::PrologReasoner::initializeReasonerStorage ( )
inlineprotectedvirtual

Reimplemented in knowrob::MongologReasoner, and knowrob::MongologReasoner.

Definition at line 93 of file PrologReasoner.h.

93 { knowledgeGraph_ = getTypedStorage<PrologBackend>(); }

◆ load_rdf_xml() [1/2]

bool PrologReasoner::load_rdf_xml ( const std::filesystem::path &  rdfFile)
Parameters
rdfFilea rdf-xml encoded file.

Definition at line 198 of file PrologReasoner.cpp.

198  {
199  static auto load_rdf_xml_f = "load_rdf_xml";
200  auto path = PrologEngine::getResourcePath(rdfFile);
201  return PROLOG_REASONER_EVAL(PrologTerm(load_rdf_xml_f, path.native(), reasonerName()));
202 }
static std::filesystem::path getResourcePath(const std::filesystem::path &filename)

◆ load_rdf_xml() [2/2]

bool knowrob::PrologReasoner::load_rdf_xml ( const std::filesystem::path &  rdfFile)
Parameters
rdfFilea rdf-xml encoded file.

◆ loadDataSourceWithUnknownFormat() [1/2]

bool knowrob::PrologReasoner::loadDataSourceWithUnknownFormat ( const DataSourcePtr dataFile)
inlineoverrideprotectedvirtual

Reimplemented from knowrob::DataSourceHandler.

Definition at line 95 of file PrologReasoner.h.

95  {
96  return consult(dataFile->uri());
97  };

◆ loadDataSourceWithUnknownFormat() [2/2]

bool knowrob::PrologReasoner::loadDataSourceWithUnknownFormat ( const DataSourcePtr dataFile)
inlineoverrideprotectedvirtual

Reimplemented from knowrob::DataSourceHandler.

Definition at line 95 of file PrologReasoner.h.

95  {
96  return consult(dataFile->uri());
97  };

◆ no() [1/2]

AnswerNoPtr PrologReasoner::no ( const GoalPtr query)
protected

Definition at line 291 of file PrologReasoner.cpp.

291  {
292  KB_DEBUG("Prolog has no solution.");
293  // if no solution was found, indicate that via a NegativeAnswer.
294  auto negativeAnswer = std::make_shared<AnswerNo>();
295  negativeAnswer->setReasonerTerm(reasonerName());
296  // however, as Prolog cannot proof negations such an answer is always not well-founded
297  // and can be overruled by a well-founded one.
298  negativeAnswer->setIsUncertain(true, std::nullopt);
299 
300  // add literals to the answer for which the query has failed.
301  // NOTE: At the moment negations will only appear in simple queries
302  // without connective operators, so no problem that below we can
303  // only handle queries with a single literal.
304  auto &literals = query->formula()->literals();
305  if (literals.size() == 1) {
306  auto &firstLiteral = *literals.begin();
307  negativeAnswer->addUngrounded(
308  std::static_pointer_cast<Predicate>(firstLiteral->predicate()),
309  firstLiteral->isNegated());
310  }
311 
312  return negativeAnswer;
313 }
#define KB_DEBUG
Definition: Logger.h:25

◆ no() [2/2]

AnswerNoPtr knowrob::PrologReasoner::no ( const GoalPtr query)
protected

◆ putQueryFrame() [1/2]

bool PrologReasoner::putQueryFrame ( PrologTerm frameTerm,
const GraphSelector frame 
)
staticprotected

Definition at line 316 of file PrologReasoner.cpp.

316  {
317  // Map an GraphSelector to a Prolog dict term.
318  // The term has the form:
319  // { epistemicMode: knowledge|belief,
320  // temporalMode: sometimes|always,
321  // [agent: $name,]
322  // [since: $time,]
323  // [until: $time] }
324 
325  int numFrameKeys = 2;
326  if (frame.perspective) numFrameKeys += 1;
327  if (frame.begin.has_value()) numFrameKeys += 1;
328  if (frame.end.has_value()) numFrameKeys += 1;
329 
330  // option: frame($dictTerm)
331  atom_t scopeKeys[numFrameKeys];
332  auto scopeValues = PL_new_term_refs(numFrameKeys);
333 
334  // epistemicMode: knowledge|belief
335  static const auto epistemicMode_a = PL_new_atom("epistemicMode");
336  static const auto knowledge_a = PL_new_atom("knowledge");
337  static const auto belief_a = PL_new_atom("belief");
338 
339  bool isAboutBelief = (frame.uncertain);
340  int keyIndex = 0;
341  scopeKeys[keyIndex] = epistemicMode_a;
342  if (!PL_put_atom(scopeValues, isAboutBelief ? belief_a : knowledge_a)) return false;
343 
344  // temporalMode: sometimes|always
345  static const auto temporalMode_a = PL_new_atom("temporalMode");
346  static const auto sometimes_a = PL_new_atom("sometimes");
347  static const auto always_a = PL_new_atom("always");
348 
349  bool isAboutSomePast = (frame.occasional);
350  scopeKeys[++keyIndex] = temporalMode_a;
351  if (!PL_put_atom(scopeValues + keyIndex, isAboutSomePast ? sometimes_a : always_a)) return false;
352 
353  // agent: $name
354  if (frame.perspective) {
355  static const auto agent_a = PL_new_atom("agent");
356  scopeKeys[++keyIndex] = agent_a;
357  auto agent_iri = frame.perspective->iri();
358  if (!PL_put_atom_chars(scopeValues + keyIndex, agent_iri.data())) return false;
359  }
360 
361  // since: $name
362  if (frame.begin.has_value()) {
363  static const auto since_a = PL_new_atom("since");
364  scopeKeys[++keyIndex] = since_a;
365  if (!PL_put_float(scopeValues + keyIndex, frame.begin.value())) return false;
366  }
367  // until: $name
368  if (frame.end.has_value()) {
369  static const auto until_a = PL_new_atom("until");
370  scopeKeys[++keyIndex] = until_a;
371  if (!PL_put_float(scopeValues + keyIndex, frame.end.value())) return false;
372  }
373 
374  return PL_put_dict(frameTerm(), 0, numFrameKeys, scopeKeys, scopeValues);
375 }
std::optional< double > end
Definition: GraphSelector.h:46
PerspectivePtr perspective
Definition: GraphSelector.h:30
std::optional< double > begin
Definition: GraphSelector.h:42

◆ putQueryFrame() [2/2]

static bool knowrob::PrologReasoner::putQueryFrame ( PrologTerm frameTerm,
const GraphSelector frame 
)
staticprotected

◆ runTests() [1/2]

std::list< TermPtr > PrologReasoner::runTests ( const std::string &  target)

Definition at line 457 of file PrologReasoner.cpp.

457  {
458  static const auto xunit_var = std::make_shared<Variable>("Term");
459  static const auto silent_flag = Atom::Tabled("silent");
460  static const auto xunit_opt = std::make_shared<Function>(Function("xunit_term", {xunit_var}));
461 
462  TermPtr pred = std::make_shared<Function>(Function(
463  "test_and_report", {
464  // unittest target
465  Atom::Tabled(target),
466  // options
467  std::make_shared<ListTerm>(ListTerm({xunit_opt, silent_flag}))
468  }));
469  auto solutions = PROLOG_ENGINE_ALL_SOL(getReasonerQuery(PrologTerm(pred)));
470 
471  std::list<TermPtr> output;
472  for (auto &solution: solutions) {
473  if (solution.count(*xunit_var) > 0) {
474  output.push_back(solution[*xunit_var]);
475  } else {
476  KB_WARN("Solution has no key '{}'.", xunit_var->name());
477  }
478  }
479  return output;
480 }
#define PROLOG_ENGINE_ALL_SOL(term)
Definition: PrologEngine.h:130
static std::shared_ptr< knowrob::Atom > Tabled(std::string_view stringForm)
Definition: Atom.cpp:40
std::shared_ptr< Term > TermPtr
Definition: Term.h:117

◆ runTests() [2/2]

std::list<TermPtr> knowrob::PrologReasoner::runTests ( const std::string &  target)

◆ setReasonerSetting() [1/2]

bool PrologReasoner::setReasonerSetting ( const TermPtr key,
const TermPtr valueString 
)
Parameters
key
valueString
Returns

Definition at line 152 of file PrologReasoner.cpp.

152  {
153  static auto set_setting_f = "reasoner_set_setting";
154  return PROLOG_REASONER_EVAL(PrologTerm(set_setting_f, reasonerName(), key, valueString));
155 }

◆ setReasonerSetting() [2/2]

bool knowrob::PrologReasoner::setReasonerSetting ( const TermPtr key,
const TermPtr valueString 
)
Parameters
key
valueString
Returns

◆ transformGoal() [1/2]

PrologTerm PrologReasoner::transformGoal ( const PrologTerm goal)

Definition at line 105 of file PrologReasoner.cpp.

105  {
106  return PrologTerm(callFunctor(), goal, PrologTerm::nil());
107 }
static PrologTerm nil()
Definition: PrologTerm.cpp:90

◆ transformGoal() [2/2]

PrologTerm knowrob::PrologReasoner::transformGoal ( const PrologTerm goal)

◆ unload() [1/2]

void PrologReasoner::unload ( )
overridevirtual

Unload the reasoner, meaning that all static resources associated to this reasoner are released.

Reimplemented from knowrob::Reasoner.

Reimplemented in knowrob::SWRLReasoner, knowrob::MongologReasoner, and knowrob::SWRLReasoner.

Definition at line 95 of file PrologReasoner.cpp.

95  {
96  static auto unload_f = "reasoner_unload";
98 }
#define PROLOG_ENGINE_EVAL(term)
Definition: PrologEngine.h:128

◆ unload() [2/2]

void knowrob::PrologReasoner::unload ( )
overridevirtual

Unload the reasoner, meaning that all static resources associated to this reasoner are released.

Reimplemented from knowrob::Reasoner.

Reimplemented in knowrob::SWRLReasoner.

◆ yes() [1/2]

AnswerYesPtr PrologReasoner::yes ( const GoalPtr query,
const PrologTerm rdfGoal,
const PrologTerm frameTerm 
)
protected

Definition at line 252 of file PrologReasoner.cpp.

254  {
255  KB_DEBUG("Prolog has a next solution.");
256 
257  // create bindings object
258  auto bindings = std::make_shared<Bindings>();
259  for (const auto &kv: rdfGoal.vars()) {
260  auto grounding = PrologTerm::toKnowRobTerm(kv.second);
261  if (grounding && grounding->termType() != TermType::VARIABLE) {
262  bindings->set(std::make_shared<Variable>(kv.first), PrologTerm::toKnowRobTerm(kv.second));
263  }
264  }
265 
266  // create an answer object given the bindings
267  auto yes = std::make_shared<AnswerYes>(bindings);
268  yes->setReasonerTerm(reasonerName());
269 
270  // set the solution scope, if reasoner specified it
271  auto answerFrame_rw = createAnswerFrame(answerFrameTerm);
272  GraphSelectorPtr answerFrame_ro;
273  if (answerFrame_rw) {
274  yes->setFrame(answerFrame_rw);
275  answerFrame_ro = answerFrame_rw;
276  } else {
277  answerFrame_ro = DefaultGraphSelector();
278  }
279 
280  // store instantiations of literals
281  auto &phi = query->formula();
282  for (auto &literal: phi->literals()) {
283  auto &p = literal->predicate();
284  auto p_instance = applyBindings(p, *yes->substitution());
285  yes->addGrounding(std::static_pointer_cast<Predicate>(p_instance), literal->isNegated(), answerFrame_ro);
286  }
287 
288  return yes;
289 }
static std::shared_ptr< GraphSelector > createAnswerFrame(const PrologTerm &plTerm)
TermPtr toKnowRobTerm() const
Definition: PrologTerm.cpp:691
auto & vars() const
Definition: PrologTerm.h:206
GraphSelectorPtr DefaultGraphSelector()
std::shared_ptr< const GraphSelector > GraphSelectorPtr
Definition: GraphSelector.h:76
FirstOrderLiteralPtr applyBindings(const FirstOrderLiteralPtr &lit, const Bindings &bindings)

◆ yes() [2/2]

AnswerYesPtr knowrob::PrologReasoner::yes ( const GoalPtr query,
const PrologTerm rdfGoal,
const PrologTerm frameTerm 
)
protected

Member Data Documentation

◆ isKnowRobInitialized_

bool PrologReasoner::isKnowRobInitialized_ = false
staticprotected

Definition at line 86 of file PrologReasoner.h.

◆ knowledgeGraph_

std::shared_ptr< PrologBackend > knowrob::PrologReasoner::knowledgeGraph_
protected

Definition at line 87 of file PrologReasoner.h.


The documentation for this class was generated from the following files: