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?

Foi útil?

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 :-
       ...
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top