1 / 20

Introdución al procesamiento del lenguaje natural en PROLOG

Introdución al procesamiento del lenguaje natural en PROLOG. Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria. Procesamiento del lenguaje natural en Prolog.

chin
Download Presentation

Introdución al procesamiento del lenguaje natural en PROLOG

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Introdución al procesamiento del lenguaje natural en PROLOG Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria Prolog

  2. Procesamiento del lenguaje natural en Prolog • Prolog ofrece algunas facilidades para definir analizadores gramaticales y, en general, para diseñar sistemas orientados al procesamiento del lenguaje natural. • Supongamos que necesitamos definir un programa que sea capaz de aceptar frases como: • Mi abuelo come papaya. • El coche rojo es muy veloz. • Tu hermano es el hijo de tus padres • Tu abuelo es el padre de tus padres • Mi primo es el hijo de mis tíos Prolog

  3. Procesamiento del lenguaje natural en Prolog • Tu hermano es el hijo de tus padres • Tu abuelo es el padre de tus padres • Mi primo es el hijo de mis tíos • Estas frases se ajustan a la siguiente gramática BNF: • <frase>::= <sn> <sv> • <sn>::= <adjetivo> <nombre> | <determinante> <nombre> • <sv>::= <verbo> <atributo> • <atributo>::= <sn> <cn> • <adjetivo>::= tu | mi | mis | tus • <nombre>::= hermano | abuelo | primo | padres | tíos | hijo | padre • <verbo>::= es • <determinante>::= el • <cn>::= <prep> <sn> • <prep>::= de Prolog

  4. La idea es escribir un programa que acepte una frase si se adecúa a las reglas de la gramática o la rechace en caso contrario. La frase en cuestión se presentará como una lista de palabras, p.e.: ?- frase([mi,primo,es,el,hijo,de,mis,tíos]). Una forma de implementar estas reglas gramaticales es emplear una estrategia de “generación_y_test” como muestra el siguiente ejemplo: frase(L):- append(SN,SV,L), sn(SN), sv(SV). <frase>::= <sn> <sv> <sn>::= <adjetivo> <nombre> | <determinante> <nombre> <sv>::= <verbo> <atributo> <atributo>::= <sn> <cn> <adjetivo>::= tu | mi | mis | tus <nombre>::= hermano | abuelo | primo | padres | tíos | hijo | padre <verbo>::= es <determinante>::= el <cn>::= <prep> <sn> <prep>::= de Prolog

  5. <frase>::= <sn> <sv> <sn>::= <adjetivo> <nombre> | <determinante> <nombre> <sv>::= <verbo> <atributo> <atributo>::= <sn> <cn> <adjetivo>::= tu | mi | mis | tus <nombre>::= hermano | abuelo | primo | padres | tíos | hijo | padre <verbo>::= es <determinante>::= el <cn>::= <prep> <sn> <prep>::= de adjetivo([mi]). adjetivo([mis]). adjetivo([tu]). adjetivo([tus]). nombre([hermano]). nombre([abuelo]). nombre([primo]). nombre([padres]). nombre([tíos]). nombre([hijo]). nombre([padre]). verbo([es]). determinante([el]). prep([de]). sv(SV):- append(SVA,SVB,SV), verbo(SVA), atributo(SVB). atributo(SA):- append(SN,CN,SA), sn(SN), cn(CN). cn(SV):- append(P,SN,SV), prep(P), sn(SN). frase(L):- append(SN,SV,L), sn(SN), sv(SV). sn(SN):- append(SNA,SNB,SN), adjetivo(SNA), nombre(SNB). sn(SN):- append(SNA,SNB,SN), determinante(SNA), nombre(SNB). Prolog

  6. Listas “diferencia” Se denominan “listas diferencia” (difference lists) a una forma de representar listas en Prolog que - como técnica de programación - puede provocar un notable incremento de eficiencia. Ejemplo: Supongamos que deseamos diseñar un procedimiento que nos permita añadir un elemento a una lista por la cabeza. add_to_head(X,Ys,[X|Ys]). Esto es fácil. Supongamos ahora que deseamos diseñar el procedimiento complementario add_to_back. Prolog

  7. Ejemplo (cont): Realmente no es muy difícil ... add_to_back(X, [ ], [X]). add_to_back(X, [Y|Ys], [Y|Zs]):- add_to_back(X,Ys,Zs). Sin embargo, es terriblemente ineficiente por motivos evidentes. Ejemplo: Algo similar ocurre con la definición estándar de append/3: append([ ], Ys, Ys). append([X|Xs], Ys, [X|Zs]):- append(Xs,Ys,Zs). Prolog

  8. Las listas diferencia permiten manipular listas de forma mucho más eficiente definiendo “patrones de listas”. Por ejemplo: difference_append (A-Z, Z-B, A-B). ?- difference_append([a,b,c], [d,e], R). No. ?- difference_append([a,b,c]-Z, Z-[d,e], R). Z = _G379 R = [a, b, c]-[d, e] Yes ?- difference_append([a,b,c|Z] - Z, [d,e] - [ ], R- [ ]). Z = [d, e] R = [a, b, c, d, e] Yes ?- difference_append([a,b,c|Z] - Z, [d,e] - [ ], R). Z = [d, e] R = [a, b, c, d, e] - [ ] Yes Prolog

  9. Las siguientes definiciones transforman una lista diferencia en una lista “normal”, pero no a la inversa dl_to_list([ ] - _, [ ]) :- !. dl_to_list([X|Y] - Z, [X|W]) :- dl_to_list(Y - Z, W). ?- dl_to_list([1,2,3|X]-X,L). X = [ ] L = [1,2,3]; No Recíprocamente, list_to_dl transforma una lista “normal” en una lista diferencia, pero no a la inversa list_to_dl([], X - X). list_to_dl([X|W], [X|Y] - Z) :- list_to_dl(W, Y - Z). ?- list_to_dl([a,b,c],Y-Z). Y = [a, b, c|_G167] Z = _G167 ; No Prolog

  10. Listas Diferencia El problema con esta estrategia es que es terriblemente ineficaz como puede comprobarse fácilmente realizando una traza de la anterior definición de frase/1. La estrategia más eficiente es evitar la etapa de generación y pasar la lista completa a los predicados que implementan las reglas gramaticales. Éstos identificarán los correspondientes elementos gramaticales procesando secuencialmente los elementos de la lista de izquierda a derecha, devolviendo el resto de la lista. Para hacer esto podemos emplear listas diferencia como se ilustra en la siguiente versión del analizador gramatical del ejemplo anterior. Prolog

  11. <frase>::= <sn> <sv> <sn>::= <adjetivo> <nombre> | <determinante> <nombre> <sv>::= <verbo> <atributo> <atributo>::= <sn> <cn> <adjetivo>::= tu | mi | mis | tus <nombre>::= hermano | abuelo | primo | padres | tíos | hijo | padre <verbo>::= es <determinante>::= el <cn>::= <prep> <sn> <prep>::= de adjetivo([mi|X]-X). adjetivo([mis|X]-X). adjetivo([tu|X]-X). adjetivo([tus|X]-X). nombre([hermano|X]-X). nombre([abuelo|X]-X). nombre([primo|X]-X). nombre([padres|X]-X). nombre([tíos|X]-X). nombre([hijo|X]-X). nombre([padre|X]-X). verbo([es|X]-X). determinante([el|X]-X). prep([de|X]-X). sv(SV-R):- verbo(SV-SV1), atributo(SV1-R). atributo(SA-R):- sn(SA-SA1), cn(SA1-R). cn(SV-R):- prep(SV-SV1), sn(SV1-R). frase(S):- sn(S-S1), sv(S1-[]). sn(SN-R):- adjetivo(SN-SN1), nombre(SN1-R). sn(SN-R):- determinante(SN-SN1), nombre(SN1-R). Prolog

  12. ?- nombre([hijo,de,mis,tíos] - X). X = [de, mis, tíos] Yes ?- sn([mi,abuelo,es,el,padre,de,mi,padre] - X). X = [es, el, padre, de, mi, padre] Yes adjetivo([mi|X]-X). adjetivo([mis|X]-X). adjetivo([tu|X]-X). adjetivo([tus|X]-X). nombre([hermano|X]-X). nombre([abuelo|X]-X). nombre([primo|X]-X). nombre([padres|X]-X). nombre([tíos|X]-X). nombre([hijo|X]-X). nombre([padre|X]-X). verbo([es|X]-X). determinante([el|X]-X). prep([de|X]-X). sv(SV-R):- verbo(SV-SV1), atributo(SV1-R). atributo(SA-R):- sn(SA-SA1), cn(SA1-R). cn(SV-R):- prep(SV-SV1), sn(SV1-R). frase(S):- sn(S-S1), sv(S1-[ ]). sn(SN-R):- adjetivo(SN-SN1), nombre(SN1-R). sn(SN-R):- determinante(SN-SN1), nombre(SN1-R). Prolog

  13. Gramática Definida por Cláusulas La mayoría de las implementaciones de Prolog incorporan la posibilidad de definir gramáticas mediante una sintaxis especial que oculta la presencia de las listas diferencia. A esta sintaxis se le conoce como gramática definida por cláusulas (Definite Clause Grammar, DCG). frase --> sn, sv. sn --> adjetivo, nombre. sn --> determinante, nombre. sv --> verbo, atributo. atributo --> sn, cn. cn --> prep, sn. adjetivo --> [mi]. adjetivo --> [mis]. adjetivo --> [tu]. adjetivo --> [tus]. nombre --> [hermano]. nombre --> [abuelo]. nombre --> [primo]. nombre --> [padres]. nombre --> [tíos]. nombre --> [hijo]. nombre --> [padre]. verbo --> [es]. determinante --> [el]. prep --> [de]. Prolog

  14. Gramática de Cláusulas Definidas • Las cláusulas gramaticales así definidas se analizan y “traducen” en cláusulas Prolog que emplean listas diferencias. Por ejemplo, la primera de las reglas: • frase --> sn, sv. • se traduce en: • frase(A, B) :- • sn(A, C), • sv(C, B). • Así que para analizar una frase, hemos de invocar frase/2 con dos argumentos: • ?- frase([mi,abuelo,es,el,padre,de,mi,padre],R). • R = [] • Yes • Evidentemente , el segundo argumento “recogerá” el resto “inaceptado” de la frase cuando éste exista. Prolog

  15. Gramática de Cláusulas Definidas • Las cláusulas gramaticales que recogen los símbolos terminales, el vocabulario, se traducen también en listas diferencias. Por ejemplo: • adjetivo --> [mi]. • se traduce en: • adjetivo([mi|A],A). • La gramática que hemos definido presenta algunas deficiencias como la falta de concordancia entre el número del adjetivo y el nombre. Por ejemplo, “mi padres” resultaría aceptable como sintagma nominal (sn): • ?- sn([mi,padres], R). • R = [] • Yes • Por ello una frase como la siguiente sería aceptable: • ?- frase([mi,abuelo,es,el,padres,de,mis,padre],R). • R = [] • Yes Prolog

  16. Uso de Variables en DCGs Para resolver este problema podemos emplear argumentos en las cláusulas de la gramática como se muestra a continuación: nombre(sing) --> [hermano]. nombre(sing) --> [abuelo]. nombre(sing) --> [primo]. nombre(plur) --> [padres]. nombre(plur) --> [tíos]. nombre(sing) --> [hijo]. nombre(sing) --> [padre]. verbo --> [es]. determinante(sing) --> [el]. prep --> [de]. frase --> sn, sv. sn --> adjetivo(N), nombre(N). sn --> determinante(N), nombre(N). sv --> verbo, atributo. atributo --> sn, cn. cn --> prep, sn. adjetivo(sing) --> [mi]. adjetivo(plur) --> [mis]. adjetivo(sing) --> [tu]. adjetivo(plur) --> [tus]. • Ahora una frase como: • ?- frase([mi,primo,es,el,hijo,de,mi,tíos],R). • No • ya no resulta aceptable Prolog

  17. Uso de Variables en DCGs El uso de variables no está restringido al cuerpo de las reglas. Así la versión de la gramática que se muestra en la siguiente diapositiva usa variables para devolver un análisis sintáctico (y eventualmente morfológico) de la frase. Por ejemplo (ligeramente retocado): ?- frase(S,[mi,primo,es,el,hijo,de,mis,tíos],[]). S = análisis( sn(adj(mi), nom(primo)), sv(v(es), atrib(sn(det(el), nom(hijo)), cn(prep(de), sn(adj(mis), nom(tíos)))))) Yes Prolog

  18. frase(análisis(S,V)) --> sn(S), sv(V). sn(sn(A,B)) --> adjetivo(A,N), nombre(B,N). sn(sn(A,B)) --> determinante(A,N), nombre(B,N). sv(sv(V,A)) --> verbo(V), atributo(A). atributo(atrib(S,C)) --> sn(S), cn(C). cn(cn(P,S)) --> prep(P), sn(S). adjetivo(adj(mi),sing) --> [mi]. adjetivo(adj(mis),plur) --> [mis]. adjetivo(adj(tu),sing) --> [tu]. adjetivo(adj(tus),plur) --> [tus]. nombre(nom(hermano),sing) --> [hermano]. nombre(nom(abuelo),sing) --> [abuelo]. nombre(nom(primo),sing) --> [primo]. nombre(nom(padres),plur) --> [padres]. nombre(nom(tíos),plur) --> [tíos]. nombre(nom(hijo),sing) --> [hijo]. nombre(nom(padre),sing) --> [padre]. verbo(v(es)) --> [es]. determinante(det(el),sing) --> [el]. prep(prep(de)) --> [de]. Prolog

  19. Es posible incluir cláusulas “prolog” en la definición de las cláusulas gramaticales. Las cláusulas “prolog” deben encerrarse entre llaves { }, como se muestra en el siguiente ejemplo, donde se han agrupado las definiciones de los adjetivos en la gramática que se ha venido usando como ejemplo (exactamente lo mismo puede hacerse con los nombres): adjetivo(adj(X),sing) --> [X],{ member(X,[mi,tu]) }. adjetivo(adj(X),plural) --> [X], { concat_atom([Y,s],X), adjetivo(adj(Y),sing,[Y],[])}. ?- listing(adjetivo). adjetivo(adj(A), sing, B, C) :- 'C'(B, A, D), member(A, [mi, tu]), C=D. adjetivo(adj(A), plural, B, C) :- 'C'(B, A, D), concat_atom([E, s], A), adjetivo(adj(E), sing, [E], []), C=D. Yes Prolog

  20. frase(análisis(S,V)) --> sn(S), sv(V). sn(sn(A,B)) --> adjetivo(A,N), nombre(B,N). sn(sn(A,B)) --> determinante(A,N), nombre(B,N). sv(sv(V,A)) --> verbo(V), atributo(A). atributo(atrib(S,C)) --> sn(S), cn(C). cn(cn(P,S)) --> prep(P), sn(S). adjetivo(adj(X),sing) --> [X],{ member(X,[mi,tu]) }. adjetivo(adj(X),plural) --> [X], { concat_atom([Y,s],X), adjetivo(adj(Y),sing,[Y],[])}. nombre(nom(X),sing) --> [X], { member(X,[abuelo,hermano,padre, primo,tío,hijo]) }. nombre(nom(X),plural) --> [X], { concat_atom([Y,s],X), nombre(nom(Y),sing,[Y],[])}. verbo(v(es)) --> [es]. determinante(det(el),sing) --> [el]. prep(prep(de)) --> [de]. Prolog

More Related