5

高次マップ述語を次のように定義できます。

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

これらは正しいですか?

4

1 に答える 1

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.

宣言を追加しました

:- meta_predicateフォールド(+,?,+,3)。
:- meta_predicate reduce(+,?,3).

引数をクロージャーとして修飾し、ラムダにライブラリ(yall)を使用しました...

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.
于 2016-01-24T22:54:53.550 に答える