There is an inherent problem with filter functions that use the success or failure of a predicate as a filter criterion: the resulting program is no longer a pure monotonous program. Therefore, he loses all his declarative properties; the only meaning that remains is a procedural phased interpretation. Here is a clean, reworked version of filtering using 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).
Thus, the first argument is the closure / continuation, which will receive two more arguments: The element and the resulting truth value.
=(X,X,true). =(X,Y,false) :- dif(X,Y).
Now the results remain accurate:
| ?- 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
There are four possibilities by which you can filter a list of two elements by the criterion equal to X Each element may be equal or may differ.
The disadvantage of this approach is that you need to provide updated versions of all the criteria.