Está en la página 1de 50

Prolog(Sin,Esfuerzo) :- en 44 minutos(Sin), y 15 segundos(Esfuerzo).

francisco miguel garc olmedo a Departamento de Algebra Universidad de Granada 18071 Granada, Espaa n 22 de mayo de 2011

Indice
1. Introduccin o 2. Utilizar Prolog 3. Sintaxis 3.1. Atomos . . . . . . . 3.2. Nmeros . . . . . . . u 3.3. Variables . . . . . . . 3.4. Trminos compuestos e 3.5. Operadores . . . . . 3.6. Funciones aritmticas e 3.7. Conectivas . . . . . . 3.8. Reglas . . . . . . . . 3.9. Comentarios . . . . . 4. Programas 5. Estructuras de Datos 5.1. Arboles . . . . . . . . . . . . 5.2. Listas . . . . . . . . . . . . . 5.3. Coleccionando Soluciones. . . 5.3.1. findall/3 . . . . . . . 5.3.2. bagof/3 . . . . . . . . 5.3.3. setof/3 . . . . . . . . 5.4. Conjuntos . . . . . . . . . . . 5.5. La estructura de los trminos e 5.5.1. functor . . . . . . . . 5.5.2. arg . . . . . . . . . . . 5.5.3. =.. . . . . . . . . . . . 2 3 5 5 6 6 6 7 10 10 11 12 12 15 15 16 19 19 20 21 21 23 23 24 24

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . . 1

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

5.5.4. name . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6. Recursos de Control en la Programacin o 6.1. Recursin (recursion) . . . . . . . . . . . o 6.2. Unicacin (unication, matching) . . . o 6.3. Reevaluacin (backtracking) . . . . . . . o 6.4. Corte (cut) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

25 25 26 28 29 30 31 31 32 32 33 34 35 36 36 37 38 39 40 41 43 45 50

7. Usos del Corte 7.1. Conrmacin . . . . . . . . . . . . . . . . . o 7.2. Advertencia . . . . . . . . . . . . . . . . . . 7.3. Finalizacin . . . . . . . . . . . . . . . . . . o 7.4. Efectos indeseados, pero tolerables, del corte 7.5. Predicados de control . . . . . . . . . . . . . 7.6. Otros ejemplos . . . . . . . . . . . . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

8. La I/O en Prolog 8.1. Lectura y escritura de trminos . . . . . . . . . . . . . . . . . . . . . . . e 8.2. Lectura y escritura de caracteres . . . . . . . . . . . . . . . . . . . . . . . 8.3. Lectura y escritura en cheros . . . . . . . . . . . . . . . . . . . . . . . . 9. Modicacin de la Base de Conocimiento o 9.1. Adicin de Bases de Conocimiento externas . . . . . . . . . . . . . . . . o 9.2. Manipulacin de la Base de Conocimiento . . . . . . . . . . . . . . . . . o 10.Depuracin de Programas Prolog o A. Predicados Predenidos B. Notacin comparativa entre Lgica y Prolog o o

Indice de guras
1. 2. 3. Ejemplos de atomos, nmeros y variables. . . . . . . . . . . . . . . . . . u Operadores aritmticos y relacionales predenidos en SWI-Prolog. . . . . e Denicin inja, preja o suja de un operador. . . . . . . . . . . . . . . o 6 7 8

1.

Introduccin o

Prolog (proviene de Programmation en Logique) fue creado por Alain Colmerauer y sus colaboradores alrededor de 1970 en la Universidad de MarseilleAix, si bien en el desarrollo del lenguaje intervino de forma esencial Robert Kowalski de la Universidad de Edimburgh. Las investigaciones de Kowalski proporcionaron el marco terico, mieno tras que los trabajos de Colmerauer dieron origen al actual lenguaje de programacin, o construyendo el primer intrprete de Prolog. e

El lenguaje Prolog juega un importante papel dentro de la Inteligencia Articial; de hecho se propuso como el lenguaje nativo de las mquinas de la quinta generacin, que a o se quer que fueran Sistemas de Procesamiento de Conocimiento. a Prolog es un lenguaje de programacin para ordenadores que se basa en el lenguaje de o la Lgica de Primer Orden y que se utiliza para resolver problemas en los que entran en o juego objetos y relaciones entre ellos. Una de las ventajas de la programacin lgica es o o que se especica qu se tiene que hacer (programacin declarativa) y no cmo se debe e o o hacer (programacin imperativa). o Los presentes notas son una reformulacin y adaptacin muy cercana al documento orio o ginal de los profesores Castel y Llorens. Estos autores han compuesto una introduccin o magn ca a Prolog: es concisa, ecaz, clara, ilustrada y correcta. Despus de leerla, ya e podemos ir a por los manuales y libros.

2.

Utilizar Prolog

En un sistema Linux lo ms interesante es instalar SWI-Prolog, lo cual puede extenderse a al resto de plataformas debido a que se trata de software libre. Si el sistema est basado a en Debian (nos referimos, por ejemplo, a: un Debian, un Ubuntu, Guadalinex, etc.), la instalacin se lleva a cabo con la orden: o sudo apt-get install swi-prolog Si nuestro sistema es Windows o Mac OS X podemos llevar a cabo la instalacin desde o la informacin que brinda la pgina ocial de SWI-Prolog. o a http://www.swi-prolog.org/ y mejor an, su pgina de descargas: u a http://www.swi-prolog.org/download/stable Recomendamos editar los cheros .pl con Emacs, un editor polivalente con licencia GNU que est disponible en todas las plataformas. Se trata de un clsico con mantenimiento a a garantizado que nos servir como editor auxiliar de cualquier lenguaje. Una gu sucinta a a de su uso es: http://matematicas.unal.edu.co/hmora/emacs_man.pdf En nuestro sistema Linux basado en Debian, la instalacin de Emacs se lleva a cabo o como sigue: sudo apt-get install emacs emacs23-el prolog-el Con el propio Emacs editaremos un chero .emacs en nuestro directorio ra e incluirez mos en l el siguiente texto: e

(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)) As habremos adecuado emacs para dar colorido y entender los cheros .pl Si nuestro sistema es Mac OS X podemos bajar de: http://aquamacs.org/download.shtml el chero de instalacin de Aquamacs, que actualmente es Aquamacs-Emacs-2.2.dmg. o Se trata de la mejor implementacin que conocemos de Emacs. Con Aquamacs no es o necesario completar la instalacin para que el editor se adecue a los cheros .pl, pues o esto viene hecho por defecto. Si nuestro sistema es Windows, la instalacin de Emacs viene detallada en uno de los o puntos del famoso blog: http://instalaremacsenwindows7.blogspot.com/ Aunque el blog habla de la instalacin en Windows 7, nosotros la hemos probado tamo bin en Windows Vista y funciona. Con pequeas modicaciones tambin vale esta e n e informacin para Windows XP, si es que an disfrutamos de l. No olvidar incluir en o u e el .emacs que el muchachillo dice de crear, el texto de adaptacin antes mencionado; o aqu s que es necesario. Con nuestro editor escribir amos un chero .pl, que por ejemplo y por hacer honor a la costumbre, podr ser el chero hola.pl con el siguiente contenido: a venga_saluda :- write(hola mundo!). Ejecutaremos en el terminal, sea cual sea la plataforma, la orden: swipl y entraremos en el intrprete de Prolog que nos permite escribir tras el prompt e habitual de la marca: ? Esta es una sesin t o pica: ?- [hola.pl]. % hola.pl compiled 0.00 sec, 272 bytes true. ?- listing. 4

venga_saluda :write(hola mundo!). true. ?- venga_saluda. hola mundo! true. Y ste es el momento en que comprendemos, con certeza y regocijo, que est en el bote: e a hemos escrito nuestro primer programa en Prolog! Lo que pasa es que surge la pregunta: qu faciln, no!? pero . . . tan fcil?. e o a Si hacemos: ?- help(help). se despliega una ventana de ayuda con mucha calidad. No olvidar que cuando se hace una pregunta, o sea se marca un objetivo, es necesario nalizar con punto . antes de pulsar intro. Cuando queramos dejar el entorno intrprete haremos: e ?- halt. Y ahora . . . adelante!

3.

Sintaxis

En la programacin de Prolog usaremos trminos que son de las siguientes clases: o e 1. Atomos. 2. Nmeros. u 3. Variables. 4. Trminos compuestos. e Adems incluimos en esta leccin los siguientes aspectos: a o 1. Operadores 2. Comentarios

3.1.

Atomos

Los tomos de Prolog son de tres tipos: a 1. Una cadena de caracteres compuesta de letras mayculas, minsculas, d u u gitos y el carcter de subrayado; debe comenzar por una letra minscula. Ejemplos: don eladio guardiola, a u mantequilla y puerta2. 2. Cualquier cadena de caracteres encerrada entre comillas simples. Ejemplos: El Gimp, y tambin ^& %#$& * e 5

3. Todos los operadores, en particular los relacionados en la seccin Operadores y o otros. 4. Las conectivas relacionadas en la seccin Conectivas. o 5. Ciertas cadenas de caracteres especiales, por ejemplo: @=, ====>, ; y :Para saber si ciertas secuencias de caracteres son atomo tenemos atom(?Secuencia).

3.2.

N meros u

Los nmeros son de dos tipos: u 1. enteros; en la implementacin de Prolog-2 los enteros son los del intervalo [223 , 223 o 1] = [8388608, 8388607]. 2. reales; decimales con signo en coma otante consistentes en al menos un d gito, opcionalmente un punto decimal seguido de la parte decimal. Cabe la notacin o cient ca siguiendo a la letra mayscula E u

3.3.

Variables

En cuanto a las variables, empiezan con letras maysculas o con el signo de subrayado ( ). u Son las incgnitas de los problemas y estn destinadas a representar objetos cualesquiera o a del universo del problema. Tiene un valor especial la variable annima, que representa un o valor desconocido cuya identidad no interesa; las variables annimas no estn compartidas o a entre s Una variable est instanciada si representa a un valor concreto; puede estar . a instancia o no. Para saber si ciertas secuencias de caracteres son variable tenemos var(?Secuencia) y nonvar(?Secuencia). tomos a a don vito corleone Anibal Lecter b52 n meros u variables 4 X -1.2 Dividendo primero 1.2E+3 resto 1.2E-3

Figura 1: Ejemplos de atomos, nmeros y variables. u

3.4.

Trminos compuestos e

Son sinnimos trmino compuesto, estructura, hechos y predicado. Las estructuras tienen o e la siguiente sintaxis: funtor(argumento1,...,argumentoN) 6

donde funtor es un atomo y argumentok, con 1 k N , es trmino. Ejemplos: e mujer(clara) ama(X,prolog) libro(programacion en Prolog,autores(Clocksin,Mellish),1981) Admitimos el trmino vaco como trmino. e e

3.5.

Operadores

Encontramos predenidos en Prolog los operadores de la tabla de la Figura 2. El manejo de esos operadores ha sido dulcicado respecto a lo que es la representacin interna o de Prolog. Internamete Prolog usar is(11,+(2,*(3,3))), pero nosotros escribimos a 11 is 2 + 3 * 3. Aqu encontramos un primer detalle a subrayar: se ha hecho un uso injo permitido del operador *. Sabemos que un operador es prejo, injo o sujo segn u lo que indica la tabla de la Figura 3. operadores signo positivo signo negativo potencia producto divisin o divisin entera o resto divisin entera o suma resta igualdad distinto menor que menor o igual que mayor que mayor o igual que evaluacin aritmtica o e s mbolos precendencia especicador + 200 fx 200 fx ^ o ** 200 xfx * 400 yfx / 400 yfx // 400 yfx mod 400 yfx + 500 yfx 500 yfx = 700 xfx \= 700 xfx < 700 xfx =< 700 xfx > 700 xfx >= 700 xfx is 700 xfx

Figura 2: Operadores aritmticos y relacionales predenidos en SWI-Prolog. e Prolog incorpora convenios para evitar ambigedad en las expresiones. Considrese el u e siguiente dilogo: a ?- 15 is 2+3*3. false. ?- 11 is 2+3*3. true. 7

Esto se explica en funcin de la precedencia, que es mayor para + que para *; ello hace o que la representacin interna de 2+3*3 sea +(2,*(3,3)), es decir, + es el operador ms o a externo. De forma similar 11 is 2+3*3 es interpretada como is(11,+(2,*(3,3))), y no como is(11,+(2,*(3,3))), porque la precedencia de is es superior a la de +. Nmero u ms alto indica precedencia ms alta. a a carcter a injo prejo sujo especicador xfx, xfy, yfx fx, fy xf, yf

Figura 3: Denicin inja, preja o suja de un operador. o Prolog permite al programador denir sus propios operadores. La sintaxis de esta operacin es: o :- op(Precedencia, Tipo, Nombre). donde Precedencia es un nmero entre 0 y 1200. La precedencia de =, por ejemplo, u es 700, la de + es 500 y la de * es 400. Tipo es un tomo que especica el tipo y la a asociatividad del operador. En el caso de + este atomo es yf x, que indica que + es un operador injo; f representa al operador, x e y los argumentos. Ms an, x quiere signicar a u que el argumento que ocupa su lugar es de precedencia inferior a la precedencia de + e y indica que el argumento que ocupa su lugar es de precedencia menor o igual que la precedencia de +. As : ?- 2 + 3 + 4 = +(2,+(3,4)). false ?- 2 + 3 + 4 = +(+(2,3),4). true ?- 6 is 7-3-2. false. ?- 2 is 7-3-2. true. Algunos ejemplos reales son: :::::1200, xfx, [ :-, --> ]). 1200, fx, [ :-, ?- ]). 1100, xfy, [ ; ]). 1000, xfy, [ , ]). 700, xfx, [ =, is, =.., ==, \==, =:=, =\=, <, >, =<, >= ]). :- op( 500, yfx, [ +, -]). 8 op( op( op( op( op(

:- op( 500, fx, [ +, - ]). :- op( 300, xfx, [ mod ]). :- op( 200, xfy, [ ^ ]). Los operadores no hacen que se efete ningn tipo de operacin aritmtica. El predicado u u o e de evaluacin es el operador injo is: o -Numero is +Expresion donde Expresion es un trmino que se interpreta como una expresin aritmtica, con e o e todos sus valores instanciados. Numero puede ser una variable o una constante numrica. e ?- 6 is 7-3-2. false. ?- X is 7-3-2. X = 2. No obstante, obsrvese tambin el siguiente dilogo: e e a ?- 2+2 \= 4. true. ?- 2+2 \== 4. true. ?- 2+2 =\= 4. false. Como ejemplo, considerar que hemos editado el chero endulzar.pl con el siguiente contenido: :- op(500,xf,es_dulce). endulza(azucar,cafe). es_dulce(X) :- endulza(_,X). Ahora tiene sentido el siguiente dilogo: a ?- [endulzar.pl]. % endulzar.pl compiled 0.00 sec, 1,432 bytes true. ?- cafe es_dulce. true. Acabamos de indicar a Prolog como traducir una notacin informal, cafe es dulce, a o una notacin real suya es dulce(cafe). Adems hemos dotado a Prolog de una base o a de datos para decidir sobre la cuestin cafe es dulce. o

3.6.

Funciones aritmticas e

Prolog incorpora ciertas funciones aritmticas entre las que destacamos: abs, sig, min, e max, random, round, integer, float, sqrt, sin, cos, tan, log, log10, exp, etc. Como ejemplo de utilizacin tenemos el siguiente dilogo: o a ?- X is abs(-2). X = 2. ?- X is min(-1,2*4+1). X = -1. ?- X is min(2*4+1,13). X = 9. ?- X is random(13). X = 8. ?- X is random(13). X = 5. ?- X is random(13). X = 11. ?- X is sqrt(10). X = 3.16228. ?- X is sin(2*pi/4). X = 1.0. ?- X is log(e). X = 1.0. ?- X is log(e**3). X = 3.0. ?- X is log10(1000000). X = 6.0.

3.7.

Conectivas

Las conectivas lgicas son las siguientes: o 1. la conjuncin; se representa poniendo , entre los objetivos (hechos), por ejemplo; o X, Y entrada(X), plato principal(Y), postre(Z) 10

Para satisfacer una secuencia de objetivos separados por comas, deben ser satisfechos uno detrs del otro de izquierda a derecha en el orden dado. La satisfaccin es a o buscada sobre trminos del universo del problema, segn la relaciones establecidas e u en la base de datos del mismo. Para satisfacer la secuencia, debern ser satisfechos a en un mismo objeto todos los objetivos conjuntados. Los trminos satisfactores e pueden ser uno, varios o ninguno. 2. la disyuncin; se representa poniendo ; entre los objetivos (hechos): o X; Y entrada(X); plato principal(Y); postre(Z) La disyuncin tendr xito cuando lo tenga alguno de los objetivos que la componen o ae en al menos un trmino. e 3. la negacin; se representa poniendo not o \+ sobre el objeto (hecho): o not(X) \+ X Tendr xito cuando, y slo cuando, el objetivo negado (X en el ejemplo) fracasa. ae o No es una verdadera negacin en el sentido lgico, sino una negacin por fallo o o o Son combinaciones proposicionales de trminos: e 1. !, fail 2. los trmino compuesto. e 3. (cpt 01, clt 02), siempre que cpt 01 y cpt 02 sean combinaciones proposicionales de trminos. e 4. (cpt 01; clt 02), siempre que cpt 01 y cpt 02 sean combinaciones proposicionales de trminos. e o e 5. not(cpt 01), siempre que cpt 01 sea una combinacin proposicional de trminos. En las combinaciones proposicionales de trminos pueden desaparecer los parntesis si e e ello no origina ambigedad debido a la precedencia. u

3.8.

Reglas

En Prolog las reglas tienen la siguiente estructura: cabeza_de_la_regla :- cuerpo_de_la_regla. En una regla, cabeza de la regla es un trmino (hecho) y puede ser el trmino vaco, es e e decir, puede faltar. cuerpo de la regla es una combinacin proposicional de trminos o e y no puede ser vac Muy frecuentemente el cuerpo de la regla es una conjuncin de a. o hechos, por ejemplo: comida(X, Y, Z) :- entrada(X), plato_principal(Y), postre(Z). 11

en cuyo caso cada conjunto de la conjuncin se denomina objetivo. En la lgica de primer o o orden, el objeto lgico equivalente a la regla de Prolog es el de una clusula. El ejemplo: o a p(X, Y) :- q(X,Z), q(Z,Y). ser equivalente a cualquiera de las siguientes frmulas equivalentes: a o xy(z(q(x, z) q(z, y)) p(x, y)) xy(z(q(x, z) q(z, y)) p(x, y)) xyz(q(x, z) q(z, y) p(x, y)) xyz(p(x, y) q(x, z) q(z, y)) xyz((q(x, z) q(z, y)) p(x, y)) En una regla, la cabeza describe el hecho que se intenta denir; el cuerpo describe los objetivos que deben ser satisfechos, como condicin suciente, para que la cabeza sea o satisfecha. Un mismo nombre de variable representa el mismo objeto siempre que aparece en la regla. As cuando X se instancia a algn objeto, todas las X de dicha regla tambin se instancian , u e a ese objeto; o mejor, cuando X se instancia a algn objeto, la instanciacin tiene efecto en u o todo el mbito de la variable cuanticada universalmente y dicho cuanticador universal a sobre esa variable desaparece temporalmente en el tanteo. Bien entendido, debemos saber que hechos y reglas comparten una misma naturaleza, a saber, son clusulas de la lgica de predicados. a o

3.9.

Comentarios

Si en programacin imperativa es importante comentar los programas, en programacin o o declarativa la necesidad se acentua. Para comentar un prrafo de Prolog lo incluimos a en un entorno /* */ de acuerdo con el siguiente patrn o /* Este es el prrafo que a queremos comentar para ilustrar el contenido del programa */ Pero si lo que queremos comentar es solamente un rengln, entonces lo hacemos preceder o por el s mbolo % % regln explicativo del programa o

4.

Programas

Confeccionar un programa en Prolog es establecer un universo nito de hechos y reglas, o si se quiere con ms precisin un universo nito de clusulas. Con ello se a o a proporciona un caldo primigenio que Prolog aprovecha para establecer inferencias. As pues, se declaran hechos sobre objetos y relaciones, se denen reglas sobre los mismos y se hacen preguntas sobre esos objetos y sus relaciones. Ejecutar un programa es, de hecho, demostrar un teorema que versa sobre el universo de objetos y relaciones. 12

Un sistema Prolog es una implementacin de un demostrador de teoremas por resoluo cin para clusulas de Horn. La estrategia de resolucin utilizada es un tipo de resolucin o a o o lineal y el mtodo de bsqueda est basado en la iniciativa primero en profundidad. El e u a orden de las clusulas en un programa importa, ya que determina el orden en que las a soluciones sern encontradas. Un determinado orden puede conducir a fallos en el proa grama mientras que otro no. Es de capital importancia el orden de las metas a alcanzar dentro del cuerpo de la reglas. Prolog considera la base de datos de cada programa como contraste de verdad, o sea, es cierta para l cada clusula que gure en la base de datos y falsa cualquier otra que no e a gure en ella. Prolog responde true cuando puede demostrar algo y false cuando no puede demostrarlo; por lo que debemos entender el false en el sentido de no puedo demostrarlo con lo que s. e Cuando se formula a Prolog una pregunta que incluye una variable, sta est iniciale a mente no instanciada. Inmediatamente se trata de instanciarla a trminos involucrados e en la base de datos de forma que empareje con la pregunta (algoritmo de unicacin). o Cuando encuentra un trmino, o juego de trminos, que emparejan, muestra por pantalla e e aquello a lo que estn instanciadas entonces las variables involucradas en la pregunta como a primera solucin del problema. Prolog queda entonces a la espera de instrucciones: o si pulsamos <enter>, cesa la bsqueda. u si pulsamos ; reanuda la bsqueda comenzando donde hab dejado la marca en un u a intento por resatisfacer los hechos de la pregunta. Ejemplo 4.1. Como ejemplo consideremos la siguiente base de datos que est contenida a en el chero u711.pl: 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). que a travs de nuestro SWI-Prolog nos proporciona el siguiente dilogo: e a ?- [u711.pl]. % u711.pl compiled 0.00 sec, 1,472 bytes true. 13

?- p(X). X = a ; X = a ; X = b ; X = d. ?- s(d). false. ?- u(d). true. ?- p(a), s(X). X = a ; X = b ; X = c ; X = a ; X = b ; X = c ; false. ?- u(X), s(X). false. ?- u(X), p(X). X = d. ?- u(X); s(X). X = d ; X = a ; X = b ; X = c. ?- not(p(X)). false. ?- not(p(a)). false. ?- not(u(a)). true. Ejemplo 4.2. Considerar el siguiente cdigo: o horoscopo(aries,21,3,21,4). horoscopo(tauro,21,4,21,5). horoscopo(geminis,21,5,21,6). 14

horoscopo(cancer,21,6,21,7). horoscopo(leo,21,7,21,8). horoscopo(virgo,21,8,21,9). horoscopo(libra,21,9,21,10). horoscopo(escorpio,21,10,21,11). horoscopo(sagitario,21,11,21,12). horoscopo(capricornio,21,12,21,1). horoscopo(acuario,21,1,21,2). horoscopo(piscis,21,2,21,3). signo(Dia,Mes,Signo) :- horoscopo(Signo,D1,M1,D2,M2), ((Mes = M1, Dia >= D1); (Mes=M2, Dia =< D2)). e interpretar las respuestas a las siguientes preguntas: ?- signo(8,5,tauro). ?- signo(7,8,acuario). ?- signo(7,8,Signo). ?- signo(7,X,Signo). ?- signo(X,7,Signo). La respuesta a: ?- signo(33,4,tauro). true es incorrecta. Cmo se podra reparar para que el comportamiento fuese el siguiente?: o ?- signo(33,4,tauro). false. Ejercicio 4.3. Hacer un programa para Prolog que en la base de datos contenga la supercie y el nmero de habitantes de las provincias andaluzas. El programa debe ser u capaz de responder correctamente cuando se le pregunte por la densidad de las diferentes provincias.

5.
5.1.

Estructuras de Datos
Arboles

La estructura ms conocida y usada en Prolog es la de rbol. Si dado un trmino a a e compuesto funtor(argumento1,...,argumentoN) consideremos funtor como un nodo de arbol y de l hacemos colgar los rboles corres e a pondientes a cada uno de los argumentos argumentok, con 1 k N , entonces hemos entendido el trmino compuesto como un arbol. e 15

5.2.

Listas

La programacin, y sobre todo en matemtica discreta, no puede prescindir del concepto o a de lista. Los miembros de las listas pueden ser trminos o listas. La lista queda denida de la e siguiente forma: [ ] es una lista, la lista vac a. .(miembro1,miembro2) es una lista siempre que miembro1 y miembro2 sean miembros de listas; en cuyo caso a miembro1 se le llama cabeza de la lista y a miembro2 se le llama cola de la lista. Ejemplo 5.1. .(a,[ ]) es una lista, la lista [a]. .(a,.(b,.(c,[ ]))) es una lista, la lista [a,b,c]. En general, si la lista L tiene cabeza X y cola Y, L es representada como [X|Y] Para manipular lista Prolog cuenta con diversos procedimientos entre los cuales tenemos: is list, append, member, delete, select, nth0, nth1, last, reverse, flatten, length, merge, sort, msort, etc. Ejemplo 5.2. miembro debe ser un procedimiento que compruebe si un determinado elemento pertenece a una lista. La idea sera, por ejemplo, que una solicitud a miembro de un club est entre las solicitudes al mismo si es la primera o est entre el resto. Cmo a a o expresar amos esto? 1. Primera idea: miembro(E,L) :- L=[X|Y], X=E. miembro(E,L) :- L=[X|Y], miembro(E,Y). 2. Segunda idea: miembro(E,[X|Y]) :- X=E. miembro(E,[X|Y]) :- miembro(E,Y). 3. Tercera idea: miembro(X,[X|Y]). miembro(E,[X|Y]) :- miembro(E,Y). 4. Cuarta idea: 16

miembro(X,[X|_]). miembro(E,[_|Y]) :- miembro(E,Y). Hemos de destacar los procedimientos de Prolog para ordenar listas, que tienen la siguiente sintaxis: msort(+Lista,-ListaOrdenada) sort(+Lista,-ListaOrdenada) y que funcionan como sugiere el siguiente dilogo: a ?- msort([a,t,v,a,m,f,g,l],L). L = [a, a, f, g, l, m, t, v]. ?- sort([a,t,v,a,m,f,g,l],L). L = [a, f, g, l, m, t, v]. ?- msort([a,1,0,[b,a]],L). L = [0, 1, a, [b, a]]. Para ilustrar el trabajo con listas damos los siguientes ejemplos: /* miembro(Elem,Lista) <- el trmino Elem pertenece a la lista Lista */ e miembro(X,[X|_]). miembro(X,[_|Y]) :- miembro(X,Y). /* nel(Lista,N) <- el nmero de elementos de la lista Lista es N */ u nel([],0). nel([_|Y],N) :- nel(Y,M), N is M+1. /* es_lista(Lista) <- Lista es una lista */ es_lista([]). es_lista([_|_]). /* concatena(L1,L2,L3) <- concatenacin de las listas L1 y L2 o dando lugar a la lista L3 */ concatena([],L,L). concatena([X|L1],L2,[X|L3]) :- concatena(L1,L2,L3). /* ultimo(Elem,Lista) <- Elem es el ultimo elemento de la lista Lista */ ultimo(X,[X]). ultimo(X,[_|Y]) :- ultimo(X,Y). /* inversa(Lista,Inver) <- Inver es la inversa de la lista Lista */ inversa([],[]). inversa([X|Y],L) :- inversa(Y,Z), concatena(Z,[X],L). 17

/* borrar(Elem,L1,L2) <- se borra el elemento Elem de la lista L1 obteniendose la lista L2 */ borrar(X,[X|Y],Y). borrar(X,[Z|L],[Z|M]) :- borrar(X,L,M). /* subconjunto(L1,L2) <- la lista L1 es un subconjunto de la lista L2 */ subconjunto([X|Y],Z) :- miembro(X,Z), subconjunto(Y,Z). subconjunto([],_). /* insertar(Elem,L1,L2) <- se inserta el elemento Elem en la lista L1 obteniendose la lista L2 */ insertar(E,L,[E|L]). insertar(E,[X|Y],[X|Z]) :- insertar(E,Y,Z). /* permutacion(L1,L2) <- la lista L2 es una permutacin de la lista L1 */ o permutacion([],[]). permutacion([X|Y],Z) :- permutacion(Y,L), insertar(X,L,Z). Ejercicio 5.3. Hacer los siguientes ejercicios: 1. Leer, comprobar el funcionamiento y familiarizarse con los procedimientos antes descritos. 2. Escribir un procedimiento zip que actue sobre dos listas produciendo una tercera cuyo i-simo elemento sea la lista con dos componentes formada por el i-simo de e e la primera, como primer elemento, y por el i-simo de la segunda, como segundo; e es decir, debe producir el siguiente dilogo: a ?- zip([1,2],[a,b,c],L). L = [[1, a], [2, b]] 3. Escribir un procedimiento que obtenga el elemento que ocupa la posicin n de una o lista o la posicin que ocupa el elemento e: o ?- elemento(E,3,[a,b,c,d]). E = c ?- elemento(c,N,[a,b,c,d]). N = 3 4. Modicar el procedimiento borrar para que borre el elemento que ocupa la posicin o n de la lista: ?- borrar(3,[a,b,c,d],L). L = [a,b,d] 18

5.3.

Coleccionando Soluciones.

Dada una Base de Concocimiento, para determinadas preguntas sobre ella puede haber varias respuestas. Considrese por ejemplo el siguiente cdigo: e o hijo(martha,charlotte). hijo(charlotte,caroline). hijo(caroline,laura). hijo(laura,rose). descendiente(X,Y) :- hijo(X,Y). descendiente(X,Y) :- hijo(X,Z), descendiente(Z,Y). que, una vez cargado, admite la siguiente pregunta: ?- descendiente(martha,X). X = charlotte ; X = caroline ; X = laura ; X = rose ; false. Es decir, hay cuatro soluciones, a saber: X=charlotte, X=caroline, X=laura y X=rose. Prolog aporta las soluciones a una pregunta una a una, no obstante puede interesar que nos las entregue todas juntas, de forma limpia y en un formato apto para ser usadas. Prolog dispone de tres predicados primitivos al efecto: findall, bagof y setof. En esencia, estos predicados recolectan las repuestas a una pregunta y las colocan en una lista; no obstante, hay importantes diferencias entre ellos. 5.3.1. findall/3

La sintaxis de findall es la siguiente: findall(+Objeto,+Objetivo,-Lista) y produce una lista Lista de objetos Objeto que satisfacen el objetivo Objetivo. Por ejemplo: ?- findall(X,descendiente(martha,X),Z). Z = [charlotte, caroline, laura, rose]. No obstante, Objeto no tiene por qu ser un s e mbolo de variable, puede contener un s mbolo de variable que est en el objetivo. Por ejemplo, hemos decidido construir un e predicado nuevo deMartha/1 que es verdadero slo para los descendientes de martha. Lo o llevamos a cabo con: ?- findall(deMartha(X),descendiente(martha,X),Z). Z = [deMartha(charlotte), deMartha(caroline), deMartha(laura), deMartha(rose)]. es decir, Z contiene todos los valores de deMartha(X) que satisfacen el objetivo descendiente(martha,X). 19

Un uso menor, de findall es el siguiente: ?- findall(Y,descendiente(martha,X),Z), length(Z,N). Z = [_G458, _G455, _G452, _G449], N = 4. en el que no nos interesaba tanto las soluciones como el nmero de ellas. u Finalmente obsrvese el siguiente dilogo: e a ?- findall(X,descendiente(mary,X),Z). Z = []. Ejercicio 5.4. Basndose en findall, escribir un predicado la lista de los primeros 8 a nmeros naturales. u 5.3.2. bagof/3

El predicado primitivo findall es util, pero a veces puede resultar algo crudo. Por ejemplo: ?- findall(Hijo,descendiente(Madre,Hijo),Lista). Lista = [charlotte,caroline,laura,rose,caroline, laura,rose,laura,rose,rose] Pero nos gustar tener una lista para cada una de las instancias de Madre. Esto es justo a lo que hace: bagof(Hijo,descendiente(Madre,Hijo),Lista) Vase lo siguiente: e ?- bagof(Hijo,descendiente(Madre,Hijo),Lista). Madre = caroline, Lista = [laura, rose] ; Madre = charlotte, Lista = [caroline, laura, rose] ; Madre = laura, Lista = [rose] ; Madre = martha, Lista = [charlotte, caroline, laura, rose]. Si queremos que bagof se comporte como findall, es posible: ?- bagof(Hijo,Madre^descend(Madre,Hijo),Lista). List = [charlotte, caroline, laura, rose, caroline, laura, rose,laura, rose,rose]. Hay una diferencia ms respecto a findall. Obsrvese el siguiente dilogo y comprese a e a a con el oportuno de findall: 20

?- bagof(X,descendiente(mary,X),Z). false. Es posible usar findall y bagof conjuntamente. Observar el siguiente dilogo: a ?- findall(List,bagof(Child,descendiente(Mother,Child),List),Z). Z = [[laura, rose], [caroline, laura, rose], [rose], [charlotte, caroline, laura, rose]]. Pero esto mismo es obtenido con: ?- bagof(List,Hijo^Madre^bagof(Hijo, descendiente(Madre,Hijo),List),Z). 5.3.3. setof/3

El predicado predenido setof/3 funciona como bagof, pero la lista resultado est ora denada y no contiene repeticiones. Considerar el sitguiente cdigo: o edad(harry,13). edad(draco,14). edad(ron,13). edad(hermione,13). edad(dumbledore,60). edad(hagrid,30). Si lo cargamos, podemos efectuar al siguiente consulta: ?- findall(X,edad(X,Y),Lista). Lista = [harry, draco, ron, hermione, dumbledore, hagrid]. ?- setof(X,Y^edad(X,Y),Lista). Lista = [draco, dumbledore, hagrid, harry, hermione, ron]. y an ms expl u a cito es el siguiente: ?- findall(Y,edad(X,Y),Lista). Lista = [13, 14, 13, 13, 60, 30]. ?- setof(Y,X ^ edad(X,Y),Lista). Lista = [13, 14, 30, 60].

5.4.

Conjuntos

Prolog implementa unos predicados para manipular conjuntos. Para SWIProlog los conjuntos son listas sin repeticiones. Destacamos los siguientes predicados: 21

is set(+Lista); tiene xito cuando Lista es un conjunto. e ?- is_set([1,2,3]). true. ?- is_set([1,2,3,3]). false. list to set(+Lista,-Conjunto): Conjunto es el conjunto de elementos de Lista. Por tanto, Lista y Conjunto coinciden si Lista no tiene repeticiones; pero si las tiene, Conjunto es Lista sin repeticiones. ?- list_to_set([1,3,3,2],X). X = [1, 3, 2]. ?- list_to_set([1,3,2],X). X = [1, 3, 2]. intersection(+Set1,+Set2,-Set3); Set3 es la interseccin de Set1 con Set2. o Prolog no comprueba si Set1 y Set2 son conjuntos, por lo que Set3 podr no a ser conjunto. ?- intersection([1,3,2],[3,4,5,2],X). X = [3, 2]. ?- intersection([1,3,2,2],[3,4,5,2],X). X = [3, 2, 2]. subtract(+Set,+Delete,-Result); elimina de Set todos los elementos del conjunto Delete. ?- subtract([1,2,3,3],[2],X). X = [1, 3, 3]. ?- subtract([1,2,3,3],[2,3],X). X = [1]. union(+Set1, +Set2, -Set3); Set3 es la unin de Set1 y Set2. o ?- union([1,2],[2,3],X). X = [1, 2, 3]. subset(+Subset, +Set): indaga si Subset es un subconjunto de Set. ?- subset([1],X). X = [1|_G598]. ?- subset([1],[1,2]). true. 22

Ejercicio 5.5. Redenir intersection en un nuevo predicado interseccion(+Set1,+Set2,-Set3) tal que si Set1 o Set2 no son conjuntos, Set3 s lo sea. Extender esta accin al resto de o predicados antes enumerados para los que quepa. Ejercicio 5.6. El predicado subset presenta el siguiente comportamiento: ?- subset(X,[1,2,3]). X = []. Cmo podramos mejorarlo? o

5.5.

La estructura de los trminos e

En Prolog un programa puede ser visto como una estructura. Para manejar las estructuras tenemos esencialmente los siguientes predicados: functor arg =.. name que tiene la utilidad que se explica seguidamente. 5.5.1. functor

La sintaxis de functor es: functor(estructura,nombre,ariedad) donde estructura es una estructura con nombre nombre y ariedad ariedad. Para ver su manejo consideremos el siguiente dilogo: a ?- functor(f(a,b),F,A). F = f, A = 2. ?- functor(coche,F,A). F = coche, A = 0. ?- functor(1+2,F,A). F = +, A = 2. ?- functor([1,2,3],F,A). F = ., A = 2. 23

?- functor(L,libro,2). L = libro(_G286, _G287). ?- functor(1+2+3,+,2). true. ?- functor(1+2+3,+,3). false. Ejercicio 5.7. Utilizar functor para decidir cuando un trmino dado es compuesto. e 5.5.2. arg

La sintaxis de arg es: arg(?Posicion,?Estructura,?Argumento) donde el argumento de la Estructura que ocupa la posicin Posicion es Argumento. o Para ver su manejo consideremos el siguiente dilogo: a ?- arg(2,ama(vicente,logica),X). X = logica. ?- arg(2,ama(vicente,X),logica). X = logica. ?- arg(2,es_feliz(roberta),X). false. ?- arg(1,[a,b,c],Arg). Arg = a. ?- arg(1,p(x,f(y)),Arg). Arg = x. ?- arg(2,p(x,f(y)),Arg). Arg = f(y). 5.5.3. =..

La sintaxis de =.. es: ?Estructura =.. ?Lista donde si Estructura es instanciada, Lista ser una lista cuya primera componente (caa beza) es el functor de Estructura y el resto (cola) los distintos argumentos de dicha estructura. Si Lista est instanciada, crear una Estructura cuyo functor ser la cabea a a za de la lista y cuyos argumentos sern los distintos elementos de la lista. Para ver su a manejo consideremos el siguiente dilogo: a 24

?- p(x,f(y),z) =.. L. L = [p, x, f(y), z]. ?- E =.. [+,2,3]. E = 2+3. Ejercicio 5.8. Defnase un predicado llamado copy term el cual haga una copia de un trmino reemplazando las variables que ocurran en el trmino original por nuevas e e variables en la copia. Solucin. copy_term(X,_) :- var(X). o copy_term(X,X) :- atomic(X). copy_term(X,Y) :- nonvar(X), functor(X,F,A), functor(Y,F,A), A > 0, X =.. [F|ArgsX], Y =.. [F|ArgsY], copy_terms_in_list(ArgsX,ArgsY). copy_terms_in_list([],[]). copy_terms_in_list([HIn|TIn],[HOut|TOut]) :- copy_term(HIn,Hout), copy_terms_in_list(TIn,TOut). 5.5.4. name

La sintaxis de name es: name(?Atomo,?Lista) donde si Atomo es un tomo formado por los caracteres de la lista Lista. Puede tana to crear un atomo con los caracteres de la lista como crear una lista de los caracteres correspondientes al tomo. Para ver su manejo consideremos el siguiente dilogo: a a ?- name(prolog,L). L = [112, 114, 111, 108, 111, 103]. ?- name(Atomo,[112, 114, 111, 108, 111, 103]). Atomo = prolog. ?- name(estacion,"estacion"). true.

6.

Recursos de Control en la Programacin o


25

Destacamos las siguientes herramientas:

1. Recursin (recursion) o 2. Unicacin (unication, matching) o 3. Reevaluacin (backtracking) o 4. Corte (cut)

6.1.

Recursin (recursion) o

En el apartado que hemos llamado Listas (subseccin 5.2) hemos visto como las reglas o denitorias inclu en su cuerpo el mismo trmino trmino que aparec en su cabeza. an e e a Esta prctica es de extrema utilidad en programacin si no cae en el clsico problema a o a de la peticin de principio. Para ello, uno de los argumentos de la denicin en la o o llamada recursiva debe decrecer o crecer, para poder unicar en determinado paso con una clusula que ha sido establecida a modo de condicin de parada. a o Ejemplo 6.1. Consideremos la denicin: o nel([],0). nel([_|Y],N) :- nel(Y,M), N is M+1. que es un ejemplo de denicin recursiva. En ella la condicin de parada es o o nel([],0). y la clusula que hace evolucionar los parmetros es: a a nel([_|Y],N) :- nel(Y,M), N is M+1. El ujo del programa para nel([a,[b,c],d],N) en resumen sera: 1. nel([a,[b,c],d],N) (comienzan las llamadas recursivas) 2. nel([[b,c],d],M1) (la lista decrece en longitud) 3. nel([d],M2) 4. nel([],M3) (actua la condicin de detencin) o o 5. M3=0 (comienza el clculo en retroceso) a 6. M2=M3+1=0+1=1 7. M1=M2+1=1+1=2 8. N=M1+1=2+1=3 9. N=3 (concluye con el resultado) Si se quiere se puede pedir a Prolog un informe del ujo del programa: 26

?- trace, nel([a,[b,c],d],N), notrace. Call: (7) nel([a, [b, c], d], _G726) ? creep Call: (8) nel([[b, c], d], _G893) ? creep Call: (9) nel([d], _G893) ? creep Call: (10) nel([], _G893) ? creep Exit: (10) nel([], 0) ? creep ^ Call: (10) _G898 is 0+1 ? creep ^ Exit: (10) 1 is 0+1 ? creep Exit: (9) nel([d], 1) ? creep ^ Call: (9) _G901 is 1+1 ? creep ^ Exit: (9) 2 is 1+1 ? creep Exit: (8) nel([[b, c], d], 2) ? creep ^ Call: (8) _G726 is 2+1 ? creep ^ Exit: (8) 3 is 2+1 ? creep Exit: (7) nel([a, [b, c], d], 3) ? creep N = 3. o tambin: e ?- trace(nel). % nel/2: [call,redo,exit,fail] true. [debug] T Call: T Call: T Call: T Call: T Exit: T Exit: T Exit: T Exit: N = 3. ?- nel([a,[b,c],d],N). (6) nel([a, [b, c], d], _G1180) (7) nel([[b, c], d], _G1288) (8) nel([d], _G1288) (9) nel([], _G1288) (9) nel([], 0) (8) nel([d], 1) (7) nel([[b, c], d], 2) (6) nel([a, [b, c], d], 3)

Los dos grandes errores en el planteamiento de una recursin son: o 1. la recursin circular con la que se entra en un bucle que no termina nunca. Es lo o que tradicionamente ha recibido en nombre de peticin de principio. Por ejemplo: o padre(X,Y) :- hijo(Y,X). hijo(A,B):- padre(B,A). 2. y la llamada recursin a izquierdas que esencialmente supone la denicin indeo o nida porque s Por ejemplo: . persona(X) :- persona(Y), madre(X,Y). persona(adam). 27

Ejemplo 6.2. Como ejemplo correcto traemos ahora el clsico y bello ejemplo de la a solucin a las Torres de Hanoi. El programa torres hanoi.pl contiene el siguiente texto: o mover(1,X,_,Z) :write(Mueva el disco superior de ), write(X), write( a ), write(Z), nl. mover(N,X,Y,Z) :N>1, M is N-1, mover(M,X,Z,Y), mover(1,X,_,Z), mover(M,Y,X,Z). torres_hanoi(N) :- mover(N,izq,cen,der). donde aparece: 1. Una condicin de parada siempre satisfacible dado que presupone un trabajo como puesto de impresin por pantalla. o 2. Una llamada recursiva con disminucin del parmetro inicial, de forma que alguna o a vez llegue a valer 1. 3. Una simplicacin de la llamada. o Ejercicio 6.3. Dar una implementacin que simule los nmeros naturales y denir, o u dentro de esa simulacin, la suma y el producto. o

6.2.

Unicacin (unication, matching) o

La unicacin constituye uno de los mecanismos esenciales de Prolog junto a la reo solucin, sin ambos ser imposible extraer respuestas. Cuando se desencadena es para o a instanciar variables de forma que dos trminos coincidan tras dicha instanciacin. Si los e o trminos t1 y t2 son unicables, Prolog encuentra una sustitucin de variables M tal que e o aplicada M a t1 da el mismo resultado que aplicada a t2. Si no son unicables, Prolog lo pone de maniesto. El algoritmo que usa es en esencia el clsico algoritmo de unicacin a o visto en teor Tener en cuenta el siguiente dilogo: a. a ?- p(X,f(Y),a) = p(a,f(a),Y). X = a, Y = a. ?- p(X,f(Y),a) = p(a,f(b),Y). false. 28

?- p(X,f(Y),a) = p(Z,f(b),a). X = Z, Y = b. ?- p(X,f(Y),a) = p(Z,f(b),a), X is 1. X = 1, Y = b, Z = 1. ?- p(X,f(Y),a) = p(Z,f(b),a), X=d. X = d, Y = b, Z = d. Cuando una varible deba ser instanciada a un trmino que la contiene, la unicacin falla, e o como sabemos. Nos es de ayuda en este caso el procedimiento binario: unify with occurs check. Considerar lo siguiente: ?- X=f(X). X = f(**). ?- unify_with_occurs_check(X,f(X)). false. ?- X=f(X), X=a. false. a no puede ser unicada con f(X): ?- a \= f(X). true.

6.3.

Reevaluacin (backtracking) o

La reevaluacin consiste en revisar lo hecho para intentar extraer una respuesta altero nativa resatisfaciendo los objetivos. Cuando Prolog acaba de dar una respuesta, la reevaluacin se desencadena escribiendo y ejecutando ;. Cmo busca Prolog respueso o tas?: Trata de satisfacer objetivos buscando en la base de conocimiento: si existe un hecho que pueda unicar con el objetivo, marca el lugar en la base de conocimientos e instancia todas las variables que coincidan previamente no instanciadas. Si el hecho es la cabeza de una regla con cuerpo, intenta satisfacer los objetivos del cuerpo de la regla. si no encuentra ningn hecho que unique, el objetivo ha fallado e intenta u resatisfacer el objetivo anterior.

29

Resatisfacer consiste en intentar resatisfacer cada uno de los objetivos del cuerpo de la regla por orden inverso. Para ello intenta encontrar una clusula alternativa para a el objetivo, en cuyo caso, se dejan sin instanciar todas las variables instanciadas al elegir la clusula previa. La bsqueda es retomada desde donde se hab dejado el a u a marcardor de posicin de objetivo. o Ejemplo 6.4. Considerar el programa digestion.pl: acaba_de_comer(mosquito,sangre(pedro)). acaba_de_comer(mosquito,nectar). acaba_de_comer(mosquito,savia). acaba_de_comer(pez,mosquito). acaba_de_comer(serpiente,pez). acaba_de_comer(oso,pez). acaba_de_comer(aguila,serpiente). acaba_de_comer(rana,mosquito). acaba_de_comer(garza,rana). acaba_de_comer(aguila,perdiz). acaba_de_comer(perdiz,trigo). esta_digiriendo(X,Y) :- acaba_de_comer(X,Y); acaba_de_comer(X,Z), esta_digiriendo(Z,Y). que cargado en el entorno nos permitira: ?- [digestion.pl]. % digestion.pl compiled 0.00 sec, 148 bytes true. ?- esta_digiriendo(X,Y). Anal cese la extensa respuesta.

6.4.

Corte (cut)

El trmino corte de Prolog, representado por !, elimina opciones en un rbol de derie a vacin Prolog. El objetivo corte tiene xito cada vez que es considerado como objetivo o e actual, y el rbol de derivacin resulta podado de todas las otras opciones en el camino a o de regreso, incluyendo el punto en el arbol de derivacin en el que se introdujo el corte o como parte de la secuencia de objetivos. El corte se satisface incondicionalmente, pero no se puede resatisfacer. El corte se convierte en un impedimento que impide al proceso de reevaluacin el franqueo del camino de vuelta hacia atrs, convirtiendo en inaccesibles o a todos los marcadores de las metas que se encuentran a su izquierda. Si se quiere, se puede imaginar como una vlvula que permite el paso en un sentido del ujo del programa, a pero que lo impide en el contrario.

30

El corte es una intervencin en la forma automtica de aplicar recursin, unicacin y o a o o reevaluacin de Prolog, que sesga la misma. Optimiza el tiempo de ejecucin, no malo o gastando el tiempo en satisfacer objetivos que de antemano sabemos que no contribuirn a a una solucin. Optimiza el uso de la memoria no registrando puntos de reevaluacin o o para un examen posterior. Aunque cabe que haga dif la comprensin de un programa, cil o su uso puede ser la diferencia entre que un programa funcione o que no funcione. En n, el corte es imprescindible en la programacin con Prolog. o Ejercicio 6.5. Considerar el programa que fuera: sumatorio(1,1) :- !. sumatorio(N,S) :- N1 is N-1, sumatorio(N1,S1), S is N+S1. y decir qu ocurrira si en lugar de la primera lnea, tuvisemos simplemente sumatorio(1,1). e e

7.

Usos del Corte


Conrmacin o Advertencia Finalizacin o

Vamos a destacar tres usos del corte:

7.1.

Conrmacin o

Con el corte podemos conrmar al ujo de Prolog de que si ha franqueado el corte, sigue la regla correcta. Si las metas siguientes fracasan, deber fracasar el objetivo. Podemos a ejemplicar este uso en una simulacin del if-then-else clsico en programacin. Para o a o ello, considerar el texto: a :- b,!,c. a :- d. que expresado en una forma ineciente (puede acabar intentando satisfacer b dos veces) pero ms clara, ser a a a :- b,c. a :- not(b),d. Como ejemplo de este uso nos vale tambin el programa correcto que gura en el Ejercicio e 6.5. Ejercicio 7.1. Hacer un programa en Prolog que dada una lista de nmero enteros, u suprima de ella los nmeros impares. u

31

7.2.

Advertencia

Usando el corte en combinacin con el predicado de fallo fail podemos dar cuenta de o que el hecho ha de fracasar sin intentar encontrar soluciones alternativas. fail siempre fracasa como objetivo. Considrese el siguiente programa no.pl en el que se dene la e negacin por fallo; es realmente la denicin Prolog de not: o o no(Q) :- call(Q), !, fail. no(Q). Explicaremos posteriormente el signicado de call, pero adelantamos que call(P) fuerza a que P sea un objetivo; tiene xito si lo tiene P y fracasa en otro caso. De hecho, lo que e hacemos en P es tomar a P como una varible de trmino. e

7.3.

Finalizacin o

Podemos usar el corte para informar a Prolog que deseamos nalizar la generacin de soo luciones alternativas mediante reevaluacin. Considrese el siguiente programa divisionEntera.pl: o e /* natural(Num) <- Num es un nmero perteneciente a los Naturales */ u natural(0). natural(X) :- natural(Y), X is Y+1. /* diventera(Dividendo,Divisor,Cociente) <- Cociente es el resultado de la divisin entera entre Dividendo y Divisor o */ diventera(A,B,C) :- natural(C), Y1 is C*B, Y2 is (C+1)*B, Y1=<A, Y2>A, !. Que es un generador de nmeros naturales hasta encontrar un valor de C que cumpla la u condicin: o B*C =<A <B*(C+1) siendo A el dividendo y B el divisor de la divisin. La regla natural va generando o innitos nmeros naturales, pero slo uno de ellos es el que nos interesa y ser el que u o a pase la condicin. As el corte al nal de la regla impide que en un posible proceso de o , reevaluacin entremos en un bucle innito: hemos encontrado la unica solucin y no hay o o ninguna razn para volver a buscar otra. o Ejercicio 7.2. Encontrar en qu falla la siguiente denicin de mximo: e o a max_mal(X,Y,Y) :- Y>X. max_mal(X,Y,X). y arreglarla. Justicar por qu es ineciente la siguiente versin: e o max_ineficiente(X,Y,Y) :- Y>X. max_ineficiente(X,Y,X) :- not(Y>X). 32

Ejercicio 7.3. Considerar el programa pruebaCorte.pl p(e). 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). Efectuar en pruebaCorte.pl los siguientes cambios e interpretar los resultados de pedir a Prolog la pregunta p(X).: con el programa tal cual. sustituyendo la lnea segunda por p(X) :- !, q(X), r(X). sustituyendo la lnea segunda por p(X) :- q(X),! , r(X). sustituyendo la lnea segunda por p(X) :- q(X), r(X), !. cambiando las lneas 2 y 3 por las siguientes respectivamente: p(X) :- u(X). p(X) :- !,q(X),r(X). cambiando las lneas 1, 2 y 3 por las siguientes respectivamente: p(e) :- !. p(X) :- q(X),r(X). p(X) :- u(X).

7.4.

Efectos indeseados, pero tolerables, del corte

Mientras que un corte puede ser inofensivo, o incluso benecioso, cuando se utiliza una regla de una forma dada, el mismo corte puede provocar un comportamiento extrao si la n regla se utiliza de otra forma. Considerar el programa discusionCorte.pl que contiene: /* concatena(L1,L2,L3) <- concatenacin de las listas L1 y L2 o dando lugar a la lista L3 */ concatena([],L,L) :- !. concatena([X|L1],L2,[X|L3]) :- concatena(L1,L2,L3). 33

Cuando se consideran objetivos de la forma: ?- [discusionCorte.pl]. % discusionCorte.pl compiled 0.00 sec, 5,736 bytes true. ?- concatena([a,b,c],[d,e],X). X = [a, b, c, d, e]. ?- concatena([a,b,c],X,[a, b, c, d, e]). X = [d, e]. el corte resulta muy adecuado, pero si tenemos el objetivo: ?- concatena(X,Y,[a,b,c]). X = [], Y = [a, b, c]. no ofrece todas las soluciones posibles. Por tanto, la introduccin del corte debe contar, en todo caso, con el uso que se va a o hacer de la regla.

7.5.

Predicados de control

Existen unos predicados predenidos que ayudan cuando queremos utilizar estructuras de control. Por ejemplo: fail, siempre falla. true, siempre tiene xito. e repeat, permite simular bucles junto con la combinacin cortefail. Considrese el o e siguiente ejemplo: /*-----------------------------------------------------------*/ /* PROGRAMA PRINCIPAL */ /* */ menu :- cabecera, repeat, leer(Formula), hacer(Formula). hacer(X) :- integer(X), X=0. hacer(A) :- cabecera, ayuda, !, fail. hacer(a) :- cabecera, ayuda, !, fail. 34

hacer(Formula) :- fbf(Formula), formaNormal(Formula,FNC,FND), escribirFormasNormales(FNC,FND), pausa,!, fail. hacer(_) :- pausa,!,fail.

/* */ /* Fin Programa Principal */ /* */ /*-----------------------------------------------------------*/ +Condicion ->+Accion, permite simular la estructura condicional: si-entonces y si-entonces-sino rojo(a). negro(b). clr(Y,rojo) :- rojo(Y),!. clr(Y,negro) :- negro(Y),!. clr(Y,desconocido). % "color_alt" tiene el mismo efecto que "clr" % "->" simula el uso de "!" color_alt(X,C) :- red(X) -> C = red ; black(X) -> C = black ; C = unknown.

7.6.

Otros ejemplos

Presentamos ejemplos de uso del corte en programas. /* borrar(Elem,L1,L2) <- L2 es la lista resultado de borrar todas las ocurrencias del elemento Elem de la lista L1 */ borrar(_,[],[]). borrar(E,[E|L1],L2) :- !,borrar(E,L1,L2). borrar(E,[A|L1],[A|L2]) :- borrar(E,L1,L2). /* sust(E1,E2,L1,L2) <- L2 es la lista resultado de sustituir en la lista L1 todas las ocurrencias del elemento E1 por E2 */ sust(_,_,[],[]). sust(E1,E2,[E1|L1],[E2|L2]) :- !, sust(E1,E2,L1,L2). sust(E1,E2,[Y|L1],[Y|L2]) :- sust(E1,E2,L1,L2). 35

/* union(L1,L2,L3) <- L3 es ls lista-conjunto unin de las o listas-conjuntos L1 y L2 */ union([],L,L). union([X|L1],L2,L3) :- miembro(X,L2), !, union(L1,L2,L3). union([X|L1],L2,[X|L3]) :- union(L1,L2,L3).

8.

La I/O en Prolog

Si se desea una mayor interaccin de Prolog con el usuario que la mera presentacin o o por pantalla de los resultados a nuestras preguntas, por unicacin entre las mismas y la o base clausular del programa, es preciso recurrir a otro tipo de predicados. Se trata de los predicados Entrada/Salida, que cumplen por coherencia lo siguiente: Se evalan siempre a verdad. u Nunca se pueden resatisfacer: la reevaluacin contina hacia la izquierda. o u Tiene un efecto lateral, no lgico, durante su ejecucin: entrada o salida de un o o carcter, trmino, etc. a e

8.1.

Lectura y escritura de trminos e


write(+Termino); si Termino est instanciado a un trmino, lo saca por pantalla. a e En caso contrario, se sacar por pantalla una variable numerada de forma unica a (por ejemplo: G245). nl; la salida posterior se presenta en la siguiente l nea de la pantalla. write ln(+Termino); es equivalente a write(+Termino), nl writef(+Formato,+Termino); escritura con formato. tab(+X); desplaza el cursor a la derecha X espacios, para ello X debe estar instanciada a un entero (una expresin evaluada como un entero positivo). o sisplay(+Termino); se comporta como write(+Termino), excepto que pasa por alto cualquier declaracin de operadores que se haya hecho. o read(-Termino); lee el siguiente trmino que se teclee desde el ordenador. Debe ir e seguido de un punto . y un retorno de carro. Instancia Termino al trmino le e do, si Termino no estaba instanciada. En caso contrario, los compara y se satisfar o a fracasar dependiendo del xito de la comparacin. a e o

Destacamos lo siguiente:

Ejemplo 8.1. Considrese el chero io ejemplo.pl que contiene lo siguiente: e

36

/* ibl(L) <- imprime la lista L de forma bonita, es decir saca por pantalla los elementos de la lista separados por un espacio y terminado en salto de lnea */ ibl([]) :- nl. ibl([X|Y]) :- write(X), tab(1), ibl(Y). /* escribe_cadena(L) <- escribe en pantalla la lista L de cdigos ASCII en forma de cadena de o caracteres */ escribe_cadena([]). escribe_cadena([X|Y]) :- put(X), escribe_cadena(Y). Que presenta el siguiente comportamiento: ?- [io_ejemplo.pl]. % io_ejemplo.pl compiled 0.00 sec, 1,084 bytes true. ?- write(8+5*6),nl,display(8+5*6). 8+5*6 +(8,*(5,6)) true. ?- write(8+5*6), nl, display(8+5*6). 8+5*6 +(8,*(5,6)) true. ?- X=[esto,es,una,lista], write(X), nl, display(X), nl, ibl(X). [esto,es,una,lista] .(esto,.(es,.(una,.(lista,[])))) esto es una lista X = [esto, es, una, lista]. ?- writef(Atomo = %w\nNmero = %w\n,[pepe,4.5]). u Atomo = pepe Nmero = 4.5 u true.

8.2.

Lectura y escritura de caracteres

Prolog trata los caracteres como enteros, hacindoles corresponder su cdigo ASCII. e o Considrese lo siguiente: e 37

put(+Caracter); si Caracter est instanciada a un entero entre 0 y 255, saca por a pantalla el carcter correspondiente a ese cdigo ASCII. Si Caracter no est insa o a tanciada o no es entero, proporciona error. get(-Caracter); lee caracteres desde el teclado, instanciando Caracter al primer carcter imprimible que se teclee. Si Caracter ya est instanciada, los compara a a satisfacindose o fracasando. e get0(-Caracter); igual que get(-Caracter) sin importar el tipo de carcter tea cleado. skip(+Caracter); lee del teclado hasta el carcter Caracter o el nal del chero. a Ejemplo 8.2. Considrese el siguiente cdigo includo en el chero io ejemplo.pl: e o /* escribe_cadena(L) <- escribe en pantalla la lista L de cdigos ASCII en forma de cadena de o caracteres */ escribe_cadena([]). escribe_cadena([X|Y]) :- put(X), escribe_cadena(Y). que proporciona el siguiente dilogo: a ?- [io_ejemplo.pl]. % io_ejemplo.pl compiled 0.00 sec, 1,084 bytes true. ?- escribe_cadena([80,114,111,108,111,103]). Prolog true. ?- put(80),put(114),put(111),put(108),put(111),put(103). Prolog true.

8.3.

Lectura y escritura en cheros

Existe un chero predenido llamado user. Al leer de este chero se hace que al informacin de entrada venga desde el teclado, y al escribir, se hace que los caracteres aparezcan o en al pantalla; este es el modo normal de funcionamiento. Pero pueden ser escritos trmie nos y caracteres sobre cheros utilizando los mismos predicados que se acaban de ver. la unica diferencia es que cuando queramos escribir o leer en un chero debemos cambiar el canal de salida activo o el canal de entrada activo, respectivamente. Posiblemente queramos leer y escribir sobre cheros almacenados en discos. Cada uno de estos tendr un nombre de chero que utilizaremos para identicarlo. En Prolog a los nombres de cheros se representan como atomos. Los cheros tienen una longitud determinada, es decir, contienen un cierto nmero de caracteres. Al nal del chero hay u 38

una marca especial de n de chero. Cuando la entrada viene del teclado, puede generarse un n de chero tecleando el carcter de control ASCII 26 o Ctrl+Z. Se pueden tener a abiertos varios cheros, si conmutamos el canal de salida activo sin cerrarlos (told), permitindonos escribir sobre ellos en varios momentos diferentes, sin destruir lo escrito e previamente. Destacamos lo siguiente: tell(+NomFichero); si NomFichero est instanciada al nombre de un chero, cama bia el canal de salida activo. Crea un nuevo chero con ese nombre. Si NomFichero no est instanciada o no es un nombre de chero, producir un error. a a telling(?NomFichero); si NomFichero no est instanciada, la instanciar al noma a bre del chero que es el canal de salida activo. En caso contrario, se satisface si es el nombre del chero actual de salida. told; cierra el chero para escritura y dirige la salida hacia la pantalla. see(+NomFichero); si NomFichero est instanciada al nombre de un chero, cambia a el canal de entrada activo al chero especicado. La primera vez que se satisface, el chero pasa a estar abierto y empezamos al comienzo del chero. Si NomFichero no est instanciada o no es un nombre de chero, producir un error. a a seeing(?NomFichero); si NomFichero no est instanciada, la instanciar al nombre a a del chero que es el canal de entrada activo. En caso contrario, se satisface si es el nombre del chero actual de entrada. seen; cierra el chero para lectura y dirige la entrada hacia el teclado. Ejemplo 8.3. /* secuencia normal de escritura */ ... , tell(fichero), write(X), told, ... /* conmutacin de ficheros */ o ... , tell(fichero), write(A), tell(user), write(B), tell(fichero), write(C), told. /* secuencia normal de lectura */ ... , see(fichero), read(X), seen, ...

9.

Modicacin de la Base de Conocimiento o

Presentaremos una serie de predicados predenidos en Prolog que nos permitirn mania pular la Base de Conocimiento consultando, aadiendo, eliminando o modicando clusun a las.

39

9.1.

Adicin de Bases de Conocimiento externas o

Si queremos que Prolog lea nuevas clusulas de un chero que hemos preparado prea viamente, podemos utilizar los predicados consult y reconsult. Esto ser conveniente a cuando tengamos que trabajar con programas de tamao considerable y no queramos n teclear cada vez todas las clusulas. As podremos crear el programa con nuestro editor a , de textos preferidos (sugerimos el uso de Emacs) para posteriores usos, con la ventaja aadida de que lo podremos modicar y ampliar en cualquier momento. n Destacamos lo siguiente: consult(+Fichero); el predicado predeninido consult aade las clusulas exisn a tentes en el chero de nombre Fichero a la base de conocimiento de Prolog, al nal de las ya existentes, sin destruir las anteriores. Como argumento pasamos un atomo con el nombre del chero del que queremos leer las clusulas. Recordemos a que un atomo est formado por letras, d a gitos y el carcter de subrayado. Si quea remos que contenga otros caracteres (los dos puntos : para la unidad, la barra / para el directorio o el punto . para la extensin1 deberemos encerrarlo entre o comillas simples. reconsult(+Fichero); el predicado predenido reconsult acta como consult u excepto que, de existir clusulas para un mismo predicado (nombre y ariedad), las a nuevas sustituyen a las existentes.2 Se suele utilizar para la correccin de errores o mientras se est realizando el programa, ya que de esta manera la nueva versin a o sustituye a la anterior errnea. Tambin es interesante cuando queremos asegurar o e que se utilizan las clusulas que vamos a leer, y no otras posibles con el mismo a nombre que tuviese el sistema de alguna consulta anterior. La mayor parte de las implementaciones permiten una notacin especial para consultar o una lista de cheros, uno tras otro: la notacin en forma de lista. Consiste en poner o los nombres de los cheros en una lista y darla como objetivo a satisfacer. Si se quiere consultar un chero, se pone el nombre en la lista tal cual, mientras que si se quiere reconsultar se pone el nombre precedido de un signo -. A modo de ejemplo considrese: e ?- consult(fichero). ?- reconsult(fichero). ?- [fichero1, -fichero2, -prueba, /home/usuario/prueba]. ?- consult(practica1.pro). ?- reconsult(/home/usuario/practica1.pl). ?- [/home/usuario/prueba.pl].
SWI-Prolog asume por defecto la extesin .pl y Prolog2 toma la extensin .pro. Pero o o esto depender del sistema Prolog utilizado y se puede personalizar. a 2 SWI-Prolog no tiene un predicado reconsult ya que al consultar un chero ya almacenado, automticamente es reconsultado. a
1

40

?- [-/home/usuario/prueba.pl].

9.2.

Manipulacin de la Base de Conocimiento o

A veces es muy conveniente enriquecer la Base de Conocimiento con nuevas clusulas, a incluso resultado de alguna computacin. A tal n existen en Prolog predicados predeo nidos, entre los que destacamos los siguientes: listing; escribe todas las clusulas de la Base de Conocimiento en el chero de a salida activo. listing(+Predicado); muestra por el chero de salida activo (pantalla por defecto) todas las clusulas que tienen como predicado el tomo al que est instanciada a a a a variable Predicado. clause(?Cabeza,?Cuerpo); se hace coincidir Cabeza con la cabeza y Cuerpo con el cuerpo de una clusula existente en la Base de Conocimiento. Por lo menso Cabeza a debe estar instanciada. Un hecho es considerado como una clusula cuyo cuerpo es a true. assert(+Clausula), asserta(+Clausula), assertz(+Clausula); estos predicados permiten aadir nuevas clusulas a la Base de Conocimiento. El predicado n a asserta la aade al principio (observar la letra a) y assertz la aade al nal n n (observar la letra z) de cualquier otra clusula del mismo tipo que hubiese en la a Base de Conocimiento. En todos los casos, Clausula debe estar previamente instanciada a una clusula. Dicha clusula queda incorporada a la Base de Conocimiento a a y no se pierde aunque se haga reevaluacin. Como ejemplo considerar el siguiente o dilogo: a ?- asignatura(X). ERROR: toplevel: Undefined procedure: asignatura/1 (DWIM could not correct goal) ?- assert(asignatura(logica_informatica)). true. ?- asserta(asignatura(flp)). true. ?- assertz(asignatura(lmd)). true. ?- asignatura(X). X = flp ; X = logica_informatica ; X = lmd. retract(+Clausula), retractall(+Clausula); nos permite eliminar una clusua la de la Base de Conocimiento. Para ello, Clausula debe estar instanciada y se 41

quitar la primera clusula de la Base de Conocimiento que empareje con ella. Si se a a resatisface el objetivo, se irn eliminando, sucesivamente, las clusulas que coincia a dan. Con retractall se eliminarn todas. Como ejemplo, considrese el siguiente: a e ?- listing(asignatura). :- dynamic asignatura/1. asignatura(flp). asignatura(logica_informatica). asignatura(lmd). true. ?- retract(asignatura(lmd)). true. ?- listing(asignatura). :- dynamic asignatura/1. asignatura(flp). asignatura(logica_informatica). true. ?- retract(asignatura(X)). X = flp . ?- listing(asignatura). :- dynamic asignatura/1. asignatura(logica_informatica). true. abolish(+Predicado/Ariedad), abolish(+Predicado,+Ariedad); retira de la Base de Conocimiento todas las clusulas del predicado Predicado. Debe estar idena ticado completamente el predicado: nombre y ariedad. Considerar el siguiente dilogo: a ?- listing(asignatura). :- dynamic asignatura/1. asignatura(logica_matematica). asignatura(flp). asignatura(lmd). :- dynamic asignatura/2. 42

asignatura(logica_matematica, primero). asignatura(flp, segundo). asignatura(lmd, tercero). true. ?- abolish(asignatura/1). true. ?- listing(asignatura). :- dynamic asignatura/2. asignatura(logica_matematica, primero). asignatura(flp, segundo). asignatura(lmd, tercero). true. ?- abolish(asignatura,2). true. ?- listing(asignatura). ERROR: toplevel: procedure asignatura does not exist (DWIM could not correct goal)

10.

Depuracin de Programas Prolog o

Prolog contiene una serie de predicados predenidos para supervisar el funcionamiento de los programas durante su ejecucin. Ellos nos permitirn la depuracin y correccin o a o o de los mismos, pues hay errores dif ciles de detectar. Los errores en programacin son de o naturaleza sintctica, fciles de detectar y corregir, o de naturaleza semntica, que slo a a a o puedenn ser descubiertos revisando el planteamiento o siguiendo el proceso de inferencia paso a paso. Es en ese ultimo punto donde entra en juego el contenido de esta seccin. o Tengamos en cuenta los siguiente: Call; se intenta satisfacer dicho predicado Exit; el predicado ha tenido xito y se ha satisfecho e Fail; el objetivo ha fracasado Redo; se intenta resatisfacer el objetivo al haber fracasado un predicado posterior Destacamos lo siguiente:

43

trace, trace(+Predicado); activa el seguimiento exhaustivo de la traza de ejecucin del as metas posteriores a la consecucin de este objetivo o del predicado o o Predicado, viendo los distintos objetivos que intenta satisfacer y el resultado de esta accin. A partir de la consecucin de este objetivo, hay una interaccin entre o o o el programador y la mquina Prolog, pidindonos que conrmemos cada paso. a e Podemos utilizar las siguientes opciones del modo traza: <return>, <espacio> (avanzar ); continua con la traza. a (abort); retorna a Prolog. b (break ); inicia un nuevo nivel de Prolog. c (continue); contina con la traza. u e (exit); abandona el sistema Prolog. f (fail ); hace fallar a ese objetivo. g (goal stack ); muestra la pila de objetivos cumplidos hasta el objetivo actual. i (ignore); ignora el objetivo actual, como si se hubiera cumplido. l (leap); realiza la pausa slo en los puntos esp o a. n (nodebug); contina ejecucin en modo no debug. u o r (retry); reintenta satisfacer el objetivo. s (skip); salta el modo interactivo hasta que se cumple o falla ese objetivo. notrace, notrace(+Objetivo); su efecto es el inverso del predicado anterior, es decir, desactiva la traza. Con el argumento Objetivo, intenta satisfacer el objetivo desactivando la traza mientras dure su ejecucin. o spy(+Predicado); ja un punto esp en el predicado Predicado para poder seguir a su funcionamiento. Predicado debe ser: un atomo: se ponen puntos esp en todos los predicados con ese tomo, inde a a pendientemente del nmero de argumentos que tenga. u una estructura (functor/ariedad): slo establecer puntos esp en aquellos o a a predicados con dicho functor y nmero de argumentos. u una lista: situar puntos esp en todos los lugares especicados por cada uno a a de los elementos de la lista. Ejemplos: ????spy(iniciar). spy(iniciar/0). spy(iniciar/1). spy([iniciar,pertenece]).

nospy(+Predicado), nospyall; elimina los puntos esp especicados en Predicado a (determinado de manera anloga a la referida en el punto anterior) o retira los puna tos esp activos en ese momento. a 44

debugging; permite ver una lista con los puntos esp que se han establecido hasta a el momento. Como ejemplo: ?- debugging. There are spypoints set on : iniciar/0 iniciar/1 pertenece/2 debug, nodebug; inicializa y naliza el depurador.

A.

Predicados Predenidos

Hacemos relacin de algunos predicados predenidos en Prolog. o 1. Adicin de Bases de Conocimiento externas: o consult(X); aadir las clusulas del chero X a la base de conocimiento n a reconsult(Y); las clusulas le a das de chero Y sustituyen a las existentes para el mismo predicado. [X,-Y,Z]; notacin ms cmoda para consult y reconsult o a o halt; salir del sistema Prolog 2. Construccin de objetivos compuestos (conectivas lgicas): o o X,Y; conjuncin de objetivos o X;Y; disyuncin de objetivos o \+ X; se cumple si fracasa el intento de satisfacer X not(X); se cumple si fracasa el intento de satisfacer X 3. Clasicacin de trminos: o e var(X); se cumple si X es en ese momento una variable no instanciada nonvar(X); se cumple si X no es una variable sin instanciar en ese momento atomic(X); se cumple si X representa en ese momento un nmero o un atomo u atom(X); se cumple si X representa en ese momento un atomo de Prolog numeric(X); se cumple si X representa en ese momento un nmero u integer(X); se cumple si X representa en ese momento un nmero entero u real(X); se cumple si X representa en ese momento un nmero real u 4. Control del programa: true; objetivo que siempre se cumple fail; objetivo que siempre fracasa 45

!; corte. Fuerza al sistema Prolog a mantener ciertas elecciones repeat; sirve para generar soluciones mltiples mediante el mecanismo de u reevaluacin o X ->Y; si X entonces Y. En combinacin con ; acta como Si-Entonces- Sino. o u call(X); se cumple si tiene xito el intento de satisfacer X (instanciada a un e trmino) e 5. Operadores artimticos y relacionales: e X=Y; se cumple si puede hacer X e Y iguales (unicarlos) X\=Y; se cumple si X=Y fracasa X==Y; igualdad ms estricta a X\==Y; se cumple si fracasa == X<Y; predicado menor que X>Y; predicado mayor que X>=Y; predicado mayor o igual que X=<Y; predicado menor o igual que X@<Y; ordenacin de trminos. Predicado menor que o e X@>Y; ordenacin de trminos. Predicado mayor que o e X@>= Y; ordenacin de trminos. Predicado mayor o igual que o e X@=<Y; ordenacin de trminos. Predicado menor o igual que o e X is Y; se evala la expresin a la que est instanciada Y para dar como u o a resultado un nmero, que se intentar hacer coincidir con X u a X is string Y; se evala la expresin a la que est instanciada Y para dar u o a como resultado una cadena, que se intentar hacer coincidir con X a X & Y; operador concatenacin de cadenas de caracteres o X + Y; operador suma X - Y; operador resta X * Y; operador de multiplicacin o X / Y; operador de divisin o X // Y; operador de divisin entera o X mod Y; operador de resto de la divisin entera o X ** Y; operador de exponenciacin o X ^ Y; operador de exponenciacin o op(X,Y,Z); declara el operador de nombre Z con clase de precedencia X y posicin-asociatividad Y. o current op(X,Y,Z); busca el operador ya declarado de nombre Z con clase de precedencia X y posicin-asociatividad Y. o 46

6. Funciones aritmticas: e abs(X); devuelve el valor absoluto de la expresin X. o sign(X); devuelve -1 si X <0, 1 si X >0 y 0 si X = 0 min(X,Y); devuelve el menor de X e Y max(X,Y); devuelve el mayor de X e Y random(X); devuelve un entero aleatorio i ( 0 =<i <X ); la semilla es determinada por el reloj del sistema cuando se arranca SWI-Prolog between(M,N,X); X toma los valores enteros comprendidos entre M y N round(X); evalua la expresin X y la redondea al entero ms cercano o a integer(X); evalua la expresin X y tiene xito si el resultado es entero o e float(X); evalua la expresin X en un nmero en coma otante o u truncate(X); trunca la expresin X en un nmero entero o u floor(X); devuleve el mayor nmero entero menor o igual que el resultado de u la expresin X o ceiling(X); devuleve el menor nmero entero mayor o igual que el resultado u de la expresin X o sqrt(X); ra cuadrada de la expresin X z o sin(X); seno de la expresin X (ngulo en radianes) o a cos(X); coseno de la expresin X (ngulo en radianes) o a tan(X); tangente de la expresin X (ngulo en radianes) o a asin(X); arcoseno (ngulo en radianes) de la expresin X a o acos(X); arcocoseno (ngulo en radianes) de la expresin X a o atan(X); arcotangente (ngulo en radianes) de la expresin X a o log(X); logaritmo neperiano de la expresin X o log10(X); logaritmo en base 10 de la expresin X o exp(X); e elevado al resultado de la expresin X o pi; constante matemtica (3.141593) a e; constante matemtica e (2.718282) a 7. Manejo de listas: [X|Y]; X es la cabeza e Y la cola de la lista is list(X); se cumple si X es una lista o la lista vac [] a append(X,Y,Z); Z es la concatenacin de las listas X e Y o member(X,Y); X es uno de los elementos de la lista Y delete(X,Y,Z); borra el elemento Y de la lista X y da como resultado la lista Z 47

select(X,Y,Z); selecciona el elemento X de la lista Y y da como resultado la lista Z nth0(X,Y,Z); el elemento X-simo de la lista Y es Z (empezando en 0) e nth1(X,Y,Z); el elemento X-simo de la lista Y es Z (empezando en 1) e last(X,Y); X es el ultimo elemento de la lista Y reverse(X,Y); Y es la lista invertida de X length(X,Y); Y es la longitud de la lista X merge(X,Y,Z); siendo X e Y listas ordenadas, Z es la lista ordenada con los elementos de mbas a sort(X,Y); Y es la lista ordenada de X (sin elementos duplicados) msort(X,Y); Y es la lista ordenada de X findall(X,Y,Z); Z es la lista de objetos X que satisfacen Y findall(X,Y,Z); Z es la lista de objetos X que satisfacen Y bagof/3; consultar ayuda (?- help(bagof).). setof/3; consultar ayuda (?- help(setof).). 8. Predicados de Entrada/Salida: get0(X); se cumple si X puede hacerse corresponder con el siguiente carcter a encontrado en el canal de entrada activo (en cdigo ASCII) o get(X); xe cumple si X puede hacerse corresponder con el siguiente carcter a imprimible encontrado en el canal de entrada activo skip(X); lee y pasa por alto todos los caracteres del canal de entrada activo hasta que encuentra un carcter que coincida con X a read(X); lee el siguiente trmino del canal de entrada activo e put(X); escribe el entero X como un carcter en el canal de salida activo a nl; genera una nueva l nea en el canal de salida activo tab(X); escribe X espacios en el canal de salida activo write(X); escribe el trmino X en el canal de salida activo e write ln(X); escribe el trmino X en el canal de salida activo y salta la l e nea writef(X,Y); escribe en el canal de salida activo, siendo X el formato e Y la lista con los argumentos a escribir display(X); escribe el trmino X en el canal de salida activo, pasando por alto e las declaraciones de operadores 9. Manejo de cheros: see(X); abre el chero X y lo dene como canal de entrada activo seeing(X); se cumple si el nombre del canal de entrada activo coincide con X seen; cierra el canal de entrada activo, y retorna al teclado 48

tell(X); abre el chero X y lo dene como canal de salida activo telling(X); se cumple si X coincide con el nombre del canal de salida activo told; cierra con un n de chero el canal de salida activo, que pasa a ser la pantalla 10. Maninpulacin de la Base de Conocimiento: o listing; se escriben en el chero de salida activo todas las clusulas a listing(X); siendo X un atomo, se escriben en el chero de salida activo todas las clusulas que tienen como predicado dicho tomo a a clause(X,Y); se hace coincidir X con la cabeza e Y con el cuerpo de una clusula existente en la base de conocimiento a assert(X); permite aadir la nueva clusula X a la base de conocimiento n a asserta(X); permite aadir la nueva clusula X al principio de la base de n a conocimiento assertz(X); permite aadir la nueva clusula X al nal de la base de conocin a miento retract(X); permite eliminar la primera clusula de la base de conocimiento a que empareje con X retractall(X); permite eliminar todas las clusulas de la base de conocimiena to que emparejen con X abolish(X); retira de la Base de Conocimiento todas las clusulas del predia cado X abolish(X,Y); retira de la Base de Conocimiento todas las clusulas del prea dicado de nombre X y nmero de argumentos Y u 11. Construccin y acceso a componentes de estructuras: o functor(E,F,N); E es una estructura con nombre F y nmero de argumentos u N arg(N,E,A); el argumento nmero N de la estructura E es A u E=..L; predicado univ. L es la lista cuya cabeza es el functor de la estructura E y la cola sus argumentos name(A,L); los caracteres del atomo A tienen por ASCII los nmeros de la lista u L 12. Depuracin de programas Prolog: o trace; activacin de un seguimiento exhaustivo, generando la traza de la ejeo cucin de las metas siguientes o trace(X); activacin de un seguimiento del predicado X o notrace; desactiva el seguimiento exhaustivo notrace(X); desactiva el seguimiento mientras dure la llamada al objetivo X 49

spy(X); jacin de puntos esp en el predicado X o a nospy(X); elimina los puntos esp especicados a nospyall; elimina todos los puntos esp a debugging; ver el estado del depurador y los puntos esp se han establecido a hasta el momento debug; inicia el depurador nodebug; desactiva el depurador

B.

Notacin comparativa entre Lgica y Prolog o o


Prolog A :- N1 , . . . , Nm A. ?- N1 , . . . , Nm

frmula o clusula de Horn a (A N1 Nm ) regla {A, N1 , . . . , Nm } ((N1 Nm ) A) hecho (A) {A} (N1 Nm ) objetivo {N1 , . . . , Nm } (N1 Nm )

frmula o program. lgica o (A N1 Nm ) regla A N1 , . . . , Nm ((N1 Nm ) A) hecho (A) A (N1 Nm ) objetivo N1 , . . . , Nm (N1 Nm )

50