Buscar varios elementos en una lista de Prolog

publicado por: Anonymous

Estoy tratando de buscar varios elementos en una lista:

buscar([]).
buscar([X|Xs]):-  member(X,[a,b,c,d,e]), buscar(Xs).

pero solo me busca
si todos los elementos de la lista son iguales da true
y
si un elemennto no es igual la consulta da false

pero eso no es lo que busco.

El resultado deberia de salir asi:

?.- buscar([a,b,c]).

true.
true.
true.

o asi:

?.- buscar([a,x,c,e]).

true.
false.
true.
true.

No sé qué estoy haciendo mal.

solución

Esto se debe a que no estás definiendo una condición de parada para la recursividad, y al recorrer toda la lista de elementos cuando se encuesta por la lista vacía, entonces esta no es miembro de la lista [a,b,c,d,e], lo cual provoca que falle la condición y todo el predicado en si.
Conclusión, para evitar esto, debes considerar el caso de la lista vacía.

buscar([]).
buscar([X|Xs]):-  member(X,[a,b,c,d,e]), buscar(Xs).

De esta forma tu predicado buscar/1 ya no fallará al terminar de recorrer la lista:

?- buscar([a,b,c]).
true

?- buscar([a,f,g]).
false

Por otro lado, sería recomendable que añadieras una condición de corte en la segunda cláusula del predicado, de esta forma evitarías hacer bactracking (buscar una solución alternativa), lo cual no tiene sentido, porque por lo que entiendo tu predicado es solo para determinar si una lista de elementos está contenida en otra lista de elementos. Añadiendo la condición de corte, buscar/1, quedaría de esta forma:

buscar([]).
buscar([X|Xs]):-  member(X,[a,b,c,d,e]), !, buscar(Xs).

Para que entiendas la diferencia:
Si realizamos la siguiente pregunta utilizando la primera definición del predicado:

?- buscar([a,b,c]).

Obtendrías las siguientes respuestas:

true;
false.

Sin embargo, utilizando la segunda definición del predicado, solo obtendríamos una respuesta, la correcta:

true.

ACTUALIZACIÓN

Teniendo en cuenta la edición de tu pregunta, te adjunto una nueva respuesta para tu caso, donde la detallo menos, porque básicamente es el mismo principio, solo que en este caso necesitas una nueva variable para instanciar el resultado, ahora el predicado sería buscar/2, quedando de la siguiente forma

buscar([], []).
buscar([X|Xs], [true|Tail]):-  member(X,[a,b,c,d,e]),! , buscar(Xs, Tail).
buscar([_|Xs], [false|Tail]):-  buscar(Xs, Tail).

Una consulta válida sería la siguiente:

?- buscar([a,x,c,e], L).
 L = [true, false, true, true]
Respondido por: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *