/***
LUCIEN ISMAEL FANTIN    RA: 880518

Universidade                            UNICAMP
Instituto                               IC - Instituto de Computacao
Curso:                                  Mestrado em Ciencia da Computacao
Area:                                   Processamento de Lingua Natural
Tese:                                   Analisador Sintatico para o Portugues
Orientadora:                            Ariadne Carvalho
Co-orientador:                          Jorge Stolfi
Auxiliar de iniciacao cientifica:       Sheila Almeida  RA: 993255
Inicio:                                 Marco/2000

	Programa em Prolog com gramatica de clausulas definidas 
para analisar a estrutura sintatica de sentencas. 
	Como resultado, gera a arvore de derivacao correspondendo 
as sentencas gramaticais, enquanto rejeita as sentencas agramaticais.

Para iniciar o programa digite:
?- gram.
***/

/***INTERFACE***/

/*Controle Principal*/
gram:-
	nl,
	nl,
	no(Last_Node),
	(
		sentenca(1,Last_Node,1,Last_Node,d,_)
	->
		apres_result(Last_Node)
	;
		tell(user_error),
		nl,
		write('Sentença incorreta!'),
		nl,nl,
		told
	).

/*Faz o backtrack apresentando todos os resultados possiveis*/
apres_result(Last_Node):-
	(
		retractall(vez(_)),
		assert(vez(1)),
		sentenca(1,Last_Node,1,Last_Node,d,Arvore),
		retract(vez(N)),
		N1 is N+1,
		assert(vez(N1)),
		escreve_arv(Arvore,N),
		fail
	;
		retract(vez(_))
	).

/*Escreve a N-esima arvore na saida padrao(tela)*/
escreve_arv(Arvore,N):-
	nl,nl,
	write(Arvore),
	escreve_cab_arv(N),
	formata_estrutura(Arvore,0).

/*Escreve o cabecalho de identificacao da arvore*/
escreve_cab_arv(N):-
	nl,
	nl,
	write('Árvore de derivação '),
	write(N),
	write(':').


/*Exibicao da Arvore de Derivacao Identada*/

/*Exibicao da estrutura da sentenca*/

formata_estrutura(Estrut,Ident):-
	(
		atom(Estrut)
	->
		tab(1),
		(
			Estrut=[]
		->
			write(Estrut)
		;
			write([Estrut])
		)
	;
		nl,
		Estrut=..[Nome|Lista_Args],
		tab(Ident),
		write(Nome),
		Ident_args is Ident + 2,
		trata_args(Lista_Args,Ident_args)
	).

trata_args([],_):-!.
trata_args([C|L],Ident):-
	formata_estrutura(C,Ident),
	trata_args(L,Ident).



/*Monta uma arvore com a raiz dada e os elementos da lista que nao forem '',
se a raiz do elemento for ., adiciona somente seus subelementos
ex. da chamada: monta_arv(Arv,sint_nom,[AE,N,AD])*/

monta_arv(Arv,Raiz,Lista):-
	analisa([],Lexist,Lista),
	Arv=..[Raiz|Lexist].

analisa(L,L,[]):-!.
analisa(Lja,LS,[Cab|Resto]):-
	analisa(Lja,LR,Resto),
	inclui_elem(Cab,LR,LS).

inclui_elem(.(''),LE,LE):-!.
inclui_elem('',LE,LE):-!.
inclui_elem(Elem,LE,LS):-
	Elem=..[.|Lsub],
	!,
	append(Lsub,LE,LS).
inclui_elem(Elem,LE,[Elem|LE]).


sentenca(S1,S,INF,SUP,_,A):-
	sint_orac(S1,S,INF,SUP,d,A1),
	monta_arv(A,sentenca,[A1]).

sint_orac(S1,S,INF,SUP,_,A):-
	sint_verb(S2,S3,INF,SUP,d,A2,P,N),
	sint_nom(S1,S2,INF,S2,e,A1,P,_,N),
	sint_nom(S3,S,S3,SUP,d,A3,_,_,_),
	monta_arv(A,sint_orac,[A1,A2,A3]).

sint_nom(S1,S,INF,SUP,_,A,3,G,N):-
	subst(S2,S,INF,SUP,d,A2,_,_,G,N,_),
	det(S1,S2,INF,S2,e,A1,G,N),
	monta_arv(A,sint_nom,[A1,A2]).

sint_verb(S1,S,INF,SUP,_,A,P,N):-
	verbo(S1,S,INF,SUP,d,A1,_,_,fin,ind,_,P,N),
	monta_arv(A,sint_verb,[A1]).

det(S1,S,INF,SUP,_,A,G,N):-
	art(S1,S,INF,SUP,d,A1,_,_,def,G,N),
	monta_arv(A,det,[A1]).

adj(S1,S,INF,SUP,_,A,PAL,CAN,G,N,Gr):-
	x_adj(S1,S,PAL,CAN,G,N,Gr),
	INF =< S1,
	SUP >= S,
	monta_arv(A,adjetivo,[PAL]).

x_adj(0,0,_,_,_,_,_).

adv(S1,S,INF,SUP,_,A,PAL,CAN,TAdv,Gr):-
	x_adv(S1,S,PAL,CAN,TAdv,Gr),
	INF =< S1,
	SUP >= S,
	monta_arv(A,adverbio,[PAL]).

x_adv(0,0,_,_,_,_).

art(S1,S,INF,SUP,_,A,PAL,CAN,Tart,G,N):-
	x_art(S1,S,PAL,CAN,Tart,G,N),
	INF =< S1,
	SUP >= S,
	monta_arv(A,artigo,[PAL]).

x_art(0,0,_,_,_,_,_).

avos(S1,S,INF,SUP,_,A,PAL,CAN,G,N):-
	x_avos(S1,S,PAL,CAN,G,N),
	INF =< S1,
	SUP >= S,
	monta_arv(A,avos,[PAL]).

x_avos(0,0,_,_,_,_).

cod(S1,S,INF,SUP,_,A,PAL,CAN,TCod,G,N):-
	x_cod(S1,S,PAL,CAN,TCod,G,N),
	INF =< S1,
	SUP >= S,
	monta_arv(A,codificacao,[PAL]).

x_cod(0,0,_,_,_,_,_).

coord(S1,S,INF,SUP,_,A,PAL,CAN,TCoord,GCoord,C):-
	x_coord(S1,S,PAL,CAN,TCoord,GCoord,C),
	INF =< S1,
	SUP >= S,
	monta_arv(A,coordenador,[PAL]).

x_coord(0,0,_,_,_,_,_).

comp(S1,S,INF,SUP,_,A,PAL,CAN,TComp):-
	x_comp(S1,S,PAL,CAN,TComp),
	INF =< S1,
	SUP >= S,
	monta_arv(A,comparador,[PAL]).

x_comp(0,0,_,_,_).

conj(S1,S,INF,SUP,_,A,PAL,CAN,TConj,FV,MV):-
	x_conj(S1,S,PAL,CAN,TConj,FV,MV),
	INF =< S1,
	SUP >= S,
	monta_arv(A,conjuncao,[PAL]).

x_conj(0,0,_,_,_,_,_).

interj(S1,S,INF,SUP,_,A,PAL,CAN,TInterj):-
	x_interj(S1,S,PAL,CAN,TInterj),
	INF =< S1,
	SUP >= S,
	monta_arv(A,interjeicao,[PAL]).

x_interj(0,0,_,_,_).

nome(S1,S,INF,SUP,_,A,PAL,CAN,G,N):-
	x_nome(S1,S,PAL,CAN,G,N),
	INF =< S1,
	SUP >= S,
	monta_arv(A,nome_proprio,[PAL]).

x_nome(0,0,_,_,_,_).

num(S1,S,INF,SUP,_,A,PAL,CAN,TNum,GNum,F,G,N,ONum):-
	x_num(S1,S,PAL,CAN,TNum,GNum,F,G,N,ONum),
	INF =< S1,
	SUP >= S,
	monta_arv(A,numeral,[PAL]).

x_num(0,0,_,_,_,_,_,_,_,_).

pont(S1,S,INF,SUP,_,A,PAL,CAN,TPont):-
	x_pont(S1,S,PAL,CAN,TPont),
	INF =< S1,
	SUP >= S,
	monta_arv(A,pontuacao,[PAL]).

x_pont(0,0,_,_,_).

prep(S1,S,INF,SUP,_,A,PAL,CAN):-
	x_prep(S1,S,PAL,CAN),
	INF =< S1,
	SUP >= S,
	monta_arv(A,preposicao,[PAL]).

x_prep(0,0,_,_).

pron(S1,S,INF,SUP,_,A,PAL,CAN,TPron,F,P,G,N):-
	x_pron(S1,S,PAL,CAN,TPron,F,P,G,N),
	INF =< S1,
	SUP >= S,
	monta_arv(A,pronome,[PAL]).

x_pron(0,0,_,_,_,_,_,_,_).

pron(S1,S,INF,SUP,_,A,PAL,CAN,TPron,F,P,G,N,PPron):-
	x_pron(S1,S,PAL,CAN,TPron,F,P,G,N,PPron),
	INF =< S1,
	SUP >= S,
	monta_arv(A,pronome,[PAL]).

x_pron(0,0,_,_,_,_,_,_,_,_).

pron(S1,S,INF,SUP,_,A,PAL,CAN,TPron,F,P,G,N,P2,N2):-
	x_pron(S1,S,PAL,CAN,TPron,F,P,G,N,P2,N2),
	INF =< S1,
	SUP >= S,
	monta_arv(A,pronome,[PAL]).

x_pron(0,0,_,_,_,_,_,_,_,_,_).

rel(S1,S,INF,SUP,_,A,PAL,CAN,FE,FI,P,G,N):-
	x_rel(S1,S,PAL,CAN,FE,FI,P,G,N),
	INF =< S1,
	SUP >= S,
	monta_arv(A,relativo,[PAL]).

x_rel(0,0,_,_,_,_,_,_,_).

sigla(S1,S,INF,SUP,_,A,PAL,CAN,G,N):-
	x_sigla(S1,S,PAL,CAN,G,N),
	INF =< S1,
	SUP >= S,
	monta_arv(A,sigla,[PAL]).

x_sigla(0,0,_,_,_,_).

simb(S1,S,INF,SUP,_,A,PAL,CAN):-
	x_simb(S1,S,PAL,CAN),
	INF =< S1,
	SUP >= S,
	monta_arv(A,simbolos,[PAL]).

x_simb(0,0,_,_).

subst(S1,S,INF,SUP,_,A,PAL,CAN,G,N,Gr):-
	x_subst(S1,S,PAL,CAN,G,N,Gr),
	INF =< S1,
	SUP >= S,
	monta_arv(A,substantivo,[PAL]).

x_subst(0,0,_,_,_,_,_).

verbo(S1,S,INF,SUP,_,A,PAL,CAN,FV,MV,TV,P,N):-
	x_verbo(S1,S,PAL,CAN,FV,MV,TV,P,N),
	INF =< S1,
	SUP >= S,
	monta_arv(A,verbo,[PAL]).

x_verbo(0,0,_,_,_,_,_,_,_).

no(00016).
x_art(10,13,'a','o',def,fem,sin).
x_art(1,4,'o','o',def,mas,sin).
x_pron(10,13,'a','o',atd,sub,3,fem,sin).
x_pron(1,4,'o','o',atd,sub,3,mas,sin).
x_pron(10,13,'a','o',dmo,sub,3,fem,sin).
x_pron(1,4,'o','o',dmo,sub,3,mas,sin).
x_prep(10,13,'a','a').
x_subst(13,16,'dama','dama',fem,sin,nor).
x_subst(4,7,'rapaz','rapaz',mas,sin,nor).
x_verbo(7,10,'beijou','beijar',fin,ind,ppe,3,sin).
arco(00001,00004,'O',0).
arco(00004,00007,'rapaz',0).
arco(00007,00010,'beijou',0).
arco(00010,00013,'a',0).
arco(00013,00016,'dama',0).
