I am writing a prolog program with can perform Peano arithmetics.
I have standard definitions for natural numbers.
nat(n).
nat(s(N)) :-
nat(N).
Because I want to enumerate all possible relation of addition between natural numbers, I defined an auxiliary function (in order for defining total ordering over the set).
cmp_n(X, Y, lt) :-
nat(Y), % generate a stream : n s(n) s(s(n)) ...
cmp_n_lt_helper(X, Y). % gives all XS smaller than Y
cmp_n_lt_helper(s(X), s(Y)) :-
cmp_n_lt_helper(X, Y).
cmp_n_lt_helper(n, s(Y)) :-
nat(Y).
Then, I defined addition
% need to use a wrapper because I want to generate (n, n, n) first
% if I don't use this warper, it would start from (n, s(n), s(n))
add_n(X, Y, R) :-
nat(R), % same reason as above
cmp_n(X, R, lt),
add_n_helper(X, Y, R).
add_n_helper(s(X), Y, s(R)):-
add_n_helper(X, Y, R).
add_n_helper(n, Y, Y).
If I enumerate all possible relations over this definition of addition, it worked fine. And when outputting a finite set of answers, it can halt.
?- add_n(X, Y, R).
X = Y, Y = R, R = n ;
X = R, R = s(n),
Y = n ;
X = n,
Y = R, R = s(n) ;
X = R, R = s(s(n)),
Y = n ;
X = Y, Y = s(n),
R = s(s(n)) ;
X = n,
Y = R, R = s(s(n)) .
?- add_n(X, Y, s(s(s(s(n))))).
X = s(s(s(s(n)))),
Y = n ;
X = s(s(s(n))),
Y = s(n) ;
X = Y, Y = s(s(n)) ;
X = s(n),
Y = s(s(s(n))) ;
X = n,
Y = s(s(s(s(n)))) ;
false.
These worked fine.
However, if I do the regular forward evaluation,
?- add_n(s(s(s(n))), s(s(n)), R).
R = s(s(s(s(s(n)))))
this program cannot halt.
I am wondering : is there a way to
- for any finite answer, give a finite result.
- for any infinite answer, fix a specific valid answer, give this specified answer in finite time