Implementación del Chatbot Eliza

 

El algoritmo, que permite que Eliza genere una respuesta acorde a las consultas del usuario, se basa en comparar término a término la data ingresada versus una lista de templates con las respuestas predefinidas. Las ideas iniciales para desarrollar este algoritmo fueron obtenidas de [2] y de [3], a partir de estas fuentes se realizó una implementación propia.

El formato de cada template es el siguiente:

template([lista con las palabras del estímulo], [lista con las palabras de la respuesta de Eliza], [lista con las posiciones de las palabras clave en el estímulo empezando de cero]).

Un template de ejemplo tendrá la forma:


Las palabras clave le permiten a Eliza generar una coincidencia para diferentes listas de palabras, tales como “i am sad.” o “i am angry.”. Las palabras claves se reemplazarán en la respuesta en las posiciones donde hay números y no palabras.
 

La función que realiza la comparación es la función “match”. En el estímulo, las palabras clave están marcadas por predicados, mientras que el resto de los términos son atómicos. Cuando la función match detecta un dato no atómico, usando la función de SWI-Prolog “atom”, lo ignora y continúa con la comparación término a término entre la data ingresada y el estímulo. Si se encuentra un template que coincida, devolverá la respuesta correspondiente y la lista de índices. Los índices deben coincidir con las posiciones de los datos no atómicos en el estímulo del template.
 

La función “replace0” se encarga de reemplazar las palabras claves de la data ingresada en las posiciones donde la respuesta del template tiene números. Las palabras clave pueden ser una o más. Para saber qué palabra clave corresponde a qué posición en la respuesta, los números se van incrementando de uno en uno. Si no hay palabras para reemplazar, la lista de índices será una lista vacía.

Esta función llama a las siguientes funciones ya implementadas en SWI-Porlog:

nth0: devuelve el elemento de una lista en una posición dada.

select: reemplaza el valor de un elemento de una lista por otro en función a sus valores.

append: concatena dos listas. En este caso va concatenando las palabras de la respuesta, junto con la palabra reemplazada en la posición donde hay un número, palabra por palabra.
 

La función “replace0” también genera las respuestas a preguntas y consultas del tipo “do you like ...?”, “you are ...” y “do you (verb) ...?”. Los templates correspondientes tienen el siguiente formato:
 


 

Si la función “replace0” detecta una de las banderas (flags) configuradas, buscará la respuesta correspondiente en las funciones elizaDoes, elizaIs y ElizaLikes, las cuales evalúan los hechos que determinan si Eliza hace, es o le gusta algo.
 

El código donde se declaran estos hechos es el siguiente.


 

El código que le permite al usuario ingresar sus consultas es el siguiente:


 

La función “readln” convierte las consultas del usuario en una lista. Luego el programa escogerá el primer template de la base del conocimiento, a continuación el estímulo de ese template, y la consulta del usuario (Input), son ingresados a la función “match”. Si el estímulo no coincide con la consulta, Prolog empezará el backtracking, escogiendo el siguiente template y repitiendo la operación. El último template de la base de conocimiento hace que la función “match” retorne verdadero si ninguno de los otros estímulos de los otros templates coincide con la consulta del usuario. Esto evita que se rompa el bucle de Eliza y finalice el programa de forma abrupta. A continuación se llama a la función “replace0”, para luego imprimir la respuesta en la pantalla. Eliza seguirá esperando las consultas del usuario mientras éste no ingrese “bye” o “bye.”.
 

II

Conversando con Eliza


Para interactuar con el programa Eliza, se debe ejecutar el intérprete SWI-Prolog, abrir el archvo eliza_complete.pl y compilarlo. En la consola de SWI-Prolog se deberá ingresar “eliza.” Eliza mostrará un mensaje de bienvenida y esperará por más consultas del usuario. Éstas deben estar en minúsculas y tener un punto al final.

Una conversación de ejemplo es la siguiente:


 

Eliza da las respuestas en forma de listas de palabras, separadas por comas y entre corchetes. Se mantuvo este formato porque en una aplicación Eliza real, es muy probable que las respuesta halladas requieran un procesamiento posterior.
 

La aplicación ha sido probada en SWI-Prolog versión 7.2.1. No se ha probado en versiones anteriores. No funcionará en versiones de SWI-Prolog que no tengan implementadas las funciones length, nth0, atom y select.

Esta implementación de Eliza no tiene memoria, es decir, no recuerda las consultas ingresadas y sus respuestas, por lo que la coherencia de la conversación depende del usuario. Por ejemplo, para Eliza es válido ingresar primero la consulta “because you are creepy.” Y luego “i hate you.”.
 

Para ampliar las respuestas de Eliza a más estímulos basta crear más templates con los formatos ya mencionados.


En este programa, la aparente inteligencia de Eliza está en función a la amplitud de su base de conocimientos. Como la coincidencia de las consultas del usuario y los estímulos se realiza término a término, la base de conocimiento de Eliza debe ser bastante grande para producir una conversación coherente, y poder respetar género, número, tiempos verbales, etc. Un programa más completo consideraría toda una lista de palabras clave en lugar de sólo una.

El código fuente puede descargarse de aquí.

 

Referencias
 

  1. Revisiting the Eliza classic in Prolog: example conversation. http://prog.vub.ac.be/~cderoove/declarative_programming/decprog3_eliza.pdf

  2. Richard A. O'Keefe, “The Craft of Prolog”.

  3. Sterling & Shapiro, “The Art of Prolog”, 2nd Ed.

 

www.000webhost.com