knowrob  2.1.0
A Knowledge Base System for Cognition-enabled Robots
Triple.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/semweb/Triple.h"
7 #include "knowrob/integration/python/utils.h"
8 #include "knowrob/Logger.h"
9 
10 using namespace knowrob;
11 
12 template<typename T>
13 T xsdConv(std::string_view str) {
14  T result;
15  std::istringstream(str.data()) >> result;
16  return result;
17 }
18 
19 template<typename T>
20 T xsdConvFixed(std::string_view str) {
21  T result;
22  std::istringstream(str.data()) >> std::fixed >> result;
23  return result;
24 }
25 
26 bool xsdConvBool(std::string_view str) {
27  bool result;
28  std::istringstream(str.data()) >> std::boolalpha >> result;
29  return result;
30 }
31 
32 void Triple::setXSDValue(std::string_view v, XSDType type) {
33  switch (type) {
34  case XSDType::STRING:
35  setStringValue(v);
36  break;
37  case XSDType::DOUBLE:
38  setDoubleValue(xsdConvFixed<double>(v));
39  break;
40  case XSDType::FLOAT:
41  setDoubleValue(xsdConvFixed<float>(v));
42  break;
44  case XSDType::INTEGER:
45  setIntValue(xsdConv<int>(v));
46  break;
47  case XSDType::LONG:
48  setLongValue(xsdConv<long>(v));
49  break;
50  case XSDType::SHORT:
51  setShortValue(xsdConv<short>(v));
52  break;
54  setUnsignedLongValue(xsdConv<unsigned long>(v));
55  break;
57  setUnsignedIntValue(xsdConv<unsigned int>(v));
58  break;
60  setUnsignedShortValue(xsdConv<unsigned short>(v));
61  break;
62  case XSDType::BOOLEAN:
64  break;
65  case XSDType::LAST:
66  KB_ERROR("Invalid XSD type");
67  break;
68  }
69 }
70 
72  static const auto a_true = "true";
73  static const auto a_false = "false";
74 
75  if (isObjectIRI() || isObjectBlank()) {
76  return std::string(valueAsString());
77  }
78 
79  if (xsdType()) {
80  switch (xsdType().value()) {
81  case XSDType::DOUBLE: {
82  std::ostringstream os;
83  os << std::fixed << valueAsDouble();
84  return os.str();
85  }
86  case XSDType::FLOAT: {
87  std::ostringstream os;
88  os << std::fixed << valueAsFloat();
89  return os.str();
90  }
92  case XSDType::INTEGER:
93  return std::to_string(valueAsInt());
94  case XSDType::LONG:
95  return std::to_string(valueAsLong());
96  case XSDType::SHORT:
97  return std::to_string(valueAsShort());
99  return std::to_string(valueAsUnsignedLong());
101  return std::to_string(valueAsUnsignedInt());
103  return std::to_string(valueAsUnsignedShort());
104  case XSDType::BOOLEAN:
105  return valueAsBoolean() ? a_true : a_false;
106  case XSDType::STRING:
107  return std::string(valueAsString());
108  case XSDType::LAST:
109  break;
110  }
111  }
112 
113  return "null";
114 }
115 
116 bool Triple::operator<(const Triple &other) const {
117  if (graph() != other.graph()) {
118  return graph() < other.graph();
119  }
120  if (perspective() != other.perspective()) {
121  return perspective() < other.perspective();
122  }
123  if (subject() != other.subject()) {
124  return subject() < other.subject();
125  }
126  if (predicate() != other.predicate()) {
127  return predicate() < other.predicate();
128  }
129  if (xsdType() != other.xsdType()) {
130  return xsdType() < other.xsdType();
131  }
132  if (xsdType()) {
133  switch (xsdType().value()) {
134  case XSDType::STRING:
135  if (valueAsString() != other.valueAsString()) {
136  return valueAsString() < other.valueAsString();
137  } else {
138  break;
139  }
140  case XSDType::DOUBLE:
141  if (valueAsDouble() != other.valueAsDouble()) {
142  return valueAsDouble() < other.valueAsDouble();
143  } else {
144  break;
145  }
146  case XSDType::FLOAT:
147  if (valueAsFloat() != other.valueAsFloat()) {
148  return valueAsFloat() < other.valueAsFloat();
149  } else {
150  break;
151  }
153  case XSDType::INTEGER:
154  if (valueAsInt() != other.valueAsInt()) {
155  return valueAsInt() < other.valueAsInt();
156  } else {
157  break;
158  }
159  case XSDType::BOOLEAN:
160  if (valueAsBoolean() != other.valueAsBoolean()) {
161  return valueAsBoolean() < other.valueAsBoolean();
162  } else {
163  break;
164  }
165  case XSDType::LONG:
166  if (valueAsLong() != other.valueAsLong()) {
167  return valueAsLong() < other.valueAsLong();
168  } else {
169  break;
170  }
171  case XSDType::SHORT:
172  if (valueAsShort() != other.valueAsShort()) {
173  return valueAsShort() < other.valueAsShort();
174  } else {
175  break;
176  }
178  if (valueAsUnsignedLong() != other.valueAsUnsignedLong()) {
179  return valueAsUnsignedLong() < other.valueAsUnsignedLong();
180  } else {
181  break;
182  }
184  if (valueAsUnsignedInt() != other.valueAsUnsignedInt()) {
185  return valueAsUnsignedInt() < other.valueAsUnsignedInt();
186  } else {
187  break;
188  }
190  if (valueAsUnsignedShort() != other.valueAsUnsignedShort()) {
191  return valueAsUnsignedShort() < other.valueAsUnsignedShort();
192  } else {
193  break;
194  }
195  case XSDType::LAST:
196  KB_ERROR("Invalid XSD type");
197  break;
198  }
199  } else if (valueAsString() != other.valueAsString()) {
200  return valueAsString() < other.valueAsString();
201  }
202  if (isUncertain() != other.isUncertain()) {
203  return isUncertain() < other.isUncertain();
204  }
205  if (isOccasional() != other.isOccasional()) {
206  return isOccasional() < other.isOccasional();
207  }
208  if (begin() != other.begin()) {
209  return begin() < other.begin();
210  }
211  if (end() != other.end()) {
212  return end() < other.end();
213  }
214  if (confidence() != other.confidence()) {
215  return confidence() < other.confidence();
216  }
217  return false;
218 }
219 
220 bool Triple::operator==(const Triple &other) const {
221  if (subject() != other.subject()) return false;
222  if (predicate() != other.predicate()) return false;
223  if (graph(), other.graph()) return false;
224  if (perspective(), other.perspective()) return false;
225  if (isUncertain() != other.isUncertain()) return false;
226  if (isOccasional() != other.isOccasional()) return false;
227  if (begin() != other.begin()) return false;
228  if (end() != other.end()) return false;
229  if (confidence() != other.confidence()) return false;
230  if (xsdType() != other.xsdType()) return false;
231  if (xsdType()) {
232  switch (xsdType().value()) {
233  case XSDType::STRING:
234  if (valueAsString() != other.valueAsString()) return false;
235  break;
236  case XSDType::DOUBLE:
237  if (valueAsDouble() != other.valueAsDouble()) return false;
238  break;
239  case XSDType::FLOAT:
240  if (valueAsFloat() != other.valueAsFloat()) return false;
241  break;
242  case XSDType::BOOLEAN:
243  if (valueAsBoolean() != other.valueAsBoolean()) return false;
244  break;
246  case XSDType::INTEGER:
247  if (valueAsInt() != other.valueAsInt()) return false;
248  break;
249  case XSDType::LONG:
250  if (valueAsLong() != other.valueAsLong()) return false;
251  break;
252  case XSDType::SHORT:
253  if (valueAsShort() != other.valueAsShort()) return false;
254  break;
256  if (valueAsUnsignedLong() != other.valueAsUnsignedLong()) return false;
257  break;
259  if (valueAsUnsignedInt() != other.valueAsUnsignedInt()) return false;
260  break;
262  if (valueAsUnsignedShort() != other.valueAsUnsignedShort()) return false;
263  break;
264  case XSDType::LAST:
265  KB_ERROR("Invalid XSD type");
266  break;
267  }
268  } else if (valueAsString() != other.valueAsString()) {
269  return false;
270  }
271  return true;
272 }
273 
274 bool Triple::mergeFrame(const Triple &other) {
275  bool sameBegin = begin() == other.begin();
276  bool sameEnd = end() == other.end();
277  bool sameTime = sameBegin && sameEnd;
278 
279  if (sameTime) {
280  // occasional can switch to always if both triples have the same time
282  // same for uncertain vs. certain
283  setIsUncertain(isUncertain() && other.isUncertain());
284  // plus we can take the max confidence
285  if (other.confidence().has_value() && confidence().has_value()) {
286  setConfidence(std::max(confidence().value(), other.confidence().value()));
287  } else if (!other.confidence().has_value()) {
288  confidence_ = std::nullopt;
289  }
290  } else {
291  // either both triples must be occasional or neither
292  if (isOccasional() != other.isOccasional()) return false;
293  // same for uncertain vs. certain
294  if (isUncertain() != other.isUncertain()) return false;
295  // also confidence must match in order to merge different time frames
296  if (confidence() != other.confidence()) return false;
297  // finally we can merge time frame
298  if (isOccasional()) {
299  if (begin() && other.begin()) {
300  setBegin(std::max(begin().value(), other.begin().value()));
301  } else if (other.begin()) {
302  setBegin(other.begin().value());
303  }
304  if (end() && other.end()) {
305  setEnd(std::min(end().value(), other.end().value()));
306  } else if (other.end()) {
307  setEnd(other.end().value());
308  }
309  } else {
310  if (begin() && other.begin()) {
311  setBegin(std::min(begin().value(), other.begin().value()));
312  } else if (!other.begin().has_value()) {
313  begin_ = std::nullopt;
314  }
315  if (end() && other.end()) {
316  setEnd(std::max(end().value(), other.end().value()));
317  } else if (!other.end().has_value()) {
318  end_ = std::nullopt;
319  }
320  }
321  }
322  return true;
323 }
324 
325 void Triple::write(std::ostream &os) const {
326  os << '(';
327  os << subject() << ',' << ' ';
328  os << predicate() << ',' << ' ';
329  if (isObjectIRI() || isObjectBlank()) {
330  os << valueAsString();
331  } else {
332  os << createStringValue();
333  }
334  if (graph()) {
335  os << ',' << " g=" << graph().value();
336  }
337  if (perspective()) {
338  os << ',' << " p=" << perspective().value();
339  }
340  if (isOccasional()) {
341  os << ',' << " o";
342  }
343  if (isUncertain()) {
344  os << ',' << " u";
345  }
346  if (begin()) {
347  os << ',' << " b=" << begin().value();
348  }
349  if (end()) {
350  os << ',' << " e=" << end().value();
351  }
352  os << ')';
353 }
354 
355 namespace knowrob::py {
356  // this struct is needed because Triple has pure virtual methods
357  struct TripleWrap : public Triple, boost::python::wrapper<Triple> {
358  explicit TripleWrap(PyObject *p) : Triple(), self(p) {}
359 
360  void setSubject(std::string_view subject) override { call_method<void>(self, "setSubject", subject); }
361 
362  void setPredicate(std::string_view predicate) override { call_method<void>(self, "setPredicate", predicate); }
363 
364  void setObjectIRI(std::string_view object) override { call_method<void>(self, "setObjectIRI", object); }
365 
366  void setSubjectBlank(std::string_view str) override { call_method<void>(self, "setSubjectBlank", str); }
367 
368  void setObjectBlank(std::string_view str) override { call_method<void>(self, "setObjectBlank", str); }
369 
370  std::string_view subject() const override { return call_method<std::string_view>(self, "subject"); }
371 
372  std::string_view predicate() const override { return call_method<std::string_view>(self, "predicate"); }
373 
374  void setGraph(std::string_view graph) override { call_method<void>(self, "setGraph", graph); }
375 
376  void setPerspective(std::string_view perspective) override {
377  call_method<void>(self, "setPerspective", perspective);
378  }
379 
380  std::optional<std::string_view> graph() const override {
381  return call_method<std::optional<std::string_view>>(self, "graph");
382  }
383 
384  std::optional<std::string_view> perspective() const override {
385  return call_method<std::optional<std::string_view>>(self, "perspective");
386  }
387 
388  std::string_view valueAsString() const override { return call_method<std::string_view>(self, "valueAsString"); }
389 
390  private:
391  PyObject *self;
392  };
393 
394  template<>
396  using namespace boost::python;
397  class_<Triple, std::shared_ptr<TripleWrap>, boost::noncopyable>
398  ("Triple", no_init)
399  .def("__eq__", &Triple::operator==)
400  .def("isObjectIRI", &Triple::isObjectIRI)
401  .def("isSubjectIRI", &Triple::isSubjectIRI)
402  .def("isObjectBlank", &Triple::isObjectBlank)
403  .def("isSubjectBlank", &Triple::isSubjectBlank)
404  .def("isXSDLiteral", &Triple::isXSDLiteral)
405  .def("setSubject", pure_virtual(&Triple::setSubject))
406  .def("setPredicate", pure_virtual(&Triple::setPredicate))
407  .def("setSubjectBlank", pure_virtual(&Triple::setSubjectBlank))
408  .def("setObjectIRI", pure_virtual(&Triple::setObjectIRI))
409  .def("setObjectBlank", pure_virtual(&Triple::setObjectBlank))
410  .def("valueAsString", pure_virtual(&Triple::valueAsString))
411  .def("createStringValue", &Triple::createStringValue)
412  .def("setXSDValue", &Triple::setXSDValue)
413  .def("xsdTypeIRI", &Triple::xsdTypeIRI)
414  .def("setGraph", pure_virtual(&Triple::setGraph))
415  .def("setPerspective", pure_virtual(&Triple::setPerspective))
416  .def("setIsOccasional", &Triple::setIsOccasional)
417  .def("setIsUncertain", &Triple::setIsUncertain)
418  .def("setBegin", &Triple::setBegin)
419  .def("setEnd", &Triple::setEnd)
420  .def("setConfidence", &Triple::setConfidence)
421  .def("xsdType", &Triple::xsdType)
422  .def("subject", pure_virtual(&Triple::subject))
423  .def("predicate", pure_virtual(&Triple::predicate))
424  .def("graph", pure_virtual(&Triple::graph))
425  .def("perspective", pure_virtual(&Triple::perspective))
426  .def("isOccasional", &Triple::isOccasional)
427  .def("isUncertain", &Triple::isUncertain)
428  .def("begin", &Triple::begin)
429  .def("end", &Triple::end)
430  .def("confidence", &Triple::confidence);
431  class_<TripleCopy, std::shared_ptr<TripleCopy>, bases<Triple>>
432  ("TripleCopy", init<>())
433  .def(init<std::string_view, std::string_view, std::string_view>());
434  class_<TripleView, std::shared_ptr<TripleView>, bases<Triple>>
435  ("TripleView", init<>())
436  .def(init<std::string_view, std::string_view, std::string_view>());
437  class_<TriplePtr>("TriplePtr", init<>())
438  .def("get", &TriplePtr::get, return_value_policy<reference_existing_object>());
439  }
440 }
T xsdConvFixed(std::string_view str)
Definition: Triple.cpp:20
bool xsdConvBool(std::string_view str)
Definition: Triple.cpp:26
T xsdConv(std::string_view str)
Definition: Triple.cpp:13
#define KB_ERROR
Definition: Logger.h:28
virtual std::string_view valueAsString() const =0
auto xsdType() const
Definition: Triple.h:64
void write(std::ostream &os) const override
Definition: Triple.cpp:325
virtual short valueAsShort() const =0
virtual std::optional< std::string_view > perspective() const =0
bool isUncertain() const
Definition: Triple.h:267
virtual void setDoubleValue(double v)=0
virtual unsigned int valueAsUnsignedInt() const =0
virtual void setSubject(std::string_view subject)=0
virtual std::optional< std::string_view > graph() const =0
std::optional< double > end_
Definition: Triple.h:333
bool isXSDLiteral() const
Definition: Triple.h:39
virtual double valueAsDouble() const =0
virtual void setGraph(std::string_view graph)=0
virtual void setIntValue(int v)=0
auto end() const
Definition: Triple.h:277
virtual void setStringValue(std::string_view v)=0
virtual void setUnsignedLongValue(unsigned long v)=0
void setConfidence(double confidence)
Definition: Triple.h:307
virtual std::string_view subject() const =0
bool isSubjectIRI() const
Definition: Triple.h:59
std::optional< double > confidence_
Definition: Triple.h:334
virtual float valueAsFloat() const =0
bool operator==(const Triple &other) const
Definition: Triple.cpp:220
auto confidence() const
Definition: Triple.h:282
virtual void setPerspective(std::string_view perspective)=0
void setIsUncertain(bool isUncertain)
Definition: Triple.h:292
virtual void setLongValue(long v)=0
auto begin() const
Definition: Triple.h:272
void setIsOccasional(bool isOccasional)
Definition: Triple.h:287
bool isSubjectBlank() const
Definition: Triple.h:44
std::optional< double > begin_
Definition: Triple.h:332
bool mergeFrame(const Triple &other)
Definition: Triple.cpp:274
virtual std::string_view predicate() const =0
void setBegin(double begin)
Definition: Triple.h:297
void setEnd(double end)
Definition: Triple.h:302
virtual long valueAsLong() const =0
std::string createStringValue() const
Definition: Triple.cpp:71
virtual void setObjectIRI(std::string_view object)=0
virtual void setUnsignedIntValue(unsigned int v)=0
bool operator<(const Triple &other) const
Definition: Triple.cpp:116
bool isObjectIRI() const
Definition: Triple.h:54
virtual unsigned short valueAsUnsignedShort() const =0
virtual void setObjectBlank(std::string_view str)=0
virtual unsigned long valueAsUnsignedLong() const =0
virtual void setUnsignedShortValue(unsigned short v)=0
virtual void setSubjectBlank(std::string_view str)=0
auto xsdTypeIRI() const
Definition: Triple.h:69
virtual void setPredicate(std::string_view predicate)=0
virtual void setShortValue(short v)=0
bool isOccasional() const
Definition: Triple.h:262
bool isObjectBlank() const
Definition: Triple.h:49
virtual int valueAsInt() const =0
virtual bool valueAsBoolean() const =0
virtual void setBooleanValue(bool v)=0
void setXSDValue(std::string_view v, XSDType type)
Definition: Triple.cpp:32
PredicateRule & predicate()
Definition: formula.cpp:221
TermRule & string()
Definition: terms.cpp:63
void createType< Triple >()
Definition: Triple.cpp:395
const IRIAtomPtr type
Definition: rdf.h:15
XSDType
The XSDType enum Enumeration of the XSD types.
Definition: XSDType.h:16
Triple & get() const
Definition: Triple.h:615