Удаление всех членов списка без объединения в прологе

Возможный дубликат:
Пролог удалить: не удаляет все элементы, которые объединяются с элементом

В Прологе, если вы напишите это:

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

результат будет:

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

Что является нормальным, потому что переменная _ связывается с 1 в первом элементе и ищет другие элементы (1,1) и удаляет их.

Есть ли способ предотвратить это объединение и удалить все элементы формы (1,_). В этом случае результат должен быть: L = [ (3, 4)].

2 ответа

Решение
delete_pattern([], _, []).
delete_pattern([H|T], P, O) :-
    (    H \= P
    ->   O = [H|O1],
         delete_pattern(T, P, O1)
    ;    delete_pattern(T, P, O) ).

Вы можете использовать другие предикаты для фильтрации, что приведет к немного другой семантике, как ==/2 или же =@=/2,

Вот другая версия. На самом деле, чистый:

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).

Попытка сделать это по вашему запросу выявляет фактические источники неоднозначности в вашей постановке задачи:

?- 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).

Так что все зависит от того, что X на самом деле это: 1, 2 или что-то еще. Обратите внимание, что предыдущие версии, обсуждаемые здесь, зависят от фактической реализации, что значительно усложняет рассуждение:

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

?- X = c, delete([a],X, Xs).
X = c,
Xs = [a].
Другие вопросы по тегам