Prolog高阶规约谓词

5
我们可以将高阶 map 谓词定义为:
map([], [], F).
map([A|As], [B|Bs], F) :-
   call(F, A, B),
   map(As, Bs, F).

同样地,我们可以定义折叠(左)为:
fold([], Acc, Acc, _F).
fold([A|As], B, Acc1, F) :-
   call(F, Acc1, A, Acc2),
   fold(As, B, Acc2, F).

reduce (left)的正确定义是什么?我们可以如下定义吗?

reduce([A|As], Bs, F) :-   
   fold(As, Bs, A, F).

如下所示,进行reduceback(右)操作?

reduceback([], Ident, F) :-
   identity(F, Ident).
reduceback([A|As], B, F) :-
   reduceback(As, C, F),
   call(F, C, A, B).

这些正确吗?

1个回答

4

在没有identity/1的情况下,reduceback/3是不完整的,但是fold/4和reduce/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.

我已经添加了声明,这些声明将参数标识为闭包,并使用yall库进行lambda表达式...
在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).

测试:

?- 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.

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