Cortes no final de predicados recursivos no Prolog
-
20-09-2019 - |
Pergunta
pred(Args).
pred(Args) :-
goalA,
goalB,
!,
pred(Args).
pred(Args) :-
goalC,
goalD,
!,
pred(Args).
Normalmente, eu escrevia um predicado recursivo que se preocupava com o desempenho da memória algo parecido com o snippet de código acima. Com o corte sendo usado para tentar forçar a otimização de chamadas de cauda. Recentemente, tenho passado por uma grande base de código Prolog e encontrei alguns exemplos em que o corte é realmente após a chamada recursiva e não imediatamente antes dela. Presumivelmente, isso tem o efeito de impedir que a otimização de chamadas de cauda aconteça, em vez de ajudá -lo.
Minha pergunta é: posso mover o corte após a chamada recursiva para imediatamente antes dela sem afetar o significado do programa? Isso assume que há um corte no mesmo local relativo para cada cláusula do predicado.
Agora eu tenho pensado um pouco mais, acho que talvez a resposta seja "não necessariamente", mas depois de reescrever todo o código com o corte antes da chamada e descobrindo que a suíte de teste ainda está passando, também estou Quer saber se pode haver outra razão esotérica para escrever predicados como este. Ou é apenas uma codificação ruim?
Solução
Meu palpite é que pode ser uma codificação ruim (ou entendendo mal o que o autor estava fazendo)
Estou dizendo isso, porque eu mesmo fiz uma vez o mesmo erro:
https://mailbox.iai.uni-bonn.de/mailman/public/swi-prolog/2009/001540.html
http://xonix.habrahabr.ru/blog/60430/ (Aviso, em russo)
Mas as pessoas da lista de correspondência SWI confirmaram que o caminho certo do código recursivo é
head :-
<guard goals>, !,
<deterministic stuff>,
head.
head :-
...