2009-08-27 3 views
4
pred(Args). 
pred(Args) :- 
    goalA, 
    goalB, 
    !, 
    pred(Args). 
pred(Args) :- 
    goalC, 
    goalD, 
    !, 
    pred(Args). 

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

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

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

ответ

2

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

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

https://mailbox.iai.uni-bonn.de/mailman/public/swi-prolog/2009/001540.html

http://xonix.habrahabr.ru/blog/60430/ (предупреждение, в России)

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

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

Поскольку мое перемещение разреза не изменило способ поведения кода во всех наших тестовых случаях, я думаю, что вы можете быть правы - это было просто плохое кодирование. – nedned

Смежные вопросы