:- set_prolog_flag( discontiguous_warnings,off ).
:- set_prolog_flag( single_var_warnings,off ).
:- set_prolog_flag( unknown,fail ).

:- op( 900,xfy,'::').
:- dynamic aluno/3.



% ALUNOS

aluno(12333,joaocosta,lei).
aluno(13444,anarocha,desconhecido).
aluno(18999,joaomota,lcc).
aluno(15000,joaosilva,lei).
aluno(1,naopermitido,lesi).

-aluno(N,A,C):-
nao(aluno(N,A,C)),
nao(excepcao(aluno(N,A,C))).

excepcao(aluno(N,A,C)):- aluno(N,A,desconhecido).

excepcao(aluno(14000,paulojorge,lei)).
excepcao(aluno(14000,pedrojorge,lei)).

excepcao(aluno(15233,isabelmendes,lei)).
excepcao(aluno(15233,isabelmendes,lcc)).

excepcao(aluno(N,A,C)):- aluno(N,naopermitido,C).

nulo(naopermitido).

+aluno(N,A,C) :: (findall( D , (aluno(N,A,C) , nao(nulo(A))) , L) , length(L,N) , N==0).


nao( X ) :- X,!,fail.
nao( X ).

%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extensao do meta-predicado demo: Questao,Resposta -> {V,F}

demo( Questao,verdadeiro ) :-
Questao.
demo( Questao,falso ) :-
-Questao.
demo( Questao,desconhecido ) :-
nao( Questao ),
nao( -Questao ).

%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% 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 ).


%--------------------------------- - - - - - - - - - -  -  -  -  -   -
%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Evolu‹o de Conhecimento
%--------------------------------- - - - - - - - - - -  -  -  -  -   -
%--------------------------------- - - - - - - - - - -  -  -  -  -   -

% 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 remover: Termo -> {V,F}

remover(Termo) :- retract(Termo).
remover(Termo) :- assert(Termo), !, fail.

%--------------------------------- - - - - - - - - - -  -  -  -  -   -
% Extens‹o do predicado remo‹o: Termo -> {V,F}

remocao(Termo) :-
Termo,
solucoes( Invariante, -Termo::Invariante, Lista ),
remover( Termo ),
testar( Lista ).