Q:

Find All Relatives with Prolog

I'm having trouble wrapping my head around how I would return a list of everyone related to a certain person.  So, if I say relatives(A,B), A would be a person and B is a list of all of the people related to that person.  I can write any additional rules needed to assist in doing this.  Here is what I have so far.
man(joe).
man(tim).
man(milan).
man(matt).
man(eugene).

woman(mary).
woman(emily).
woman(lily).
woman(rosie).
woman(chris).

parent(milan, mary).
parent(tim, milan).
parent(mary, lily).
parent(mary, joe).
parent(mary, matt).
parent(chris, rosie).
parent(eugene, mary).
parent(eugene, chris).

cousins(A, B) :- parent(C, A), parent(D, B), parent(E, C), parent(E, D), not(parent(C, B)), not(parent(D, A)), A \=B.

paternalgrandfather(A, C) :- man(A), man(B), parent(B, C), parent(A, B).

sibling(A, B) :- parent(C, A), parent(C, B), A \= B.

Can someone guide me as to how I would go about doing this?  Thanks.

A:

I think that you should concentrate on the 'true' relation, i.e. parent(Old,Jung), other predicates are irrelevant here. The obvious assumption it's that atoms occurring in parent/2 are identifiers (i.e. names are unique). From this picture seems that all persons here are relatives:

Then your problem should be equivalent to find all connected vertices in parent relation. You can implement a depth first visit, passing down the list of visited nodes to avoid loops (note that you need to go back to parents and down to children!), something like
relatives(Person, Relatives) :-
    relatives([], Person, [Person|Relatives]).

relatives(Visited, Person, [Person|Relatives]) :-
    findall(Relative, immediate(Person, Visited, R), Immediates),
    ... find relatives of immediates and append all in relatives.

immediate(Person, Visited, R) :-
    (parent(Person, R) ; parent(R, Person)),
    \+ member(R, Visited).

See if you can complete this snippet. Note the order of arguments in relatives/3 is choosen to easy maplist/3.
If you are willing to study more advanced code, SWI-Prolog library(ugraph) offers a reachable(+Vertex, +Graph, -Vertices) predicate that does it on a list based graph representation.
Here the SWI-Prolog snippet to get the image (a file to be feed to dot):
graph(Fact2) :-
    format('digraph ~s {~n', [Fact2]),
    forall(call(Fact2, From, To), format(' ~s -> ~s;~n', [From, To])),
    format('}\n').

you can call in this way:
?- tell('/tmp/parent.gv'),graph(parent),told.

and then issue on command line dot -Tjpg /tmp/parent.gv | display

