tags:

views:

125

answers:

1
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?

A: 

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 :-
       ...
Xonix
Since my moving the cut didn't change the way the code behaved across all our test cases, I'm thinking you might be right - that it was just bad coding.
humble coffee