How to do tail recursion without growing the stack?

I swear this has worked for me before, I must be missing something. I’m trying to build a predicate that uses tail recursion to keep repeating without growing the stack, but mine keeps growing it.

I thought SWI Prolog would optimize the case below but it doesn’t seem to be…

Any ideas?

stack_level(Level) :-
    % See if the stack is growing by getting the stack level
    prolog_current_frame(Me),
    prolog_frame_attribute(Me, level, Level).

startTest :-
    assert(a(1)), assert(a(1)), assert(a(1)).

stackTest :-
    stack_level(Level),
    writeln(Level),
    a(X),
    retract(a(X)), !, stackTest.
?- startTest,stackTest.
12
14
15
16
false.

The Level computes the virtual level and is (thus) also increased on last calls. That is why, when a stack trace is dumped, the indicated levels typically have missing levels: due to a last call the frame(s) in between are missing.

To verify LCO does its job you can use statistics(localused, Bytes)

Perfect, thanks @jan! I must have misremembered using Level before.