【问题标题】:CLIPS processing data rows in file sequentiallyCLIPS 顺序处理文件中的数据行
【发布时间】:2021-03-01 09:46:37
【问题描述】:

我正在使用(模糊)CLIPS 6.31 版

我正在尝试为动态过程构建实时控制系统。该过程由多个电子设备监控,这些设备将数据写入文件。

我想从文件中读取数据,并根据数据做出决策。

我设想的工作流程如下:

  1. 读取嵌入领域知识的规则文件(rules.clp)
  2. 打开包含记录的测量数据的文件 (measurements.dat)
  3. 对于读取文件中的每一行:使用 defrule 调用自定义函数来处理行数据并根据行断言事实(如果条件匹配)。
  4. (运行)?我不确定run 是否可以多次调用?
  5. 进入下一行...(继续 EOF)然后关闭文件

如何使用 CLIPS 来执行此工作流程 - 无需人工干预?

【问题讨论】:

  • 您是否考虑过为此使用 CLIPS API?您可以使用兼容的编程语言来读取行并将它们作为事实断言到 CLIPS 中,而不是使用 CLIPS 逻辑读取文件。通过这种方式,您可以使用 CLIPS 规则来实现推理,而 IO 和其他相关事物则以命令式编程语言处理。
  • @noxdafox 你所描述的,正是我的目标。我的想法是重写 main.c 中的 main() 函数并从那里进行文件读取、事实断言等 - 但是,我还没有看到任何这样做的例子。有什么在线资源可以指导我吗?
  • Advanced Programming Guide 仍然是最好的参考资料。您还可以通过其语言绑定将 CLIPS 集成到其他编程语言中。您可以查看clipspyclipsgo。请记住,这些绑定针对的是 CLIPS 而不是 FuzzyCLIPS,因此您可能会遇到一些挑战。

标签: clips


【解决方案1】:

假设 rules.clp 包含以下内容:

(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))

而measurements.dat 包含以下内容:

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

您可以使用此代码重新定义 main 来处理数据:

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;
  }

此数据的输出将是:

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

您可以类似地完全在 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> 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-19
    • 2021-12-24
    • 1970-01-01
    • 1970-01-01
    • 2021-02-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多