CLIPS - 从事实列表中获取特定模板的事实

时间:2017-05-29 23:30:37

标签: c++ clips expert-system

我有像(Student (Name x) (Age y))这样的模板。我可以通过使用以下内容检查名为Name的广告位的所有事实来获取Name的值:

EnvGetFactList(theEnv, &factlist, NULL);
if (GetType(factlist) == MULTIFIELD)
{
    end = GetDOEnd(factlist);
    multifieldPtr = GetValue(factlist);
    for (i = GetDOBegin(factlist); i <= end; i++)
    {
        EnvGetFactSlot(theEnv,GetMFValue(multifieldPtr, i),"Name",&theValue);
        buf = DOToString(theValue);
        printf("%s\n", buf);
    }
}

我想检查这个事实是否属于Student类型。如果是,请获取Name插槽的值。 我想我应该使用EnvFactDeftemplate,但我无法让它发挥作用。这是我的代码

templatePtr = EnvFindDeftemplate(theEnv, "Student");
templatePtr = EnvFactDeftemplate(theEnv,templatePtr);
EnvGetFactSlot(theEnv,&templatePtr,"Name",&theValue);

但我得到以下运行时错误:Segmentation fault (core dumped)。问题在哪里?

1 个答案:

答案 0 :(得分:0)

EnvGetFactSlot期望指向事实的指针,而不是指向deftemplate的指针。使用EnvGetNextFact函数之一而不是EnvGetFactList来迭代事实也更容易。这是一个有效的例子:

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