In Prolog it seems that sets are represented using lists.
For example, here is the implementation of union/3
from SWI-Prolog:
union([], L, L) :- !.
union([H|T], L, R) :-
memberchk(H, L), !,
union(T, L, R).
union([H|T], L, [H|R]) :-
union(T, L, R).
However this predicate isn't very declarative, for example:
?- union([1,2,3],X,[1,2,3,4]).
X = [1, 2, 3, 4].
which should leave some choice points, or:
?- union(X,[1,2],[1,2,3,4]).
<infinite loop>
which doesn't even work!
That aside, we also find the following problems:
?- union([1,2,3],[4,5],[1,2,3,5,4]).
false.
?- union([1,1,1],[4,5],[1,1,1,4,5]).
true.
which are obviously wrong if we would be really talking about sets.
We can clearly see that using lists to talk about sets isn't straightforward because:
- Sets are not ordered whereas lists are;
- Sets do not contain duplicate values whereas lists can.
As a consequence we either find predicates working on sets that cut possible solutions (e.g. this implementation of union which only works if the set is ordered) or predicates which provide useless choice points depending on variables' instanciation (e.g. a union predicate which would have as many choice points as the number of permutations of the resulting set).
How should predicates that work on sets be properly implemented in Prolog?
This question is very general and not specific to the example of union/3
used here.