So come rimuovere un elemento da un elenco ma esiste un modo per rimuovere più di un elemento da un elenco? Ad esempio,Prolog rimuovi elementi multipli da un elenco
deletelist([a,b,c,a,b],[a,c],X)
X = [b,b] % delete a and c from the list.
So come rimuovere un elemento da un elenco ma esiste un modo per rimuovere più di un elemento da un elenco? Ad esempio,Prolog rimuovi elementi multipli da un elenco
deletelist([a,b,c,a,b],[a,c],X)
X = [b,b] % delete a and c from the list.
Per rimuovere più elementi, si controlla se un elemento è nel secondo elenco e rimuoverla quando la condizione è vera:
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 offre 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).
Per rimuovere un singolo elemento in una lista c'è una funzione di libreria 'delete/3' che contiene un elenco e un elemento che si desidera rimuovere da quell'elenco e restituisce il nuovo elenco con l'elemento rimosso. Ho fatto uso di questo e ho superato l'elenco degli articoli che devono essere rimossi dalla lista.
Qui è una definizione che produce sempre risposte corrette (terminazione modulo):
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).
Utilizzando tfilter/3
e memberd_truth/3
da altre risposte. Nel caso in cui il tuo Prolog non supporti dif/2
, vedi iso_dif/2
per un'approssimazione sicura.
Alcune delle domande più insoliti che vengono ancora fuori corretta:
?- deletelist([a], [X], Zs).
X = a,
Zs = [] ;
Zs = [a],
dif(X, a) ;
false.
?- deletelist([X], [Y], [X]).
dif(X, Y) ;
false.
Ed ecco alcune query che in realtà dovrebbe fallire (e quindi terminare), ma piuttosto loop. Si noti che il ciclo è di gran lunga migliore di una risposta errata.
?- deletelist([a], Zs, Zs).
ERROR: Out of global stack
?- deletelist(Xs, Xs, Xs).
Xs = [] ;
ERROR: Out of local stack
Avrei inserito il! tra membro e deleteList. – Vincent
'deletelist ([a], [a], [a]).' Succede, ma dovrebbe fallire. – false