删除包含prolog中列表的列表中元素的出现

时间:2013-03-10 18:27:11

标签: prolog

我一直在研究这个问题。我找到了一个典型的prolog exercice的解决方案,删除列表中元素的所有发生...但是如果列表中有列表,我一直在试图找出如何删除它们。

这是我带来的加速:

delete(X, Y, Lres) :- 
delete(X, Y, [], Lres).

delete([], Y, Ac, Lres):-
Lres = Ac.

delete([H|T], Y, Ac, Lres):-
is_list(H),
delete(H, Y, Ac, Lres),
delete(T, Y, Lres, Lres).

delete([H|T], Y, Ac, Lres):-
H = Y,
delete(T, Y, Ac, Lres).

delete([H|T], Y, Ac, Lres):-
delete(T, Y, [H|Ac], Lres).

拨打此电话:

[trace] 23 ?- delete([1, 2, [3, 1,3], 4, 5, 3], 2, LRes).

它失败了:

Call: (13) delete([], 2, [3, 5, 4, 3, 1, 3, 1], [3, 1, 3, 1]) ? creep
Call: (14) [3, 1, 3, 1]=[3, 5, 4, 3, 1, 3, 1] ? creep
Fail: (14) [3, 1, 3, 1]=[3, 5, 4, 3, 1, 3, 1] ? 

如果有办法在prolog中更改变量的值?

我自己解释一下:

当我写这篇文章时:

delete([], Y, Ac, Lres):-
Lres = Ac.

我认为Lres的值会被Ac取代,但实际上它是将Lres与Ac进行比较,这是假的,但我不明白为什么当Lres为空时它会起作用。来自同一个电话的是这种情况的追踪:

Call: (13) delete([], 2, [3, 1, 3, 1], _G1276) ? creep
Call: (14) _G1276=[3, 1, 3, 1] ? creep
Exit: (14) [3, 1, 3, 1]=[3, 1, 3, 1] ? creep

我在这方面已经考虑了一段时间,我没有看到任何其他方法来做到这一点!

1 个答案:

答案 0 :(得分:2)

我认为你做的比你需要的更复杂:你为什么要引入一个额外的论点?简单匹配似乎导致了一个简单的解决方案:

delete([], _, []).
delete([E|Es], E, Rs) :-
    !, delete(Es, E, Rs).
delete([L|Es], E, [D|Rs]) :-
    is_list(L),
    !, delete(L, E, D),
    delete(Es, E, Rs).
delete([N|Es], E, [N|Rs]) :-
    delete(Es, E, Rs).

,这会产生

?- delete([1, 2, [3, 1, 2, 3], 4, 5, 3], 2, LRes).
LRes = [1, [3, 1, 3], 4, 5, 3].