如果您执行以下查询,Left 和 Right 将绑定到两个列表,当它们连接在一起时,结果为 [1,2,3,4,5]:
?- append(Left, Right, [1,2,3,4,5]).
上面的查询承认 6 个解决方案(Left 为空,列表 [1],列表 [1,2] 等)。您可以通过说 Left 恰好包含三个元素来限制查询:
?- length(Left, 3), append(Left, Right, [1,2,3,4,5]).
Left = [1, 2, 3]
Right = [4, 5]
这只有一种解决方案。
轮换包括生成一个列表,其中Left 部分位于Right 列表的右侧:
?- length(Left, 3),
append(Left, Right, [1,2,3,4,5]),
append(Right, Left, Result).
Left = [1, 2, 3]
Right = [4, 5]
Result = [4, 5, 1, 2, 3]
您需要编写的第一个谓词如下:
rotate_left(List, Offset, Rotated) :-
length(Left, Offset),
append(Left, Right, List),
append(Right, Left, Rotated).
然后您可以将此谓词应用于列表列表。
注意。你可以考虑改用这个版本:
rotate_left(List, Offset, Rotated) :-
append(Left, Right, List),
length(Left, Offset),
append(Right, Left, Rotated).
更好一点,因为它允许Offset 是可变的:
[eclipse 2]: rotate_left([a, b, c, d], N, [c, d, a, b]).
N = 2
Yes (0.00s cpu, solution 1, maybe more) ? ;
No (0.00s cpu)
在原始版本中,length(Left, N) 的两个参数都是变量,并且它会不断生成越来越长的列表的答案。