ОШИБКА новичка в Prolog: из локального стека

#prolog #transitive-closure

#пролог #транзитивное закрытие

Вопрос:

Я очень новичок в программировании на Prolog. Любая помощь приветствуется. У меня есть следующая программа,

 bigger(elephant, horse).
bigger(horse, donkey).
bigger(donkey, dog).
bigger(donkey, monkey).

is_bigger(X, Y) :- bigger(X, Y).
is_bigger(X, Y) :- is_bigger(Z, Y), bigger(X,Z).
  

При выполнении запроса,

 ?- is_bigger(A, donkey)
  

Я получаю следующий вывод,

 A = horse ;
A = elephant ;
ERROR: Out of local stack
  

Хотя я немного понимаю, как A = horse и A = elephant, мне трудно понять, почему он повторяется бесконечно (я использовал встроенный предикат трассировки трассировки, но не мог понять его после A = elephant).

Спасибо.

Ответ №1:

 is_bigger(X, Y) :- is_bigger(Z, Y), bigger(X,Z).
  

Приведенная выше строка является причиной сообщения о выходе из локального стека. Вы снова вызываете «is_bigger», который снова вызывает «is_bigger» и так далее, рекурсивно


Ваш ввод: is_bigger(A, donkey)

Во-первых, вы хотите найти что-то, что больше осла или / и что-то, что больше, чем вещь, которая больше осла.

Поэтому:

 is_bigger(X, Y) :- bigger(Z, Y), bigger(X,Z).
  

Почему?

Y привязывается к ослу.

Z привязка к лошади.

В качестве последнего шага вы ищете bigger(X, horse)

Имеет ли это смысл?

Комментарии:

1. Я думаю, что рекурсия — это весь смысл, поскольку мы хотим иметь возможность обнаруживать цепочки длиннее 2, то есть что-то большее, чем что-то большее, чем … это больше, чем осел. Если бы у нас тоже было bigger(whale, elephant). , то ваш подход не согласился бы с этим is_bigger(whale, donkey) .

2. В этом случае: is_bigger(X, Y) : — больше (Z, Y), is_bigger(X, Z).

3. Причина, по которой он не работает, когда вы ставите is_bigger первым, заключается в том, что он будет продолжать цикл, пытаясь найти is_bigger(Z, Y) . Но если вы поместите его последним, он уже найдет всех животных в большем (Z, Y), которые затем могут быть повторены / сопоставлены через Z в последнем is_bigger(X, Z) .

4. @programmingwat не могли бы вы обновить свой ответ правильным рекурсивным решением, чтобы мы могли поддержать его?