I have this program in prolog, where I basically define a graph of people and I need to make some predicates that will show me which people are connected and which are the cliques. Here are the facts:
graph([person(susan, [reed, jen, andrzej, jessica]),
person(reed, [tony, jessica]),
person(jessica, [jen,susan]),
person(tony, []),
person(ken, [andrzej]),
person(jen, [tony, susan, jessica]),
person(andrzej, [susan, ken])]).
And here is the definition of my predicate named clique. It takes as parameters the graph G, and a list of persons and tries to check if the person inside the list are indeed a clique of friends.(which means that the predicate goodfriends is true for each pair of persons inside the list)
clique(G, [FriendOne, FriendTwo]):-
goodfriends(G, FriendOne, FriendTwo).
clique(G, [FriendOne | FriendList]):-
atLeastTwoElements(FriendList),
clique(G, FriendList),
goodFriendWith(G, FriendOne, FriendList).
What clique does is: if the list consists of only two people then just check these two people if they are goodfriends. If this is true then there is a clique between the two of them. If there are more than two people in the list of people then for each head of the list i.e. person check if he is a good friend with the rest of the persons in the tail of the list, and do that recursively for all the list of persons. Below are defined the rest of the helper predicates for the clique to work.
goodfriends(G, FriendOne, FriendTwo):-
getPerson(G, FriendOne, PersonOne),
getPerson(G, FriendTwo, PersonTwo),
hasFriend(PersonOne, FriendTwo),
hasFriend(PersonTwo, FriendOne).
%% checks if this friend is goodfriend with all these friends
goodFriendWith(_, _, []).
goodFriendWith(G, FriendOne, [FriendTwo | FriendList]):-
goodFriendWith(G, FriendOne, FriendList),
goodfriends(G, FriendOne, FriendTwo).
%% gets specific person by a name from the graph
getPerson([person(Name, Friends)|_], Name, person(Name, Friends)).
getPerson([_|T], Name, Result):-
getPerson(T, Name, Result).
%% checks if a person has a certain friend
hasFriend(person(_, Friends), Friend):-
member_(Friend, Friends).
member_(X, [X|_]).
member_(X, [_|Tail]) :- member_(X, Tail).
atLeastOneElement([_|_]).
atLeastTwoElements([_,_|_]).
Question
When I create the predicate named runner to test the predicate "clique":
runner(R):-
graph(G),
clique(G, R).
I want it to return all the cliques inside the graph but my result is:
?- runner(R).
R = [susan, jessica] ;
R = [susan, jen] ;
R = [susan, andrzej] ;
R = [jessica, susan] ;
R = [jessica, jen] ;
R = [ken, andrzej] ;
R = [jen, susan] ;
R = [jen, jessica] ;
R = [andrzej, susan] ;
R = [andrzej, ken] ;
R = [jen, susan, jessica] ;
R = [jessica, susan, jen] ;
R = [jen, jessica, susan] ;
R = [susan, jessica, jen] ;
R = [jessica, jen, susan] ;
R = [susan, jen, jessica] ;
ERROR: Out of local stack
What is wrong in the recursion? I know I get the correct results but for some reason after, all the results are shown it keeps recursing.
Thank you in advance.