How to use the CLIPS DLL
- Table of Contents -
- What is the CLIPS DLL?
- How do I use the CLIPS DLL?
- How do I compile a program that uses the class wrappers?
- How can I write User-Defined Functions using AppWizard?
What is the CLIPS DLL?
The CLIPS DLL encapsulates the core CLIPS actions like Load, Reset and Run and allow a developer to embed CLIPS into a C++ program. There are class wrappers available that expose the CLIPS functions in class members.How do I use the CLIPS DLL?
The most frequently asked question concerning the CLIPS DLL is :"How do I pass information back and forth to CLIPS?"
The best way to answer this question is to show some simple (console
mode) programs.
The examples given below use the MFC version of the class wrappers and are
coded in C++. The other versions of the class wrappers expose much of the same
interface.
Example programs :
- I have rules and facts in one file
- I have rules in one file and facts in another file
-
I have rules in one file, I need to assert facts from the
program, and I am only interested in the output from
stdout
- I have rules in one file and I want to use MS Access or Oracle or any ODBC data source
-
I have a binary image CLIPS program that uses a
non-standard router (i.e.
(printout UserOut ....)
)
int PrintCLIPSOutput(const char *szOutFile) { FILE *fp; long lFileSize, lNumBytesRead; char *buf; //Open the file if((fp = fopen(szOutFile, "r+b")) == NULL) { fprintf(stderr, "\nFile %s could not be opened\n", szOutFile); return(-1); } //Set the file pointer to the end fseek(fp, 0L, SEEK_END); //Get the file size lFileSize = ftell(fp); //Set the pointer back to the beginning fseek(fp, 0L, SEEK_SET); //Allocate a buffer for the file buf = NULL; buf = (char *)malloc(lFileSize + 1); if(!buf) { fprintf(stderr, "Buffer Allocation failed\n"); return(-1); } buf[lFileSize] = '\0'; //Terminating NULL //Read the file lNumBytesRead = fread(buf, sizeof(char), lFileSize, fp); if(lNumBytesRead != lFileSize) { fprintf(stderr, "Unable to read file %s\n", szOutFile); free(buf); return(-1); } //Close the file fclose(fp); //Print the output and free memory printf("%s\n", buf); free(buf); return(0); }
I have rules and facts in one file
#include <stdio.h> #include "c:\clips\wrapper\clipsmfc.h" int main(int argc, char *argv[]) { //Create an instance of CLIPS CCLIPSWrap CLIPSEng(1); CString strCLIPSScript, strOutFile = "clpdrb.txt"; int iErrCode, i; //Initialize the CLIPS Engine -- DLL Loaded here! //If Initialization fails, display a message. if(!CLIPSEng.CLIPSInit()) { printf("CLIPS failed during initialization.\n"); printf("Make sure that the CLIPS DLL is somewhere in your PATH\n"); return(0); } //Load the CLIPS script(facts/rules etc.) //If Load fails, display message. strCLIPSScript = "c:\\CLIPS\\program.clp"; iErrCode = CLIPSEng.CLIPSLoad(strCLIPSScript); if(iErrCode != CCLIPSWrap::READ_OK) { printf("CLIPS failed while loading the script %s\n", LPCSTR(strCLIPSScript)); switch (iErrCode) { case CCLIPSWrap::READ_FAIL : printf("Read Failure\n"); break; case CCLIPSWrap::PARSE_FAIL : printf("Parse Failure\n"); break; case CCLIPSWrap::BAD_LOAD_NAME : printf("Bad Load Name\n"); break; case CCLIPSWrap::READ_NOT_INIT : printf("CLIPS Not Initialized\n"); } CLIPSEng.CLIPSExit(0); return(0); } //Issue CLIPS 'reset' Command CLIPSEng.CLIPSReset(); //Dribble the output to a file to be displayed later CLIPSEng.CLIPSDribble(strOutFile, TRUE); //Run the CLIPS Engine CLIPSEng.CLIPSRun(); //Close dribble output CLIPSEng.CLIPSDribble(strOutFile, FALSE); //Print the output if(PrintCLIPSOutput(LPCSTR(strOutFile)) != 0) printf("Error occurred on file output!\n"); //Exit CLIPS CLIPSEng.CLIPSExit(0); return(0); }Back to Examples List
I have rules in one file and facts in another file
#include <stdio.h> #include "c:\clips\wrapper\clipsmfc.h" int main(int argc, char *argv[]) { //Create an instance of CLIPS CCLIPSWrap CLIPSEng(1); CString strCLIPSScript, strOutFile = "clpdrb.txt"; CString strFactsFile; int iErrCode, i; //Initialize the CLIPS Engine -- DLL Loaded here! //If Initialization fails, display a message. if(!CLIPSEng.CLIPSInit()) { printf("CLIPS failed during initialization.\n"); printf("Make sure that the CLIPS DLL is somewhere in your PATH\n"); return(0); } //Load the CLIPS script (rules) //If Load fails, display message. strCLIPSScript = "c:\\CLIPS\\program.clp"; iErrCode = CLIPSEng.CLIPSLoad(strCLIPSScript); if(iErrCode != CCLIPSWrap::READ_OK) { printf("CLIPS failed while loading the script %s\n", LPCSTR(strCLIPSScript)); switch (iErrCode) { case CCLIPSWrap::READ_FAIL : printf("Read Failure\n"); break; case CCLIPSWrap::PARSE_FAIL : printf("Parse Failure\n"); break; case CCLIPSWrap::BAD_LOAD_NAME : printf("Bad Load Name\n"); break; case CCLIPSWrap::READ_NOT_INIT : printf("CLIPS Not Initialized\n"); } CLIPSEng.CLIPSExit(0); return(0); } //Issue CLIPS 'reset' Command CLIPSEng.CLIPSReset(); //Load the facts //If Load fails, display message. strFactsFile = "c:\\CLIPS\\facts1.clp"; iErrCode = CLIPSEng.CLIPSLoadFacts(strFactsFile); if(iErrCode != CCLIPSWrap::READ_OK) { printf("CLIPS failed while loading the script %s\n", LPCSTR(strCLIPSScript)); switch (iErrCode) { case CCLIPSWrap::READ_FAIL : printf("Read Failure\n"); break; case CCLIPSWrap::BAD_LOAD_NAME : printf("Bad Load Name\n"); break; } CLIPSEng.CLIPSExit(0); return(0); } //Dribble the output to a file to be displayed later CLIPSEng.CLIPSDribble(strOutFile, TRUE); //Run the CLIPS Engine CLIPSEng.CLIPSRun(); //Close dribble output CLIPSEng.CLIPSDribble(strOutFile, FALSE); //Print the output if(PrintCLIPSOutput(LPCSTR(strOutFile)) != 0) printf("Error occurred on file output!\n"); //Exit CLIPS CLIPSEng.CLIPSExit(0); return(0); }Back to Examples List
#include <stdio.h> #include "c:\clips\wrapper\clipsmfc.h" int main(int argc, char *argv[]) { //Create an instance of CLIPS CCLIPSWrap CLIPSEng(1); CString strCLIPSScript, strOutFile = "clpdrb.txt"; CString strFact, strStdout = "stdout"; int iErrCode, i; //Initialize the CLIPS Engine -- DLL Loaded here! //If Initialization fails, display a message. if(!CLIPSEng.CLIPSInit()) { printf("CLIPS failed during initialization.\n"); printf("Make sure that the CLIPS DLL is somewhere in your PATH\n"); return(0); } //Load the CLIPS script (rules) //If Load fails, display message. strCLIPSScript = "c:\\CLIPS\\program.clp"; iErrCode = CLIPSEng.CLIPSLoad(strCLIPSScript); if(iErrCode != CCLIPSWrap::READ_OK) { printf("CLIPS failed while loading the script %s\n", LPCSTR(strCLIPSScript)); switch (iErrCode) { case CCLIPSWrap::READ_FAIL : printf("Read Failure\n"); break; case CCLIPSWrap::PARSE_FAIL : printf("Parse Failure\n"); break; case CCLIPSWrap::BAD_LOAD_NAME : printf("Bad Load Name\n"); break; case CCLIPSWrap::READ_NOT_INIT : printf("CLIPS Not Initialized\n"); } CLIPSEng.CLIPSExit(0); return(0); } //Issue CLIPS 'reset' Command CLIPSEng.CLIPSReset(); //Assumes a deftemplate exists in program.clp // (deftemplate Person (slot Name) (slot Age)) strFact = "(Person (Name Joe) (Age 22))" if(CLIPSEng.CLIPSAssert(strFact) == FALSE) { printf("An error occured while asserting a fact\n"); return(0); } strFact = "(Person (Name Jane) (Age 20))" if(CLIPSEng.CLIPSAssert(strFact) == FALSE) { printf("An error occured while asserting a fact\n"); return(0); } //Redirect the output from stdout to a file CLIPSEng.SetRouteFile(strStdout, strOutFile); //Run the CLIPS Engine CLIPSEng.CLIPSRun(); //Print the output if(PrintCLIPSOutput(LPCSTR(strOutFile)) != 0) printf("Error occurred on file output!\n"); //Exit CLIPS CLIPSEng.CLIPSExit(0); return(0); }Back to Examples List
I have rules in one file and I want to use MS Access or Oracle or any ODBC data source
There is more information about the CLIPS/ODBC interface here
#include <stdio.h> #include "c:\clips\wrapper\clipsmfc.h" int main(int argc, char *argv[]) { //Create an instance of CLIPS CCLIPSWrap CLIPSEng(1); CString strCLIPSScript, strOutFile = "clpdrb.txt"; int iErrCode, i; CString strODBCInfo, strDeftemplateName, strQuery, strODBCError; strODBCInfo = "DSN=CLIPSODBC;"; strCLIPSScript = "c:\\clips\\example\\relation.clp"; //Initialize the CLIPS Engine -- DLL Loaded here! //If Initialization fails, display a message. if(!CLIPSEng.CLIPSInit()) { printf("CLIPS failed during initialization.\n"); printf("Make sure that the CLIPS DLL is somewhere in your PATH\n"); return(0); } //Load the CLIPS script (rules) //If Load fails, display message. iErrCode = CLIPSEng.CLIPSLoad(strCLIPSScript); if(iErrCode != CCLIPSWrap::READ_OK) { printf("CLIPS failed while loading the script %s\n", LPCSTR(strCLIPSScript)); switch (iErrCode) { case CCLIPSWrap::READ_FAIL : printf("Read Failure\n"); break; case CCLIPSWrap::PARSE_FAIL : printf("Parse Failure\n"); break; case CCLIPSWrap::BAD_LOAD_NAME : printf("Bad Load Name\n"); break; case CCLIPSWrap::READ_NOT_INIT : printf("CLIPS Not Initialized\n"); } CLIPSEng.CLIPSExit(0); return(0); } //Issue CLIPS 'reset' Command CLIPSEng.CLIPSReset(); // -- Execute any ODBC Queries -- // //Assert 'father-of' facts strDeftemplateName = "father-of"; strQuery = "SELECT father, child FROM FATHEROF"; if(!CLIPSEng.CLIPSODBCQuery( strQuery, strODBCInfo, strDeftemplateName, TRUE, strODBCError)) { printf("ODBC Error %s\n", LPCSTR(strODBCError)); return(0); } //Assert 'mother-of' facts strDeftemplateName = "mother-of"; strQuery = "SELECT mother, child FROM MOTHEROF"; if(!CLIPSEng.CLIPSODBCQuery( strQuery, strODBCInfo, strDeftemplateName, TRUE, strODBCError)) { printf("ODBC Error %s\n", LPCSTR(strODBCError)); return(0); } //Assert 'wife-of' facts, husband of automatic strDeftemplateName = "wife-of"; strQuery = "SELECT wife, husband FROM WIFEOF"; if(!CLIPSEng.CLIPSODBCQuery( strQuery, strODBCInfo, strDeftemplateName, TRUE, strODBCError)) { printf("ODBC Error %s\n", LPCSTR(strODBCError)); return(0); } //Assert 'male' facts strDeftemplateName = "male"; strQuery = "SELECT person FROM male"; if(!CLIPSEng.CLIPSODBCQuery( strQuery, strODBCInfo, strDeftemplateName, TRUE, strODBCError)) { printf("ODBC Error %s\n", LPCSTR(strODBCError)); return(0); } //Assert 'female' facts strDeftemplateName = "female"; strQuery = "SELECT person FROM female"; if(!CLIPSEng.CLIPSODBCQuery( strQuery, strODBCInfo, strDeftemplateName, TRUE, strODBCError)) { printf("ODBC Error %s\n", LPCSTR(strODBCError)); return(0); } //Dribble the output to a file to be displayed later CLIPSEng.CLIPSDribble(strOutFile, TRUE); //Run the CLIPS Engine CLIPSEng.CLIPSRun(); //Close dribble output CLIPSEng.CLIPSDribble(strOutFile, FALSE); //Print the output if(PrintCLIPSOutput(LPCSTR(strOutFile)) != 0) printf("Error occurred on file output!\n"); //Exit CLIPS CLIPSEng.CLIPSExit(0); return(0); }Back to Examples List
I have a binary image CLIPS program that uses a
non-standard router (i.e. (printout UserOut ....)
)
#include <stdio.h> #include <iostream.h> #include "c:\clips\wrapper\clipsmfc.h" int main(int argc, char *argv[]) { //Create an instance of CLIPS CCLIPSWrap CLIPSEng(1); CString strCLIPSScript, strOutFile = "clpdrb.txt"; int iErrCode, i; CStringArray RouterOutput; //Initialize the CLIPS Engine -- DLL Loaded here! //If Initialization fails, display a message. if(!CLIPSEng.CLIPSInit()) { printf("CLIPS failed during initialization.n"); printf("Make sure that the CLIPS DLL is somewhere in your PATH\n"); return(0); } //Load the CLIPS script(facts/rules etc.) //If Load fails, display message. strCLIPSScript = "c:\\CLIPS\\program.bin"; iErrCode = CLIPSEng.CLIPSBLoad(strCLIPSScript); if(iErrCode != CCLIPSWrap::READ_OK) { printf("CLIPS failed while Bloading the script %s\n", LPCSTR(strCLIPSScript)); switch (iErrCode) { case CCLIPSWrap::READ_FAIL : printf("Read Failure\n"); break; case CCLIPSWrap::BAD_LOAD_NAME : printf("Bad Load Name\n"); break; case CCLIPSWrap::READ_NOT_INIT : printf("CLIPS Not Initialized\n"); } CLIPSEng.CLIPSExit(0); return(0); } //Issue CLIPS 'reset' Command CLIPSEng.CLIPSReset(); //Dribble the output to a file to be displayed later CLIPSEng.CLIPSDribble(strOutFile, TRUE); //Add the new router CString strUserRouterName = "UserOut"; CLIPSEng.AddUserRouter(strUserRouterName, &RouterOutput); //Run the CLIPS Engine CLIPSEng.CLIPSRun(); //Close dribble output CLIPSEng.CLIPSDribble(strOutFile, FALSE); //Print the dribble output if(PrintCLIPSOutput(LPCSTR(strOutFile)) != 0) printf("Error occurred on file output!\n"); //Print the output from UserOut router for(i = 0; i < RouterOutput.GetSize(); i++) { cout << RouterOutput[i]; } //Exit CLIPS CLIPSEng.CLIPSExit(0); return(0); }Back to Examples List
How do I compile a program that uses the
class wrappers?
The instructions given here pertain to Microsoft's Developer Studio.
Properly linking a CLIPS program requires the use of Multithreaded libraries.
While working on a project, go to the Project
menu item,
select Settings
(or press Alt-F7
), click the
C/C++
tab. Under the heading of Category
select
the Code Generation
option. Under the heading of Use run-time library
select Debug Multithreaded
for Debug builds or Multithreaded
for Release builds.
There are two ways to use the class wrappers.
-
Include the wrapper directly in your project.
Under the
Project
menu item, selectAdd To Project | Files
. Find and selectClipsmfc.cpp
, make sure thatdynclips.h
anddynaload.h
appear in yourVC\Include
directory. Also, make sure that the#include
statement forClipsmfc.h
is coded properly. -
Build a wrapper library and include it in your project.
Build the
.lib
file fromClipsmfc.cpp
. Next, under theProject
menu item, selectSettings
(or pressAlt-F7
), click theLink
tab and under the headingObject/library modules
include the name of the.lib
file.
Michael Giordano