Sé cómo eliminar un elemento de una lista, pero ¿hay alguna manera de eliminar más de un elemento de una lista? Por ejemplo,Prolog eliminar elementos múltiples de una lista
deletelist([a,b,c,a,b],[a,c],X)
X = [b,b] % delete a and c from the list.
Sé cómo eliminar un elemento de una lista, pero ¿hay alguna manera de eliminar más de un elemento de una lista? Por ejemplo,Prolog eliminar elementos múltiples de una lista
deletelist([a,b,c,a,b],[a,c],X)
X = [b,b] % delete a and c from the list.
Para eliminar varios elementos, comprobamos si un elemento está en la segunda lista y quitarlo cuando la condición es verdadera:
deletelist([], _, []).
deletelist([X|Xs], Y, Z) :- member(X, Y), deletelist(Xs, Y, Z), !.
deletelist([X|Xs], Y, [X|Zs]) :- deletelist(Xs, Y, Zs).
% sorry!
deletelist(Xs,Ys,Zs) :-
findall(A,(
member(A,Xs),
\+(member(A,Ys))),
Zs).
SWI-Prolog ofrece subtract/3
:
?- subtract([a,b,c,a,b], [a,c], X).
X = [b, b].
?- listing(subtract).
lists:subtract([], _, []) :- !.
lists:subtract([A|C], B, D) :-
memberchk(A, B), !,
subtract(C, B, D).
lists:subtract([A|B], C, [A|D]) :-
subtract(B, C, D).
deletelist(Xs,[],Xs).
deletelist(Xs,[Y|Ys],Zs):-
delete(Xs,Y,As),
deletelist(As,Ys,Zs).
Para eliminar un solo elemento de una lista, hay una función de biblioteca 'eliminar/3' que toma una lista y un elemento que desea eliminar de esa lista y devuelve la nueva lista con el elemento eliminado. Utilicé esto y recreé la lista de elementos que deben eliminarse de la lista.
Aquí es una definición que siempre produce respuestas correctas (terminación de módulo):
deletelist(Xs, Ys, Zs) :-
tfilter(not(list_memberd_truth(Ys)),Xs, Zs).
not(G, E, T) :-
call(G, E, NT),
(NT = true, T = false
; NT = false, T = true
).
list_memberd_truth(Xs, X, Truth) :-
memberd_truth(X, Xs, Truth).
Usando tfilter/3
y memberd_truth/3
de otras respuestas. En caso de que su Prolog no sea compatible con dif/2
, consulte iso_dif/2
para una aproximación segura.
Algunas de las preguntas más inusuales que aún así salir correcta:
?- deletelist([a], [X], Zs).
X = a,
Zs = [] ;
Zs = [a],
dif(X, a) ;
false.
?- deletelist([X], [Y], [X]).
dif(X, Y) ;
false.
Y aquí algunas consultas que en realidad debería fallar (y así terminar), sino más bien de bucle. Tenga en cuenta que el bucle es mucho mejor que dar una respuesta incorrecta.
?- deletelist([a], Zs, Zs).
ERROR: Out of global stack
?- deletelist(Xs, Xs, Xs).
Xs = [] ;
ERROR: Out of local stack
¡Hubiera colocado el! entre miembro y deleteList. – Vincent
'deletelist ([a], [a], [a]). 'Tiene éxito, pero debería fallar. – false