我有代码:
locdiff([A|T], [A|_], T).
locdiff([H|T], L2, [H|T2]) :-
locdiff(T, L2, T2).
当我用它进行测试时locdiff([(a,1), (b,2), (b,3), (c,3), (c,4)], [(b,_)], L3)
,它只会找到并删除其中[(b,_)]
之一(b,2)
。我需要它来查找和删除两者(b,2)
和(b,3)
/或所[(b,_)]
包含的内容。谁能帮我解决我错过的问题?
我有代码:
locdiff([A|T], [A|_], T).
locdiff([H|T], L2, [H|T2]) :-
locdiff(T, L2, T2).
当我用它进行测试时locdiff([(a,1), (b,2), (b,3), (c,3), (c,4)], [(b,_)], L3)
,它只会找到并删除其中[(b,_)]
之一(b,2)
。我需要它来查找和删除两者(b,2)
和(b,3)
/或所[(b,_)]
包含的内容。谁能帮我解决我错过的问题?
可能是你需要一些东西:
locdiff([], _, []).
locdiff([(b,_)|T], [(b,_)], T1) :-
!, locdiff(T, [(b,_)], T1).
locdiff([H|T], L2, [H|T2]) :-
locdiff(T, L2, T2).
但是你为什么写[A| _] 如果列表中只有一个元素?
[编辑] 我忘记了!在第二条规则中
如果您遵循 larsman 的提示,有一个值得注意的技术并发症,我会以这种方式直接实施
locdiff([], _, []).
locdiff([A|T], [A|_], R) :-
!, locdiff(T, [A|_], R).
locdiff([H|T], L2, [H|T2]) :-
locdiff(T, L2, T2).
有了这个
?- locdiff([(a,1), (b,2), (b,3), (c,3), (c,4)], [(b,_)], L3).
L3 = [ (a, 1), (b, 3), (c, 3), (c, 4)].
您可以看到第一个实例被删除,最后一个实例被删除。那是因为第一个匹配绑定了匿名变量,然后禁止后面的匹配,除了最后一个(b,_)
然后一个完整的程序将读取
locdiff([], _, []).
locdiff([H|T], [A|_], R) :-
\+ \+ H = A, % double negation allows matching without binding
!, locdiff(T, [A|_], R).
locdiff([H|T], L2, [H|T2]) :-
locdiff(T, L2, T2).
现在结果就是你所需要的。
或者,您需要更精确地进行模式匹配,避免过度绑定
locdiff([], _, []).
locdiff([(A,_)|T], [(A,_)|_], R) :-
!, locdiff(T, [(A,_)|_], R).
locdiff([H|T], L2, [H|T2]) :-
locdiff(T, L2, T2).
?- locdiff([(a,1), (b,2), (b,3), (c,3), (c,4)], [(b,_)], L3).
L3 = [ (a, 1), (c, 3), (c, 4)].
请注意,某些库具有特定功能,例如SWI-Prolog 中的exclude /3,但您仍然需要注意避免绑定:
eq([(E,_)|_], (E,_)).
locdiff(L, E, R) :-
exclude(eq(E), L, R).