Prolog 高阶归约谓词

S0r*_*rin 5 prolog higher-order-functions meta-predicate

我们可以将高阶映射谓词定义为:

map([], [], F).
map([A|As], [B|Bs], F) :-
   call(F, A, B),
   map(As, Bs, F).
Run Code Online (Sandbox Code Playgroud)

同样,我们可以将fold (left)定义为:

fold([], Acc, Acc, _F).
fold([A|As], B, Acc1, F) :-
   call(F, Acc1, A, Acc2),
   fold(As, B, Acc2, F).
Run Code Online (Sandbox Code Playgroud)

reduce(左)的正确定义是什么?我们可以这样定义吗?

reduce([A|As], Bs, F) :-   
   fold(As, Bs, A, F).
Run Code Online (Sandbox Code Playgroud)

减少(右)如下?

reduceback([], Ident, F) :-
   identity(F, Ident).
reduceback([A|As], B, F) :-
   reduceback(As, C, F),
   call(F, C, A, B).
Run Code Online (Sandbox Code Playgroud)

这些正确吗?

Cap*_*liC 4

Fold/4和reduce/3执行正确,而没有identity/1的reduceback/3是不完整的。但控制流程似乎是正确的

1 ?- fold([1,2,3],S,0,[X,Y,Z]>>(Z is X+Y)).
S = 6.

2 ?- reduce([1,2,3],S,[X,Y,Z]>>(Z is X+Y)).
S = 6.
Run Code Online (Sandbox Code Playgroud)

我已经添加了声明

:-元谓词折叠(+,?,+,3)。
:- 元谓词减少(+,?,3)。

将参数限定为闭包,并使用库(yall)作为 lambdas...

在 Prolog 中,一个常见的约定是将输出参数放在最后,所以你的定义对我来说相当难以理解......

编辑

对于reduce/3的对称性,identity/1似乎没用,可以使用最后一个元素来代替:所以它可以是

:- meta_predicate reduceback(+,?,3).

reduceback([Last],Last,_F).
reduceback([A|As],B,F):-
  reduceback(As,C,F),
  call(F,C,A,B).
Run Code Online (Sandbox Code Playgroud)

测试:

?- reduceback([1,2,3],S,[X,Y,Z]>>(Z is X+Y)).
S = 6 ;
false.

?- reduceback([1,2,3],S,[X,Y,Z]>>(Z is X-Y)).
S = 0 ;
false.
Run Code Online (Sandbox Code Playgroud)