How to embed a Clips Program as a subroutine within a C program

244 views
Skip to first unread message

camilo....@gmail.com

unread,
Jun 5, 2007, 1:20:28 PM6/5/07
to CLIPSESG
Hellooo

Please... I need some help, i'm really a beginner at Clips n just have
made my first Expert Prototype... it is already running as i wanted...
there's just one thing left...
as far as I know Clips doesn't allow me to get a good-looking user
interface for my Expert System so i'd like to "export" my ES to create
this interface using a more "graphically-friendly" language... as you
see i'm not an expert when it comes to programation, in fact all I
know is Clips...


Any help or hints would b great... what i've thought to do is to embed
the Clips program as a subroutine of other program in a different
language such as C, or visual C++ but i got no clue how to do
that......n by what i've read in Clips Homepage n User's Manual i know
it is possible...


Plz tell me howww


Merci à toussss!!!

Camilo Caicedo
Industrial Engineer (Beginner in Clips)
Bogotá, Colombia

Johan Lindberg

unread,
Jun 6, 2007, 7:46:04 AM6/6/07
to CLIP...@googlegroups.com
Hello Camilo.

> as far as I know Clips doesn't allow me to get a good-looking user
> interface for my Expert System so i'd like to "export" my ES to create
> this interface using a more "graphically-friendly" language...

> [...I cut out some stuff here...] what i've thought to do is to embed


> the Clips program as a subroutine of other program in a different
> language such as C, or visual C++ but i got no clue how to do
> that......n by what i've read in Clips Homepage n User's Manual i know
> it is possible...

You don't have to embed Clips yourself, you can use (for example)
JClips[1] which is Clips embedded in Java or PyClips[2] which is Clips
embedded in Python and use either of those languages to create the GUI
part and still have Clips perform all (or at least most of) the logic
as usual.

I've only tried out toy-examples with them and I stopped because I
found no "good" way to pass facts back and forth between the
environments. But that might not be a problem for you, it depends on
what you want to do. But I definitely think it's worth to have a look
before you decide on C or C++.

HTH
Johan Lindberg
jo...@pulp.se

[1] http://www.cs.vu.nl/~mrmenken/jclips/
[2] http://pyclips.sourceforge.net/

camilo....@gmail.com

unread,
Jun 6, 2007, 9:40:41 AM6/6/07
to CLIPSESG
Hello Johan

thanks a lot for the support, since you are clearly more experienced
than me in programming (believe me i'm a beginner betweens beginners
lol) I'm gonna try n follow ur advice, which I really apreciate, i've
already read the info on the links u sent me n i think u are right,
that seems to be what i was looking for... nonetheless i'm still far
away from getting my probs solved :( as i got no clue about java or
Python... but i think i could learn, get someone who explains it to
me, sk someone to do it for me lol, whatever...anyways ur help has
been way helpful as u've given me a light to address my efforts n
avoid wasting time in unuseful applications.

mmm one thing else.... please, i'd like to know a lil bit more about
the problems u found at passing the facts between the enviroments,
what was actually the problem, i didn't get it right... plz explain
me.

Thx a lot once again swedish supporter ;)

Greetings from the Colombian learner!

Johan Lindberg

unread,
Jun 6, 2007, 12:42:54 PM6/6/07
to CLIP...@googlegroups.com
Hi again.

> [...] ... nonetheless i'm still far


> away from getting my probs solved :( as i got no clue about java or
> Python... but i think i could learn, get someone who explains it to
> me, sk someone to do it for me lol, whatever...

I'm totaly biased but I'd say go with Python. There are a couple of
reasons for that, I think it's generally considered to be more
friendly to beginning programmers (at least that's a claim I hear
every now and then), also with Python you can choose between many
GUI-toolkits (wxWidgets, Qt, Tk etc). There are also lots of
higher-level toolkits that work on-top of them which allows you to not
have to worry about the low-level details (which can be a bit
confusing sometimes). Have a look at Boa Constructor[1] (requires
wxPython[2]) and see if that can get you started.

There's also a lot of information about learning to program Python[3]
on the Python webpage[4].

> [...] mmm one thing else.... please, i'd like to know a lil bit more about


> the problems u found at passing the facts between the enviroments,
> what was actually the problem, i didn't get it right... plz explain
> me.

Well, I can't remember all of the details and I can't find the
programs now. But IIRC you communicate with Clips using strings. This
means that if you're doing:

CLIPS> (assert (foo))

in Clips, you need to do:

>>> import clips
>>> clips.Assert("(foo)")

in PyClips. Notice the string construct: "(foo)". That, for me and my
needs, is not good enough.

My specific problem was/is that I have a collection of objects that
are native to Python. I create, read, update and delete them in Python
code, but I also want to have some reasoning capability, which I use
Clips for. At some point in my (Python) program I want to be able to
say run(), or fireAllRules(), or the equivalent, and have my Python
objects manipulated by the rules defined in Clips (or actually,
prefferably have my rules defined in Python as well).

Unfortunately, there's no *automatic* way to make that happen. The
Python objects don't live in Clips Working Memory unless I put them
there, and there's no way of doing that without converting them to a
number of string representations first. Both PyClips and JClips work
this way (if the above is wrong, please let me know).

Another approach is to not use Python objects as "master" facts and
only define them in Clips because you can access those from Python
easily.

It sounds like, and I hope that, your application can fit into the
last category. But i can't really tell from your description of what
you want to do. What kind of GUI are we talking about? What do you
want to have graphical representations of? Facts? Rules? Functions?
All of the above? How do you want them graphically represented? Items
in a list? Icons? or something completely different? Whatever you want
to do, it's going to take some work. But don't worry, it's very often
fun as well.

For completeness sake, I should also mention that there's a third
alternative that I'm a bit afraid to mention (because it's like
swearing in church ;-) but Clips has an almost identical younger
brother called Jess[5] which provides built-in GUI support (Jess is
written in Java and can use it's GUI capabilities from within the
engine). I think that you can use your Clips code unchanged in Jess
but don't quote me on that, cause I'm really not sure.

Good luck.
Johan Lindberg
jo...@pulp.se

[1] http://sourceforge.net/projects/boa-constructor/
[2] http://www.wxpython.org
[3] http://docs.python.org/tut/
[4] http://www.python.org
[5] http://www.jessrules.com/

Message has been deleted

CLIPS Support

unread,
Jun 6, 2007, 6:06:13 PM6/6/07
to CLIPSESG

If you're starting from scratch, generally, it is easier to embed
CLIPS in a C/C++ program than it is to embed CLIPS in another
programming language. When using two different languages, there
are typically data conversion issues that increase the complexity
of the task. For example, comparing C and Java, C strings have a
different representation that Java strings and C does not support
automatic garbage collection whereas Java does. As mentioned,
there are some existing code bridge available, such as JClips and
PyClips, which do a lot of this work for you. If you're using
Visual C++, you have the option to use the older Win32 APIs or
the newer .NET APIs. Integrating with the .NET APIs is for
practical purposes like integrating with a language other than C,
so you have the same bridging issues you'd have with a language
like Java. A .NET code bridge is available at
http://www.proai.net/clips.htm.

Communication between the GUI and CLIPS is the key issue when
embedding CLIPS. Communication from the GUI to CLIPS is usually
easier than the other direction. Many of the most useful commands
take standard C data types as arguments, so writing a simple
program to load some rules, reset the system, assert a few
additional facts, and run the program is relatively
straightforward:

main()
{
InitializeEnvironment();
Load("program.clp");
Reset();
AssertString("(code 1)");
AssertString("(respond immediately)");
Run(-1L)
}

Communication in the other direction is usually more difficult
because you're dealing directly with the C data structures CLIPS
uses to represent information. For example, if you want to
retrieve a multifield value from the slot of a fact, you need to
get a pointer to the fact, request the slot value, and then
retrieve the information from the data structure CLIPS uses to
represent multiple fields each having its own type and value.
This communication is more difficult if you're embedding CLIPS in
another language. For example, Java doesn't support pointers in
the same method as C, so any bridge used to communicate with
CLIPS would first have to request the data and then create a copy
of the data usable by the requesting language.

Wrapping a GUI around CLIPS can require the use of user-defined
functions (section 3 of the Advanced Programming Guide), the APIs
for embedding CLIPS (section 4 of the APG), and the I/O router
system (section 7 of the APG).

First, determine whether your CLIPS program will be writing to
standard output using functions like printout or format (directed
to the logical name t) or reading from standard input (again from
the logical name t). If so, you'll need to create an I/O router
so that I/O requests from CLIPS can be directed to the window in
your GUI designd to process them. Presumably, if you're building
a GUI you're trying to move the user away from typing in a
response and replace it instead with a point and click action.
This is one place user-defined functions can be used to create a
GUI. Let's say you have a rule which asks the user to select a
color:

(defrule find-color
(phase pick-color $?available-colors)
=>
(bind ?color none)
(while (not (member$ ?color ?available-colors))
(printout t "Pick a bike color: ")
(bind ?color (read)))
(assert (bike-color ?color)))

Instead of having the user type in the name of the color, you
could create a user-defined function called select-color which
takes two arguments: a string to be used as a dialog box title
and a list of available colors. The select-color function would
then display a palette of colors allowing the user to click on
the color of their choice. The function would convert the
selected color to the symbolic name of the color, then return
this value as a CLIPS symbol. Your original rule could then be
rewritten as this:

(defrule find-color
(phase pick-color $?available-colors)
=>
(bind ?color
(select-color "Pick a bike color"
?available-colors))
(assert (bike-color ?color)))

Another consideration in building a GUI is whether CLIPS is run
in a "batch" mode or directly interacts with the GUI as the
program is running. By batch mode, I'm thinking of a scenario
where a user makes a number of choices, then clicks a button that
initiates CLIPS. The choices selected by the user are asserted as
facts and then CLIPS is allowed to run. When CLIPS finishes
running, the GUI can then query CLIPS for the results.

If CLIPS is run in a batch mode, then files can be used as a
simple method for passing information from CLIPS back to the GUI.
Suppose there are a group of coordinates that need to be plotted
on a graph after CLIPS finishes executing. CLIPS could open a
file and save the coordinates in the file as text. When CLIPS
finishes, just have the GUI open up the file and read in the
values.

5 7
8 9
2 8

Alternately, if you wanted to plot the points as they are found
by the rules, you could use a user-function to notify your GUI
that a point needs to be plotted:

(defrule plot-point
(point-found ?x ?y)
=>
(plot-point ?x ?y)) ; <- Your user-defined function

If you want to query CLIPS from C to retrieve the data, then the
fact query mechanism available in CLIPS 6.24, is probably the
best way to go about doing this:

DATA_OBJECT result;

Eval("(find-all-facts ((?f point-found)) TRUE)",&result);

The Eval function allows you to evaluate a command passed in as a
string argument and returns the result in the data structure
passed as another argument. In this case, the argument is a call
to the find-all-facts function which will return all of the
point-found facts present in the fact-list. Once retrieved, you'd
have to use other CLIPS API calls to decode the contents of the
response returned in the result variable.

On Jun 5, 12:20 pm, "camilo.caic...@gmail.com"

Rick Vinyard

unread,
Jun 9, 2007, 1:54:26 PM6/9/07
to CLIPSESG
And, for C++, there is clipsmm (http://clipsmm.sf.net). The project
has several example applications.

franzg

unread,
Jun 13, 2007, 6:12:15 PM6/13/07
to CLIPSESG
Hi Johan,

you say:

> My specific problem was/is that I have a collection of objects that
> are native to Python. I create, read, update and delete them in Python
> code, but I also want to have some reasoning capability, which I use
> Clips for. At some point in my (Python) program I want to be able to
> say run(), or fireAllRules(), or the equivalent, and have my Python
> objects manipulated by the rules defined in Clips (or actually,
> prefferably have my rules defined in Python as well).
>
> Unfortunately, there's no *automatic* way to make that happen. The
> Python objects don't live in Clips Working Memory unless I put them
> there, and there's no way of doing that without converting them to a
> number of string representations first. Both PyClips and JClips work
> this way (if the above is wrong, please let me know).

Ok, that's true. Actually, the easiest way to have a correspondence
between facts and Python object is probably via a dictionary. But
there is another possibility if you want to create _true_ Python
objects from the "CLIPS world" in PyCLIPS, that is registering
appropriate Python functions into CLIPS. The following is one of the
roughest possible examples:

===[CODE]===

# make an object in Python from CLIPS using PyCLIPS

import clips
CLIPS_OBJECTS = []

class A(object):
def __init__(self, name):
self.__name = name
def __str__(self):
return "Hi, I'm an A, named %s!" % self.__name
Name = property(lambda self: self.__name)

def make_A(s):
CLIPS_OBJECTS.append(A(s))

clips.RegisterPythonFunction(make_A)

r_start = clips.BuildRule(
"start",
"(initial-fact)",
"(assert (foo))",
)
r_start_SE = clips.BuildRule(
"start-SideEffect",
"(foo)",
"(python-call make_A triggered-by-foo)", # no effect in CLIPS
world!
)

clips.Reset()
clips.Run()

for x in CLIPS_OBJECTS:
print x

# end.

===[END CODE]===

The result looks like this:

>>>
Hi, I'm an A, named triggered-by-foo!
>>>

Of course, by means of introspection and other features of both CLIPS
and Python, you can write code that is more generic and useful. I'm
investigating the possibility to build a more pythonic layer on top of
PyCLIPS in order to achieve something similar to what you expect,
since I feel the same as you with this kind of interaction between the
two environments.

Cheers,

F.

Johan Lindberg

unread,
Jun 14, 2007, 3:01:56 PM6/14/07
to CLIP...@googlegroups.com
Hello Franz,

> Ok, that's true. Actually, the easiest way to have a correspondence
> between facts and Python object is probably via a dictionary. But
> there is another possibility if you want to create _true_ Python
> objects from the "CLIPS world" in PyCLIPS, that is registering
> appropriate Python functions into CLIPS.

Well, that's at least part of the solution, but I'd also like to
create _true_ CLIPS facts (and rules) from Python code.

> Of course, by means of introspection and other features of both CLIPS
> and Python, you can write code that is more generic and useful. I'm
> investigating the possibility to build a more pythonic layer on top of
> PyCLIPS in order to achieve something similar to what you expect,
> since I feel the same as you with this kind of interaction between the
> two environments.

Having a more pythonic abstraction layer on top of Clips would be very
useful indeed. Unfortunately I'm no good at C so I can't make it
happen myself but I'd be glad to help in any (other) way I can.

BR
Johan Lindberg
jo...@pulp.se

franzg

unread,
Jun 21, 2007, 3:58:45 PM6/21/07
to CLIPSESG
Hi Johan,

On Jun 14, 9:01 pm, "Johan Lindberg" <johan.h.lindb...@gmail.com>
wrote:

> Having a more pythonic abstraction layer on top of Clips would be very
> useful indeed. Unfortunately I'm no good at C so I can't make it
> happen myself but I'd be glad to help in any (other) way I can.

Sorry for taking so much time to reply, I was also wondering in fact
whether or not this is the best place to discuss about this topic - I
think, I'll open an entry in the PyCLIPS SF.net forum. However, in my
opinion, the layer should take advantage of the existing PyCLIPS
structure, and simply make it accessible from a different point of
view. So, probably, you could help a lot, being a Python coder!

Cheers,

F.

Reply all
Reply to author
Forward
0 new messages