So what you are here into is to understand the precise termination properties of a particular program. Prolog is here quite different to other programming languages since it has a relatively complex execution mechanism. In particular backtracking is quite intertwined with "normal resolution" and then combined with unification.
The easiest way to understand the problem with your original program is to consider the following failure slice (see the link for other examples):
plus(0,B,B) :- false, nat(B).
plus(s(A),B,C) :- plus(A,s(B),C), false.
If this tiny program will not terminate, then also your original program will not terminate. So we can consider the question when this program will not terminate, first.
Consider the third argument: There is simply a variable C
that is passed along. Nobody is interested in its value (in this fragment). So the third argument will have no influence on termination whatsoever!
Worse, also the second argument is just a free variable B
in the head, thus again, the argument will never influence whether or not this fragment terminates.
And thus: If you want that this fragment terminates, the first argument has to be known. Otherwise the program will loop.
You can also use a termination inferencer to to see this yielding as termination condition:
plus(A,B,C)terminates_if b(A),b(B);b(A),b(C).
The best seems to be to reformulate your program. Giving you the following termination condition:
plus(A,B,C)terminates_if b(A),b(B);b(C).
In Prolog, we commonly like to generalize programs even further, accepting also some unexpected solutions while improving its termination condition to an even better condition:
plus(A,B,C)terminates_if b(A);b(C).
However, this last version now admits solutions that are not always acceptable. E.g. plus(0, nonnumber, nonnumnber)
now succeeds, whereas you might want it to fail.
Of course, you might also do some experiments with cuts, but be warned, using cut is extremely error-prone. At least you should combine it with appropriate tests which often nix the "efficiency gain".