在Prolog中删除列表中的所有成员而不统一

时间:2011-11-11 22:18:28

标签: list prolog unification prolog-dif

  

可能重复:
  Prolog delete: doesn't delete all elements that unify with Element

如果您这样写,请在Prolog中:

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

结果将是:

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

什么是正常的,因为_变量在第一个元素中与1绑定,并且它会搜索(1,1)的其他元素并删除它们。

有没有办法防止这种统一发生并删除表单的所有成员(1,_)。 在这种情况下,结果必须是:     L = [(3,4)]。

2 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:3)

这是另一个版本。实际上,纯粹的一个:

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