-
-
Notifications
You must be signed in to change notification settings - Fork 177
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Compilation warnings with PL_initialise #1327
Comments
You may also be interested by these warnings when including SWI-cpp.h:
|
Instead of calling This doesn't fix the problem with I can change the code for these to use |
|
Ah I saw this file but I did not open it 😱 I'll give you feedback tomorrow. Thank you. |
Thanks for the feedback. I think it is time to actively deprecate the old SWi-cpp.h by moving the docs to some separate corner or maybe better, remove the docs completely, pointing people at the manual of older versions. @kamahen ? C++ programmers should have a good experience using SWI-cpp2.h. I'm a little reluctant about consistent introduction of |
Hi !
class PlEngine
{
public:
...
PlEngine(char *av0)
{ int ac = 0;
char **av = static_cast<char**>(malloc(sizeof(char *) * 2)); // <=== Allocation but never free !
av[ac++] = av0;
if ( !PL_initialise(1, av) )
throw PlError("failed to initialise");
}
~PlEngine()
{ PL_cleanup(0);
}
};
const char* argv[] = {"", "-q"};
int argc = sizeof(argv) / sizeof(argv[0]);
PL_initialise(argc, const_cast<char**>(argv)); while this may lead to undefined behaviour (I hope yo do not modify).
in this basic example: PlCall("consult('test.pl')");
PlTermv args(1);
args[0] = PlTerm_var();
PlQuery query("foo", args);
while (query.next_solution())
{
std::cout << "Result : " << args[0].as_string() << std::endl;
} I did not find examples and doc is not clear for beginners.
#include <SWI-cpp2.h>
#include <optional>
#include <stdexcept>
#include <string>
#include <vector>
class PrologInterface
{
public:
class Exception: public PlException
{
public:
explicit Exception(const PlException& ex) : PlException(ex) {}
explicit Exception(const std::string& message)
: PlException(PlTerm(message.c_str()))
{
}
virtual const char* what() const noexcept override
{
static std::string msg =
"Exception: " + PlException::term().as_string();
return msg.c_str();
}
};
PrologInterface(int argc, char** argv)
{
if (!PL_initialise(argc, argv))
{
throw Exception("Failed to initialize Prolog engine.");
}
}
PrologInterface()
{
const char* argv[] = {"", "-q"};
int argc = sizeof(argv) / sizeof(argv[0]);
if (!PL_initialise(argc, const_cast<char**>(argv)))
{
throw Exception("Failed to initialize Prolog engine.");
}
}
~PrologInterface() noexcept
{
PL_halt(0);
}
void consult(const std::string& file)
{
std::string query = "consult('" + file + "')";
if (!PlCall(query))
{
throw Exception("Failed to consult file: " + file);
}
}
template <typename... Args>
std::vector<std::vector<PlTerm>> query(const std::string& query_str, Args&&... args)
{
PlTermv termv(sizeof...(args));
setArguments(termv, std::forward<Args>(args)...);
PlQuery query(query_str.c_str(), termv);
std::vector<std::vector<PlTerm>> solutions;
try
{
while (query.next_solution())
{
std::vector<PlTerm> solution;
for (size_t i = 0; i < termv.size(); ++i)
{
solution.push_back(termv[i]);
}
solutions.push_back(solution);
}
}
catch (const PlException& ex)
{
throw Exception(ex);
}
return solutions;
}
private:
template <typename Arg, typename... Args>
void setArguments(PlTermv& termv, Arg&& arg, Args&&... args)
{
termv[sizeof...(Args)] = PlTerm(std::forward<Arg>(arg));
if constexpr (sizeof...(Args) > 0)
{
setArguments(termv, std::forward<Args>(args)...);
}
}
void setArguments(PlTermv&) {}
}; Idea: auto solutions = prolog.query("foo", "X");
if (solutions.empty())
{
std::cout << "No solutions found" << std::endl;
}
else
{
for (const auto& solution : solutions)
{
for (const auto& term : solution)
{
std::cout << term.as_string() << " ";
}
std::cout << std::endl;
}
} But this code does not compile, and I guess has several issues: |
About I tried calling I'll look at your other comments later. There are some legacy issues (both in SWI-Prolog and C++), so I'm not sure what's best. @JanWielemaker - I'm in favour of removing |
No worry, this is just a minor issue. If the doc could be a little more explicit about |
I just tried some of the example code that uses |
That is a it too drastic IMO. I don't want to break working code if not strictly necessary and having to edit in a distributed software package is not what I like doing (and one may not have the rights). A warning and removing the docs should be enough. |
I just deleted the version 1 docs and uncommented the |
If someone is converting old code to use |
Just for information: I also found this nice repo https://github.com/ethz-asl/ros-prolog (sadly archived! Why ?) with a smooth C++ API wrapping your C API. It also hides some Prolog guts for example where a term is either a variable or an atom. I'm personally not fan of projects using Pimpl (i.e. they use void* instead of PL_engine_t) in our case to avoid exporting the SWI-Prolog.h. I'm giving a try cleaning on folders prolog_swi and prolog_common (other code can be drop I guess):
The only dark point is the compilation of the Engine class: they are using old Prolog |
I guess this is more a discussion for the Discourse forum. There are definitely more ways to talk to Prolog from C++. I guess the main advantage of using the bundled one is that you can be fairly sure it will be maintained for a long time. I'm not much of a C++ programmer though and have little opinion on this ... |
Hello !
For a C++ Linux project, I do not want to do:
but this instead:
but the compilo complains:
warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
because of missing const.Now the compilo fails because PL_initialise does not take
const char**
.This is the war between serious and modern C++ and legacy C :) Therefore can you adapt your API for:
Because I have either to choose between warnings and ugly hack
char* argv[2] = {const_cast<char*>(""), const_cast<char*>("-q")};
The text was updated successfully, but these errors were encountered: