1

I've been working with this for a while. I came to a solution for a typical prolog exercice, to remove all the ocurrences of an element in a list... But I've been trying to figure out how to remove them if there are lists inside the list.

This is the furthes I've come with:

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).

Doing this call:

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

It fails with this:

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] ? 

If there a way to change the value of a variable in prolog?

I explain myself:

When I wrote this:

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

I thought that the value of Lres would be replaced by Ac, but indeed it is comparing Lres with Ac which is false, but I don't get why it does work when Lres is empty. From the same call here is the trace for that case:

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

I've been thinking a while in this and I don't see any other way to do this!

4

1 回答 1

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].
于 2013-03-10T20:15:38.760 回答