我是Prolog的初学者,被困在家庭作业中。我必须建立一个谓词myReverse(XS,YS)
,其中XS
是YS
的反向列表。我建立了一些逻辑,如下所示:
myReverse([],[]).
myReverse([H],[H]).
myReverse([L|H],[H|T]) :- myReverse(L,T).
这有点用,但是输出不是我想要的。一些例子:
myReverse(L,[]).
L = [] % ok, that's fine
myReverse(L,[a]).
L = [a] % still fine
myReverse(L,[a,b]).
L = [[b]|a] % expected [b,a]
myReverse(L,[a,b,c]).
L = [[[c]|b]|a] % expected [c,b,a]
...
有什么方法可以在不使用累加器或append
之类的第三方实现的情况下实现预期的输出?
编辑:该问题不是是Reversing a List in Prolog的副本,因为我不想要使用累加器。同样,这个问题更多地是关于给定解决方案的输出格式,而不是解决方案本身。
答案 0 :(得分:0)
您误解了[H|T]
表示法,通过查看示例reverse(L, [a, b])
会发现它。
第一次统一:
rule: myReverse([L|H],[H|T]) :- myReverse(L,T).
unified: myReverse([L|a], [a|[b]]) :- myReverse(L, [b]).
在这一点上,a
是单个原子,而不是列表,T in [H|T]
必须是列表,列表才能完整。 [a, b, c]
是.(a, .(b, .(c, [])))
的语法糖。
您的第二个统一和第三个统一是:
second: myReverse([b], [b]).
going back: myReverse([[b]|a], [a|[b]]) :- myReverse([b], [b]).
which outputs as: myReverse([[b]|a], [a, b]).
您的输出[[b]|a]
不是完整列表,因为a
是一个原子,而不是列表,这就是为什么不输出为[[b], a]
的原因。 / p>
要不使用累加器,您需要在退出递归并返回堆栈框架时向列表中添加元素,在处理列表或原子时要牢记:
myReverse([], []). % base case
myReverse([Head|Tail], Reversed) :-
myReverse(Tail, TailReversed), % recursive call
add_to_tail(Head, TailReversed, Reversed). % Put Head onto the end
add_to_tail(X, [],[X]). % base case
add_to_tail(X, [H|T], [H|Out]) :-
add_to_tail(X, T, Out). % recursive call, work done on exit
使用累加器效率更高。祝您好运学习Prolog。