Prolog:向右旋转列表n次

Ada*_*all 3 prolog

处理谓词,rotate(L,M,N)在哪里L是通过旋转M到正确的N时间形成的新列表.

我的方法是将尾巴追加M到它的头部N时间.

rotate(L, M, N) :- 
   (  N > 0,
      rotate2(L, M, N)
   ;  L = M
   ).

rotate2(L, [H|T], Ct) :- 
   append(T, [H], L), 
   Ct2 is Ct - 1, 
   rotate2(L, T, Ct2).
Run Code Online (Sandbox Code Playgroud)

目前,我的代码返回L等于原始代码M,无论N设置为什么.好像我正在递归时,尾巴没有正确地移动到头部.

小智 8

您可以使用append拆分列表和length创建列表:

% rotate(+List, +N, -RotatedList)
% True when RotatedList is List rotated N positions to the right
rotate(List, N, RotatedList) :-
    length(Back, N),           % create a list of variables of length N
    append(Front, Back, List), % split L
    append(Back, Front, RotatedList).
Run Code Online (Sandbox Code Playgroud)

注意:这仅适用于N <= length(L).您可以使用算术来解决这个问题.

编辑为清晰起见 此谓词是为ListN参数定义的,这些参数在调用谓词时不是变量.我无意中重新排序了原始问题中的参数,因为在Prolog中,约定是严格的输入参数应该在输出参数之前.因此,ListN以及输入参数,RotatedList是输出参数.所以这些是正确的查询:

?- rotate([a,b,c], 2, R).
?- rotate([a,b,c], 1, [c,a,b]).
Run Code Online (Sandbox Code Playgroud)

但是这个:

?- rotate(L, 2, [a,b,c]).
Run Code Online (Sandbox Code Playgroud)

找到一个答案后会进入无限递归.

在阅读SWI-Prolog文档时,请注意标有"?"的谓词参数,如length.它们可以如本例所示使用.