carregar:-
	open(dadosTaxonomicos, append, S1), write(S1,''),close(S1),
	['dadosTaxonomicos'],
	open(animaisAChecar, append, S2), write(S2,''),close(S2),
	['animaisAChecar'].

iniciar :- nl, nl, 
	write('========================================================'), nl,
	write('Disciplina: INE5417 - Paradigmas de Programação')         , nl,
	write('João Paulo Pizani Flor - 07132025')                       , nl,
	write('Daniel Ricardo dos Santos - 07132013')                    , nl,
	write('========================================================'), nl,
	write('                Classificação de animais                '), nl,
	write('========================================================'), nl,
	write('Para inserir uma nova classificação, utilize "inserir."') , nl,
	write('Para classificar um animal, utilize "buscar."')           , nl,
	write('========================================================'), nl,
	carregar.


buscar :- 
	assertz(eh(nova_especie)),
	eh(Animal),
	write('De acordo com meus conhecimentos, o animal é: '),
	write(Animal),
	nl,
	retrairAfirmacoes.


inserir :-
	write('Para inserir uma nova categoria digite "categoria."'), nl,
	write('Para inserir uma nova espécie digite "especie."')    , nl.

imprimirInstrucoes :-
	write('Escreva os nodos que deseja inserir na árvore taxonômica.')                             , nl,
	write('Sintaxe: <nome_do_nodo> :- <nome_do_nodo_pai>, { checa(<característica_específica>) }.'), nl,
	write('Obs: <característica_específica> é um atributo que define a categoria')                 , nl,
	write('    As chaves {} indicam 1 ou mais repetições, separadas por vírgula')                  , nl.

categoria :-
	imprimirInstrucoes,
	open(dadosTaxonomicos, append, Stream),
	lerRegraDoUsuario(Stream,', !.'),
	close(Stream),
	carregar.
	
especie :-
	imprimirInstrucoes,
	open(dadosTaxonomicos, append, Stream),
	lerRegraDoUsuario(Stream, '.'),
	close(Stream),
	carregar.

continuaEscrevendo(fim,_,_) :- !.
continuaEscrevendo(Regra,Stream,Sufixo) :- 
	write(Stream, Regra), write(Stream,Sufixo), write(Stream,'\n'),
	lerRegraDoUsuario(Stream,Sufixo).

lerRegraDoUsuario(Stream,Sufixo):- 
	read(Regra),
	continuaEscrevendo(Regra,Stream,Sufixo).



/* Como perguntar pelas características */
perguntar(Caracteristica) :-
	write('A seguinte característica está presente: '),
	write(Caracteristica),
	write('? '),
	read(Resposta),
	( (Resposta == sim ; Resposta == s)
		->
		assert(sim(Caracteristica)) ;
		assert(nao(Caracteristica)), fail
	).

:- dynamic sim/1,nao/1.

/* Como checar por alguma característica */
checa(C) :-
	(sim(C) -> true;
	(nao(C) -> fail;
	perguntar(C))).

/* desafirma todas os predicados com características */
retrairAfirmacoes :- retract(sim(_)),fail.
retrairAfirmacoes :- retract(nao(_)),fail.
retrairAfirmacoes :- retract(eh(nova_especie)),fail.
retrairAfirmacoes.

