What is the correct way to assert a rule with Janus?

Hi,

I am struggling to assert rules with the Janus Python β†’ Prolog interface.

I tried this approach:

janus.query_once("assert((happy(A):- rich(A)))")

However, it gives the error janus.PrologError: '$c_call_prolog'/0: Arguments are not sufficiently instantiated

Note that the query assert((happy(A):- rich(A))) works if used directly in SWI-Prolog.

I also tried this code:

janus.query_once("assert(X)", {'X':'happy(A):- rich(A)'})
print(janus.query_once("happy(X)"))

However, it gives the error # janus.PrologError: janus:py_call/4: Unknown procedure: happy/1. Moreover, calling janus.query_once("listing(X)") shows that the literal string 'happy(A):- rich(A)' is added to the database.

What is the correct way to assert rules with Janus?

Kind regards,

Andrew

Your first attempt fails because the query succeeds, trying to return the binding for the variable to Python, but as Python cannot represent logical variables, this fails. The error should be better. The second approach fails as well because you cannot create an arbitrary Prolog term from Python. Possibly we should add a constructor to the class Term. There are several ways to add a rule.

You can cheat by adding ,fail, that will fail, so there are no bindings to report.

 janus.query_once("assert((happy(A):- rich(A))),fail")

A bit nicer is by prefixing the variables with _, so they are not reported:

janus.query_once("assert((happy(_A):- rich(_A)))")

Finally, there is janus.consult() using a string. See SWI-Prolog -- Calling Prolog from Python

2 Likes

Brilliant, thanks!

BTW this must have been one of the most intelligent rules ever… :sweat_smile: