我编写了以下用于反转给定列表的小知识库,
reverse_list([],[]).
reverse_list([X|L1], [L2|X]) :-
reverse_list(L1, L2).
当前执行时
reverse_list([a,b,c,d], X).
它产生,
X = [[[[[]|d]|c]|b]|a].
如果能解释一下为什么会发生这种情况,我们将不胜感激。而且,我该如何解决这个问题?
我认为最后一步L2变成了[],并且在反向传播期间它变成了那样。
如何使用此方法的修改获得类似 X = [d,c,b,a]
的输出。
P.S:我是 Prolog 的新人。
最佳答案
您可以用代数方式推理 Prolog 程序。
为了向您展示一种方法,让我们考虑一个也能显示问题的更简单目标:
?- reverse_list([a], Ls). Ls = [[]|a].
为什么这个成立?
因为如果以下条件成立:
?- [a] = [X|L1], Ls = [L2|X], reverse_list(L1, L2). L1 = L2, L2 = [], Ls = [[]|a], X = a.
我只是插入了 reverse_list/2
的定义,使其等同于原始查询,因此当然仍然显示问题。
现在重点是:我们可以概括查询(只需忽略一些目标),并且仍然看到问题:
?- [a] = [X|L1], Ls = [L2|X]. L1 = [], Ls = [L2|a], X = a.
因此,很明显子句头部包含一个错误:您正在描述[Ls|a]
形式的术语。这不是一个列表,因为a
是一个原子。
+1 以获得良好的命名约定! list_reversed/2
会更好(避免强制建议其他使用模式也有意义),并且可能有更好的名称。
关于prolog - 理解序言中反向列表的实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39701206/