next up previous contents
Next: Procedimientos y programación en Up: Programación en lógica Previous: Problemas   Contents


Interpretación algorítmica

Abstract:

La interpretación algorítmica de la programación en lógica, induce una semántica operacional, que sirve de base a las implementaciones existentes. Un programa en lógica se interpreta como un conjunto de definiciones de procedimientos. Sin embargo el modelo de activación y ejecución de los procedimientos aquí presentados, no corresponde al tradicional de los lenguajes imperativos. Por un lado los parámetros servirán para determinar cuál procedimiento activar. La ejecución corresponderá al recorrido de un espacio de computaciones posibles, ya que el modelo general de evaluación será no determinista. En este capítulo se analizarán todos estos aspectos y se culminará presentando las estrategias usuales de evaluación.

En el capítulo anterior se presentó una interpretación lógica que permite entender el significado de los programas en lógica. Un programa representa la definición axiomática de una teoría formal, y una invocación a la ejecución del mismo se interpreta como una fórmula a ser demostrada como válida en dicha teoría. Dicha demostración se puede realizar mediante los mecanismos de derivación sintáctica, utilizando reglas de derivación que sean completas. En particular se presentó la regla de resolución de Robinson, que cumple con dicha propiedad, y se culminó el capítulo con un modelo para la aplicación de un paso inferencial. Sin embargo queda sin explicar una estrategia general de la prueba, que contemple los casos de imposibilidad de unificación, así como la selección de predicados y reglas del programa. En definitiva, es necesario definir un control global que especifique en cada punto de decisión cuál es el camino a seguir.

La componente de control es una de las características más claras de la programación imperativa tradicional. La semántica operacional de los lenguajes de programación clásicos se basan en una máquina de estados, y cada constructor se define en términos de de la transición de estados que la ejecución del mismo produce. La evolución de la máquina de estados es la base del concepto de algoritmo. La dificultad que surge para utilizar el mismo enfoque en la programación en lógica proviene de que la máquina que naturalmente se necesitaría, sería no determinística, en el sentido en que se aplica en teoría de autómatas.

La ejecución de un programa en lógica implica la existencia de una derivación sintáctica. El problema que se presenta es cómo hallar dicha derivación. De la metodología presentada en el capítulo anterior, surge que en el proceso de la prueba existen varios puntos donde es necesario realizar una decisión. En los ejemplos presentados las elecciones de objetivos y reglas se han hecho escogiendo la buena alternativa. No se planteó, sin embargo, qué hacer en caso contrario. Lo que está faltando, entonces, es definir una componente de control a la programación en lógica, que determine cómo proceder para la ejecución total de un programa.

Para expresar una visión de la programación que se fue imponiendo hace unos años, Wirth escribió un libro con un título muy sugestivo:

Algoritmos + Estructuras de datos = Programas

donde se pretende poner en evidencia que un programa se obtiene a partir de la información estructurada a través del concepto de tipo (que constituye una componente estática), combinada con un algortimo, donde aparece el control.

Kowalski[Kow79] por su parte escribió un artículo cuyo título, emulando al de Wirth, fue:

Algoritmos = Lógica + Control

En este caso la componente estática proviene de la lógica, y si a ella se le agrega un mecanismo de control, entonces se obtienen los algoritmos. Es de hacer notar que en la parte que representa la lógica en la ecuación se incluyen tanto los datos como la especificación del problema a resolver. Este elemento es el que le da el carácter denotacional a la programación en lógica, y utilizando una terminología que ya ha sido presentada, es posible reformular la ecuación de Kowalski escribiendo:

Algoritmos = Qué + Cómo

La interpretación algorítmica que se verá en este capítulo se concentrará en cómo iintroducir una componente de control a la programación en lógica. En esta interpretación los programas serán considerados como definiciones de procedimientos, y la ejecución de los mismos se realizará siguiendo el modelo de invocación a rutinas de un lenguaje a la Pascal. Es por dicha razón que a la interpretación que aquí se llama algorítmica, se la llama también procedimental, que pretende ser una adaptación al castellano de la palabra inglesa «englishprocedural».

El auge actual de la programación en lógica, se inicia con los trabajos de A. Colmerauer y Ph. Roussel en la Universidad de Aix-Marsella II. Ellos crearon en 1973 el lenguaje PROLOG, inicialmente concebido para el tratamiento del lenguaje natural[Col73]. El nombre PROLOG proviene de PROGgrammation en LOGique, y una primera presentación del mismo apareció en[Rou75]. Luego de implementaciones internas realizadas por Ph. Roussel, el primer intérprete que tuvo difusión fue escrito por Battani y Meloni[Bat73]. Dicho intérprete fue escrito en lenguaje FORTRAN, y ese hecho facilitó su instalación en diversas universidades y centros de investigación; ¿quién no disponía de un compilador FORTRAN en aquella época? (¡y aún hoy día!). Enormes paquetes de tarjetas perforadas con el intérprete se trasladaron por Europa, llegando a Inglaterra, Escocia, Hungría, Portugal, entre otros países. En 1976, uno de los autores de este trabajo, J. Vidart, consiguió una copia que instaló en la Universidad Simón Bolívar, en Venezuela. Se formó así el primer grupo en Latinoamérica trabajando en PROLOG, y ese grupo se reforzó con la presencia durante cuatro años de Ph. Roussel.

PROLOG fue durante bastante tiempo un lenguaje de investigación, considerado por muchos como un juguete académico. Su utilización estaba poco generalizada, e incluso era muy poco conocido en los Estado Unidos de Norteamérica, donde se pensaba que para las aplicaciones de Inteligencia Artificial alcanzaba con el lenguaje LISP. Sin embargo, se habían producido avances muy importantes en la implementación de PROLOG, y el excelente trabajo de Warren[War79] constituyó un aporte de capital importancia, al abandonar el terreno de los prototipos y disponer de eficiencia en el trabajo con el lenguaje. A nivel de la divulgación de PROLOG, el libro de Clocksin y Mellish[Clo81] significó a su vez, un aporte relevante.

No fue, sin embargo, hasta la aparición del proyecto de 5.ª generación de computadoras anunciado por el Japón, que PROLOG adquirió relevancia internacional, y pasó a ocupar el primer plano de la investigación y desarrollo de lenguajes para la inteligencia artificial. El proyecto japonés representó un verdadero impacto en el desarrollo de la inteligencia artificial, y de la informática en general, tal vez no tanto por los objetivos planteados, sino por el cambio que manifestaba en la priorización de las herramientas informáticas. La programación de los años ´90 sería simbólica y no numérica: las nuevas máquinas deben ser capaces de inferir, más que de calcular; la capacidad de esas máquinas se deberá medir en LIPS (englishlogical inferences per second) y no en MIPS como actualmente. Desde el punto de vista de diseño, la máquina a que apunta el proyecto, tendría como lenguaje de máquina a alguna versión de PROLOG.

A partir del anuncio japonés, PROLOG tuvo un desarrollo impresionante. Se multiplicaron las implementaciones, y aparecieron compiladores muy eficientes. Las desventajas iniciales respecto a las implementaciones de lenguajes como LISP, se han ido reduciendo, y actualmente la decisión de elegir entre PROLOG y LISP para una aplicación de inteligencia artificial, no pasa necesariamente por la eficiencia de los programas que se construyen. No sólo se han desarrollado implementaciones para máquinas de tamaño importante, sino que existen múltiples versiones para micro computadores. La aparición del TURBO-PROLOG (MR) de Borland a un precio muy accesible, contribuyó a la difución masiva del lenguaje, si bien introduce algunas modificaciones a lo que puede llamarse el PROLOG tradicional.

No solamente el desarrollo consistió en implementaciones cada vez más eficientes, sino que además se ha ido generando una serie de lenguajes derivados del PROLOG inicial, donde se ha ido incorporando mejoras. Esencialmente las modificaciones conciernen a las primitivas de control, y a mecanismos de modularización para facilitar la construcción de sistemas de tamaño importante.

Para poder utilizar alguna versión de PROLOG como lenguaje de base para el proyecto de 5.ª generación, resultaba imprescindible disponer de primitivas explícitas para el manejo de la concurrencia. Los lenguajes Concurrent PROLOG y GHC (englishGuarded Horn Clauses) proveen mecanismos para expresar que ciertas operaciones pueden ejecutarse en paralelo.



Subsections
next up previous contents
Next: Procedimientos y programación en Up: Programación en lógica Previous: Problemas   Contents
Cesar Ballardini
2003-10-14
Hosted by www.Geocities.ws

1