knowrob  2.1.0
A Knowledge Base System for Cognition-enabled Robots
SPARQLBackend.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/SPARQLBackend.h"
7 
8 using namespace knowrob;
9 
10 bool SPARQLBackend::query(const SPARQLQuery &q, const BindingsHandler &callback) const {
11  return sparql(q(), callback);
12 }
13 
14 void SPARQLBackend::query(const GraphQueryPtr &q, const BindingsHandler &callback) { // NOLINT
15  std::shared_ptr<GraphPattern> negatedPattern;
16  if (q->term()->termType() == GraphTermType::Pattern) {
17  // Currently we cannot support negations where the object is grounded.
18  // This is because the SPARQL query would need to use NOT-EXISTS or MINUS, which is not supported by rasqal.
19  // Instead, we use OPTIONAL and !BOUND to simulate negation which requires that the object is not grounded
20  // when entering the negated pattern.
21  // But, on the other hand negations are handled separately by the KnowledgeBase anyway.
22  // So KnowRob will at the moment only call this interface with single negated patterns
23  // while evaluating sequences of negations in parallel and after any positive pattern that
24  // appears in a query.
25  auto pat = std::static_pointer_cast<GraphPattern>(q->term());
26  if (pat->value()->isNegated()) {
27  negatedPattern = pat;
28  }
29  }
30 
31  if (negatedPattern) {
32  // negation-as-failure: Try positive query, if it has no solution, then the negated pattern is true.
33  auto positivePat = std::make_shared<TriplePattern>(*negatedPattern->value());
34  positivePat->setIsNegated(false);
35  auto positiveQuery = std::make_shared<GraphQuery>(
36  std::make_shared<GraphPattern>(positivePat),
38  bool hasSolution = false;
39  query(positiveQuery, [&](const BindingsPtr& /*bindings*/) {
40  hasSolution = true;
41  });
42  if (!hasSolution) {
43  callback(Bindings::emptyBindings());
44  }
45  } else {
46  sparql(SPARQLQuery(q, sparqlFlags_)(), callback);
47  }
48 }
49 
50 void SPARQLBackend::count(const ResourceCounter &callback) const {
51  static const char *sparqlString = "SELECT ?resource (COUNT(?s) AS ?count) WHERE "\
52  "{ ?s rdf:type ?resource . } UNION { ?s ?resource ?o . } } "\
53  "GROUP BY ?resource";
54  sparql(sparqlString, [&](const BindingsPtr &bindings) {
55  auto resource = bindings->getAtomic("resource");
56  auto count = bindings->getAtomic("count");
57  if (!resource || !count || !count->isNumeric()) {
58  KB_WARN("Failed to count triples!");
59  return;
60  }
61  callback(resource->stringForm(), std::static_pointer_cast<Numeric>(count)->asLong());
62  });
63 }
static std::shared_ptr< const Bindings > emptyBindings()
Definition: Bindings.cpp:99
void count(const ResourceCounter &callback) const override
virtual bool sparql(std::string_view queryString, const BindingsHandler &callback) const =0
bool query(const SPARQLQuery &query, const BindingsHandler &callback) const
SPARQLFlags sparqlFlags_
Definition: SPARQLBackend.h:43
std::shared_ptr< const Bindings > BindingsPtr
Definition: Bindings.h:151
std::function< void(std::string_view, uint64_t)> ResourceCounter
QueryContextPtr OneSolutionContext()
Definition: Query.cpp:15
std::function< void(const BindingsPtr &)> BindingsHandler
Definition: Bindings.h:152
std::shared_ptr< GraphQuery > GraphQueryPtr
Definition: GraphQuery.h:65