Aquí va una implementación:
subset([], []).
subset([E|Tail], [E|NTail]):-
subset(Tail, NTail).
subset([_|Tail], NTail):-
subset(Tail, NTail).
Se generará todos los subconjuntos, aunque no en el orden que se muestra en tu ejemplo
Según la petición comentarista aquí va una explicación:
La primera cláusula es el caso base. Establece que la lista vacía es un subconjunto de la lista vacía.
La segunda y tercera cláusulas se refieren a la recursividad. La segunda cláusula establece que si dos listas tienen la misma Cabeza y la cola de la lista derecha es un subconjunto de la cola de la lista de la izquierda, entonces la lista de la derecha es un subconjunto de la lista de la izquierda.
La tercera cláusula establece que si saltamos el encabezado de la lista de la izquierda, y la lista de la derecha es un subconjunto de la cola de la lista de la izquierda, la lista de la derecha es un subconjunto de la lista de la izquierda.
El procedimiento que se muestra arriba genera conjuntos ordenados. Para los conjuntos desordenados podría usar permutation/3
:
unordered_subset(Set, SubSet):-
length(Set, LSet),
between(0,LSet, LSubSet),
length(NSubSet, LSubSet),
permutation(SubSet, NSubSet),
subset(Set, NSubSet).
Debería cambiar los argumentos en el predicado del subconjunto (X, Y) para que de manera natural leamos que X es un subconjunto de Y, no como lo hizo: Y es un subconjunto de X. –