【问题标题】:Shifting a list to the left N times in Prolog在Prolog中将列表向左移动N次
【发布时间】:2014-06-24 05:40:27
【问题描述】:

我正在尝试在 Prolog shiftL(L1,N,L2) 中建立一个关系,它将 L1 向左移动 N 次(旋转),结果是 L2,因此例如 shiftL([1,2,3], 2, [3,1,2]) 为真。

我尝试了以下方法:

shiftL([],N,[]).
shiftL([X|Xs],1,L) :- append(Xs,[X],L).
shiftL([X|Xs],N,L) :- N1 is N-1 , N=\=1 , shiftL(L1,N1,L) , append(Xs,[X],L1).

而且效果很好,但是在给我结果后它总是继续做其他事情,我得到一个堆栈溢出:

?- shiftL([1,2,3], 2, L).
L = [3, 1, 2] ;
ERROR: Out of global stack

我不知道是什么原因造成的。我以为我用第二行和N=\=1 语句覆盖了基本情况。

提前感谢您的帮助!

【问题讨论】:

    标签: prolog failure-slice


    【解决方案1】:

    这是相关的程序片段():

    shiftL([],N,[]) :- false。 shiftL([X|Xs],1,L) :- 追加(Xs,[X],L),。 shiftL([X|Xs],N,L) :- N1 是 N-1 , N=\=1, shiftL(L1,N1,L), , 追加(Xs,[X],L1)

    所以基本上目标append(Xs,[X],L) 循环。它会循环,因为XsL 都不是一个列表——这是一个固定长度的列表。要看到这一点,请考虑递归目标 shiftL(L1,N1,L)。正如您在片段中看到的那样,L1 不会出现在其他任何地方。因此,它是一个未实例化的变量。 L 是查询中的变量。因此,您需要创建 L1L 列表。就像把隐藏的append(Xs,[X],L1) 放在前面一样。

    还有另一个循环:

    ?- shiftL([1,2,3],-1,L).
    

    我相信你可以自己解决这个问题。

    有关故障切片如何缩小非终止问题的更多示例,请参阅

    【讨论】:

    • 哦,我明白了,所以表达式的顺序实际上很重要。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2012-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-02
    • 1970-01-01
    • 1970-01-01
    • 2019-11-10
    相关资源
    最近更新 更多