Using Python functions from the Clips expert system

Using PyClips, I am trying to create rules in Clips that dynamically retrieve data from the Python interpreter. To do this, I register the external function described in the manual .

The code below is a toy example of a problem. I do this because I have an application with a large body of data, in the form of an SQL database, which I want to use with Clips. However, I don’t want to waste time converting all this data into Clips statements if I can just β€œconnect” the clips directly to the Python namespace.

However, when I try to create a rule, I get an error message. What am I doing wrong?

import clips #user = True #def py_getvar(k): # return globals().get(k) def py_getvar(k): return True if globals.get(k) else clips.Symbol('FALSE') clips.RegisterPythonFunction(py_getvar) print clips.Eval("(python-call py_getvar user)") # Outputs "nil" # If globals().get('user') is not None: assert something clips.BuildRule("user-rule", "(neq (python-call py_getvar user) nil)", "(assert (user-present))", "the user rule") #clips.BuildRule("user-rule", "(python-call py_getvar user)", "(assert (user-present))", "the user rule") clips.Run() clips.PrintFacts() 
+4
source share
2 answers

I got some help from the PyClips support group. The solution is to ensure that your Python function returns clip.Symbol objects and use (test ...) to evaluate functions in LHS rules. Using Reset () also seems necessary to activate certain rules.

 import clips clips.Reset() user = True def py_getvar(k): return (clips.Symbol('TRUE') if globals().get(k) else clips.Symbol('FALSE')) clips.RegisterPythonFunction(py_getvar) # if globals().get('user') is not None: assert something clips.BuildRule("user-rule", "(test (eq (python-call py_getvar user) TRUE))", '(assert (user-present))', "the user rule") clips.Run() clips.PrintFacts() 
+3
source

Your problem has something to do with (neq (python-call py_getvar user) 'None') . Apparently the clips do not like the nested operator. It seems like trying to wrap a function call in an equality expression does bad things. However, you will never assert a value in any case, since your function returns neither Nil nor value. Instead, you want to do the following:

 def py_getvar(k): return clips.Symbol('TRUE') if globals.get(k) else clips.Symbol('FALSE') 

then just change "(neq (python-call py_getvar user) 'None')" to "(python-call py_getvar user)"

And that should work. I did not use pyclips before messing with it just now, but this should do what you want.

NTN!

 >>> import clips >>> def py_getvar(k): ... return clips.Symbol('TRUE') if globals.get(k) else clips.Symbol('FALSE') ... >>> clips.RegisterPythonFunction(py_getvar) >>> clips.BuildRule("user-rule", "(python-call py_getvar user)", "(assert (user- present))", "the user rule") <Rule 'user-rule': defrule object at 0x00A691D0> >>> clips.Run() 0 >>> clips.PrintFacts() >>> 
+1
source

Source: https://habr.com/ru/post/1315681/


All Articles