knowrob  2.1.0
A Knowledge Base System for Cognition-enabled Robots
PrologBackend.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/StorageManager.h"
7 #include "knowrob/integration/prolog/PrologBackend.h"
8 #include "knowrob/integration/prolog/PrologEngine.h"
9 #include "knowrob/integration/prolog/PrologTerm.h"
10 #include "knowrob/knowrob.h"
11 
12 using namespace knowrob;
13 
17 KNOWROB_BUILTIN_STORAGE("Prolog:rdf_db", PrologBackend)
18 
19 namespace knowrob {
20  static const auto rdf_quad = "rdf";
21  static const auto rdf_assert = "rdf_assert";
22  static const auto rdf_retractall = "rdf_retractall";
23  static const auto rdf_transaction = "rdf_transaction";
24 }
25 
28 }
29 
32  auto success = PROLOG_ENGINE_EVAL(
33  PrologTerm("use_module",
34  PrologTerm("library", "semweb/rdf_db"),
35  PrologList({
36  PrologTerm("/", "rdf", std::make_shared<Integer>(4)),
37  PrologTerm("/", "rdf_assert", std::make_shared<Integer>(4)),
38  PrologTerm("/", "rdf_retractall", std::make_shared<Integer>(4)),
39  PrologTerm("/", "rdf_transaction", std::make_shared<Integer>(1)),
40  PrologTerm("/", "rdf_has", std::make_shared<Integer>(3))
41  })));
42  success = success && PROLOG_ENGINE_EVAL(
43  PrologTerm("use_module",
44  PrologTerm("library", "semweb"),
45  PrologList({
46  PrologTerm("/", "sw_literal_compare", std::make_shared<Integer>(3)),
47  PrologTerm("/", "sw_literal_max", std::make_shared<Integer>(3)),
48  PrologTerm("/", "sw_literal_min", std::make_shared<Integer>(3)),
49  PrologTerm("/", "sw_resource_frequency", std::make_shared<Integer>(2)),
50  PrologTerm("/", "sw_class_frequency", std::make_shared<Integer>(2)),
51  PrologTerm("/", "sw_property_frequency", std::make_shared<Integer>(2))
52  })));
53  return success;
54 }
55 
57  return initializeBackend();
58 }
59 
60 bool PrologBackend::insertOne(const Triple &triple) {
61  // :- rdf_assert($triple.subject, $triple.predicate, $triple.object, $triple.origin).
62  return PROLOG_ENGINE_EVAL(PrologTerm(triple, rdf_assert));
63 }
64 
65 bool PrologBackend::removeOne(const Triple &triple) {
66  // :- rdf_retractall($triple.subject, $triple.predicate, $triple.object, $triple.origin).
67  return PROLOG_ENGINE_EVAL(PrologTerm(triple, rdf_retractall));
68 }
69 
70 bool PrologBackend::removeAllWithOrigin(std::string_view origin) {
71  // :- rdf_retractall(_, _, _, $origin).
72  return PROLOG_ENGINE_EVAL(PrologTerm(rdf_retractall, PrologTerm(), PrologTerm(), PrologTerm(), origin));
73 }
74 
76  // :- rdf_retractall(_, _, _, $origin).
77  return PROLOG_ENGINE_EVAL(PrologTerm(rdf_retractall, PrologTerm(), PrologTerm(), PrologTerm(), PrologTerm()));
78 }
79 
81  // :- rdf_transaction(...).
82  return PROLOG_ENGINE_EVAL(transaction(rdf_assert, triples));
83 }
84 
86  // :- rdf_transaction(...).
87  return PROLOG_ENGINE_EVAL(transaction(rdf_retractall, triples));
88 }
89 
90 PrologTerm PrologBackend::transaction(std::string_view rdf_functor, const TripleContainerPtr &triples) {
91  // transactionTerm = rdf_transaction((rdf_functor(s, p, o, g), ...)).
92  PrologTerm transactionGoal;
93  for (const auto &triple: *triples) {
94  transactionGoal = (transactionGoal & PrologTerm(*triple, rdf_functor));
95  }
96  return PrologTerm(rdf_transaction, transactionGoal);
97 }
98 
100  return false;
101 }
102 
103 static void batch_(const TripleHandler &callback, const groundable<Atom> &origin) {
104  // :- rdf(?subject, ?property, ?object, ?origin).
105  // Note: Prolog querying works via backtracking over term_t, and this
106  // changes the value of the term_t in the Prolog engine such that imo we cannot
107  // avoid copying the results into a container -- as opposed to mapping the memory
108  // which was allocated by the Prolog engine during querying.
109  // A copy of the term_t could be created though, but this seems pointless, so here
110  // we just create new KnowRob terms with their own memory allocation.
111  static auto var_s = std::make_shared<Variable>("s");
112  static auto var_p = std::make_shared<Variable>("p");
113  static auto var_o = std::make_shared<Variable>("o");
114  auto triples = std::make_shared<TripleViewBatch>(GlobalSettings::batchSize());
115 
117  PrologTerm(rdf_quad,
118  PrologTerm(var_s),
119  PrologTerm(var_p),
120  PrologTerm(var_o),
121  PrologTerm(*origin)),
122  [&](const BindingsPtr &bindings) {
123  auto val_s = bindings->getAtomic(var_s->name());
124  auto val_p = bindings->getAtomic(var_p->name());
125  auto val_o = bindings->getAtomic(var_o->name());
126  if(!val_s || !val_p || !val_o) {
127  KB_WARN("Failed to retrieve triple from Prolog: missing grounding.");
128  return;
129  }
130 
131  TriplePtr triple_ptr;
132  triple_ptr.ptr = new TripleCopy(val_s->stringForm(), val_p->stringForm());
133  if (val_o->isNumeric() || val_o->isString()) {
134  auto xsd_o = std::static_pointer_cast<XSDAtomic>(val_o);
135  triple_ptr.ptr->setXSDValue(xsd_o->stringForm(), xsd_o->xsdType());
136  } else if (val_o->isIRI()) {
137  triple_ptr.ptr->setObjectIRI(val_o->stringForm());
138  } else if (val_o->isBlank()) {
139  triple_ptr.ptr->setObjectBlank(val_o->stringForm());
140  }
141  if (origin.has_grounding()) {
142  triple_ptr.ptr->setGraph(origin.grounded()->stringForm());
143  } else {
144  auto val_g = bindings->getAtomic(origin.variable()->name());
145  if (val_g) {
146  triple_ptr.ptr->setGraph(val_g->stringForm());
147  }
148  }
149  triple_ptr.owned = true;
150 
151  triples->add(triple_ptr);
152  if (triples->size() >= GlobalSettings::batchSize()) {
153  callback(triples);
154  triples->reset();
155  }
156  });
157 
158  // Clean up
159  if (triples->size() > 0) {
160  callback(triples);
161  }
162 }
163 
164 void PrologBackend::batch(const TripleHandler &callback) const {
165  static groundable<Atom> origin_g(std::make_shared<Variable>("g"));
166  batch_(callback, origin_g);
167 }
168 
169 void PrologBackend::batchOrigin(std::string_view origin, const TripleHandler &callback) {
170  groundable<Atom> origin_g(Atom::Tabled(origin));
171  batch_(callback, groundable<Atom>(origin_g));
172 }
173 
174 void PrologBackend::query(const GraphQueryPtr &query, const BindingsHandler &callback) {
176 }
177 
178 void PrologBackend::count(const ResourceCounter &callback) const {
179  // :- sw_resource_frequency(-Resource, -Frequency)
180  static const auto freq_f = "sw_resource_frequency";
181  static auto var_res = std::make_shared<Variable>("resource");
182  static auto var_freq = std::make_shared<Variable>("frequency");
183 
184  PROLOG_ENGINE_QUERY(PrologTerm(freq_f, var_res, var_freq), [&callback](const BindingsPtr &bindings) {
185  auto val_res = bindings->getAtomic(var_res->name());
186  auto val_freq = bindings->getAtomic(var_freq->name());
187  if (val_res && val_freq && val_freq->isNumeric()) {
188  callback(val_res->stringForm(), std::static_pointer_cast<Numeric>(val_freq)->asInteger());
189  }
190  });
191 }
#define PROLOG_ENGINE_EVAL(term)
Definition: PrologEngine.h:128
#define PROLOG_ENGINE_QUERY(term, callback)
Definition: PrologEngine.h:131
#define KNOWROB_BUILTIN_STORAGE(Name, Type)
static std::shared_ptr< knowrob::Atom > Tabled(std::string_view stringForm)
Definition: Atom.cpp:40
static uint32_t batchSize()
Definition: knowrob.h:68
bool removeOne(const Triple &triple) override
void query(const GraphQueryPtr &query, const BindingsHandler &callback) override
static PrologTerm transaction(std::string_view rdf_functor, const TripleContainerPtr &triples)
bool insertAll(const TripleContainerPtr &triples) override
void batchOrigin(std::string_view origin, const TripleHandler &callback) override
bool insertOne(const Triple &triple) override
bool isPersistent() const override
void count(const ResourceCounter &callback) const override
bool removeAllWithOrigin(std::string_view origin) override
static void initializeProlog()
bool has_grounding() const
Definition: groundable.h:92
StorageFeature
Definition: Storage.h:24
std::shared_ptr< TripleContainer > TripleContainerPtr
std::shared_ptr< const Bindings > BindingsPtr
Definition: Bindings.h:151
std::function< void(std::string_view, uint64_t)> ResourceCounter
std::function< void(const BindingsPtr &)> BindingsHandler
Definition: Bindings.h:152
std::function< void(const TripleContainerPtr &)> TripleHandler
std::shared_ptr< GraphQuery > GraphQueryPtr
Definition: GraphQuery.h:65
Triple * ptr
Definition: Triple.h:590