reset(forall(member(M, [1,2,3]),shift(M)), X, Cont), reset(Cont, X2, Cont2) I get:
ERROR: Type error: `callable' expected, found `0' (an integer)
ERROR: In:
ERROR: [11] reset(user:0,_7526,_7528)
Can someone help explain what’s going on?
Is this because forall uses backtracking to drive the Generator and the first continuation “loses” knowledge of choice points, that is, it doesn’t backtrack to find next solution?
The usual idea of continuations is that you can abort (using shift/1) any computation and make it continue using call/1, just as if nothing happened. That is not always the case for Prolog’s continuations. The case that typically goes wrong is where you shift before a commit (!/0 or ->) Let us consider this
p, shift(Ball), q -> r ; s
Running this, the ;/2 choicepoint was created before the shift and thus remains part of the computation. If we resume after the shift, the link between the commit implied by → and the choice point of the ;/2 is lost and the → thus no longer has any effect. That is the original work. SWI-Prolog’s implementation can in some cases deal with the commit if the continuation is immediately restarted. Use cases such as tabling store the continuation for later reused though. In this case it doesn’t matter as tabling has the same limitations when dealing with commits.
Thus, shift only captures the current forward continuation, not the choice points.