6 #include "knowrob/storage/QueryableStorage.h"
7 #include "knowrob/ThreadPool.h"
8 #include "knowrob/queries/AnswerNo.h"
9 #include "knowrob/queries/AnswerYes.h"
10 #include "knowrob/semweb/GraphBuiltin.h"
11 #include "knowrob/semweb/ImportHierarchy.h"
12 #include "knowrob/semweb/GraphSequence.h"
13 #include "knowrob/semweb/GraphUnion.h"
14 #include "knowrob/integration/python/utils.h"
25 static auto v_origin = std::make_shared<Variable>(
"Origin");
26 static auto v_version = std::make_shared<Variable>(
"Version");
27 std::vector<VersionedOriginPtr> origins;
30 origins.push_back(std::make_shared<VersionedOrigin>(triple->
subject(), triple->
valueAsString()));
45 static auto v_version = std::make_shared<Variable>(
"Version");
46 std::optional<std::string> version;
59 class TripleView_withBindings :
public TripleView {
61 explicit TripleView_withBindings(
const BindingsPtr &bindings) : bindings_(bindings) {}
69 auto graph_query = std::make_shared<GraphQuery>(
70 std::make_shared<GraphPattern>(std::make_shared<TriplePattern>(q)),
76 triplePtr.
ptr =
new TripleView_withBindings(bindings);
77 triplePtr.
owned =
true;
84 bool hasTriple =
false;
93 for (
auto &triple: *container) {
104 auto positiveAnswer = std::make_shared<AnswerYes>(bindings);
106 positiveAnswer->setReasonerTerm(edbTerm);
108 positiveAnswer->applyFrame(original->ctx()->selector);
111 for (
auto &rdfLiteral: original->path()) {
112 auto p = rdfLiteral->predicate();
113 auto p_instance =
applyBindings(p, *positiveAnswer->substitution());
114 positiveAnswer->addGrounding(
115 std::static_pointer_cast<Predicate>(p_instance),
116 rdfLiteral->isNegated(),
117 positiveAnswer->frame());
121 positiveAnswer->setIsUncertain(
122 std::any_of(expanded->u_vars.begin(), expanded->u_vars.end(), [&](
const VariablePtr &v) {
123 auto &u_v = bindings->get(v->name());
124 return (u_v && u_v->isNumeric() && std::static_pointer_cast<Numeric>(u_v)->asBoolean());
128 positiveAnswer->setIsOccasionallyTrue(
129 std::any_of(expanded->o_vars.begin(), expanded->o_vars.end(), [&](
const VariablePtr &v) {
130 auto &o_v = bindings->get(v->name());
131 return (o_v && o_v->isNumeric() && std::static_pointer_cast<Numeric>(o_v)->asBoolean());
134 return positiveAnswer;
141 auto negativeAnswer = std::make_shared<AnswerNo>();
142 negativeAnswer->setReasonerTerm(edbTerm);
144 negativeAnswer->applyFrame(q->ctx()->selector);
147 negativeAnswer->setIsUncertain(
true, std::nullopt);
152 if (q->path().size() == 1) {
153 negativeAnswer->addUngrounded(q->path().front()->predicate(),
154 q->path().front()->isNegated());
156 return negativeAnswer;
159 static std::shared_ptr<GraphTerm>
161 const auto &p = q->value();
166 bool needsUncertainVar =
false;
167 if (p->isUncertainTerm()) {
170 needsUncertainVar =
true;
171 }
else if (p->isUncertainTerm()->isVariable()) {
173 ctx.
u_vars.emplace_back(std::static_pointer_cast<Variable>(*p->isUncertainTerm()));
179 bool needsOccasionalVar =
false;
180 if (p->isOccasionalTerm()) {
183 needsOccasionalVar =
true;
184 }
else if (p->isOccasionalTerm()->isVariable()) {
186 ctx.
o_vars.emplace_back(std::static_pointer_cast<Variable>(*p->isOccasionalTerm()));
192 bool needsIntervalComputation = (ctx.
query_ctx->selector.occasional);
194 bool needsRewrite = needsUncertainVar || needsOccasionalVar || needsIntervalComputation;
195 if (!needsRewrite)
return q;
197 auto pat_expanded = std::make_shared<TriplePattern>(*p);
199 if (needsUncertainVar) {
202 auto u_var = std::make_shared<Variable>(varPrefix + std::to_string(ctx.
counter));
205 ctx.
u_vars.emplace_back(u_var);
208 if (needsOccasionalVar) {
209 static const std::string varPrefix =
"_occasional";
211 auto o_var = std::make_shared<Variable>(varPrefix + std::to_string(ctx.
counter));
214 ctx.
o_vars.emplace_back(o_var);
218 if (needsIntervalComputation) {
223 auto g_begin = p->beginTerm();
224 auto g_end = p->endTerm();
226 if (g_begin.has_variable()) {
227 triple_begin = g_begin.variable();
230 triple_begin = std::make_shared<Variable>(varPrefix + std::to_string(ctx.
counter));
234 if (g_end.has_variable()) {
235 triple_end = g_end.variable();
238 triple_end = std::make_shared<Variable>(varPrefix + std::to_string(ctx.
counter));
243 auto q_expanded = std::make_shared<GraphPattern>(pat_expanded);
244 std::shared_ptr<GraphTerm> outer_term = q_expanded;
248 if (needsIntervalComputation) {
249 auto seq = std::make_shared<GraphSequence>();
250 seq->addMember(q_expanded);
254 auto ctx_begin = std::make_shared<Double>(ctx.
query_ctx->selector.begin.value());
258 auto ctx_end = std::make_shared<Double>(ctx.
query_ctx->selector.end.value());
270 static const std::string varPrefix_begin =
"_i_begin";
272 next_i_begin = std::make_shared<Variable>(varPrefix_begin + std::to_string(ctx.
counter));
273 next_i_end = std::make_shared<Variable>(varPrefix_end + std::to_string(ctx.
counter));
290 static std::shared_ptr<GraphTerm>
292 switch (q->termType()) {
294 return expand_pattern(std::static_pointer_cast<GraphPattern>(q), ctx);
297 auto connective = std::static_pointer_cast<GraphConnective>(q);
298 std::vector<std::shared_ptr<GraphTerm>> expandedTerms(connective->terms().size());
300 bool hasExpansion =
false;
301 for (
size_t i = 0; i < connective->terms().size(); ++i) {
302 auto expandedTerm = expand_term(connective->terms()[i], ctx);
303 expandedTerms[i] = expandedTerm;
304 hasExpansion = hasExpansion || (expandedTerm != connective->terms()[i]);
309 return std::make_shared<GraphUnion>(expandedTerms);
311 return std::make_shared<GraphSequence>(expandedTerms);
323 static const auto var_begin = std::make_shared<Variable>(
"_begin");
324 static const auto var_end = std::make_shared<Variable>(
"_end");
329 auto expandedTerm = expand_term(q->term(), ctx);
333 if (ctx.
query_ctx->selector.occasional) {
334 double b_min = ctx.
query_ctx->selector.begin.value_or(0.0);
335 double e_max = ctx.
query_ctx->selector.end.value_or(std::numeric_limits<double>::max());
341 auto seq_terms = std::static_pointer_cast<GraphSequence>(expandedTerm)->terms();
342 seq_terms.insert(seq_terms.begin(), set_e);
343 seq_terms.insert(seq_terms.begin(), set_b);
344 expandedTerm = std::make_shared<GraphSequence>(seq_terms);
347 auto seq = std::make_shared<GraphSequence>();
348 seq->addMember(set_b);
349 seq->addMember(set_e);
350 seq->addMember(expandedTerm);
355 if (expandedTerm == q->term()) {
358 return std::make_shared<GraphQuery>(expandedTerm, q->ctx());
365 auto exp_ctx = std::make_shared<GraphQueryExpansion>();
366 exp_ctx->query_ctx = q->ctx();
368 exp_ctx->expanded = expand_query(q, *exp_ctx);
373 struct QueryableStorageWrap :
public QueryableStorage, boost::python::wrapper<QueryableStorage> {
374 explicit QueryableStorageWrap(PyObject *p,
const StorageFeatures features)
379 call_method<void>(
self,
"foreach", visitor);
386 bool contains(
const Triple &triple)
override {
387 return call_method<bool, const Triple &>(
self,
"contains", triple);
390 bool contains_default(
const Triple &triple) {
395 call_method<void>(
self,
"match", query, visitor);
403 bool isPersistent()
const override {
404 return call_method<bool>(
self,
"isPersistent");
409 call_method<void>(
self,
"batch", callback);
413 void batchOrigin(std::string_view origin,
const TripleHandler &callback)
override {
414 call_method<void>(
self,
"batchOrigin", origin, callback);
419 call_method<void>(
self,
"query", query, callback);
424 call_method<void>(
self,
"count", callback);
428 bool initializeBackend(
const PropertyTree &config)
override {
429 return call_method<bool>(
self,
"initializeBackend", config);
433 bool insertOne(
const Triple &triple)
override {
434 return call_method<bool>(
self,
"insertOne", &triple);
439 return call_method<bool>(
self,
"insertAll", triples);
443 bool removeOne(
const Triple &triple)
override {
444 return call_method<bool>(
self,
"removeOne", &triple);
449 return call_method<bool>(
self,
"removeAll", triples);
453 bool removeAllWithOrigin(std::string_view origin)
override {
454 return call_method<bool>(
self,
"removeAllWithOrigin", origin.data());
464 class_<QueryableStorage, std::shared_ptr<QueryableStorageWrap>, bases<Storage>, boost::noncopyable>
465 (
"QueryableStorage", init<StorageFeatures>())
472 .def(
"foreach", &QueryableStorageWrap::foreach, &QueryableStorageWrap::foreach_default)
473 .def(
"contains", &QueryableStorageWrap::contains, &QueryableStorageWrap::contains_default)
474 .def(
"match", &QueryableStorageWrap::match, &QueryableStorageWrap::match_default)
475 .def(
"isPersistent", pure_virtual(&QueryableStorageWrap::isPersistent))
476 .def(
"batch", pure_virtual(&QueryableStorageWrap::batch))
477 .def(
"batchOrigin", pure_virtual(&QueryableStorageWrap::batchOrigin))
479 .def(
"count", pure_virtual(&QueryableStorageWrap::count));
480 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()
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::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