
% UNIVERSIDADE DO MINHO
% MESTRADO INTEGRADO EM ENGENHARIA BIOMEDICA
% PROG. LOGICA, CONHECIMENTO E RACIOCINIO
%%%%%%%%%%%%
% GRUPO 5
% TRABALHO PRATICO 1

%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% SICStus PROLOG: Declaracoes iniciais

:- set_prolog_flag( discontiguous_warnings,off ).
:- set_prolog_flag( single_var_warnings,off ).
:- set_prolog_flag( unknown,fail ).

% necessário para o predicado getYear(X).
:-use_module(library(system)).

%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% SICStus PROLOG: definicoes iniciais

% para efectuar alteracoes na base de conhecimento
:- op( 900,xfy,'::' ).
:- dynamic progenitor/2.
:- dynamic masculino/1.
:- dynamic feminino/1.
:- dynamic casamento/3.
:- dynamic individuo/5.
:- dynamic temp/1.
:- dynamic built_in/2.

%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% CLÁUSULAS I
%--------------------------------- - - - - - - - - - -  -  -  -  -   -

%------------------------------------%
% CONSTRUÇÃO DA BASE DE CONHECIMENTO %
%------------------------------------%

% Extensao do predicado PROGENITOR: NomeProgenitor,Progenito -> {V,F}

% FAMILIA 1
progenitor('vitoria guerra','leopoldo bravo').
progenitor('vitoria guerra','eduardo bravo').
progenitor('vitoria guerra','alfredo bravo').
progenitor('vitoria guerra','artur bravo').
progenitor('vitoria guerra','beatriz bravo').
progenitor('alberto bravo','leopoldo bravo').
progenitor('alberto bravo','eduardo bravo').
progenitor('alberto bravo','alfredo bravo').
progenitor('alberto bravo','artur bravo').
progenitor('alberto bravo','beatriz bravo').

% FAMILIA 2
progenitor('leopoldo bravo','alice bravo').
progenitor('leopoldo bravo','joao bravo').
progenitor('helena barros','alice bravo').
progenitor('helena barros','joao bravo').

% FAMILIA 3
progenitor('alice bravo','eva gama').
progenitor('alice bravo','mauricio gama').
progenitor('alice bravo','artur gama').
progenitor('antonio gama','eva gama').
progenitor('antonio gama','mauricio gama').
progenitor('antonio gama','artur gama').

% FAMILIA 4
progenitor('beatriz bravo','luisa valente').
progenitor('beatriz bravo','mauricio valente').
progenitor('beatriz bravo','hugo valente').
progenitor('beatriz bravo','eva valente').
progenitor('henrique valente','luisa valente').
progenitor('henrique valente','mauricio valente').
progenitor('henrique valente','hugo valente').
progenitor('henrique valente','eva valente').

% FAMILIA 5
progenitor('luisa valente','antonio sobral').
progenitor('luisa valente','ricardo sobral').
progenitor('luisa valente','luisa sobral').
progenitor('henrique sobral','antonio sobral').
progenitor('henrique sobral','ricardo sobral').
progenitor('henrique sobral','luisa sobral').

% FAMILIA 6
progenitor('eva valente','alice mata').
progenitor('eva valente','alberto mata').
progenitor('eva valente','hugo mata').
progenitor('eva valente','eduardo mata').
progenitor('afonso mata','alice mata').
progenitor('afonso mata','alberto mata').
progenitor('afonso mata','hugo mata').
progenitor('afonso mata','eduardo mata').

% FAMILIA 7
progenitor('teresa sousa','henrique valente').
progenitor('teresa sousa','helena valente').
progenitor('teresa sousa','manuel valente').
progenitor('joaquim valente','henrique valente').
progenitor('joaquim valente','helena valente').
progenitor('joaquim valente','manuel valente').


%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensao do predicado MASCULINO: Nome -> {V,F}

masculino('alberto bravo').
masculino('eduardo bravo').
masculino('leopoldo bravo').
masculino('alfredo bravo').
masculino('artur bravo').
masculino('joao bravo').
masculino('antonio gama').
masculino('mauricio gama').
masculino('artur gama').
masculino('joaquim valente').
masculino('manuel valente').
masculino('henrique valente').
masculino('henrique sobral').
masculino('mauricio valente').
masculino('hugo valente').
masculino('afonso mata').
masculino('antonio sobral').
masculino('ricardo sobral').
masculino('alberto mata').
masculino('hugo mata').
masculino('eduardo mata').

%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensao do predicado FEMININO: Nome -> {V,F}

feminino('vitoria guerra').
feminino('helena barros').
feminino('beatriz bravo').
feminino('teresa sousa').
feminino('helena valente').
feminino('alice bravo').
feminino('luisa valente').
feminino('eva valente').
feminino('luisa sobral').
feminino('eva gama').
feminino('alice mata').


%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensao do predicado CASAMENTO: NomeConjuge1,NomeConjuge2,Data -> {V,F}

casamento('vitoria guerra','alberto bravo',1902).
casamento('helena barros','leopoldo bravo',1924).
casamento('alice bravo','antonio gama',1950).
casamento('beatriz bravo','henrique valente',1926).
casamento('eva valente','afonso mata',1955).
casamento('luisa valente','henrique sobral',1953).
casamento('teresa sousa','joaquim valente',1900).


%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensao do predicado INDIVIDUO: Nome , Naturalidade , DataNascimento , DataMorte , InformacaoHemofilica -> {V,F}

individuo('vitoria guerra',braga,1883,1941,1).
individuo('alberto bravo',braga,1881,1937,0).
individuo('leopoldo bravo',braga,1906,1938,1).
individuo('eduardo bravo',braga,1905,1917,1).
individuo('alfredo bravo',braga,1910,1969,0).
individuo('artur bravo',braga,1910,1981,0).
individuo('beatriz bravo',braga,1908,1992,1).
individuo('helena barros',maia,1903,1966,0).
individuo('joao bravo',maia,1926,1997,0).
individuo('alice bravo',maia,1929,2012,1).
individuo('antonio gama',porto,1928,2008,0).
individuo('eva gama',porto,1951,viva,1).
individuo('mauricio gama',porto,1956,1972,1).
individuo('artur gama',porto,1960,vivo,0).
individuo('teresa sousa',guimaraes,1880,1918,0).
individuo('joaquim valente',guimaraes,1879,1924,0).
individuo('manuel valente',guimaraes,1910,1912,0).
individuo('helena valente',guimaraes,1912,1913,0).
individuo('henrique valente',guimaraes,1906,1983,0).
individuo('luisa valente',guimaraes,1930,2005,0).
individuo('mauricio valente',guimaraes,1927,1951,1).
individuo('hugo valente',guimaraes,1929,1949,1).
individuo('eva valente',guimaraes,1933,2001,1).
individuo('henrique sobral',braga,1931,1982,1).
individuo('luisa sobral',braga,1954,viva,1).
individuo('ricardo sobral',braga,1956,vivo,0).
individuo('antonio sobral',braga,1957,vivo,0).
individuo('afonso mata',coimbra,1930,vivo,0).
individuo('alice mata',coimbra,1957,viva,1).
individuo('alberto mata',coimbra,1958,1965,1).
individuo('hugo mata',coimbra,1959,vivo,0).
individuo('eduardo mata',coimbra,1963,vivo,1).


%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% CLÁUSULAS II
%--------------------------------- - - - - - - - - - -  -  -  -  -   -

%---------------------%
% RELAÇÕES FAMILIARES %
%---------------------%

% Extensao do predicado PAI: Pai,Filho/a -> {V,F}

pai(P,F) :- progenitor(P,F), masculino(P).


%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensao do predicado MÃE: Mae,Filho/a -> {V,F}

mae(M,F) :- progenitor(M,F), feminino(M).


%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensao do predicado FILHOS: Filho/a,Progenitor-> {V,F}

filhos(Y,X) :- progenitor(X,Y).


%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensao do predicado FILHO: Filho,Progenitor-> {V,F}

filho(Y,X) :- progenitor(X,Y), masculino(Y).


%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensao do predicado FILHA: Filha,Progenitor -> {V,F}

filha(Y,X) :- progenitor(X,Y), feminino(Y).


%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensao do predicado IRMÃOS: Irmao/a,Irmao/a -> {V,F}

irmaos(X,Y) :- pai(Z,X), pai(Z,Y), mae(W,X), mae(W,Y), X \= Y.


%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensao do predicado IRMÃO: Irmao,Irmao/a -> {V,F}
    
irmao(X,Y) :- masculino(X), irmaos(X,Y).
  
  
%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensao do predicado IRMÃ: Irma,Irmao/a -> {V,F}
    
irma(X,Y) :- feminino(X), irmaos(X,Y).


%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensao do predicado AVOS: Avó/Avô,Neto -> {V,F}

avos(A,N) :- progenitor(A,F), progenitor(F,N).


%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensao do predicado AVÓF: Avó,Neto -> {V,F}

avof(A,N) :- avos(A,N), feminino(A).


%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensao do predicado AVÔM: Avô,Neto -> {V,F}

avom(A,N) :- avos(A,N), masculino(A).


%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensao do predicado NETOS: Netos,Avo -> {V,F}

netos(N,A) :- avos(A,N).


%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensao do predicado NETO: Neto,Avo -> {V,F}

neto(N,A) :- avos(A,N),masculino(N).


%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensao do predicado NETA: Neta,Avo -> {V,F}

neta(N,A) :- avos(A,N),feminino(N).


%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensao do predicado BISAVÓS: bisavos/bisneto -> {V,F}

bisavos(B,N) :- grau(N,B,G), G=3.


%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensao do predicado BISAVÔ: bisavô/bisneto -> {V,F}

bisavom(B,N) :- grau(N,B,G), masculino(B), G=3.


%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensao do predicado BISAVÓ: bisavó/bisneto -> {V,F}

bisavof(B,N) :- grau(N,B,G), feminino(B), G=3.

%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensao do predicado BISNETOS: bisnetos,bisavo -> {V,F}

bisnetos(N,B) :- bisavos(B,N).


%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensao do predicado BISNETO: bisneto,bisavo -> {V,F}

bisneto(N,B) :- bisavos(B,N), masculino(N).

%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensao do predicado BISNETA: bisneta,bisavo -> {V,F}

bisneta(N,B) :- bisavos(B,N), feminino(N).


%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensao do predicado TIOS: Tio/a,Sobrinho/a -> {V,F}
    
tios(X,W) :- irmaos(X,Y), progenitor(Y,W).

tios(X,Z) :- casamento(X,Y), irmaos(Y,W), progenitor(W,Z).
    

%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensao do predicado TIO: Tio,Sobrinho/a -> {V,F}
    
tio(X,W) :- masculino(X), tios(X,W).
    

%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensao do predicado TIA: Tia,Sobrinho/a -> {V,F}
    
tia(X,W) :- feminino(X), tios(X,W).
   
 
%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensao do predicado SOBRINHOS: Sobrinho/a,Tio/a -> {V,F}
    
sobrinhos(X,Y) :- progenitor(Z,X), irmaos(Z,Y).


%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensao do predicado SOBRINHO: Sobrinho,Tio/a -> {V,F}
    
sobrinho(X,Y) :- masculino(X), sobrinhos(X,Y).


%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensao do predicado SOBRINHA: Sobrinha,Tio/a -> {V,F}
    
sobrinha(X,Y) :- feminino(X), sobrinhos(X,Y).


%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensao do predicado PRIMOS: Primo/a,Primo/a -> {V,F}
    
primos(X,Y) :- progenitor(Z,X), tios(Z,Y).


%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensao do predicado PRIMO: Primo,Primo/a -> {V,F}
    
primo(X,Y) :- progenitor(Z,X), tios(Z,Y),masculino(X).


%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensao do predicado PRIMA: Prima,Primo/a -> {V,F}
    
prima(X,Y) :- progenitor(Z,X), tios(Z,Y),feminino(X).


%--------------------------------- - - - - - - - - - -  -  -  -  -   -

%------------------------------------%
% DEPENDENTES DE RELAÇÕES FAMILIARES %
%------------------------------------%

% Extensao do predicado GRAU: descendente,ascendente,grau -> {V,F}

grau(X,Y,1) :- filhos(X,Y).
grau(X,Y,G) :- filhos(X,P), grau(P,Y,N), G is N+1.

 
%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensao do predicado DESCENDENTE: descendente,ascendente  -> {V,F}

descendente(X,Y) :- filhos(X,Y).
descendente(X,Y) :- filhos(X,P), descendente(P,Y).


%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensao do predicado ANTECESSOR: ascendente,descendente  -> {V,F}

antecessor(X,Y) :- progenitor(X,Y).
antecessor(X,Y) :- progenitor(X,Z), antecessor(Z,Y).

%--------------------------------- - - - - - - - - - -  -  -  -  -   -
%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensao do predicado ASCENDE: Individuo,Grau,ListaAntecessores -> {V,F}

ascende(X,G,S) :- solucoes(L,(grau(X,L,G)),S).


%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensao do predicado DESCENDE: Individuo,Grau,ListaDescendentes -> {V,F}

descende(X,G,S) :- solucoes(L,(grau(L,X,G)),S).

%--------------------------------- - - - - - - - - - -  -  -  -  -   -
%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensao do predicado RELACAO: Nome,Nome,Resultado -> {V,F}
    
relacao(X,Y,R) :-
    mae(X,Y),
    R=mae;
    pai(X,Y),
    R=pai.
relacao(X,Y,R) :-
    filho(X,Y),
    R=filho;
    filha(X,Y),
    R=filha.
relacao(X,Y,R) :-
    irmao(X,Y),
    R=irmao;
    irma(X,Y),
    R=irma.
relacao(X,Y,R) :-
    avof(X,Y),
    R=avo_feminino;
    avom(X,Y),
    R=avo_masculino.
relacao(X,Y,R) :-
    neto(X,Y),
    R=neto;
    neta(X,Y),
    R=neta.
relacao(X,Y,R) :-
    tio(X,Y),
    R=tio;
    tia(X,Y),
    R=tia.
relacao(X,Y,R) :-
    sobrinho(X,Y),
    R=sobrinho;
    sobrinha(X,Y),
    R=sobrinha.
relacao(X,Y,R) :-
    primo(X,Y),
    R=primo;
    prima(X,Y),
    R=prima.
relacao(X,Y,R) :-
    bisavof(X,Y),
    R=bisavo_feminino;
    bisavom(X,Y),
    R=bisavo_masculino.
relacao(X,Y,R) :-
    bisneto(X,Y),
    R=bisneto;
    bisneta(X,Y),
    R=bisneta.
relacao(F,M,R) :-
    casado(F,M),
    R=conjuge.


%--------------------------------- - - - - - - - - - -  -  -  -  -   -

%-----------%
% CASAMENTO %
%-----------%

% Extensao do predicado DATACASAMENTO: Conjuge,Conjuge,DataCasamento -> {V,F}

datacasamento(F,M,D) :- casamento(M,F,D).
datacasamento(F,M,D) :- casamento(F,M,D).


%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensao do predicado CASADO: Conjuge,Conjuge -> {V,F}

casado(F,M) :- casamento(M,F,D).
casado(F,M) :- casamento(F,M,D).


%--------------------------------- - - - - - - - - - -  -  -  -  -   -

%--------------------------%
% DEPENDENTES DO INDIVÍDUO %
%--------------------------%

% Extensao do predicado NATURALIDADE: Pessoa,Local -> {V,F}

localidade(N,L) :- individuo(N,L,DN,DM,H).


%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensao do predicado IDADE: Nome,Idade -> {V,F}

idade(N,I) :- vivo(N), individuo(N,L,DN,DM,H), A= 2012, I is A-DN.

idade(NF,I) :- falecido(NF), I='O individuo '+NF+'ja faleceu. Para saber a idade do respectivo aquando da morte, por favor utilize o predicado idademorte.'.


%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensao do predicado IDADEMORTE: Nome,Idade_Morte -> {V,F}

idademorte(N,I) :- falecido(N), individuo(N,L,DN,DM,H), number(DM), I is DM-DN.


%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensao do predicado FALECIDO: Nome -> {V,F}

falecido(N) :- individuo(N,L,DN,DM,H), number(DM).


%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensao do predicado VIVO: Nome -> {V,F}

vivo(N):- individuo(N,L,DN,DM,H), nao(number(DM)).


%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensao do predicado ANALISE: Nome,Resultado -> {V,F}

analise(N,R) :- individuo(N,L,DN,DM,H), H is 1, feminino(N), R= 'Individuo Portador do gene'.

analise(N,R) :- individuo(N,L,DN,DM,H), H is 1, masculino(N), R='Individuo Hemofilico'.

analise(N,R) :- individuo(N,L,DN,DM,H), H is 0, R='Individuo Normal'.


%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensao do predicado PROBABILIDADE: NomePai,NomeMae,Resultado -> {V,F}

probabilidade(NP,NM,R) :-
    (individuo(NP,LP,DNP,DMP,HP),
    HP is 1),
    (individuo(NM,LM,DNM,DMM,HM),
    HM is 0),
    R = '50% Hemofilico, 50% Normal'.

probabilidade(NP,NM,R) :-
    (individuo(NP,LP,DNP,DMP,HP),
    HP is 0),
    (individuo(NM,LM,DNM,DMM,HM),
    HM is 1),
    R = '25% Hemofilico, 25% Normal, 50% Portador'.

probabilidade(NP,NM,R) :-
    (individuo(NP,LP,DNP,DMP,HP),
    HP is 1),
    (individuo(NM,LM,DNM,DMM,HM),
    HM is 1),
    R = '50% Hemofilico, 25% Normal, 25% Portador'.

probabilidade(NP,NM,R) :-
    (individuo(NP,LP,DNP,DMP,HP),
    HP is 0),
    (individuo(NM,LM,DNM,DMM,HM),
    HM is 0),
    R = 'Individuo Normal'.


%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensao do predicado SOLUCOES: {V,F}

solucoes(T,Q,S) :- inserir(T,Q),
                   construir([],S).

inserir(T,Q) :- call(Q),
                 assert(temp(T)),
                 fail.

inserir(_,_).

construir(B,S) :- temp(T),
                retract(temp(T)),
                construir([T|B],S),
                !.
construir(S,S).

%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensão do predicado que permite a evolucao do conhecimento

evolucao( T ) :- solucoes( I, +T::I, L ),
		 inserir( T ),
		 teste( L ).

inserir( T ) :- assert( T ).
inserir( T ) :- retract( T ),!,fail.

teste( [] ).
teste( [R|LR] ) :- R, teste( LR ). 


%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensão do predicado que permite a remocao do conhecimento

regressao( T ) :- solucoes( I,-T::I,L ),
    		  teste( L ),
    		  remove(T).

remove( T ) :- retract( T ).
remove( T ) :- assert( T ),!,fail.


%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensão do predicado COMPRIMENTO: L,N -> V,F

comprimento([],0).
comprimento([X|L],N):- comprimento(L,M), N is M+1.


%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensao do predicado NAO: Questao -> {V,F}

nao(Questao):-
	Questao,!,fail.
nao(Questao).


%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensao do predicado GETYEAR: ano -> {V,F}

getYear(YEAR):-
	datime(datime(Y,M,D,H,Min,Sec)),
	YEAR = Y.

% obtem o ano actual da data do sistema


%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% INVARIANTES
%--------------------------------- - - - - - - - - - -  -  -  -  -   -

%-----------------------------------------%
% INVARIANTES - INSERCAO DE CONHECIMENTO  %
%-----------------------------------------%

% A informacao relativa a relacao progenitor, quando existe, apenas pode constar uma unica vez.
+progenitor(P,F) :: (solucoes( (P,F),progenitor(P,F),S ), comprimento(S,N),N==1).

% A informacao de um individuo quanto ao genero masculino apenas pode existir uma unica vez
+masculino(X) :: (solucoes(X,masculino(X),S),comprimento(S,N),N==1).

% A informacao de um individuo quanto ao genero feminino apenas pode existir uma unica vez
+feminino(X) :: (solucoes((X),(feminino(X)),S),comprimento(S,N),N==1).

% Os dados relativos a um determinado individuo so podem ser inseridos uma vez, ou seja, nao pode haver informação repetida
+individuo(X,L,DN,DM,H) :: (solucoes((X,L,DN,DM,H),(individuo(X,L,DN,DM,H)),S),comprimento( S,N ), N == 1).

% Um pessoa apenas pode ter um ou nenhum conjuge (para o sexo masculino)
+casamento(F,M) :: (solucoes( (Fs),(casamento( Fs,M )),S ),comprimento( S,C ), C =< 1).

% Um pessoa apenas pode ter um ou nenhum conjuge (para o sexo feminino)
+casamento(F,M) :: (solucoes( (Ms),(casamento( F,Ms )),S ),comprimento( S,C ), C =< 1).


%--------------------------------- - - - - - - - - - -  -  -  -  -   -

%-----------------------------------------%
%  INVARIANTES - REMOCAO DE CONHECIMENTO  %
%-----------------------------------------%

% nao remover individuo equanto tiver informacao associada ao seu genero
-individuo(N,L,DN,DM,H) :: (solucoes( N,(masculino(N);feminino(N)),S ),comprimento( S,C ), C == 0).

% nao remover individuo enquanto tiver informacao que é progenitor de alguem
-individuo(N,L,DN,DM,H) :: (solucoes( N,progenitor(N,X),S ),comprimento( S,C ), C == 0).

% nao remover individuo enquanto tiver informacao de casamento com alguem
-individuo(N,L,DN,DM,H) :: (solucoes( N,(casamento(N,X,D);casamento(X,N,D)),S ),comprimento( S,C ), C == 0).

% nao remover individuo enquanto tiver informacao que é filho de alguem
-individuo(N,L,DN,DM,H) :: (solucoes( N,progenitor(X,N),S ),comprimento( S,C ), C == 0).


%--------------------------------- - - - - - - - - - -  -  -  -  -   -

%--------------------------%
% INVARIANTES REFERENCAIS  %
%--------------------------%

% Cada indivíduo não pode ter mais do que dois Progenitores
+progenitor( P,F ) :: (solucoes( (Ps),(progenitor( Ps,F )),S ),comprimento( S,N ), N =< 2).

% Cada indivíduo não pode ter mais do que um Pai
+progenitor(P,F) :: (solucoes( (Ps),pai( Ps,F ),S ),comprimento( S,N ), N =< 1).

% Cada indivíduo não pode ter mais do que uma Mãe
+progenitor(P,F) :: (solucoes( (Ms),mae( Ms,F ),S ),comprimento( S,N ), N =< 1).

% Data de Nascimento =< Data actual
+individuo(N,L,DN,DM,H) :: getYear(Y), DN =< Y. 

% Data de Morte =< Data actual
+individuo(N,L,DN,DM,H) :: ( (DM == 'vivo') ; (getYear(Y), DM =< Y)). 

% Data de Nascimento =< Data de Morte
+individuo(N,L,DN,DM,H) :: ( (DM == 'vivo') ; (DM >= DN) ).

% Data de Nascimento Progenitor < Data de Nascimento Filho
+progenitor(P,F) :: (individuo(P,L,DNP,DMP,HP), individuo(F,L,DNF,DMF,HF), DNF > DNP).

% Data Casamento =< Data actual
+casamento(X,Y,D) :: getYear(Y), D=<Y.

% Data do Casamento > Data Nascimento do Conjuges
+casamento(X,Y,D) :: (individuo(X,L,DNX,DMX,HX),individuo(Y,L,DNY,DMY,HY), DNX < D, DNY <D).

% Apenas sao permitidos casamentos entre pessoas cujo genero esteja definido
% São permitidos casamentos entre pessoas do mesmo genero
+casamento(F,M) :: (masculino(F),feminino(M); masculino(M),feminino(F); feminino(F),feminino(M); masculino(M),masculino(M)).


