使用Prolog进行collat​​z-list实现

时间:2012-12-08 02:55:10

标签: prolog collatz

我正在尝试在Prolog中创建一个名为collatz_list的函数。该函数有两个参数,第一个是数字,第二个是列表。这个列表将是我输出的这个函数。所以,这是我的功能:

collatz_list(1,[1]).
collatz_list(N,[H|T]) :-
   N > 1,
   N mod 2 =:= 0,
   collatz_list(N, [H|T]).  
collatz_list(N,[H|T]) :-
   N > 1,
   N mod 2 =:= 1,
   N is N*3 +1,
   collatz_list(N,[H|T]). 

我正在努力创建输出列表。任何人都可以帮助我吗?

感谢。

2 个答案:

答案 0 :(得分:3)

假设您要编写带参数collatz_list/2的{​​{1}}谓词,其中(int, list)是以list开头且最终以int结尾的collat​​z序列(我们希望如此!到目前为止这是一个悬而未决的问题);你只需要以声明的方式编写递归定义。

这是我的尝试:

1

修改后的版本,包括起始编号

让我们测试一下:

/* if N = 1, we just stop */
collatz_list(1, []).

/* case 1: N even
   we place N / 2 in the head of the list
   the tail is the collatz sequence starting from N / 2 */
collatz_list(N, [H|T]) :-
    0 is N mod 2,
    H is N / 2, 
    collatz_list(H, T), !. 

/* case 2: N is odd
   we place 3N + 1 in the head of the list
   the tail is the collatz sequence starting from 3N + 1 */
collatz_list(N, [H|T]) :-
    H is 3 * N + 1, 
    collatz_list(H, T). 

答案 1 :(得分:3)

首先,我们定义简单的辅助谓词collatz_next/2来执行 Collat​​z步骤:

collatz_next(X,Y) :-
   X >= 1,
   (  X =:= 1       -> Y = 1
   ;  X mod 2 =:= 0 -> Y is X // 2
   ;                   Y is 3*X + 1
   ).

要进入固定点, 我们使用元谓词fixedpoint/3fixedpointlist/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)).