Use "rule(D)". Prolog says that identifiers that start with a capital are variables. Now the result is a dict that holds the key D with the Python value that results from translating the Prolog result to Python. So, you must make sure Prolog binds the variable to something that can be converted to Python. If you do not care about the value of the binding, use _D, i.e., start the variable with an underscore.
This has little to do with Janus. You can use Python string interpolation, e.g.,
janus.consult("rules", f"{r1}. {r2}.")
The error comes because rule/3 is a built-in that you are calling with invalid arguments.
But, this is not how you are supposed to use Janus. If you have Python data that you want in the Prolog database call assertz/1 through the API. In such cases I’d define a Prolog predicate that does the proper assert from simply arguments, e.g.
assert_data(A,B,C) :- assert(data(A,B,C)).
Now you can call this, where a, b and c are (simple) Python data items.
janus.query_once("assert_data(A,B,C)",
{"A": a, "B":b, "C":c)})
The janus.consult() using a string is mainly there to allow you defining Prolog predicates that you need in the interface directly from Python.
This simply adds the Prolog fact r(line). The argument to consult is just a Python string. If you want anything expanded there you need Python string interpolation. I know about f"....{expression}...", but there is probably more to say about that. I am not a Python expert.
This D does not relate to anything.
This binds _E to line, but as you do not ask for the binding if the variable starts with an underscore, the answer is simply true.
Looks like you have some serious misconceptions about both Python and Prolog. I suggest reading some basics on Prolog such that you understand facts, rules and queries. Next, understand what you want to do in Prolog without Python and then get Python into the picture.
I only would like to work with the variable line as a rule. If the variables E or D are equal to line it would return True, otherwise False. The problem is that it always returns True and I don’t understant why. I modified the code as you explained me some hours ago: non d letter, but D, otherwise it always returns False, because d is not a variable since it’s not in capital letter (as you have written above). The problem is that now it always returns True, but I don’t understand why
I’m sorry, I can only repeat my previous answer. Maybe someone else understands what you want? Surely the behaviour you show is what this code is supposed to do. And surely, this doesn’t make much sense …
The variables in Python and the variables in Prolog are completely different – you can’t expect rule(line) to reference your Python variable line … in fact, in Prolog, line is an atom, not a variable.
There’s an additional issue here: you’re using Numpy, and AFAIK, the Python-Prolog interface doesn’t know how to handle Numpy arrays.
Anyway, ignoring Numpy, if you want to pass the value of a Python variable to Python, you need to convert it to something the Prolog understands. So, if you have a Python variable s, you can pass its value to Prolog like this:
s = 'foo'
janus.consult("rules", f"rule('{s}').")
which, through Python interpolation, is the same as:
janus.consult("rules", f"rule('foo').")
(I put the single quotes in the call to janus.consule() as a simple way of allowing s to, for example, have a blank in it … however, this doesn’t handle situations such as having a single quote inside the value of s).
Thank you,
I have read the documentation about the data conversion and, if I understood correctly, it’s best not to try to use lists, arrays, etc. directly, but only strings. Is it correct?
The arrays are not the main issue (I think). The problem is that numpy does not use native Python numbers. So, we get
?- py_call(numpy:array([1,2,3]), R).
R = [<py_int64>(0x7ff1fc3292f0), <py_int64>(0x7ff1fc2e8230), <py_int64>(0x7ff1fd23be30)].
Here, <py_int64> says this is an instance of [numpy].int64, which is not a subclass of Python int. The Prolog interface has no way to know it would be better to turn this into an integer. We can handle them by using the item() method on the numpy data:
?- py_call(numpy:array([1,2,3]), _R), member(I, _R), py_call(I:item(), Value).
I = <py_int64>(0x7ff0f75fea70),
Value = 1 ;
I = <py_int64>(0x7ff0f75fe9f0),
Value = 2 ;
I = <py_int64>(0x7ff0f75feb50),
Value = 3.