Description of the problem:
I am trying to generate all pairs of natural numbers in Prolog (SWI-Prolog),
i.e. formally have a function f(X,Y) such that:
after calling f(X,Y) with unrelated variables X , Y for each pair of natural numbers (m, n), there exists n0 such that after pressing the semicolon n0, Prolog will return (X,Y)=(m,n) .
Error trying:
I was hoping to write a function using the Cantor Binding Function . In short, he lists the pairs as follows: (0,0), (1,0), (0,1), (2,0), (1,1), (0,2), (3,0) , (2.1), (1.2), (0.3), (4.0) ...
I expressed it as follows:
gen(0,0). % 'root' gen(M,0) :- gen(0, X), M is X+1. % 'jump to the previous diagonal' gen(M,N) :- gen(X, Y), M is X-1, N is Y+1, N > 0. % 'a step inside a diagonal'
However, due to the fact that Prolog actually works, this ends with the 2nd rule repeatedly calling itself, endlessly, ultimately, due to lack of stack space (the only results that it returns before that (0, 0) and (1,0), then it gets stuck, repeatedly fails in the second rule: "0 is 0 + 1").
Do you have any ideas how to make this or any other elegant approach?
Thanks.
Change is my decision.
Based on the accepted answer (thanks!), I wrote the following code, working as intended:
range(Min, _, Min). range(Min, Max, Val) :- NewMin is Min+1, Max >= NewMin, range(NewMin, Max, Val). natnum(0). natnum(N) :- natnum(N0), N is N0 + 1. gen(A,B) :- natnum(N), range(0, N, B), A is N - B.
Using:
?- gen(X,Y). X = 0, Y = 0 ; X = 1, Y = 0 ; X = 0, Y = 1 ; X = 2, Y = 0 ; X = 1, Y = 1 ; X = 0, Y = 2 ; X = 3, Y = 0 and so on...