Qt获取CLIPS的输出结果

3 篇文章 0 订阅
1 篇文章 0 订阅

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

是不是很通俗易懂?

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

来自星星的死心眼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值