【问题标题】:Prolog iteration off by 1Prolog 迭代关闭 1
【发布时间】:2012-03-09 00:53:58
【问题描述】:

我有一个名为myfor 的迭代器,这样当我调用myfor(3,7,X). 时,我希望它返回X = [3, 4, 5, 6, 7]。但是,此代码仅返回 X = [4, 5, 6, 7]。它跳过第一个。谁能告诉我怎么了?

myfor(A, A, []) :- !.

myfor(Start,End, Z) :-

    End > Start,
    NewValue is Start+1,
    myfor(NewValue,End, L),
    append([NewValue], L, Z).

【问题讨论】:

    标签: list prolog iteration


    【解决方案1】:

    无法在 Prolog 中检查这一点(因为我的工作机器上没有它)。这是我的 2 位

    myfor(A, A, [A]) :- !.
    
    myfor(Start,End, Z) :-
    End > Start,
    NewValue is Start+1,
    myfor(NewValue,End, L),
    append([Start], L, Z).
    

    【讨论】:

    • 您可以通过删除第二个子句中的最后一行并将头部更改为myfor(Start,End,[Start|L]) :- 来使其尾递归。摆脱追加调用。
    【解决方案2】:

    顺便说一句,如果您使用 swi-prolog 和其他一些 prolog,between/3 与您所说的 myfor/3 接近,并且通过一两个 listing/1 调用,您可以很好地了解它是如何实现的。在 between 上的 findall 应该做你的谓词所做的事情。

    【讨论】:

      【解决方案3】:

      尝试在 prolog 中实现 for/next 循环强烈表明您正在考虑命令式编程,您告诉计算机要做什么,而不是声明式编程,您可以在其中描述解决方案并让 Prolog 的推理引擎来解决。

      但是,如果您想生成一个包含有序数字范围的列表,那么类似下面的内容将使用差异列表的魔力“完成”:

      range( X , X , [X] )
        .
      range( X , Y , [X|Z] ) :-
        X < Y ,
        X1 is X + 1 ,
        range( X1 , Y , Z )
        .
      range( X , Y , [X|Z] ) :-
        X > Y ,
        X1 is X - 1 ,
        range( X1 , Y , Z )
        .
      

      【讨论】:

        猜你喜欢
        • 2014-01-28
        • 2013-03-03
        • 2012-10-08
        • 2019-07-27
        • 2017-03-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-31
        相关资源
        最近更新 更多