knowrob  2.1.0
A Knowledge Base System for Cognition-enabled Robots
QueryableStorage.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/storage/QueryableStorage.h"
7 #include <knowrob/semweb/TripleFormatter.h>
8 #include "knowrob/ThreadPool.h"
9 #include "knowrob/queries/AnswerNo.h"
10 #include "knowrob/queries/AnswerYes.h"
11 #include "knowrob/semweb/GraphBuiltin.h"
12 #include "knowrob/semweb/ImportHierarchy.h"
13 #include "knowrob/semweb/GraphSequence.h"
14 #include "knowrob/semweb/GraphUnion.h"
15 #include "knowrob/integration/python/utils.h"
16 
17 using namespace knowrob;
18 
19 AtomPtr QueryableStorage::versionProperty = IRIAtom::Tabled("http://knowrob.org/kb/knowrob.owl#hasVersionOfOrigin");
20 
22  : Storage(features) {
23 }
24 
25 std::vector<VersionedOriginPtr> QueryableStorage::getOrigins() {
26  static auto v_origin = std::make_shared<Variable>("Origin");
27  static auto v_version = std::make_shared<Variable>("Version");
28  std::vector<VersionedOriginPtr> origins;
29  match(TriplePattern(v_origin, versionProperty, v_version),
30  [&](const TriplePtr &triple) {
31  origins.push_back(std::make_shared<VersionedOrigin>(triple->subject(), triple->valueAsString()));
32  });
33  return origins;
34 }
35 
36 void QueryableStorage::setVersionOfOrigin(std::string_view origin, std::string_view version) {
37  TripleView triple;
38  triple.setSubject(origin);
39  triple.setPredicate(versionProperty->stringForm());
40  triple.setStringValue(version);
41  triple.setGraph(origin);
42  insertOne(triple);
43 }
44 
45 std::optional<std::string> QueryableStorage::getVersionOfOrigin(std::string_view origin) {
46  static auto v_version = std::make_shared<Variable>("Version");
47  std::optional<std::string> version;
48  match(TriplePattern(std::make_shared<Atom>(origin), versionProperty, v_version),
49  [&](const TriplePtr &triple) { version = triple->createStringValue(); });
50  return version;
51 }
52 
57 }
58 
59 namespace knowrob {
60  class TripleView_withBindings : public TripleView {
61  public:
62  explicit TripleView_withBindings(const BindingsPtr &bindings) : bindings_(bindings) {}
63 
64  private:
65  const BindingsPtr bindings_;
66  };
67 }
68 
69 void QueryableStorage::match(const TriplePattern &q, const TripleVisitor &visitor) {
70  auto graph_query = std::make_shared<GraphQuery>(
71  std::make_shared<GraphPattern>(std::make_shared<TriplePattern>(q)),
73  query(graph_query, [&](const BindingsPtr &bindings) {
74  TriplePtr triplePtr;
75  // create a triple view that holds a reference to the bindings.
76  // this is done to allow the visitor to take over the ownership of the triple.
77  triplePtr.ptr = new TripleView_withBindings(bindings);
78  triplePtr.owned = true;
79  q.instantiateInto(*triplePtr, bindings);
80  visitor(triplePtr);
81  });
82 }
83 
84 bool QueryableStorage::contains(const Triple &triple) {
85  bool hasTriple = false;
86  match(TriplePattern(triple), [&hasTriple](const TriplePtr &) {
87  hasTriple = true;
88  });
89  return hasTriple;
90 }
91 
92 void QueryableStorage::foreach(const TripleVisitor &visitor) const {
93  batch([&](const TripleContainerPtr &container) {
94  for (auto &triple: *container) {
95  visitor(triple);
96  }
97  });
98 }
99 
100 std::shared_ptr<AnswerYes> QueryableStorage::yes(const GraphPathQueryPtr &original,
101  const GraphQueryExpansionPtr &expanded,
102  const BindingsPtr &bindings) {
103  static const auto edbTerm = Atom::Tabled("EDB");
104 
105  auto positiveAnswer = std::make_shared<AnswerYes>(bindings);
106  // Indicate that EDB has computed the grounding.
107  positiveAnswer->setReasonerTerm(edbTerm);
108  // Apply query context to the answer for some parameters.
109  positiveAnswer->applyFrame(original->ctx()->selector);
110 
111  // Add predicate groundings to the answer
112  for (auto &rdfLiteral: original->path()) {
113  auto p = rdfLiteral->predicate();
114  auto p_instance = applyBindings(p, *positiveAnswer->substitution());
115  positiveAnswer->addGrounding(
116  std::static_pointer_cast<Predicate>(p_instance),
117  rdfLiteral->isNegated(),
118  positiveAnswer->frame());
119  }
120 
121  // The answer is uncertain if any of the groundings is uncertain.
122  positiveAnswer->setIsUncertain(
123  std::any_of(expanded->u_vars.begin(), expanded->u_vars.end(), [&](const VariablePtr &v) {
124  auto &u_v = bindings->get(v->name());
125  return (u_v && u_v->isNumeric() && std::static_pointer_cast<Numeric>(u_v)->asBoolean());
126  }), std::nullopt);
127 
128  // The answer is occasional if any of the groundings has occasional=true flag
129  positiveAnswer->setIsOccasionallyTrue(
130  std::any_of(expanded->o_vars.begin(), expanded->o_vars.end(), [&](const VariablePtr &v) {
131  auto &o_v = bindings->get(v->name());
132  return (o_v && o_v->isNumeric() && std::static_pointer_cast<Numeric>(o_v)->asBoolean());
133  }));
134 
135  return positiveAnswer;
136 }
137 
138 std::shared_ptr<AnswerNo> QueryableStorage::no(const GraphPathQueryPtr &q) {
139  static const auto edbTerm = Atom::Tabled("EDB");
140 
141  // send one negative answer if no positive answer was found
142  auto negativeAnswer = std::make_shared<AnswerNo>();
143  negativeAnswer->setReasonerTerm(edbTerm);
144  // Apply query context "origin" and "perspective" to the answer if any
145  negativeAnswer->applyFrame(q->ctx()->selector);
146  // the answer is uncertain as we only were not able to obtain a positive answer
147  // which does not mean that there is no positive answer.
148  negativeAnswer->setIsUncertain(true, std::nullopt);
149 
150  // Add ungrounded literals to negative answer.
151  // But at the moment the information is not provided by EDBs, would be difficult to implement e.g. in MongoDB.
152  // Well at least we know if the query is only a single triple pattern.
153  if (q->path().size() == 1) {
154  negativeAnswer->addUngrounded(q->path().front()->predicate(),
155  q->path().front()->isNegated());
156  }
157  return negativeAnswer;
158 }
159 
160 static std::shared_ptr<GraphTerm>
161 expand_pattern(const std::shared_ptr<GraphPattern> &q, GraphQueryExpansion &ctx) {
162  const auto &p = q->value();
163  ctx.counter += 1;
164 
165  // Find out if an additional variable must be added for the "isUncertain" flag.
166  // If a variable exists, rather use the existing one.
167  bool needsUncertainVar = false;
168  if (p->isUncertainTerm()) {
169  if (**p->isUncertainTerm() == *Numeric::trueAtom()) {
170  // For each possibly uncertain triple, add a variable to the query for the isUncertain flag.
171  needsUncertainVar = true;
172  } else if (p->isUncertainTerm()->isVariable()) {
173  // In case uncertain term is already a variable, remember it.
174  ctx.u_vars.emplace_back(std::static_pointer_cast<Variable>(*p->isUncertainTerm()));
175  }
176  }
177 
178  // Find out if an additional variable must be added for the "isOccasional" flag.
179  // If a variable exists, rather use the existing one.
180  bool needsOccasionalVar = false;
181  if (p->isOccasionalTerm()) {
182  if (**p->isOccasionalTerm() == *Numeric::trueAtom()) {
183  // For each possibly occasional triple, add a variable to the query for the isOccasional flag.
184  needsOccasionalVar = true;
185  } else if (p->isOccasionalTerm()->isVariable()) {
186  // In case occasional term is already a variable, remember it.
187  ctx.o_vars.emplace_back(std::static_pointer_cast<Variable>(*p->isOccasionalTerm()));
188  }
189  }
190 
191  // Find out if begin/end variables must be added for the computation of the time interval.
192  // This is always the case if the query uses SOMETIMES operator.
193  bool needsIntervalComputation = (ctx.query_ctx->selector.occasional);
194 
195  bool needsRewrite = needsUncertainVar || needsOccasionalVar || needsIntervalComputation;
196  if (!needsRewrite) return q;
197 
198  auto pat_expanded = std::make_shared<TriplePattern>(*p);
199 
200  if (needsUncertainVar) {
201  static const std::string varPrefix = "_uncertain";
202  // insert a fresh variable for the isUncertain flag
203  auto u_var = std::make_shared<Variable>(varPrefix + std::to_string(ctx.counter));
204  pat_expanded->setIsUncertainTerm(groundable<Numeric>(u_var));
205  // also remember the variable in the context
206  ctx.u_vars.emplace_back(u_var);
207  }
208 
209  if (needsOccasionalVar) {
210  static const std::string varPrefix = "_occasional";
211  // insert a fresh variable for the isOccasional flag
212  auto o_var = std::make_shared<Variable>(varPrefix + std::to_string(ctx.counter));
213  pat_expanded->setIsOccasionalTerm(groundable<Numeric>(o_var));
214  // also remember the variable in the context
215  ctx.o_vars.emplace_back(o_var);
216  }
217 
218  VariablePtr triple_begin, triple_end;
219  if (needsIntervalComputation) {
220  // Add begin/end variables possibly replacing fixed values for begin/end in the query.
221  // This is ok assuming each pattern has the same query frame.
222  // FILTER will be performed through a builtin instead, so deleting the values is ok,
223  // SPARQL would insert ad-hoc variables anyway.
224  auto g_begin = p->beginTerm();
225  auto g_end = p->endTerm();
226 
227  if (g_begin.has_variable()) {
228  triple_begin = g_begin.variable();
229  } else {
230  static const std::string varPrefix = "_begin";
231  triple_begin = std::make_shared<Variable>(varPrefix + std::to_string(ctx.counter));
232  pat_expanded->setBeginTerm(groundable<Double>(triple_begin));
233  }
234 
235  if (g_end.has_variable()) {
236  triple_end = g_end.variable();
237  } else {
238  static const std::string varPrefix = "_end";
239  triple_end = std::make_shared<Variable>(varPrefix + std::to_string(ctx.counter));
240  pat_expanded->setEndTerm(groundable<Double>(triple_end));
241  }
242  }
243 
244  auto q_expanded = std::make_shared<GraphPattern>(pat_expanded);
245  std::shared_ptr<GraphTerm> outer_term = q_expanded;
246 
247  // If the query uses SOMETIMES operator, then we need to insert builtins to the query for
248  // the computation of the time interval.
249  if (needsIntervalComputation) {
250  auto seq = std::make_shared<GraphSequence>();
251  seq->addMember(q_expanded);
252 
253  // FILTER all triples that do not intersect with begin/end of query frame
254  if (ctx.query_ctx->selector.begin) {
255  auto ctx_begin = std::make_shared<Double>(ctx.query_ctx->selector.begin.value());
256  seq->addMember(GraphBuiltin::lessOrEqual(ctx_begin, triple_end));
257  }
258  if (ctx.query_ctx->selector.end) {
259  auto ctx_end = std::make_shared<Double>(ctx.query_ctx->selector.end.value());
260  seq->addMember(GraphBuiltin::greaterOrEqual(ctx_end, triple_begin));
261  }
262 
263  // Set accumulated begin and end time.
264  // But not all backends support variable re-assignment.
265  // For the ones that don't support it like (SPARQL), we need to introduce a new variable for each intersection computed.
266  VariablePtr next_i_begin, next_i_end;
267  if (ctx.with_reassignment) {
268  next_i_begin = ctx.accumulated_begin;
269  next_i_end = ctx.accumulated_end;
270  } else {
271  static const std::string varPrefix_begin = "_i_begin";
272  static const std::string varPrefix_end = "_i_end";
273  next_i_begin = std::make_shared<Variable>(varPrefix_begin + std::to_string(ctx.counter));
274  next_i_end = std::make_shared<Variable>(varPrefix_end + std::to_string(ctx.counter));
275  }
276  seq->addMember(GraphBuiltin::max(next_i_begin, ctx.accumulated_begin, triple_begin));
277  seq->addMember(GraphBuiltin::min(next_i_end, ctx.accumulated_end, triple_end));
278  ctx.accumulated_begin = next_i_begin;
279  ctx.accumulated_end = next_i_end;
280 
281  // Ensure that begin < end
282  seq->addMember(GraphBuiltin::less(ctx.accumulated_begin, ctx.accumulated_end));
283 
284  // Update outer term
285  outer_term = seq;
286  }
287 
288  return outer_term;
289 }
290 
291 static std::shared_ptr<GraphTerm>
292 expand_term(const std::shared_ptr<GraphTerm> &q, GraphQueryExpansion &ctx) { // NOLINT
293  switch (q->termType()) {
295  return expand_pattern(std::static_pointer_cast<GraphPattern>(q), ctx);
298  auto connective = std::static_pointer_cast<GraphConnective>(q);
299  std::vector<std::shared_ptr<GraphTerm>> expandedTerms(connective->terms().size());
300 
301  bool hasExpansion = false;
302  for (size_t i = 0; i < connective->terms().size(); ++i) {
303  auto expandedTerm = expand_term(connective->terms()[i], ctx);
304  expandedTerms[i] = expandedTerm;
305  hasExpansion = hasExpansion || (expandedTerm != connective->terms()[i]);
306  }
307 
308  if (hasExpansion) {
309  if (q->termType() == GraphTermType::Union)
310  return std::make_shared<GraphUnion>(expandedTerms);
311  else
312  return std::make_shared<GraphSequence>(expandedTerms);
313  }
314  break;
315  }
317  break;
318  }
319  return q;
320 }
321 
322 static GraphQueryPtr expand_query(const GraphQueryPtr &q, GraphQueryExpansion &ctx) {
323  // Initialize begin/end variables for the computation of the time interval.
324  static const auto var_begin = std::make_shared<Variable>("_begin");
325  static const auto var_end = std::make_shared<Variable>("_end");
326  ctx.accumulated_begin = var_begin;
327  ctx.accumulated_end = var_end;
328 
329  // Expand the query
330  auto expandedTerm = expand_term(q->term(), ctx);
331 
332  // If the query uses SOMETIMES operator, prepend initialization of the accumulated_begin and accumulated_end variables
333  // used to compute the intersection of triple time intervals.
334  if (ctx.query_ctx->selector.occasional) {
335  double b_min = ctx.query_ctx->selector.begin.value_or(0.0);
336  double e_max = ctx.query_ctx->selector.end.value_or(std::numeric_limits<double>::max());
337  auto set_b = GraphBuiltin::bind(var_begin, std::make_shared<Double>(b_min));
338  auto set_e = GraphBuiltin::bind(var_end, std::make_shared<Double>(e_max));
339 
340  if (expandedTerm->termType() == GraphTermType::Sequence) {
341  // Prepend to existing sequence
342  auto seq_terms = std::static_pointer_cast<GraphSequence>(expandedTerm)->terms();
343  seq_terms.insert(seq_terms.begin(), set_e);
344  seq_terms.insert(seq_terms.begin(), set_b);
345  expandedTerm = std::make_shared<GraphSequence>(seq_terms);
346  } else {
347  // Create a new sequence
348  auto seq = std::make_shared<GraphSequence>();
349  seq->addMember(set_b);
350  seq->addMember(set_e);
351  seq->addMember(expandedTerm);
352  expandedTerm = seq;
353  }
354  }
355 
356  if (expandedTerm == q->term()) {
357  return q;
358  } else {
359  return std::make_shared<GraphQuery>(expandedTerm, q->ctx());
360  }
361 }
362 
364  // Expand the query. Currently, this is mainly used to compute the answer frame here.
365  // But also to insert some builtins for occasional triples.
366  auto exp_ctx = std::make_shared<GraphQueryExpansion>();
367  exp_ctx->query_ctx = q->ctx();
368  exp_ctx->with_reassignment = supports(StorageFeature::ReAssignment);
369  exp_ctx->expanded = expand_query(q, *exp_ctx);
370  return exp_ctx;
371 }
372 
374  const std::string &filename,
375  semweb::TripleFormat format) const {
376  // collects all triples per subject
377  semweb::ExportedTriples subjectTriples;
378  // iterate over all triples in the storage
379  batch([&](const TripleContainerPtr &container) {
380  for (auto &triple: *container) {
381  // collect triples per subject
382  auto tripleCopy = std::make_shared<TripleCopy>(*triple.ptr);
383  auto needle = subjectTriples.find(tripleCopy->subject());
384  if (needle == subjectTriples.end()) {
385  // if the subject is not yet in the map, insert it
386  needle = subjectTriples.insert(std::make_pair(
387  tripleCopy->subject(), std::vector<std::shared_ptr<Triple>>())).first;
388 
389  }
390  needle->second.push_back(tripleCopy);
391  }
392  });
393  // write all triples to the file
394  return semweb::TripleFormatter::exportTo(subjectTriples, filename, format);
395 }
396 
397 namespace knowrob::py {
398  struct QueryableStorageWrap : public QueryableStorage, boost::python::wrapper<QueryableStorage> {
399  explicit QueryableStorageWrap(PyObject *p, const StorageFeatures features)
400  : QueryableStorage(features), self(p) {}
401 
402  // virtual
403  void foreach(const TripleVisitor &visitor) const override {
404  call_method<void>(self, "foreach", visitor);
405  }
406 
407  void foreach_default(const TripleVisitor &visitor) const {
408  this->QueryableStorage::foreach(visitor);
409  }
410 
411  bool contains(const Triple &triple) override {
412  return call_method<bool, const Triple &>(self, "contains", triple);
413  }
414 
415  bool contains_default(const Triple &triple) {
416  return this->QueryableStorage::contains(triple);
417  }
418 
419  void match(const TriplePattern &query, const TripleVisitor &visitor) override {
420  call_method<void>(self, "match", query, visitor);
421  }
422 
423  void match_default(const TriplePattern &query, const TripleVisitor &visitor) {
424  this->QueryableStorage::match(query, visitor);
425  }
426 
427  // pure virtual
428  bool isPersistent() const override {
429  return call_method<bool>(self, "isPersistent");
430  }
431 
432  // pure virtual
433  void batch(const TripleHandler &callback) const override {
434  call_method<void>(self, "batch", callback);
435  }
436 
437  // pure virtual
438  void batchOrigin(std::string_view origin, const TripleHandler &callback) override {
439  call_method<void>(self, "batchOrigin", origin, callback);
440  }
441 
442  // pure virtual
443  void query(const GraphQueryPtr &query, const BindingsHandler &callback) override {
444  call_method<void>(self, "query", query, callback);
445  }
446 
447  // pure virtual
448  void count(const ResourceCounter &callback) const override {
449  call_method<void>(self, "count", callback);
450  }
451 
452  // pure virtual
453  bool initializeBackend(const PropertyTree &config) override {
454  return call_method<bool>(self, "initializeBackend", config);
455  }
456 
457  // pure virtual
458  bool insertOne(const Triple &triple) override {
459  return call_method<bool>(self, "insertOne", &triple);
460  }
461 
462  // pure virtual
463  bool insertAll(const TripleContainerPtr &triples) override {
464  return call_method<bool>(self, "insertAll", triples);
465  }
466 
467  // pure virtual
468  bool removeOne(const Triple &triple) override {
469  return call_method<bool>(self, "removeOne", &triple);
470  }
471 
472  // pure virtual
473  bool removeAll(const TripleContainerPtr &triples) override {
474  return call_method<bool>(self, "removeAll", triples);
475  }
476 
477  // pure virtual
478  bool removeAllWithOrigin(std::string_view origin) override {
479  return call_method<bool>(self, "removeAllWithOrigin", origin.data());
480  }
481 
482  private:
483  PyObject *self;
484  };
485 
486  template<>
488  using namespace boost::python;
489  class_<QueryableStorage, std::shared_ptr<QueryableStorageWrap>, bases<Storage>, boost::noncopyable>
490  ("QueryableStorage", init<StorageFeatures>())
491  .def("setVersionOfOrigin", &QueryableStorage::setVersionOfOrigin)
492  .def("getVersionOfOrigin", &QueryableStorage::getVersionOfOrigin)
493  .def("dropSessionOrigins", &QueryableStorage::dropSessionOrigins)
494  .def("yes", &QueryableStorage::yes).staticmethod("yes")
495  .def("no", &QueryableStorage::no).staticmethod("no")
496  // methods that must be implemented by backend plugins
497  .def("foreach", &QueryableStorageWrap::foreach, &QueryableStorageWrap::foreach_default)
498  .def("contains", &QueryableStorageWrap::contains, &QueryableStorageWrap::contains_default)
499  .def("match", &QueryableStorageWrap::match, &QueryableStorageWrap::match_default)
500  .def("isPersistent", pure_virtual(&QueryableStorageWrap::isPersistent))
501  .def("batch", pure_virtual(&QueryableStorageWrap::batch))
502  .def("batchOrigin", pure_virtual(&QueryableStorageWrap::batchOrigin))
503  .def("query", +[](QueryableStorage &x, const GraphQueryPtr &query, object &fn) { x.query(query, fn); })
504  .def("count", pure_virtual(&QueryableStorageWrap::count));
505  register_ptr_to_python< std::shared_ptr< QueryableStorage > >();
506  }
507 }
static std::shared_ptr< knowrob::Atom > Tabled(std::string_view stringForm)
Definition: Atom.cpp:40
static BuiltinPtr greaterOrEqual(const TermPtr &a, const TermPtr &b)
Definition: GraphBuiltin.h:210
static BuiltinPtr max(const VariablePtr &var, const TermPtr &a, const TermPtr &b)
Definition: GraphBuiltin.h:157
static BuiltinPtr lessOrEqual(const TermPtr &a, const TermPtr &b)
Definition: GraphBuiltin.h:184
static BuiltinPtr less(const TermPtr &a, const TermPtr &b)
Definition: GraphBuiltin.h:171
static BuiltinPtr bind(const VariablePtr &var, const TermPtr &val)
Definition: GraphBuiltin.h:127
static BuiltinPtr min(const VariablePtr &var, const TermPtr &a, const TermPtr &b)
Definition: GraphBuiltin.h:142
static std::shared_ptr< IRIAtom > Tabled(std::string_view stringForm)
Definition: IRIAtom.cpp:25
static constexpr std::string_view ORIGIN_SESSION
static constexpr std::string_view ORIGIN_USER
static constexpr std::string_view ORIGIN_REASONER
static std::shared_ptr< Numeric > trueAtom()
Definition: Numeric.cpp:15
std::optional< std::string > getVersionOfOrigin(std::string_view origin)
static std::shared_ptr< AnswerNo > no(const GraphPathQueryPtr &q)
virtual void match(const TriplePattern &query, const TripleVisitor &visitor)
QueryableStorage(StorageFeatures features=StorageFeature::NothingSpecial)
static std::shared_ptr< AnswerYes > yes(const GraphPathQueryPtr &original, const GraphQueryExpansionPtr &expansion, const BindingsPtr &bindings)
virtual void foreach(const TripleVisitor &visitor) const
GraphQueryExpansionPtr expand(const GraphQueryPtr &q)
virtual void batch(const TripleHandler &callback) const =0
void setVersionOfOrigin(std::string_view origin, std::string_view version)
virtual bool contains(const Triple &triple)
static AtomPtr versionProperty
std::vector< VersionedOriginPtr > getOrigins()
bool exportTo(const std::string &filename, semweb::TripleFormat format=semweb::RDF_XML) const
virtual void query(const GraphQueryPtr &query, const BindingsHandler &callback)=0
bool supports(StorageFeature feature) const
Definition: Storage.h:84
virtual bool removeAllWithOrigin(std::string_view origin)=0
virtual bool insertOne(const Triple &triple)=0
virtual std::string_view valueAsString() const =0
virtual std::string_view subject() const =0
std::string createStringValue() const
Definition: Triple.cpp:71
bool instantiateInto(Triple &triple, const std::shared_ptr< const Bindings > &bindings=Bindings::emptyBindings()) const
void setStringValue(std::string_view v) override
Definition: Triple.h:464
void setPredicate(std::string_view predicate) override
Definition: Triple.h:449
void setGraph(std::string_view graph) override
Definition: Triple.h:497
void setSubject(std::string_view subject) override
Definition: Triple.h:446
static bool exportTo(const ExportedTriples &triples, const std::string &filename, TripleFormat format=TripleFormat::RDF_XML)
TermRule & string()
Definition: terms.cpp:63
void createType< QueryableStorage >()
std::map< std::string_view, std::vector< std::shared_ptr< Triple > >> ExportedTriples
std::function< void(const TriplePtr &)> TripleVisitor
StorageFeature
Definition: Storage.h:24
std::shared_ptr< TripleContainer > TripleContainerPtr
std::shared_ptr< GraphQueryExpansion > GraphQueryExpansionPtr
std::shared_ptr< const Bindings > BindingsPtr
Definition: Bindings.h:151
std::function< void(std::string_view, uint64_t)> ResourceCounter
QueryContextPtr DefaultQueryContext()
Definition: Query.cpp:11
std::function< void(const BindingsPtr &)> BindingsHandler
Definition: Bindings.h:152
std::shared_ptr< Atom > AtomPtr
Definition: Atom.h:69
std::function< void(const TripleContainerPtr &)> TripleHandler
std::shared_ptr< GraphQuery > GraphQueryPtr
Definition: GraphQuery.h:65
std::shared_ptr< GraphPathQuery > GraphPathQueryPtr
std::shared_ptr< Variable > VariablePtr
Definition: Variable.h:60
FirstOrderLiteralPtr applyBindings(const FirstOrderLiteralPtr &lit, const Bindings &bindings)
std::vector< VariablePtr > o_vars
std::vector< VariablePtr > u_vars
Triple * ptr
Definition: Triple.h:590