В книге нам предлагается определить предикаты left_of, right_of, выше и ниже, используя следующий макет.left_of упражнения из Art Of Prolog
% bike camera
% pencil hourglass butterfly fish
left_of(pencil, hourglass).
left_of(hourglass, butterfly).
left_of(butterfly, fish).
above(bike, pencil).
above(camera, butterfly).
right_of(Obj1, Obj2) :-
left_of(Obj2, Obj1).
below(Obj1, Obj2) :-
above(Obj2, Obj1).
Это похоже на правильные решения.
Позже в книге нам предлагается добавить рекурсивное правило для left_of. Единственное решение, которое я смог найти, это использовать другое имя функтора: left_of2. Поэтому я в основном переопределял отношения между предками.
left_of2(Obj1, Obj2) :-
left_of(Obj1, Obj2).
left_of2(Obj1, Obj2) :-
left_of(Obj1, X),
left_of2(X, Obj2).
В своих попытках повторного использования left_of, я могу получить все правильное решение, но на конечном повтор, происходит переполнение стека. Я предполагаю, что это потому, что у меня нет правильного базового аргумента. Может ли это быть закодировано с использованием left_of для фактов и рекурсивной процедурой?
Действительно? Кажется, он работает правильно. Возможно, вы захотите выйти из сеанса Prolog и снова загрузить код, чтобы убедиться. –
Даниэль, мой вопрос можно было использовать для фактов и рекурсивного правила (без использования left_of2). Возможно, я неправильно интерпретирую упражнение. – stirfoo
В этом случае ответ отрицательный. В Prolog есть много случаев, когда у вас должны быть отдельные предикаты, где вам не нужны они на других языках (на ум приходят также петли с шагами инициализации или финализации). Это всего лишь один из них. Вы всегда можете скрыть «внутренний» предикат с другим именем ('direct_left_of/2' приходит на ум) и выставить' left_of2' как 'left_of' для ваших пользователей. –