I have a small CLIPS app which runs and asks a user questions when
loaded into CLIPS interactive shell but I'm now trying to get it to
interact with the user using Python via pyclips. It just runs to
completion as I'm lost on how to get it to "interact".
[ What I eventually wish to do is to have the Python run from a Web
interface interactively i.e. the web pages puts up a question and the
user clicks a link to choose, then based on that the next questions
appears. Eventually the user is provided with a list of experiments to
run. ]
This is the output so far:
--- CLIPS ---
Hello, World!
------------------------
Rules
------------------------
MAIN:
get-sample-composition
get-cell-type
get-body-fluid-type
get-plasma-type
state-human-plasma-preparation
------------------------
Agenda:
------------------------
MAIN:
0 get-sample-composition: f-0,
For a total of 1 activation.
Before Run
f-0 (initial-fact)
For a total of 1 fact.
After Run
f-0 (initial-fact)
f-1 (sample-composition EOF)
For a total of 2 facts.
-------------------------------------------------
#!/usr/bin/python
import clips
print "\n--- CLIPS ---\n"
clips.Eval('(printout t "Hello, World!" crlf)')
print clips.StdoutStream.Read()
clips.Reset()
print "------------------------"
print "Rules"
print "------------------------"
# BuildRule(name, lhs, rhs [, comment ])
# Build a Rule object with specified name and body. comment is the optional
# comment to give to the object. The lhs and rhs parameters correspond to the
# left-hand side and right-hand side of a Rule.
#clips.BuildRule("duck-rule", "(duck)", "(assert (quack))", "the Duck Rule")
# Build(construct)
# Build construct given in argument as a string. The string must enclose a
# full construct in the CLIPS language.
clips.Build("""
; Sample Composition for Protein Extraction
(defrule get-sample-composition ""
(not (sample-composition ?))
=>
(printout t "Is the sample Cellular (C), tissue sample (T) or body
fluid (B) ? " )
(assert (sample-composition = (upcase (read))))
)
""")
clips.Build("""
; Protein Extraction for Cellular Samples
(defrule get-cell-type""
(sample-composition C)
=>
(printout t "Is the sample Mammalian cells (M) or other (O) i.e.
Fungal, plant or bacterial cells ? " )
(assert (cell-type = (upcase (read))))
)
""")
clips.Build("""
; Body Fluid Extraction Procedure
(defrule get-body-fluid-type""
(sample-composition B)
=>
(printout t "Is the sample Plasma (P), Urine (U), Cerebro-spinal
fluid (C) or Sputum (S) ? " )
(assert (body-fluid-type = (upcase (read))))
)
""")
clips.Build("""
; Plasma Sample Preparation
(defrule get-plasma-type ""
(body-fluid-type P)
=>
(printout t "Is the sample Human Plasma (H) or plasma from another
species (O) ? " )
(assert (plasma-type = (upcase (read))))
)
""")
clips.Build("""
; Human Plasma
(defrule state-human-plasma-preparation ""
(plasma-type H)
;?fact <- (sample-composition ?)
=>
;(bind ?procedure_list (create$ a b c))
(printout t crlf crlf)
(printout t "--- Expert System Advice ------------- " crlf)
(printout t "The procedures you should perform are: " crlf crlf)
(printout t "1. Human Plasma Preparation" crlf)
(printout t "2. Perform a depletion" crlf)
(printout t "-------------------------------------- " crlf)
;(assert (procedure depletion))
; (insert$ ?procedure_list 1000 depletion)
(assert (finished 1))
;(retract ?fact)
;(facts)
)
""")
clips.PrintRules()
print "\n"
print "------------------------"
print "Agenda:"
print "------------------------"
clips.PrintAgenda()
print "\n"
print "Before Run"
clips.PrintFacts()
clips.Run()
print "\n"
print "After Run"
clips.PrintFacts()
print "\n"
--
Michael Lake
Caver, Linux enthusiast & interested in most things technical.
Q: Can I use PyCLIPS for interactive sessions?
A: Yes, but you can't use clips.StdinStream and clips.StdoutStream in
an
effective way. Ok, if you structure your CLIPS subprogram very
carefully
and pay special attention to the execution order you might also be
able
to use the default CLIPS streams to provide input from an hypothetical
user, but the quickest way to achieve a result is to let Python do the
I/O job using a Python function:
def clips_raw_input(prompt):
return clips.String(raw_input(prompt))
clips.RegisterPythonFunction(clips_raw_input, "raw-input")
this function will let Python interact with the user, such as in the
following session:
>>> import clips
>>> def clips_raw_input(prompt):
return clips.String(raw_input(prompt))
>>> clips.RegisterPythonFunction(clips_raw_input, "raw-input")
>>> r1 = clips.BuildRule(
"name-rule",
"(initial-fact)",
"""(bind ?user-name (python-call raw-input "Your Name? "))
(assert (user-name-is ?user-name))""")
>>> clips.Reset()
>>> clips.Run()
Your Name? Francesco
1
>>> clips.PrintFacts()
f-0 (initial-fact)
f-1 (user-name-is "Francesco")
For a total of 2 facts.
>>>
Of course you can use raw_input, but you can also pop up a dialog box
or whatever else to retrieve input from the interactive session, using
virtually all Python possibilities.
> I have a small CLIPS app which runs and asks a user questions when
> loaded into CLIPS interactive shell but I'm now trying to get it to
> interact with the user using Python via pyclips. It just runs to
> completion as I'm lost on how to get it to "interact".
>
> [ What I eventually wish to do is to have the Python run from a Web
> interface interactively i.e. the web pages puts up a question and the
> user clicks a link to choose, then based on that the next questions
> appears. Eventually the user is provided with a list of experiments to
> run. ]
Making the application interactive using pyClips is a bit different
from standalone Clips. It's a good thing to work out all of the logic
in standalone Clips first, but once you're done you're going to have
to write some python code that manages and controls communication
between the front-end (Tk, wxPython, HTML or whatever you've decided
on) and the Clips engine.
The control algorithm I've used is basically:
0. Set Clips in start mode using Reset or whatever else needed
1. Read the Facts in Clips and (based on those) generate a "front-end"
(or quit the application).
2. Render front-end (and wait for user response).
3. Parse user's response and construct and assert new Fact objects (or
modify existing ones)
4. issue Clips Run
5. Goto 1
Note! The algorithm above puts some other requirements on your Clips
app. You cannot use the read-function from a Rule's RHS to get fresh
facts to work with. Instead you can, for example, assert an "askuser"
fact which holds the question and the answer options. You can easily
use this to render the HTML needed.
HTH
Johan Lindberg
jo...@pulp.se
gdronline2 wrote:
> I found this in the FAQ included in the PyCLIPS distribution:
> Q: Can I use PyCLIPS for interactive sessions?
......
> >>> def clips_raw_input(prompt):
> return clips.String(raw_input(prompt))
> >>> clips.RegisterPythonFunction(clips_raw_input, "raw-input")
> >>> r1 = clips.BuildRule(
> "name-rule",
> "(initial-fact)",
> """(bind ?user-name (python-call raw-input "Your Name? "))
> (assert (user-name-is ?user-name))""")
Thanks, I have included this python function in some code to try this
out in a python script.
I'm a bit confused as to whether to use read versus bind and how to
print things to the user and get data back.
I notice that "printout t" does not work in method 2, and when I tried
to use upcase in method 2 I get an unable to parse expression. Moving
to a python script that will interact with the user is not so clear.
# Method 1
# Here is the previous way I did it without raw-input. I use read then
upcase to uppercase all responses.
# With no
clips.Build("""
; Sample Composition for Protein Extraction
(defrule get-sample-composition ""
(not (sample-composition ?))
=>
(printout t "Is the sample Cellular (C), tissue sample (T) or
body fluid (B) ? " )
(assert (sample-composition = (upcase (read))))
)
""")
# Method 2
# Here I call raw-input and use bind to create a variable ?sample-
composition.
# Then assert a fact 'sample-composition' which will be used later
based on this variable.
def clips_raw_input(prompt):
return clips.String(raw_input(prompt))
clips.RegisterPythonFunction(clips_raw_input, "raw-input")
clips.Build("""
; Sample Composition for Protein Extraction
(defrule get-sample-composition ""
(not (sample-composition ?))
=>
(printout t "Why does this not get printed ? ")
(bind ?sample-composition (python-call raw-input "Is the
sample Cellular (C), tissue sample (T) or body fluid (B) ? " ))
(assert (sample-composition = ?sample-composition))
)
""")
Ah thanks, It looks like it's a pretty quiet group. Anyhow I'll join
up and post there as I can see it's more specific to pyclips.
Thanks
On Oct 16, 1:16 am, CLIPS Support <gdronline2...@swbell.net> wrote:
> There's a forum for PyCLIPS at this location:http://sourceforge.net/forum/forum.php?forum_id=390146. The author's
> email address is in the contact information at the bottom of this
> page:http://pyclips.sourceforge.net/readme.html.
Michael Lake