Qt获取CLIPS的输出结果
CLIPS在专家系统开发的应用十分广泛,基于C语言开发的CLIPS很容易嵌入到各种开发环境中,当然也包括C++。然而,CLIPS包含了一个关键字“slots”,这就与qt的关键字“slots”发生了冲突,所以,直接利用网上流传的各种编译好的CLIPS.dll都没办法将CLIPS与Qt结合起来,于是我想到了一个直接暴力的方法——将CLIPS源码中所有单独出现的“slots”改成别的字符(如:Qslots、Cslots等与源码中slots不一样的字符)就可以了,这样一来,不管CLIPS的开发者想要利用原本的“slots”来做什么,我们都可以利用我们重新定义的字符来代替。这样就解决了很多朋友在利用Qt编译CLIPS时候遇到的一大困难,在这里就不展开讲述了。
本文需要解决的问题是,如何将CLIPS中产生的Fact输出到我们想要的任何一个地方?
tips:不想看我推导过程的朋友,可以直接跳转文末看总结。
首先,CLIPS本身提供了一个printout()函数来打印专家系统的slot value,我们先来看看这个函数的形式。
(printout t "待打印的内容" crlf)
待打印的内容输出位置由参数t来给出,通常就是输出到内存窗口里面,如下图所示:

那么除此之外,我们还有别的函数可以打印CLIPS中的Fact吗?当然是有的,基于C语言开发的CLIPS,在源码中多次出现fprintf()函数。我们还有EnvPrintRouter()函数可以做到,根据CLIPS文档的高级版,我们可以查看一些这个函数的基本情况。
int EnvPrintRouter(environment,logicalName,str)
void *environment;
const char *logicalName;
const char *str;
这个函数的基本功能就是把environment中的str打印到logicalName,嗯,,,好像和printout的输出没什么区别。
不过不用担心,我们还有例子呢。。。这个例子的功能很简单,是CLIPS开发者Gary Rirley在帮助一个外国小伙伴关于CLIPS判断语句时给出的对比结果,在这里用到EnvPrintRouter()函数,正好被我看到了,这就直接帖上他的代码过来,在这个例子中,我们可以看到Gary Rirley用到了一下两句话来实现了两次打印,相信有的朋友已经发现了猫腻,一是这个函数给的logicalName是STDOUT (源码定义的stdout),二是这个函数直接将第三个参数打印出来了。注意第一次打印的时候,内容是DOToString(theValue)。结合之前的EnvGetFactSlot()函数,我们可以得知,CLIPS将Fact存入了开头定义的
DATA_OBJECT theValue变量中。
因此,我们只需要将theValue转换成我们C++的常规数据类型就可以进行输出调用了。
以下代码的出处为 http://qaru.site/questions/13797825/clips-getting-facts-of-a-specific-template-from-fact-list
int main(){void *theEnv;void *theFact;void *templatePtr;DATA_OBJECT theValue;theEnv = CreateEnvironment();EnvBuild(theEnv,"(deftemplate Student (slot Name))");EnvBuild(theEnv,"(deftemplate Teacher (slot Name))");EnvAssertString(theEnv,"(Student (Name \"John Brown\"))");EnvAssertString(theEnv,"(Teacher (Name \"Susan Smith\"))");EnvAssertString(theEnv,"(Student (Name \"Sally Green\"))");EnvAssertString(theEnv,"(Teacher (Name \"Jack Jones\"))");templatePtr = EnvFindDeftemplate(theEnv,"Student");for (theFact = EnvGetNextFact(theEnv,NULL);theFact != NULL;theFact = EnvGetNextFact(theEnv,theFact)){if (EnvFactDeftemplate(theEnv,theFact) != templatePtr) continue;EnvGetFactSlot(theEnv,theFact,"Name",&theValue);EnvPrintRouter(theEnv,STDOUT,DOToString(theValue));EnvPrintRouter(theEnv,STDOUT,"\n");}EnvPrintRouter(theEnv,STDOUT,"-------------\n");for (theFact = EnvGetNextFactInTemplate(theEnv,templatePtr,NULL);theFact != NULL;theFact = EnvGetNextFactInTemplate(theEnv,templatePtr,theFact)){EnvGetFactSlot(theEnv,theFact,"Name",&theValue);EnvPrintRouter(theEnv,STDOUT,DOToString(theValue));EnvPrintRouter(theEnv,STDOUT,"\n");}}
总结:CLIPS将Fact存入了 DATA_OBJECT 中,我们想要获取CLIPS产生的Fact,只需要从DATA_OBJECT theValue里面取就可以了。至于则么取的问题,请看接下来这行代码:
QString my = DOToString(theValue);
是不是很通俗易懂?
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
