CLIPS - how to process data sequentially from a file

72 views
Skip to first unread message

Pointer2VoidStar

unread,
Mar 1, 2021, 4:09:27 PM3/1/21
to CLIPSESG

I am using (Fuzzy)CLIPS ver 6.31

I am trying to build a real time control system for a dynamic process. The process is being monitored by several electronic devices, which write the data to file.

I want to read the data from the file, and make decisions based on the data.

The workflow I envisage, is as follows:

  1. Read the rules file that embeds the domain knowledge (rules.clp)
  2. Open the file containing the recorded measurement data (measurements.dat)
  3. For each row in the read file: use a defrule calling a custom function to process row data and assert fact based on row (if criteria matched).
  4. (Run)? I'm not sure if run can be called more than once?
  5. Proceed to next row ... (continue to EOF) then close file

How can I use CLIPS to carry out this workflow - which requires no manual intervention?

CLIPS Support

unread,
Mar 1, 2021, 4:12:49 PM3/1/21
to CLIPSESG

Suppose rules.clp contains this content:

(deftemplate points 
   (slot x1)
   (slot y1)
   (slot x2)
   (slot y2))
   
(defrule print-length
   (points (x1 ?x1)
           (y1 ?y1)
           (x2 ?x2)
           (y2 ?y2))
   =>
   (bind ?length (sqrt (+  (** (- ?x2 ?x1) 2)
                           (** (- ?y2 ?y1) 2))))
   (printout t "Length is " ?length crlf))
   
And measurements.dat contains this content:

3 4 0 0
8 3 -3 2
9 4 1 0
0 8 0 2

You can redefine main with this code to process the data:

int main(
  int argc,
  char *argv[])
  {
   void *theEnv;
   FILE *theFile;
   int x1, y1, x2, y2;
   char buffer[256];
   int rv;

   theEnv = CreateEnvironment();

   EnvLoad(theEnv,"rules.clp");
   
   theFile = fopen("measurements.dat","r");
   
   if (theFile == NULL) return -1;
   
   while (fscanf(theFile,"%d %d %d %d",&x1,&y1,&x2,&y2) == 4)
     {
      sprintf(buffer,"(points (x1 %d) (y1 %d) (x2 %d) (y2 %d))",x1,y1,x2,y2);
      EnvAssertString(theEnv,buffer);
      EnvRun(theEnv,-1);
     }
    
   fclose(theFile);
         
   return 0;
  }
  
The output from this data will be:

Length is 5.0
Length is 11.0453610171873
Length is 8.94427190999916
Length is 6.0

You can similarly process the data totally within CLIPS:

         CLIPS (6.31 6/12/19)
CLIPS> (load rules.clp)
Defining deftemplate: points
Defining defrule: print-length +j+j
TRUE
CLIPS> 
(defrule open-file
   =>
   (assert (input (open "measurements.dat" input "r"))))
CLIPS> 
(defrule get-data
   (declare (salience -10))
   ?f <- (input TRUE)
   =>
   (retract ?f)
   (bind ?line (readline input))
   (if (eq ?line EOF)
      then
      (close input)
      else
      (bind ?points (explode$ ?line))
      (assert (points (x1 (nth$ 1 ?points))
                      (y1 (nth$ 2 ?points))
                      (x2 (nth$ 3 ?points))
                      (y2 (nth$ 4 ?points))))
      (assert (input TRUE))))
CLIPS> (run)
Length is 5.0
Length is 11.0453610171873
Length is 8.94427190999916
Length is 6.0
CLIPS> 
Reply all
Reply to author
Forward
0 new messages