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");
}
}
非常感谢Gary对您的一贯支持。你真好。 –