Почему эта пролог-программа вызывает бесконечную рекурсию? - PullRequest
3 голосов
/ 21 октября 2011

Я пытаюсь сделать простую базу знаний. Однако я изо всех сил пытаюсь заставить работать систему категорий.

Вот программа на данный момент:

subset(tomatoes, fruits).
subset(fruits, food).
subset(X, Z) :- subset(X, Y), subset(Y, Z), not(X==Y), not(Y==Z), not(X==Z).
member(X, Z) :- member(X, Y), subset(Y, Z).
member(t1, tomatoes).

Запрос:

member(t1,tomatoes).
ERROR: Out of local stack
   Exception: (1,765,494) member(t1, _G28504) ? abort
% Execution Aborted

1 Ответ

4 голосов
/ 21 октября 2011

Вы столкнулись с явлением левая рекурсия . Решение цели subset(X, Z) сводится к решению цели subset(X, Y) с новой несвязанной переменной Y, и это приводит к решению той же цели subset(X, Z) и т. Д. До бесконечности. Левых рекурсий следует избегать.

Обычный подход состоит в том, чтобы разобраться в основных фактах и ​​правилах транзитивных замыканий. Вы можете попробовать:

subset1(tomatoes, fruits).
subset1(fruits, food).

subset(X, Y) :- subset1(X, Y).
subset(X, Z) :- subset1(X, Y), subset(Y, Z).

member1(t1, tomatoes).
member1(t2, tomatoes).

member(X, Y) :- member1(X, Y).
member(X, Z) :- member1(X, Y), subset(Y, Z).

?- member(t1, food).       ===> TRUE

В этой формулировке нет рекурсии слева. Сначала проверяется прямой факт, который может прекратить рекурсию. Только при отсутствии факта выполняется рекурсивный вызов.

...