Предикат сокращения пролога более высокого порядка
Мы можем определить предикат более высокого порядка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).
Являются ли они правильными?
1 ответ:
Створка/4 и уменьшить/3 правильно выполнять, а без идентичности/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 ) для лямбд...
В прологе общепринятым является размещение выходных аргументов в качестве последних, поэтому ваши определения довольно нечитабельны для меня....
edit
Для симметрии с уменьшением/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.