Shiloh_C
Shiloh_C

Reputation: 197

Prolog, find friend of friend

I'm new to Prolog. I'm trying to write a query to check if a person is the friend or friend of friend of another person.

I have some facts like this:

friends(joe, [john, ann, pete, ellen, 
          maria, jose, bruno, ali, jing, yang]).
friends(john, [rick]).
friends(ellen, [mia, xing, jun, maria]).
friends(maria, [pete, ellen, zhang, jose, serena]).
friends(serena, [ali, rick, zhang, mia]).
friends(jose, [maria, jose, bruno, ali, jing]).

My target is to write a query like this:

visible(joe, ann).
true

I have made something like this:

visible(X,Y) :- friends(X,[Y|T]); member(Y,T).
visible(X,Y) :- visible(X,Z), visible(Z,Y).

member(X,[X|T]). 
member(X,[H|T]) :- member(X,T).

But it becomes an infinite loop. I don't know how to write the base case.

The relationship is a graph with loop. Is there anyway to recursively find the friend of friend, transitively?

Upvotes: 2

Views: 1147

Answers (1)

damianodamiano
damianodamiano

Reputation: 2662

visible(X,Y):- friends(X,YS), member(Y,YS).
visible(X,Y):- friends(X,XF), friends(Y,YF), member(Z,XF), member(Z,YF).

The first line checks if two people are directly friends (Y is in the list of friends of X). The second line checks if two peolpe are friend of friends (an element Z is both in the list of friends of X and Y. If you also want to know wich is the friend in common you could add write(Z)). In this case, for instance, joe is friend of john but no viceversa. If you want also this property you should add

visible(X,Y):- friends(Y,XS), member(X,XS).

Queries:

?-visible(john,serena).
true.

?-visible(joe,john).
true.

?-visible(john,joe).
true. (only if you add the third line of code).

Upvotes: 1

Related Questions