我正在尝试递归地旋转prolog中的列表,但它不能按预期工作。
代码:
rot([],[]).
rot([H|T1], [T2|H]):-rot(T1,T2).
输出:
?- rot([1,2,3], V).
V = [[[[]|3]|2]|1]
预期产出:
?- rot([1,2,3], V).
V = [3,2,1]
有人能解释一下为什么我的代码不起作用吗?
答案 0 :(得分:4)
由于Prolog是无类型的,你确实可以编写类似[List|Element]
的内容,但是如果你想让列表有意义,那么构建列表的唯一方法就是[Element|List]
。所以[T2|H]
根本没有意义。在这种情况下,T2
应为元素,H
为列表(或空列表[]
)。
您需要定义两个谓词:
rot/2
),它只是从给定列表中弹出头部并调用递归谓词;和rot/3
),它只传递给定列表的所有元素,并将原始头部作为尾部元素发出。这一起工作如下:
%main predicate rot/2
rot([],[]).
rot([H|T1],T2) :-
rot(T1,H,T2).
%recursive predicate rot/3
rot([],Last,[Last]).
rot([H|T1],Last,[H|T2]) :-
rot(T1,Last,T2).
答案 1 :(得分:3)
您的代码不起作用,因为在[H|T]
之类的表达式中,H
是列表的元素,T
是列表的尾部 - 也是列表。例如:
?- [H|T] = [1,2,3].
H = 1,
T = [2, 3].
那么当你转换它时会发生什么?
?- [H|T] = [1,2,3], X = [T|H].
H = 1,
T = [2, 3],
X = [[2, 3]|1].
看到问题?
答案 2 :(得分:2)
问题在于第二个条款。我做的是旋转L1内第一个列表的尾部,然后用L1和第一个元素调用append
并将结果赋值给L(第二个参数)
my-append([], L, L).
my-append([H|T], L, [H|R]) :- my-append(T, L, R).
rot([], []).
rot([H|T], L) :- rot(T, L1), my-append(L1, H, L).