I've come across very strange behaviour (to me) regarding a particular cut. From what I understood, once the execution passes a cut, it cannot backtrack back above it. But that is exactly what this code does. Can someone explain why it does this?
Here is the code:
example([],[]).
example([X,Y,Z|Tail],[Z|NewTail]) :-
X < Y,
example(Tail,NewTail).
example([X,Y,Z|Tail],[X|NewTail]) :-
Y < Z,
example(Tail,NewTail).
example([X,Y,Z|Tail],[Y|NewTail]) :-
X < Z,
example(Tail,NewTail).
Now with no cuts, the output is as follows for this particular input:
example([1,3,2,4,5,6],L).
L = [2, 6] ;
L = [2, 4] ;
L = [2, 5] ;
L = [3, 6] ;
L = [3, 4] ;
L = [3, 5].
Now if I add the following cut:
example([],[]).
example([X,Y,Z|Tail],[Z|NewTail]) :-
X < Y,
example(Tail,NewTail).
example([X,Y,Z|Tail],[X|NewTail]) :-
Y < Z,
!, <---- cut here
example(Tail,NewTail).
example([X,Y,Z|Tail],[Y|NewTail]) :-
X < Z,
example(Tail,NewTail).
I would expect it to return
L = [2,6] ;
L - [2,4].
As once it passes the cut on the third clause it can no longer back trace.
Instead it returns:
L = [2, 6] ;
L = [2, 4] ;
L = [3, 6] ;
L = [3, 4]
Why is this happening? It literally jumps back over the cut and begins executing clause 4, why?
Why does it execute clause 4, when if i move the cut up to clause 2:
example([],[]).
example([X,Y,Z|Tail],[Z|NewTail]) :-
X < Y,
!, <---- cut here
example(Tail,NewTail).
example([X,Y,Z|Tail],[X|NewTail]) :-
Y < Z,
example(Tail,NewTail).
example([X,Y,Z|Tail],[Y|NewTail]) :-
X < Z,
example(Tail,NewTail).
It only produces:
L = [2, 6].
Why does the cut work in clause 2, but not in clause 3? This makes no sense to me.