1

So I have this code to remove any element=X from a list.

remove(X,[],L).
remove(X,[X|T],Result):- remove(X,T,Result), !.
remove(X,[H|T],[H|Result]):- remove(X,T,Result).

But when I run it, in the result I get this weird |_G19. I understand this has to do with the [Head|Tail] thingy but I can't figure out a way to get rid of it from my result.

?- remove(2,[1,2,3,2,5,6,2],R).
R = [1, 3, 5, 6|_G19].

So what's wrong with it? Why does this 6|_G19 appears? How do I get rid of it? Everything else is working as intended.

repeat
  • 18,496
  • 4
  • 54
  • 166
DieCriminal
  • 59
  • 1
  • 1
  • 8

2 Answers2

1

Your mistake is on the first clause:

remove(X,[],L).

For you the second parameter is the output, so... in this base case, what is L? that's why you're getting _G19 (a pointer to something).

If you do directly:

remove(X,[],[]).
remove(X,[X|T],Result):- remove(X,T,Result).
remove(X,[H|T],[H|Result]):- remove(X,T,Result).

You should have it

Guillermo Merino
  • 3,197
  • 2
  • 17
  • 34
1

Simply use the tfilter/3 in combination with reified term inequality dif/3:

remove(E,Xs,Ys) :- tfilter(dif(E),Xs,Ys).

Let's look at the query the OP gave in the question:

?- remove(2,[1,2,3,2,5,6,2],R).
R = [1,3,5,6].                     % succeeds deterministically

As both tfilter/3 and dif/3 are pure, we get sound answers if we ask more general queries:

?- remove(X,[A,B,C],Ys).
Ys = [     ],     X=A ,     X=B ,     X=C  ;
Ys = [    C],     X=A ,     X=B , dif(X,C) ;
Ys = [  B  ],     X=A , dif(X,B),     X=C  ;
Ys = [  B,C],     X=A , dif(X,B), dif(X,C) ;
Ys = [A    ], dif(X,A),     X=B ,     X=C  ;
Ys = [A,  C], dif(X,A),     X=B , dif(X,C) ;
Ys = [A,B  ], dif(X,A), dif(X,B),     X=C  ;
Ys = [A,B,C], dif(X,A), dif(X,B), dif(X,C).
Community
  • 1
  • 1
repeat
  • 18,496
  • 4
  • 54
  • 166