3

collatz_listPrologで呼び出される関数を作成しようとしています。この関数は2つの引数を取ります。最初の引数は数値で、2番目の引数はリスト内です。このリストは、この関数の出力になります。だから、これが私の関数です:

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]). 

出力リストの作成に苦労しています。誰かがそれについて私を助けることができますか?

ありがとう。

4

2 に答える 2

3

collatz_list/2パラメータを使用して述語を記述したいとします(int, list)。ここlistで、コラッツのシーケンスはで始まりint、最終的にはで終わります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). 

変更されたバージョン、開始番号が含まれています

それをテストしてみましょう:

full_list(N, [N|T]) :-
    collatz_list(N, T).

collatz_list(1, []).

collatz_list(N, [H|T]) :-
    0 is N mod 2,
    H is N / 2, 
    collatz_list(H, T), !. 

collatz_list(N, [H|T]) :-
    H is 3 * N + 1, 
    collatz_list(H, T). 

?- full_list(27, L).
L = [27, 82, 41, 124, 62, 31, 94, 47, 142|...].
于 2012-12-08T13:10:11.117 に答える
3

最初に、単一のCollat​​zステップcollatz_next/2を実行するための単純な補助述語を定義します。

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)).
于 2015-05-26T09:35:56.143 に答える