Communicating with Clips rules engine in Python

1.2k Views Asked by At

I would like to communicate several times with Clips rule engine in Python 3.8.3.

For example, I would like to have the following communication

  1. Launch Clips
    C:\Users\username\Clips>"C:\Program Files\CLIPS 6.31\CLIPSDOS64.exe"
             CLIPS (6.31 6/12/19)
  1. Define rules
    (defrule ValueManipulation
      (value ?v)
    =>
      (assert (result ?v))
    )
  1. Query with first fact set and read results from stdout
    (deffacts f1 "My facts" (value 1))
    (reset)
    (run)
    (facts)
  1. Query with second fact set and read results from stdout
    (deffacts f1 "My facts" (value 2))
    (reset)
    (run)
    (facts)
  1. Exit
    (exit)

I have managed to input to stdin once and read from stdout once:

import subprocess

clips_commands = """
(defrule ValueManipulation
  (value ?v)
=>
  (assert (result ?v))
)
(deffacts f1 "My facts" (value 1))
(reset)
(run)
(facts)
(exit)
"""
p = subprocess.Popen('"C:\Program Files\CLIPS 6.31\CLIPSDOS64.exe"', 
                     stdin=subprocess.PIPE, stdout=subprocess.PIPE)
result = p.communicate(input=bytes(clips_commands,'utf-8'))

for line in str(result[0]).split('\\r\\n'):
    print(line)

However, I would like the following kind of query several times and read the output from stdout

    (deffacts f1 "My facts" (value 3))
    (reset)
    (run)
    (facts)

Using packages like pyclips or clipspy was not preferred in the above example, because these packages were not available with pip install. However, repackaging one of these packages could solve the question.

1

There are 1 best solutions below

0
On

Thanks to @noxdafox, I was able to use clipspy library!

Below is the test code which demonstrates reusing clips rules:

import clips

env = clips.Environment()

rule = """
(defrule ValueManipulation
  (value ?v)
=>
  (assert (result ?v))
)
"""
env.build(rule)

print('Add fact 1:')
env.assert_string("(value 1)")
for fact in env.facts():
    print(fact)
env.run()
print('\nResult for fact 1:')
for fact in env.facts():
    print(fact)

print('\nFacts after reset:')
env.reset()
for fact in env.facts():
    print(fact)
env.assert_string("(value 2)")

print('\nResult for fact 2:')
env.run()
for fact in env.facts():
    print(fact)

print('\nResult for fact 3:')
env.reset()
env.assert_string("(value 3)")
env.run()
for fact in env.facts():
    print(fact)

The above code produces the following results:

Add fact 1:
(initial-fact)
(value 1)

Result for fact 1:
(initial-fact)
(value 1)
(result 1)

Facts after reset:
(initial-fact)

Result for fact 2:
(initial-fact)
(value 2)
(result 2)

Result for fact 3:
(initial-fact)
(value 3)
(result 3)