knowrob  2.1.0
A Knowledge Base System for Cognition-enabled Robots
InterfaceUtils.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2023, Sascha Jongebloed
3  * All rights reserved.
4  *
5  * This file is part of KnowRob, please consult
6  * https://github.com/knowrob/knowrob for license details.
7  */
8 
9 #include <unordered_map>
10 #include <boost/any.hpp>
11 #include <boost/property_tree/json_parser.hpp>
12 #include "knowrob/integration/InterfaceUtils.h"
13 #include "knowrob/formulas/ModalFormula.h"
14 #include "knowrob/semweb/Triple.h"
15 #include "knowrob/queries/QueryTree.h"
16 #include "knowrob/queries/QueryError.h"
17 #include "knowrob/KnowledgeBase.h"
18 
19 
20 using namespace knowrob;
21 
22 // enum for epistemicOperator
24  KNOWLEDGE = 0,
25  BELIEF = 1
26 };
27 
28 // enum for temporalOperator
30  CURRENTLY = 0,
31  ALL_PAST = 1,
32  SOME_PAST = 2
33 };
34 
35 boost::property_tree::ptree InterfaceUtils::loadSettings() {
36  // Check for settings file
37  std::string config_path = "default.json";
38  if (std::getenv("KNOWROB_SETTINGS")) {
39  config_path = std::getenv("KNOWROB_SETTINGS");
40  }
41 
42  // read the settings
43  boost::property_tree::ptree config;
44  boost::property_tree::read_json(
45  config_path,
46  config);
47 
48  return config;
49 
50 }
51 
52 bool InterfaceUtils::assertStatements(const KnowledgeBasePtr &kb_, const std::vector<FormulaPtr> &args) {
53  // Create the query trees for each formula and calculate the number of nodes of type Predicate
54  // first create the list of query trees
55  std::vector<std::unique_ptr<QueryTree>> queryTrees;
56  for (auto &phi : args) {
57  auto qt = std::make_unique<QueryTree>(phi);
58  if (qt->numPaths() > 1) {
59  throw QueryError("Disjunctions are not allowed in assertions. "
60  "Appears in statement {}.", *phi);
61  } else if (qt->numPaths() == 0) {
62  throw QueryError("Invalid assertion: '{}'", *phi);
63  }
64  queryTrees.push_back(std::move(qt)); // ✔️ move the unique_ptr
65  }
66  // create a counter for the number of nodes of type Predicate
67  int numPredicates = 0;
68  for (auto &qt: queryTrees) {
69  for (auto &psi: qt->begin()->nodes()) {
70  if (psi->type() == knowrob::FormulaType::PREDICATE) {
71  numPredicates += 1;
72  }
73  }
74  }
75 
76  // create a vector of TriplePtr and TriplePatternPtr
77  std::vector<TriplePtr> data(numPredicates);
78  std::vector<TriplePatternPtr> buf(numPredicates);
79  uint32_t dataIndex = 0;
80 
81  // iterate over the query trees and create the TriplePattern objects
82  for (auto &qt: queryTrees) {
83  for (auto &psi: qt->begin()->nodes()) {
84  switch (psi->type()) {
86  buf[dataIndex] = std::make_shared<TriplePattern>(
87  std::static_pointer_cast<Predicate>(psi), false);
88  data[dataIndex].ptr = new TripleCopy();
89  data[dataIndex].owned = true;
90  buf[dataIndex]->instantiateInto(*data[dataIndex].ptr);
91  dataIndex += 1;
92  break;
93  default:
94  throw QueryError("Invalid assertion: '{}'", *psi);
95  }
96  }
97  }
98 
99 
100  if (kb_->insertAll(data)) {
101  std::cout << "success, " << dataIndex << " statement(s) were asserted." << "\n";
102  return true;
103  } else {
104  std::cout << "assertion failed." << "\n";
105  return false;
106  }
107 }
108 
110 InterfaceUtils::applyModality(const std::unordered_map<std::string, boost::any> &options,
111  FormulaPtr phi) {
112  FormulaPtr mFormula = std::move(phi);
113 
114  // Retrieve epistemicOperator and check if it is "BELIEF"
115  auto epistemicOperator = boost::any_cast<int>(options.at("epistemicOperator"));
116  if (epistemicOperator == EpistemicOperator::BELIEF) {
117  // Retrieve aboutAgentIRI and confidence
118  auto aboutAgentIRI = boost::any_cast<std::string>(options.at("aboutAgentIRI"));
119  auto confidence = boost::any_cast<double>(options.at("confidence"));
120  if (!aboutAgentIRI.empty()) {
121  if (confidence != 1.0) {
122  mFormula = std::make_shared<ModalFormula>(
123  modals::B(aboutAgentIRI, confidence), mFormula);
124  } else {
125  mFormula = std::make_shared<ModalFormula>(
126  modals::B(aboutAgentIRI), mFormula);
127  }
128  }
129  } else if (epistemicOperator == EpistemicOperator::KNOWLEDGE) {
130  // Retrieve aboutAgentIRI
131  auto aboutAgentIRI = boost::any_cast<std::string>(options.at("aboutAgentIRI"));
132  if (!aboutAgentIRI.empty()) {
133  mFormula = std::make_shared<ModalFormula>(
134  modals::K(aboutAgentIRI), mFormula);
135  }
136  }
137  // Retrieve temporalOperator
138  auto temporalOperator = boost::any_cast<int>(options.at("temporalOperator"));
139 
140  // Retrieve minPastTimestamp and maxPastTimestamp
141  auto minPastTimestamp = boost::any_cast<double>(options.at("minPastTimestamp"));
142  auto maxPastTimestamp = boost::any_cast<double>(options.at("maxPastTimestamp"));
143 
144  auto minPastTimePoint =
145  minPastTimestamp != -1 ? std::optional<TimePoint>(knowrob::time::fromSeconds(minPastTimestamp))
146  : std::nullopt;
147  auto maxPastTimePoint =
148  maxPastTimestamp != -1 ? std::optional<TimePoint>(knowrob::time::fromSeconds(maxPastTimestamp))
149  : std::nullopt;
150 
151  if (temporalOperator == TemporalOperator::SOME_PAST) {
152  if (minPastTimestamp != -1 || maxPastTimestamp != -1) {
153  if (minPastTimestamp == -1) {
154  mFormula = std::make_shared<ModalFormula>(
155  modals::P(TimeInterval(std::nullopt,
156  maxPastTimePoint)), mFormula);
157  } else if (maxPastTimestamp == -1) {
158  mFormula = std::make_shared<ModalFormula>(
159  modals::P(TimeInterval(minPastTimePoint,
160  std::nullopt)), mFormula);
161  } else {
162  mFormula = std::make_shared<ModalFormula>(
163  modals::P(TimeInterval(minPastTimePoint,
164  maxPastTimePoint)), mFormula);
165  }
166  } else {
167  mFormula = std::make_shared<ModalFormula>(
168  modals::P(), mFormula);
169  }
170  } else if (temporalOperator == TemporalOperator::ALL_PAST) {
171  if (minPastTimestamp != -1 || maxPastTimestamp != -1) {
172  if (minPastTimestamp == -1) {
173  mFormula = std::make_shared<ModalFormula>(
174  modals::H(TimeInterval(std::nullopt,
175  maxPastTimePoint)), mFormula);
176  } else if (maxPastTimestamp == -1) {
177  mFormula = std::make_shared<ModalFormula>(
178  modals::H(TimeInterval(minPastTimePoint,
179  std::nullopt)), mFormula);
180  } else {
181  mFormula = std::make_shared<ModalFormula>(
182  modals::H(TimeInterval(minPastTimePoint,
183  maxPastTimePoint)), mFormula);
184  }
185  } else {
186  mFormula = std::make_shared<ModalFormula>(
187  modals::H(), mFormula);
188  }
189  }
190  return mFormula;
191 }
192 
193 namespace knowrob::py {
194  template<>
196  using namespace boost::python;
197 
198  // Expose InterfaceUtils class and its methods
199  class_<InterfaceUtils>("InterfaceUtils")
200  .def("assertStatements", &InterfaceUtils::assertStatements).staticmethod("assertStatements")
201  .def("applyModality", &InterfaceUtils::applyModality).staticmethod("applyModality");
202 
203  // Expose enums
204  enum_<EpistemicOperator>("EpistemicOperator")
205  .value("KNOWLEDGE", KNOWLEDGE)
206  .value("BELIEF", BELIEF);
207  enum_<TemporalOperator>("TemporalOperator")
208  .value("CURRENTLY", CURRENTLY)
209  .value("ALL_PAST", ALL_PAST)
210  .value("SOME_PAST", SOME_PAST);
211  }
212 }
TemporalOperator
@ SOME_PAST
@ CURRENTLY
@ ALL_PAST
EpistemicOperator
@ KNOWLEDGE
@ BELIEF
static boost::property_tree::ptree loadSettings()
static FormulaPtr applyModality(const std::unordered_map< std::string, boost::any > &options, FormulaPtr phi)
static bool assertStatements(const KnowledgeBasePtr &kb, const std::vector< FormulaPtr > &args)
std::shared_ptr< ModalFormula > K(const FormulaPtr &phi)
std::shared_ptr< ModalFormula > P(const FormulaPtr &phi)
std::shared_ptr< ModalFormula > B(const FormulaPtr &phi)
std::shared_ptr< ModalFormula > H(const FormulaPtr &phi)
TermRule & string()
Definition: terms.cpp:63
TermRule & options()
Definition: terms.cpp:114
void createType< InterfaceUtils >()
TimePoint fromSeconds(double seconds)
Definition: TimePoint.cpp:17
std::shared_ptr< KnowledgeBase > KnowledgeBasePtr
TripleTemplate< std::string > TripleCopy
Definition: Triple.h:577
std::shared_ptr< Formula > FormulaPtr
Definition: Formula.h:99