是否有任何版本的Prolog支持累加器的更高阶抽象?

Mar*_*een 6 prolog mercury

我想知道一个Prolog可能包含这样的内置调用:

accum(generator, filter, accumulator)
Calculates all solutions to generator.
For each one, if filter can be proved, accumulator is proved.
Backtracks to find all solutions to filter and generator.
Accumulator may backtrack internally, but multiple proofs of accumulator are 
  conjoined, not backtracked.
Run Code Online (Sandbox Code Playgroud)

因此,例如,要在不使用递归的情况下对列表求和,您可以编写:

X is 0, accum(member(Val,List), True, X is X + Val).
Run Code Online (Sandbox Code Playgroud)

是否有任何Prolog与此结构或等效?请记住,我是Prolog的新手,可能会遗漏一些明显的东西.

Cap*_*liC 5

例如,SWI-Prolog 库(聚合)具有强大的接口

aggregate_all(sum(Val), member(Val,List), Sum)
Run Code Online (Sandbox Code Playgroud)

使用您可能感兴趣的谓词foreach/2 获得聚合和生成之间(显然很简单)变量的共享.

在SWI-Prolog中你可以做?- edit(library(aggregate)).研究内部...

库(聚合)效率相对较低,但与SWI-Prolog nb_(非可回溯)数据结构相结合应该可以很好地完成其工作...

关于非可回溯数据结构:是我的'自建'累加器的一个例子,通过nb_setarg/3实现.


Pau*_*ura 3

我想你的意思是没有显式递归?如果是这样,您可以使用高阶谓词列表左折叠的实现以及 lambda 表达式来避免需要辅助谓词。以Logtalk为例,你可以这样写:

?- Sum0 is 0, meta::fold_left([X,Y,Z]>>(Z is Y+X), Sum0, [1,2,3], Sum).
Sum0 = 0,
Sum = 6.
Run Code Online (Sandbox Code Playgroud)

Logtalk 可以使用大多数 Prolog 实现 ( http://logtalk.org/ )作为后端编译器。您还可以将 Ulrich 的lambda库 ( http://www.complang.tuwien.ac.at/ulrich/Prolog-inedit/ISO-Hiord.html ) 与受支持的 Prolog 编译器以及 Prolog 库一起使用,为相同的结果。现在以 YAP 为例:

$ yap
...
 ?- use_module(library(lambda)).
...
 ?- use_module(library(maplist)).
...
 ?- Sum0 is 0, foldl(\X^Y^Z^(Z is Y+X), [1,2,3], Sum0, Sum).
Sum = 6,
Sum0 = 0.
Run Code Online (Sandbox Code Playgroud)

简而言之,fold left 谓词迭代列表,将其第一个参数中的闭包递归地应用于列表元素和累加器,返回最终累加器值。