2011-11-11 28 views
5

可能重复:
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)]. 

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

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

回答

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[email protected]=/2

+0

工程原则,但如果破裂列表项在当时不够实例化'delete_pattern/3'运行。 – repeat

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

@repeat:把你的解决方案[这里](http://stackoverflow.com/questions/8100586/prolog-delete-doesnt-delete-all-elements-that-unify-with-element#)。 – false