21
Cap´ ıtulo 6 Programaci´on de gram´ aticas clausales en Prolog Fernando Soler Toscano 1 En este trabajo presentamos una introducci´ on, a modo de tutorial, a la escritura de gram´aticasdecl´ausulasdefinidas (conocidas como DCG, por su nombre ingl´ es, Definite Clause Grammars ) en Prolog. No pretende ser un trabajo t´ ecnico ni sobre Programaci´ on L´ogica ni sobre Ling¨ ıstica, sino una peque˜ na ayuda para quien desee conocer de un modo pr´ actico algunas de las t´ ecnicas elementales de la programaci´ on de gram´ aticas. 6.1. Introducci´on Como introducci´ on a las gram´ aticas formales, mostramos a continua- ci´ on la jerarqu´ ıa que proporciona Chomsky [2] de las diferentes clases de gram´ aticas generativas en virtud del tipo de reglas que las configuran. Una gram´ atica G = V n ,V t , R, O se compone de los siguientes cuatro elementos: Un conjunto de ımbolos no terminales, representado por V n , que est´ a formado por las categor´ ıas gramaticales. En las gram´ aticas de ejemplo que veremos en las siguientes secciones, pertenecer´ an a este conjunto elementos tales como sintagma nominal, art´ ıculo, etc. 1 Este trabajo se enmarca en el proyecto de investigaci´ on L´ogica y lenguaje: informaci´ on yrepresentaci´on (HUM2004-01255) del Ministerio de Educaci´ on y Ciencia.

Programación de gramáticas clausales en Prolog

Embed Size (px)

Citation preview

Page 1: Programación de gramáticas clausales en Prolog

“libro” — 2006/1/9 — 12:58 — page 91 — #109

Capıtulo 6

Programacion de gramaticasclausales en Prolog

Fernando Soler Toscano1

En este trabajo presentamos una introduccion, a modo de tutorial, a laescritura de gramaticas de clausulas definidas (conocidas como DCG, porsu nombre ingles, Definite Clause Grammars) en Prolog. No pretende serun trabajo tecnico ni sobre Programacion Logica ni sobre Linguıstica, sinouna pequena ayuda para quien desee conocer de un modo practico algunasde las tecnicas elementales de la programacion de gramaticas.

6.1. Introduccion

Como introduccion a las gramaticas formales, mostramos a continua-cion la jerarquıa que proporciona Chomsky [2] de las diferentes clases degramaticas generativas en virtud del tipo de reglas que las configuran. Unagramatica G = 〈Vn, Vt, R,O〉 se compone de los siguientes cuatro elementos:

Un conjunto de sımbolos no terminales, representado por Vn, que estaformado por las categorıas gramaticales. En las gramaticas de ejemploque veremos en las siguientes secciones, perteneceran a este conjuntoelementos tales como sintagma nominal, artıculo, etc.

1Este trabajo se enmarca en el proyecto de investigacion Logica y lenguaje: informaciony representacion (HUM2004-01255) del Ministerio de Educacion y Ciencia.

Page 2: Programación de gramáticas clausales en Prolog

“libro” — 2006/1/9 — 12:58 — page 92 — #110

92 Capıtulo 6. Programacion de gramaticas clausales. . .

Un conjunto de sımbolos terminales, reunidos en Vt, que mas o me-nos viene a ser el diccionario del lenguaje para el que escribimos lagramatica.

Un conjunto de reglas de transformacion, al que llamamos R, quetienen la forma α → β, donde α y β son cadenas (secuencias) deelementos de Vn y Vt. Cada una de tales reglas nos permite transformarla cadena α en β, como mas adelante veremos.

Un sımbolo raız, que representamos mediante O, que debe pertenecera Vn (es decir, se trata de un sımbolo no terminal). Representa lacategorıa superior de la gramatica, y debe constituir la parte izquierdade al menos una de las reglas de R. Cuando la gramatica G es la deuna lengua natural2, O se corresponde con la categorıa oracion.

Segun las restricciones que se impongan respecto de la forma de cadaelemento α→ β3 de R, son posibles cuatro tipos de gramaticas4:

Tipo 0, formado por las gramaticas irrestrictas, o recursivamente enu-merables, que no imponen restricciones a las estructuras de α y β.

Tipo 1, de gramaticas dependientes del contexto. En este caso, α =ηAλ y β = ηγλ, donde A es un sımbolo no terminal, y η, λ y γcadenas de sımbolos de Vn y Vt. En el caso de η y λ, se permite quesean vacıas; no ası con γ.

Tipo 2, de gramaticas independientes (o libres) del contexto, en lasque α debe ser un sımbolo de Vn y β cualquier cadena de terminos(elementos tanto de Vn como de Vt).

Tipo 3, de gramaticas regulares o de estados finitos. En este caso, αdebe ser un sımbolo de Vn y β puede ser o bien un sımbolo de Vt obien la concatenacion de un sımbolo de Vt y otro de Vn.

2Este paradigma es usado en muchos contextos. Por ejemplo, es frecuente la descripcionde los lenguajes de programacion segun la forma conocida como de Backus-Naur (BNF,por Backus-Naur Form, en referencia a John Backus y Peter Naur), que no es mas queuna gramatica con la misma estructura que hemos descrito.

3Como hemos explicado α y β representan cadenas (secuencias de uno o mas elementos)de terminos. Se llama termino a todo elemento que pertenece a Vn o Vt.

4Mostramos solo los rasgos mas importantes de cada tipo, y omitimos algunos de losdetalles mas tecnicos, como el tratamiento que cada uno de ellos hace de la cadena vacıa ε.

Page 3: Programación de gramáticas clausales en Prolog

“libro” — 2006/1/9 — 12:58 — page 93 — #111

6.1. Introduccion 93

La idea de jerarquıa de lenguajes se debe a que las restricciones que cadauno de los cuatro tipos impone son progresivamente mas estrictas, de modoque

Tipo 3 ⊂ Tipo 2 ⊂ Tipo 1 ⊂ Tipo 0

es decir, toda gramatica de tipo n+ 1 (para n entre 0 y 2), es tambien unagramatica de tipo n.

Veamos un ejemplo ilustrativo de una gramatica G = 〈Vn, Vt, R,O〉 libredel contexto, compuesta por:

Vn, que en este caso es el conjunto formado por o (que representa lacategorıa oracion), sn (sintagma nominal), sv (sintagma verbal), det(determinante), n (nombre), vt (verbo transitivo) y vi (verbo intran-sitivo).

Vt, que se compone de: el, un, una, perro, hueso, ladra y muerde.

R, que contiene las siguientes reglas:

o → sn, sv (6.1)sn → det, n (6.2)sv → vt, sn (6.3)sv → vi (6.4)det → el (6.5)det → un (6.6)det → una (6.7)n → perro (6.8)n → hueso (6.9)vi → ladra (6.10)vt → muerde (6.11)

O, que en este caso es o.

Veamos como nuestra gramatica permite derivar la cadena “el perromuerde un hueso”. A continuacion mostramos las transformaciones que de-ben aplicarse sucesivamente, comenzando por el sımbolo no terminal o, paraobtener la oracion anterior:

Page 4: Programación de gramáticas clausales en Prolog

“libro” — 2006/1/9 — 12:58 — page 94 — #112

94 Capıtulo 6. Programacion de gramaticas clausales. . .

o → sn, sv regla (6.1)o → det, n, sv regla (6.2)o → det, n, vt, sn regla (6.3)o → det, n, vt, det, n regla (6.2)o → el, n, vt, det, n regla (6.5)o → el, n, vt, un, n regla (6.6)o → el, perro, vt, un, n regla (6.8)o → el, perro, vt, un, hueso regla (6.9)o → el, perro, muerde, un, hueso regla (6.11)

En cada transformacion se indica, a la derecha, la regla que se ha usadosobre el paso anterior. Podrıamos haber empleado las reglas en otro ordenpara llegar a “o → el, perro, muerde, un, hueso”, oracion que querıa-mos generar. Con esta gramatica podemos producir otras oraciones como“un perro ladra”. Igualmente, nos resulta imposible generar “el perro ladraun hueso”. Sin embargo, permite oraciones agramaticales, como “una pe-rro muerde una hueso”. Mas adelante veremos como podemos anadir a lasgramaticas restricciones de concordancia.

6.2. Nuestra primera gramatica en Prolog

Prolog, el lenguaje mas popular de Programacion Logica, puede usarsepara escribir parsers, analizadores gramaticales que se componen de:

Una gramatica. Construiremos las gramaticas simplemente a partirde su conjunto de reglas, porque ahı se encontraran, implıcitos, losconjuntos de sımbolos terminales y no terminales.

Un mecanismo de busqueda, que sirve para recorrer las reglas de lagramatica al generar o analizar producciones correctas. En nuestrocaso, el mecanismo de busqueda sera el que proporciona Prolog, basadoen las operaciones logicas de unificacion y resolucion5.

En este trabajo usaremos las gramaticas clausales para programar par-sers gramaticales. Sin, embargo, las gramaticas DCG tambien sirven paraimplementar parsers morfologicos. Ası, el sistema GRAMPAL [6], emplealas DCG de Prolog para escribir gramaticas de formacion de palabras quesirven tanto para la generacion como para el analisis morfologico.

5Para profundizar en los fundamentos logicos de Prolog, recomendamos especialmenteel manual de P. Flach [4].

Page 5: Programación de gramáticas clausales en Prolog

“libro” — 2006/1/9 — 12:58 — page 95 — #113

6.2. Nuestra primera gramatica en Prolog 95

Vamos a comenzar explicando los elementos mınimos que nos permitiranimplementar gramaticas clausales en Prolog. Comencemos por el final. Lagramatica que mostramos en el ejemplo anterior puede programarse en Pro-log escribiendo tan solo lo siguiente, en un fichero de texto que podrıamosguardar, por ejemplo, con el nombre gramatica1.pl:

o --> sn, sv.sn --> det, n.sv --> vt, sn.sv --> vi.det --> [el].det --> [un].det --> [una].n --> [perro].n --> [hueso].vi --> [ladra].vt --> [muerde].

Como puede observarse, la sintaxis es la misma que ya habıamos usado.Solo debemos tener en cuenta la forma de la flecha de transformacion “-->”,que todas las reglas terminan en punto, que a la izquierda de cada reglasiempre hay un solo sımbolo no terminal, y que los sımbolos terminales vanencerrados entre los corchetes “[” y “]”. Por lo demas, podemos dar a lossımbolos los nombres que elijamos.

Ahora bien, ¿como hacemos para que nuestra gramatica “funcione”? Ne-cesitamos un compilador de Prolog, un sistema que permite a nuestro orde-nador comprender los programas (las gramaticas que escribiremos en estetrabajo son en realidad programas logicos) escritos en Prolog. Recomenda-mos el uso de SWI-Prolog, pues es el que hemos usado para crear las grama-ticas, y todo el codigo que aparece en este trabajo funciona en dicho com-pilador6. Puede descargarse gratis desde http://www.swi-prolog.org/, dondetambien podemos encontrar abundante documentacion. Una vez instalado7,podemos abrirlo8:

6A diferencia de lo que ocurre con otros lenguajes de programacion, no existe unestandar rıgido en Prolog. Aunque se suele tomar [3] como referencia, cada compiladorlo desarrolla de forma diferente, lo que hace que los programas escritos para un sistemadeban adaptarse en mayor o menor medida para que funcionen con otros compiladores.

7SWI-Prolog dispone de versiones para Linux, MS-Windows y MacOS X. En cualquiercaso, la instalacion es igual a la de cualquier programa para tales sistemas operativos.

8Generalmente basta con teclear pl en una consola, tal como hacemos en el ejemplo.

Page 6: Programación de gramáticas clausales en Prolog

“libro” — 2006/1/9 — 12:58 — page 96 — #114

96 Capıtulo 6. Programacion de gramaticas clausales. . .

> plWelcome to SWI-Prolog (Multi-threaded, Version 5.4.3)Copyright (c) 1990-2003 University of Amsterdam.SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is freesoftware, and you are welcome to redistribute it under certainconditions. Please visit http://www.swi-prolog.org for details

For help, use ?- help(Topic). or ?- apropos(Word).

?-

Entonces compilamos nuestra gramatica. Solo tenemos que escribir laorden “[gramatica1].” tras el signo “?-” con el que podemos dar instruc-ciones a Prolog. Veamos:

?- [gramatica1].% gramatica1 compiled 0.01 sec, 3,060 bytesYes

De nuevo debemos observar que las instrucciones que damos terminan siem-pre en punto. Lo anterior solo funciona si el fichero “gramatica1.pl” quecontiene nuestra gramatica se encuentra en la misma ruta desde la que eje-cutamos SWI-Prolog en la consola.

Una forma mas sencilla para escribir y compilar nuestras gramaticas esusar el editor que proporciona SWI-Prolog, que podemos abrir mediante“?- emacs.”. Desde ahı disponemos de menus que permiten abrir, editar ycompilar nuestros programas. Ademas, ofrece facilidades de edicion como elcoloreado de la sintaxis.

Tras compilar “gramatica1.pl” volvemos a encontrar, en la consola deSWI-Prolog, el signo“?-”. Ya podemos experimentar con nuestra gramatica:

?- phrase(o, [el, perro, ladra]).Yes?- phrase(o, [el, perro, Palabra, un, hueso]).Palabra = muerdeYes?- phrase(o, [el, perro, ladra, un, hueso]).No?- phrase(o, [el, perro, muerde, una, hueso]).Yes

Page 7: Programación de gramáticas clausales en Prolog

“libro” — 2006/1/9 — 12:58 — page 97 — #115

6.3. Concordancia de genero y numero 97

Hemos usado “phrase”, que es el predicado que emplea Prolog pararealizar las transformaciones gramaticales. Tambien ahora hemos termina-do cada instruccion en un punto. Ademas, “phrase” toma dos argumentos,separados por comas y encerrados entre parentesis. Las oraciones las re-presentamos como listas de Prolog, con los elementos separados por comasy encerrados entre corchetes. Por ultimo, solo las variables (mas adelantecomentaremos mas sobre ellas) pueden comenzar por una letra mayuscula.Para comprender el funcionamiento de“phrase/2” (lo escribimos ası por serun predicado de dos argumentos), comentemos los ejemplos anteriores. Me-diante“?- phrase(o, [el, perro, ladra])” lo que hacemos es preguntara Prolog si “el perro ladra” es una transformacion correcta (gramatical) dela categorıa “o” (por supuesto, siempre referido a la gramatica que hemoscompilado). Prolog nos responde que sı y vuelve a aceptar una nueva or-den. Entonces (segunda llamada a phrase/2) le preguntamos si hay algunaoracion gramatical tipo “el perro Palabra un hueso”, para algun valor dePalabra (se trata de una variable) y que nos diga cual es dicho valor. Enton-ces nos responde que sı, la cadena es gramatical si Palabra vale “muerde”9.En los dos ultimos ejemplos nos ha dicho que “el perro ladra un hueso” noes gramatical, pero que sı lo es “el perro muerde una hueso”.

6.3. Concordancia de genero y numero

La gramatica que hemos construido no contiene ninguna restriccion deconcordancia gramatical, por ello genera oraciones como “el perro muerdeuna hueso”. Una solucion posible a este problema es:

o --> sn(_Gen2,Num), sv(Num).sn(Gen,Num) --> det(Gen,Num), n(Gen,Num).sv(Num) --> vt(Num), sn(_Gen,_Num2).sv(Num) --> vi(Num).det(f,sg) --> [la]; [una].det(f,pl) --> [las]; [unas].det(m,sg) --> [el]; [un].det(m,pl) --> [los]; [unos].

9Cuando Prolog devuelve Palabra = muerde aun no escribe Yes, a la espera de quele pidamos o no mas soluciones (mas valores alternativos para Palabra). Lo que nosotroshemos hecho es pulsar la tecla enter en ese momento, por ello Prolog responde Yes. Peropodrıamos haber escrito tambien “;” (seguido o no de enter, segun la consola que usemos)para pedir nuevos valores de Palabra. En este ultimo caso, la respuesta final habrıa sidoNo. Cuando hay valores alternativos, los devuelve tras cada pulsacion del punto y coma.

Page 8: Programación de gramáticas clausales en Prolog

“libro” — 2006/1/9 — 12:58 — page 98 — #116

98 Capıtulo 6. Programacion de gramaticas clausales. . .

vi(sg) --> [ladra].vi(pl) --> [ladran].vt(sg) --> [muerde].vt(pl) --> [muerden].n(f,sg) --> [perra].n(f,pl) --> [perras].n(m,sg) --> [perro]; [hueso].n(m,pl) --> [perros]; [huesos].

Lo que hemos hecho es convertir las categorıas gramaticales en predi-cados de Prolog con argumentos que indican el genero y el numero. Porejemplo, la regla

sn(Gen,Num) --> det(Gen,Num), n(Gen,Num).

indica que un sintagma nominal tiene genero “Gen” (que sera “m” para mas-culino y “f” para femenino) y numero “Num” (“sg” para singular y “pl” paraplural) si esta compuesto por “det(Gen,Num)” y “n(Gen, Num)”, es decir,por un determinante y un nombre cuyos genero y numero no solo debencoincidir entre sı, sino que seran el genero y el numero que se transfieran ala oracion.

En algunas categorıas, de las que solo nos ha interesado marcar el nu-mero, hemos usado un solo argumento. Lo importante es que la gramaticaguarde coherencia interna. Es decir, el numero de argumentos, ası como suorden y contenido (genero, numero, etc.) debe ser fijo para cada categorıaen toda la gramatica.

Algo importante para que funcione la gramatica es que debe hacerseun uso correcto de las variables de Prolog10, que usaremos para expresarrasgos que pueden tomar distintos valores. Esta idea del uso de rasgos concontenido gramatical, y mecanismos de unificacion (como hace Prolog) paraimponer restricciones de concordancia, esta presente en numerosas teorıaslinguısticas [8]. Las gramaticas DCG de Prolog pueden emplearse para im-plementar muchas de tales teorıas, como la Gramatica Lexico-Funcional [11].

Hemos usado la variable universal de Prolog, que se representa mediantecualquier cadena de caracteres que comience por el guion bajo “_”. Porejemplo, en la regla

sv(Num) --> vt(Num), sn(_Gen,_Num2).

10Como hemos comentado, son variables de Prolog las cadenas de letras que empiezanpor al menos una letra mayuscula.

Page 9: Programación de gramáticas clausales en Prolog

“libro” — 2006/1/9 — 12:58 — page 99 — #117

6.3. Concordancia de genero y numero 99

la variable universal nos sirve para expresar que el sintagma verbal toma elnumero de su verbo, independientemente de los valores que tengan generoy numero de su sintagma nominal. En realidad, cuando usamos la variableuniversal no tiene importancia lo que escribamos tras el guion.

Por ultimo, queremos comentar el uso que se ha hecho del punto y coma“;”, que en Prolog tiene un valor disyuntivo. En realidad, una regla como

n(m,sg) --> [perro]; [hueso].

equivale a

n(m,sg) --> [perro].n(m,sg) --> [hueso].

con lo que podrıan haberse incluido las dos ultimas en vez de la primera yla gramatica serıa equivalente (en el sentido de que generarıa y reconocerıalas mismas oraciones). Sin embargo, para que sean mas cortos los ficheroshemos preferido emplear el punto y coma.

Ya solo queda usar nuestra gramatica11. Veamos:

?- phrase(o,[el, perro, muerde, un, hueso]).Yes?- phrase(o,[la, perro, muerde, un, hueso]).No?- phrase(o,[las, perras, muerde, un, hueso]).No?- phrase(o,[las, perras, muerden, un, hueso]).Yes?- phrase(o,[las, perras, muerden, un, huesos]).No?- phrase(o,[las, perras, muerden, unos, huesos]).Yes

Ahora sı hemos conseguido implementar la concordancia de genero y nu-mero. Pero las gramaticas no solo sirven para reconocer oraciones correctas,tambien pueden generarlas:

?- phrase(o, Oracion).Oracion = [la, perra, muerde, la, perra] ;Oracion = [la, perra, muerde, una, perra] ;

11Como antes, para ello debemos guardarla en un fichero con extension pl, como gra-

matica2.pl, y compilarla de la forma indicada.

Page 10: Programación de gramáticas clausales en Prolog

“libro” — 2006/1/9 — 12:58 — page 100 — #118

100 Capıtulo 6. Programacion de gramaticas clausales. . .

Oracion = [la, perra, muerde, las, perras] ;Oracion = [la, perra, muerde, unas, perras]Yes

Ahora lo que se ha hecho es pedir a Prolog que devuelva posibles valoresde “Oracion”, y como lo pedimos mediante “phrase(o, Oracion)” (sin ol-vidar el punto al final cuando lo escribamos en el compilador) exigimos que“Oracion” sea una transformacion correcta de la categorıa “o” en nuestragramatica. Prolog comienza a devolver diferentes valores (como vemos haycierto orden en las oraciones que devuelve, lo que se debe al modo en querecorre las reglas de la gramatica) mientras nosotros introduzcamos “;”. Sino hubieramos parado, habrıa devuelto un total de 156 oraciones, todas gra-maticales, pero alguna sin sentido, como “los huesos ladran”. Se trata de lacobertura de nuestra gramatica.

6.4. Construccion de arboles sintacticos

En ocasiones nos interesa no solo que los sistemas determinen si cier-ta oracion es o no gramatical, sino que ademas nos devuelvan un analisissintactico. Esto es lo que vamos a hacer en esta seccion, anadir a nuestragramatica la posibilidad de construir arboles sintacticos de las oraciones quegenera. Veamos como queda:

o(o(SN,SV)) --> sn(SN,_Gen,Num), sv(SV,Num).sn(sn(DET,N),Gen,Num) --> det(DET,Gen,Num), n(N,Gen,Num).sv(sv(VT,SN),Num) --> vt(VT,Num), sn(SN,_Gen,_Num).sv(sv(VI),Num) --> vi(VI,Num).det(det(X),f,sg) --> [X], {member(X,[la,una])}.det(det(X),f,pl) --> [X], {member(X,[las,unas])}.det(det(X),m,sg) --> [X], {member(X,[el,un])}.det(det(X),m,pl) --> [X], {member(X,[los,unos])}.vi(vi(ladra),sg) --> [ladra].vi(vi(ladran),pl) --> [ladran].vt(vt(muerde),sg) --> [muerde].vt(vt(muerden),pl) --> [muerden].n(n(perra),f,sg) --> [perra].n(n(perras),f,pl) --> [perras].n(n(X),m,sg) --> [X], {member(X,[perro,hueso])}.n(n(X),m,pl) --> [X], {member(X,[perros,huesos])}.arbol(Orac):- arbol(0,Orac).

Page 11: Programación de gramáticas clausales en Prolog

“libro” — 2006/1/9 — 12:58 — page 101 — #119

6.4. Construccion de arboles sintacticos 101

arbol(Tab,R):-nl,tab(Tab),R =.. Li,(Li = [_,_] ->format(’~w’,[R]);(Li = [S|Otros],format(’~w(’,[S]),atom_length(S,Ls),Tab2 is Tab+Ls+1,findall(_,(member(X,Otros),arbol(Tab2,X)),_)),format(’)’)).

Hay varias cosas que debemos explicar. Lo mas importante es que ahoralos predicados que representan las categorıas gramaticales toman un argu-mento mas. Los argumentos segundo y tercero no tienen ninguna novedad,son los que usamos en la gramatica de la seccion anterior. La clave esta enel primero. Para cada categorıa, el primer argumento recoge su analisis. Porejemplo, la regla

sn(sn(DET,N),Gen,Num) --> det(DET,Gen,Num), n(N,Gen,Num).

indica que el analisis de un sintagma nominal es sn(DET,N) si esta formadopor un determinante cuyo analisis es DET y por un nombre que tiene poranalisis N. Los restantes argumentos de cada categorıa implementan las res-tricciones de concordancia, y se comportan como ya hemos explicado. Deesta forma, se van anidando los analisis de los diferentes componentes de laoracion. El resultado es que, para una oracion como “el perro muerde unoshuesos”, el analisis que se genera es:

o(sn(det(el),n(perro)),sv(vt(muerde),sn(det(unos),n(huesos))))

Puede ser difıcil seguir la estructura del analisis anterior debido al grananidamiento de parentesis que contiene. Por ello, hemos incluido en la gra-matica el predicado arbol/1, que sirve para representar graficamente es-tructuras como la anterior de una forma mas sencilla de visualizar. Veamosun ejemplo de su uso:

?- phrase(o(A),[el,perro,muerde,unos,huesos]), arbol(A).o(sn(

det(el)n(perro))

sv(vt(muerde)sn(

Page 12: Programación de gramáticas clausales en Prolog

“libro” — 2006/1/9 — 12:58 — page 102 — #120

102 Capıtulo 6. Programacion de gramaticas clausales. . .

det(unos)n(huesos))))

A = o(sn(det(el), n(perro)),sv(vt(muerde), sn(det(unos), n(huesos))))

Yes

En este ejemplo hemos pedido a Prolog que compruebe si“el perro muer-de unos huesos” es o no una oracion correcta, cuyo analisis sea A (puestoque hemos lanzado la pregunta usando phrase/2, y poniendo o(A) como lacategorıa de la que deseamos comprobar si la frase propuesta es una trans-formacion correcta o no; como A es una variable estamos pidiendo los valoresque debe tomar para que sea verdad nuestra pregunta). En este caso, no he-mos puesto un punto al final de la pregunta, sino una coma y otro predicado,arbol(A), seguido de un punto. Con esto lo que hacemos es que, una vezobtenido el valor de A, dibuje un arbol que represente su estructura.

No vamos a explicar como funciona el predicado arbol/1; para ver masdetalles sobre esto, se puede acudir a la ayuda de SWI-Prolog (a la quees posible acceder mediante “?- help.”), donde se da cuenta de todos lospredicados contenidos en su definicion.

Terminamos esta seccion comentando uno de los recursos mas intere-santes que se han empleado en esta gramatica. Se trata de las llaves “{” y“}” que aparecen en algunas reglas. Aquı esta la clave de la gran expresivi-dad que pueden tener estas gramaticas, puesto que con estas llaves resultaposible anadir a las reglas condiciones adicionales, usando para ello todoslos recursos del lenguaje Prolog. Como Prolog es un lenguaje de Progra-macion universal, es decir, podemos implementar en el cualquier algoritmo,podremos hacer gramaticas tan expresivas como queramos (por supuesto,pagando el correspondiente precio en complejidad).

En la gramatica anterior, hemos usado los corchetes solo en reglas deltipo

det(det(X),f,sg) --> [X], {member(X,[la,una])}.

y lo que encierran en su interior es una llamada al predicado member/2de Prolog, en este caso para senalar que X debe ser un miembro de la listaformada por la y una. Ası, solo necesitamos una regla para los determinantesde genero femenino y numero singular. En la seccion 6.6 se hara un mayoruso de este recurso.

Page 13: Programación de gramáticas clausales en Prolog

“libro” — 2006/1/9 — 12:58 — page 103 — #121

6.5. Pequeno sistema de traduccion 103

6.5. Pequeno sistema de traduccion

La traduccion automatica es probablemente la aplicacion mas impor-tante de la Linguıstica Computacional. En esta seccion vamos a mostrarcomo podemos emplear las gramaticas para realizar traducciones. Nos cen-traremos en el conjunto de oraciones simples de tipo Sujeto-Verbo-Objetousadas en el juego “piedra, papel, tijeras”. Las clausulas que definen nuestragramatica son:

% Inglessentence(s(S,V,O)) --> nom_p(S,N), verb(V,N), nom_p(O,_).nom_p(np(M,S),N) --> modifier(M), noun(S,N).modifier(m(art)) --> [the].noun(n(n_1),sg) --> [stone].noun(n(n_2),sg) --> [paper].noun(n(n_3),pl) --> [scissors].verb(v(v_1),sg) --> [cuts].verb(v(v_2),sg) --> [wraps].verb(v(v_3),sg) --> [breaks].verb(v(v_1),pl) --> [cut].verb(v(v_2),pl) --> [wrap].verb(v(v_3),pl) --> [break].

% Espa~noloracion(s(S,V,O)) --> sint_n(S,N), verbo(V,N), sint_n(O,_).sint_n(np(M,S),N) --> artıculo(M,G,N), nombre(S,G,N).artıculo(m(art),f,sg) --> [la].artıculo(m(art),m,sg) --> [el].artıculo(m(art),f,pl) --> [las].nombre(n(n_1),f,sg) --> [piedra].nombre(n(n_2),m,sg) --> [papel].nombre(n(n_3),f,pl) --> [tijeras].verbo(v(v_1),sg) --> [corta].verbo(v(v_2),sg) --> [envuelve].verbo(v(v_3),sg) --> [rompe].verbo(v(v_1),pl) --> [cortan].verbo(v(v_2),pl) --> [envuelven].verbo(v(v_3),pl) --> [rompen].

Como vemos, la gramatica esta dividida en dos secciones. Una, que sirvepara generar oraciones en ingles, que desarrolla las transformaciones posibles

Page 14: Programación de gramáticas clausales en Prolog

“libro” — 2006/1/9 — 12:58 — page 104 — #122

104 Capıtulo 6. Programacion de gramaticas clausales. . .

del sımbolo no terminal sentence, y otra, para el espanol, que hace posibleslas transformaciones del sımbolo oracion. Cada una de las dos partes porseparado se parece a la gramatica que construimos en la seccion 6.4. Ademas,cada gramatica tiene sus propios sımbolos terminales y no terminales12. Nopodemos ni siquiera hacer correspondencias exactas entre sımbolos, puespor ejemplo nombre, en la gramatica del espanol, toma tres argumentos,mientras que noun, en la del ingles, tiene tan solo dos. Entonces, ¿que nospermitira hacer traducciones? Pues que las dos gramaticas comparten elanalisis sintactico, que ahora no es el propio ni del espanol ni del ingles,sino que se trata de un codigo artificial (algo ası como una interlingua) quehemos creado a proposito. Veamos,

?- phrase(oracion(A),[las, tijeras, cortan, el, papel]).A = s(np(m(art), n(n_3)), v(v_1), np(m(art), n(n_2)))Yes?- phrase(sentence(B),[the, scissors, cut, the, paper]).B = s(np(m(art), n(n_3)), v(v_1), np(m(art), n(n_2)))Yes

Si pedimos el analisis de “las tijeras cortan el papel” como transforma-cion de oracion(A) y de “the scissors cut the paper” de sentence(B), enambos casos A y B contienen el mismo analisis (vease el ejemplo anterior). Setrata de un termino formado por el sımbolo s (que en espanol representaraoracion y en ingles sentence) que toma dos argumentos (primero y tercero)construidos mediante el sımbolo np (que representa un sintagma nominal,lo que en la gramatica del espanol se ha representado como sint_n y en ladel ingles como nom_p) y otro mediante v (verbo o verb). Por lo demas, mrepresenta un artıculo y n un sustantivo. En cuanto al lexico, para este co-digo comun hemos usado unas etiquetas que despues hacemos correspondencon palabras o conjuntos de palabras de cada lengua. Ası, v_1 representa enespanol tanto “corta” como “cortan” (que se use una forma u otra, en cadaoracion, vendra impuesto por las restricciones propias de la gramatica delespanol) y en ingles “cuts” o “cut”. Es significativo lo que ocurre con art;mientras que en la gramatica del ingles solo se corresponde con “the”, enespanol puede adquirir varias formas, segun el genero y numero.

Podemos usar estas gramaticas de varias formas:

?- phrase(sentence(A),[the, stone, breaks, the, scissors]),

12Por ello hemos podido programar ambas gramaticas en el mismo fichero. En otro casohabrıa que haber usado modulos (mas informacion sobre esto en la documentacion deSWI-Prolog).

Page 15: Programación de gramáticas clausales en Prolog

“libro” — 2006/1/9 — 12:58 — page 105 — #123

6.6. Una gramatica mas compleja 105

phrase(oracion(A),Espa~nol).A = s(np(m(art), n(n_1)), v(v_3), np(m(art), n(n_3)))Espa~nol = [la, piedra, rompe, las, tijeras]Yes?- phrase(oracion(B),[el, papel, envuelve, la, piedra]),

phrase(sentence(B),Ingles).B = s(np(m(art), n(n_2)), v(v_2), np(m(art), n(n_1)))Ingles = [the, paper, wraps, the, stone]Yes?- phrase(oracion(C),Espa~nol), phrase(sentence(C),Ingles).C = s(np(m(art), n(n_1)), v(v_1), np(m(art), n(n_1)))Espa~nol = [la, piedra, corta, la, piedra]Ingles = [the, stone, cuts, the, stone] ;

C = s(np(m(art), n(n_1)), v(v_1), np(m(art), n(n_2)))Espa~nol = [la, piedra, corta, el, papel]Ingles = [the, stone, cuts, the, paper]Yes

En el primer caso, hemos pedido que analice “the stone breaks the scis-sors” como una transformacion de sentence (por lo que empleara la gra-matica inglesa) y guarde el analisis en A, para a continuacion pedir quegenere, en espanol, una oracion que tenga A por analisis. Usamos la variableEspa~nol para pedir dicha oracion. Prolog realiza estas tareas, y devuelvepara Espa~nol el valor “la piedra rompe las tijeras”. El segundo ejemplo essimilar, aunque esta vez traduce del espanol al ingles. En el ultimo ejem-plo, pedimos que genere una oracion en espanol que tenga C como analisisy Espa~nol como transformacion. Como ambos argumentos son variables,Prolog buscara la primera oracion en espanol que encuentre. A continua-cion, pedimos que genere la traduccion en ingles para dicha oracion, puestoque mediante phrase(sentence(C),Ingles) pedimos que tome el analisisC y lo transforme en Ingles, una expansion de sentence. Cuando Prolognos devuelve la primera solucion (con los valores correspondientes para C,Espa~nol e Ingles) pedimos otra mediante “;”.

6.6. Una gramatica mas compleja

A continuacion presentamos una gramatica mas compleja que las ante-riores, en que las reglas de produccion recurren frecuentemente a predicadosde Prolog. El proposito de esta gramatica es generar, para cada hora expre-

Page 16: Programación de gramáticas clausales en Prolog

“libro” — 2006/1/9 — 12:58 — page 106 — #124

106 Capıtulo 6. Programacion de gramaticas clausales. . .

sada numericamente, como 4 : 45, una expresion en espanol que se refiera ala misma hora, como“las cinco menos cuarto”. Igualmente, para cada expre-sion verbal de una hora, debera generar la hora correspondiente en formanumerica. Ası veremos que la posibilidad de analizar las oraciones generadaspor gramaticas DCG sirve para mucho mas que para obtener arboles sin-tacticos. En realidad, lo que hara esta gramatica es relacionar pares H : M ,en que H es una hora entre 1 y 12 y M un numero de minutos entre 0 y59, con secuencias de palabras que expresan cada hora. La cobertura seracompleta, es decir, para cada una de las 720 posibles horas (el productode 12, numero de horas, y 60, numero de minutos) habra una cadena depalabras correspondiente. Veamos el programa:

hora(H:M) --> {between(1,12,H), between(0,59,M)},artıculo(H,M), que_hora(H,M), minutos(M).

artıculo(H,M) --> [la], {sg_pl(H,M,sg)}.artıculo(H,M) --> [las], {sg_pl(H,M,pl)}.que_hora(H,M) --> [Hora], {hora_base(H,M,HB),h(HB,_,_,Hora)}.minutos(0) --> [en, punto].minutos(M) --> [y], exp_mins(M), {between(1,30,M)}.minutos(M) --> [menos],exp_mins(M2),

{between(31,59,M),h(M2,M,_,_)}.exp_mins(15) --> [cuarto].exp_mins(30) --> [media].exp_mins(M) --> [Pal], num_mins(M),{h(M,_,Pal,_),

(between(1,14,M); between(16,29,M))}.num_mins(1) --> [minuto].num_mins(M) --> [minutos], {between(2,29,M)}.

sg_pl(H,M,sg) :- hora_base(H,M,1).sg_pl(H,M,pl) :- hora_base(H,M,HB), between(2,12,HB).hora_base(H,M,H) :- between(0,30,M).hora_base(12,M,1) :- between(31,59,M).hora_base(H,M,HB) :- between(31,59,M),

between(2,12,HB), succ(H,HB).h(1, 59, un, una).h(Num1, Num2, Pal, Pal) :-

between(2,29,Num1),plus(Num1,Num2,60),nth1(Num1,[uno,dos,tres,cuatro,cinco,seis,siete,ocho,nueve,diez,once,doce,trece,catorce,quince,dieciseis,diecisiete,dieciocho,diecinueve,veinte,veintiun,veintidos,veintitres,

Page 17: Programación de gramáticas clausales en Prolog

“libro” — 2006/1/9 — 12:58 — page 107 — #125

6.6. Una gramatica mas compleja 107

veinticuatro,veinticinco,veintiseis,veintisiete,veintiocho,veintinueve],Pal).

El sımbolo raız de la gramatica es hora(H:M). En su argumento, H:M,hemos usado los dos puntos “:”, que estan predefinidos en Prolog comooperador. En la regla de produccion correspondiente, se realizan llamadas(dentro de las llaves, para imponer a las reglas restricciones basadas enpredicados de Prolog) a between(N1,N2,M), predicado que impone que elnumero M este comprendido entre los dos numeros N1 y N2. Con ello, res-tringimos las expresiones tipo H:M a valores de H entre 1 y 12 y de M entre0 y 59. Entonces, hora(H:M) se reescribe como:

artıculo(H,M), que sera o bien “la” (como en “la una menos cuarto”)o “las” (“las cuatro y media”), segun sean H y M.

que_hora(H,M), que sera el nombre de la hora que se expresa, y de-pende no solo de H sino tambien de M, pues por ejemplo para 3:50diremos “las cuatro menos diez minutos”.

minutos(M), que segun sea M tomara valores tales como“y media”, “enpunto”, “menos diez minutos”, “y un minuto”, etc.

Comencemos con artıculo(H,M). Las dos reglas de produccion paraeste sımbolo imponen que se reescriba como“la” o como“las” segun sea “sg”o “pl” el valor que devuelva sg_pl(H,M,X) para X. En realidad, se trata deque “la” se reserve para “la una. . . ” y en todos los demas casos se use “las”.El predicado sg_pl/3 se encarga de este cometido. No comentaremos lospredicados auxiliares empleados en esta gramatica. Estan todos construidosa partir de un pequeno numero de predicados predefinidos en SWI-Prolog(puede encontrarse documentacion sobre estos predicados en la ayuda delcompilador).

En cuanto a que_hora(H,M), se reescribe como la palabra correspon-diente a la hora que va a aparecer en la expresion correspondiente a H:M. Laregla de produccion empleada recurre a los predicados hora_base(H,M,HB),que dadas H y M devuelve el numero HB de la hora que se escribira (debetenerse en cuenta que si M es mayor a 30 entonces HB es la hora siguiente aH, y en otro caso es H; ademas, la hora siguiente a H no siempre se obtienesumandole una unidad, pues cuando H es 12 la siguiente hora es la 1), y elpredicado h(HB, _, _, Hora) (algunos argumentos aparecen con la varia-ble universal porque su contenido no nos interesa ahora) que dada la horaHB devuelve su nombre Hora, que sera una palabra como “una”, “dos”, etc.

Page 18: Programación de gramáticas clausales en Prolog

“libro” — 2006/1/9 — 12:58 — page 108 — #126

108 Capıtulo 6. Programacion de gramaticas clausales. . .

El sımbolo minutos(M) se transformara o bien en “en punto”, si M es 0, oen una expresion que comienza por “y” (si M esta entre 1 y 30) o por “menos”(para valores de M mayores a 30 y que termina por el numero de minutos,resultado de transformar exp_mins(M), cuando M es menor o igual a 30, obien exp_mins(M2), donde M2 es la diferencia entre 60 y M (para encontrarM2 se emplea h/4 tambien), cuando M es mayor a 30. Esto es ası porque,por ejemplo, para 5 : 35 decimos “las seis menos veinticinco minutos”, pues60− 35 = 25.

La transformacion de exp_mins(M) es “cuarto” (si M es 15), “media” (siM es 30) o bien la palabra que expresa el numero de minutos M. Ahora,obtenemos esta palabra con el tercer argumento de h/4, en vez de con elcuarto, que usamos para las palabras correspondiente a las horas. Esto esası para respetar la concordancia de genero entre de “horas” con las formasfemeninas de los numeros (“la una”) y de “minutos” con las masculinas (“yun minuto”). Por ultimo, la transformacion de exp_mins(M) termina connum_mins(M).

Finalmente, num_mins(M) se transforma en “minuto” si M es 1 y en “mi-nutos” en otro caso.

Terminamos con algunos ejemplos. En los dos primeros Prolog nos de-vuelve la frase correspondiente a una hora. En el ultimo, nos dice la horaque corresponde a una frase:

?- phrase(hora(12:40),F).F = [la, una, menos, veinte, minutos]Yes?- phrase(hora(15:25),F).F = [las, tres, y, veinticinco, minutos]Yes?- phrase(hora(H), [las, dos, y, cuarto]).H = 2:15Yes

6.7. Comparacion con las gramaticasindependientes del contexto

Las gramaticas independientes del contexto han recibido siempre unaatencion especial, debido a la cantidad de fenomenos linguısticos que per-miten modelar, ası como por su tratabilidad computacional13, debido a su

13A medida que subimos en la jerarquıa de Chomsky, y nos acercamos a las gramaticasde tipo 0, las gramaticas son mas expresivas, es decir, permiten generar mayor cantidad de

Page 19: Programación de gramáticas clausales en Prolog

“libro” — 2006/1/9 — 12:58 — page 109 — #127

6.7. Comparacion con las gramaticas. . . 109

moderada complejidad. Sin embargo, el propio Chomsky [2] observa que es-tas gramaticas no tienen suficiente expresividad para dar cuenta de ciertasestructuras propias de las lenguas naturales. Por ejemplo, no es posible crearuna gramatica independiente del contexto que genere todas las cadenas tipoanbncn, es decir, cadenas compuestas por n repeticiones de a seguidas porotras tantas de b y finalmente de c, para cualquier valor arbitrario de n. Puesbien, esta limitacion impide a las gramaticas independientes del contexto darcuenta de oraciones que en ciertas lenguas naturales son gramaticales y quesiguen esta misma estructura.

Sin embargo, es posible escribir en Prolog una gramatica DCG que ge-nere todas y solo todas las cadenas tipo anbncn. Veamos:

o --> [a], s(i). % 1s(I) --> nb(I), nc(I). % 2s(I) --> [a], s(i(I)). % 3nb(i(I)) --> [b], nb(I). % 4nb(i) --> [b]. % 5nc(i(I)) --> [c], nc(I). % 6nc(i) --> [c]. % 7

Si pedimos mediante “phrase(o,C)” que genere sucesivamente todas lastransformaciones posibles para la categorıa “o” ocurre lo siguiente:

?- phrase(o,C).C = [a, b, c] ;C = [a, a, b, b, c, c] ;C = [a, a, a, b, b, b, c, c, c] ;C = [a, a, a, a, b, b, b, b, c, c, c, c]Yes

Como vemos, se generan solo las cadenas que querıamos. Con esto ob-servamos que las gramaticas DCG de Prolog son mas expresivas que lasgramaticas independientes del contexto.

¿Como consigue la gramatica anterior generar todas las cadenas tipoanbncn? La clave esta en el sımbolo no terminal “s(I)”, que funciona comoun contador. Al inicio, la unica transformacion posible es la que permite la

lenguajes. Pero a la vez, los parsers que pueden manejar tales gramaticas (para analizaro generar oraciones correctas) son mas complejos, en el sentido de que necesitan masrecursos (en un ordenador, memoria y tiempo) para funcionar. Por ello, uno de los temasde investigacion mas recurrentes en Linguıstica Computacional es la busqueda de lasgramaticas menos complejas que puedan dar cuenta de los fenomenos linguısticos propiosde las lenguas naturales.

Page 20: Programación de gramáticas clausales en Prolog

“libro” — 2006/1/9 — 12:58 — page 110 — #128

110 Capıtulo 6. Programacion de gramaticas clausales. . .

regla 1 (nos referimos a cada regla por el numero que aparece tras “%”; estesigno se usa para hacer comentarios en el programa, anotaciones que el com-pilador no interpreta), que transforma “o” en la secuencia que contiene “a”y “s(i)”. Este es unico sımbolo al que es posible ahora aplicar una trans-formacion; en este momento tiene el valor inicial del contador. Entonces,mientras se apliquen ahora sucesivas transformaciones segun la regla 3, sevan anadiendo nuevas “a” a la cadena, pero a la vez el valor del contador seincrementa, pasando de s(i) a s(s(i)), a s(s(s(i))) y ası sucesivamente.Finalmente, cuando se aplica al contador la regla 2, se escriben tantas “b”y tantas “c” como sea su valor, mediante las reglas 4–7.

El recurso que nos ha permitido superar la expresividad de las gramati-cas independientes del contexto ha sido, como hemos comentado, el uso quehemos hecho de los mecanismos propios de Prolog. En resumen, los elemen-tos de las DCG que extienden las gramaticas independientes del contexto,son:

La posibilidad de usar predicados (en el sentido de Prolog) para lossımbolos terminales y no terminales. Este recurso, que hemos usado entodas las gramaticas presentadas a partir de la seccion 6.3., ha mos-trado su utilidad para implementar desde la concordancia de genero ynumero hasta la traduccion entre lenguas.

La posibilidad de anadir condiciones adicionales a las reglas. Esto lohemos hecho en la gramatica de la seccion 6.4 (donde se explico el usode las llaves “{” y “}” a este proposito) y en la seccion 6.6.

La disponibilidad de los mecanismos de control propios de Prolog. Dehecho, estas gramaticas son programas logicos en Prolog, por lo quepueden usarse recursos como la disyuncion “;” o el corte “!”14.

Bibliografıa

[1] Patrick Blackburn, Johan Bos, y Kristina Striegnitz. Learn Prolognow! University of the Saarland, 2001. Publicacion electronica enhttp://www.coli.uni-sb.de/˜kris/learn-prolog-now/.

14No hemos comentado nada del corte “!” de Prolog, puesto que va mas alla de losobjetivos de este trabajo. Los lectores que deseen profundizar en Prolog pueden hacerloa traves de las referencias que proporcionamos en la bibliografıa. Recomendamos espe-cialmente el curso de P. Blackburn, J. Boss y K. Striegnitz [1], al que puede accederselibremente a traves de Internet.

Page 21: Programación de gramáticas clausales en Prolog

“libro” — 2006/1/9 — 12:58 — page 111 — #129

Bibliografıa 111

[2] Noam Chomsky. Syntactic Structures. Mouton, La Haya, 1957. Trad.esp.: Estructuras sintacticas, Mexico, Siglo XXI, 1974.

[3] Pierre Deransart, AbdelAli Ed-Dbali, and Laurent Cervoni. Prolog,The Standard: Reference Manual. Springer, 1996.

[4] Peter Flach. Simply Logical. Intelligent Reasoning by Example. JohnWiley, 1994.

[5] Joaquın Garrido Medina. Logica y Linguıstica. Sıntesis, 1994.

[6] Antonio Moreno y Jose M. Goni. GRAMPAL: a morphological pro-cessor for Spanish implemented in Prolog. En Proceedings of the JointConference on Declarative Programming (GULP-PRODE’95), paginas321–331, 1995.

[7] Antonio Moreno Sandoval. Linguıstica computacional. Ed. Sıntesis,1998.

[8] Antonio Moreno Sandoval. Gramaticas de unificacion y rasgos. A.Machado Libros, 2001.

[9] David Poole, Alan Mackworth, y Randy Goebel. Computational Inte-lligence: A Logical Approach. Oxford University Press, 1998.

[10] Stuart Russell y Peter Norvig. Inteligencia Artificial: un enfoque mo-derno. Prentice Hall, 1996.

[11] Hideki Yasukawa. LFG System in Prolog. En COLING, paginas 358–361, 1984.