Manual Casero Prolog Beta 02

March 23, 2018 | Author: Adán Kevin Martín Rodriguez | Category: Division (Mathematics), Mathematics, Computing And Information Technology, Science, Software


Comments



Description

Prolog(Sin,Esfuerzo) :- en 44 minutos(Sin), y 15 segundos(Esfuerzo).francisco miguel garc´ olmedo ıa ´ Departamento de Algebra Universidad de Granada 18071 Granada, Espa˜a n 22 de mayo de 2011 ´ Indice 1. Introducci´n o 2. Utilizar Prolog 3. Sintaxis ´ 3.1. Atomos . . . . . . . 3.2. N´meros . . . . . . . u 3.3. Variables . . . . . . . 3.4. T´rminos compuestos e 3.5. Operadores . . . . . 3.6. Funciones aritm´ticas 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 t´rminos 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 Programaci´n o 6.1. Recursi´n (recursion) . . . . . . . . . . . o 6.2. Unificaci´n (unification, matching) . . . o 6.3. Reevaluaci´n (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. Confirmaci´n . . . . . . . . . . . . . . . . . o 7.2. Advertencia . . . . . . . . . . . . . . . . . . 7.3. Finalizaci´n . . . . . . . . . . . . . . . . . . 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 t´rminos . . . . . . . . . . . . . . . . . . . . . . . e 8.2. Lectura y escritura de caracteres . . . . . . . . . . . . . . . . . . . . . . . 8.3. Lectura y escritura en ficheros . . . . . . . . . . . . . . . . . . . . . . . . 9. Modificaci´n de la Base de Conocimiento o 9.1. Adici´n de Bases de Conocimiento externas . . . . . . . . . . . . . . . . o 9.2. Manipulaci´n de la Base de Conocimiento . . . . . . . . . . . . . . . . . o 10.Depuraci´n de Programas Prolog o A. Predicados Predefinidos B. Notaci´n comparativa entre L´gica y Prolog o o ´ Indice de figuras 1. 2. 3. Ejemplos de atomos, n´meros y variables. . . . . . . . . . . . . . . . . . ´ u Operadores aritm´ticos y relacionales predefinidos en SWI-Prolog. . . . . e Definici´n infija, prefija o sufija de un operador. . . . . . . . . . . . . . . o 6 7 8 1. Introducci´n o Prolog (proviene de “Programmation en Logique”) fue creado por Alain Colmerauer y sus colaboradores alrededor de 1970 en la Universidad de Marseille–Aix, 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 te´rico, mieno tras que los trabajos de Colmerauer dieron origen al actual lenguaje de programaci´n, o construyendo el primer int´rprete de Prolog. e 2 El lenguaje Prolog juega un importante papel dentro de la Inteligencia Artificial; de hecho se propuso como el lenguaje nativo de las m´quinas de la quinta generaci´n, que a o se quer´ que fueran Sistemas de Procesamiento de Conocimiento. ıa Prolog es un lenguaje de programaci´n para ordenadores que se basa en el lenguaje de o la L´gica 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 programaci´n l´gica es o o que se especifica qu´ se tiene que hacer (programaci´n declarativa) y no c´mo se debe e o o hacer (programaci´n imperativa). o Los presentes notas son una reformulaci´n y adaptaci´n muy cercana al documento orio o ginal de los profesores Castel y Llorens. Estos autores han compuesto una introducci´n o magn´ ıfica a Prolog: es concisa, eficaz, clara, ilustrada y correcta. Despu´s de leerla, ya e podemos ir a por los manuales y libros. 2. Utilizar Prolog En un sistema Linux lo m´s 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 instalaci´n 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 instalaci´n desde o la informaci´n que brinda la p´gina oficial de SWI-Prolog. o a http://www.swi-prolog.org/ y mejor a´n, su p´gina de descargas: u a http://www.swi-prolog.org/download/stable Recomendamos editar los ficheros .pl con Emacs, un editor polivalente con licencia GNU que est´ disponible en todas las plataformas. Se trata de un cl´sico 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 instalaci´n de Emacs se lleva a cabo o como sigue: sudo apt-get install emacs emacs23-el prolog-el Con el propio Emacs editaremos un fichero .emacs en nuestro directorio ra´ e incluireız mos en ´l el siguiente texto: e 3 (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 ficheros .pl ı Si nuestro sistema es Mac OS X podemos bajar de: http://aquamacs.org/download.shtml el fichero de instalaci´n de Aquamacs, que actualmente es Aquamacs-Emacs-2.2.dmg. o Se trata de la mejor implementaci´n que conocemos de Emacs. Con Aquamacs no es o necesario completar la instalaci´n para que el editor se adecue a los ficheros .pl, pues o esto viene hecho por defecto. Si nuestro sistema es Windows, la instalaci´n de Emacs viene detallada en uno de los o puntos del famoso blog: http://instalaremacsenwindows7.blogspot.com/ Aunque el blog habla de la instalaci´n en Windows 7, nosotros la hemos probado tamo bi´n en Windows Vista y funciona. Con peque˜as modificaciones tambi´n vale esta e n e informaci´n para Windows XP, si es que a´n disfrutamos de ´l. No olvidar incluir en o u e el .emacs que el muchachillo dice de crear, el texto de adaptaci´n antes mencionado; o aqu´ s´ que es necesario. ı ı Con nuestro editor escribir´ ıamos un fichero .pl, que por ejemplo y por hacer honor a la costumbre, podr´ ser el fichero 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 int´rprete de Prolog que nos permite escribir tras el “prompt” e habitual de la marca: ?´ Esta es una sesi´n 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´ facil´n, no!? ¿pero . . . tan f´cil?. 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 finalizar con punto “.” antes de pulsar intro. Cuando queramos dejar el entorno int´rprete haremos: e ?- halt. Y ahora . . . ¡adelante! 3. Sintaxis En la programaci´n de Prolog usaremos t´rminos que son de las siguientes clases: o e ´ 1. Atomos. 2. N´meros. u 3. Variables. 4. T´rminos compuestos. e Adem´s incluimos en esta lecci´n 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 may´culas, min´sculas, d´ u u ıgitos y el car´cter de subrayado; debe comenzar por una letra min´scula. Ejemplos: don eladio guardiola, a u mantequilla y puerta2. 2. Cualquier cadena de caracteres encerrada entre comillas simples. Ejemplos: ’El Gimp’, ’ ’ y tambi´n ’^& %#$& *’ e 5 .3. y :Para saber si ciertas secuencias de caracteres son atomo tenemos atom(?Secuencia). u Son las inc´gnitas de los problemas y est´n destinadas a representar objetos cualesquiera o a del universo del problema. empiezan con letras may´sculas o con el signo de subrayado ( ). por ejemplo: @=. n´meros y variables. decimales con signo en coma flotante consistentes en al menos un d´ ıgito..2E-3 Figura 1: Ejemplos de atomos.2 Dividendo primero 1. ´tomos a a don vito corleone ’Anibal Lecter’ b52 n´ meros u variables 4 X -1. 4. 223 − o 1] = [−8388608. Las conectivas relacionadas en la secci´n Conectivas. Las estructuras tienen o e la siguiente sintaxis: funtor(argumento1. enteros. Para saber si ciertas secuencias de caracteres son variable tenemos var(?Secuencia) y nonvar(?Secuencia).2.2E+3 resto 1. Todos los operadores. N´ meros u Los n´meros son de dos tipos: u 1. Tiene un valor especial la variable an´nima. hechos y predicado. 2.. puede estar ı. en la implementaci´n de Prolog-2 los enteros son los del intervalo [−223 . . 8388607]. Variables En cuanto a las variables. las variables an´nimas no est´n compartidas o a entre s´ Una variable est´ instanciada si representa a un valor concreto.. ´ u 3. o 5. Ciertas cadenas de caracteres especiales.argumentoN) 6 .3. reales. en particular los relacionados en la secci´n Operadores y o otros. que representa un o valor desconocido cuya identidad no interesa.4. opcionalmente un punto decimal seguido de la parte decimal. Cabe la notaci´n o cient´ ıfica siguiendo a la letra may´scula “E” u 3. ´ 3. a instancia o no. ====>. estructura. T´rminos compuestos e Son sin´nimos t´rmino compuesto. 3))). pero nosotros escribimos a 11 is 2 + 3 * 3. 7 .autores(Clocksin.11 is 2+3*3. true.Mellish). El manejo de esos operadores ha sido “dulcificado” respecto a lo que es la representaci´n interna o de Prolog.prolog) libro(programacion en Prolog. Aqu´ encontramos un primer detalle a subrayar: se ha hecho un uso ı infijo permitido del operador *. Consid´rese el u e siguiente di´logo: a ?. e Prolog incorpora convenios para evitar ambig¨edad en las expresiones. e ı e 3.donde funtor es un atomo y argumentok. operadores signo positivo signo negativo potencia producto divisi´n o divisi´n entera o resto divisi´n entera o suma resta igualdad distinto menor que menor o igual que mayor que mayor o igual que evaluaci´n aritm´tica o e s´ ımbolos precendencia especificador + 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 aritm´ticos y relacionales predefinidos en SWI-Prolog. infijo o sufijo seg´n u lo que indica la tabla de la Figura 3.+(2. ?. con 1 ≤ k ≤ N . es t´rmino. Internamete Prolog usar´ is(11.5. Sabemos que un operador es prefijo.1981) Admitimos el t´rmino vac´o como t´rmino.*(3. false. Ejemplos: ´ e mujer(clara) ama(X. Operadores Encontramos predefinidos en Prolog los operadores de la tabla de la Figura 2.15 is 2+3*3. *(3. fy xf.Esto se explica en funci´n de la precedencia. 8 op( op( op( op( op( . xfx.2 + 3 + 4 = +(2. a a car´cter a infijo prefijo sufijo especificador xfx. =:=. -]). que indica que + es un ´ operador infijo. Tipo es un ´tomo que especifica el tipo y la a asociatividad del operador. yf Figura 3: Definici´n infija. 1100. f representa al operador. xfy. La precedencia de =.3)). la de + es 500 y la de * es 400. 700.]). \==.+(2. [ :-. prefija o sufija de un operador. :. 1000.+(2. 1200. M´s a´n. yfx.*(3. o Prolog permite al programador definir sus propios operadores. =\=.3))). =<. =.2 + 3 + 4 = +(+(2. As´ ı: ?.. true.4). yfx fx. >.3))). xfx. [ . Algunos ejemplos reales son: :::::1200. x quiere significar 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 +. es decir. false ?..op(Precedencia. xfy. ello hace o que la representaci´n interna de 2+3*3 sea +(2.op( 500. En el caso de + este atomo es yf x. N´mero u m´s alto indica precedencia m´s alta. Tipo. false. ]). que es mayor para + que para *.3). xfy. fx. [ +. ?. donde Precedencia es un n´mero entre 0 y 1200. ?. La sintaxis de esta operaci´n es: o :.2 is 7-3-2. + es el operador m´s o a externo. porque la precedencia de is es superior a la de +. <. [ :-.+(3. x e y los argumentos. [ ’. >= ]).’ ]). por ejemplo.*(3. y no como is(11.6 is 7-3-2. --> ]). [ =. ==.4)). true ?. De forma similar 11 is 2+3*3 es interpretada como is(11. is. u es 700. Nombre). % endulzar. [ mod ]). a o una notaci´n real suya es dulce(cafe).op( 200. xfx. 1.6 is 7-3-2. Adem´s hemos dotado a Prolog de una base o a de datos para decidir sobre la cuesti´n cafe es dulce.2+2 \== 4. considerar que hemos editado el fichero endulzar.cafe es_dulce. es_dulce(X) :. true. obs´rvese tambi´n el siguiente di´logo: e e a ?. No obstante. Numero puede ser una variable o una constante num´rica. El predicado u u o e de evaluaci´n es el operador infijo is: o -Numero is +Expresion donde Expresion es un t´rmino que se interpreta como una expresi´n aritm´tica. o 9 .X is 7-3-2. false. con e o e todos sus valores instanciados. fx. :.cafe). e ?. X = 2. false.]). . ?. true. Ahora tiene sentido el siguiente di´logo: a ?. xfy.00 sec.op(500.X).pl con el siguiente contenido: :. true. Los operadores no hacen que se efet´e ning´n tipo de operaci´n aritm´tica. ?.[’endulzar. cafe es dulce.op( 300.endulza(_.:. [ +. Acabamos de indicar a Prolog como traducir una notaci´n informal. Como ejemplo.pl compiled 0.es_dulce).op( 500. :. ?. endulza(azucar. [ ^ ]).pl’].2+2 \= 4.xf.2+2 =\= 4. ?.432 bytes true. X = 9.X is sin(2*pi/4). X = 2. ?.6. Y entrada(X). Como ejemplo de utilizaci´n tenemos el siguiente di´logo: o a ?.13). X = 1.X is log10(1000000). round. Conectivas Las conectivas l´gicas son las siguientes: o 1. cos.0. ?. o X.0.0. ?.X is random(13).16228.2*4+1). 3.X is abs(-2). exp.X is log(e). X = 11. min. integer. postre(Z) 10 . random. float. sig. ?. Funciones aritm´ticas e Prolog incorpora ciertas funciones aritm´ticas entre las que destacamos: abs.0. por ejemplo. X = 6. ?. ?. sqrt. ?. X = 8. log10.” entre los objetivos (hechos). X = 3.3. plato principal(Y).X is min(-1. X = 1. tan.X is sqrt(10).7. log. se representa poniendo “. etc.X is random(13).X is min(2*4+1. e max. X = 5. X = -1. sin.X is log(e**3). ?. la conjunci´n.X is random(13). ?. X = 3. ?. Los t´rminos satisfactores e pueden ser uno. siempre que cpt 01 y cpt 02 sean combinaciones proposicionales de t´rminos. seg´n la relaciones establecidas e u en la base de datos del mismo. postre(Z) La disyunci´n tendr´ ´xito cuando lo tenga alguno de los objetivos que la componen o ae en al menos un t´rmino. e 3. sino una negaci´n “por fallo” o o o Son combinaciones proposicionales de t´rminos: e 1.cuerpo_de_la_regla. plato_principal(Y). varios o ninguno. se representa poniendo “. 11 . el objetivo negado (X en el ejemplo) fracasa. (cpt 01.Para satisfacer una secuencia de objetivos separados por comas. En una regla.entrada(X). los t´rmino compuesto. e 4. por ejemplo: comida(X. postre(Z). e 3. (cpt 01. clt 02). 2. Reglas En Prolog las reglas tienen la siguiente estructura: cabeza_de_la_regla :. siempre que cpt 01 y cpt 02 sean combinaciones proposicionales de t´rminos. deber´n ser satisfechos a en un mismo objeto todos los objetivos conjuntados. cuerpo de la regla es una combinaci´n proposicional de t´rminos o e y no puede ser vac´ Muy frecuentemente el cuerpo de la regla es una conjunci´n de ıa. ae o No es una verdadera negaci´n en el sentido l´gico. es e e ı decir. fail 2. !. plato principal(Y). siempre que cpt 01 sea una combinaci´n proposicional de t´rminos. Z) :. cabeza de la regla es un t´rmino (hecho) y puede ser el t´rmino vac´o. Para satisfacer la secuencia. u 3. la disyunci´n. e o e 5. y s´lo cuando. En las combinaciones proposicionales de t´rminos pueden desaparecer los par´ntesis si e e ello no origina ambig¨edad debido a la precedencia. la negaci´n. o hechos. deben ser satisfechos uno detr´s del otro de izquierda a derecha en el orden dado. clt 02). not(cpt 01).8. se representa poniendo “not” o “\+” sobre el objeto (hecho): o not(X) \+ X Tendr´ ´xito cuando. La satisfacci´n es a o buscada sobre t´rminos del universo del problema. Y. Y entrada(X). puede faltar.” entre los objetivos (hechos): o X. Con ello se a o a proporciona un “caldo primigenio” que Prolog aprovecha para establecer inferencias. z) ∧ q(z. u e a ese objeto. z) ∧ q(z. y)) → p(x. de hecho. Comentarios Si en programaci´n imperativa es importante comentar los programas. y) ∨ p(x. Ejecutar un programa es. y)) ∨ p(x.Y). debemos saber que hechos y reglas comparten una misma naturaleza. en programaci´n o o declarativa la necesidad se acentua. a saber. a o 3. como condici´n suficiente. En la l´gica de primer o o orden. entonces lo hacemos preceder o por el s´ ımbolo “ %” % regl´n explicativo del programa o 4. y)) ∀x∀y∀z(¬q(x. el cuerpo describe los objetivos que deben ser satisfechos. y) ∨ ¬q(x. se declaran hechos sobre objetos y relaciones. z) ∨ ¬q(z. Un mismo nombre de variable representa el mismo objeto siempre que aparece en la regla. todas las X de dicha regla tambi´n se instancian ı. As´ pues. o mejor. El ejemplo: o a p(X. q(Z.9. 12 . y)) ∀x∀y∀z((q(x. la instanciaci´n tiene efecto en u o todo el ´mbito de la variable cuantificada universalmente y dicho cuantificador universal a sobre esa variable desaparece temporalmente en el tanteo. As´ cuando X se instancia a alg´n objeto. demostrar un teorema que versa sobre el universo de objetos y relaciones. y)) En una regla. o si se quiere —con m´s precisi´n— un universo finito de cl´usulas. ser´ equivalente a cualquiera de las siguientes f´rmulas equivalentes: ıa o ∀x∀y(∃z(q(x. y)) → p(x. para que la cabeza sea o satisfecha.Z). cuando X se instancia a alg´n objeto. son cl´usulas de la l´gica de predicados. la cabeza describe el hecho que se intenta definir.en cuyo caso cada conjunto de la conjunci´n se denomina objetivo. Programas Confeccionar un programa en Prolog es establecer un universo finito de hechos y reglas. el objeto l´gico equivalente a la regla de Prolog es el de una cl´usula. z) ∨ ¬q(z.q(X. Bien entendido. y)) ∀x∀y∀z(p(x. se definen reglas sobre los mismos ı y se hacen preguntas sobre esos objetos y sus relaciones. Y) :. Para comentar un p´rrafo de Prolog lo incluimos a en un entorno “/* */” de acuerdo con el siguiente patr´n o /* Este es el p´rrafo que a queremos comentar para ilustrar el contenido del programa */ Pero si lo que queremos comentar es solamente un rengl´n. y)) ∀x∀y(¬∃z(q(x. z) ∧ q(z. 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´”. p(X) :. r(a).[’u711.s(X). reanuda la b´squeda comenzando donde hab´ dejado la marca en un u ıa intento por resatisfacer los hechos de la pregunta. r(X). La estrategia de resoluci´n utilizada es un tipo de resoluci´n o a o o lineal y el m´todo de b´squeda est´ basado en la iniciativa primero en profundidad.u(X).00 sec. cesa la b´squeda. Como ejemplo consideremos la siguiente base de datos que est´ contenida a en el fichero u711.pl’]. p(X) :. o Cuando encuentra un t´rmino. s(c).pl compiled 0. u(d). o sea. Prolog considera la base de datos de cada programa como “contraste de verdad”. es cierta para ´l cada cl´usula que figure en la base de datos y falsa cualquier otra que no e a figure en ella.472 bytes true. Prolog queda entonces a la espera de instrucciones: o si pulsamos <enter>. muestra por pantalla e e aquello a lo que est´n instanciadas entonces las variables involucradas en la pregunta como a primera soluci´n del problema. s(b). % u711. que a trav´s de nuestro SWI-Prolog nos proporciona el siguiente di´logo: e a ?. 1. Un determinado orden puede conducir a fallos en el proa grama mientras que otro no. El e u a orden de las cl´usulas en un programa importa. ´sta est´ iniciale a mente no instanciada. r(b). 13 . Inmediatamente se trata de instanciarla a t´rminos involucrados e en la base de datos de forma que empareje con la pregunta (algoritmo de unificaci´n). Ejemplo 4.1. e Cuando se formula a Prolog una pregunta que incluye una variable. ya que determina el orden en que las a soluciones ser´n encontradas. u si pulsamos .q(X). Es de capital importancia el orden de las metas a alcanzar dentro del cuerpo de la reglas. que emparejan. q(X) :. o juego de t´rminos. s(a).Un sistema Prolog es una implementaci´n de un demostrador de teoremas por resoluo ci´n para cl´usulas de Horn.pl: p(a). ?. horoscopo(tauro. false. horoscopo(geminis. ?. X = b .3.21.s(d).6). false. X = b . X = a . X = a . X = d.5).u(X).not(p(X)). false. ?. Considerar el siguiente c´digo: o horoscopo(aries. 14 . Ejemplo 4. X = c. false. false.21. X = d . s(X).4. ?. ?. X = a . X = b .21.not(p(a)).p(X). p(X). true. X = a .4).?.u(X).5. ?. X = c . s(X). ?.p(a). s(X). ?.not(u(a)). X = d. true. X = b .u(X). X = a . ?.21.21.2.21. X = c .u(d). signo(7.11. Estructuras de Datos ´ Arboles La estructura m´s conocida y usada en Prolog es la de ´rbol.4. 5.21. ?.21.M1..21.7.21. signo(Dia.8. ((Mes = M1.21.21.Signo).21. ?.D1.21.horoscopo(cancer.9. ?..tauro). El programa debe ser u capaz de responder correctamente cuando se le pregunte por la densidad de las diferentes provincias. horoscopo(sagitario.6.21.signo(7. Dia >= D1).9).tauro).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.acuario). ?.21.. La respuesta a: ?.21.horoscopo(Signo.Mes. e interpretar las respuestas a las siguientes preguntas: ?.3.8.M2). ¿C´mo se podr´a reparar para que el comportamiento fuese el siguiente?: o ı ?.12). horoscopo(leo.Signo).21. horoscopo(escorpio.10).5. (Mes=M2. con 1 ≤ k ≤ N . horoscopo(piscis. horoscopo(libra.1).3). false.8). horoscopo(acuario.1. entonces hemos entendido el t´rmino compuesto como un arbol.Signo) :. true es incorrecta.signo(33.7). e ´ 15 .21. Ejercicio 4.Signo).tauro).21.signo(X.21.21. Si dado un t´rmino a a e compuesto funtor(argumento1. Dia =< D2)).11). 5.10.8.12.1.7.D2. Hacer un programa para Prolog que en la base de datos contenga la superficie y el n´mero de habitantes de las provincias andaluzas.2.signo(7.signo(8. horoscopo(virgo.2). horoscopo(capricornio.signo(33..4.X.21.21. [X|Y]) :. la lista [a].2.(c. Listas La programaci´n.(a. X=E. sort. 3.[X|Y]) :. member. la lista vac´ ıa.(b. select. Primera idea: miembro(E. . etc.L) :. La idea ser´a. nth1. miembro(E.[X|Y]).miembro(E. nth0. por ejemplo.L=[X|Y].[ ]) es una lista. .1. que una solicitud a miembro ı de un club est´ entre las solicitudes al mismo si es la primera o est´ entre el resto.c].X=E. 4. la lista [a.. La lista queda definida de la e siguiente forma: [ ] es una lista. miembro(E.[ ]))) es una lista.miembro2) es una lista siempre que miembro1 y miembro2 sean miembros de listas.(a. . Segunda idea: miembro(E. no puede prescindir del concepto o a de lista. delete. msort.5.L=[X|Y]. Ejemplo 5. append.Y). 2. reverse.(miembro1.. miembro(E.2.Y). last.Y). ¿C´mo a a o expresar´ ıamos esto? 1.L) :. si la lista L tiene cabeza X y cola Y. y sobre todo en matem´tica discreta.b. Ejemplo 5. Los miembros de las listas pueden ser t´rminos o listas. miembro(E. merge.[X|Y]) :. Tercera idea: miembro(X.miembro(E. length. miembro debe ser un procedimiento que compruebe si un determinado elemento pertenece a una lista. Cuarta idea: 16 . en cuyo caso a miembro1 se le llama cabeza de la lista y a miembro2 se le llama cola de la lista. L es representada como [X|Y] Para manipular lista Prolog cuenta con diversos procedimientos entre los cuales tenemos: is list. En general. flatten. f.inversa(Y. /* ultimo(Elem.el t´rmino Elem pertenece a la lista Lista */ e miembro(X.a]].Elem es el ultimo elemento de la lista Lista */ ´ ultimo(X. ?.0). f.g.Lista) <.L).l]. nel([_|Y]. /* nel(Lista.Lista) <. g.Inver es la inversa de la lista Lista */ inversa([].concatenaci´n de las listas L1 y L2 o dando lugar a la lista L3 */ concatena([]. L = [0.ultimo(X. miembro(X.Inver) <.[X|_]).v.L2. /* concatena(L1. m. [b.g.f.m.[_|Y]) :. concatena(Z.l].miembro(X.miembro(E.[X].L). t.Z). f.L). a. v].1. L = [a.Y).[]).[X]). v].L3) <.[X|L3]) :. 17 .sort([a.L. Para ilustrar el trabajo con listas damos los siguientes ejemplos: /* miembro(Elem.el n´mero de elementos de la lista Lista es N */ u nel([].[X|_]).msort([a.concatena(L1.msort([a.[b. l. concatena([X|L1]. l. L = [a. t.L2. ?.m.L) :.[_|Y]) :.[_|Y]) :. ultimo(X.Y). g.miembro(X. Hemos de destacar los procedimientos de Prolog para ordenar listas.t. a.N) <.L).Y).L2.a. a]]. /* inversa(Lista.v.Lista es una lista */ es_lista([]).L3). es_lista([_|_]).t.N) :. miembro(E. 1.-ListaOrdenada) y que funcionan como sugiere el siguiente di´logo: a ?. /* es_lista(Lista) <.-ListaOrdenada) sort(+Lista.M). que tienen la siguiente sintaxis: msort(+Lista. N is M+1.L).nel(Y. m.0.a. inversa([X|Y]. d] 18 .borrar(X.L.[a._).borrar(3.la lista L1 es un subconjunto de la lista L2 */ subconjunto([X|Y].b. 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.b.2].la lista L2 es una permutaci´n de la lista L1 */ o permutacion([]. borrar(X. subconjunto([].N./* borrar(Elem.L2) <.se inserta el elemento Elem en la lista L1 obteniendose la lista L2 */ insertar(E.elemento(E.L).M).c.[Z|L]. [2. L = [a.b. comprobar el funcionamiento y familiarizarse con los procedimientos antes descritos.[X|Z]) :.c. permutacion([X|Y].c. como segundo.[a.L.permutacion(Y.L). Ejercicio 5.d]).L2) <. Leer.[Z|M]) :.zip([1.Z).b. a].Y).3.Z). e es decir.[]).3.[X|Y].b.[a. N = 3 4. insertar(E.Z).L1. y por el i-´simo de la segunda.miembro(X.L.elemento(c.insertar(E.c].L2) <.L). Modificar el procedimiento borrar para que borre el elemento que ocupa la posici´n o n de la lista: ?.d]. /* insertar(Elem.L2) <. E = c ?.Z) :.Y. debe producir el siguiente di´logo: a ?. como primer elemento. /* subconjunto(L1.se borra el elemento Elem de la lista L1 obteniendose la lista L2 */ borrar(X.L1. insertar(X. Hacer los siguientes ejercicios: 1. /* permutacion(L1. 2.Z) :. b]] 3. Escribir un procedimiento que obtenga el elemento que ocupa la posici´n n de una o lista o la posici´n que ocupa el elemento e: o ?.Z).d]).[a.[E|L]).[X|Y]. subconjunto(Y. L = [[1. findall(deMartha(X). X = rose . Consid´rese por ejemplo el siguiente c´digo: e o hijo(martha. Por ejemplo.Y) :.X).3. Coleccionando Soluciones.charlotte). es decir. no obstante puede interesar que nos las entregue todas juntas. hijo(laura. X = charlotte .-Lista) y produce una lista Lista de objetos Objeto que satisfacen el objetivo Objetivo. descendiente(X. estos predicados recolectan las repuestas a una pregunta y las colocan en una lista. Lo o llevamos a cabo con: ?.caroline). X = caroline . Prolog dispone de tres predicados primitivos al efecto: findall. bagof y setof.Z).Z). hay importantes diferencias entre ellos. deMartha(caroline).descendiente(martha. Prolog aporta las soluciones a una pregunta una a una. Z contiene todos los valores de deMartha(X) que satisfacen el objetivo descendiente(martha. deMartha(laura). 5.1. caroline. false.Y) :.descendiente(martha. que.Y). X=caroline.5.X).Z). puede contener un s´ ımbolo de variable que est´ en el objetivo.X). laura. 19 . deMartha(rose)].findall(X.Y). Objeto no tiene por qu´ ser un s´ e ımbolo de variable.3. X = laura . para determinadas preguntas sobre ella puede haber varias respuestas. una vez cargado. Dada una Base de Concocimiento. descendiente(X.hijo(X. Z = [deMartha(charlotte). findall/3 La sintaxis de findall es la siguiente: findall(+Objeto. Es decir. Por ejemplo: ?.X).+Objetivo. descendiente(Z. No obstante. hay cuatro soluciones. X=laura y X=rose. hijo(charlotte. no obstante. admite la siguiente pregunta: ?. Z = [charlotte.hijo(X. En esencia. hijo(caroline. a saber: X=charlotte.rose). de forma limpia y en un formato apto para ser usadas. rose].laura).descendiente(martha. hemos decidido construir un e predicado nuevo deMartha/1 que es verdadero s´lo para los descendientes de martha. Lista). pero a veces puede resultar algo crudo.rose] Pero nos gustar´ tener una lista para cada una de las instancias de Madre.Z).laura. Lista = [laura. Z = [_G458. length(Z.findall(Y.rose. laura.Lista).Z). Madre = charlotte.laura. caroline.4. N = 4. escribir un predicado la lista de los primeros 8 a n´meros naturales. Por ´ ejemplo: ?.X).X). Ejercicio 5. Lista = [charlotte. Lista = [charlotte.caroline.Un uso menor.Hijo). Obs´rvese el siguiente di´logo y comp´rese a e a a con el oportuno de findall: 20 . u Finalmente obs´rvese el siguiente di´logo: e a ?. rose.bagof(Hijo. rose.rose. Madre = martha.descendiente(Madre. laura. _G452. Si queremos que bagof se comporte como findall. Madre = laura.rose. Hay una diferencia m´s respecto a findall.bagof(Hijo. caroline. rose] . bagof/3 El predicado primitivo findall es util.findall(Hijo. de findall es el siguiente: ?.rose].descendiente(Madre.Lista) V´ase lo siguiente: e ?. laura. _G455.descendiente(martha. Esto es justo ıa lo que hace: bagof(Hijo. es posible: ?.laura.descendiente(mary. rose. List = [charlotte. Bas´ndose en findall. caroline.Hijo). Lista = [rose] . Z = [].descendiente(Madre. Madre = caroline.Hijo). laura. en el que no nos interesaba tanto las soluciones como el n´mero de ellas. rose] .N). rose].Madre^descend(Madre. u 5. laura.caroline.Lista). _G449].findall(X.2.3. Lista = [caroline.Hijo). hermione. false. 60]. edad(ron.?.setof(Y. [caroline. Z = [[laura.3. edad(hermione. Si lo cargamos.Lista). [charlotte.bagof(Child.Lista).3.X).Child).13).Y). Pero esto mismo es obtenido con: ?.List).Y).findall(X. Considerar el sitguiente c´digo: o edad(harry.X ^ edad(X. pero la lista resultado est´ ora denada y no contiene repeticiones.Z). Lista = [draco.13).findall(Y. [rose]. dumbledore. ?.descendiente(Mother.60). edad(draco.bagof(List.setof(X. rose]]. edad(dumbledore. caroline. laura. hagrid]. hagrid.4. Es posible usar findall y bagof conjuntamente.14). edad(hagrid. podemos efectuar al siguiente consulta: ?. ron].descendiente(mary.Lista).Y). Lista = [13.Lista). hermione. 30]. ron. descendiente(Madre. 13. Destacamos los siguientes predicados: 21 . Lista = [harry. 30. 14. 60. laura. 14.Z).Y^edad(X.Y).Hijo). draco.edad(X. y a´n m´s expl´ u a ıcito es el siguiente: ?. rose]. Conjuntos Prolog implementa unos predicados para manipular conjuntos.bagof(X. 13. Observar el siguiente di´logo: a ?.List). rose]. dumbledore. 5.edad(X.Hijo^Madre^bagof(Hijo.30). Lista = [13. 5. harry.findall(List. setof/3 El predicado predefinido setof/3 funciona como bagof. ?.13). Para SWI–Prolog los conjuntos son listas sin repeticiones.Z). -Result). X = [1.X). 3].2]. false. 22 .X). por lo que Set3 podr´ no ıa ser conjunto.3.+Set2.3. X = [3. Conjunto es Lista sin repeticiones. union(+Set1.2. intersection(+Set1.2].intersection([1. 2].4. ?. e ?.X). X = [1.[2. X = [1. X = [1. true. 2.-Conjunto): Conjunto es el conjunto de elementos de Lista.2. X = [3. ?. Set3 es la uni´n de Set1 y Set2.list_to_set([1.3.[1.X).2]). o Prolog no comprueba si Set1 y Set2 son conjuntos.union([1. true.3.5. +Set2.2.X). tiene ´xito cuando Lista es un conjunto.subtract([1.3.[3.list_to_set([1. 3].[3. o ?.subset([1].X).2.subset([1].3].3]).+Delete.is_set([1. pero si las tiene.2].4.subtract([1. Lista y Conjunto coinciden si Lista no tiene repeticiones.2]. 2].[2].3]). ?.2].X).-Set3). 3. ?. 3.[2. ?.3. Set3 es la intersecci´n de Set1 con Set2. -Set3).3. 2]. Por tanto. +Set): indaga si Subset es un subconjunto de Set. elimina de Set todos los elementos del conjunto Delete.is_set([1. ?. ?. subset(+Subset.X). ?. X = [1].2]. ?. X = [1|_G598]. 2. 2].3]. subtract(+Set.is set(+Lista). 3.3].3.5.2. list to set(+Lista.2].intersection([1.3]. A = 2. Set3 s´ lo sea.ariedad) donde estructura es una estructura con nombre nombre y ariedad ariedad.A).6. 5. F = +.A). X = []. ?.subset(X. ?. ?.3]).5.F.functor(1+2. functor La sintaxis de functor es: functor(estructura. Para ver su manejo consideremos el siguiente di´logo: a ?. La estructura de los t´rminos e En Prolog un programa puede ser visto como una estructura. Ejercicio 5. ¿C´mo podr´amos mejorarlo? o ı 5.2. Extender esta acci´n al resto de ı o predicados antes enumerados para los que quepa.2.5.A).Ejercicio 5. F = coche.1. 23 .functor(f(a.-Set3) tal que si Set1 o Set2 no son conjuntos..5. A = 0.3]. F = ’.F.’. F = f.F.b).+Set2.nombre. Para manejar las estructuras tenemos esencialmente los siguientes predicados: functor arg =. name que tiene la utilidad que se explica seguidamente.F.functor([1.A).[1. A = 2.functor(coche. El predicado subset presenta el siguiente comportamiento: ?. Redefinir intersection en un nuevo predicado interseccion(+Set1. A = 2. o Para ver su manejo consideremos el siguiente di´logo: a ?..logica).2.3).Arg).Arg).2). es: ?Estructura =.arg(2.+.arg(2. ?.arg(2.+.f(y)).7. ?.Arg).?. false..3. ?.es_feliz(roberta). true. 5. Si Lista est´ instanciada. false.X). Para ver su a manejo consideremos el siguiente di´logo: a 24 .ama(vicente.functor(L. ?Lista donde si Estructura es instanciada. arg La sintaxis de arg es: arg(?Posicion. X = logica.arg(1.p(x. Arg = x.ama(vicente.functor(1+2+3. ?.b.X).?Estructura. La sintaxis de =. _G287). Lista ser´ una lista cuya primera componente (caa beza) es el functor de Estructura y el resto (cola) los distintos argumentos de dicha estructura.p(x. ?.[a. Arg = a.. Utilizar functor para decidir cuando un t´rmino dado es compuesto. Arg = f(y). L = libro(_G286. e 5.logica).f(y)).functor(1+2+3.libro.2).arg(2.c]. =. ?. X = logica. ?.X). Ejercicio 5.?Argumento) donde el argumento de la Estructura que ocupa la posici´n Posicion es Argumento.5.5. crear´ una Estructura cuyo functor ser´ la cabea a a za de la lista y cuyos argumentos ser´n los distintos elementos de la lista.arg(1. z) =.X) :. z]. Y =. Puede tana to crear un atomo con los caracteres de la lista como crear una lista de los caracteres ´ correspondientes al ´tomo. ?. true.name(prolog. copy_term(X.[HOut|TOut]) :. copy_terms_in_list(TIn.[]). L = [p. 111. [F|ArgsX]..var(X). Recursos de Control en la Programaci´n o 25 Destacamos las siguientes herramientas: . 111.copy_term(HIn.L)..Hout). 108. copy_terms_in_list([HIn|TIn]. 103].. [+. 114."estacion"). A > 0. Soluci´n. L = [112._) :.. functor(X. 6.F. copy_term(X.ArgsY). 114.5.?Lista) donde si Atomo es un ´tomo formado por los caracteres de la lista Lista. ?. x.?. X =. 108. 111. name La sintaxis de name es: name(?Atomo. 111.E =. ?. f(y).f(y).p(x.8. copy_terms_in_list([]. Ejercicio 5.F.3]. 5. E = 2+3.TOut).4.A).atomic(X).nonvar(X).[112. Atomo = prolog. [F|ArgsY].name(Atomo. Def´nase un predicado llamado copy term el cual haga una copia de ı un t´rmino reemplazando las variables que ocurran en el t´rmino original por nuevas e e variables en la copia. Para ver su manejo consideremos el siguiente di´logo: a a ?. functor(Y.A). 103]).name(estacion. copy_terms_in_list(ArgsX.2. o copy_term(X. L.Y) :. 0).nel(Y.N) en resumen ser´a: ı 1. Para ello. N=3 (concluye con el resultado) Si se quiere se puede pedir a Prolog un informe del flujo del programa: 26 .N) (comienzan las llamadas recursivas) 2.[b.d]. matching) o 3. En ella la condici´n de parada es o o nel([]. N is M+1.M3) (actua la condici´n de detenci´n) o o 5.[b. Unificaci´n (unification. nel([_|Y]. Consideremos la definici´n: o nel([].M1) (la lista decrece en “longitud”) 3.1. M3=0 (comienza el c´lculo en retroceso) a 6. Recursi´n (recursion) o En el apartado que hemos llamado Listas (subsecci´n 5. M2=M3+1=0+1=1 7.1.M). y la cl´usula que hace evolucionar los par´metros es: a a nel([_|Y].2) hemos visto como las reglas o definitorias inclu´ en su cuerpo el mismo t´rmino t´rmino que aparec´ en su cabeza.M2) 4.1. que es un ejemplo de definici´n recursiva. Recursi´n (recursion) o 2. Reevaluaci´n (backtracking) o 4.N) :. nel([a. N=M1+1=2+1=3 9. ıan e e ıa Esta pr´ctica es de extrema utilidad en programaci´n si no cae en el cl´sico problema a o a de la “petici´n de principio”. a o Ejemplo 6. para poder unificar en determinado paso con una cl´usula que ha sido establecida a modo de “condici´n de parada”.c].nel(Y. nel([d]. El flujo del programa para nel([a.d].N) :.M). nel([].0). M1=M2+1=1+1=2 8. uno de los argumentos de la definici´n en la o o llamada recursiva debe decrecer o crecer. Corte (cut) 6. nel([[b. N is M+1.c].c].d]. 3) ? creep N = 3. _G1288) (9) nel([]. c]. madre(X.c]. 0) ? creep ^ Call: (10) _G898 is 0+1 ? creep ^ Exit: (10) 1 is 0+1 ? creep Exit: (9) nel([d]. o tambi´n: e ?. c].d]. Call: (7) nel([a.trace. d].[b. [b. (6) nel([a. c]. 2) ? creep ^ Call: (8) _G726 is 2+1 ? creep ^ Exit: (8) 3 is 2+1 ? creep Exit: (7) nel([a. 3) Los dos grandes errores en el planteamiento de una recursi´n son: o 1. [b.B):. [debug] T Call: T Call: T Call: T Call: T Exit: T Exit: T Exit: T Exit: N = 3. _G893) ? creep Call: (9) nel([d]. 1) ? creep ^ Call: (9) _G901 is 1+1 ? creep ^ Exit: (9) 2 is 1+1 ? creep Exit: (8) nel([[b. _G1288) (8) nel([d]. % nel/2: [call.exit. c]. d]. _G893) ? creep Call: (10) nel([].hijo(Y.Y).N). d].Y) :. d].persona(Y). notrace. 27 . Es lo o que tradicionamente ha recibido en nombre de “petici´n de principio”. _G1180) (7) nel([[b. persona(X) :.fail] true.nel([a.[b. 2) (6) nel([a. d].d]. _G726) ? creep Call: (8) nel([[b.N). c]. c].padre(B. d].redo. 2.c].A). Por ejemplo: o padre(X. d]. c]. _G1288) (9) nel([]. d]. nel([a. persona(adam).?. y la llamada recursi´n a izquierdas que esencialmente supone la “definici´n indefio o nida porque s´ Por ejemplo: ı”. 1) (7) nel([[b. [b. 0) (8) nel([d]. _G893) ? creep Exit: (10) nel([].trace(nel). ?. [b.X). c]. la recursi´n circular con la que se entra en un bucle que no termina nunca. hijo(A. Z). Una llamada recursiva con disminuci´n del par´metro inicial. Cuando se desencadena es para o ıa instanciar variables de forma que dos t´rminos coincidan tras dicha instanciaci´n. Prolog lo pone de manifiesto.f(a).f(Y).der). o Ejercicio 6. donde aparece: 1. mover(1.f(b).Y.a) = p(a. mover(M. Si los e o t´rminos t1 y t2 son unificables. 3.mover(N.Y). Dar una implementaci´n que simule los n´meros naturales y definir.Y). write(’ a ’). false.a) = p(a.X.cen. Si no son unificables.X. a ?.Z) :write(’Mueva el disco superior de ’).Z) :N>1. mover(M.izq.X.X.X. Como ejemplo correcto traemos ahora el cl´sico y bello ejemplo de la a soluci´n a las Torres de Hanoi. nl. write(X). ?. o 2. matching) o La unificaci´n constituye uno de los mecanismos esenciales de Prolog junto a la reo soluci´n. El programa torres hanoi. El algoritmo que usa es en esencia el cl´sico algoritmo de unificaci´n a o visto en teor´ Tener en cuenta el siguiente di´logo: ıa. X = a. write(Z)._. de forma que alguna o a vez llegue a valer 1. M is N-1. Una simplificaci´n de la llamada. o u dentro de esa simulaci´n.2.3.2.Y).Z). Y = a.f(Y).Y. sin ambos ser´ imposible extraer respuestas.Z.p(X.pl contiene el siguiente texto: o mover(1. o 6. mover(N.Ejemplo 6._. 28 . la suma y el producto. Una condici´n de parada siempre satisfacible dado que presupone un trabajo como puesto de impresi´n por pantalla. Unificaci´n (unification.p(X. Prolog encuentra una sustituci´n de variables M tal que e o aplicada M a t1 da el mismo resultado que aplicada a t2. torres_hanoi(N) :. X=a. Y = b. Y = b.X=f(X). X is 1. ?. intenta satisfacer los objetivos del cuerpo de la regla.a).f(b). X = 1. X=d..f(Y). ?.?.unify_with_occurs_check(X. Reevaluaci´n (backtracking) o La reevaluaci´n consiste en revisar lo hecho para intentar extraer una respuesta altero nativa resatisfaciendo los objetivos.a \= f(X).f(Y). Z = d. a no puede ser unificada con f(X): ?.a) = p(Z.p(X. e o como sabemos. X = d.f(X)).f(Y). la unificaci´n falla. true. Cuando una varible deba ser instanciada a un t´rmino que la contiene. Si el hecho es la cabeza de una regla con cuerpo.a) = p(Z. Considerar lo siguiente: ?. X = Z. marca el lugar en la base de conocimientos e instancia todas las variables que coincidan previamente no instanciadas.p(X. el objetivo ha fallado e intenta u resatisfacer el objetivo anterior. Cuando Prolog acaba de dar una respuesta. false. Nos es de ayuda en este caso el procedimiento binario: unify with occurs check. ?.f(b).a).X=f(X). la reevaluaci´n se desencadena escribiendo y ejecutando . 29 . false. Y = b.f(b). X = f(**). • si no encuentra ning´n hecho que unifique. ?.3.a) = p(Z. Z = 1.a). ¿C´mo busca Prolog respueso o tas?: Trata de satisfacer objetivos buscando en la base de conocimiento: • si existe un hecho que pueda unificar con el objetivo.p(X. 6. acaba_de_comer(mosquito.serpiente).00 sec. incluyendo el punto en el arbol de derivaci´n en el que se introdujo el corte ´ o como parte de la secuencia de objetivos. acaba_de_comer(serpiente. pero no se puede resatisfacer. El corte se convierte en un impedimento que impide al proceso de reevaluaci´n el franqueo del camino de vuelta hacia atr´s. Si se quiere. Corte (cut) El t´rmino corte de Prolog. esta_digiriendo(X.rana).pl: acaba_de_comer(mosquito. representado por !. 30 . Anal´ ıcese la extensa respuesta. acaba_de_comer(aguila.pl compiled 0. acaba_de_comer(rana.Y) :.pez). % digestion.sangre(pedro)). acaba_de_comer(oso.4. convirtiendo en inaccesibles o a todos los marcadores de las metas que se encuentran a su izquierda.nectar). en cuyo caso. acaba_de_comer(garza.Resatisfacer consiste en intentar resatisfacer cada uno de los objetivos del cuerpo de la regla por orden inverso. Para ello intenta encontrar una cl´usula alternativa para a el objetivo. esta_digiriendo(Z. se puede imaginar como una v´lvula que permite el paso en un sentido —del flujo del programa. acaba_de_comer(X.4.mosquito).pez).pl’]. La b´squeda es retomada desde donde se hab´ dejado el a u ıa marcardor de posici´n de objetivo.trigo).acaba_de_comer(X.mosquito). 6. a pero que lo impide en el contrario.Z). 148 bytes true. Considerar el programa digestion. o Ejemplo 6. El objetivo corte tiene ´xito cada vez que es considerado como objetivo o e actual.savia).esta_digiriendo(X. y el ´rbol de derivaci´n resulta podado de todas las otras opciones en el camino a o de regreso. elimina opciones en un ´rbol de derie a vaci´n Prolog.Y).Y).Y). El corte se satisface incondicionalmente. acaba_de_comer(mosquito.perdiz). acaba_de_comer(aguila. acaba_de_comer(pez. que cargado en el entorno nos permitir´a: ı ?. acaba_de_comer(perdiz. se dejan sin instanciar todas las variables instanciadas al elegir la cl´usula previa. ?.[’digestion. e ı ı e 7.1) :. Podemos a ejemplificar este uso en una simulaci´n del if-then-else cl´sico en programaci´n. u 31 . S is N+S1. deber´ fracasar el objetivo. tuvi´semos simplemente sumatorio(1. que sesga la misma. sigue la regla correcta. Si las metas siguientes fracasan.5.b. a :.S1). sumatorio(N1. Optimiza el uso de la memoria no registrando puntos de reevaluaci´n o o para un examen posterior. u suprima de ella los n´meros impares.1).El corte es una intervenci´n en la forma autom´tica de aplicar recursi´n. no malo o gastando el tiempo en satisfacer objetivos que de antemano sabemos que no contribuir´n a a una soluci´n.1. Ejercicio 7. Como ejemplo de este uso nos vale tambi´n el programa correcto que figura en el Ejercicio e 6.c. ser´ a ıa a :. Hacer un programa en Prolog que dada una lista de n´mero enteros.N1 is N-1. unificaci´n y o a o o reevaluaci´n de Prolog.d. a :. Considerar el programa que fuera: sumatorio(1.5. Aunque cabe que haga dif´ la comprensi´n de un programa. Para o a o ello. Confirmaci´n o Con el corte podemos confirmar al flujo de Prolog de que si ha franqueado el corte. considerar el texto: a :. Optimiza el tiempo de ejecuci´n.1. que expresado en una forma ineficiente (puede acabar intentando satisfacer b dos veces) pero m´s clara.d. o Ejercicio 6.b.S) :. y decir qu´ ocurrir´a si en lugar de la primera l´nea. sumatorio(N.!. el corte es imprescindible en la programaci´n con Prolog.!.not(b). ıcil o su uso puede ser la diferencia entre que un programa funcione o que no funcione. En fin.c. Usos del Corte Confirmaci´n o Advertencia Finalizaci´n o Vamos a destacar tres usos del corte: 7. pl en el que se define la e negaci´n por fallo.Cociente) <. Justificar por qu´ es ineficiente la siguiente versi´n: e o max_ineficiente(X. Y1 is C*B.2.Divisor.7. Encontrar en qu´ falla la siguiente definici´n de m´ximo: e o a max_mal(X. As´ el corte al final de la regla impide que en un posible proceso de o ı. Consid´rese el siguiente programa no.Y>X. !.Y) :.Y) :. Y2 is (C+1)*B. no(Q).Y.Y. pero s´lo uno de ellos es el que nos interesa y ser´ el que u o a pase la condici´n. natural(X) :. Que es un generador de n´meros naturales hasta encontrar un valor de C que cumpla la u condici´n: o B*C =<A <B*(C+1) siendo A el dividendo y B el divisor de la divisi´n. max_mal(X.Y. Y1=<A.call(Q). Y2>A.Cociente es el resultado de la divisi´n entera entre Dividendo y Divisor o */ diventera(A. o Ejercicio 7. De hecho. /* diventera(Dividendo.pl: o e /* natural(Num) <.3. 32 .Y. Explicaremos posteriormente el significado de call. lo que e hacemos en P es tomar a P como una varible de t´rmino.Y>X. e 7. es realmente la definici´n Prolog de not: o o no(Q) :.2. Advertencia Usando el corte en combinaci´n con el predicado de fallo fail podemos dar cuenta de o que el hecho ha de fracasar sin intentar encontrar soluciones alternativas. fail. Finalizaci´n o Podemos usar el corte para informar a Prolog que deseamos finalizar la generaci´n de soo luciones alternativas mediante reevaluaci´n.not(Y>X).X) :.natural(Y). X is Y+1. Consid´rese el siguiente programa divisionEntera. y arreglarla.B.X). !. tiene ´xito si lo tiene P y fracasa en otro caso. pero adelantamos que call(P) fuerza a que P sea un objetivo.Num es un n´mero perteneciente a los Naturales */ u natural(0). max_ineficiente(X.C) :.natural(C). La regla natural va generando o infinitos n´meros naturales. fail siempre fracasa como objetivo. reevaluaci´n entremos en un bucle infinito: hemos encontrado la unica soluci´n y no hay o ´ o ninguna raz´n para volver a buscar otra. !.!. s(c). o incluso beneficioso. p(X) :.L3). cuando se utiliza una regla de una forma dada.L.u(X). del corte Mientras que un corte puede ser inofensivo. 33 .L) :. p(X) :.4.L2.!. p(X) :.L2. r(X). p(X) :.L3) <.L2. r(X). 7.3.! . Efectos indeseados.q(X). !. Efectuar en pruebaCorte. sustituyendo la l´nea segunda por p(X) :. 2 y 3 por las siguientes respectivamente: ı p(e) :.Ejercicio 7.[X|L3]) :.pl p(e). pero tolerables. Considerar el programa pruebaCorte.q(X).pl que contiene: /* concatena(L1. cambiando las l´neas 1. ı sustituyendo la l´nea segunda por p(X) :. el mismo corte puede provocar un comportamiento extra˜o si la n regla se utiliza de otra forma. q(X).s(X).!. q(X) :. Considerar el programa discusionCorte.pl los siguientes cambios e interpretar los resultados de pedir a Prolog la pregunta p(X).: con el programa tal cual.q(X). s(b). r(b).r(X).q(X). u(d).u(X). r(a).r(X). concatena([X|L1].concatena(L1. r(X). s(a).concatenaci´n de las listas L1 y L2 o dando lugar a la lista L3 */ concatena([].u(X). ı cambiando las l´neas 2 y 3 por las siguientes respectivamente: ı p(X) :.r(X).q(X). ı sustituyendo la l´nea segunda por p(X) :. p(X) :. c]. e repeat. ayuda. ayuda. d. d. no ofrece todas las soluciones posibles. hacer(’a’) :. 7.cabecera. b.b.[’discusionCorte.00 sec. true.c]).[a. Y = [a. en todo caso. siempre tiene ´xito.integer(X). hacer(X) :. X = [].Y. ?. e]. siempre falla. 5.concatena([a. Consid´rese el o e siguiente ejemplo: /*-----------------------------------------------------------*/ /* PROGRAMA PRINCIPAL */ /* */ menu :. !.b.e]. hacer(Formula). X = [d.[d.cabecera. b.Cuando se consideran objetivos de la forma: ?. leer(Formula).pl compiled 0. repeat.pl’]. % discusionCorte. el corte resulta muy adecuado. !. con el uso que se va a o hacer de la regla.cabecera. fail.X).X. c]. Por tanto. pero si tenemos el objetivo: ?. permite simular bucles junto con la combinaci´n corte–fail.concatena(X. 34 . X=0.736 bytes true. hacer(’A’) :.[a.b. fail. X = [a.5. e]). c. e]. la introducci´n del corte debe contar. ?. c.c].concatena([a. Predicados de control Existen unos predicados predefinidos que ayudan cuando queremos utilizar estructuras de control. b. Por ejemplo: fail. FND).negro) :. fail.E2. 35 . clr(Y.[].!.L1.L2).[A|L1].E2. /* sust(E1.pausa. sust(E1.E2. formaNormal(Formula.desconocido).L2).hacer(Formula) :.E2. Otros ejemplos Presentamos ejemplos de uso del corte en programas.L1.L1.rojo(Y).[E1|L1].fbf(Formula). sust(E1.fail. pausa.[].!.borrar(E.!.L1.FNC. borrar(E.[E|L1]. clr(Y.FND).E2.red(X) -> C = red .negro(Y).[]).[Y|L1]. clr(Y.L2) <. sust(E1.rojo) :.[A|L2]) :. /* borrar(Elem. escribirFormasNormales(FNC.sust(E1. 7.L2).L2).6. hacer(_) :. black(X) -> C = black .L1.L2 es la lista resultado de borrar todas las ocurrencias del elemento Elem de la lista L1 */ borrar(_.L2 es la lista resultado de sustituir en la lista L1 todas las ocurrencias del elemento E1 por E2 */ sust(_. borrar(E.C) :.[]).[E2|L2]) :. C = unknown. negro(b). /* */ /* Fin Programa Principal */ /* */ /*-----------------------------------------------------------*/ +Condicion ->+Accion.[Y|L2]) :. % "color_alt" tiene el mismo efecto que "clr" % "->" simula el uso de "!" color_alt(X.L2) :.L1.L2) <._.!.borrar(E.!.!. permite simular la estructura condicional: si-entonces y si-entonces-sino rojo(a). tab(+X). 8.L2. escritura con formato. union([X|L1].L). lo saca por pantalla.pl que contiene lo siguiente: e 36 . Debe ir e seguido de un punto “.L. Instancia Termino al t´rmino le´ e ıdo.” y un “retorno de carro”.L2. no l´gico.miembro(X. union(L1. nl writef(+Formato. la salida posterior se presenta en la siguiente l´ ınea de la pantalla. o sisplay(+Termino). es equivalente a write(+Termino). para ello X debe estar instanciada a un entero (una expresi´n evaluada como un entero positivo).[X|L3]) :.1. excepto que pasa por alto cualquier declaraci´n de operadores que se haya hecho.L2.1. u Nunca se pueden resatisfacer: la reevaluaci´n contin´a hacia la izquierda. se comporta como write(+Termino). La I/O en Prolog Si se desea una mayor interacci´n de Prolog con el usuario que la mera presentaci´n o o por pantalla de los resultados a nuestras preguntas.L3) <. desplaza el cursor a la derecha X espacios. a e o Destacamos lo siguiente: Ejemplo 8.L2). a e 8. es preciso recurrir a otro tipo de predicados.L3).L2.L3) :. a e En caso contrario. !. por unificaci´n entre las mismas y la o base clausular del programa. nl. Lectura y escritura de t´rminos e write(+Termino). o read(-Termino). se sacar´ por pantalla una variable numerada de forma unica a ´ (por ejemplo: G245).L3). si Termino est´ instanciado a un t´rmino.union(L1. En caso contrario. union([X|L1]. que cumplen por coherencia lo siguiente: Se eval´an siempre a verdad./* union(L1.L2. o u Tiene un efecto lateral. si Termino no estaba instanciada. Se trata de los predicados Entrada/Salida. lee el siguiente t´rmino que se teclee desde el ordenador. write ln(+Termino). Consid´rese el fichero io ejemplo. durante su ejecuci´n: entrada o salida de un o o car´cter. los compara y se satisfar´ o a fracasar´ dependiendo del ´xito de la comparaci´n.+Termino).L3 es ls lista-conjunto uni´n de las o listas-conjuntos L1 y L2 */ union([]. t´rmino. etc. [’io_ejemplo.. /* escribe_cadena(L) <.6)) true.nl.. tab(1).una. 8+5*6 +(8. ?.. una. es decir saca por pantalla los elementos de la lista separados por un espacio y terminado en salto de l´nea ı */ ibl([]) :.4. haci´ndoles corresponder su c´digo ASCII. nl.imprime la lista L de forma bonita./* ibl(L) <. u Atomo = pepe N´mero = 4.2. lista]. ?.write(8+5*6). Lectura y escritura de caracteres Prolog trata los caracteres como enteros. e o Consid´rese lo siguiente: e 37 .084 bytes true.(una.[pepe.pl compiled 0.5 u true.es.pl’]. 8.(lista.display(8+5*6).put(X).00 sec. display(8+5*6). nl.escribe en pantalla la lista L de c´digos ASCII en forma de cadena de o caracteres */ escribe_cadena([]). nl.writef(’Atomo = %w\nN´mero = %w\n’.(esto. display(X).es. ibl(X).X=[esto. ?.write(8+5*6).*(5.*(5. 1.(es.5]). [esto. write(X). ibl([X|Y]) :.lista] .una. ibl(Y). Que presenta el siguiente comportamiento: ?.nl. 8+5*6 +(8. escribe_cadena([X|Y]) :. % io_ejemplo.lista]. es.[])))) esto es una lista X = [esto. ?.6)) true.write(X). escribe_cadena(Y). 8.put(111).put(108).put(111). Prolog true.put(103).[’io_ejemplo. la unica diferencia es que cuando queramos escribir o leer en un fichero debemos cambiar el ´ canal de salida activo o el canal de entrada activo.103]). Si Caracter ya est´ instanciada. skip(+Caracter). contienen un cierto n´mero de caracteres.put(X). instanciando Caracter al primer car´cter imprimible que se teclee. que proporciona el siguiente di´logo: a ?.084 bytes true. Lectura y escritura en ficheros Existe un fichero predefinido llamado user. y al escribir. e get0(-Caracter). escribe_cadena([X|Y]) :.pl compiled 0. Al leer de este fichero se hace que al informaci´n de entrada venga desde el teclado. los compara a a satisfaci´ndose o fracasando. Cada uno de estos tendr´ un nombre de fichero que utilizaremos para identificarlo. se hace que los caracteres aparezcan o en al pantalla. % io_ejemplo. proporciona error. respectivamente. igual que get(-Caracter) sin importar el tipo de car´cter tea cleado. Si Caracter no est´ insa o a tanciada o no es entero.108. 1. escribe_cadena(Y).114.111. Consid´rese el siguiente c´digo inclu´do en el fichero io ejemplo.pl’].escribe_cadena([80. Al final del fichero hay u 38 . Pero pueden ser escritos t´rmie nos y caracteres sobre ficheros utilizando los mismos predicados que se acaban de ver. ?.put(80). En Prolog a los nombres de ficheros se representan como atomos. saca por a pantalla el car´cter correspondiente a ese c´digo ASCII.00 sec.put(114). si Caracter est´ instanciada a un entero entre 0 y 255.put(+Caracter).3. lee caracteres desde el teclado.escribe en pantalla la lista L de c´digos ASCII en forma de cadena de o caracteres */ escribe_cadena([]). Los ficheros tienen una longitud ´ determinada.2. este es el modo normal de funcionamiento.111. es decir. lee del teclado hasta el car´cter Caracter o el final del fichero. ?. get(-Caracter). a Ejemplo 8. Prolog true.pl: e o ı /* escribe_cadena(L) <. Posiblemente queramos leer y escribir sobre ficheros almacenados en discos. told. si NomFichero est´ instanciada al nombre de un fichero. write(B). tell(fichero). el fichero pasa a estar abierto y empezamos al comienzo del fichero. told. La primera vez que se satisface. write(C). a a seeing(?NomFichero). /* secuencia normal de escritura */ .3. la instanciar´ al nombre a a del fichero que es el canal de entrada activo. . si NomFichero no est´ instanciada. see(+NomFichero). permiti´ndonos escribir sobre ellos en varios momentos diferentes. .. see(fichero).. tell(user). eliminando o modificando cl´usun a las. read(X). puede generarse un fin de fichero tecleando el car´cter de control ASCII 26 o Ctrl+Z. . cierra el fichero para lectura y dirige la entrada hacia el teclado. se satisface si es el nombre del fichero actual de salida. producir´ un error. si conmutamos el canal de salida activo sin cerrarlos (told).. la instanciar´ al noma a bre del fichero que es el canal de salida activo. En caso contrario. 39 . told. 9. Si NomFichero no est´ instanciada o no es un nombre de fichero. . cambia a el canal de entrada activo al fichero especificado. ... seen. a˜adiendo. En caso contrario. Destacamos lo siguiente: tell(+NomFichero). cama bia el canal de salida activo.. Si NomFichero no est´ instanciada o no es un nombre de fichero. Modificaci´n de la Base de Conocimiento o Presentaremos una serie de predicados predefinidos en Prolog que nos permitir´n mania pular la Base de Conocimiento consultando. write(X). seen. Crea un nuevo fichero con ese nombre. tell(fichero).una marca especial de fin de fichero.. Se pueden tener a abiertos varios ficheros. /* conmutaci´n de ficheros */ o . se satisface si es el nombre del fichero actual de entrada. cierra el fichero para escritura y dirige la salida hacia la pantalla.. si NomFichero est´ instanciada al nombre de un fichero. Cuando la entrada viene del teclado. producir´ un error. /* secuencia normal de lectura */ .. si NomFichero no est´ instanciada. sin destruir lo escrito e previamente. a a telling(?NomFichero). Ejemplo 8. tell(fichero). write(A).. Tambi´n es interesante cuando queremos asegurar o e que se utilizan las cl´usulas que vamos a leer.9.[’/home/usuario/prueba. la barra “/” para el directorio o el punto “. mientras que si se quiere reconsultar se pone el nombre precedido de un signo “-”. Como argumento pasamos un atomo con el nombre del fichero del que queremos leer las cl´usulas. Adici´n de Bases de Conocimiento externas o Si queremos que Prolog lea nuevas cl´usulas de un fichero que hemos preparado prea viamente. el predicado predefinido reconsult act´a como consult u excepto que. de textos preferidos (sugerimos el uso de Emacs) para posteriores usos.[fichero1. reconsult(+Fichero). Esto ser´ conveniente a cuando tengamos que trabajar con programas de tama˜o considerable y no queramos n teclear cada vez todas las cl´usulas. -’prueba’.consult(’practica1. d´ ´ a ıgitos y el car´cter de subrayado. a 1 40 . Si quea remos que contenga otros caracteres (los dos puntos “:” para la unidad.reconsult(’/home/usuario/practica1.pro”.2 Se suele utilizar para la correcci´n de errores o mientras se est´ realizando el programa. a 2 SWI-Prolog no tiene un predicado reconsult ya que al consultar un fichero ya almacenado.1.consult(fichero). al final de las ya existentes.pl’).reconsult(fichero). A modo de ejemplo consid´rese: e ?. podemos utilizar los predicados consult y reconsult. ’/home/usuario/prueba’]. Si se quiere consultar un fichero. de existir cl´usulas para un mismo predicado (nombre y ariedad). La mayor parte de las implementaciones permiten una notaci´n especial para consultar o una lista de ficheros. se pone el nombre en la lista tal cual. autom´ticamente es reconsultado. Recordemos ´ a que un atomo est´ formado por letras. Pero o o esto depender´ del sistema Prolog utilizado y se puede personalizar. As´ podremos crear el programa con nuestro editor a ı. ?. con la ventaja a˜adida de que lo podremos modificar y ampliar en cualquier momento. ?. el predicado predefininido consult a˜ade las cl´usulas exisn a tentes en el fichero de nombre Fichero a la base de conocimiento de Prolog. uno tras otro: la notaci´n en forma de lista.” para la extensi´n1 deberemos encerrarlo entre o comillas simples.pro’). ?. ya que de esta manera la nueva versi´n a o sustituye a la anterior err´nea. SWI-Prolog asume por defecto la extesi´n “. sin destruir las anteriores. ?. ?. Consiste en poner o los nombres de los ficheros en una lista y darla como objetivo a satisfacer. -fichero2.pl” y Prolog–2 toma la extensi´n “. y no otras posibles con el mismo a nombre que tuviese el sistema de alguna consulta anterior. las a nuevas sustituyen a las existentes. n Destacamos lo siguiente: consult(+Fichero).pl’]. retractall(+Clausula).asignatura(X). X = flp . ?. Un hecho es considerado como una cl´usula cuyo cuerpo es a true. clause(?Cabeza. X = lmd. nos permite eliminar una cl´usua la de la Base de Conocimiento. assert(+Clausula). muestra por el fichero de salida activo (pantalla por defecto) todas las cl´usulas que tienen como predicado el ´tomo al que est´ instanciada a a a a variable Predicado. listing(+Predicado). assertz(+Clausula). Manipulaci´n de la Base de Conocimiento o A veces es muy conveniente enriquecer la Base de Conocimiento con nuevas cl´usulas. Dicha cl´usula queda incorporada a la Base de Conocimiento a a y no se pierde aunque se haga reevaluaci´n. Clausula debe estar previamente instanciada a una cl´usula. a incluso resultado de alguna computaci´n. ERROR: toplevel: Undefined procedure: asignatura/1 (DWIM could not correct goal) ?.asignatura(X). 9. X = logica_informatica . se hace coincidir Cabeza con la cabeza y Cuerpo con el cuerpo de una cl´usula existente en la Base de Conocimiento.?Cuerpo).assert(asignatura(logica_informatica)).2. ?. estos predicados permiten a˜adir nuevas cl´usulas a la Base de Conocimiento. true. true.assertz(asignatura(lmd)). Clausula debe estar instanciada y se 41 . Como ejemplo considerar el siguiente o di´logo: a ?. ?. A tal fin existen en Prolog predicados predeo finidos. retract(+Clausula).pl’]. escribe todas las cl´usulas de la Base de Conocimiento en el fichero de a salida activo. El predicado n a asserta la a˜ade al principio (observar la letra “a”) y assertz la a˜ade al final n n (observar la letra “z”) de cualquier otra cl´usula del mismo tipo que hubiese en la a Base de Conocimiento. En todos los casos. asserta(+Clausula).?. entre los que destacamos los siguientes: listing. true. Para ello.[-’/home/usuario/prueba.asserta(asignatura(flp)). Por lo menso Cabeza a debe estar instanciada. dynamic asignatura/1. Con retractall se eliminar´n todas. asignatura(flp). asignatura(flp). :. :. :. true. Si se a a resatisface el objetivo.listing(asignatura). abolish(+Predicado/Ariedad). true. asignatura(lmd).retract(asignatura(lmd)). Considerar el siguiente di´logo: a ?. true. ?.listing(asignatura).dynamic asignatura/2.dynamic asignatura/1. asignatura(logica_informatica).quitar´ la primera cl´usula de la Base de Conocimiento que empareje con ella. 42 .dynamic asignatura/1. ?. ?. sucesivamente. :. asignatura(lmd). ?. asignatura(logica_informatica). asignatura(flp).listing(asignatura). X = flp . :. abolish(+Predicado. true. se ir´n eliminando.+Ariedad). consid´rese el siguiente: a e ?.listing(asignatura).retract(asignatura(X)). asignatura(logica_matematica). Debe estar idena tificado completamente el predicado: nombre y ariedad.dynamic asignatura/1. Como ejemplo. asignatura(logica_informatica). las cl´usulas que coincia a dan. retira de la Base de Conocimiento todas las cl´usulas del predicado Predicado. true. segundo). se intenta satisfacer dicho predicado Exit. ?. Los errores en programaci´n son de o naturaleza sint´ctica. tercero). primero). tercero). el objetivo ha fracasado Redo. ERROR: toplevel: procedure ‘asignatura’ does not exist (DWIM could not correct goal) 10. Ellos nos permitir´n la depuraci´n y correcci´n o a o o de los mismos. ´ o Tengamos en cuenta los siguiente: Call. asignatura(flp. f´ciles de detectar y corregir. true. se intenta resatisfacer el objetivo al haber fracasado un predicado posterior Destacamos lo siguiente: 43 . Es en ese ultimo punto donde entra en juego el contenido de esta secci´n.listing(asignatura). Depuraci´n de Programas Prolog o Prolog contiene una serie de predicados predefinidos para supervisar el funcionamiento de los programas durante su ejecuci´n.listing(asignatura). que s´lo a a a o puedenn ser descubiertos revisando el planteamiento o siguiendo el proceso de inferencia paso a paso.abolish(asignatura. ?. o de naturaleza sem´ntica. :. el predicado ha tenido ´xito y se ha satisfecho e Fail. true. asignatura(logica_matematica. asignatura(lmd.asignatura(logica_matematica. ?. asignatura(flp. primero).dynamic asignatura/2.abolish(asignatura/1).2). asignatura(lmd. ?. true. segundo). pues hay errores dif´ ıciles de detectar. notrace. • c (continue). • n (nodebug). desactiva la traza. como si se hubiera cumplido. nospyall. notrace(+Objetivo). u • e (exit). viendo los distintos objetivos que intenta satisfacer y el resultado de esta acci´n. contin´a con la traza. pidi´ndonos que confirmemos cada paso. fija un punto esp´ en el predicado Predicado para poder seguir ıa su funcionamiento. su efecto es el inverso del predicado anterior. intenta satisfacer el objetivo desactivando la traza mientras dure su ejecuci´n. spy([iniciar. • f (fail ). abandona el sistema Prolog. Ejemplos: ????spy(iniciar). • b (break ). A partir de la consecuci´n de este objetivo.trace. <espacio> (avanzar ). muestra la pila de objetivos cumplidos hasta el objetivo actual. u • una lista: situar´ puntos esp´ en todos los lugares especificados por cada uno ıa ıa de los elementos de la lista. • a (abort). spy(iniciar/0). retorna a Prolog. hace fallar a ese objetivo. reintenta satisfacer el objetivo. activa el seguimiento exhaustivo de la traza de ejecuci´n del as metas posteriores a la consecuci´n de este objetivo o del predicado o o Predicado. hay una interacci´n entre o o o el programador y la m´quina Prolog. realiza la pausa s´lo en los puntos esp´ o ıa. trace(+Predicado). u o • r (retry). es decir. a e Podemos utilizar las siguientes opciones del modo traza: • <return>. salta el modo interactivo hasta que se cumple o falla ese objetivo. inicia un nuevo nivel de Prolog. continua con la traza.pertenece]). • g (goal stack ). o spy(+Predicado). • s (skip). spy(iniciar/1). inde´ ıa a pendientemente del n´mero de argumentos que tenga. Con el argumento Objetivo. elimina los puntos esp´ especificados en Predicado ıa (determinado de manera an´loga a la referida en el punto anterior) o retira los puna tos esp´ activos en ese momento. ignora el objetivo actual. ıa 44 . • l (leap). nospy(+Predicado). u • una estructura (functor/ariedad): s´lo establecer´ puntos esp´ en aquellos o ıa ıa predicados con dicho functor y n´mero de argumentos. • i (ignore). Predicado debe ser: • un atomo: se ponen puntos esp´ en todos los predicados con ese ´tomo. contin´a ejecuci´n en modo “no debug”. -Y. se cumple si X representa en ese momento un n´mero real u 4. se cumple si X representa en ese momento un atomo de Prolog ´ numeric(X). There are spypoints set on : iniciar/0 iniciar/1 pertenece/2 debug. se cumple si X representa en ese momento un n´mero o un atomo u ´ atom(X). Construcci´n de objetivos compuestos (conectivas l´gicas): o o X. se cumple si X representa en ese momento un n´mero entero u real(X). o 1. a˜adir las cl´usulas del fichero X a la base de conocimiento n a reconsult(Y). A. las cl´usulas le´ a ıdas de fichero Y sustituyen a las existentes para el mismo predicado. Adici´n de Bases de Conocimiento externas: o consult(X). salir del sistema Prolog 2. inicializa y finaliza el depurador. se cumple si fracasa el intento de satisfacer X 3.debugging. se cumple si fracasa el intento de satisfacer X not(X). Predicados Predefinidos Hacemos relaci´n de algunos predicados predefinidos en Prolog. permite ver una lista con los puntos esp´ que se han establecido hasta ıa el momento. conjunci´n de objetivos o X.Z]. Control del programa: true. nodebug. disyunci´n de objetivos o \+ X.Y. objetivo que siempre se cumple fail. se cumple si X representa en ese momento un n´mero u integer(X).Y.debugging. objetivo que siempre fracasa 45 . se cumple si X no es una variable sin instanciar en ese momento atomic(X). notaci´n m´s c´moda para consult y reconsult o a o halt. Clasificaci´n de t´rminos: o e var(X). Como ejemplo: ?. [X. se cumple si X es en ese momento una variable no instanciada nonvar(X). Predicado menor o igual que o e X is Y. operador de multiplicaci´n o X / Y.Z). ordenaci´n de t´rminos. se cumple si puede hacer X e Y iguales (unificarlos) X\=Y. operador concatenaci´n de cadenas de caracteres o X + Y. o current op(X. operador suma X . si X entonces Y. Predicado menor que o e X@>Y. ordenaci´n de t´rminos. o 46 .Z). igualdad m´s estricta a X\==Y. Predicado mayor que o e X@>= Y. corte. se eval´a la expresi´n a la que est´ instanciada Y para dar u o a como resultado una cadena.Y. Fuerza al sistema Prolog a mantener ciertas elecciones repeat. predicado menor o igual que X@<Y. se cumple si fracasa == X<Y. se eval´a la expresi´n a la que est´ instanciada Y para dar como u o a resultado un n´mero.Y. predicado mayor o igual que X=<Y. ordenaci´n de t´rminos.!. que se intentar´ hacer coincidir con X u a X is string Y. busca el operador ya declarado de nombre Z con clase de precedencia X y posici´n-asociatividad Y. predicado mayor que X>=Y. declara el operador de nombre Z con clase de precedencia X y posici´n-asociatividad Y. sirve para generar soluciones m´ltiples mediante el mecanismo de u reevaluaci´n o X ->Y. se cumple si tiene ´xito el intento de satisfacer X (instanciada a un e t´rmino) e 5. operador de exponenciaci´n o op(X. se cumple si X=Y fracasa X==Y. predicado menor que X>Y. Predicado mayor o igual que o e X@=<Y. En combinaci´n con . operador resta X * Y. ordenaci´n de t´rminos. act´a como Si-Entonces. Operadores artim´ticos y relacionales: e X=Y.Sino. que se intentar´ hacer coincidir con X a X & Y. o u call(X). operador de divisi´n entera o X mod Y. operador de resto de la divisi´n entera o X ** Y. operador de divisi´n o X // Y. operador de exponenciaci´n o X ^ Y.Y. evalua la expresi´n X en un n´mero en coma flotante o u truncate(X). X toma los valores enteros comprendidos entre M y N round(X). arcotangente (´ngulo en radianes) de la expresi´n X a o log(X). trunca la expresi´n X en un n´mero entero o u floor(X). Z es la concatenaci´n de las listas X e Y o member(X. seno de la expresi´n X (´ngulo en radianes) o a cos(X). constante matem´tica e (2. constante matem´tica π (3. la semilla es determinada por el reloj del sistema cuando se arranca SWI-Prolog between(M.718282) a 7. devuelve el valor absoluto de la expresi´n X. 1 si X >0 y 0 si X = 0 min(X. borra el elemento Y de la lista X y da como resultado la lista Z 47 .Y). e elevado al resultado de la expresi´n X o pi. devuelve el menor de X e Y max(X. arcocoseno (´ngulo en radianes) de la expresi´n X a o atan(X). Funciones aritm´ticas: e abs(X). X es uno de los elementos de la lista Y delete(X.Z).Y.X). se cumple si X es una lista o la lista vac´ [] ıa append(X.Y). coseno de la expresi´n X (´ngulo en radianes) o a tan(X).Z).N. arcoseno (´ngulo en radianes) de la expresi´n X a o acos(X). logaritmo en base 10 de la expresi´n X o exp(X).Y.141593) a e.Y). evalua la expresi´n X y la redondea al entero m´s cercano o a integer(X). X es la cabeza e Y la cola de la lista is list(X). evalua la expresi´n X y tiene ´xito si el resultado es entero o e float(X). devuelve un entero aleatorio i ( 0 =<i <X ). ra´ cuadrada de la expresi´n X ız o sin(X). logaritmo neperiano de la expresi´n X o log10(X). o sign(X).6. devuelve el mayor de X e Y random(X). tangente de la expresi´n X (´ngulo en radianes) o a asin(X). devuleve el menor n´mero entero mayor o igual que el resultado u de la expresi´n X o sqrt(X). devuelve -1 si X <0. devuleve el mayor n´mero entero menor o igual que el resultado de u la expresi´n X o ceiling(X). Manejo de listas: [X|Y]. Z).Y). selecciona el elemento X de la lista Y y da como resultado la lista Z nth0(X.Z).Y).Y. Y es la longitud de la lista X merge(X.). Y es la lista ordenada de X findall(X.Y).). escribe en el canal de salida activo. escribe el t´rmino X en el canal de salida activo e write ln(X).Y). X es el ultimo elemento de la lista Y ´ reverse(X. siendo X e Y listas ordenadas. y retorna al teclado 48 . Y es la lista invertida de X length(X. se cumple si X puede hacerse corresponder con el siguiente car´cter a encontrado en el canal de entrada activo (en c´digo ASCII) o get(X). escribe X espacios en el canal de salida activo write(X). Z es la lista ordenada con los elementos de ´mbas a sort(X. lee el siguiente t´rmino del canal de entrada activo e put(X).help(setof). escribe el t´rmino X en el canal de salida activo.Y).Y. setof/3. Predicados de Entrada/Salida: get0(X).select(X. escribe el entero X como un car´cter en el canal de salida activo a nl. Manejo de ficheros: see(X). el elemento X-´simo de la lista Y es Z (empezando en 0) e nth1(X.Z).help(bagof).Y. consultar ayuda (?.Z).Z). consultar ayuda (?.Y.Z).Y. escribe el t´rmino X en el canal de salida activo y salta la l´ e ınea writef(X. abre el fichero X y lo define como canal de entrada activo seeing(X). genera una nueva l´ ınea en el canal de salida activo tab(X). pasando por alto e las declaraciones de operadores 9. xe cumple si X puede hacerse corresponder con el siguiente car´cter a imprimible encontrado en el canal de entrada activo skip(X). 8. Z es la lista de objetos X que satisfacen Y bagof/3. cierra el canal de entrada activo. se cumple si el nombre del canal de entrada activo coincide con X seen. siendo X el formato e Y la lista con los argumentos a escribir display(X). el elemento X-´simo de la lista Y es Z (empezando en 1) e last(X.Y). Y es la lista ordenada de X (sin elementos duplicados) msort(X. lee y pasa por alto todos los caracteres del canal de entrada activo hasta que encuentra un car´cter que coincida con X a read(X). Z es la lista de objetos X que satisfacen Y findall(X.Y. L.A). se escriben en el fichero de salida activo todas ´ las cl´usulas que tienen como predicado dicho ´tomo a a clause(X.Y). que pasa a ser la pantalla 10.E. el argumento n´mero N de la estructura E es A u E=. Maninpulaci´n de la Base de Conocimiento: o listing. siendo X un atomo.N). se cumple si X coincide con el nombre del canal de salida activo told. los caracteres del atomo A tienen por ASCII los n´meros de la lista ´ u L 12.F. generando la traza de la ejeo cuci´n de las metas siguientes o trace(X). retira de la Base de Conocimiento todas las cl´usulas del predia cado X abolish(X.. predicado univ.tell(X). Construcci´n y acceso a componentes de estructuras: o functor(E. se escriben en el fichero de salida activo todas las cl´usulas a listing(X). se hace coincidir X con la cabeza e Y con el cuerpo de una cl´usula existente en la base de conocimiento a assert(X). activaci´n de un seguimiento exhaustivo. permite eliminar todas las cl´usulas de la base de conocimiena to que emparejen con X abolish(X). desactiva el seguimiento mientras dure la llamada al objetivo X 49 .L). desactiva el seguimiento exhaustivo notrace(X). permite a˜adir la nueva cl´usula X al principio de la base de n a conocimiento assertz(X). permite a˜adir la nueva cl´usula X al final de la base de conocin a miento retract(X). activaci´n de un seguimiento del predicado X o notrace. retira de la Base de Conocimiento todas las cl´usulas del prea dicado de nombre X y n´mero de argumentos Y u 11. L es la lista cuya cabeza es el functor de la estructura E y la cola sus argumentos name(A. permite eliminar la primera cl´usula de la base de conocimiento a que empareje con X retractall(X). abre el fichero X y lo define como canal de salida activo telling(X). Depuraci´n de programas Prolog: o trace. E es una estructura con nombre F y n´mero de argumentos u N arg(N. permite a˜adir la nueva cl´usula X a la base de conocimiento n a asserta(X).Y). cierra con un fin de fichero el canal de salida activo. spy(X). ?. elimina los puntos esp´ especificados ıa nospyall. ¬Nm A. ¬Nm } ¬∃(¬N1 ∧ · · · ∧ ¬Nm ) f´rmula o program. . . fijaci´n de puntos esp´ en el predicado X o ıa nospy(X). ¬Nm f´rmula o cl´usula de Horn a ∀(A ∨ ¬N1 ∨ · · · ∨ ¬Nm ) regla {A. ver el estado del depurador y los puntos esp´ se han establecido ıa hasta el momento debug. .¬N1 . . inicia el depurador nodebug. . . . . . ¬Nm ¬∃(¬N1 ∧ · · · ∧ ¬Nm ) 50 . . . desactiva el depurador B. . Notaci´n comparativa entre L´gica y Prolog o o Prolog A :. . l´gica o ∀(A ∨ ¬N1 ∨ · · · ∨ ¬Nm ) regla A ← ¬N1 .¬N1 . ¬Nm ∀((¬N1 ∨ · · · ∨ ¬Nm ) → A) hecho ∀(A) A← ∀(¬N1 ∨ · ∨ ¬Nm ) objetivo ← ¬N1 . . ¬Nm } ∀((¬N1 ∨ · · · ∨ ¬Nm ) → A) hecho ∀(A) {A} ∀(¬N1 ∨ · ∨ ¬Nm ) objetivo {¬N1 . . . . . ¬N1 . . elimina todos los puntos esp´ ıa debugging. . . . . .
Copyright © 2024 DOKUMEN.SITE Inc.