使用Prolog折叠并相加列表中的所有项

3

我想写一个函数,递归地将列表中前两个项目相加,并在只剩下一个项目时返回。 例如:

addList([1,2,3,4], X) 
x = [10]

(操作步骤:[1,2,3,4] -> [3,3,4] -> [6,4] -> [10] )
(以下是需要翻译的内容):

这是我目前所拥有的:

addList([],[]).
addList([H|[H2|T]], []) :- L is H+H2, addList(T, [L|T]).
addList([H|T], [H2|_]) :- L is H+H2, addList(T, [L|T]).

在我的看法中,这将会做如下事情:

addList([1,2,3,4], X).
L=1+2 --> addList([3,4], [3,3,4])
L=3+3 --> addList([4], [6, 4])
L=6+4 --> addList([], [10])

这实际上会导致一个错误 - "参数未充分实例化"。
如果我将第一个addList改为addList([],[_]).,它将首先输出X = []。,然后如果我使用; 继续,就会出现同样的错误。应该以false。结束。
(在链条X = [1,2,3,4] ; X = [3,3,4] ; X = [6,4] ; X = [10] ; false.之后)。
1个回答

1
首先,要注意你可以将[H|[H2|T]]等效地写为[H,H2|T]
此外,据我所知,在Prolog中,首选的样式是使用snake_case而不是camelCase
add_list([H1,H2|T], []) :- ...

在上述子句中,您已经将第二个术语与空列表统一起来,... 中发生的事情只是一种检查关系是否成立的方式。正文中出现的L仅是一个局部变量;同样,对add_list的递归调用不用于计算“结果”(第二个参数)。
您期望结果始终是一个包含值总和的单例列表,除非列表为空(在这种情况下结果为空)。然后基本情况如下:
add_list([], []).
add_list([N], [N]).

一般情况下,必然是这样的:

add_list([H1,H2|T], [Sum]) :- ...

您需要用H1H2TSum来表达递归关系。实际上,在达到基本情况之前,您可能只会传递未修改的第二个参数,因此您不需要明确地写出[Sum],而可以直接写Res

add_list([H1,H2|T], Res) :-
    ...,
    add_list(..., Res).

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接