我一直在研究这个问题。我找到了一个典型的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
我在这方面已经考虑了一段时间,我没有看到任何其他方法来做到这一点!
答案 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].