Многие системы обеспечивают чистую и эффективную реализацию member/2. В частности, точка выбора остается открытой для:
?- member(b,[a,b]).
true.
тогда как наивная реализация member/2 дает скорее:
?- member(b,[a,b]).
true ;
false.
что, безусловно, верно с декларативной точки зрения, но менее эффективно.
С другой стороны, существуют некоторые технические проблемы с member/2. Он позволяет использовать избыточные решения, например:
?- member(a,[a,a]).
true ;
true.
memberd/2 решает эту проблему, используя if_/3 и (=)/3.
memberd(E, [X|Xs]) :-
if_(E = X, true, memberd(E, Xs)).
?- memberd(a,[a,a]).
true.
К сожалению, это определение снова оставляет открытые точки выбора - создание ; false ( "оставшихся точек выбора" ) в ситуациях, когда член не выполняет:
?- memberd(X,[a,b]).
X = a ;
X = b ;
false. % BAD - to be avoided!
?- member(X,[a,b]).
X = a ;
X = b.
Итак, мой вопрос: существует ли определение memberd/2, которое позволяет избежать точки выбора, указанной выше?