Prolog program to find equality of two lists in any order
isSubset([],_).
isSubset([H|T],Y):-
member(H,Y),
select(H,Y,Z),
isSubset(T,Z).
equal(X,Y):-
isSubset(X,Y),
isSubset(Y,X).
Try using predicate that checks if one of sets is a permutation of other set:
delete(X, [X|T], T).
delete(X, [H|T], [H|S]):-
delete(X, T, S).
permutation([], []).
permutation([H|T], R):-
permutation(T, X), delete(H, R, X).
(Predicate taken from http://www.dreamincode.net/code/snippet3411.htm)
?- permutation([1,2,3],[3,1,2]).
true
The actual reason for the non-termination that you observed is this: the following clause does not constrain L2
in any way, shape, or form.
equal([H1|T], L2) :- member(H1, L2), del(H1, L2, L3), equal(T, L3).
So your query ?- equal([1,2,3], X).
implies proving the goal member(_, L2)
which does not terminate universally. Therefore equal([1,2,3], X)
cannot terminate universally, too!
For more information on how to explain non-termination of Prolog code read about failure-slice!
PS. Looking at the termination problem from a different angle, we see that the non-termination is, in fact, a necessary consequence in this case.
Why? Because you do not constrain the number of multiplicities, which makes the solution set infinite in size. The set cannot be represented by a finite number of answers (provided you do not permit delaying goals).