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

问题描述:

我有像(Student (Name x) (Age y))这样的模板。我可以检查一个使用以下命名Name插槽的所有事实得到Name值:CLIPS - 从事实列表中获取特定模板的事实

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)。哪里有问题?

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

非常感谢Gary对您的一贯支持。你真好。 –