Closed marklaw closed 3 years ago
The clingo library as such does not even link against the Python and Lua libraries. For this to work, another library including the code from libpyclingo
would have to be included. Then, you could call clingo_register_python_
to enable execution of Python scripts. There is no target to build such a library.
Yes, I did this actually. But unfortunately, although the Python script is being executed when the program is ground (i.e. if I put a print statement in the main script, it gets printed), but the functions themselves are not being called by the grounder. Is this because when I use the C++ API, it expects that all functions will be handled by the C++ callback?
I can post a simple minimal example of what I have tried if it would help.
I think that if you pass a context object to ground, then the globally registered scripts are ignored. If you pass a nullptr
, then it should work. You could register another script to call functions to avoid using the context callback.
Thanks for your help! Sorry if I'm being dim, but I'm not sure what you mean by passing a context object to ground. The ground function takes two arguments (the program parts and an optional callback, which is nullptr
by default).
On registering another script, is this not what clingo_registerpython does? Can I just copy the code from clingo_register_python_
, or call clingo_register_python_
again (if so, at what point should this be executed? just before grounding?). Or, do I need to completely rewrite the functions used by clingo_register_python_
? If so, what will be the difference between my customised versions and those used by clingo_register_python_
?
For reference, this is what I am currently doing:
#include <string>
#include <clingo.hh>
#include <pyclingo.h>
#include <iostream>
std::string program = R"ESC(
#script (python)
import clingo
print("script executed")
def ident(x):
print("ident function called ident({x})")
return clingo.Number(x)
#end.
p(@ident(2)).
p(test).
)ESC";
int main(int argc, char *argv[]) {
using namespace std;
clingo_register_python_();
Clingo::Logger logger = [](Clingo::WarningCode, char const *message) { cout << message << endl;};
Clingo::Control ctl({{}, logger, 20});
cout << "grounding..." << endl;
ctl.add("", {}, program.c_str());
ctl.ground({{"", {}}});
cout << "solving..." << endl;
for(auto& m : ctl.solve())
for(auto& atom : m.symbols())
cout << atom << " ";
cout << endl;
return 0;
}
And I see the following output:
grounding...
script executed
solving...
p(test)
As far as I can see, it should work like this. Or at least there should be a message because it has to be
def ident(x)
return clingo.Number(x.number)
Maybe it is just the message that gets gobbled but it is working otherwise.
The identity function should also be written like this:
def ident(x)
return x
Sorry, that was me going from my larger program to a minimal example (in my larger program I was doing something with x and returning something else). I've corrected the identity function, but it still produces the same output for me.
I know this is an odd use case, so understand if you don't have the time to fix it. Is there anything else I can try to get it working myself?
I will have a look. But it might take some time because I am currently working on another project and also vacation is ahead.
Okay, thanks!
This should be fixed now.
Great. Thanks for your help!
Hi,
Is there a simple way to call python functions during grounding when using the C++ API? Please correct me if I'm wrong, but I think this is not currently supported.
I've started down the line of trying to use a C++ API grounding callback to pass the callback onto python myself, but I got stuck in converting Clingo::SymbolSpan arguments to a PyObject. I assume there is a function somewhere in libpyclingo that could do this for me, but I couldn't find it. I'm also not sure this is the most efficient approach, so any better suggestions would be greatly appreciated.
I'm aware it might sound a bit of an odd use case that I am using the C++ API and I also need python functions. My use case is that I am developing systems written in C++ that call Clingo using the C++ API, but I would like users to be able to write custom functions that can be evaluated during grounding without needing to write them in C++ and recompile my systems.
Thanks in advance,
Mark