6 #include <SWI-Prolog.h>
11 #include "knowrob/Logger.h"
12 #include "knowrob/integration/prolog/PrologEngine.h"
13 #include "knowrob/knowrob.h"
14 #include "knowrob/queries/QueryError.h"
15 #include "knowrob/integration/prolog/logging.h"
16 #include "knowrob/integration/prolog/ext/algebra.h"
17 #include "knowrob/semweb/PrefixRegistry.h"
18 #include "knowrob/URI.h"
19 #include "knowrob/reasoner/prolog/semweb.h"
23 static const int prologQueryFlags = PL_Q_CATCH_EXCEPTION | PL_Q_NODEBUG;
36 PL_thread_destroy_engine();
44 if (PL_thread_attach_engine(
nullptr) < 0) {
46 KB_ERROR(
"Failed to attach Prolog engine to current thread!");
50 KB_DEBUG(
"Attached Prolog engine to current thread.");
57 if (PL_get_atom_chars(prefix_term, &
prefix) && PL_get_atom_chars(uri_term, &uri)) {
65 if (PL_get_atom_chars(t_url, &url)) {
67 return PL_unify_atom_chars(t_resolved, resolved.c_str());
81 setenv(
"LC_NUMERIC",
"C", 1);
92 for (
int i = 0; i < pl_ac; i++) {
95 PL_initialise(pl_ac, pl_av);
96 KB_DEBUG(
"Prolog has been initialized.");
97 self_.emplace(std::thread::hardware_concurrency());
104 PL_register_foreign(
"knowrob_register_namespace",
106 PL_register_foreign(
"url_resolve",
112 KB_DEBUG(
"common foreign Prolog modules have been registered.");
114 consult(std::filesystem::path(
"integration") /
"prolog" /
"__init__.pl",
"user");
115 KB_DEBUG(
"KnowRob __init__.pl has been consulted.");
124 self_ = std::nullopt;
127 KB_DEBUG(
"Prolog has been finalized.");
131 static std::filesystem::path projectPath(KNOWROB_SOURCE_DIR);
132 static std::filesystem::path installPath(KNOWROB_INSTALL_PREFIX);
137 installPath /
"share" /
"knowrob" /
"integration" /
"prolog",
138 installPath /
"share" /
"knowrob" /
"reasoner" /
"prolog",
139 installPath /
"share" /
"knowrob" /
"reasoner",
140 installPath /
"share" /
"knowrob",
141 projectPath /
"src" /
"integration" /
"prolog",
142 projectPath /
"src" /
"reasoner" /
"prolog",
143 projectPath /
"src" /
"reasoner",
146 for (
const auto &p: libPaths) {
147 if (!exists(p))
continue;
155 auto filePaths_knowrob = {
157 installPath /
"share" /
"knowrob"
159 for (
const auto &p: filePaths_knowrob) {
160 if (!exists(p))
continue;
167 auto filePaths_tests = {
168 projectPath /
"tests"
170 for (
const auto &p: filePaths_tests) {
171 if (!exists(p))
continue;
179 self_->pushWork(goal, errHandler);
184 std::exception_ptr excPtr =
nullptr;
185 pushGoal(goal, [&excPtr](...) { excPtr = std::current_exception(); });
188 if (excPtr) std::rethrow_exception(excPtr);
192 bool hasSolution =
false;
196 auto goal = goalFactory();
197 auto qid = goal.openQuery(prologQueryFlags);
198 hasSolution = goal.nextSolution(qid);
206 std::optional<Solution> solution;
210 auto goal = goalFactory();
211 auto qid = goal.openQuery(prologQueryFlags);
212 if (goal.nextSolution(qid)) {
214 for (
auto &
var: goal.vars()) {
225 std::vector<Solution> solutions;
229 auto goal = goalFactory();
230 auto qid = goal.openQuery(prologQueryFlags);
231 while (!hasStopRequest() && goal.nextSolution(qid)) {
233 for (
auto &
var: goal.vars()) {
236 solutions.push_back(solution);
247 auto goal = goalFactory();
248 auto qid = goal.openQuery(prologQueryFlags);
249 while (!hasStopRequest() && goal.nextSolution(qid)) {
250 auto bindings = std::make_shared<Bindings>();
251 for (
auto &
var: goal.vars()) {
252 if (PL_term_type(
var.second) == PL_VARIABLE) {
255 bindings->set(std::make_shared<Variable>(
var.first),
265 static auto consult_f =
"consult";
276 static std::filesystem::path projectPath(KNOWROB_SOURCE_DIR);
277 static std::filesystem::path installPath(KNOWROB_INSTALL_PREFIX);
279 if (!exists(filePath)) {
280 auto possiblePaths = {
281 projectPath / filePath,
282 projectPath /
"src" / filePath,
283 projectPath /
"src" /
"reasoner" /
"prolog" / filePath,
284 installPath /
"share" /
"knowrob" / filePath
286 for (
const auto &p: possiblePaths) {
287 if (exists(p))
return p;
294 static std::filesystem::path projectPath(KNOWROB_SOURCE_DIR);
295 static std::filesystem::path installPath(KNOWROB_INSTALL_PREFIX);
297 if (!exists(filePath)) {
298 auto possiblePaths = {
299 projectPath / filePath,
300 installPath /
"share" /
"knowrob" / filePath
302 for (
const auto &p: possiblePaths) {
303 if (exists(p))
return p;
foreign_t pl_rdf_register_namespace2(term_t prefix_term, term_t uri_term)
foreign_t url_resolve2(term_t t_url, term_t t_resolved)
static void registerPrefix(std::string_view prefix, std::string_view uri)
static std::vector< std::string > arguments_
std::map< Variable, TermPtr, std::less<> > Solution
static void initializeProlog()
static std::optional< Solution > oneSolution(const GoalFactory &goalFactory)
static void finalizeProlog()
static bool consult(const std::filesystem::path &uri, const char *module={})
PrologEngine(uint32_t maxNumThreads=0)
static std::filesystem::path getPrologPath(const std::filesystem::path &filename)
static std::optional< PrologEngine > self_
static bool isPrologInitialized_
static void pushGoal(const std::shared_ptr< ThreadPool::Runner > &goal, const ErrorHandler &errHandler)
std::function< PrologTerm()> GoalFactory
ThreadPool::ExceptionHandler ErrorHandler
static void pushGoalAndJoin(const std::shared_ptr< ThreadPool::Runner > &goal)
static bool eval(const GoalFactory &goalFactory)
static std::filesystem::path getResourcePath(const std::filesystem::path &filename)
static void expandSearchPaths()
static void query(const GoalFactory &goalFactory, const BindingsHandler &callback)
static std::vector< Solution > allSolutions(const GoalFactory &goalFactory)
bool initializeWorker() override
void setModule(std::string_view module)
TermPtr toKnowRobTerm() const
std::function< bool()> StopChecker
std::function< void()> finalizeWorker_
static std::string resolve(const std::string_view &uriString)
constexpr std::string_view prefix
foreign_t log_message4(term_t level_term, term_t msg_term, term_t file_term, term_t line_term)
PL_extension PL_extension_algebra[]
PL_extension PL_extension_semweb[]
foreign_t log_message2(term_t level_term, term_t msg_term)
std::function< void(const BindingsPtr &)> BindingsHandler
char * getNameOfExecutable()