Сокращения в конце рекурсивных предикатов в Прологе - PullRequest
4 голосов
/ 27 августа 2009
pred(Args).
pred(Args) :-
    goalA,
    goalB,
    !,
    pred(Args).
pred(Args) :-
    goalC,
    goalD,
    !,
    pred(Args).

Обычно я писал бы рекурсивный предикат, который касался производительности памяти, что-то вроде приведенного выше фрагмента кода. С сокращением, используемым, чтобы попытаться заставить оптимизацию хвостового вызова произойти. Недавно я просматривал большую базу кодов пролога и нашел несколько примеров, когда сокращение происходит после рекурсивного вызова, а не непосредственно перед ним. Предположительно, это скорее препятствует оптимизации хвостового вызова, чем помогает ему.

У меня вопрос: можно ли переместить вырез после рекурсивного вызова непосредственно перед ним, не затрагивая смысла программы? Это при условии, что в каждом относительном положении предиката есть разрез в одном и том же относительном местоположении.

Теперь я подумал об этом еще немного, думаю, что, возможно, ответ «не обязательно», но переписав весь код с сокращением перед вызовом и обнаружив, что набор тестов все еще проходит, я Мне также интересно, может ли быть какая-то другая эзотерическая причина для написания таких предикатов. Или это просто плохое кодирование?

1 Ответ

2 голосов
/ 29 августа 2009

Я предполагаю, что это может быть плохое кодирование (или неправильное понимание того, что делал автор)

Я говорю это, потому что я сам однажды сделал ту же ошибку:

https://mailbox.iai.uni -bonn.de / Почтальон / государственные / SWI-Пролог / 2009 / 001540.html

http://xonix.habrahabr.ru/blog/60430/ (предупреждение)

Но люди из списка рассылки SWI подтвердили, что правильный путь хвостово-рекурсивного кода -

head :-
       <guard goals>, !,
       <deterministic stuff>,
       head.
head :-
       ...
...