Prolog removing all variables and duplicates
I need a query, which will remove me all variables and duplicates from list.
?- L = [1,2,3,X,Y,3,2], my_awesome_predicate(L, Res).
Then, Res should be: [1,2,3].
I don't care about order (it could be [2,3,1], [3,2,1] or whatever).
Unfortunately, I have a task in which I have to care about efficiency, so my main question is - can it be done faster? Currently, I have the following code:
remove_variables(, ). remove_variables([H|List], Res):- var(H), !, remove_variables(List, Res). remove_variables([H|List], [H|Res]):- remove_variables(List, Res). my_awesome_predicate(, ). my_awesome_predicate(List, Res):- sort(List, Sorted), remove_variables(Sorted, Res).
If you are using SWI then you can improve a little further with this code:
my_awesome_predicate(List, Res):- sort(List, MRes), remove_variables(MRes, Res). remove_variables([Var|Tail], NTail):- var(Var), !, remove_variables(Tail, NTail). remove_variables(Res, Res).
as it seems that SWI's sort will leave unbounded variables first (don't know if this behavior is a standard among other prolog's), so you can stop removing variables once you find the first non-variable.
Reading a bit SWI's documentation, it's stated that:
4.7.1 Standard Order of Terms Comparison and unification of arbitrary terms. Terms are ordered in the so called ``standard order''. This order is defined as follows: 1. Variables < Numbers < Atoms < Strings < Compound Terms
so it seems safe to stop removing elements when you find the first non-variable...