Клипы — получение фактов определенного шаблона из списка фактов

У меня есть шаблоны как (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), В чем проблема?

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

Другие решения

Других решений пока нет …