首先,我们定义简单的辅助谓词collatz_next/2
来执行单个Collatz 步骤:
collatz_next(X,Y) :-
X >= 1,
( X =:= 1 -> Y = 1
; X mod 2 =:= 0 -> Y is X // 2
; Y is 3*X + 1
).
为了推进到一个固定点,我们使用元谓词fixedpoint/3
和fixedpointlist/3
:
?- fixedpoint(collatz_next,11,X).
X = 1. % succeeds deterministically
?- fixedpointlist(collatz_next,11,Xs).
Xs = [11,34,17,52,26,13,40,20,10,5,16,8,4,2,1]. % succeeds deterministically
上述查询中使用的两个元谓词都是基于单调控制结构if_/3
和具体化术语相等谓词(=)/3
,可以定义如下:
:- meta_predicate fixedpoint(2,?,?).
fixedpoint(P_2, X0,X) :-
call(P_2, X0,X1),
if_(X0=X1, X=X0, fixedpoint(P_2, X1,X)).
:- meta_predicate fixedpointlist(2,?,?).
fixedpointlist(P_2,X0,[X0|Xs]) :-
call(P_2, X0,X1),
if_(X0=X1, Xs=[], fixedpointlist(P_2,X1,Xs)).