2013-02-25 67 views
0

我我有代码:序言查找并删除谓词

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,_)]包含的内容。任何人都可以帮我解决我所错过的问题吗?

+0

您正在停止第一场比赛。您需要继续搜索,直到您点击列表的末尾。 – 2013-02-25 12:29:34

回答

0

有技术性并发症,是值得大家注意的,如果你遵循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)]. 

请注意,某些图书馆都有特定的功能,如exclude在SWI-Prolog的/ 3,但你仍然需要注意避免绑定:

eq([(E,_)|_], (E,_)). 
locdiff(L, E, R) :- 
    exclude(eq(E), L, R). 
0

可能是你需要的东西魔神是:

locdiff([], _, []). 

locdiff([(b,_)|T], [(b,_)], T1) :- 
    !, locdiff(T, [(b,_)], T1). 

locdiff([H|T], L2, [H|T2]) :- 
    locdiff(T, L2, T2). 

但是,为什么你写的[A | _]如果列表中只有一个元素?

[编辑]我忘了!第二个规则