在 Prolog 中,如果你这样写:
delete([(1,1),(1,2),(1,1),(3,4)],(1,_),L).
结果将是:
L = [ (1, 2), (3, 4)].
这是正常的,因为 _ 变量在第一个元素中与 1 绑定,它会搜索 (1,1) 的其他元素并删除它们。
有没有办法防止这种统一发生并删除表单(1,_)的所有成员。在这种情况下,结果必须是:L = [ (3, 4)]。
在 Prolog 中,如果你这样写:
delete([(1,1),(1,2),(1,1),(3,4)],(1,_),L).
结果将是:
L = [ (1, 2), (3, 4)].
这是正常的,因为 _ 变量在第一个元素中与 1 绑定,它会搜索 (1,1) 的其他元素并删除它们。
有没有办法防止这种统一发生并删除表单(1,_)的所有成员。在这种情况下,结果必须是:L = [ (3, 4)]。
delete_pattern([], _, []).
delete_pattern([H|T], P, O) :-
( H \= P
-> O = [H|O1],
delete_pattern(T, P, O1)
; delete_pattern(T, P, O) ).
您可能希望使用其他谓词进行过滤,这会导致与==/2
or的语义略有不同=@=/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].