Introducción
El término "Prolog" (o "PROLOG"), proviene de la expresión en francés "PROgrammation en LOGique", es un lenguaje de programación lógico e interpretado, bastante conocido en el medio de investigación en Inteligencia Artificial.
En nuestro Mac OS-X instalaremos SWI-Prolog a través de MacPorts. Para Mac OS-X el programa "port" de MacPorts es uno de los análogos al "apt-get" de Ubuntu. La orden de consola sería:
$ sudo port -v install swi-prolog
sin duda esto es lo mejor, aunque como mal menor siempre podemos llevar a cabo la instalación a través del paquete mpkg provisto en la página oficial de descargas de SWI-Prolog, donde también recomiendan y dan sugerencias para llevar a cabo la instalación vía MacPorts.
Si aún disfrutamos de Windows descargaremos el instalador según nuestras preferencias de la página oficial de descargas de SWI-Prolog.
Prolog y Emacs
Aún habiendo instalado el paquete "prolog-el" sigue siendo necesario, hoy por hoy, incluir en el fichero ".emacs" lo siguiente:
(autoload 'run-prolog "prolog" "Start a Prolog sub-process." t)
(autoload 'prolog-mode "prolog" "Major mode for editing Prolog programs." t)
(autoload 'mercury-mode "prolog" "Major mode for editing Mercury programs." t)
(setq prolog-system 'swi)
(setq auto-mode-alist (append '(("\\.pl$" . prolog-mode)
("\\.m$" . mercury-mode))
auto-mode-alist))
si queremos que nuestro emacs de colorines y eso ... a nuestros ficheros .pl. En cambio, si trabajamos en Mac OS-X la dificultad no existe, pues el maravilloso Aquamacs viene preparado ya. Para ver cómo instalar Emacs en Windows, pueden visitar éste nuestro post o bien éste otro; nunca es tarde para pasarse.
El hola mundo
Ha llegado el momento de escribir el "hola mundo", ese programa que nos da la seguridad de que hemos empezado con buen pie, que vamos por buen camino y que sólo es cuestión de persistir. He aquí el código:
?- ['hola.pl'].
con lo que tendremos el siguiente diálogo:
¡hola ... mundo!
true.
?-
Hay que observar que cuando se pide una validación, dicha petición acaba en "." y luego es cuando se pulsa "enter". Puede llamar la atención en nuestro particular código del hola.pl la línea ":- mensaje.". A grandes rasgos, su cometido es solicitar en tiempo de interpretación la validación automática del predicado "mensaje" que había sido argumentado aguas arriba de código. No le demos más importancia por ahora, pero guardemos en la memoria el alcance de esta técnica. Observar también que los ficheros que vamos a interpretar con SWI-Prolog deben tener la extensión ".pl".
Un programa arquetípico
Habitualmente hemos recurrido en "Mi primera clase ..." a mostrar ejecuciones aritméticas. Ahora dejamos esa vía para resaltar las muy especiales características de este otro lenguaje. Nuestra propuesta arquetípica es ahora un código, contenido en el fichero razona.pl que muestra cómo Prolog "razona", pues Prolog incluye un "demostrador":
p(a).
p(X) :- q(X), r(X).
p(X) :- u(X).
q(X) :- s(X).
r(a).
r(b).
s(a).
s(b).
s(c).
u(d).
Realmente los programas en Prolog son todos como éste, con mayor o menor sofistificación. La estructura del esquema ordena ---y aquí el orden importa--- una serie de reglas del tipo:
cabeza_de_la_regla :- cuerpo_de_la_regla.
Si queremos que el intérprete muestre su ayuda haremos:
?- help(help).
Un reto
Les dejamos el siguiente código que puede formar parte del fichero "sumatorio.pl":
sumatorio(1,1) :- !.
sumatorio(N,S) :- N1 is N-1,
sumatorio(N1,S1),
S is N+S1.
Les invitamos a que establezcan el siguiente diálogo:
?- ['sumatorio.pl'].
% sumatorio.pl compiled 0.00 sec, 1,200 bytes
true.
?- sumatorio(10,X).
X = 55.
y que según lo observado traten de entender el programa. Podrían editar seguidamente el fichero "sumatorio_dp.pl" con el mismo contenido del anterior pero quitando el carácter "!" del código:
sumatorio(1,1).
sumatorio(N,S) :- N1 is N-1,
sumatorio(N1,S1),
S is N+S1.
Ahora pueden repetir lo hecho con "sumatorio.pl". ¿Qué disfunción observan? ¿A qué se debe?
Y ... esto es todo por hoy.
El término "Prolog" (o "PROLOG"), proviene de la expresión en francés "PROgrammation en LOGique", es un lenguaje de programación lógico e interpretado, bastante conocido en el medio de investigación en Inteligencia Artificial.
Prolog es un lenguaje de programación para ordenadores que se basa en el lenguaje de la Lógica de Primer Orden y que se utiliza para resolver problemas en los que entran en juego objetos y relaciones entre ellos. Una de las ventajas de la programación lógica es que se especifica qué se tiene que hacer (programación declarativa) y no cómo se debe hacer (programación imperativa).
Instalación
En Ubuntu 11.10 y Ubuntu 12.04 haremos la instalación ejecutando la orden:
sudo apt-get install swi-prolog prolog-el ncurses-doc swi-prolog-doc
En nuestro Mac OS-X instalaremos SWI-Prolog a través de MacPorts. Para Mac OS-X el programa "port" de MacPorts es uno de los análogos al "apt-get" de Ubuntu. La orden de consola sería:
$ sudo port -v install swi-prolog
sin duda esto es lo mejor, aunque como mal menor siempre podemos llevar a cabo la instalación a través del paquete mpkg provisto en la página oficial de descargas de SWI-Prolog, donde también recomiendan y dan sugerencias para llevar a cabo la instalación vía MacPorts.
Si aún disfrutamos de Windows descargaremos el instalador según nuestras preferencias de la página oficial de descargas de SWI-Prolog.
Prolog y Emacs
Aún habiendo instalado el paquete "prolog-el" sigue siendo necesario, hoy por hoy, incluir en el fichero ".emacs" lo siguiente:
(autoload 'run-prolog "prolog" "Start a Prolog sub-process." t)
(autoload 'prolog-mode "prolog" "Major mode for editing Prolog programs." t)
(autoload 'mercury-mode "prolog" "Major mode for editing Mercury programs." t)
(setq prolog-system 'swi)
(setq auto-mode-alist (append '(("\\.pl$" . prolog-mode)
("\\.m$" . mercury-mode))
auto-mode-alist))
si queremos que nuestro emacs de colorines y eso ... a nuestros ficheros .pl. En cambio, si trabajamos en Mac OS-X la dificultad no existe, pues el maravilloso Aquamacs viene preparado ya. Para ver cómo instalar Emacs en Windows, pueden visitar éste nuestro post o bien éste otro; nunca es tarde para pasarse.
El hola mundo
Ha llegado el momento de escribir el "hola mundo", ese programa que nos da la seguridad de que hemos empezado con buen pie, que vamos por buen camino y que sólo es cuestión de persistir. He aquí el código:
mensaje :- nl,
write('Ejemplo: "El hola mundo de Prolog" cargado. '),
nl,
nl.
salude :- write('¡hola ... mundo!').
:- mensaje.
Tomaremos el texto anterior, editaremos un fichero que podría llamarse hola.pl, por ejemplo, y abriremos una terminal (Ctrl+t) en la que viajaremos hasta el lugar donde se halle el hola.pl (si no tendremos que cargar el fichero dando el camino, que también se puede). Seguidamente ejecutamos en la línea de la terminal la orden:
swipl
y seguidamente, tras el diálogo de bienvenida ejecutamos
con lo que tendremos el siguiente diálogo:
Ejemplo: "El hola mundo de Prolog" cargado.
% hola.pl compiled 0.00 sec, 1,632 bytes
true.
Ahora podemos pedir la validación del predicado salude:
?- salude.¡hola ... mundo!
true.
?-
Hay que observar que cuando se pide una validación, dicha petición acaba en "." y luego es cuando se pulsa "enter". Puede llamar la atención en nuestro particular código del hola.pl la línea ":- mensaje.". A grandes rasgos, su cometido es solicitar en tiempo de interpretación la validación automática del predicado "mensaje" que había sido argumentado aguas arriba de código. No le demos más importancia por ahora, pero guardemos en la memoria el alcance de esta técnica. Observar también que los ficheros que vamos a interpretar con SWI-Prolog deben tener la extensión ".pl".
Un programa arquetípico
Habitualmente hemos recurrido en "Mi primera clase ..." a mostrar ejecuciones aritméticas. Ahora dejamos esa vía para resaltar las muy especiales características de este otro lenguaje. Nuestra propuesta arquetípica es ahora un código, contenido en el fichero razona.pl que muestra cómo Prolog "razona", pues Prolog incluye un "demostrador":
p(a).
p(X) :- q(X), r(X).
p(X) :- u(X).
q(X) :- s(X).
r(a).
r(b).
s(a).
s(b).
s(c).
u(d).
Realmente los programas en Prolog son todos como éste, con mayor o menor sofistificación. La estructura del esquema ordena ---y aquí el orden importa--- una serie de reglas del tipo:
cabeza_de_la_regla :- cuerpo_de_la_regla.
en las que puede faltar la "cabeza_de_la_regla" o el " cuerpo_de_la_regla", como hemos visto. El conjunto de las reglas dadas constituye una base de datos que Prolog recorre de arriba hacia abajo. En nuestro caso, la línea p(a)sirve para informar al intérprete de que debe considerar que el predicado "p(X)" vale si "X=a". La línea
p(X) :- q(X), r(X).
sirve para informar al intérprete de que debe dar por válido a p(X) para aquellos valores atribuibles a X con los cuales resultase válido simultáneamente q(X) y r(X). Pero veamos a nuestro programa en acción con el siguiente diálogo:
?- ['razona.pl'].
% razona.pl compiled 0.00 sec, 2,776 bytes
true.
?- p(X).
X = a.
?- p(X).
X = a.
?- p(X).
X = a;
X = a;
X = b;
X = d.
Observe que en la primera línea sólo ha habido una respuesta porque hemos pulsado "." tras el primer "X = a"; ello indica al intérprete que debe parar de buscar valores para "X" que satisfagan a "p". Si pulsamos en lugar de "." el signo ";", el intérprete busca otras alternativas como valores de "X" que satisfagan a "p". En nuestro caso vuelve a encontrar que vale "a" por otra razón, encuentra como candidatos a "b" y también a "d". Entonces detiene la búsqueda al constatar que no hay más candidatos. Nuestro lector puede tratar de razonar el porqué de este comportamiento; será en segundo gran hito que alcance ... y puede que el último pues encontrará entonces que realmente lo que hace el intérprete es explorar un árbol unificando y resolviendo.
Algunas precisiones
Si queremos que el intérprete muestre su ayuda haremos:
?- help(help).
y si queremos salir del intérprete haremos:
?- halt.
Para cargar más de un programa en la interfax del intérprete podemos hacer lo siguiente
?- ['hola.pl','razona.pl'].
y habremos cargado "hola.pl" y "razona.pl". Habrá que tener cuidado de que no haya conflictos en los contenidos de ambos ficheros. Podemos ver lo que hemos cargado hasta el momento con:
?- listing.
Les dejamos el siguiente código que puede formar parte del fichero "sumatorio.pl":
sumatorio(1,1) :- !.
sumatorio(N,S) :- N1 is N-1,
sumatorio(N1,S1),
S is N+S1.
?- ['sumatorio.pl'].
% sumatorio.pl compiled 0.00 sec, 1,200 bytes
true.
?- sumatorio(10,X).
X = 55.
y que según lo observado traten de entender el programa. Podrían editar seguidamente el fichero "sumatorio_dp.pl" con el mismo contenido del anterior pero quitando el carácter "!" del código:
sumatorio(1,1).
sumatorio(N,S) :- N1 is N-1,
sumatorio(N1,S1),
S is N+S1.
Ahora pueden repetir lo hecho con "sumatorio.pl". ¿Qué disfunción observan? ¿A qué se debe?
Y ... esto es todo por hoy.



