#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 не могли бы вы обновить свой ответ правильным рекурсивным решением, чтобы мы могли поддержать его?