Prolog Reverse / 2列表输出格式

时间:2019-07-04 03:04:36

标签: prolog

我是Prolog的初学者,被困在家庭作业中。我必须建立一个谓词myReverse(XS,YS),其中XSYS的反向列表。我建立了一些逻辑,如下所示:

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的副本,因为我不想要使用累加器。同样,这个问题更多地是关于给定解决方案的输出格式,而不是解决方案本身。

1 个答案:

答案 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。