I have the following code: Bear in mind that while this code works on lists, these lists represent sets, so [1,1,2,2,3,3] and [1,2,3] should be equivalent.
%contains(L1, L2), returns true if L1 contains L2
contains(_, []).
contains(L1, [Head|Tail]) :- member(Head, L1), contains(L1, Tail).
%equals(L1, L2), returns true if L1 is equal to L2
equals([X|L1],[X|L2]) :- equals(L1, L2).
equals(L1, L2) :- contains(L1, L2), contains(L2, L1).
The idea is that equals([1,2,3],[1,2,1,3]) should return true. However, based on the above definition what I would expect to happen is the following:
- equals([1,2,3],[1,2,1,3]) matches the first rule, and invokes equals([2,3],[2,1,3]]).
- equals([2,3],[2,1,3]]) matches the second rule and invokes contains([2,3], [2,1,3]), contains([2,1,3], [2,3]).
- contains([2,3], [2,1,3]) fails, and equals returns No.
And yet it still works. And so do other attempts to confuse it. Can someone please explain it to me?
(Prolog implementation: SWI-Prolog Version 2.7.12)