У меня есть шаблоны как (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)
, В чем проблема?
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");
}
}
Других решений пока нет …