【发布时间】:2018-01-01 21:47:11
【问题描述】:
问题陈述:
我正在尝试在 Prolog (SWI-Prolog) 中生成所有自然数对,
即正式有一个函数f(X,Y),这样:
在使用未绑定变量X、Y 调用f(X,Y) 后,对于每对自然数 (m, n),存在一个 n0,这样在按分号 n0 次后,Prolog 将返回 (X,Y)=(m,n)。
尝试失败:
我希望使用Cantor's pairing function 编写函数。简而言之,它按如下方式枚举对:(0,0), (1,0), (0,1), (2,0), (1,1), (0,2), (3,0 ), (2,1), (1,2), (0,3), (4,0)...
我是这样表达的:
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'
但是,由于 Prolog 搜索的实际工作方式,这最终导致第二条规则反复调用自身,ad 无穷大,最终由于堆栈空间不足而崩溃(它在此之前返回的唯一结果是 (0,0) 和(1,0),然后它就卡住了,反复失败关于 '0 是 0+1' 的第二条规则)。
您对如何使这种或任何其他优雅的方法发挥作用有任何想法吗?
谢谢。
编辑 - 我的解决方案。
根据接受的答案(谢谢!),我编写了以下代码,按预期工作:
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.
使用时:
?- 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...
【问题讨论】:
-
作为一个术语,Prolog 没有函数,而是谓词。它们不是一回事。
标签: prolog