%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% PROG. LOGICA, CONHECIMENTO E RACIOCINIO - MIEB/4

%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% SEMANA 05: 13.OUT.2014 - 17.OUT.2014

%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Invariantes

%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% SICStus PROLOG: Declaracoes iniciais

:- set_prolog_flag( discontiguous_warnings,off ).
:- set_prolog_flag( single_var_warnings,off ).
:- set_prolog_flag( unknown,fail ).

%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% SICStus PROLOG: definicoes iniciais

:- op( 900,xfy,'::' ).
:- dynamic filho/2.
:- dynamic pai/2.
:- dynamic neto/2.
:- dynamic avo/2.
:- dynamic descendente/3


%--------------------------------- - - - - - - - - - -  -  -  -  -   -
%--------------------------------- - - - - - - - - - -  -  -  -  -   -
%Base de Conhecimento
%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensao do predicado filho: Filho,Pai -> {V,F,D}

filho( joao,jose ).
filho( jose,manuel ).
filho( carlos,jose ).


% PREDICADOS

%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensão do predicado soluções: X,Y,Z -> {V,F}

solucoes( X,Y,Z ) :-
	findall( X,Y,Z ).

%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensão do predicado comprimento: S,N -> {V,F}
comprimento( S,N ) :-
	length( S,N ).

%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensão do predicado filho/pai: F,P -> {V,F}

filho( F,P ) :- pai( P,F ).

%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensão do predicado avo: A,N -> {V,F}

avo( A,N ) :-
	pai( A,X ),
	pai( X,N ).

%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensão do predicado neto: N,A -> {V,F}

neto( N,A ) :-
	avo( A,N ).

%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensão do predicado descendente: D,A,G -> {V,F}

descendente( D,A,1 ):-
	filho( D,A ).

descendente( D,A,G ):-
	filho( D,X ),
	descendente( X,A,Y ), G is Y+1.


%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Invariantes Estruturais:  nao permitir a insercao de conhecimento repetido
%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Não se admitirá a existência de mais do que uma ocorrência da mesma evidência
% na relação filho/2;

+filho( F,P ) :: ( solucoes( (F,P),(filho(F,P)), S),
		comprimento( S,N ), N==1
		).


%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Não se admitirá a existência de mais do que uma ocorrência da mesma evidência na
% relação pai/2

+pai( P,F ) :: ( solucoes( (P,F),(pai(P,F)),S),
		comprimento( S,N ), N==1 ).


%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Não se admitirá a existência de mais do que uma ocorrência da mesma evidência na
% relação neto/2;

+neto( N,A ) :: ( solucoes( (N,A),(neto(N,A)),S ),
		comprimento( S,C ), C==1 ).

%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Não se admitirá a existência de mais do que uma ocorrência da mesma evidência
% na relação avô/2;

+avo( A,N ) :: ( solucoes( (A,N),(avo(A,N)),S ),
		comprimento( S,C ), C==1 ).

%--------------------------------- - - - - - - - - - -  -  -  -  -   -
v. Não se admitirá a existência de mais do que uma ocorrência da mesma evidência
% na relação descendente/3;

+descendente :: ( solucoes(( D,A,_),(descendente( D,A,_)),S ),
		comprimento( S,N ), N ==1 ).

%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Invariantes Referenciais
%--------------------------------- - - - - - - - - - -  -  -  -  -   -

%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Não é admissível existirem mais do que 2 progenitores para um determinado indivíduo,
% na relação filho/2;

+filho( F,P ) :: (solucoes( (Ps),(filho( F,Ps )),S ),
                  comprimento( S,N ), N =< 2
                  ).

%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Não é admissível existirem mais do que 2 progenitores para um determinado indivíduo,
% na relação pai/2;

+pai( P,F ) :: (solucoes( (Ps),(pai( Ps,F )),S ),
                  comprimento( S,N ), N =< 2
                  ).
%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Não poderá acontecer existirem mais do que 4 indivíduos identificados como «avô» na
% relação neto/2;

+neto( N,A ) :: ( solucoes( (As),(neto(N,As)),S ),
		comprimento( S,C ), C=< 4 ).

%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Não poderá acontecer existirem mais do que 4 indivíduos identificados como «avô»
% na relação avô/2;

+avo( A,N ) :: ( solucoes( (As),(avo(As,N)),S ),
		comprimento( S,C ), C=< 4 ).

%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensão do predicado que permite a evolucao do conhecimento
% evolucao: Termo -> {V,F}

evolucao( Termo ) :-
    solucoes( Invariante,+Termo::Invariante,Lista ),
    insercao( Termo ),
    teste( Lista ).

%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensão do predicado insercao: Termo -> {V,F}

insercao( Termo ) :- assert( Termo ).
insercao( Termo ) :- retract( Termo ),!,fail.

%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensão do predicado teste: LI -> {V,F}

teste( [] ).
teste( [I|LI] ) :-
	I,
	teste( LI ).                

%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% A identificação do «grau» de descendência na relação descendente/3 deverá pertencer
% ao conjunto dos números naturais
% ????


