- Table of Contents -

  1. What is the CLIPS DLL?
  2. How do I use the CLIPS DLL?
  3. How do I compile a program that uses the class wrappers?
  4. 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.

Go to Table of Contents


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 :

  1. I have rules and facts in one file
  2. I have rules in one file and facts in another file
  3. I have rules in one file, I need to assert facts from the program, and I am only interested in the output from stdout
  4. I have rules in one file and I want to use MS Access or Oracle or any ODBC data source
  5. I have a binary image CLIPS program that uses a non-standard router (i.e. (printout UserOut ....))
The programs use the following function to print a file :
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

I have rules in one file, I need to assert facts from the program, and I am only interested in the output from stdout

#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

Go to Table of Contents


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.

  1. Include the wrapper directly in your project.

    Under the Project menu item, select Add To Project | Files. Find and select Clipsmfc.cpp, make sure that dynclips.h and dynaload.h appear in your VC\Include directory. Also, make sure that the #include statement for Clipsmfc.h is coded properly.

  2. Build a wrapper library and include it in your project.

    Build the .lib file from Clipsmfc.cpp. Next, under the Project menu item, select Settings (or press Alt-F7), click the Link tab and under the heading Object/library modules include the name of the .lib file.

Last modified : 29-Jul-2003
Michael Giordano