Mais determinismo para `memberd / 2`?
Muitos sistemas fornecem uma implementação pura e eficiente demember/2
. Em particular, nenhum ponto de escolha é deixado em aberto para:
?- member(b,[a,b]).
true.
Considerando que uma aplicação ingénua demember/2
produz sim:
?- member(b,[a,b]).
true ;
false.
o que certamente é correto do ponto de vista declarativo, mas menos eficiente.
Por outro lado, existem alguns problemas técnicos commember/2
. Permite soluções redundantes, como em:
?- member(a,[a,a]).
true ;
true.
memberd/2
resolve esse problema usandoif_/3
e(=)/3
.
memberd(E, [X|Xs]) :-
if_(E = X, true, memberd(E, Xs)).
?- memberd(a,[a,a]).
true.
Infelizmente, essa definição deixa em aberto os pontos de escolha - produzindo; false
("sobras de pontos de escolha") em situações em que o membro não:
?- memberd(X,[a,b]).
X = a ;
X = b ;
false. % BAD - to be avoided!
?- member(X,[a,b]).
X = a ;
X = b.
Então, minha pergunta: existe uma definição dememberd/2
que evita o ponto de escolha como este acima?