INTRODUCCION¶ ALLENGUAJEPROLOG -...

26
INTRODUCCI ´ ON AL LENGUAJE PROLOG ´ Indice 1. Introducci´ on 2 2. Caracter´ ısticas Generales 2 2.1. Evoluci´ on hist´ orica ................................... 2 2.2. Esquema general de trabajo en Prolog ........................ 3 2.3. Implementaciones de Prolog .............................. 4 2.3.1. SICStus Prolog ................................. 5 2.3.2. SWI-Prolog ................................... 6 3. Prolog y el paradigma de la Programaci´ on L´ ogica 6 3.1. Sintaxis ......................................... 6 3.1.1. erminos .................................... 6 3.1.2. Programas ................................... 8 3.1.3. Consultas para la activaci´ on de programas .................. 10 3.1.4. Resumen .................................... 10 3.2. Sem´ antica ........................................ 11 4. Predicados Predefinidos 15 4.1. Aritm´ etica ........................................ 15 4.1.1. Operadores aritm´ eticos ............................ 15 4.1.2. Predicados aritm´ eticos ............................. 16 4.1.3. Programas aritm´ eticos en Prolog ....................... 17 4.2. Entrada/Salida ..................................... 18 4.3. Control: el corte .................................... 20 4.3.1. Definici´ on y propiedades ............................ 21 4.3.2. Usos del corte. Ejemplos ............................ 23

Transcript of INTRODUCCION¶ ALLENGUAJEPROLOG -...

Page 1: INTRODUCCION¶ ALLENGUAJEPROLOG - …arantxa.ii.uam.es/~dcamacho/logica/recursos/3848.0.prolog.pdf · Prolog admite tambi¶en una notaci¶on m¶as sencilla que consiste en enumerar

INTRODUCCION AL LENGUAJE PROLOG

Indice

1. Introduccion 2

2. Caracterısticas Generales 2

2.1. Evolucion historica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

2.2. Esquema general de trabajo en Prolog . . . . . . . . . . . . . . . . . . . . . . . . 3

2.3. Implementaciones de Prolog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

2.3.1. SICStus Prolog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

2.3.2. SWI-Prolog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

3. Prolog y el paradigma de la Programacion Logica 6

3.1. Sintaxis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

3.1.1. Terminos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

3.1.2. Programas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

3.1.3. Consultas para la activacion de programas . . . . . . . . . . . . . . . . . . 10

3.1.4. Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

3.2. Semantica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

4. Predicados Predefinidos 15

4.1. Aritmetica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

4.1.1. Operadores aritmeticos . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

4.1.2. Predicados aritmeticos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

4.1.3. Programas aritmeticos en Prolog . . . . . . . . . . . . . . . . . . . . . . . 17

4.2. Entrada/Salida . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

4.3. Control: el corte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

4.3.1. Definicion y propiedades . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

4.3.2. Usos del corte. Ejemplos . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

Page 2: INTRODUCCION¶ ALLENGUAJEPROLOG - …arantxa.ii.uam.es/~dcamacho/logica/recursos/3848.0.prolog.pdf · Prolog admite tambi¶en una notaci¶on m¶as sencilla que consiste en enumerar

1. Introduccion

En este documento se realiza una breve introduccion al lenguaje de programacion Prolog, conel objetivo fundamental de mostrar como se da el paso desde el concepto de programacionlogica “pura” estudiado en el tema anterior a un lenguaje de programacion “real”. En efecto,el lenguaje Prolog se puede ver como una extension de la programacion logica pura, en elsentido de que, ademas de permitir programar de acuerdo con el paradigma de la programacionlogica, incorpora una serie de elementos adicionales cuyo objetivo es ofrecer una herramientade programacion que sea util en la practica.

Despues de una descripcion de las caracterısticas generales del lenguaje (evolucion historica,esquema general de trabajo e implementaciones existentes), el apartado 3 estudia el funciona-miento de Prolog desde el punto de vista de la programacion logica pura, basado en la Progra-macion Logica Definida estudiada en el tema anterior. Su extension, que se realiza mediante laintroduccion de los denominados predicados predefinidos, se resume en el apartado 4.

No se abordan, por lo tanto, mas que algunos de los aspectos mas relevantes del lenguaje.Para un estudio mas en profundidad de Prolog se recomienda consultar los siguientes libros (lostres primeros son libros de caracter introductorio, mientras que el ultimo trata aspectos masavanzados).

L. Sterling and E. Shapiro. The Art of Prolog. The MIT Press, Cambridge, Mass., secondedition, 1994.

W.F. Clocksin and C.S. Mellish. Programming in Prolog. Springer-Verlag, Berlin, fourthedition, 1994.

I. Bratko. Prolog Programming for Artificial Intelligence. Addison-Wesley, Reading, Mas-sachusetts, third edition, 2001.

R. O’Keefe. The Craft of Prolog. The MIT Press, Cambridge, MA, 1990.

2. Caracterısticas Generales

2.1. Evolucion historica

Prolog (del frances, PROgrammation en LOGique) fue el primer lenguaje de programacion ba-sado en el paradigma de la programacion logica. Se implemento por primera vez a principios delos anos setenta en la Universidad de Marsella (Francia), por un equipo dirigido por A. Colme-raeur, utilizando resultados teoricos aportados por R. Kowalski (Universidad de Edimburgo).Aunque con ciertas dificultades iniciales, debido principalmente a la novedad del paradigmay a la escasa eficiencia de las implementaciones disponibles, el lenguaje se fue expandiendorapidamente, sobre todo en Europa y en Japon (en este ultimo paıs la programacion logicase incluyo como parte central del proyecto de ordenadores de quinta generacion de los anosochenta). En 1995 el lenguaje se normaliza con el correspondiente estandar ISO. En la actua-lidad Prolog se ha convertido en una herramienta de desarrollo de software practica y de granaceptacion para la que se dispone de multiples compiladores, tanto comerciales como de libredistribucion.

2

Page 3: INTRODUCCION¶ ALLENGUAJEPROLOG - …arantxa.ii.uam.es/~dcamacho/logica/recursos/3848.0.prolog.pdf · Prolog admite tambi¶en una notaci¶on m¶as sencilla que consiste en enumerar

2.2. Esquema general de trabajo en Prolog

El esquema general de trabajo en Prolog es el siguiente:

1. Escribir un programa logico en Prolog.

Como se ha visto en el tema anterior, un programa logico es un conjunto finito de formulaslogicas, que reflejan el conocimiento del que se dispone acerca del problema a resolver.Por lo tanto, un programa en Prolog estara formado por una serie de formulas logicasque, evidentemente, tendran que adaptarse a la sintaxis especıfica del lenguaje (esta sedetalla mas adelante). Podran asimismo incluirse comentarios:

% El sımbolo % precede los comentarios en una unica lınea

/* Los comentarios en varias lıneas empiezan con /*

y terminan con */

*/

Los programas se pueden escribir mediante cualquier editor de textos, aunque, como severa despues, existen editores especiales que facilitan la escritura de programas en Prolog.Una vez escrito un programa, este se debera guardar en un fichero (la extension habitualpara los programas en Prolog es “.pl”).

2. Iniciar el sistema Prolog y cargar un programa.

Cuando se inicia un sistema Prolog, este muestra por pantalla una lınea con el siguienteformato:

?-

que indica que el sistema esta esperando la introduccion por parte del usuario de algunaconsulta. Para poder trabajar con un programa escrito previamente, es necesario cargarel fichero correspondiente en el sistema Prolog. Lo anterior se puede hacer de dos formasdistintas:

- interpretando el programa por medio del interprete del lenguaje. Esta solucion es lamas habitual cuando se esta probando un programa, y la accion se conoce como“consultar” un fichero. Para realizarla, basta con utilizar el predicado del sistemaconsult, con el nombre del fichero que se quiere cargar:

?- consult(’c:/Prolog/prueba.pl’).

Lo anterior es equivalente a escribir simplemente el nombre del fichero entre corche-tes:

?- [’c:/Prolog/prueba.pl’].

- compilando el programa por medio del compilador del lenguaje. El codigo compiladoes mas rapido que el codigo interpretado, aunque ofrece menos facilidades en lo quea depuracion se refiere. La compilacion de un programa se realiza por medio delpredicado del sistema compile:

?- compile(’c:/Prolog/prueba.pl’).

3

Page 4: INTRODUCCION¶ ALLENGUAJEPROLOG - …arantxa.ii.uam.es/~dcamacho/logica/recursos/3848.0.prolog.pdf · Prolog admite tambi¶en una notaci¶on m¶as sencilla que consiste en enumerar

En cualquiera de los dos casos, la respuesta del sistema puede ser de dos tipos:

- si se ha detectado algun error sintactico en el programa, el sistema Prolog avisa de ellomediante un mensaje. En estos casos habra que volver a editar el programa paracorregir los errores que contiene y volver a cargarlo.

- en caso contrario, el sistema responde con la palabra yes, que indica que el programase ha cargado correctamente y el sistema esta listo para recibir consultas del usuario.

Nota: la mayorıa de los sistemas Prolog ofrecen un entorno de programacion interactivodotado de menus mediante los cuales se ofrecen las acciones mas habituales, entre ellas lacarga de ficheros tanto para ser interpretados como para ser compilados (normalmente,“File/Consult...” y “File/Compile...”).

3. Activar un programa desde el sistema Prolog.

Una vez que se ha cargado correctamente un programa, el sistema esta preparado pararecibir las consultas del usuario relativas al problema que se pretende resolver. Para ellobastara con escribir dichas consultas, siguiendo la sintaxis especıfica del lenguaje, enla lınea de consultas del sistema. El formato de estas consultas ası como las posiblesreacciones del sistema ante ellas se detallan mas adelante.

Nota: Los sistemas Prolog suelen incorporar un mecanismo de depuracion que permiteseguir paso a paso la ejecucion de las consultas, establecer puntos de corte en la ejecucion,etc. Su funcionamiento basico es el siguiente:

para entrar en modo de depuracion debe escribirse el predicado del sistema trace

en la lınea de consultas:

?- trace.

A partir de ese momento, las consultas que se realicen se ejecutaran en modo dedepuracion, mostrando una despues de otra todas las llamadas realizadas interna-mente por el sistema Prolog. Para avanzar en la depuracion, basta con pulsar la teclaRETURN. Tambien puede pulsarse la tecla h para obtener ayuda sobre las distin-tas opciones disponibles. En particular, la tecla n permite abandonar el proceso dedepuracion.

para desactivar el modo de depuracion se utiliza el predicado notrace:

?- notrace.

Para una informacion mas detallada sobre el mecanismo de depuracion de Prolog serecomienda leer el capıtulo 8 del libro de Clocksin y Mellish citado en la introduccion oconsultar el manual de referencia del sistema Prolog que se este utilizando.

4. Salir del sistema Prolog.

Para salir del sistema Prolog basta con escribir el predicado del sistema halt en la lıneade comandos:

?- halt.

2.3. Implementaciones de Prolog

Como se ha comentado previamente, existen muchas implementaciones del lenguaje Prolog,tanto comerciales como de libre distribucion. La mayorıa de ellas se adaptan al estandar ISO,

4

Page 5: INTRODUCCION¶ ALLENGUAJEPROLOG - …arantxa.ii.uam.es/~dcamacho/logica/recursos/3848.0.prolog.pdf · Prolog admite tambi¶en una notaci¶on m¶as sencilla que consiste en enumerar

por lo que los programas Prolog que se generen de acuerdo con dicho estandar podran ejecutarseen cualquiera de estos sistemas.

En esta asignatura (y en este documento) se va a utilizar la implementacion comercial de-nominada “SICStus Prolog”, para la cual la URJC dispone de una licencia de Campus. Acontinuacion se describe brevemente tanto este sistema como otro sistema Prolog, de dominiopublico, denominado SWI-Prolog.

2.3.1. SICStus Prolog

SICStus Prolog es un compilador de Prolog comercial, desarrollado por el Instituto Sueco deCiencias de la Computacion (SICS), compatible con el estandar ISO-Prolog, con facilidades dedepuracion, interfaz con el lenguaje C, estructuracion modular, bibliotecas con las estructurasde datos mas habituales, etc.

Aunque SICStus Prolog se puede usar directamente (activando el ejecutable correspondiente ysiguiendo el esquema general de trabajo en Prolog descrito mas arriba), lo mas recomendablees usarlo a traves del editor de textos GNU Emacs (Emacs es un potente editor de textos,programable y de libre distribucion, que puede obtenerse en la URL http://www.emacs.org).Para ello, SICStus Prolog incluye en su distribucion un fichero de interfaz con Emacs (.emacs),que aporta un modo de edicion especial para programas en Prolog, ası como acceso directodesde el editor Emacs a la carga de programas, al sistema SICStus Prolog y a su manual deayuda.

Ası, una vez instalado dicho interfaz, el modo de trabajar en SICStus Prolog a traves del editorEmacs sera el siguiente:

1. Iniciar Emacs.

El editor Emacs se inicia mediante el ejecutable “runemacs.exe”, ubicado en el subdirec-torio “bin” del directorio en el que se haya instalado el editor.

2. Crear/editar un programa Prolog.

Tanto para crear un nuevo programa como para modificar un programa ya existentese usara la opcion del menu de Emacs “File/Open File...”, o, alternativamente, lacombinacion de teclas CONTROL-X CONTROL-F. Si el nombre facilitado se correspondecon un fichero existente, el editor mostrara su contenido en pantalla; en caso contrario,mostrara una ventana vacıa en la que se podra escribir el nuevo programa. Las entradas delos menus “Edit” y “File” (o las combinaciones de teclas asociadas) ofrecen las opcioneshabituales para editar y guardar (CONTROL-X CONTROL-S) el contenido del fichero.

3. Cargar un programa e iniciar el sistema Prolog.

Si el fichero abierto en el punto anterior tiene extension “.pl”, el interfaz de SICStusProlog con Emacs anadira automaticamente a la barra de menus de Emacs una nuevaentrada bajo el nombre Prolog que incluye, entre otras, las opciones pertinentes paraconsultar (CONTROL-C CONTROL-F) o compilar el programa correspondiente. Al ele-gir cualquiera de ellas, no solo se cargara el programa en el sistema sino que ademasse abrira una nueva ventana con el sistema SICStus Prolog, que permitira realizar lasconsultas pertinentes.

5

Page 6: INTRODUCCION¶ ALLENGUAJEPROLOG - …arantxa.ii.uam.es/~dcamacho/logica/recursos/3848.0.prolog.pdf · Prolog admite tambi¶en una notaci¶on m¶as sencilla que consiste en enumerar

Tambien es posible acceder desde Emacs al sistema de ayuda de SICStus Prolog:

- el menu “Help/Manuals/Browse Manuals with Info” permite acceder a los manuales deusuario de SICStus.

- la opcion “Help on Predicate” (CONTROL-C ?) del menu contextual “Prolog” antescitado ofrece ayuda sobre los predicados predefinidos de Prolog.

2.3.2. SWI-Prolog

SWI-Prolog es un compilador de Prolog de dominio publico disenado e implementado en la Uni-versidad de Amsterdam, compatible con el estandar ISO y disponible para distintas platafor-mas. Se puede obtener en la direccion http://www.swi-prolog.org. La version para Windowsconsta de un unico fichero ejecutable que instala automaticamente el sistema. Este se utiliza deacuerdo con el esquema general de trabajo en Prolog descrito mas arriba.

3. Prolog y el paradigma de la Programacion Logica

Como se ha visto previamente, existen muchos modelos distintos de programacion logica, quese distinguen dependiendo del tipo de Logica utilizada para representar el conocimiento y delmecanismo de demostracion automatica elegido. El lenguaje Prolog se basa en la ProgramacionLogica Definida estudiada en el tema anterior, pero con ciertas peculiaridades, tanto sintacticascomo semanticas, que se discuten a continuacion.

3.1. Sintaxis

3.1.1. Terminos

Al igual que en Logica de Primer Orden, los terminos en Prolog se clasifican en tres categorıas:constantes, variables y terminos compuestos.

Constantes

Prolog distingue dos tipos de constantes:

Numeros. Este tipo de constantes se utilizan para representar tanto numeros enteros comonumeros reales y poder realizar con ellos operaciones aritmeticas.

- La representacion mas corriente de los numeros enteros es la notacion decimal habitual(por ejemplo 0, 1, -320, 539, etc) aunque tambien se pueden representar en otrasbases no decimales.

- Los numeros reales se pueden representar tanto en notacion decimal (por ejemplo1.0, -3.14) como en notacion exponencial (por ejemplo 4.5E6, -0.12e+3, 12.0e-2). Enambos casos debera haber siempre por lo menos un dıgito a cada lado del punto.

6

Page 7: INTRODUCCION¶ ALLENGUAJEPROLOG - …arantxa.ii.uam.es/~dcamacho/logica/recursos/3848.0.prolog.pdf · Prolog admite tambi¶en una notaci¶on m¶as sencilla que consiste en enumerar

Atomos. Los atomos (no confundir con las formulas atomicas de la LPO) se utilizan paradar nombre a objetos especıficos, es decir, representan individuos concretos. Existen tresclases principales de atomos:

- cadenas formadas por letras, dıgitos y el sımbolo de subrayado, que deben empezarnecesariamente por una letra minuscula.

Cadenas validas: f, pepe1, libro33a, libro_blanco.

Cadenas no validas: 1libro, libro-blanco, _hola, Libro.

- cualquier cadena de caracteres encerrada entre comillas simples.

Ejemplos: ’SICStus Prolog’, ’Libro-blanco’, ’28003 Madrid’.

Estos atomos son utiles cuando se necesita trabajar con constantes que empiecen poruna letra mayuscula o por un dıgito.

- existe ademas otro tipo de atomos, compuestos por combinaciones especiales de signos,de uso menos comun.

Variables

Las variables en Prolog se representan mediante cadenas formadas por letras, dıgitos y el sımbolode subrayado, pero deben necesariamente empezar por una letra mayuscula o por un sımbolo desubrayado.

Ejemplos: X, Resultado_1, Entrada, _total3, _3bis, _

Las variables que empiezan con un sımbolo de subrayado, _, se denominan variables anonimas,y se usan cuando se necesita trabajar con variables cuyos posibles valores no interesan. Suutilidad se describira mas adelante al analizar la construccion de programas y consultas.

Terminos Compuestos

Los terminos compuestos, o estructuras, se construyen mediante un sımbolo de funcion, deno-minado functor, que se denota mediante un atomo, seguido, entre parentesis, por una serie determinos separados por comas, denominados argumentos.

Ejemplos: fecha(1,mayo,2001), punto(X,Y), recta(punto(1,2), punto(3,5))

Nota: al escribir un termino compuesto, no puede haber ningun espacio entre el functor yel parentesis abierto previo a los argumentos. Por ejemplo, “punto (X,Y)” no es un terminocompuesto correcto y producira un error de compilacion.

Prolog tambien permite escribir ciertos terminos compuestos en forma de operadores, general-mente en notacion infija en el caso de functores de aridad 2 y en notacion prefija o postfija enel caso de functores de aridad 1. Este es el caso de los operadores aritmeticos predefinidos deProlog, que se mencionaran mas adelante, y que permiten escribir terminos compuestos de laforma X+Y o -X en lugar de +(X,Y) o -(X). El programador tambien puede definir sus propiosoperadores.

Uno de los terminos compuestos mas importantes y utiles que ofrece Prolog son las listas,secuencias ordenadas de cero o mas elementos, donde los elementos pueden ser cualquier tipode termino. Prolog representa las listas teniendo en cuenta su estructura recursiva:

- la lista vacıa se representa mediante el atomo [].

7

Page 8: INTRODUCCION¶ ALLENGUAJEPROLOG - …arantxa.ii.uam.es/~dcamacho/logica/recursos/3848.0.prolog.pdf · Prolog admite tambi¶en una notaci¶on m¶as sencilla que consiste en enumerar

- toda lista no vacıa tiene una cabeza (que sera cualquier termino) y un resto (que sera unalista), y se representa mediante un termino compuesto de aridad 2, cuyo functor es unpunto · y cuyos argumentos son, respectivamente, la cabeza y el resto de la lista.

Ejemplos: la lista compuesta por un unico elemento, la constante a, se representa como “·(a, [])”.La lista compuesta por los elementos a, b y c se corresponde con la estructura “·(a, ·(b, ·(c, [])))”.

Dado que la notacion anterior puede resultar incomoda a la hora de escribir listas complicadas,Prolog admite tambien una notacion mas sencilla que consiste en enumerar entre corchetestodos los elementos de la lista, separados por comas. Con esta notacion, las dos listas delejemplo anterior se representarıan, respectivamente, como [a] y [a, b, c]. Prolog tambien disponede otra notacion para las listas, que consiste en representar la lista con cabeza X y resto Y

mediante el termino [X|Y ]. Esta ultima notacion es fundamental para poder separar la cabezadel resto de una lista. Su utilidad en la practica se vera en las clases de problemas.

3.1.2. Programas

Los programas Prolog son programas logicos definidos, y estan por lo tanto compuestos poruna serie de clausulas de Horn positivas, esto es, hechos y reglas. Hay que tener en cuenta sinembargo las siguientes diferencias en cuanto a la notacion empleada en la Programacion LogicaDefinida:

Los sımbolos de predicado se denotan mediante atomos, por lo que no pueden empezar,como ocurre en Programacion Logica, mediante una letra mayuscula. Observese por lotanto que el lenguaje Prolog no distingue entre sımbolos de predicado, sımbolos de fun-cion y constantes, puesto que todos ellos se representan mediante atomos (el compiladordistingue unos de otros dependiendo del contexto en el que aparecen). Para referirse a unpredicado nombre_predicado se suele emplear la notacion nombre_predicado/n, donden indica el numero de argumentos del predicado.

Los hechos deben terminar con un punto y omitir el sımbolo “←” utilizado en Programa-cion Logica. Ası, el hecho “← A” se escribe en Prolog de la forma “A.”.

Las reglas deben tambien terminar con un punto y sustituir el sımbolo “←” de la Progra-macion Logica por el sımbolo “:-”. Ası, la regla “A ← A1, . . . , An” se escribe en Prologde la forma “A :- A1, . . . , An.”.

Nota: Al trabajar en Prolog se suele aplicar un convenio estandar para describir el uso delos predicados (tanto predefinidos como definidos por el programador): en los programas, lasclausulas de cada predicado deberan ir precedidas de un comentario incluyendo una lınea quedescriba su uso, ası como una descripcion en lenguaje natural de su cometido. El convenio paradescribir el uso de un predicado es el siguiente:

nombre_predicado(#NomVar_1, ...., #NomVar_n)

donde NomVar_1, ..., NomVar_n son nombres de variables y el sımbolo #, que sirve para indicarcomo debe usarse el argumento correspondiente al realizarse una consulta, puede tomar uno delos tres siguientes valores:

8

Page 9: INTRODUCCION¶ ALLENGUAJEPROLOG - …arantxa.ii.uam.es/~dcamacho/logica/recursos/3848.0.prolog.pdf · Prolog admite tambi¶en una notaci¶on m¶as sencilla que consiste en enumerar

+ para indicar que el argumento correspondiente debe estar, en la consulta, instanciado con untermino no variable (este tipo de argumentos se corresponden por lo tanto con parametrosde entrada).

- para indicar que el argumento correspondiente no debe estar instanciado en la consulta, esdecir, debe ser una variable (este tipo de argumentos se corresponden por lo tanto conparametros de salida).

? para indicar que el argumento puede estar tanto instanciado como no instanciado (es decir,se trata de parametros que se pueden usar tanto para entrada como para salida).

Por ejemplo, el predicado predefinido sort/2, que sirve para ordenar listas de elementos, se des-cribe como sort(+Lista1, ?Lista2), indicando ası que para utilizarlo el primer argumento de-be estar instanciado (debe ser una lista concreta). Por lo tanto, el predicado sort/2 se podra uti-lizar en consultas de la forma “ ?- sort([c,v,a], X).” o “ ?- sort([c,v,a], [a,c,v]).”,pero si se intenta hacer una consulta en la que el primer argumento no este instanciado, comopor ejemplo “?- sort(X, [c,v,a]).”, se producira un error.

Ejemplo: Los programas logicos para el calculo del factorial y la suma de numeros naturalesestudiados en el tema anterior eran programas logicos definidos, por lo que se pueden convertirfacilmente en programas Prolog con solo adaptar su sintaxis de acuerdo con lo establecido masarriba (ficheros “factorial.pl” y “suma.pl”):

PROGRAMA LOGICO DEFINIDO PROGRAMA PROLOG

Factorial(0,s(0)) ←Factorial(s(x),s(x)*y) ← Factorial(x,y)

% factorial(?X,?Y)

% cierto si Y es el factorial de X

factorial(0,s(0)).

factorial(s(X),s(X)*Y) :- factorial(X,Y).

Suma(x,0,x) ←Suma(x,s(y),s(z)) ← Suma(x,y,z).

% suma(?X,?Y,?Z)

% cierto si Z es la suma de X e Y

suma(X,0,X).

suma(X,s(Y),s(Z)) :- suma(X,Y,Z).

Observese que en los ejemplos anteriores las variables X, Y y Z aparecen a ambos lados de lasrespectivas reglas. Existen sin embargo casos en los que una variable aparece solo a un lado deuna regla y sus posibles valores no tienen importancia. En estos casos no es necesario pensarun nombre de variable sino que basta con usar la variable anonima “_”.

Ejemplo: Supongase que, dado el predicado factorial, se necesita definir a partir de el unpredicado es_factorial(X) que es cierto si X es el factorial de algun numero natural. Unaforma de definir este predicado serıa estableciendo que X es un factorial siempre y cuandoexista algun Y tal que X sea el factorial de ese Y , es decir:

% es_factorial(?X): cierto si X es el factorial de algun numero

es_factorial(X) :- factorial(Y,X).

Sin embargo, en este caso el posible valor de la variable Y es indiferente, puesto que lo unicoque se quiere saber es si X es el factorial de algun numero, sin importar quien sea este. Ası, ladefinicion anterior se podrıa sustituir por:

es_factorial(X) :- factorial(_,X).

9

Page 10: INTRODUCCION¶ ALLENGUAJEPROLOG - …arantxa.ii.uam.es/~dcamacho/logica/recursos/3848.0.prolog.pdf · Prolog admite tambi¶en una notaci¶on m¶as sencilla que consiste en enumerar

3.1.3. Consultas para la activacion de programas

Al estar Prolog basado en la Programacion Logica Definida, las unicas consultas que se puedenrealizar para activar un programa Prolog se corresponden con clausulas de Horn negativas,esto es, clausulas objetivo (clausulas meta). Se recuerda que estas clausulas, que son de laforma “← A1, . . . , An”, se corresponden con la negacion de formulas ∃x1 . . .∃xp(A1 ∧ . . .∧An),p ≥ 0, n ≥ 1, donde A1, . . . , An son predicados. En Prolog, las consultas deben terminar siemprecon un punto, y el sımbolo “←” de la Programacion Logica debe sustituirse por el sımbolo “?-”.Ası, la consulta “← A1, . . . , An” se escribe en Prolog de la forma “?- A1, . . . , An.”. Observesesin embargo que no sera necesario escribir el sımbolo “?-”, puesto que, como se ha comentadoantes, dicho sımbolo aparece directamente en el sistema Prolog.

Ejemplo: Dados los programas para el calculo del factorial y para la suma facilitados previa-mente, algunas consultas posibles serıan las siguientes:

?- factorial(s(s(s(0))), Fact3). ¿Cuanto vale el factorial de 3?

?- factorial(s(s(0)), s(s(0))). ¿Es cierto que el factorial de 2 es 2?

?- factorial(0,Z), factorial(s(s(0)),Z). ¿Existe algun numero natural que sea igualal factorial de 0 y al factorial de 2? ¿Cual?

?- suma(s(0), s(0), X). ¿Cuanto vale la suma 1+1?

?- suma(X, Y, s(s(0))). ¿Que numeros existen tales que su suma sea 2?

?- suma(s(0), Y, s(s(s(0)))). ¿Cuales son los numeros tales que sumados a 1 dan 3?

Las consultas anteriores incluyen variables no anonimas, puesto que el objetivo no es solo sabersi existen numeros que cumplan lo pedido sino que se desea ademas conocer su valor. Existensin embargo ocasiones en las que las consultas pueden incluir variables anonimas.

Ejemplo: En la ultima consulta del ejemplo anterior se pretendıa averiguar cual es el numeronatural tal que sumado a 1 da 3. Sin embargo, si lo unico que se desea saber es si existe algunnumero natural tal que sumado a 1 de 3, bastarıa con utilizar una variable anonima:

?- suma(s(0), _, s(s(s(0)))).

3.1.4. Resumen

Como se acaba de ver, la sintaxis del lenguaje Prolog, aunque se basa en la sintaxis de la Pro-gramacion Logica Definida, presenta ciertas diferencias respecto a esta ultima. A continuacionse resumen las mas importantes:

- los sımbolos de variable se escriben empezando por una letra mayuscula o por un sımbolo desubrayado.

- los sımbolos de predicado se escriben empezando por una letra minuscula, al igual que lossımbolos de funcion y las constantes.

10

Page 11: INTRODUCCION¶ ALLENGUAJEPROLOG - …arantxa.ii.uam.es/~dcamacho/logica/recursos/3848.0.prolog.pdf · Prolog admite tambi¶en una notaci¶on m¶as sencilla que consiste en enumerar

- las clausulas de Horn terminan siempre con un punto. Ademas:

· en las reglas, el sımbolo “←” se sustituye por el sımbolo “:-”

· en los hechos, el sımbolo “←” desaparece.

· en las clausulas objetivo, el sımbolo “←” se sustituye por el sımbolo “?-”.

La siguiente tabla resume las distintas notaciones para clausulas de Horn vistas hasta el mo-mento:

NOTACION REGLAS HECHOS METAS

clausular {¬A1, . . . ,¬An, A} {A} {¬A1, . . . ,¬An}

logica estandar ∀x1 . . .∀xp[(A1 ∧ . . . ∧An)→ A] ∀x1 . . .∀xp(A) ¬∃x1 . . .∃xp(A1 ∧ . . . ∧An)

prog. logica A← A1, . . . , An A← ← A1, . . . , An

Prolog A :- A1, . . . , An. A. ?- A1, . . . , An.

3.2. Semantica

El mecanismo de demostracion automatica utilizado por Prolog es el sistema de ResolucionSLD estudiado en el tema anterior, pero implementado de acuerdo con las siguientes pautas:

Unificacion. Prolog usa el algoritmo de unificacion estandar estudiado en el tema anteriorpero, por razones de eficiencia, no suele incluir el test de ocurrencia. Aunque la omision deeste test puede llevar a la obtencion de resultados erroneos, esto ocurre raramente. Prologpermite al programador la utilizacion directa de su algoritmo de unificacion mediante losdos siguientes predicados predefinidos, que se pueden usar en notacion infija:

- el predicado =, que devuelve cierto si las dos expresiones que se le pasan resultan ser,omitiendo el test de ocurrencia, unificables.

- el predicado \=, que devuelve cierto si el predicado = falla y falso en caso contrario.

Ejemplos:

?- f(X, g(b,c)) = f(Z, g(Y,c)).

Y = b, Z = X ?

yes

?- f(X, g(b,c)) = f(Z, g(Y,d)).

no

?- [a,b,[c,d]] = [X|Y].

X = a, Y = [b,[c,d]] ?

yes

?- 3+5 = 8.

no % 3+5 no es mas que el termino compuesto +(3,5)

11

Page 12: INTRODUCCION¶ ALLENGUAJEPROLOG - …arantxa.ii.uam.es/~dcamacho/logica/recursos/3848.0.prolog.pdf · Prolog admite tambi¶en una notaci¶on m¶as sencilla que consiste en enumerar

?- X = f(X).

X = f(f(f(f(f(f(f(f(f(f(...)))))))))) ?

yes % no se realiza el test de ocurrencia

Nota: algunas implementaciones de Prolog, como por ejemplo SICStus Prolog, incorporanun predicado predefinido especial que permite unificar con test de ocurrencia. En SICStusProlog este predicado se denomina unify_with_occurs_check.

?- unify_with_occurs_check(X,f(X)).

no % sı se realiza el test de ocurrencia

Funcion de seleccion. Selecciona siempre el literal mas a la izquierda.

Regla de ordenacion. Elige las clausulas de acuerdo con el orden en el que estas aparecenen el programa.

Estrategia de busqueda: busqueda en profundidad (se recuerda que esta estrategia es muyeficiente pero tiene el inconveniente de que no es completa, esto es, puede conducir a unacomputacion infinita aun en el caso de que exista una solucion).

Por lo tanto, cuando, una vez cargado un programa logico, se realiza una consulta, Prologconstruye el arbol de Resolucion SLD correspondiente, de acuerdo con la funcion de seleccion yla regla de ordenacion citadas, haciendo un recorrido en profundidad. Ası, las posibles respuestasdel sistema ante una consulta son las siguientes:

Si todas las ramas del arbol SLD son ramas fallo, la respuesta del sistema sera “no”.

Si el arbol SLD tiene alguna rama infinita mas a la izquierda que cualquier posible ramaexito, la reaccion del sistema dependera de la implementacion concreta de Prolog que seeste utilizando. Algunos sistemas, como por ejemplo SWI-Prolog, presentan un mensajede error. Otros, como es el caso de SICStus Prolog, no responden, por lo que es necesariointerrumpir la ejecucion de la consulta mediante CONTROL-C (si se esta usando SICStusProlog a traves de Emacs, la composicion de teclas CONTROL-C debera efectuarse dosveces seguidas). Una vez interrumpida la ejecucion, el sistema muestra por pantalla elmensaje:

Prolog interruption (h for help)?

y acepta a continuacion una letra que determine la accion a seguir. Las posibles accionesse pueden consultar pulsando la tecla h, aunque lo mas habitual sera contestar con laletra a, cuya accion asociada es abortar la ejecucion de la consulta.

En otro caso (es decir, cuando el arbol de Resolucion tiene por lo menos una rama exitomas a la izquierda que cualquier posible rama infinita):

- Si la consulta realizada no tiene variables (o las que tiene son anonimas), la respuestadel sistema sera “yes”, terminandose ası la ejecucion de la consulta.

- Si la consulta realizada tiene alguna variable no anonima, el sistema muestra porpantalla los valores de las variables que se corresponden con la primera rama exitoencontrada al buscar en profundidad en el arbol de Resolucion, y queda a la esperade nuevas instrucciones por parte del usuario:

12

Page 13: INTRODUCCION¶ ALLENGUAJEPROLOG - …arantxa.ii.uam.es/~dcamacho/logica/recursos/3848.0.prolog.pdf · Prolog admite tambi¶en una notaci¶on m¶as sencilla que consiste en enumerar

· si se introduce un retorno de carro, el sistema contesta “yes” y abandona labusqueda de posibles nuevas soluciones.

· si se introduce un punto y coma seguido de un retorno de carro, el sistema continuala busqueda de nuevas soluciones en el arbol de Resolucion, con lo que el procesose vuelve a repetir, dependiendo la respuesta del resultado de la busqueda (“no”si termina de recorrer el arbol sin encontrar ninguna nueva solucion ni ningunarama infinita, computacion infinita si encuentra una rama infinita o valor de lasvariables correspondientes en caso de encontrarse otra solucion).

Como ya se comento en el tema anterior, resulta claro que tanto el orden en el que aparecenlas clausulas en los programas como el orden de los literales dentro de las clausulas puedeninfluir no solo en el orden en el que aparecen las soluciones sino tambien en la terminacion delas consultas que se realizan.

Ejemplo: Considerese el siguiente programa (“ancestros.pl”), que incluye, ademas de un pre-dicado progenitor(X,Y) que es cierto cuando X es progenitor de Y , cuatro versiones distintasdel predicado ancestro(X,Y), cierto cuando X es un ancestro de Y . Las cuatro versiones varıandependiendo del orden de sus clausulas y del orden en el que se colocan los literales dentro deellas.

% progenitor(?X, ?Y): cierto si X es progenitor de Y

progenitor(pepa, pepito).

progenitor(pepito, pepin).

% ancestro(?X, ?Y): cierto si X es un ancestro de Y

% VERSION 1

ancestro1(X, Y) :- progenitor(X, Y).

ancestro1(X, Y) :- progenitor(X, Z), ancestro1(Z, Y).

% VERSION 2

ancestro2(X, Y) :- progenitor(X, Z), ancestro2(Z, Y).

ancestro2(X, Y) :- progenitor(X, Y).

% VERSION 3

ancestro3(X, Y) :- progenitor(X, Y).

ancestro3(X, Y) :- ancestro3(Z, Y), progenitor(X, Z).

% VERSION 4

ancestro4(X, Y) :- ancestro4(Z, Y), progenitor(X, Z).

ancestro4(X, Y) :- progenitor(X, Y).

Aunque las cuatro definiciones anteriores del predicado ancestro son iguales desde el puntode vista logico, su comportamiento en Prolog es distinto, ya que daran lugar a arboles deResolucion distintos. Por ejemplo, si se intenta averiguar de quien es ancestro pepa, resulta losiguiente (compruebense estos resultados mediante la construccion de los arboles de resolucionSLD correspondientes):

13

Page 14: INTRODUCCION¶ ALLENGUAJEPROLOG - …arantxa.ii.uam.es/~dcamacho/logica/recursos/3848.0.prolog.pdf · Prolog admite tambi¶en una notaci¶on m¶as sencilla que consiste en enumerar

Consulta con “ancestro1”: ofrece las dos posibles soluciones y termina.

?- ancestro1(pepa, D).

D = pepito ? ;

D = pepin ? ;

no

Consulta con “ancestro2”: ofrece las dos posibles soluciones (en orden inverso al casoanterior) y termina.

?- ancestro2(pepa, D).

D = pepin ? ;

D = pepito ? ;

no

Consulta con “ancestro3”: ofrece las dos posibles soluciones, en el mismo orden que“ancestro1”, pero si se piden mas soluciones la consulta no termina.

?- ancestro3(pepa, D).

D = pepito ? ;

D = pepin ? ;

% el sistema entra en un bucle, que se interrumpe con CTRL-C CTRL-C

Prolog interruption (h for help)? a

{Execution aborted}

Consulta con “ancestro4”: no produce ninguna solucion, porque entra directamente enuna rama infinita.

?- ancestro4(pepa, D).

% el sistema entra en un bucle, que se interrumpe con CTRL-C CTRL-C

Prolog interruption (h for help)? a

{Execution aborted}

Aunque no existe ninguna regla general que establezca el orden optimo de las clausulas ni elorden optimo de los literales dentro de ellas, sı suelen ser recomendables los siguientes principiosbasicos, basados en la idea de “hacer antes lo mas sencillo”:

1. Colocar las clausulas que expresan las condiciones de parada de la recursividad antes quelas otras (esto se cumple en las versiones 1 y 3 del ejemplo anterior).

2. Evitar las reglas con recursion a la izquierda, es decir, las reglas tales que el primer literalde su cuerpo es una llamada recursiva al mismo predicado de la cabeza de la regla (lasversiones 3 y 4 del ejemplo anterior presentan recursion a la izquierda).

De las cuatro versiones del ejemplo anterior, la unica que cumple estas dos recomendaciones esla primera.

Es por otro lado necesario evitar definiciones circulares del estilo:

14

Page 15: INTRODUCCION¶ ALLENGUAJEPROLOG - …arantxa.ii.uam.es/~dcamacho/logica/recursos/3848.0.prolog.pdf · Prolog admite tambi¶en una notaci¶on m¶as sencilla que consiste en enumerar

progenitor(X,Y) :- hijo(Y,X).

hijo(A,B) :- progenitor(B,A).

puesto que cualquier consulta a uno de los dos predicados anteriores provocara necesariamenteun bucle infinito.

4. Predicados Predefinidos

En el apartado anterior se ha resumido el funcionamiento del lenguaje Prolog desde el puntode vista del paradigma de la Programacion Logica. Sin embargo, las facilidades descritas noson suficientes para obtener un lenguaje de programacion util en la practica: por ejemplo,todo lenguaje de programacion “real” necesita facilidades para leer y/o escribir o mecanismoseficientes para realizar operaciones aritmeticas. Para ello, el lenguaje Prolog incorpora toda unaserie de predicados del sistema o predicados predefinidos (“system or built-in predicates”) queofrecen al usuario facilidades como las citadas ası como otro tipo de funcionalidades extra-logicaso meta-logicas. Estos predicados no pueden ser redefinidos por el programador.

En lo que sigue se describen solo algunos de estos predicados predefinidos, en concreto los re-lacionados con la realizacion de operaciones aritmeticas, ciertos predicados para entrada/saliday el predicado de control denominado corte.

4.1. Aritmetica

4.1.1. Operadores aritmeticos

Prolog tiene predefinidos los operadores aritmeticos mas habituales, mediante los que se puedenformar expresiones aritmeticas. A continuacion se enumeran algunos de los mas importantes:

X+Y suma de X e YX-Y X menos YX*Y producto de X por YX/Y cociente real de la division de X por YX//Y cociente entero de la division de X por YX mod Y resto de la division entera de X por Yabs(X) valor absoluto de Xsqrt(X) raız cuadrada de Xlog(X) logaritmo neperiano de X

Tengase en cuenta que los operadores anteriores permiten simplemente construir expresionesaritmeticas, pero estas no son mas que estructuras (terminos compuestos) que no representanningun valor. Por ejemplo, la expresion 3+5 no es mas que el termino compuesto +(3,5) escritoen notacion infija. Ası, no es posible hacer consultas del estilo “ ?- 3+5.”, puesto que “+” noes un predicado, y si se hiciese la consulta “ ?- 3+5 = 8.”, la respuesta de Prolog serıa no,dado que el termino compuesto +(3,5) no es unificable con el termino constante 8.

Para poder evaluar expresiones aritmeticas en Prolog hay que utilizar los predicados aritmeticosque se describen a continuacion.

15

Page 16: INTRODUCCION¶ ALLENGUAJEPROLOG - …arantxa.ii.uam.es/~dcamacho/logica/recursos/3848.0.prolog.pdf · Prolog admite tambi¶en una notaci¶on m¶as sencilla que consiste en enumerar

4.1.2. Predicados aritmeticos

Los predicados aritmeticos predefinidos de Prolog se utilizan para evaluar expresiones aritmeti-cas. El mas habitual es el predicado predefinido “is”, que se usa en notacion infija de la siguienteforma:

X is Y Si Y es una expresion aritmetica, esta se evalua y el resultadose intenta unificar con X.

A la hora de usar este predicado hay que tener en cuenta las siguientes consideraciones:

1. Su uso puede dar lugar a un error en los dos siguientes casos:

a) cuando la parte derecha no es una expresion aritmetica:

?- X is a+1.

{DOMAIN ERROR: _157 is a+1 - arg 2: expected expression, found a}

b) cuando la parte derecha es una expresion aritmetica pero no se puede evaluar:

?- X is 4*Z.

{INSTANTIATION ERROR: _157 is 4*_155 - arg 2}

2. Salvo en los casos anteriores, el resultado del predicado dependera de si la parte izquierdaunifica o no con el resultado obtenido al evaluar la parte derecha:

?- X is sqrt(4).

X = 2.0 ?

yes

?- 5 is 2+3.

yes

?- X is 5, Y is X+1.

X = 5, Y = 6 ?

yes

?- 3+5 is 3+5.

no

La respuesta negativa obtenida en el ultimo ejemplo se debe a que la expresion “3+5” dela parte izquierda (recuerdese que se trata simplemente del termino compuesto +(3,5))no es unificable con el entero 8, resultante de evaluar la parte derecha.

Ademas del predicado anterior, Prolog incorpora otros predicados comunes para comparacionesaritmeticas, aunque en algunos casos con una notacion distinta a la habitual: observense enparticular los sımbolos para la igualdad/desigualdad (que no pueden ser los habituales = y \=

puesto que estos se utilizan para la unificacion) y la comparacion menor o igual, que se escribeal reves de lo que suele ser normal en otros lenguajes de programacion (<=).

X =:= Y cierto si los valores numericos de X e Y son igualesX =\= Y cierto si los valores numericos de X e Y son distintosX < Y cierto si el valor numerico de X es menor que el de YX =< Y cierto si el valor numerico de X es menor o igual que el de YX > Y cierto si el valor numerico de X es mayor que el de YX >= Y cierto si el valor numerico de X es mayor o igual que el de Y

El funcionamiento de estos predicados es similar al del predicado “is”: produciran un erroren caso de que alguno de los dos argumentos no sea una expresion aritmetica o, a pesar de

16

Page 17: INTRODUCCION¶ ALLENGUAJEPROLOG - …arantxa.ii.uam.es/~dcamacho/logica/recursos/3848.0.prolog.pdf · Prolog admite tambi¶en una notaci¶on m¶as sencilla que consiste en enumerar

serlo, no se pueda evaluar. En caso contrario, el sistema evalua las dos expresiones aritmeticasy devuelve el resultado de la comparacion solicitada.

?- X+3 < sqrt(4).

.. ERROR: ..

?- 3+5 =:= 8.

yes

?- 1+ 5 > abs(-8).

no

?- 3 =\= 3*a.

.. ERROR: ..

4.1.3. Programas aritmeticos en Prolog

En el tema anterior, relativo a la Programacion Logica general, se estudiaron varios programaslogicos aritmeticos, como por ejemplo los programas para el calculo de la suma y el factorialde numeros naturales. Se trataba en ambos casos de programas logicos definidos, por lo quebasta con adaptar su sintaxis para obtener los correspondientes programas en Prolog (vease elapartado 3.1.2 de este documento).

Los programas aritmeticos del estilo de los anteriores se pueden considerar programas logicospuros, puesto que estan definidos utilizando exclusivamente propiedades logicas, y tienen doscaracterısticas principales:

- Son, por un lado, programas sencillos y versatiles. Recuerdese en particular como puedenutilizarse para varios cometidos distintos -por ejemplo el programa de la suma tambiensirve para restar- ya que cualquiera de sus argumentos puede usarse tanto de entradacomo de salida (veanse los ejemplos de consultas dados en el apartado 3.1.3).

- Son tambien, sin embargo, incomodos de utilizar en la practica y poco eficientes. Su inco-modidad proviene del hecho de que los numeros naturales se deben manipular mediantela funcion sucesor, y la ineficiencia se debe al calculo recursivo utilizado para resolveroperaciones aritmeticas elementales.

Una alternativa evidente para mejorar la comodidad y la eficiencia de estos programas es reem-plazarlos por otros que hagan uso de las facilidades aritmeticas ofrecidas por Prolog, tanto enlo que se refiere al uso de sus constantes numericas como al uso de los operadores y predicadosaritmeticos mencionados mas arriba. Ası, si se desease disponer de un predicado para sumarnumeros naturales, bastarıa con definirlo como sigue, utilizando simplemente el predicado deevaluacion is:

% suma(+X,+Y,?Z): cierto si Z es la suma de X e Y

suma(X,Y,Z) :- Z is X+Y.

Esta version del predicado suma es claramente mucho mas comoda (permite utilizar directa-mente numeros naturales en notacion decimal) y mucho mas eficiente (utiliza la potencia decalculo aritmetico del ordenador). Tiene sin embargo la desventaja respecto a la version logicapura de que pierde la versatilidad de esta. En efecto, como se puede ver en el comentario previoa la definicion del nuevo predicado, este, a diferencia del anterior, solo se puede usar cuando susdos primeros argumentos estan instanciados: si se intenta usar de otra forma se producira unerror. Esto es debido a la utilizacion en el cuerpo de la regla del predicado predefinido is, que,como se vio antes, requiere que su parte derecha este instanciada.

17

Page 18: INTRODUCCION¶ ALLENGUAJEPROLOG - …arantxa.ii.uam.es/~dcamacho/logica/recursos/3848.0.prolog.pdf · Prolog admite tambi¶en una notaci¶on m¶as sencilla que consiste en enumerar

De forma similar, una definicion mas eficiente -aunque menos elegante- del predicado factorialserıa la siguiente:

% factorial(+X, ?Y): cierto si Y es el factorial de X.

factorial(0, 1).

factorial(X, Y) :-

X >0, X1 is X-1, factorial(X1, FactX1), Y is X*FactX1.

Por el mismo motivo que antes, el predicado anterior solo se podra usar cuando el primerargumento este instanciado, es decir, el predicado es valido para calcular factoriales, pero nosirve ya para averiguar si un numero es o no el factorial de algun otro numero. Esta restriccionno solo afecta al uso directo del predicado, sino tambien a su capacidad para ser usado en ladefinicion de otros: por ejemplo, el predicado es_factorial que se describio en el apartado2.1.2. a partir de la version logica del predicado factorial ya no podra definirse utilizandoesta nueva version. Observese asimismo que en la nueva version se ha introducido, antes de lallamada recursiva, la comprobacion X>0, necesaria si se quiere evitar que se produzca una ramainfinita en el arbol de Resolucion SLD correspondiente (construyanse como ejercicio los arbolesde Resolucion asociados a una consulta concreta con y sin la comprobacion anterior).

4.2. Entrada/Salida

El lenguaje Prolog ofrece toda una serie de predicados predefinidos para la realizacion de opera-ciones de entrada/salida. Se trata de predicados que no tienen sentido desde un punto de vistapuramente logico, sino que producen un efecto colateral (escritura/lectura de algun termino,apertura/cierre de un fichero, etc). A continuacion se describen algunos de los predicados deentrada/salida mas basicos:

open(+NombreFichero, +Modo, -Fichero)

Si NombreFichero es un nombre de fichero valido, abre el fichero correspondiente deacuerdo con el modo especificado por Modo, y unifica con Fichero el identificador delfichero abierto. Los valores para el argumento Modo pueden ser:

read para abrir el fichero en modo lectura.

write para abrir el fichero en modo escritura (si el fichero no existe, lo crea; si ya existe,su contenido se perdera).

append para abrir el fichero en modo escritura (si el fichero no existe, lo crea; si ya existe,las operaciones de escritura se realizaran al final del fichero).

close(+Fichero)

Cierra el fichero asociado con el identificador Fichero.

set_input(+Fichero) set_output(+Fichero)

Convierte al fichero con identificador Fichero en el fichero de lectura (escritura) actual.

current_input(?Fichero) current_output(?Fichero)

Fichero es el fichero de lectura (escritura) actual.

18

Page 19: INTRODUCCION¶ ALLENGUAJEPROLOG - …arantxa.ii.uam.es/~dcamacho/logica/recursos/3848.0.prolog.pdf · Prolog admite tambi¶en una notaci¶on m¶as sencilla que consiste en enumerar

Nota: el fichero por defecto, tanto para lectura como para escritura, es la pantalla, cuyoidentificador es user.

read(?Termino) read(+Fichero, ?Termino)

Lee el siguiente termino (del fichero de lectura actual o del fichero especificado, previa-mente abierto en modo lectura) y unifica el resultado con Termino. El termino debe acabarcon un punto y un retorno de carro.

write(?Termino) write(+Fichero, ?Termino)

Escribe el termino Termino en el fichero de escritura actual o en el fichero especificado(previamente abierto en modo escritura).

nl nl(+Fichero)

Escribe un retorno de carro en el fichero de escritura actual o en el fichero especificado(previamente abierto en modo escritura).

Ejemplos: Se incluyen a continuacion algunos ejemplos tıpicos de predicados que realizan ope-raciones de entrada/salida (fichero “entrada-salida.pl”):

% pide_numero(-X)

% X es un numero leıdo del fichero de lectura actual

pide_numero(X) :-

write(’Introduzca un numero: ’),

nl,

read(X).

% escribe_cuadrado(+X)

% escribe el cuadrado de X en el fichero de escritura actual

escribe_cuadrado(X) :-

X2 is X*X,

write(’El cuadrado de ’),

write(X),

write(’ es ’),

write(X2).

% pide un numero y escribe su cuadrado por pantalla

cuadrado :-

pide_numero(X),

escribe_cuadrado(X).

% imprime_lista(+Fichero, +L)

% Si Fichero es un identificador de fichero y L es una lista,

% escribe los elementos de L en el fichero, uno por lınea

imprime_lista(_Fichero, []).

imprime_lista(Fichero, [C|R]) :-

write(Fichero, C),

nl(Fichero),

imprime_lista(Fichero, R).

19

Page 20: INTRODUCCION¶ ALLENGUAJEPROLOG - …arantxa.ii.uam.es/~dcamacho/logica/recursos/3848.0.prolog.pdf · Prolog admite tambi¶en una notaci¶on m¶as sencilla que consiste en enumerar

% imprime_lista(+L)

% Si L es una lista, imprime por pantalla sus elementos, uno por lınea

imprime_lista(L) :-

imprime_lista(user, L). % user es el identificador de la pantalla

% pide una lista y la imprime en un fichero

prueba_fich :-

write(’Introduzca una lista: ’), nl,

read(Lista),

open(’prueba.txt’, write, Prueba),

imprime_lista(Prueba, Lista),

write(’la lista se ha escrito en el fichero prueba.txt’),

close(Prueba).

A continuacion se reproduce la ejecucion de algunos de los predicados anteriores:

?- cuadrado.

Introduzca un numero:

|: 3.

El cuadrado de 3 es 9

yes

?- imprime_lista([esto,es,una,lista]).

esto

es

una

lista

yes

?- prueba_fich.

Introduzca una lista:

|: [h,o,l,a].

la lista se ha escrito en el fichero prueba.txt

yes

La ejecucion de este ultimo predicado tiene como efecto colateral la escritura de los elementosde la lista [h,o,l,a] en el fichero “prueba.txt”.

4.3. Control: el corte

Los predicados de control son predicados predefinidos que permiten al programador interveniren el mecanismo de busqueda de soluciones de Prolog. En este apartado se va a introducirexclusivamente uno de ellos, el denominado predicado de corte.

20

Page 21: INTRODUCCION¶ ALLENGUAJEPROLOG - …arantxa.ii.uam.es/~dcamacho/logica/recursos/3848.0.prolog.pdf · Prolog admite tambi¶en una notaci¶on m¶as sencilla que consiste en enumerar

4.3.1. Definicion y propiedades

El corte es un predicado predefinido que se denota mediante un punto de exclamacion (!), notiene argumentos, y cuya evaluacion es siempre cierta. Se puede incluir, como un predicadomas, en el cuerpo de las reglas o en las consultas (por ejemplo a :- b, c, !, d.).

Los cortes permiten al programador intervenir en el control del programa, puesto que su pre-sencia hace que el sistema ignore ciertas ramas del arbol SLD correspondiente. En concreto, elefecto de los cortes en la construccion y recorrido de los arboles de resolucion SLD se producecuando el sistema llega a un nodo del arbol cuyo primer predicado es un corte, es decir, un nodode la forma “?- !,a1,..,an.”. En estos casos ocurre lo siguiente (siendo N el nodo anterior):

1. El predicado de corte siempre se evalua como cierto, por lo que el nodo N tendra un unicohijo, que sera igual a N pero sin el corte, es decir, sera de la forma “?- a1,..,an.”. Laexpansion de este nodo se realiza igual que la expansion de cualquier otro nodo del arbol.

2. Tanto para cada uno de los nodos ascendientes de N que contengan el corte como para elprimer ascendiente que no lo contiene (sea N’ dicho nodo) se ignoran todas sus posiblesramas situadas mas a la derecha de la rama que lleva a N.

La siguiente figura ilustra lo anterior. Las ramas tachadas con una raya son aquellas que seignoran como consecuencia del corte.

���

����� � ���� � ���

� � ���� � ���

Ejemplo. Considerese el programa Prolog dado por las siguientes clausulas:

a :- b, c.

a :- ....

b :- d, !, e.

b.

b :- ....

d.

d :- ....

e :- ....

21

Page 22: INTRODUCCION¶ ALLENGUAJEPROLOG - …arantxa.ii.uam.es/~dcamacho/logica/recursos/3848.0.prolog.pdf · Prolog admite tambi¶en una notaci¶on m¶as sencilla que consiste en enumerar

La figura incluida a continuacion muestra el arbol de Resolucion SLD resultante al realizarsela consulta ?-a. Las ramas tachadas son las que se deben ignorar debido al corte.

�������

��������� ��� �������

���������������� ����������������

������������� ��������������������

����������

�������

El efecto de la existencia de una regla de la forma “a:-a1,..,ai,!,..,an” se produce porlo tanto cuando el sistema llega a la evaluacion del corte, y consiste en hacer que todas lasopciones tomadas desde el momento en el que aparece la clausula objetivo conteniendo un corte(incluida la decision que lleva a la consideracion de esta clausula) hasta la evaluacion del cortesean obligatorias, eliminandose cualquier alternativa. En concreto:

En el momento de evaluar el corte, el sistema ya ha encontrado soluciones para los objeti-vos a1,..,ai, y no se consideraran otras alternativas para ninguno de ellos (en el ejemploanterior, no se consideran nuevas alternativas para el objetivo d).

Tampoco se consideraran otras alternativas para el predicado responsable de la introduc-cion del corte (en el ejemplo anterior, el predicado b).

El predicado de corte tiene dos ventajas fundamentales:

Su utilidad basica, dado que reduce el espacio de busqueda de soluciones, es mejorar laeficiencia de los programas, evitando la exploracion de partes del arbol de resolucion delas que se sabe de antemano que no conduciran a ninguna nueva solucion.

22

Page 23: INTRODUCCION¶ ALLENGUAJEPROLOG - …arantxa.ii.uam.es/~dcamacho/logica/recursos/3848.0.prolog.pdf · Prolog admite tambi¶en una notaci¶on m¶as sencilla que consiste en enumerar

Por otro lado, el corte tambien permite aumentar la expresividad del lenguaje: su uso, nor-malmente en combinacion con otros predicados predefinidos, aporta nuevas construccionesde gran utilidad, como por ejemplo la negacion por fallo finito.

Sin embargo, el corte es un predicado muy controvertido. Al tratarse de una herramienta decontrol (interviene en como se debe resolver el problema), su uso entra en clara contradiccioncon los principios basicos de la programacion logica pura, que preconiza una separacion nıtidaentre la logica del problema (responsabilidad del programador) y la forma de resolverlo (respon-sabilidad del mecanismo de demostracion automatica). Ası, el corte puede conducir a programaslogicos difıciles de leer y de validar, y puede provocar muchos errores de programacion.

En definitiva, el predicado de corte de Prolog constituye una herramienta de caracter extra-logico, muy potente pero que debe usarse con mucho cuidado y en casos muy concretos.

4.3.2. Usos del corte. Ejemplos

Aunque el predicado de corte tiene usos muy variados (en general, en combinacion con otrospredicados predefinidos de Prolog) uno de los mas habituales es la simulacion de estructurascondicionales de la forma:

si b1 entonces c1;si no: si b2, entonces c2;....si no: si bn, entonces cn;si no: c.

En Prolog, este tipo de estructuras, con condiciones mutuamente excluyentes, se representanmediante un predicado definido por medio de n + 1 reglas, donde cada regla expresa una delas posibles formas de calcular el predicado: la regla i-esima expresa que el predicado es ciertosi no se cumple ninguna de las condiciones b1, ..., bi−1 anteriores y, ademas, se cumplen lascondiciones bi y ci.

El corte permite simplificar la representacion anterior y conseguir un uso mas eficiente de estetipo de estructuras. Su representacion utilizando el corte es la siguiente:

a :- b1, !, c1.

a :- b2, !, c2.

....

a :- bn, !, cn.

a :- c.

De esta forma se consigue que, en el momento en que se compruebe que se verifica una ciertacondicion bi, no se intente aplicar ninguna regla posterior.

A continuacion se describe el uso del corte mediante su aplicacion a varios ejemplos (todos elloscontenidos en el fichero “corte.pl”).

23

Page 24: INTRODUCCION¶ ALLENGUAJEPROLOG - …arantxa.ii.uam.es/~dcamacho/logica/recursos/3848.0.prolog.pdf · Prolog admite tambi¶en una notaci¶on m¶as sencilla que consiste en enumerar

Ejemplo 1: calculo de una funcion

Supongase que se necesita definir un predicado en Prolog que permita calcular la siguientefuncion fun:

fun(x) =

0, si x ≤ 101, si 10 < x ≤ 202, si x > 20

Una primera aproximacion para la resolucion del problema anterior es definir un predicadof(X,Y), cierto si Y es igual a fun(X), mediante las tres siguientes reglas:

f(X,0) :- X =< 10.

f(X,1) :- X>10, X =< 20.

f(X,2) :- X > 20.

La representacion anterior calcula correctamente los valores de la funcion fun, pero tiene elsiguiente inconveniente. Supongase que se realiza la consulta “?- f(0,Z), Z>1.”. La respuestade Prolog sera “no”, pero para llegar a dicha conclusion el sistema tiene que recorrer las 3posibles ramas del arbol de Resolucion SLD correspondiente (dibujese como ejercicio dichoarbol). Lo anterior es poco eficiente, puesto que, al ser las tres reglas que describen el predicadof mutuamente excluyentes, una vez que se ha encontrado una solucion con una de ellas notiene sentido probar con el resto. En efecto, la funcion que se esta calculando tiene la siguienteestructura condicional:

si X ≤ 10 entonces Y = 0;si no: si X ≤ 20, entonces Y = 1;si no: Y = 2.

Por lo tanto, una forma de remediar la ineficiencia anterior es utilizando el predicado de cortecomo se ha indicado al principio de este apartado:

f(X,Y) :- X =< 10, !, Y=0.

f(X,Y) :- X =< 20, !, Y=1.

f(_X,2).

Con esta nueva version, la respuesta de Prolog a la consulta “?- f(0,Z), Z>1.” sera tam-bien “no”, pero ahora, gracias a la introduccion del corte en la primera regla, el sistema solotendra que explorar la primera rama del arbol SLD.

Observese que una forma mas comoda para representar esta nueva version consistirıa en, aligual que en la primera version, realizar la unificacion directamente en la cabeza de las reglas:

f(X,0) :- X =< 10, !.

f(X,1) :- X =< 20, !.

f(_X,2).

24

Page 25: INTRODUCCION¶ ALLENGUAJEPROLOG - …arantxa.ii.uam.es/~dcamacho/logica/recursos/3848.0.prolog.pdf · Prolog admite tambi¶en una notaci¶on m¶as sencilla que consiste en enumerar

Sin embargo, hay que destacar que esta ultima version, a pesar de ser mas comoda de escribir,tiene el inconveniente de que no siempre es correcta, porque no funciona adecuadamente paraciertos usos del predicado: resuelve correctamente consultas de la forma “?- f(5,Z).”, pero sinembargo no siempre funciona con consultas en las que ambos argumentos estan instanciados:por ejemplo, la respuesta del sistema ante la consulta “?- f(0,2).” serıa afirmativa, cuandodeberıa ser evidentemente negativa. Este problema no se da en las versiones anteriores.

Ejemplo 2: calculo del maximo de dos numeros

El procedimiento para calcular el maximo de dos numeros naturales se puede implementar enProlog mediante un predicado maximo(X,Y,Z), cierto si Z es el maximo de X e Y. Al igual queen el ejemplo anterior, una primera version para dicho predicado podrıa ser la siguiente:

maximo(X,Y,X) :- X >= Y.

maximo(X,Y,Y) :- X < Y.

Dado que las dos opciones son mutuamente excluyentes, una forma mas comoda y eficiente deexpresar lo anterior es utilizando el corte:

maximo(X,Y,Z) :- X >= Y, !, Z=X.

maximo(_X,Y,Y).

Otra posibilidad, similar a lo que se comento en el ejemplo anterior, es modificar la versionanterior de forma que la unificacion se realice directamente en la cabeza de las clausulas:

maximo(X,Y,X) :- X >= Y, !.

maximo(_X,Y,Y).

Al igual que en el ejemplo anterior, resulta que esta ultima version no puede usarse de cual-quier forma, porque con ciertas consultas puede dar lugar a resultados erroneos: por ejemplo,la respuesta del sistema ante la consulta “?-maximo(3,0,0).” es afirmativa, cuando deberıaser evidentemente negativa.

Ejemplo 3: pertenencia de un elemento a una lista

La forma mas inmediata para representar en Prolog la pertenencia de un elemento a una listaes la siguiente:

pertenece(C, [C|_]).

pertenece(C, [_|R]) :- pertenece(C,R).

En la definicion anterior, las dos opciones no se consideran excluyentes, por lo que si un elementoaparece varias veces en una lista, el predicado encontrara todas sus posibles ocurrencias. Ası,

25

Page 26: INTRODUCCION¶ ALLENGUAJEPROLOG - …arantxa.ii.uam.es/~dcamacho/logica/recursos/3848.0.prolog.pdf · Prolog admite tambi¶en una notaci¶on m¶as sencilla que consiste en enumerar

el predicado anterior podra utilizarse no solo para averiguar si un elemento pertenece a unalista determinada sino tambien para recorrer todos los elementos de una lista. Por ejemplo, larespuesta del sistema ante la consulta “pertenece(X,[a,b,c]).” es la siguiente (compruebeseconstruyendo el arbol de resolucion SLD correspondiente).

?- pertenece(X,[a,b,c]).

X = a ? ;

X = b ? ;

X = c ? ;

no

Una version mas eficiente del predicado anterior se consigue introduciendo un corte en el cuerpode la primera regla, de forma que el predicado termine en el momento de encontrar la primeraocurrencia de un cierto elemento:

pertenece(C, [C|_]) :- !.

pertenece(C, [_|R]) :- pertenece(C,R).

Con esto se consigue una version determinista y mas eficiente del predicado. Sin embargo,la introduccion del corte y la consiguiente poda del arbol de Resolucion SLD hace que elpredicado ya no se pueda usar, como con la version anterior, para enumerar todos los elementosde una lista. En efecto, ahora se tendra (compruebese construyendo el arbol de resolucion SLDcorrespondiente):

?- pertenece(X,[a,b,c]).

X = a ? ;

no

26