【问题标题】:collatz-list implementation using Prolog使用 Prolog 的 collat​​z-list 实现
【发布时间】:2012-12-08 02:55:09
【问题描述】:

我正在尝试在 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]). 

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

谢谢。

【问题讨论】:

    标签: prolog collatz


    【解决方案1】:

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

    这是我的尝试:

    /* 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|...].
    

    【讨论】:

    • 你确定divide是/而不是//。我运行了您的代码,但出现此错误: collat​​z_list/2: Undefined procedure: (-)/2
    • 好的,工作了,但是现在如果您查看 collat​​z-list(27) 的答案,它不会显示 27 本身。我认为应该包括 27。
    • 好吧,修改它以包含起始编号。
    • 老兄,这就是我一开始就想做的。我不知道它的语法。我想附加 N 然后递归调用该函数。所以,我这样做:[N |整理列表(H,T)]。但这似乎不起作用。
    • 关于如何将头部附加到列表尾部的任何想法?
    【解决方案2】:

    首先,我们定义简单的辅助谓词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)).
    

    【讨论】:

      猜你喜欢
      • 2012-11-13
      • 1970-01-01
      • 2017-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-19
      • 2019-03-09
      相关资源
      最近更新 更多