Существует неотъемлемая проблема с функциями фильтра, которые принимают успех или неудачу предиката в качестве критерия для фильтрации: Полученная программа больше не является чисто монотонной программой. Поэтому он теряет все свои декларативные свойства & mdash; единственное значение, которое остается, - это процедурная пошаговая интерпретация. Вот чистая, усовершенствованная версия фильтрации с использованием if_/3
:
tfilter(_CT_2, [], []).
tfilter(CT_2, [E|Es], Fs0) :-
if_(call(CT_2,E), Fs0 = [E|Fs], Fs0 = Fs ),
tfilter(CT_2, Es, Fs).
Таким образом, первый аргумент является замыканием / продолжением, которое получит еще два аргумента: элемент и полученное значение истинности.
=(X,X,true).
=(X,Y,false) :- dif(X,Y).
Теперь результаты остаются точными:
| ?- tfilter(=(X),[A,B],Xs).
B = A,
X = A,
Xs = [A,A] ? ;
X = A,
Xs = [A],
dif(A,B) ? ;
X = B,
Xs = [B],
dif(B,A) ? ;
Xs = [],
dif(X,A),
dif(X,B) ? ;
no
Существует четыре возможности фильтрации списка из двух элементов по критерию, равному X
. Каждый элемент может быть одинаковым или различным.
Недостаток этого подхода заключается в том, что необходимо предоставить уточненные версии всех критериев.