¿Más determinismo para `memberd / 2`?
Muchos sistemas proporcionan una implementación pura y eficiente demember/2
. En particular, no se deja abierto ningún punto de elección para:
?- member(b,[a,b]).
true.
mientras que una implementación ingenua demember/2
produce más bien:
?- member(b,[a,b]).
true ;
false.
lo cual es ciertamente correcto desde un punto de vista declarativo, pero menos eficiente.
Por otro lado, hay algunos problemas técnicos conmember/2
. Permite soluciones redundantes, como en:
?- member(a,[a,a]).
true ;
true.
memberd/2
resuelve este problema usandoif_/3
y(=)/3
.
memberd(E, [X|Xs]) :-
if_(E = X, true, memberd(E, Xs)).
?- memberd(a,[a,a]).
true.
Desafortunadamente, esta definición deja los puntos de elección abiertos nuevamente - produciendo; false
("puntos de elección sobrantes") en situaciones en las que el miembro no:
?- memberd(X,[a,b]).
X = a ;
X = b ;
false. % BAD - to be avoided!
?- member(X,[a,b]).
X = a ;
X = b.
Entonces mi pregunta: ¿hay una definición dememberd/2
que evita el punto de elección como este arriba?