I'm doing a very simple exercise in Prolog and there's something I don't understand in the trace. The program is a "greater than" (>
) on integers represented as successors:
greater_than(succ(_), 0).
greater_than(succ(A), succ(B)) :-
greater_than(A, B).
My problem: I don't understand why the request greater_than(succ(succ(succ(0))),succ(0))
generates a redo
in the following trace:
[trace] ?- greater_than(succ(succ(succ(0))),succ(0)).
Call: (6) greater_than(succ(succ(succ(0))), succ(0)) ? creep
Call: (7) greater_than(succ(succ(0)), 0) ? creep
Exit: (7) greater_than(succ(succ(0)), 0) ? creep
Exit: (6) greater_than(succ(succ(succ(0))), succ(0)) ? creep
true ;
Redo: (7) greater_than(succ(succ(0)), 0) ? creep
Fail: (7) greater_than(succ(succ(0)), 0) ? creep
Fail: (6) greater_than(succ(succ(succ(0))), succ(0)) ? creep
false.
Why is there a redo
here? How can I avoid it (without a cut, of course)?
BTW, before you ask : no, it's not some kind of homework...
OK, so it's a compiler optimization that a given compiler/version combination might or might not have.
Later versions of SWI do not have this problem. It is probably related to clause indexing. This behaviour would be seen on implementations without indexing, or such that index on the first argument only.
But apparently, "SWI-Prolog provides `just-in-time' indexing over multiple arguments". SWI 5.6.56 manual states that "at most 4 arguments can be indexed". So it probably indexes more than one.