knowrob  2.1.0
A Knowledge Base System for Cognition-enabled Robots
ReifiedQuery.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 <utility>
7 
8 #include "knowrob/storage/ReifiedQuery.h"
9 #include "knowrob/semweb/rdf.h"
10 #include "knowrob/storage/reification.h"
11 #include "knowrob/semweb/Property.h"
12 #include "knowrob/queries/QueryError.h"
13 
14 using namespace knowrob;
15 
16 ReifiedQuery::ReifiedQuery(const std::shared_ptr<GraphQuery> &nonReified, VocabularyPtr vocabulary, bool withFullFrame)
17  : GraphQuery(nonReified->ctx()),
18  vocabulary_(std::move(vocabulary)),
19  varCounter_(0),
20  withFullFrame_(withFullFrame) {
21  setNonReified(nonReified->term());
22 }
23 
24 ReifiedQuery::ReifiedQuery(const TriplePattern &nonReified, VocabularyPtr vocabulary, bool withFullFrame)
25  : GraphQuery(),
26  vocabulary_(std::move(vocabulary)),
27  varCounter_(0),
28  withFullFrame_(withFullFrame) {
29  term_ = reifiedPatternSequence(nonReified);
30 }
31 
32 void ReifiedQuery::setNonReified(const std::shared_ptr<GraphTerm> &nonReified) {
33  switch (nonReified->termType()) {
35  term_ = reifyPattern(std::static_pointer_cast<GraphPattern>(nonReified));
36  break;
38  term_ = reifyUnion(std::static_pointer_cast<GraphUnion>(nonReified));
39  break;
41  term_ = reifySequence(std::static_pointer_cast<GraphSequence>(nonReified));
42  break;
44  term_ = nonReified;
45  break;
46  }
47 }
48 
49 void ReifiedQuery::reifyConnective(const std::shared_ptr<GraphConnective> &reifiedConnective, //NOLINT
50  const std::shared_ptr<GraphConnective> &originalConnective) {
51  for (auto &t: originalConnective->terms()) {
52  switch (t->termType()) {
54  reifiedConnective->addMember(reifyPattern(std::static_pointer_cast<GraphPattern>(t)));
55  break;
57  reifiedConnective->addMember(reifyUnion(std::static_pointer_cast<GraphUnion>(t)));
58  break;
60  reifiedConnective->addMember(reifySequence(std::static_pointer_cast<GraphSequence>(t)));
61  break;
63  reifiedConnective->addMember(t);
64  break;
65  }
66  }
67 }
68 
69 std::shared_ptr<GraphUnion> ReifiedQuery::reifyUnion(const std::shared_ptr<GraphUnion> &graphUnion) { //NOLINT
70  auto reified = std::make_shared<GraphUnion>();
71  reifyConnective(reified, graphUnion);
72  return reified;
73 }
74 
75 std::shared_ptr<GraphSequence>
76 ReifiedQuery::reifySequence(const std::shared_ptr<GraphSequence> &graphSequence) { //NOLINT
77  auto reified = std::make_shared<GraphSequence>();
78  reifyConnective(reified, graphSequence);
79  return reified;
80 }
81 
82 std::shared_ptr<GraphTerm> ReifiedQuery::reifyPattern(const std::shared_ptr<GraphPattern> &nonReified) {
83  auto flags = getReificationFlags(*nonReified->value());
84  if (flags & IncludeReified && flags & IncludeOriginal) {
85  // if both reified and original are included, we need to create a union of both
86  auto graphUnion = std::make_shared<GraphUnion>();
87  graphUnion->addMember(nonReified);
88  graphUnion->addMember(reifiedPatternSequence(*nonReified->value()));
89  return graphUnion;
90  } else if (flags & IncludeReified) {
91  return reifiedPatternSequence(*nonReified->value());
92  } else {
93  return nonReified;
94  }
95 }
96 
97 std::shared_ptr<TriplePattern> addPattern(
98  const std::shared_ptr<GraphSequence> &sequence,
99  const TermPtr &s,
100  const TermPtr &p,
101  const TermPtr &o,
102  const groundable<Atom> &g) {
103  auto reified = std::make_shared<TriplePattern>(s, p, o);
104  if (g.has_grounding()) {
105  reified->setGraphName(g.grounded()->stringForm());
106  }
107  sequence->addPattern(reified);
108  return reified;
109 }
110 
111 std::shared_ptr<GraphTerm> ReifiedQuery::reifiedPatternSequence(const TriplePattern &nonReified) {
112  static auto fullyConfident = std::make_shared<Double>(1.0);
113  static auto egoPerspective = Perspective::getEgoPerspective()->atom();
114  static auto b_var = std::make_shared<Variable>("_reified_b");
115  static auto e_var = std::make_shared<Variable>("_reified_e");
116 
117  if (!nonReified.propertyTerm() || !nonReified.propertyTerm()->isAtom()) {
118  throw QueryError("non-reified triple does not have a property term");
119  }
120  auto seq = std::make_shared<GraphSequence>();
121  auto p_atom = std::static_pointer_cast<Atom>(nonReified.propertyTerm());
122  auto property = vocabulary_->defineProperty(p_atom->stringForm());
123  // map the property to a Relation concept
124  auto relationType = property->reification();
125  // generate a unique individual variable.
126  // note that we are actually not interested in its instantiation.
127  auto name = std::make_shared<Variable>("_reified" + std::to_string(varCounter_++));
128  // optionally set origin of reified queries if term is grounded
129  auto &g = nonReified.graphTerm();
130 
131  // create a type assertion
132  addPattern(seq, name, rdf::type, relationType->iriAtom(), g);
133 
134  // create a query for subject
135  addPattern(seq, name, reification::hasSubject, nonReified.subjectTerm(), g);
136 
137  // create a query for the object/literal value
138  std::shared_ptr<TriplePattern> objectQuery;
139  if (property->isObjectProperty()) {
140  objectQuery = addPattern(seq, name, reification::hasObject, nonReified.objectTerm(), g);
141  } else {
142  objectQuery = addPattern(seq, name, reification::hasLiteral, nonReified.objectTerm(), g);
143  }
144  objectQuery->setObjectOperator(nonReified.objectOperator());
145 
146  // create queries for optional properties
147  bool includeOnlyCertain;
148  if (nonReified.isUncertainTerm().has_grounding() && nonReified.isUncertainTerm().grounded()->asBoolean()) {
149  if (withFullFrame_) {
150  auto x = addPattern(seq, name, reification::isUncertain, Numeric::trueAtom(), g);
151  x->setIsOptional(true);
152  }
153  includeOnlyCertain = false;
154  } else if (nonReified.isUncertainTerm().has_variable()) {
155  auto x = addPattern(seq, name, reification::isUncertain, nonReified.isUncertainTerm().variable(), g);
156  x->setIsOptional(true);
157  includeOnlyCertain = false;
158  } else {
159  auto x = addPattern(seq, name, reification::isUncertain, Numeric::falseAtom(), g);
160  x->setIsOptional(true);
161  includeOnlyCertain = true;
162  }
163 
164  if (nonReified.confidenceTerm().has_grounding()) {
165  auto x = addPattern(seq, name, reification::hasConfidence, nonReified.confidenceTerm().grounded(), g);
166  x->setObjectOperator(FilterType::GEQ);
167  x->setIsOptional(true);
168  } else if (nonReified.confidenceTerm().has_variable()) {
169  auto x = addPattern(seq, name, reification::hasConfidence, nonReified.confidenceTerm().variable(), g);
170  x->setIsOptional(true);
171  } else if (includeOnlyCertain) {
172  auto x = addPattern(seq, name, reification::hasConfidence, fullyConfident, g);
173  x->setObjectOperator(FilterType::GEQ);
174  x->setIsOptional(true);
175  }
176 
177  if (nonReified.perspectiveTerm().has_grounding()) {
178  if (Perspective::isEgoPerspective(nonReified.perspectiveTerm().grounded()->stringForm())) {
179  auto x = addPattern(seq, name, reification::hasPerspective, egoPerspective, g);
180  x->setIsOptional(true);
181  } else {
182  addPattern(seq, name, reification::hasPerspective, nonReified.perspectiveTerm().grounded(), g);
183  }
184  } else if (nonReified.perspectiveTerm().has_variable()) {
185  auto x = addPattern(seq, name, reification::hasPerspective, nonReified.perspectiveTerm().variable(), g);
186  x->setIsOptional(true);
187  } else {
188  auto x = addPattern(seq, name, reification::hasPerspective, egoPerspective, g);
189  x->setIsOptional(true);
190  }
191 
192  bool includeOccasional;
193  if (nonReified.isOccasionalTerm().has_grounding() && nonReified.isOccasionalTerm().grounded()->asBoolean()) {
194  if (withFullFrame_) {
195  auto x = addPattern(seq, name, reification::isOccasional, Numeric::trueAtom(), g);
196  x->setIsOptional(true);
197  }
198  includeOccasional = true;
199  } else if (nonReified.isOccasionalTerm().has_variable()) {
200  auto x = addPattern(seq, name, reification::isOccasional, nonReified.isOccasionalTerm().variable(), g);
201  x->setIsOptional(true);
202  includeOccasional = true;
203  } else {
204  auto x = addPattern(seq, name, reification::isOccasional, Numeric::falseAtom(), g);
205  x->setIsOptional(true);
206  includeOccasional = false;
207  }
208 
209  if (nonReified.beginTerm().has_grounding()) {
210  if (includeOccasional) {
211  auto x = addPattern(seq, name, reification::hasEndTime, nonReified.beginTerm().grounded(), g);
212  x->setObjectOperator(FilterType::GEQ);
213  x->setIsOptional(true);
214  } else {
215  auto x = addPattern(seq, name, reification::hasBeginTime, nonReified.beginTerm().grounded(), g);
216  x->setObjectOperator(FilterType::LEQ);
217  x->setIsOptional(true);
218  }
219  } else if (nonReified.beginTerm().has_variable()) {
220  auto x = addPattern(seq, name, reification::hasBeginTime, nonReified.beginTerm().variable(), g);
221  x->setIsOptional(true);
222  } else {
223  auto x = addPattern(seq, name, reification::hasBeginTime, b_var, g);
224  x->setIsNegated(true);
225  }
226 
227  if (nonReified.endTerm().has_grounding()) {
228  if (includeOccasional) {
229  auto x = addPattern(seq, name, reification::hasBeginTime, nonReified.endTerm().grounded(), g);
230  x->setObjectOperator(FilterType::LEQ);
231  x->setIsOptional(true);
232  } else {
233  auto x = addPattern(seq, name, reification::hasEndTime, nonReified.endTerm().grounded(), g);
234  x->setObjectOperator(FilterType::GEQ);
235  x->setIsOptional(true);
236  }
237  } else if (nonReified.endTerm().has_variable()) {
238  auto x = addPattern(seq, name, reification::hasEndTime, nonReified.endTerm().variable(), g);
239  x->setIsOptional(true);
240  } else {
241  auto x = addPattern(seq, name, reification::hasEndTime, e_var, g);
242  x->setIsNegated(true);
243  }
244 
245  return seq;
246 }
247 
249  switch (term->termType()) {
251  return getReificationFlags(*((const GraphPattern *) term)->value()) & IncludeReified;
253  for (auto &t: ((const GraphUnion *) term)->terms()) {
254  if (hasReifiablePattern(t.get())) {
255  return true;
256  }
257  }
258  return false;
260  for (auto &t: ((const GraphSequence *) term)->terms()) {
261  if (hasReifiablePattern(t.get())) {
262  return true;
263  }
264  }
265  return false;
267  return false;
268  }
269  return false;
270 }
271 
272 bool ReifiedQuery::hasReifiablePattern(const std::shared_ptr<GraphQuery> &nonReified) {
273  return hasReifiablePattern(nonReified->term().get());
274 }
275 
277  bool includeOriginal = true;
278  bool includeReified = false;
279  // include reified if isUncertain is true or a variable in the query
280  if ((q.isUncertainTerm().has_grounding() && q.isUncertainTerm().grounded()->asBoolean()) ||
281  q.isUncertainTerm().has_variable()) {
282  includeReified = true;
283  }
284  // include reified if confidence has a value or is a variable
285  if (q.confidenceTerm().has_grounding() || q.confidenceTerm().has_variable()) {
286  includeReified = true;
287  }
288  // include reified if perspective is not the ego perspective or a variable.
289  // In case perspective is not ego perspective, the original triples are not included.
290  if (q.perspectiveTerm().has_grounding()) {
291  auto perspective = q.perspectiveTerm().grounded();
292  if (!Perspective::isEgoPerspective(perspective->stringForm())) {
293  includeOriginal = false;
294  includeReified = true;
295  }
296  } else if (q.perspectiveTerm().has_variable()) {
297  includeReified = true;
298  }
299  // include reified if isOccasional is true or a variable in the query.
300  // In case isOccasional is true, the original triples are not included.
301  if (q.isOccasionalTerm().has_grounding()) {
302  auto occasional = q.isOccasionalTerm().grounded();
303  if (occasional->asBoolean()) {
304  includeReified = true;
305  includeOriginal = false;
306  }
307  } else if (q.isOccasionalTerm().has_variable()) {
308  includeReified = true;
309  }
310  // include reified if begin or end is a variable or has a grounding.
311  if (q.beginTerm().has_grounding() || q.beginTerm().has_variable() ||
312  q.endTerm().has_grounding() || q.endTerm().has_variable()) {
313  includeReified = true;
314  }
315  int flags = 0;
316  if (includeOriginal) flags |= IncludeOriginal;
317  if (includeReified) flags |= IncludeReified;
318  return flags;
319 }
std::shared_ptr< TriplePattern > addPattern(const std::shared_ptr< GraphSequence > &sequence, const TermPtr &s, const TermPtr &p, const TermPtr &o, const groundable< Atom > &g)
auto term() const
Definition: GraphQuery.h:48
std::shared_ptr< GraphTerm > term_
Definition: GraphQuery.h:57
static std::shared_ptr< Numeric > trueAtom()
Definition: Numeric.cpp:15
static std::shared_ptr< Numeric > falseAtom()
Definition: Numeric.cpp:20
static std::shared_ptr< Perspective > getEgoPerspective()
Definition: Perspective.cpp:18
static bool isEgoPerspective(std::string_view iri)
Definition: Perspective.cpp:27
static int getReificationFlags(const TriplePattern &q)
ReifiedQuery(const std::shared_ptr< GraphQuery > &nonReified, VocabularyPtr vocabulary, bool withFullFrame=false)
std::shared_ptr< GraphTerm > reifiedPatternSequence(const TriplePattern &pattern)
void setNonReified(const std::shared_ptr< GraphTerm > &nonReified)
void reifyConnective(const std::shared_ptr< GraphConnective > &reifiedConnective, const std::shared_ptr< GraphConnective > &originalConnective)
static bool hasReifiablePattern(const std::shared_ptr< GraphQuery > &nonReified)
VocabularyPtr vocabulary_
Definition: ReifiedQuery.h:53
std::shared_ptr< GraphTerm > reifyPattern(const std::shared_ptr< GraphPattern > &nonReified)
std::shared_ptr< GraphUnion > reifyUnion(const std::shared_ptr< GraphUnion > &graphUnion)
std::shared_ptr< GraphSequence > reifySequence(const std::shared_ptr< GraphSequence > &graphSequence)
auto objectOperator() const
auto & propertyTerm() const
Definition: TriplePattern.h:92
auto & subjectTerm() const
Definition: TriplePattern.h:81
auto & isOccasionalTerm() const
auto & isUncertainTerm() const
auto & beginTerm() const
auto & objectTerm() const
Definition: TriplePattern.h:97
auto & endTerm() const
auto & graphTerm() const
auto & perspectiveTerm() const
auto & confidenceTerm() const
auto grounded() const
Definition: groundable.h:102
bool has_grounding() const
Definition: groundable.h:92
TermRule & term()
Definition: terms.cpp:136
const IRIAtomPtr type
Definition: rdf.h:15
const IRIAtomPtr hasSubject
Definition: reification.h:15
const IRIAtomPtr isUncertain
Definition: reification.h:18
const IRIAtomPtr hasConfidence
Definition: reification.h:21
const IRIAtomPtr isOccasional
Definition: reification.h:19
const IRIAtomPtr hasEndTime
Definition: reification.h:23
const IRIAtomPtr hasLiteral
Definition: reification.h:17
const IRIAtomPtr hasBeginTime
Definition: reification.h:22
const IRIAtomPtr hasPerspective
Definition: reification.h:20
const IRIAtomPtr hasObject
Definition: reification.h:16
std::shared_ptr< Term > TermPtr
Definition: Term.h:117
@ IncludeReified
Definition: ReifiedQuery.h:18
@ IncludeOriginal
Definition: ReifiedQuery.h:17
std::shared_ptr< Vocabulary > VocabularyPtr
Definition: Vocabulary.h:233