Многие системы обеспечивают чистую и эффективную реализацию 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
, которое позволяет избежать точки выбора, указанной выше?