espos(joao,jesuina).
espos(ildefonso,vomariquinha).
espos(angelin,madalena).
espos(florinda,humberto).
espos(diogenes,marina).
espos(abraao,maria).
espos(jose,veneranda).
% progenitor(A,B) :- B e progenitor de A
progenitor(angelin,ildefonso).
progenitor(florinda,ildefonso).
progenitor(diogenes,angelin).
progenitor(abraao,angelin).
progenitor(joaoneto,angelin).
progenitor(jose,florinda).
progenitor(otto,florinda).
progenitor(diomar,diogenes).
progenitor(diomarino,diogenes).
progenitor(dimas,diogenes).
progenitor(dion,diogenes).
progenitor(dimar,diogenes).
progenitor(dilene,diogenes).
progenitor(dineia,diogenes).
progenitor(diomarono,diogenes).
progenitor(edimar,abraao).
progenitor(enice,abraao).
progenitor(elia,abraao).
progenitor(dario,jose).
homem(joao).
homem(ildefonso).
homem(angelin).
homem(diogenes).
homem(abraao).
homem(joaoneto).
homem(jose).
homem(otto).
homem(diomarino).
homem(dimas).
homem(dion).
homem(diomarono).
homem(edimar).
homem(dario).
mulher(florinda).
mulher(diomar).
mulher(dimar).
mulher(dilene).
mulher(dineia).
mulher(enice).
mulher(elia).
% Funcoes auxiliares
membro(X,[X|_]).
membro(X,[_|L]) :- membro(X,L).
% B e irmao/irma de A
irmao(A,B) :- progenitor(A,P), progenitor(B,P), A \= B.
% B e primo de A
primo(A,B) :- homem(B), progenitor(A,PA), progenitor(B,PB), irmao(PA,PB).
% B e prima de A
prima(A,B) :- mulher(B), progenitor(A,PA), progenitor(B,PB), irmao(PA,PB).
% retorna a lista de primos de S
primos(S,Ts) :- primosexceto(S,[],Ts).
primosexceto(S,E,Ts) :- primo(S,T), \+(membro(T,E)), primosexceto(S,[T|E],Tst), Ts = [T|Tst], !.
primosexceto(_,_,[]).
% retorna a lista de tias de S
primas(S,Ts) :- primasexceto(S,[],Ts).
primasexceto(S,E,Ts) :- prima(S,T), \+(membro(T,E)), primasexceto(S,[T|E],Tst), Ts = [T|Tst], !.
primasexceto(_,_,[]).
% retorna os parentes de S de grau N
parentes(S,N,Ts) :- parentesexceto(S,N,[],Ts).
parentesexceto(S,N,E,Ts) :- descendente(S,T,N), \+(membro(T,E)), parentesexceto(S,N,[T|N],Tst), Ts = [T|Tst], !.
parentesexceto(_,_,_,[]).
% X e Y tem grau de parentesco N
parentesco(X,Y,N) :- descendente(X,Y,N). % X e descendente de Y com grau N
parentesco(X,Y,N) :- descendente(Y,X,N). % Y e descendente de X com grau N
parentesco(X,Y,N) :-
descendente(X,Z,P), % X e Y sao descendentes de Z com grau P e Q
descendente(Y,Z,Q),
X \== Y, % X e Y nao sao a mesma pessoa
N is max(P,Q). % N e o maximo de P e Q
% X e descendente de grau N de Y
descendente(X,Y,1) :- progenitor(Y,X). % X e descendente de Y de grau 1 se Y e um progenitor de X
descendente(X,Y,N) :-
progenitor(Z,X), % X e descendente de Y de grau N se Z e um progenitor de X
descendente(Z,Y,M), % Z e descendente de Y de grau N
N is M+2. % N e M+1