Вот определение, которое всегда дает правильные ответы (по модулю завершения):
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).
Использование tfilter/3
и
memberd_truth/3
из других ответов. Если ваш пролог не поддерживает dif/2
, см. iso_dif/2
для безопасного приближения.
Некоторые из более необычных вопросов, которые все еще выходят правильными:
?- deletelist([a], [X], Zs).
X = a,
Zs = [] ;
Zs = [a],
dif(X, a) ;
false.
?- deletelist([X], [Y], [X]).
dif(X, Y) ;
false.
А здесь некоторые запросы, которые на самом деле должны давать сбой (и, следовательно, завершаться), а скорее цикл. Обратите внимание, что зацикливание намного лучше, чем неправильный ответ.
?- deletelist([a], Zs, Zs).
ERROR: Out of global stack
?- deletelist(Xs, Xs, Xs).
Xs = [] ;
ERROR: Out of local stack