在Prolog中通过列表递归

在Prolog中通过列表递归,prolog,Prolog,我试图在Prolog中反转列表。当我用['item1','item2']调用它时,它工作正常,但用['item1'|'item2']调用它时就不行了。我对Prolog还处于初级阶段,但我认为这两种符号基本上是可以互换的 以下是我使用的代码: reverse_list([], Acc, Acc). reverse_list([Head|Tail], Acc, Reversed) :- reverse_list(Tail, [Head|Acc], Reversed). reverse_l

我试图在Prolog中反转列表。当我用
['item1','item2']
调用它时,它工作正常,但用
['item1'|'item2']
调用它时就不行了。我对Prolog还处于初级阶段,但我认为这两种符号基本上是可以互换的

以下是我使用的代码:

reverse_list([], Acc, Acc).
reverse_list([Head|Tail], Acc, Reversed) :-
    reverse_list(Tail, [Head|Acc], Reversed). 

reverse_list(List,Reversed) :-
    reverse_list(List,[],Reversed).
问题在于使用列表尾部进行递归调用时

当我使用list
['item1','item2']
调用它时,调试器显示它工作正常,使用尾部作为
['item2']
进行递归调用,这是应该的

当我用
['item1'|'item2']
调用它时,调试器显示它试图用'item2'进行递归调用,但失败了,可能是因为它不是一个列表

我读到当使用
[Head | Tail]
时,Tail总是一个列表,但这里的情况似乎不是这样

您能否解释一下Prolog是如何处理这些列表的,以及为什么这两种表示列表的方法不能互换?你能解释一下如何使这个代码工作吗


谢谢

列表的尾部是一个列表。例如:

| ?- [1,2,3] = [Head| Tail].
Head = 1
Tail = [2,3]
yes
您正在用作参数的复合术语,
['item1'|'item2']
,不是列表:

| ?- ['item1'|'item2'] = [Head| Tail].
Head = item1
Tail = item2
yes
您需要改为编写
[item1 |[item2]]
,这与
[item1,item2]
完全相同:

| ?- [item1|[item2]] = [item1,item2]. 
yes
由于列表表示法是语法糖,因此可以使用标准的
write\u canonical/1
谓词检查列表结构:

| ?- write_canonical([1,2,3]).       
'.'(1,'.'(2,'.'(3,[])))
yes

| ?- write_canonical([item1, item2]).
'.'(item1,'.'(item2,[]))
yes

| ?- write_canonical([item1| item2]).
'.'(item1,item2)
yes

调用
reverse_list([item1 |[item2]],Reversed)
时,当您得到
reverse_list(item2,…)
时,目标在第一次递归调用时失败,因为它与
reverse_list/3
谓词的任何子句头都不统一,因此无法证明。因此,谓词定义没有问题。只是对列表表示的误解。

[首先|休息]
。因此,在
[1,2,3,4]
中,
First=1
Rest=[2,3,4,5]
中,当我在使用它时,您可以使用
foldl
很好地定义它。首先,
cons(X,Xs,[X | Xs])。
,然后
反向(A,B):-foldl(cons,A,[],B)