Identity vs. Equality in Prolog

I’m using: SWI-Prolog version 9.2.7

My code looks like this:

isP(red).
isP(red).
isP(blue).
pairs(X, Y) :-
  isP(X),
  isP(Y),
  dif(X, Y).

Result for query “pairs(X, Y)” is

X = red,
Y = blue ;
X = red,
Y = blue ;
X = blue,
Y = red ;
X = blue,
Y = red ;

I do not understand this and would have two questions:

  1. Why are the first two facts not considered the same?
  2. Why is the same result given twice?

Because they exist as 2 facts. Prolog doesn’t automatically remove duplicates.

Use e.g. distinct/2 to remove unwanted duplicates.

Strange to me.
Because I am reasoning about the atom “red”, not the memory region it is stored.

Guarding against duplicates takes some CPU activity. Also, it’s not impossible that duplicates are intentional.

Only the programmer knows the intention, the grouping subtleties, and the appropriate points (whether for performance or for logic) to group.

A SQL database has the distinct and group by keywords for similar reasons.

An example of grouping subtleties:

?- distinct([X], (member(X, [1, 2]), member(Y, [3, 4]))).
X = 1,
Y = 3 ;
X = 2,
Y = 3 ;
false.

This is grouping by X, and using the first occurrence of Y, so Y = 4 is filtered out.

This is showing Prolog’s relational aspect, similar to a relational database.

1 Like

They are the same terms. But there are two distinct derivations.

If I really want to have two distinct derivations, I would model it this way:

isP([id1, red]).
isP([id2, red]).
isP([id1, blue]).
pairs([Idx, X], [Idy, Y]) :-
  isP([Idx, X]),
  isP([Idy, Y]),
  dif(X, Y).

My use case is to prevent duplicate facts if facts are generated.

Some methods: How to detect duplicate facts in the knowledge base? - #12 by peter.ludemann