I want to compare 2 lists, the first element should not be equal, the second one should be equal.
example database:
likes(josh,muse).
likes(sam,muse).
likes(josh,gnr).
likes(sam, radiohead).
so it should return true for same([josh,muse], [sam,muse]).
This is what I tried so far:
same([H1|R1], [H2|R2]):-
H1 \= H2,
same(R1,R2).
This returned false for every combination.
The
[Head|Tail]
Prolog notation for lists that you're using in the definition of thesame/2
predicate provides access to the list head and tail. The tail of a list is itself a (possibly empty) list. But in your case you want to access the first and the second elements, which you can do by writing[First, Second| _]
(i.e. by enumerating the elements separated by a comma; here I'm using an anonymous variable for the tail as we don't need it and therefore we can ignore it).Your predicate can be fixed by rewriting it as:
If you know that the arguments are always lists with two elements, you can simplify the predicate to:
Sample calls:
As a last note, your question is about term equality but in your solution attempt you're using term unification. These have different semantics and should not be confused.
In reading your question you first gave a database of facts
but then used list for the predicate
As Paulo answered starting with list, I will answer starting with facts.
The first thing is to create a predicate that reads the facts, does some logic and returns results.
which gives
So this needs to make sure P1 is not the same as P2.
which gives
Still two answers that are valid but essentially a duplicate. To remove these duplicates requires storing all of the results so that each new result can be checked against existing results and not added to the current results. Also before storing the results they need to be normalized so that no matter which way the names are ordered when initially created they are in the same order when comparing them before saving them.
Modifying the code to create normalized entries.
which returns
Notice that this result has the names in the same order.
Now to just save the results as they are generated and only add unique items to the result. This is done using setof/3.