Prolog: hola mundo, IA y la programación lógica

Prolog hola mundo

Un lenguaje muy de moda en Inteligencia Artificial es Prolog. Se trata de un lenguaje de programación lógica, de ahí su nombre, que viene de PROgramación LOGica. En programación lógica dejamos de pensar tanto en el cómo se hace, para pensar más en qué es lo que tenemos que hacer. Es decir, una vez que cambias el chip es muy intuitivo leerlo, y comprender lo que expresan sus sentencias.

Se utiliza mucho para crear sistemas expertos o sistemas basados en conocimiento. Se trata de un lenguaje puente, o más bien un lenguaje al que se suele recurrir desde otros lenguajes para resolver ciertos problemas. De esta forma, se programan partes de los programas en otros lenguajes más conocidos, mientras que se lanzan estos programas lógicos para resolver cierto tipo de tareas.

Por ejemplo, con Prolog se pueden construir sistemas para:

  • Diagnóstico de enfermedades.
  • Problemas técnicos de vehículos.
  • Toma de decisiones sobre el mejor CMS para tu proyecto.
  • Algoritmos de procesamiento de filtros de correo electrónico.
  • Procesamiento del lenguaje natural.
  • Crear Sudokus.
  • Detección automática de terroristas.
  • Y un largo, muy largo etcétera.

Es decir, se utiliza para hacer consultas del tipo VERDADERO o FALSO. Para resolver problemas lógicos, recorrer árboles, construir bases de conocimiento.. y para otras tareas muy relacionadas actualmente con el campo de la Inteligencia Artificial.

Instalando

Sin teorizar mucho, voy a tratar de ir al grano, podemos instalar un intérprete de Prolog, que a la vez también puede compilar estos programas a un ejecutable:

Para arrancar ponemos: swipl en línea de comandos en Linux o Mac, nos saldrá la consola de comandos. Desde Windows tendremos un icono para lanzarlo.

Prolog lanzando intérprete

Creando un primer programa

El ejemplo clásico de todo lenguaje, el hola mundo:

?- write('¡Hola Mundo!').

Todas las sentencias en Prolog terminan con un punto. Si arrancamos el entorno con swipl desde línea de comandos, podemos escribir lo anterior y Prolog escribirá por pantalla lo siguiente:

¡Hola Mundo!
true.

Hemos hecho la primera consulta, que simplemente escribe ¡Hola Mundo! y devuelve un true porque todo ha ido bien.

Cómo se trabaja

El paso siguiente es crear un fichero .pl en el que vamos a ir grabando nuestra base de conocimiento, un holaMundo.pl por ejemplo. Vamos a guardar el hola mundo anterior en el fichero así:

escribeHolaMundo :- write('¡Hola Mundo!').

Lo guardamos en el fichero, de forma que ahora un predicado que se llama escribeHolaMundo, que es una regla.  Ahora guardamos el fichero, lo cargamos desde Prolog poniendo:

?- [holaMundo].

También podemos cargar este fichero poniendo:

?- ['holaMundo.pl'].

O:

?- consult('holaMundo.pl').

Ahora podemos ‘ejecutar’ esto poniendo:

?- escribeHolaMundo.
¡Hola Mundo!
true.

Esto no tiene mucha utilidad, pero sigue, sigue.. que ahora vemos un poco más y verás como se pone interesante.. 😉

Resumiendo, debemos ir guardando nuestros programas de Prolog en ficheros .pl. También se pueden generar estos ficheros o inyectar estos ficheros .pl desde una base de datos tradicional SQL. O también se pueden generar estos conocimientos a partir de otras fuentes de entrada. El tema es que Prolog funciona así, debemos ir trabajando en ficheros .pl mientras que vamos construyendo nuestra base de conocimiento o sistema experto.

Hechos, predicados, átomos, variables y reglas

Vamos ahora con un ejemplo muy sencillo, que presenta gran parte de las piezas que tenemos para programar en Prolog. Al grano, con el siguiente ejemplo:

es_padre_de(paco, pepe).
es_hijo_de(X, Y) :- es_padre_de(Y, X).

Aquí tenemos dos líneas de programa. En la primera tenemos un hecho, que declara que Paco es padre de Pepe. es_padre_de es el predicado, Paco es un átomo, Pepe es otro átomo. La semántica de todo esto la da el programador haciendo los predicados, así que usamos un nombre de predicado que tenga significado claro (es_padre_de).

En la segunda línea tenemos una regla, que define un predicado nuevo llamado es_hijo_de. Aquí tenemos que simplemente si Paco es padre de Pepe, entonces Pepe es hijo de Paco. ¡OJO! Fíjate que los átomos siempre van en minúscula la primera letra por lo menos, mientras que las variables empiezan en mayúscula.

Una cosa importante a reflexionar es el uso de :- con lo que construimos las reglas. Estas reglas se llaman también Cláusulas de Horn, y son la principal herramienta de programación lógica. Fíjate que el predicado es_hijo_de se deduce a partir del conocimiento que tengamos con el predicado es_padre_de. Teóricamente, según las lecciones básicas de matemáticas del colegio, pensaríamos de esta forma leyendo de izquieda a derecha, pero Prolog evalúa si es cierto el predicado izquierdo comprobando la parte derecha. La parte izquierda es la conclusión o cabeza, y la parte derecha se llama cuerpo o condiciones de la regla:

X es hijo de Y <- Y es padre de X (Si Y es padre de X, entonces, X es hijo de Y).

Esto son los fundamentos de la programación lógica, su potencia, y a su vez es lo que mejor hace. Esto, aunque parezca simple, cuanta más información tengamos, más complicado se vuelve de manejar si no utilizamos programación lógica. Más abajo dejo un ejemplo más complejo para hacernos una idea de lo complicado que podría ser mantener un programa en C, C++, Java, PHP.. para hacer lo mismo. Sin embargo, con Prolog, es como un juego de niños.

Consultando la base de conocimiento

Lo siguiente es guardar el ejemplo anterior en el fichero holaMundo.pl, luego lo cargamos en Prolog poniendo [holaMundo]. y vamos a hacer unas consultas. Vamos a ver quién es el padre de Pepe así:

?- es_padre_de(X, pepe).
X = paco.

Ahora a ver de quién es padre Paco así:

?- es_padre_de(paco, X).
X = pepe.

Ahora vamos a ver quién es hijo de Paco así:

?- es_hijo_de(X, paco).
X = pepe.

Otra consulta podría ser, ¿Paco es hijo de Pepe?

?- es_hijo_de(paco, pepe).
false.

Que nos devuelve un false, porque Paco no es hijo de Pepe, sino que Pepe es hijo de Paco. Bueno, visto esto, la idea principal es que con estos pocos elementos podemos construir ejemplos más y más completos. Esto es lo que se llama representar mundos virtuales. Vamos a complicarlo un poco más.

Un poco más complejo

Ahora bien, siguiendo el ejemplo de representar el mundo virtual de una familia, podríamos llegar a esto:

estan_casados(paco, maria).
estan_casados(X, Y) :- estan_casados(Y, X), X \= Y, !.

es_madre_de(maria, pepe).
es_madre_de(maria, susana).

es_padre_de(paco, pepe).
es_padre_de(paco, susana).

varon(paco).
varon(pepe).

mujer(maria).
mujer(susana).

es_hijo_de(X, Y) :-
    varon(X),
    (es_padre_de(Y, X) ; es_madre_de(Y, X)).

es_hija_de(X, Y) :-
    mujer(X),
    (es_padre_de(Y, X) ; es_madre_de(Y, X)).

es_hermano_de(X, Y) :-
    varon(X), es_padre_de(Z, X), es_padre_de(Z, Y), X \= Y,
    write(X), write(' es hermano de '), write(Y), write(' por parte de padre'), nl.
es_hermano_de(X, Y) :-
    varon(X), es_madre_de(Z, X), es_madre_de(Z, Y), X \= Y,
    write(X), write(' es hermano de '), write(Y), write(' por parte de madre'), nl.

es_hermana_de(X, Y) :-
    mujer(X), es_padre_de(Z, X), es_padre_de(Z, Y), X \= Y,
    write(X), write(' es hermana de '), write(Y), write(' por parte de padre'), nl.
es_hermana_de(X, Y) :-
    mujer(X), es_madre_de(Z, X), es_madre_de(Z, Y), X \= Y,
    write(X), write(' es hermana de '), write(Y), write(' por parte de madre'), nl.

escribeHolaMundo :- write('¡Hola Mundo!').

Esto ya se va poniendo más divertido 😀 Ahora tenemos una familia, resulta que Paco y Maria están casados, son los padres de Pepe y Susana. Pepe y Susana son hermanos, Pepe y Susana son hijos de Paco y María, el ser hermano o hermana se deduce de los conocimientos anteriores, etc, etc..

Terminando

Así poco a poco tenemos todas las piezas del Lego, o Tente, para construir lo que necesitemos. Por ejemplo, imaginemos que necesitamos tomar decisiones como un experto en el desarrollo de aplicaciones web. Queremos montar un sistema experto para que haga esto por nosotros. Entonces podemos tener hechos como ‘el proyecto es un eCommerce’, ‘no es un eCommerce’, ‘necesita mucha carga de productos’, ‘va a tener más de 500 000 productos’, ‘es una red social’, etcétera.. y en función a esto el sistema cogerá las entradas y dara la respuesta.

Otro caso puede ser un sistema experto para saber si el paciente tiene cierta enfermedad en función a los síntomas. Podemos consultar hechos como ‘el paciente tiene fiebre’, ‘presenta vómitos’, ‘mareos’, ‘dificultad para mantener el equilibrio’, etc.. Además, todas estas entradas se pueden tratar contrastando con información obtenida de experiencias anteriores. Con esto las respuestas del sistema experto pueden ser muy muy fiables. Sobretodo si se ha construido con mucha información. También es imprescindible documentarse sobre el problema a resolver. Y es muy importante poder contar con expertos en la materia para construir estos sistemas.

Si has llegado hasta aquí espero no haberte aburrido, y haber aclarado un poco para qué es Prolog. No dudes en dejar un comentario aquí abajo 😉

¡Un saludo!

Compartir..

Dejar un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

6 + 9 =