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"
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;
31 origins.push_back(std::make_shared<VersionedOrigin>(triple->
subject(), triple->
valueAsString()));
46 static auto v_version = std::make_shared<Variable>(
"Version");
47 std::optional<std::string> version;
60 class TripleView_withBindings :
public TripleView {
62 explicit TripleView_withBindings(
const BindingsPtr &bindings) : bindings_(bindings) {}
70 auto graph_query = std::make_shared<GraphQuery>(
71 std::make_shared<GraphPattern>(std::make_shared<TriplePattern>(q)),
77 triplePtr.
ptr =
new TripleView_withBindings(bindings);
78 triplePtr.
owned =
true;
85 bool hasTriple =
false;
94 for (
auto &triple: *container) {
105 auto positiveAnswer = std::make_shared<AnswerYes>(bindings);
107 positiveAnswer->setReasonerTerm(edbTerm);
109 positiveAnswer->applyFrame(original->ctx()->selector);
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());
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());
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());
135 return positiveAnswer;
142 auto negativeAnswer = std::make_shared<AnswerNo>();
143 negativeAnswer->setReasonerTerm(edbTerm);
145 negativeAnswer->applyFrame(q->ctx()->selector);
148 negativeAnswer->setIsUncertain(
true, std::nullopt);
153 if (q->path().size() == 1) {
154 negativeAnswer->addUngrounded(q->path().front()->predicate(),
155 q->path().front()->isNegated());
157 return negativeAnswer;
160 static std::shared_ptr<GraphTerm>
162 const auto &p = q->value();
167 bool needsUncertainVar =
false;
168 if (p->isUncertainTerm()) {
171 needsUncertainVar =
true;
172 }
else if (p->isUncertainTerm()->isVariable()) {
174 ctx.
u_vars.emplace_back(std::static_pointer_cast<Variable>(*p->isUncertainTerm()));
180 bool needsOccasionalVar =
false;
181 if (p->isOccasionalTerm()) {
184 needsOccasionalVar =
true;
185 }
else if (p->isOccasionalTerm()->isVariable()) {
187 ctx.
o_vars.emplace_back(std::static_pointer_cast<Variable>(*p->isOccasionalTerm()));
193 bool needsIntervalComputation = (ctx.
query_ctx->selector.occasional);
195 bool needsRewrite = needsUncertainVar || needsOccasionalVar || needsIntervalComputation;
196 if (!needsRewrite)
return q;
198 auto pat_expanded = std::make_shared<TriplePattern>(*p);
200 if (needsUncertainVar) {
203 auto u_var = std::make_shared<Variable>(varPrefix + std::to_string(ctx.
counter));
206 ctx.
u_vars.emplace_back(u_var);
209 if (needsOccasionalVar) {
210 static const std::string varPrefix =
"_occasional";
212 auto o_var = std::make_shared<Variable>(varPrefix + std::to_string(ctx.
counter));
215 ctx.
o_vars.emplace_back(o_var);
219 if (needsIntervalComputation) {
224 auto g_begin = p->beginTerm();
225 auto g_end = p->endTerm();
227 if (g_begin.has_variable()) {
228 triple_begin = g_begin.variable();
231 triple_begin = std::make_shared<Variable>(varPrefix + std::to_string(ctx.
counter));
235 if (g_end.has_variable()) {
236 triple_end = g_end.variable();
239 triple_end = std::make_shared<Variable>(varPrefix + std::to_string(ctx.
counter));
244 auto q_expanded = std::make_shared<GraphPattern>(pat_expanded);
245 std::shared_ptr<GraphTerm> outer_term = q_expanded;
249 if (needsIntervalComputation) {
250 auto seq = std::make_shared<GraphSequence>();
251 seq->addMember(q_expanded);
255 auto ctx_begin = std::make_shared<Double>(ctx.
query_ctx->selector.begin.value());
259 auto ctx_end = std::make_shared<Double>(ctx.
query_ctx->selector.end.value());
271 static const std::string varPrefix_begin =
"_i_begin";
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));
291 static std::shared_ptr<GraphTerm>
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());
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]);
310 return std::make_shared<GraphUnion>(expandedTerms);
312 return std::make_shared<GraphSequence>(expandedTerms);
324 static const auto var_begin = std::make_shared<Variable>(
"_begin");
325 static const auto var_end = std::make_shared<Variable>(
"_end");
330 auto expandedTerm = expand_term(q->term(), ctx);
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());
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);
348 auto seq = std::make_shared<GraphSequence>();
349 seq->addMember(set_b);
350 seq->addMember(set_e);
351 seq->addMember(expandedTerm);
356 if (expandedTerm == q->term()) {
359 return std::make_shared<GraphQuery>(expandedTerm, q->ctx());
366 auto exp_ctx = std::make_shared<GraphQueryExpansion>();
367 exp_ctx->query_ctx = q->ctx();
369 exp_ctx->expanded = expand_query(q, *exp_ctx);
380 for (
auto &triple: *container) {
382 auto tripleCopy = std::make_shared<TripleCopy>(*triple.ptr);
383 auto needle = subjectTriples.find(tripleCopy->subject());
384 if (needle == subjectTriples.end()) {
386 needle = subjectTriples.insert(std::make_pair(
387 tripleCopy->subject(), std::vector<std::shared_ptr<Triple>>())).first;
390 needle->second.push_back(tripleCopy);
398 struct QueryableStorageWrap :
public QueryableStorage, boost::python::wrapper<QueryableStorage> {
399 explicit QueryableStorageWrap(PyObject *p,
const StorageFeatures features)
404 call_method<void>(
self,
"foreach", visitor);
411 bool contains(
const Triple &triple)
override {
412 return call_method<bool, const Triple &>(
self,
"contains", triple);
415 bool contains_default(
const Triple &triple) {
420 call_method<void>(
self,
"match", query, visitor);
428 bool isPersistent()
const override {
429 return call_method<bool>(
self,
"isPersistent");
434 call_method<void>(
self,
"batch", callback);
438 void batchOrigin(std::string_view origin,
const TripleHandler &callback)
override {
439 call_method<void>(
self,
"batchOrigin", origin, callback);
444 call_method<void>(
self,
"query", query, callback);
449 call_method<void>(
self,
"count", callback);
453 bool initializeBackend(
const PropertyTree &config)
override {
454 return call_method<bool>(
self,
"initializeBackend", config);
458 bool insertOne(
const Triple &triple)
override {
459 return call_method<bool>(
self,
"insertOne", &triple);
464 return call_method<bool>(
self,
"insertAll", triples);
468 bool removeOne(
const Triple &triple)
override {
469 return call_method<bool>(
self,
"removeOne", &triple);
474 return call_method<bool>(
self,
"removeAll", triples);
478 bool removeAllWithOrigin(std::string_view origin)
override {
479 return call_method<bool>(
self,
"removeAllWithOrigin", origin.data());
489 class_<QueryableStorage, std::shared_ptr<QueryableStorageWrap>, bases<Storage>, boost::noncopyable>
490 (
"QueryableStorage", init<StorageFeatures>())
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))
504 .def(
"count", pure_virtual(&QueryableStorageWrap::count));
505 register_ptr_to_python< std::shared_ptr< QueryableStorage > >();
static std::shared_ptr< knowrob::Atom > Tabled(std::string_view stringForm)
static BuiltinPtr greaterOrEqual(const TermPtr &a, const TermPtr &b)
static BuiltinPtr max(const VariablePtr &var, const TermPtr &a, const TermPtr &b)
static BuiltinPtr lessOrEqual(const TermPtr &a, const TermPtr &b)
static BuiltinPtr less(const TermPtr &a, const TermPtr &b)
static BuiltinPtr bind(const VariablePtr &var, const TermPtr &val)
static BuiltinPtr min(const VariablePtr &var, const TermPtr &a, const TermPtr &b)
static std::shared_ptr< IRIAtom > Tabled(std::string_view stringForm)
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()
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)
void dropSessionOrigins()
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
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
bool instantiateInto(Triple &triple, const std::shared_ptr< const Bindings > &bindings=Bindings::emptyBindings()) const
void setStringValue(std::string_view v) override
void setPredicate(std::string_view predicate) override
void setGraph(std::string_view graph) override
void setSubject(std::string_view subject) override
void createType< QueryableStorage >()
std::map< std::string_view, std::vector< std::shared_ptr< Triple > >> ExportedTriples
std::function< void(const TriplePtr &)> TripleVisitor
std::shared_ptr< TripleContainer > TripleContainerPtr
std::shared_ptr< GraphQueryExpansion > GraphQueryExpansionPtr
std::shared_ptr< const Bindings > BindingsPtr
std::function< void(std::string_view, uint64_t)> ResourceCounter
QueryContextPtr DefaultQueryContext()
std::function< void(const BindingsPtr &)> BindingsHandler
std::shared_ptr< Atom > AtomPtr
std::function< void(const TripleContainerPtr &)> TripleHandler
std::shared_ptr< GraphQuery > GraphQueryPtr
std::shared_ptr< GraphPathQuery > GraphPathQueryPtr
std::shared_ptr< Variable > VariablePtr
FirstOrderLiteralPtr applyBindings(const FirstOrderLiteralPtr &lit, const Bindings &bindings)
VariablePtr accumulated_begin
QueryContextPtr query_ctx
std::vector< VariablePtr > o_vars
VariablePtr accumulated_end
std::vector< VariablePtr > u_vars