Thank you for the responses and the tips.
I apologize, I see that I forgot to clear up some of the details regarding the code.
You are right that the code will backtrack to func3/2, but that only has one implementation, so when viewing it in trace mode, it doesn’t show up so I didn’t notice. However, func4/2 has multiple implementations, for example
% case when X is zero
func4(0, NX) :-
...
% case when X is not zero (but due to redoing, the program might still try it with zero)
func4(X, NX) :-
...
When func2/1 is called, and Res = [_|_]
, func4/2 runs, then, func2/1 gets called recursively. When it fails in the recursive call, it backtracks (eventually) to func4/2, and the functions above them, which is what I am trying to avoid.
Also note that there are other functions above func2 that I omitted from my explanation so it’s easier to understand, which I don’t want my program to backtrack to. My goal is that func1/1 should fail, if Res = [_|_]
is ever false.
I assume I could place X \= 0
, to the other implementations of func4/2 (I think this is what @brebs meant), but when viewing in trace, when redoing, the function still gets called (it just fails immediately). This yields correct results, but I wonder if there are solutions where redoing is skipped entirely
As @peter.ludemann said I could do (func4(X, NX) -> ...)
but what if, let’s call it func5/2 is also called just above func4/2, that I also don’t want to backtrack to?