knowrob  2.1.0
A Knowledge Base System for Cognition-enabled Robots
Answer.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/queries/Answer.h>
7 #include "knowrob/Logger.h"
8 #include "knowrob/knowrob.h"
9 #include "knowrob/queries/AnswerYes.h"
10 #include "knowrob/queries/AnswerNo.h"
11 #include "knowrob/queries/AnswerDontKnow.h"
12 #include "knowrob/integration/python/utils.h"
13 #include "knowrob/queries/EndOfEvaluation.h"
14 
15 using namespace knowrob;
16 
17 void Answer::setFrame(const std::shared_ptr<GraphSelector> &frame) {
18  if (frame != nullptr) {
19  frame_ = frame;
20  } else {
21  throw std::invalid_argument("frame must not be null");
22  }
23 }
24 
25 void Answer::applyFrame(const GraphSelector &frame) {
26  frame_->graph = frame.graph;
27  frame_->perspective = frame.perspective;
28  frame_->confidence = std::nullopt;
29  frame_->begin = frame.begin;
30  frame_->end = frame.end;
31  frame_->uncertain = frame.uncertain;
32  frame_->occasional = frame.occasional;
33 }
34 
35 bool Answer::isUncertain() const {
36  if (frame_->confidence.has_value()) {
37  if (frame_->confidence.value() < 1.0) return true;
38  }
39  if (frame_->uncertain) {
40  return true;
41  }
42  return false;
43 }
44 
46  return frame_->occasional;
47 }
48 
49 void Answer::setIsUncertain(bool val, std::optional<double> confidence) {
50  frame_->uncertain = val;
51  if (val) {
52  if (confidence.has_value()) {
53  frame_->confidence = confidence;
54  }
55  } else {
56  frame_->confidence = 1.0;
57  }
58 }
59 
61  frame_->occasional = val;
62 }
63 
64 size_t Answer::hashOfAnswer() const {
65  size_t val = 0;
66  hashCombine(val, uint8_t(tokenType()));
67  if (isNegative()) {
68  hashCombine(val, 0);
69  } else if (isPositive()) {
70  hashCombine(val, 1);
71  } else {
72  hashCombine(val, 2);
73  }
74  if (reasonerTerm()) {
75  hashCombine(val, reasonerTerm()->hash());
76  } else {
77  hashCombine(val, 0);
78  }
79  if (frame()) {
80  hashCombine(val, frame()->hash());
81  } else {
82  hashCombine(val, 0);
83  }
84  if (isPositive()) {
85  auto &bindings = ((AnswerYes *) this)->substitution();
86  hashCombine(val, bindings->hash());
87  }
88  return val;
89 }
90 
92  if (isNegative()) {
93  return ((AnswerNo *) this)->stringFormOfNo();
94  } else if (isPositive()) {
95  return ((AnswerYes *) this)->stringFormOfYes();
96  } else {
97  return ((AnswerDontKnow *) this)->stringFormOfDontKnow();
98  }
99 }
100 
102  if (isNegative()) {
103  return ((AnswerNo *) this)->humanReadableFormOfNo();
104  } else if (isPositive()) {
105  return ((AnswerYes *) this)->humanReadableFormOfYes();
106  } else {
107  return ((AnswerDontKnow *) this)->humanReadableFormOfDontKnow();
108  }
109 }
110 
111 namespace knowrob {
112  AnswerPtr mergeAnswers(const AnswerPtr &a, const AnswerPtr &b, bool ignoreInconsistencies) {
113  // also for the moment we do not combine two negative answers
114  if (a->isNegative()) {
115  if (b->isNegative()) {
116  // both are on
117  auto a_negative = std::static_pointer_cast<const AnswerNo>(a);
118  auto b_negative = std::static_pointer_cast<const AnswerNo>(b);
119  return mergeNegativeAnswers(a_negative, b_negative);
120  } else {
121  // a is "no"
122  return a;
123  }
124  } else if (b->isNegative()) {
125  // b is "no"
126  return b;
127  } else if (a->isPositive()) {
128  if (b->isPositive()) {
129  // both positive -> combine
130  auto a_positive = std::static_pointer_cast<const AnswerYes>(a);
131  auto b_positive = std::static_pointer_cast<const AnswerYes>(b);
132  return mergePositiveAnswers(a_positive, b_positive, ignoreInconsistencies);
133  } else {
134  // b is "don't know"
135  return b;
136  }
137  } else {
138  // b is "don't know"
139  return a;
140  }
141  }
142 
143  bool AnswerComparator::operator()(const AnswerPtr &v0, const AnswerPtr &v1) const {
144  if (!v0) {
145  if (!v1) return false;
146  else return true;
147  } else if (!v1 || v0 == v1) {
148  return false;
149  } else if (v0->isCertain() != v1->isCertain()) {
150  return v0->isCertain() < v1->isCertain();
151  } else if (v0->isPositive() != v1->isPositive()) {
152  return v0->isPositive() < v1->isPositive();
153  } else if (v0->isNegative() != v1->isNegative()) {
154  return v0->isNegative() > v1->isNegative();
155  } else {
156  return v0->hashOfAnswer() < v1->hashOfAnswer();
157  }
158  }
159 }
160 
161 namespace knowrob::py {
162  template<>
164  using namespace boost::python;
165  class_<Answer, std::shared_ptr<Answer>, boost::noncopyable, bases<Token>>
166  ("Answer", no_init)
167  .def("__str__", &AnswerYes::humanReadableForm)
168  .def("isPositive", &Answer::isPositive)
169  .def("isNegative", &Answer::isNegative)
170  .def("isCertain", &Answer::isCertain)
171  .def("isUncertain", &Answer::isUncertain)
172  .def("isOccasionallyTrue", &Answer::isOccasionallyTrue)
173  .def("setIsOccasionallyTrue", &Answer::setIsOccasionallyTrue)
174  .def("setIsUncertain", &Answer::setIsUncertain)
175  .def("setFrame", &Answer::setFrame)
176  .def("frame", &Answer::frame, return_value_policy<copy_const_reference>())
177  .def("reasonerTerm", &Answer::reasonerTerm, return_value_policy<copy_const_reference>());
178  // Allow implicit conversion from shared_ptr<Answer> to shared_ptr<const Answer>
179  register_ptr_to_python<std::shared_ptr<const Answer> >();
180  implicitly_convertible<std::shared_ptr<Answer>, std::shared_ptr<const Answer> >();
181  // Create subtypes
185  }
186 }
size_t hashOfAnswer() const
Definition: Answer.cpp:64
std::string stringFormOfAnswer() const
Definition: Answer.cpp:91
bool isPositive() const
Definition: Answer.h:57
bool isOccasionallyTrue() const
Definition: Answer.cpp:45
std::string humanReadableForm() const
Definition: Answer.cpp:101
auto & reasonerTerm() const
Definition: Answer.h:100
bool isCertain() const
Definition: Answer.h:67
bool isUncertain() const
Definition: Answer.cpp:35
void setIsUncertain(bool val, std::optional< double > confidence)
Definition: Answer.cpp:49
void applyFrame(const GraphSelector &frame)
Definition: Answer.cpp:25
void setIsOccasionallyTrue(bool val)
Definition: Answer.cpp:60
auto & frame() const
Definition: Answer.h:35
void setFrame(const std::shared_ptr< GraphSelector > &frame)
Definition: Answer.cpp:17
std::shared_ptr< GraphSelector > frame_
Definition: Answer.h:118
bool isNegative() const
Definition: Answer.h:52
TokenType tokenType() const
Definition: Token.h:38
size_t hash() const
Definition: Token.cpp:15
TermRule & string()
Definition: terms.cpp:63
void createType< AnswerNo >()
Definition: AnswerNo.cpp:101
void createType< AnswerYes >()
Definition: AnswerYes.cpp:193
void createType< Answer >()
Definition: Answer.cpp:163
void createType< AnswerDontKnow >()
AnswerPtr mergeAnswers(const AnswerPtr &a, const AnswerPtr &b, bool ignoreInconsistencies)
Definition: Answer.cpp:112
void hashCombine(std::size_t &seed, const std::size_t &v)
Definition: knowrob.cpp:39
AnswerPtr mergePositiveAnswers(const AnswerYesPtr &a, const AnswerYesPtr &b, bool ignoreInconsistencies)
Definition: AnswerYes.cpp:166
AnswerPtr mergeNegativeAnswers(const AnswerNoPtr &a, const AnswerNoPtr &b)
Definition: AnswerNo.cpp:88
std::shared_ptr< const Answer > AnswerPtr
Definition: Answer.h:129
bool operator()(const AnswerPtr &v0, const AnswerPtr &v1) const
Definition: Answer.cpp:143