1. Introduction - Texas A&M University

advertisement
CLIPS Win32 DLL for Embedded Applications
Version 0.5
Xiangjun Xu
Texas A&M University
February 2, 2002
CLIPS Win32 DLL for Embedded Applications, Version 0.5
Table of Contents
1. INTRODUCTION .............................................................................................. 3
2. USAGE MANUAL FOR C++ ............................................................................ 3
2.1 Basic usage .............................................................................................................................................. 3
2.2 Loading constructs ................................................................................................................................. 4
2.3 Redirecting the output messages ........................................................................................................... 4
2.4 User function ........................................................................................................................................... 5
3. JAVA INTERFACE ........................................................................................... 7
4. DATABASE INTERFACE ................................................................................ 7
5. LIMITATIONS AND CAVEATS ........................................................................ 7
6. REFERENCE .................................................................................................... 7
Texas A&M University
2
CLIPS Win32 DLL for Embedded Applications, Version 0.5
CLIPS Win32 DLL for Embedded Applications
1. Introduction
There are applications requiring interfacing with expert systems. One approach to achieve
this is through external files. The applications write facts and rules into disk files and the
users are supposed to invoke the expert system shells and open the save files to start the
reasoning process. The outputs of the expert system shells are also saved as files for the
applications to read back.
As we can see, the whole process may confuse the end users. A better solution is to
embed an expert system in the application. In this way, the application can pass the facts
and rules to the embedded engine directly. User interference is no longer needed. This
type of expert systems is called embedded applications.
This report is about such an effort. The CLIPS [1] expert system has been encapsulated as
a Win32 C++ DLL, which greatly simplifies the development of embedded expert
systems.
There are already two CLIPS DLL available. One is from the CMU AI repository [2].
But it is a Win16 DLL for Windows 3.1 and the CLIPS used is the old 5.x version.
Another CLIPS6.10 DLL [3] doesn’t provide the source codes, not even the header files,
which hinders its use. Also its quality is pretty bad; many protection errors and memory
leak problems have been encountered.
The Java version CLIPS – Jess [4] is still not supporting all the functionality of CLIPS.
For example, in Jess Ver5.1, the conditional element “or” is not yet supported (new
versions, such Ver6.0 may have added more functions). Also, Unlike CLIPS, its license is
free for non-commercial use only.
These are the reasons I decided to create our own CLIPS DLL. The DLL has been
compiled using Visual C++ 6.0. Other C++ compilers (e.g. GNU C++, Borland C++)
should also work.
Note: this new version CLIPS DLL is based on the recently release CLIPS 6.20 Beta
source codes.
2. Usage Manual for C++
2.1 Basic usage
The usage of the DLL is very simple. The following code segment shows a typical
usage:
#include "ClipsEng.h"
Texas A&M University
3
CLIPS Win32 DLL for Embedded Applications, Version 0.5
try {
CLIPSEngine eng;
eng.load("test.clp"); // load constructs
eng.reset(); // assert constructs
eng.run();
} catch (CLIPSException *ex) {
printf(“Error: %s\n”, ex->why());
delete ex;
}
First, the program creates a CLIPSEngine object, which represents the embedded
inference engine will be used in the application. Then it read in the constructs defined in
a rule file. Finally, it will start the inference engine.
The CLIPSException object encapsulates all the possible errors happened in the engine.
2.2 Loading constructs
Both the rules and the facts can be passed to the engine via files or commands. The
CLIPS function (load filename) will read in constructs from a file. For example, the
following command will open myes.clp file and load all the constructs in it.
eng.execCommand(“(load \“myes.clp\”)”);
To batch executing a command file, i.e. opening a file and executing every command
inside it, please use the eng.batch() method. execCommand("(batch)") will not work
unless you are not in a command loop. The CLIPS function (batch filename) depends on
the command loop to work.
Also, the application developer can define the rules and the facts using CLIPS
commands. For example:
eng.execCommand(“(defrule rule1 (break-time 100) => (assert (breaker
failure) ))”);
eng.execCommand(“(deffacts fact1 (breaker STP 220) )”);
2.3 Redirecting the output messages
The user can specify the output stream of the CLIPS engine. After that, all the output will
be redirected to the specified stream. Usually only the print function will be customized:
eng.addRouter("output1", MyQueryFunction, MyPrintFunction);
And your query and print functions are:
int MyQueryFunction(void* env, char* logicalname)
{
if(strcmp(logicalname, "output1") == 0))
Texas A&M University
4
CLIPS Win32 DLL for Embedded Applications, Version 0.5
return 1; // only handle "output1"
return 0;
}
int MyPrintFunction(void* env, char* logicalname, char* buffer)
{
// TODO: write out the info in buffer
}
In the above example, a new print function is provided for "output1". For example, in
CLIPS rules, you can write:
(printout output1 "my message" crlf);
And the text will be passed to your own print function (MyPrintFunction in this case).
To embed the CLIPS DLL in a Windows application, it is better to redirect all the
inputs/outputs to some Windows Common Controls such as Edit or RichEdit. By
implementing a specific MyPrintFucntion, this can be easily accomplished. For example:
int MyPrintFunction(void* env, char* logicalname, char* buffer)
{
// TODO: write out the info in buffer
m_edit.SetWindowText(buffer);
}
In general your application should already have a message loop if it is a GUI application.
Otherwise, you should implement RunEventFunction to provide the necessary message
loop. For more information, please see [5].
2.4 User function
The user can define external functions that will be called by CLIPS, which provides a
kind of "callback" mechanism. For example, sometimes, we may want to be notified
when certain rules fired. To achieve this, we can implement some user functions and call
those user functions in the consequent parts of the rules.
// In your C++ application
// step #1
int MyFunc1(void* env); // function declaration
// step #2
eng.defineFunc("myfunc1",'i', MyFunc1, "MyFunc1"); //see [5] ch3
// step #3
// implementation, this function will be called by CLIPS
int MyFunc1(void* env)
{
// do something interesting here
Texas A&M University
5
CLIPS Win32 DLL for Embedded Applications, Version 0.5
return 1;
}
And in your rule:
; step #4
; In your CLIPS rule file
(defrule r1 () … => (myfunc1) …)
When the rule fires, MyFunc1 will be called.
The engine member function defineFunc simply calls DefineFunction, whose function
prototype is:
DefineFunction(void* env, char* clips_funcname, char rettype, int (*pfunc)(void), char*
actual_funcname) :
Where rettype is (excerpted from [5]):
a - External Address
b - Boolean
c - Character
d - Double Precision Float
f - Single Precision Float
i - Integer
j - Unknown Data Type (Symbol, String, or Instance Name Expected)
k - Unknown Data Type (Symbol or String Expected)
l - Long Integer
m - Multifield
n - Unknown Data Type (Integer or Float Expected)
o - Instance Name
s - String
u - Unknown Data Type (Any Type Expected)
v - Void—No Return Value
w - Symbol
x - Instance Address
Compared with DefineFunction, DefineFunction2 provides more strict description of the
external functions, whose function prototype is:
DefineFunction2(void* env, char* clips_funcname, char rettype, int (*pfunc)(void), char*
actual_funcname, char* func_restriction)
The format of func_restriction is: <min-args> <max-args> [<default-type> <types>*],
e.g. "3*", "*5", "35n", "66fsui"
For more information, e.g. passing arguments etc., please consult Chapter 3 of [5].
Texas A&M University
6
CLIPS Win32 DLL for Embedded Applications, Version 0.5
3. Java Interface
The Java interface will enable Java application to utilize the CLIPS DLL …
4. Database Interface
Database tables can be easily mapped to unordered facts. The name of the table will be
the fact name, while the columns form the templates.
The database interface requires ODBC to work.
5. Limitations and Caveats
Some limitations of the previous version CLIPS DLL have been eliminated. The new
version is based on CLIPS 6.20 Beta, while the previous one is on CLIPS 6.10. The new
version CLIPS has introduced a new concept "environment", so multiple instances of
CLIPS Engine can be created. Also, the memory leak problem has been fixed.
But the following usage is still recommended for better performance:
 Declare a CLIPSEngine as a global object, for example:
CLIPSEngine* g_pEngine;

Initialize the CLIPSEngine object in InitInstance(), for example:
g_pEngine = new CLIPSEngine();

Delete the CLIPSEngine object in ExitInstance(), for example:
delete g_pEngine;
The DLL is only accessible from a single thread.
6. Reference
[1] CLIPS website, http://www.ghg.net/clips/CLIPS.html
[2] CLIPS5 DLL at CMU AI Repository, http://www-2.cs.cmu.edu/afs/cs/project/airepository/ai/areas/expert/systems/clips/contrib/clipsdll/v2/
[3] CLIPS6.1 DLL, http://ourworld.compuserve.com/homepages/marktoml/clipstuf.htm
[4] Jess website, http://herzberg.ca.sandia.gov/jess
[5] CLIPS Reference Manual Vol. II, Advanced Programming Guide Ver 6.10, 1998
[6] ODBC interface for CLIPS, http://www.monmouth.com/~km2580/CLIPODBC.htm
Texas A&M University
7
Download