Question

pred(Args).
pred(Args) :-
    goalA,
    goalB,
    !,
    pred(Args).
pred(Args) :-
    goalC,
    goalD,
    !,
    pred(Args).

Normally I would write a recursive predicate that was concerned with memory performance something along the lines of the above snippet of code. With the cut being used to try to force tail call optimization to occur. I have recently been going through a large prolog code base and have found some examples where the cut is actually after the recursive call rather than immediately before it. Presumably this has the effect of preventing tail call optimization from happening rather than assisting it.

My question is can I move the cut from after the recursive call to immediately prior to it without affecting the meaning of the program? This is assuming that there is a cut in the same relative location for each clause of the predicate.

Now I've been thinking about it some more, I'm thinking maybe the answer is "not necessarily", but having rewritten all the code with the cut before the call and finding that the test suite is still passing, I'm also wondering if there might be some other esoteric reason for writing predicates like this. Or is it just bad coding?

Was it helpful?

Solution

My guess is that it might be bad coding (or misunderstanding what author was doing)

I'm saying this, because I, myself, did once the same error:

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

http://xonix.habrahabr.ru/blog/60430/ (warning, in russian)

But people from SWI mailing-list confirmed that right way of tail-recursive code is

head :-
       <guard goals>, !,
       <deterministic stuff>,
       head.
head :-
       ...
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top