Prolog:Maplist 将结果附加到主列表而不是子列表

Prolog: Maplist appending results to main list instead of sublists

所以我将简单的谓词定义为

pred(Info, List, Result) :-
  maplist(pred_calculate(Info), List, Result).

pred_calculate returns 对列表元素进行操作后的 X 元素列表,因此例如 pred_calculate(Info, List, Result) 会 return 类似于 [2,3,5]

我想将 pred_calculate 谓词应用于 List 的所有元素的所有结果相加,我 运行 遇到的问题是目前它正在添加pred_calculate 中的所有结果作为子列表,而不是仅添加到单个主列表。

所以现在 Result returns [[2,3,5],[5,7,8],[8,9,11]] 应该 return 只有 [2,3,5,5,7,8,8,9,11]

我将如何更改它以解决此问题?

maplistListResult 的每个对应元素上调用 pred_calculate(Info)。如果 pred_calculate 在每次调用时都会生成一个列表,那么也许 maplist 不是您真正想在这里使用的,因为它不是 1-1 对应关系。你有一个一对多,你想要一个大而扁平的列表。您可以按照 !joel76 的建议使用 flattenfold。或者,您可以 "manually" 编写自己的 maplist 类谓词,这非常简单 - 只是一个基本的列表递归,可能使用附加来实现每个步骤:

pred(Info, List, Result) :-
    pred(Info, List, [], Result).

pred(Info, [], Result, Result).
pred(Info, [H|T], Acc, Result) :-
    pred_calculate(Info, H, R),
    append(Acc, R, Acc1),
    pred(Info, T, Acc1, Result).

foldl/4append/3 一起使用时,如果项目的顺序很重要,则必须以正确的顺序传递参数才能追加1:

pred(Info, List, Result) :-
    maplist(pred_calculate(Info), List, List1),
    foldl([A, B, C] >> append(B, A, C), List1, [], Result).

此外,flatten/2 会达到相同的结果,即:

pred(Info, List, Result) :-
    maplist(pred_calculate(Info), List, List1),
    flatten(List1, Result).

1: foldl(append, List1, [], Result) 会给你 [8,9,11,5,7,8,2,3,5] 作为结果。