2011-11-11 20 views
5

Eventuali duplicati:
Prolog delete: doesn't delete all elements that unify with ElementEliminazione di tutti i membri di una lista, senza unificazione in Prolog

In Prolog se si scrive questo:

delete([(1,1),(1,2),(1,1),(3,4)],(1,_),L). 

il risultato sarà:

L = [ (1, 2), (3, 4)]. 

Ciò che è normale perché la variabile _ si lega con 1 nel primo elemento e cerca ulteriori elementi di (1,1) e li elimina.

C'è un modo per impedire che questa unificazione si verifichi e l'eliminazione di tutti i membri del modulo (1, _). In tal caso il risultato deve essere: L = [(3, 4)].

risposta

3
delete_pattern([], _, []). 
delete_pattern([H|T], P, O) :- 
    ( H \= P 
    -> O = [H|O1], 
     delete_pattern(T, P, O1) 
    ; delete_pattern(T, P, O)). 

Come si può utilizzare altri predicati per il filtraggio che si tradurrebbe in un po 'diversi semantica ==/2 o [email protected]=/2.

+0

Lavori in linea di principio, ma si rompe se voci di elenco non sono sufficientemente istanziati nel momento in '/ 3' è gestito delete_pattern. – repeat

3

Ecco un'altra versione. In realtà, un puro uno:

list_el_deleted([], _, []). 
list_el_deleted([X|Xs], X, Ys) :- 
    list_el_deleted(Xs, X, Ys). 
list_el_deleted([X|Xs], E, [X|Ys]) :- 
    dif(X,E), 
    list_el_deleted(Xs, E, Ys). 

Cercando sulla query rivela le vere e proprie fonti di ambiguità nella sua dichiarazione problema:

?- list_el_deleted([(1,1),(1,2),(1,1),(3,4)],(1,X),L). 
X = 1, 
L = [ (1, 2), (3, 4)] ; 
X = 2, 
L = [ (1, 1), (1, 1), (3, 4)] ; 
L = [ (1, 1), (1, 2), (1, 1), (3, 4)], 
dif(X, 1), 
dif(X, 2), 
dif(X, 1). 

Quindi tutto dipende da ciò che X in realtà è: 1, 2, o qualcos'altro. Si noti che le versioni precedenti discusse qui dipendono l'istanza reale che rende il ragionamento molto più difficile:

?- delete([a],X, Xs), X = c. 
false. 

?- X = c, delete([a],X, Xs). 
X = c, 
Xs = [a]. 
+1

@repeat: metti la soluzione [qui] (http://stackoverflow.com/questions/8100586/prolog-delete-doesnt-delete-all-elements-that-unify-with-element#). – false