CLIPS 顺序处理文件中的数据行
CLIPS processing data rows in file sequentially
我正在使用(模糊)CLIPS 版本 6.31
我正在尝试为动态过程构建一个实时控制系统。该过程由多个电子设备监控,这些设备将数据写入文件。
我想从文件中读取数据,并根据数据做决定。
我设想的工作流程如下:
- 阅读嵌入领域知识的规则文件(rules.clp)
- 打开包含记录的测量数据的文件(measurements.dat)
- 对于读取文件中的每一行:使用
defrule
调用自定义函数来处理行数据并根据行断言事实(如果条件匹配)。
- (运行)?我不确定
run
是否可以多次调用?
- 继续下一行...(继续到 EOF)然后关闭文件
如何使用 CLIPS 执行此工作流程 - 无需人工干预?
假设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>
我正在使用(模糊)CLIPS 版本 6.31
我正在尝试为动态过程构建一个实时控制系统。该过程由多个电子设备监控,这些设备将数据写入文件。
我想从文件中读取数据,并根据数据做决定。
我设想的工作流程如下:
- 阅读嵌入领域知识的规则文件(rules.clp)
- 打开包含记录的测量数据的文件(measurements.dat)
- 对于读取文件中的每一行:使用
defrule
调用自定义函数来处理行数据并根据行断言事实(如果条件匹配)。 - (运行)?我不确定
run
是否可以多次调用? - 继续下一行...(继续到 EOF)然后关闭文件
如何使用 CLIPS 执行此工作流程 - 无需人工干预?
假设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>