The termination property of Prolog programs is a bit difficult to grasp due to Prolog's relatively complex control flow. There are ways to cut down the complexity. One, is to consider only parts of your program by inserting additional goals false
into your program. You can place them in any place. And no matter where you place them the following holds: If this new program, called a failure-slice does not terminate, then also your original program does not terminate. Note the "if". Here is your program:
reverse([],[]) :- false.
reverse([X|Xs],Zs) :-
reverse(Xs,Ys), false,
append(Ys, [X], Zs).
This failure-slice is completely useless for understanding what your relation describes. It will never succeed. However, it helps us to better understand how termination will do.
Note that the fact is completely eliminated. In fact, no matter what the fact looks like it cannot improve termination of this failure-slice of reverse/2
. (It could deteriorate termination, though).
Also note the second argument, the Zs
: there is no further mentioning of this Zs
. Thus: the second argument of reverse/2
can be whatever it wants to be. It will again not improve termination.
To make reverse/2
terminate, the first argument has to be instantiated such that this fragment will terminate. Thus []
, [X|[]]
will terminate, even [X|nonlist]
will terminate. But partial lists such as Xs
, [a|Xs]
etc will not terminate.
If you want improve termination for, say, reverse(Xs,[])
you need to change something in the visible, remaining part. One way is to exchange the goals. Now, Zs
may contribute to the termination. But -alas- the first argument has now no longer the influence it used to have. Consider reverse([a], Zs)
and:
reverse([],[]) :- false.
reverse([X|Xs],Zs) :-
append(Ys, [X], Zs), false,
reverse(Xs,Ys).
append([], Zs, Zs) :- false.
append([X|Xs], Ys, [X|Zs]) :-
append(Xs, Ys, Zs), false.
So while this fragment still insists that the first argument is [_|_]
it does not take the remaining term into account. And thus, the goal will not terminate.
If you want to learn more, look at failure-slice. Equally, consider using cTI. To develop a good intuition, you will need to try it out yourself.