Prolog Query Duplicates

954 views Asked by At

I've seen a few questions on this topic, however none of them really answers my question properly. I'll write a small example, here are some facts:

football(john).
football(sam).

tennis(john).
tennis(pete).

netball(sandy).

I want to create a rule that states pete likes anyone that plays football or tennis.

likes(pete, X) :- (football(X) ; tennis(X)), X \= pete.

But obviously when I query it in Prolog, john will come up twice as john plays both football and tennis. I want it to come up with john only once. How can I amend my code to do that?

Thanks in advance - Dan

3

There are 3 answers

1
mat On BEST ANSWER

One clean solution is to use your Prolog system's tabling mechanism.

For example, in SWI-Prolog, you can do this by adding the following directive at the top :

:- table likes/2.

With this directive, you get:

?- likes(pete, X).
X = john ;
X = sam.

Whereas without it, you get:

?- likes(pete, X).
X = john ;
X = sam ;
X = john.

Tabling is also known as SLG resolution.

0
CapelliC On

SWI-Prolog offers library(solution_sequences)

likes(pete, X) :- distinct( ((football(X) ; tennis(X)), X \= pete) ).

?- likes(pete, X).
X = john ;
X = sam ;
false.

It's built on the infrastructure that make tabling available, tough, so it has similar requirements on memory storage.

0
repeat On

Here's the approach mentioned by @DanielLyons in his comment to your question.

It is based on , so it is portable across different Prolog systems.

Using SICStus Prolog 4.5.0:

| ?- setof(t, likes(pete,X), _).
X = john ? ;
X = sam ? ;
no