5

I am experimenting with PyClips and I want to integrate it tightly with Python, so that when a rule is activated, it calls a python function.

Here is what I have so far:

import clips

def addf(a, b):
    return a + b

clips.RegisterPythonFunction(addf)

clips.Build("""
(defrule duck
  (animal-is duck)
  =>
  (assert (sound-is quack))
  (printout t "it’s a duck" crlf))
  (python-call addf 40 2 )
""")

However, when I assert the fact 'animal-is duck', my python function is NOT being called:

>>> clips.Assert("(animal-is duck)")
<Fact 'f-0': fact object at 0x7fe4cb323720>
>>> clips.Run()
0

What am I doing wrong?

Amittai Shapira
  • 3,749
  • 1
  • 30
  • 54
Homunculus Reticulli
  • 65,167
  • 81
  • 216
  • 341
  • CLIPS! I loved using that. I can't contribute anything useful, that looks correct as far as the CLIPs goes. – Joe Jan 23 '12 at 15:00
  • try sticking something diagnostic in your function to be sure it isn't running. `import pdb;pdb.set_trace()` or the like – Joe Jan 23 '12 at 15:21

1 Answers1

2

There's a misplaced bracket that closes the rule too soon leaving out the python-call:

clips.Build("""
(defrule duck
  (animal-is duck)
  =>
  (assert (sound-is quack))
  (printout t "it's a duck" crlf))
  (python-call addf 40 2 )       ^
""")                      ^      |
                          |   this one
                          |
                      should go here

If you want to verify that the addf actually returned 42, the result could be binded and printed it out:

clips.Build("""
(defrule duck
  (animal-is duck)
  =>
  (assert (sound-is quack))
  (printout t \"it's a duck\" crlf)
  (bind ?tot (python-call addf 40 2 ))
  (printout t ?tot crlf))
""")


clips.Assert("(animal-is duck)")
clips.Run()
t = clips.StdoutStream.Read()
print t
Rik Poggi
  • 28,332
  • 6
  • 65
  • 82
  • Thanks for the feedback. I can't believe I was stumped by misplaced brackets!. Could you please modify the snippet so that it shows how to pass variables (simple data types: bool, integer, float, string) to pyCLIPS (I think this involves 'binding' to CLIPS variables - but I'm not sure), and also how to pass (simple data type) variables from CLIPS back to Python. As an aside, if I wanted to pass a more complicated data type (e.g. list or dict) to pyCLIPS what would be your recommendation for doing so? – Homunculus Reticulli Jan 26 '12 at 21:14
  • @HomunculusReticulli: I'm sorry, I never really used clips so I can't help you with that. I also fear it will be off-topic here, but you're more then welcome to open a new question. – Rik Poggi Jan 27 '12 at 09:16
  • Hmmm, I'm not sure if you misunderstood my question. I want to know how I can pass variables from Python to PyClips (and the other way back). For example from Python to PyCLIPS, I want to know how I can assert a Python integer, double, string (or maybe list?) and see the rule triggered in PyCLIPS. For PyCLIPS -> Python, I want to know how to pass a PyCLIPS 'variable' (e.g. string, int, float) back to a Python variable - a bit like what I did with the addf Python function in my example snippet. – Homunculus Reticulli Jan 29 '12 at 13:27
  • @Hom: **The extra text that is shown in the bounty banner has only the purpose of explaining why the bounty is being offered.** When the bounty will be over that text will not be visible anymore; whoever is going to read an answer after that would not understand why those explainations were added for something that the OP didn't ask. So I must ignore such demands. Also notice that they cannot be edited, because that will result in a changed question (edits are for correct spelling, adding useful information, and similar). Once again, I say that you're more than welcome to ask a new question. – Rik Poggi Jan 29 '12 at 20:09
  • @Hom: In light of what explained in the last comment, would you consider to reward/accept this answer, since clearly solves the issue presented in the question? – Rik Poggi Jan 29 '12 at 20:16