Many systems provide a pure and efficient implementation of member/2
. In particular, no choice point is left open for:
?- member(b,[a,b]).
true.
whereas, a naive implementation of member/2
produces rather:
?- member(b,[a,b]).
true ;
false.
which is certainly correct from a declarative viewpoint, but less efficient.
On the other hand, there are some technical problems with member/2
. It permits redundant solutions, like in:
?- member(a,[a,a]).
true ;
true.
memberd/2
solves this problem using if_/3
and (=)/3
.
memberd(E, [X|Xs]) :-
if_(E = X, true, memberd(E, Xs)).
?- memberd(a,[a,a]).
true.
Unfortunately, this definition leaves choice points open again - producing ; false
("leftover choicepoints") in situations where member does not:
?- memberd(X,[a,b]).
X = a ;
X = b ;
false. % BAD - to be avoided!
?- member(X,[a,b]).
X = a ;
X = b.
So my question: Is there a definition of memberd/2
that avoids the choice point as this one above?