@Boris' answer is perfect. I would just like to explain, why your original program, and that of another answer does not terminate.
At first sight, it seems to work, after all we get an answer:
?- countD(4,L).
L = [4, 3, 2, 1]
But note that Prolog showed us only the first answer, there are more, waiting ...
?- countD(4,L).
L = [4, 3, 2, 1]
; loops.
The best way to understand termination in Prolog is to concentrate on the relevant parts of your program. And the nice thing in Prolog is that while its actual control flow is quite complex, it often suffices to look at a very tiny part of your program to determine certain properties. So there is no need to "understand everything at once".
Instead of looking at everything, I will take the following failure-slice:
countD(0,[]) :- false.
countD(Num,List) :-
List = [Num|L],
countD(M,L), false,
Num is M+1.
In the first line, by inserting false
at the fact, the fact is effectively removed. So no matter what it describes exactly, the 0
or 1
does not have any influence on the termination of this predicate. In general, non-termination of any failure-slice implies non-termination of the original program.
Of course we have to find the right slice. That's a bit of experience. But once it is found, its termination properties are easy to check.
To fix this problem, we can say immediately that adding a further clause will not improve termination (provided the program is a pure, monotonic one). We need to change something in the visible part. Boris did this by adding some check for Num
before the actual recursion.