Prolog 高阶归约谓词
Prolog Higher-order reduce predicate
我们可以定义一个高阶map谓词为:
map([], [], F).
map([A|As], [B|Bs], F) :-
call(F, A, B),
map(As, Bs, F).
同理,我们可以定义fold(左)为:
fold([], Acc, Acc, _F).
fold([A|As], B, Acc1, F) :-
call(F, Acc1, A, Acc2),
fold(As, B, Acc2, F).
reduce(左)的正确定义是什么?我们可以这样定义吗?
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).
这些正确吗?
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.
我添加了声明
:- meta_predicate fold(+,?,+,3).
:- meta_predicate reduce(+,?,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).
测试:
?- 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.
我们可以定义一个高阶map谓词为:
map([], [], F).
map([A|As], [B|Bs], F) :-
call(F, A, B),
map(As, Bs, F).
同理,我们可以定义fold(左)为:
fold([], Acc, Acc, _F).
fold([A|As], B, Acc1, F) :-
call(F, Acc1, A, Acc2),
fold(As, B, Acc2, F).
reduce(左)的正确定义是什么?我们可以这样定义吗?
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).
这些正确吗?
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.
我添加了声明
:- meta_predicate fold(+,?,+,3). :- meta_predicate reduce(+,?,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).
测试:
?- 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.