Manual de Prolog
Manual de Prolog
Manual de Prolog
Programacin Lgica
Indice
PROGRAMACIN LGICA.........................................................................................................................................................1 INDICE..................................................................................................................................................................................................1 1. INTRODUCCION A LA PROGRAMACION LOGICA ......................................................................................................2 2. LOGICA PROPOSICIONAL..................................................................................................................................................... 3 3. INTRODUCCION A PROLOG ................................................................................................................................................. 4 4. CALCULO DE RELACIONES ................................................................................................................................................. 6 4.1 RELACIONES ............................................................................................................................................................................8 4.2 RELACIONES EN PROLOG ..................................................................................................................................................8 5. BUSCANDO LAS SOLUCIONES .........................................................................................................................................15 5.1. EL CONTROL EN PROLOG................................................................................................................................................16 5.2. EL BACKTRACKING...........................................................................................................................................................17 5.3. EL CORTE (!) ..........................................................................................................................................................................23 5.4. LA NEGACIN COMO FRACASO...................................................................................................................................26 5.5. REALIZANDO EL SEGUIMIENTO DE UN PROGRAMA ..........................................................................................26 6. ESTRUCTURA DE UN PROGRAMA EN PROLOG.........................................................................................................26 7. OBJETOS COMPUESTOS ......................................................................................................................................................36 8. RECU RSIVIDAD.......................................................................................................................................................................37 9. LISTAS.........................................................................................................................................................................................40 PARTE PRACTICA .......................................................................................................................................................................45 SOLUCIONES ................................................................................................................................................................................50 REFERENCIAS Y FUENTES................................................................................................................................................................64
Una forma de razonar para resolver problemas en matemticas se fundamenta en la lgica de primer orden. El conocimiento bsico de las matemticas se puede representar en la lgica en forma de axiomas, a los cuales se aaden reglas formales para deducir cosas verdaderas (teoremas) a partir de los axiomas. Gracias al trabajo de algunos matemticos de finales del siglo pasado y principios de ste, se encontr la manera de automatizar computacionalmente el razonamiento lgico, particularmente para un conjunto significativo de la lgica de primer orden, que permiti que la lgica matemtica diera origen a otros tipos de lenguajes de programacin, conocidos como lenguajes lgicos. Tambin se conoce a estos lenguajes como lenguajes decla rativos, porque todo lo que el programador tiene que hacer para solucionar un problema es describirlo va axiomas y reglas de deduccin. En los lenguajes lgicos se utiliza el formalismo de la lgica de primer orden para representar el conocimiento sobre un problema y para hacer preguntas que, si se demuestra que se pueden deducir a partir del conocimiento dado en forma de axiomas y de las reglas de deduccin estipuladas, se vuelven teoremas. As se encuentran soluciones a problemas formulados como preguntas. Con base en la informacin expresada dentro de la lgica de primer orden, se formulan las preguntas sobre el dominio del problema y el intrprete del lenguaje lgico trata de encontrar la respuesta automticamente. El conocimiento sobre el problema se expresa en forma de predicados (axiomas) que establecen relaciones sobre los smbolos que representan los datos del dominio del problema. Este concepto de programacin lgica est ligado histricamente a un lenguaje llamado Prolog, que proviene de PROgra mmation en LOGique (programacin en lgica), que fue el primer lenguaje de programacin lgico y el ms conocido y utilizado. Este lenguaje fue desarrollado por el Grupo de Inteligencia Artificial de la Universidad de Marseille, dirigido por Alain Colmerauer, en 1972. Prolog es utilizado para el desarrollo de aplicaciones de inteligencia artificial debido a su forma de representar el conocimiento, facilitando las bsquedas en bases de datos, la escritura de compiladores, la construccin de sistemas expertos, el procesamiento de lenguaje natural y la programacin automtica. Tambin es muy adecuado para las aplicaciones que implican bsqueda de patrones, bsqueda con rastreo inverso o informacin incompleta. Asimismo es el lenguaje escogido por Japn como piedra angular de los sistemas de computacin de quinta generacin.
Pag.2
Dice Alain Colmerauer en [1]: "Se suele preguntar cul es la diferencia entre Prolog y los otros lenguajes de programacin y de dnde viene su supuesto poder. Prolog naci de un desafo: crear un lenguaje de muy alto nivel, aun cuando fuera ineficiente para los informticos de la poca. La eficiencia consista entonces en que una mquina ejecutara muy rpidamente programas laboriosamente escritos. El reto consista en poder escribir rpidamente los programas dejando a la mquina su laboriosa ejecucin. Una vez liberados de esa obsesin por la eficiencia, se pudo recurrir a los formalismos y mecanismos de inferencia de la lgica matemtica; mecanismos ciertamente ineficientes, pero poderosos sin lugar a dudas. De ah viene el nombre de Prolog Programacin en lgica. Ahora bien, si se considera lo que sucede a nivel de la mquina, resulta que sta deber ser mucho ms inteligente de lo normal: debe ser no -determinista, es decir, capaz de explorar muchas posibilidades y debe poder resolver miles y miles de pequeas ecuaciones. Estas ecuaciones introducen incgnitas, que no son otra cosa que las variables del programa, pero distan mucho de ser las variables habituales que designan localidades de memoria. El programador que llega a Prolog desde un lenguaje clsico, experimenta una revelacin semejante a la del escolar que pasa de la aritmtica a los primeros rudimentos del lgebra. Puede representar como incgnitas aquellas entidades cuyos valores busca, establecer ciertas relaciones entre esas incgnitas y, sin tener que detallarlos, dejar que la mquina considere todos los casos posibles y aportar todas las posibles soluciones... Qu ms se puede pedir?" 2. LOGICA PROPOSICIONAL La programacin lgica tiene sus orgenes en los trabajos de prueba automtica de teoremas. Para esto se utiliza una nica regla de inferencia llamada principio de resolucin1, mediante la cual la prueba de un teorema puede ser llevada a cabo en forma automtica. La resolucin es una regla que se aplica sobre las frmulas surgidas de la lgica de primer orden y la demostracin de teoremas mediante esta regla de inferencia se lleva a cabo por reduccin al absurdo. La lgica de primer orden o lgica proposicional es uno de los formalismos ms utilizados para representar conocimiento en Inteligencia Artificial. Esta lgica es la que utiliza proposiciones y nexos entre stas para expresar sus verdades. Las proposiciones equivalen a frases u oraciones del lenguaje hablado, mientras que los nexos a travs de los cuales puede relacionar estas proposiciones son la conjuncin (y), la disyuncin (o) y la implicacin (si). Cuenta con un lenguaje formal mediante el cual es posible representar frmulas llamadas axiomas o predicados, que permiten describir fragmentos del conocimiento, y adems
Pag.3
consta de un conjunto de reglas de inferencia que aplicadas a los axiomas, permiten derivar nuevo conocimiento. El lenguaje formal de la lgica proposicional o lgica de primer orden es el Lenguaje de Primer Orden (LPO). En realidad ste no es un lenguaje simple, sino que es una familia de lenguajes, donde todos sus miembros tienen una gramtica similar y comparten ciertos tems importantes de su vocabulario. De todos modos nuestro estudio se centrar en un lenguaje genrico de primer orden, que es el que luego podremos aplicar en los programas de Prolog. Los enunciados ms bsicos de LPO son los enunciados atmicos. Estos se corresponden a los enunciados ms simples del espaol, enunciados que consisten en algunos nombres conectados por algn predicado. Ejemplos de este tipo son Juan corri, Juan vio a Ana y Ana regal flores a Juan. En LPO, los enunciados atmicos son formados tambin combinando nombres (o constantes individuales, tal como suelen llamarse) y predicados, aunque como posteriormente veremos difieren un poco en el modo en que son combinados. 3. INTRODUCCION A PROLOG Prolog es un lenguaje de programacin declarativo basado en la lgica de primer orden, particularmente en una restriccin de la forma clausal de la lgica. Fue desarrollado por Alain Colmerauer en 1972 en la Universidad de Marseille, Francia. Usa como regla de inferencia el principio de resolucin propuesto por Robinson en 1965. La representacin del dominio se realiza a travs de hechos y reglas. Decimos que es declarativo porque no es imperativo. Es decir, cada lnea de programa Prolog es una declaracin, no una orden. Se tiene as un conjunto de aseveraciones expresadas simblicamente, que expresan conocimientos de una situacin real o ficticia. Para esto se usa la lgica de predicados de primer orden que se expuso anteriormente. Prolog es un lenguaje de programacin hecho para representar y utilizar el conocimiento que se tiene sobre un determinado dominio. Ms exactamente, el dominio es un conjunto de objetos y el conocimiento se representa por un conjunto de relaciones que describen las propiedades de los objetos y sus interrelaciones. En Prolog, el programa (las reglas que definen las propiedades y relaciones entre los objetos) est muy alejado del modelo Von Newman que posee la mquina en la que tienen que ser interpretados. Debido a esto, la eficiencia en la ejecucin no puede ser comparable con la de un programa equivalente escrito en algn lenguaje imperativo o procedural. El beneficio es que aqu ya no es necesario definir el algoritmo de solucin, como en la programacin imperativa,
Pag.4
sino que lo fundamental es expresar bien el conocimiento que se tenga sobre el problema que se est enfrentando. Prolog forma su lenguaje a partir de un alfabeto que contiene slo dos tipos de smbolos: 1. smbolos lgicos, entre los que se encuentran los smbolos de constantes proposicionales true y false (verdadero y falso); los smbolos para la negacin, la conjuncin, la disyuncin y la implicacin (que en Prolog se denota con los caracteres :-); los smbolos de cuantificadores; y los smbolos auxiliares de escritura como corchetes [,], parntesis (,) y coma. 2. smbolos no lgicos, agrupados en el conjunto de smbolos constantes; el conjunto de smbolos de variables individuales (identificadores); el conjunto de smbolos de relaciones n-arias; y el conjunto de smbolos de funciones n-arias. A partir de estos smbolos se construyen las expresiones vlidas en el LPO de Prolog: los trminos (nombres) y las frmulas (predicados). Este LPO posee un amplio poder de expresin, ya que los trminos permiten hacer referencia (nombrar) todos los objetos del universo, mientras que las frmulas (predicados) permiten afirmar o negar propiedades de estos o bien establecer relaciones entre los objetos del universo. Existen muchas versiones de Prolog, algunas de las ms conocidas para PC se muestran en la tabla 1. En Prolog de Edimburgo, versin de Prolog diseada por David Warren que se ha convertido en estndar, un trmino es cualquiera de las tres expresiones siguientes: una constante, como el nmero "100"; la palabra "antonio" y la letra "c"; o una variable, por ejemplo "X" (notar que los identificadores que comienzan con mayscula representan, siempre, variables). En cambio, un predicado atmico o elemental es una expresin de la forma "R(a1, a2,..., an)" donde R es un smbolo de predicado n-ario que como vimos, denota alguna relacin entre objetos o alguna propiedad de un objeto, y a1, a2,..., an son trminos funcionando como argumentos. Los conceptos generales de este apunte los explicaremos con Turbo Prolog, basado ste en Prolog de Edimburgo. TABLA 1. ALGUNAS VERSIONES DE LENGUAJE PROLOG PARA PC
Pag.5
Arity Prolog Cogent Prolog IF Prolog Quintus Prolog Turbo Prolog PIE Prolog 4. CALCULO DE RELACIONES
(Arity Corp) (Amziod) (InterFace Computer Inc.) (Quintus Corp.) (Borland International) (versin shareware)
La programacin lgica trabaja ms con relaciones que con funciones. Se basa en la premisa de que programar con relaciones es ms flexible que programar con funciones, debido a que las relaciones tratan de forma uniforme a los argumentos y a los resultados. De manera informal, las relaciones no tienen sentido de direccin ni prejuicio alguno acerca de qu se calcula a partir de qu. En Prolog se utiliza slo un tipo determinado de reglas para definir relaciones, llamadas clusulas de Horn2, llamadas as en honor al lgico Alfred Horn, quien las estudi. Estas reglas estn compuestas por dos partes: el consecuente y el antecedente. El consecuente, que es la primera parte de la clusula, es lo que se quiere probar, la conclusin de la regla. El antecedente es la condicin que determinar en qu casos el consecuente es verdadero o falso. Esta estructura de clusula es de la forma: conclusin si condicin La resolucin de una de estas clusulas podra considerarse como la invocacin a un procedimiento, que sera el encargado de comprobar qu valor de verdad posee la condicin (o condiciones), para luego asignar el resultado lgico de esa evaluacin al objeto que se halla a la izquierda de la implicacin si (el consecuente o conclusin). Las reglas que gobiernan esta asignacin, en el caso de existir ms de una condicin, son las que rigen la Lgica de Primer Orden, con idnticos operadores y precedencias entre ellos.
Pag.6
Es posible que, para verificar una condicin, deban verificarse primeramente una o varias sub -condiciones. Esto equivaldra a la llamada de varios subprocedimientos para completar la ejecucin de un procedimiento padre. Las clusulas de Horn permiten crear un lenguaje de primer orden con una sintaxis rgida (se debe respetar siempre la estructura de antecedente consecuente) pero con un gran poder de expresin, ya que nos deja representar todo el conocimiento necesario como cualquier otro LPO. Estas clusulas pueden adoptar las siguientes formas: conclusin B--Afirmacin Hecho
Implicacin Regla
Afirmacin: Cuando escribimos slo la conclusin, estamos afirmando algo que no necesita ser probado. Esto significa que estamos diciendo una verdad que no debe ser comprobada, que no tiene condicin de valides. Por ejemplo : mujer (ana) con lo que decimos que ana posee la propiedad de ser mujer, sin que se deba satisfacer ninguna condicin. Estos casos particulares de clusulas sin condicin son llamados hechos, porque son verdades por si mismas. Implicacin: Afirmacin condicional, donde el predicado B es verdadero si A1,A2,...,An son verdaderos conjuntamente. Cuando escribimos la clusula completa, estamos escribiendo un hecho condicional, llamado predicado con consecuente en la lgica de primer orden. Con este tipo de estructuras manifestamos que un objeto puede poseer cierta propiedad o que puede existir cierta relacin entre objetos si se cumple la condicin. Entonces, para expresar la idea de que Si pedro es hombre entonces pedro es racional, deberamos escribir una clusula como la siguiente : racional (pedro) si hombre (pedro) lo que indica que pedro es racional slo si es hombre. NEGACION: A1,A2,...,An Clusula objetivo o goal. Cada uno de los predicados A1,Aa2,...,An de la clusula son denominados subobjetivos. Esta es en realidad la clusula que queremos probar del conjunto de sentencias del programa.
Pag.7
Se deduce que en la prueba del objetivo se esta empleando el principio de resolucin de Robinson. Se niega la clusula que se desea probar y se la agrega a las clusulas del programa. Luego se aplican las reglas de resolucin y, al derivarse una clusula nula, queda demostrado que la clusula original es verdadera. 4.1 RELACIONES Resumiendo, el conjunto de reglas que define las relaciones y las propiedades de los objetos es el programa en Prolog. Por ejemplo, segn vimos cuando decimos "Juan es padre de Pablo" no estamos haciendo ms que afirmar que una relacin (ser padre) liga dos objetos (designados por sus nombres: Juan y Pablo), y esta relacin se puede escribir como: es_padre_de (pablo, juan) Igualmente, la respuesta a una pregunta del tipo "Quin es el padre de Pablo?" se reduce a comprobar si la relacin es_padre_de liga a Pablo con otro objeto, que ser la respuesta a la pregunta. No debemos olvidar que cuando se define una relacin entre objetos, el orden que se da a estos es releva nte: es_padre_de (pablo, juan) puede significar que "Pablo es padre de Juan" o que "Juan es padre de Pablo", ya que la relacin tiene un solo sentido. Es el programador el que ha de decidir cul de las dos es la interpretacin a usar. Ahora bien, una vez elegida la interpretacin, sta es definitiva. En el ejemplo anterior se han utilizado identificadores para nombrar a los objetos y a la relacin que los liga. En Prolog, el nombre de la relacin (es_padre_de) se denomina predicado, y los nombres que vincula (Juan y Pablo), argumentos. 4.2 RELACIONES EN PROLOG Antes de estudiar la forma en que se construyen las clusulas en Prolog, veremos cmo se escriben en este lenguaje los operadores lgicos para la conjuncin, la disyuncin y la implicacin:
Para conocer la forma de trabajar de Prolog, vamos a comenzar viendo un primer ejemplo que describe la carta de un restaurante. Los objetos que interesan aqu son los platos que se pueden consumir y una primer serie de relaciones que clasifica estos platos en entradas, platos a base de carne o de pescado (plato fuerte) y postres. Este men es un pequeo banco de datos q ue se expresa de la siguiente manera: entrada(antipasto). entrada(sopa). entrada(quesos).
pescado(congrio). pescado(pejerey).
Se podra decir que esto ya es un programa en Prolog, solo falta sierta estructuracin que ser vista mas adelante. Este programa esta compuesto por un conjunto de predicados que definen caractersticas de los objetos que poseen y los clasifican. Por ejemplo: entrada(antipasto). Indica que antipasto es una entrada y nada ms. En realidad este primer tipo de
Pag.9
regla se reduce a enunciar los hechos o declaraciones simples. Cuando se tienen estas clusulas, se pueden hacer preguntas sobre ellas. Una pregunta como: Es una e ntrada antipasto?. En prolog se hara de la siguiente manera: :-entrada(antipiasto). Ntese que, al contrario que las reglas, una pregunta comienza con :-, que es en Prolog el smbolo de la implicacin. Esto se debe a que sta es una clusula incompleta que posee slo el consecuente si antipasto es entrada, que es lo que se desea averiguar. A las clusulas de este tipo se las llama goals o clusulas objetivo, ya que son el objetivo, el problema para el que fue escrito el programa. Se busca entonces si esta afirmacin forma parte de las conocidas, la respuesta es True (Verdadero), respuesta que indica que s es verdadera esa afirmacin. Sin embargo, :- entrada(ensalada). recibir una respuesta negativa (False o Falso), ya que esta entrada no se encuentra entre las declaraciones de la base. Estas dos preguntas que realizamos tambin son llamadas consultas de existencia, porque slo verifican la existencia de hechos y/o relaciones que satisfagan la pregunta formulada. Si ahora queremos saber cules son las entradas que se pueden consumir y no se desea preguntar por separado por las infinitas entradas posibles, esperando una respuesta afirmativa (True) o negativa (False) en cada caso, entonces podemos preguntar: Cules son las entradas? o lo que es mejor Cules son los objetos X que son entradas? sin conocer al efectuar la pregunta qu objetos representa la X. El smbolo X no designa un objeto en particular, sino todo objeto perteneciente al conjunto (posiblemente vaco) de los que poseen la propiedad de ser una entrada y que se pide sea definido por el programa. En este caso se dice que la X es una variable. La pregunta del ejemplo se hara de la siguiente manera: :- entrada(X). Ante esta pregunta Prolog responder en la pantalla: X=antipasto X=sopa X=quesos
Pag.10
que es el conjunto de objetos que designa la variable X para que la declaracin pregunta se verifique. Desde el punto de vista sintctico, una pregunta es una secuencia de uno o ms trminos (metas u objetivos) que representa una conjuncin de relaciones a satisfacer. Las respuestas a esta pregunta son las restricciones sobre las variables que aparecen en la secuencia de metas y que satisfacen las relaciones consideradas. Se debe tener en cuenta que en Prolog la variables siempre comienzan con una letra mayscula, mientras que los predicados y los literales deben comenzar con minsculas. Entonces, las variables son un conjunto de una o ms letras, nmeros y guiones bajos (_), que comienzan con una letra mayscula. En cambio, los predicados y cadenas de literales deben comenzar con una letra minscula, pudiendo contener, adems de letras, nmeros y guiones bajos (_). (En realidad los predicados, y no las constantes literales, tambin pueden comenzar con maysculas, pero en aqu los vamos a escribir siempre en minsculas.) A partir de las relaciones que constituyen la base de datos inicial, se pueden construir relaciones ms complejas y generales. Por ejemplo, a partir de las relaciones carne y pescado, que indican que su argumento es un objeto que es un plato de carne o un plato de pescado, se puede definir la relacin plato_principal, que indicar que "un plato_principal es un plato de carne o un plato de pescado" y que se formula: plato_principal(P) :- carne(P). plato_principal(P) :- pescado(P). Aqu aparecen por primera vez las clusulas de Horn completas, con antecedente y consecuente, que son llamadas reglas. Estas reglas se interpretan as: P es un plato_principal si P es un plato de carne. P es un plato_principal si P es un plato de pescado. lo que indica que un objeto es plato_principal, si es un plato de carne o si es un plato de pescado. Debido a esto, el par de reglas se podra escribir de la siguiente manera plato_principal(P) :- carne(P); pescado(P).
Pag.11
aunque continuaremos utili zando la definicin inicial en pos de una mayor sencillez. En estas clusulas se utiliza la variable P para designar el conjunto de todos los platos de carne, en la primera regla, y todos los platos de pescado, en la segunda. El mbito de una variable se limita a la regla en la que est definida, por lo que la variable P de la primera regla de la definicin de plato_principal no tiene nada que ver con la variable P de la segunda. En este ejemplo, la pregunta " Cules son los platos principales?" formulada como: :- plato_principal(P). produce las respuestas P = milanesa P = bife_de_chorizo P = pollo_asado P = congrio P = pejerrey Tratamos a continuacin la composicin de una comida completa. Como es habitual, una comida consta de una entrada, de un plato fuerte (carne o pescado) y de un postre. Una comida es, por tanto, una terna: E,P,D, donde E es una entrada, P un plato y D un postre. Esto se expresa de forma natural por la regla: comida(E,P,D) :- entrada(E), plato_principal(P), postre(D). que se interpreta as: E,P,D satisfacen la relacin comida si E satisface la relacin entrada, si P satisface la relacin plato_principal y D satisface la relacin postre. Por tanto, se ha definido una nueva regla como la conjuncin de otras tres A la pregunta "Qu comidas hay?", formulada como: :- comida(E,P,D). Prolog responde: E=antipasto, P=milanesa, D=flan
Pag.12
E=antipasto, P=milanesa, D=helado ..... E=sopa, P=milanesa, D=fruta E=sopa, P=bife_de_chorizo, D=flan ..... E=quesos, P=congrio, D=flan E=quesos, P=congrio, D=helado ..... E=quesos, P=pejerrey, D=fruta
que es la lista de las 54 combinaciones posibles. Teniendo el mismo conjunto de relaciones definidas, se propone una pregunta un poco ms precisa: se desea conocer las comidas que contienen un plato de pescado. Esta pregunta se formula as: :- comida(E,P,D), pescado(P). que expresa la conjuncin de las dos condiciones que se quieren verificar. Prolog calcular los valores de las variables E,P,D para los que la primera condicin comida(E,P,D) se verifica. Se observa que antes de la evaluacin de la relacin comida, las variables E,P,D no han recibido todava ningn valor, lo que no ocurre despus de la evaluacin. En el momento en el que E,P,D han recibido ciertos valores, por ejemplo: E = antipasto P = milanesa D = flan se procede a evaluar la segunda parte de la pregunta, pescado(P) con el valor asignado a la variable P, entonces, esta seleccin se ha convertido en: pescado(milanesa)
Pag.13
Al no contener la base ninguna declaracin como sta, el juego de valores propuesto para E,P,D no satisface la pregunta: es un fallo y se intenta con la solucin siguiente para comida. Finalmente, el programa imprime las 18 soluciones posibles: E=antipasto, P=congrio, D=flan E=antipasto, P=congrio, D=helado E=antipasto, P=congrio, D=fruta E=antipasto, P=pejerrey, D=flan ..... E=sopa, P=congrio, D=flan E=sopa, P=congrio, D=helado ..... E=quesos, P=pejerrey, D=fruta Para tener en cuenta: Para satisfacer una conjuncin de relaciones, se examinan de izquierda a derecha. Durante la ejecucin, ciertas variables pueden recibir un valor. Si una variable recibe un valor, todas sus apariciones (o ms precisamente sus ocurrencias) toman el mismo valor. Las variables son locales a la regla en la que aparecen. Cada vez que se utiliza una regla, se tiene una nueva instancia de sus variables, exactamente igual como se hace para las variables locales en los lenguajes clsicos de programacin. En este caso, se dice que las variables de la regla han sido renombradas. En una relacin no hay distincin entre argumentos de entrada y argumentos de salida. Por tanto, una misma relacin puede tratarse de diversas formas: si todos sus argumentos son conocidos slo hay que verificar si la relacin se satisface o no; si algunos de sus argumentos son desconocidos (representados por variables), se calcula el conjunto de valores que se puede asignar a estos argumentos para satisfacer la relacin. La ejecucin es no determinista: se calculan todos los juegos de valores de argumentos que satisfacen la relacin.
Pag.14
Este men podra completarse con la informacin calrica de cada racin de cada plato, con un predicado que podra tener la siguiente forma: calorias(<comida>, <valor calrico>). que se interpreta como: "la racin de <comida> aporta <valor calrico> caloras". As, deber escribirse un hecho para todos y cada uno de los distintos platos que posee el men (antipasto, sopa, milanesa, pejerrey, flan, etc.), indicando cuntas caloras contiene cada uno, lo que queda de ejercicio para el lector. Con esto se podr averiguar el valor calrico total de una comida completa. Para esto ltimo se puede definir la relacin: valor(E,P,D,V) :- calorias(E,X), calorias(P,Y), calorias(D,Z), V = X+Y+Z. donde V es la suma de las caloras de los componentes de una comida. Para conocer estos valores se pregunta: :- comida(E,P,D), valor(E,P,D,V). lo que buscara todas las combinaciones posibles de comidas y calculara su valor calrico total. Ahora sera natural definir el concepto de comida equilibrada, cuando el valor calrico de una comida no excede las 800 caloras. La definicin de esta relacin queda como ejercicio para el alumno.
5. BUSCANDO LAS SOLUCIONES Hasta ahora hemos venido manejando slo objetos constantes, representados por sus nombres (pejerrey, pollo_asado, etc.). Sin embargo, la estructura que Prolog maneja ms naturalmente es el rbol. Las relaciones y sus argumentos se tratan como rboles, debido a que es una estructura suficientemente poderosa para representar informaciones complejas, organizadas jerrquicamente, y de manejo sencillo, tanto desde un punto de vista algebraico como desde un punto de vista informtico. Si representamos en forma de rbol uno de nuestros primeros ejemplos, es_padre_de(pablo, juan) que indica que Pablo es padre de Juan, tendramos algo como: es_padre_de
juan
pablo
Pag.15
Esta estructura, como veremos, es tambin utilizada a la hora de buscar las soluciones a los goals de un programa.
5.1. EL CONTROL EN PROLOG Por control se entiende la forma en que el lenguaje busca las respuestas a las clusulas objetivos. En Prolog, el control respeta dos normas: 1. Orden de metas. Escoger la meta del extremo izquierdo. 2.Orden de reglas. Seleccionar la primera regla aplicable. Qu significa esto? La primera de las normas nos indica que, cuando la clusula objetivo o goal posee ms de una regla unidas por conjunciones o disyunciones, estas se toman de izquierda a derecha para ser resueltas de a una, mediante la aplicacin de reglas. Entonces, si volvemos al primer ejemplo del men de un restaurante, para responder a la pregunta :- comida(E,P,D), pescado(P). Prolog toma en primer lugar la meta del extremo izquierdo (que es comida(E,P,D)) y la resuelve, para tomar luego la segunda de izquierd a a derecha (que es pescado(P)) y resolverla, y as sucesivamente hasta terminar con todas las submetas de la clusula objetivo. La segunda de las normas enunciadas ms arriba quiere decir que, para resolver cada una de las submetas, stas son reemplazadas por todas y cada una de las reglas de la base de datos que las satisfagan, teniendo en cuenta el orden en que estn escritas. As, por ejemplo, la primera de las submetas que Prolog toma (comida(E,P,D)), es reemplazada por el consecuente de la primer regla que la satisface, que es comida(E,P,D) :- entrada(E), plato_principal(P), postre(D). y sobre sta se vuelven a aplicar ambas normas, o sea que se toma entrada(E) y luego se la reemplaza por la primer regla que la satisfaga (si la hay), que en este caso sera entrada(antipasto). con lo que E asume un primer valor tentativo (antipasto) que puede ser o no vlido, dependiendo de todas las otras partes del goal. A la forma en que se van realizando los reemplazos la veremos con mayor detalle a continuacin, y es la tcnica conocida como backtracking o 'vuelta atrs'.
Pag.16
Concluyendo, podemos decir que si se tienen en cuenta las dos normas con que se maneja Prolog para encontrar las soluciones, se advierte que la respuesta a una pregunta se ve afectada por el orden de las metas dentro de la consulta y por el orden de las clusulas dentro de la base de datos de hechos y reglas. Es muy importante tener esto en cuenta ya que, debido a un orden errneo en la declaracin de las reglas o a una pregunta mal formulada, se pueden producir ciclos infinitos.
5.2. EL BACKTRACKING Para obtener las soluciones a las clusulas objetivo solicitadas, Prolog utiliza una tcnica de borrado que consiste en reemplazar cada submeta por los consecuentes de todas las reglas de la base que la satisfacen. Para poder hacer esto utiliza el backtracking, que es el mecanismo para la bsqueda de datos de Prolog, totalmente invisible para el usuario. De esta forma se verifica si existe cierto hecho determinado o si se cumple algn goal. Este mecanismo consiste en recorrer reiteradamente las clusulas, tratando de establecer si el objetivo actual puede considerarse como verdadero o falso. Entonces, si poseemos tres reglas P, Q y R, que son de la siguiente manera: P :- p1, p2,..., pm. (m>=0) P :- a1, a2,..., an. (n>=0) Q :- q1, q2,..., qs. (s>=0) R :- r1, r2,..., rt. (t>=0) donde P est definida de dos formas (recordar la definicin de plato_principal), y realizamos la pregunta :- P, Q, R. Prolog busca la solucin, aplicando el borrado de las submetas, respetando las dos normas del control indicadas ms arriba. As, toma la primera submeta de la izquierda (P) y la borra, esto quiere decir que la reemplaza por la primera regla de la base que la satisfaga, con lo que nuestra pregunta origina l ser ahora: :- p1, p2,..., pm, Q, R. Con esto se borra P, y se contina realizando lo mismo con las submetas del nuevo objetivo, hasta que no quede nada para borrar o hasta que se llegue a algo que no puede ser borrado. Esto ocurre cuando se llega a un hecho o
Pag.17
cuando se alcanza una contradiccin. De este modo, se borrara p1, luego p2, y as hasta terminar. Sin embargo, todava quedan posibilidades abiertas que no fueron tenidas en cuenta durante el proceso, como ser la segunda definicin de P. Entonces se vuelve atrs, se reconsidera la ltima eleccin y se intenta borrar el trmino en cuestin de otra manera para tratar de obtener otra respuesta a la pregunta. Entonces, se toma la segunda definicin de la regla P de la base de reglas (P :a1, a2,..., an.) obteniendo, en este caso, :- a1, a2,..., an, Q, R. para borrar luego nuevamente todas las submetas del nuevo objetivo, incluyendo Q y R. Se contina as hasta que no quede ningn punto de eleccin sin tener en cuenta. Es importante observar que en el momento en que se efecta una nueva eleccin para intentar borrar una submeta, se deshacen todas las asignaciones y modificaciones realizadas a las dems submetas, entre la eleccin anterior y el momento actual. Esta vuelta atrs o retroceso es lo que se denomina backtracking. Para comprender ms claramente este funcionamiento, veremos un ejemplo. Retomaremos el caso del men del restaurante donde poseemos, entre otras, las siguientes reglas: R1 carne(milanesa). R2 carne(bife_de_chorizo). R3 carne(pollo_asado). R4 pescado(congrio). R5 pescado(pejerrey).
R6 plato_principal(P) :- carne(P). R7 plato_principal(P) :- pescado(P). donde R1,..., R7 slo se agregan para numerar las reglas, y realizaremos la siguiente pregunta (conjunto inicial de metas): :- plato_principal(P), P<>milanesa. que equivale a decir cules son los platos_principales que no son milanesa. Se debe tener en cuenta que Prolog trata a todos los operadores (incluyendo a <> -
Pag.18
distinto a-) como reglas comunes, por lo que este goal posee dos reglas unidas por una conjuncin (y). El proceso de resolucin ser representado mediante un rbol, en el cual: A cada nodo se le asocia el conjunto actual de las metas a borrar y el conjunto de restricciones actuales C; A cada rama se le asocia la regla elegida para borrar la primer submeta del nodo superior; Los sucesores de un nodo son los nuevos conjuntos de objetivos generados por el borrado del primero de ellos de la lista asociada al nodo considerado. Esta rama es la que queda formada apenas Prolog comienza el anlisis de la pregunta. Lo primero que se hace es, partiendo desde el nodo de ms arriba hacia abajo, borrar plato_principal(P), reemplazndolo por el consecuente de la primera regla que lo satisface, que es la regla R6. O sea que se permuta el antecedente plato_principal(P) por su definicin relacional: carne(P) Este borrado de la primer submeta cambia nuestra pregunta inicial, que es lo que vemos en el segundo nodo, siendo ahora el objetivo: :- carne(P), P<>milanesa. Ahora debe borrarse nuevamente la primer submeta de este nuevo goal. Entonces se reemplaza carne(P) por la regla R1, que es la primera que la satisface. Llegamos as altercer nodo donde se presenta una restriccin, ya que la clusula R1 asigna ala variable P el valor milanesa. En este nodo nos queda la nueva clusula objetivo :- P<>milanesa. En esta nueva meta vemos que ya no aparece nada de la primer submeta que hemos borrado, como sucedi al pasar del nodo inicial al segundo nodo por la rama R6. Esto se debe a que llegamos a un hecho (R1) que se borra dejando nicamente la restriccin ya indicada. Entonces, respetando dicha restriccin, P toma el valor milanesa y obtenemos: :- milanesa<>milanesa. abreviado en el grfico como mil<>mil, que al borrarse (solucionarse) produce un fallo. Esto es lo que ocurre al realizarse los borrados de las submetas. Sin embargo,
Pag.19
todava no se consideraron otras reglas que podan reemplazar a las submetas borradas, ya que la base posee dos reglas que definen el plato pri ncipal y tres que definen el plato de carne. Aqu es donde aparece el backtracking retroceso). Como la ltima regla que se borr, teniendo otras posibilidades, fue carne(P), se realiza el retroceso subiendo un nodo desde el tercero y se vuelve a borrar esta submeta utilizando las otras opciones. En prime ra instancia se toma R2 que es la regla que sigue en la base, para luego repetir el proceso tomando R3. Estos borrados nos determinan el siguiente rbol:
plato principal (p), p<>milanesa C={}
R6
carne (p), p<>milanesa C={}
R1
mil <> mil C = {p= mil}
R2
bif <> mil C = {p= bif
R3
poll <> mil C = {p= poll}
Falk
xito P = bif
xito P = poll
Este segundo rbol es el que queda luego de hacer el backtracking para todas las diferentes definiciones del predicado carne( ). Aqu observamos que se presentaron dos xitos, dos valores de P que son vlidos. Estos valores sern los que Prolog nos ir mostrando en la ventana de resultados, de la siguiente manera: P = bife_de_chorizo P = pollo_asado Despus de este retroceso, Prolog intenta borrar de una manera diferente todas las submetas borradas en pasos anteriores. En este ejemplo, se puede utilizar la segunda definicin de plato_principal( )para realizar el backtracking. As se ampla el rbol para llegar finalmente a :
Pag.20
R6
carne (p), p<>milanesa C={}
R7
pescado (p), p<>milanesa C={}
R1
mil <> mil C = {p= mil}
R2
bif <> mil C = {p= bif}
R3
poll <> mil C = {p= poll}
R4
con <> mil C = {p= con}
R5
pej <> mil C = {p= pej}
Falk
xito P = bif
xito P = poll
xito
Exito
P = con P = pej
En esta nueva rama, se utiliza R7 para borrar la primer submeta de la clusula objetivo original, y se borra la nueva submeta de las dos maneras posibles (R4 y R5). Hemos encontrado as, a travs de esta tcnica, las cuatro soluciones posibles que se vern como P = bife_de_chorizo P = pollo_asado P = congrio P = pejerrey Para finalizar, se debe decir que cada rama del rbol se sigue extendiendo hacia abajo hasta que ocurre alguna de las siguientes cosas: La clusula objetivo del nodo actual est vaca. En este caso nos encontramos frente a un xito y la respuesta es la restriccin actual C. Se llega a alguna situacin donde una submeta no puede ser borrada (solucionada), por no existir una regla que lo permita. Esto es un fracaso. Ante ninguna de estas situaciones se parara el proceso ya que ste se detiene nicamente cuando se han revisado todas las opciones posibles de borrado. Lo unico que provocan es el abandono de la rama donde se present dicha
Pag.21
circunstancia, con un xito o un fallo, y el intento de abrir otra rama mediante el backtracking. Un ejemplo del primero de estos casos es el nodo
bif <> mil C = {p= bif}
donde, al borrar la meta bife_de_chorizo<>milanesa, nos queda el goal vaco, siendo esto un xito cuya solucin es la restriccin C. Como ejemplo para el segundo caso podemos tomar el nodo
mil <> mil C = {p= mil}
que tiene una meta que no se puede borrar, ya que el operador <> slo se borra cuando sus argumentos son distintos. Entonces, como tenemos un objetivo que no podemos borrar, estamos frente a un fallo y se debe abandonar esta rama del rbol e intentar por otra utilizando el backtracking. Otra explicacin, muy sencilla y con un ejemplo fcil de entender es la que encontramos en el sitio http://www.javiersuarezsanz.com/prolog/ y que citamos a continuacin textualmente:
El mecanismo empleado por PROLOG para satisfacer las cuestiones que se le plantean, es el de razonamiento hacia atrs (backward) comp lementado con la bsqueda en profundidad (depth first) y la vuelta atrs reevaluacin (backtracking). Razonamiento hacia atrs: Partiendo de un objetivo a probar, busca las aserciones que pueden probar el objetivo. Si en un punto caben varios caminos, se recorren en el orden que aparecen en el programa, esto es, de arriba a abajo y de izquierda a derecha. Reevaluacin: Si en un momento dado una variable se instancia con determinado valor con el fin de alcanzar una solucin, y se llega a un camino no satisfactorio, el mecanismo de control retrocede al punto en el cual se instanci la variable, la des-instancia y si es posible, busca otra instanciacin que supondr un nuevo camino de bsqueda. Se puede ilustrar esta estrategia sobre el ejemplo anterior: Supongamos la pregunta: ?-puede_casarse_con(maria,X). PROLOG recorre la base de conocimiento en busca de un hecho que coincida con la cuestin planteada. Lo que halla es la regla puede_casarse_con(X,Y) :- quiere_a(X,Y), varon(X), hembra(Y). producindose una coincidencia con la cabeza de la misma, y una instanciacin de la variable X de la regla con el objeto 'maria'. Tendremos por lo tanto: (1) puede_casarse_con(maria,Y) :- quiere_a(maria,Y), varon(maria), hembra(Y). A continuacin, se busca una instanciacin de la variable Y que haga cierta la regla, es decir, que verifique los hechos del cuerpo de la misma. La nueva meta ser: (2) quiere_a(maria,Y). De nuevo PROLOG recorre la base de conocimiento. En este caso encuentra un hecho que coincide con el objetivo: quiere_a(maria,enrique). instanciando la variable Y con el objeto 'enrique'. Siguiendo el orden dado por la regla (1), quedan por probar dos hechos una vez instanciada la variable Y: varon(maria), hembra(enrique). Se recorre de nuevo la base de conocimiento, no hallando en este caso ninguna coincidencia con el hecho 'varon(maria)'. Por lo tanto, PROLOG recurre a la vuelta atrs, desistanciando valor de la variable Y, y retrocediendo con el fin de encontrar una nueva instanciacin de la misma que verifique el hecho (2). Un nuevo recorrido de la base de hechos da como resultado la coincidencia con:
Pag.22
quiere_a(maria,susana). Se repite el proceso anterior. La variable Y se instancia con el objeto 'susana' y se intentan probar los hechos restantes: varon(maria), hembra(susana). De nuevo se produce un fallo que provoca la desinstanciacin de la variable Y, as como una vuelta atrs en busca de nuevos hechos que coincidan con (2). Una nueva reevaluacin da como resultado la instanciacin de Y con el objeto 'ana' (la ltima posible), y un nuevo fallo en el hecho 'varon(maria)'. Una vez comprobadas sin xito todas las posibles instanciaciones del hecho (2), PROLOG da por imposible la regla (1), se produce de nuevo la vuelta atrs y una nueva bsqueda en la base de conocimiento que tiene como resultado la coincidencia con la regla: (3) puede_casarse_con(maria,Y) :- quiere_a(maria,Y), hembra(maria), varon(Y). Se repite todo el proceso anterior, buscando nuevas instanciaciones de la variable Y que verifiquen el cuerpo de la regla. La primera coincidencia corresponde al hecho quiere_a(maria,enrique). que provoca la instanciacin de la variable Y con el objeto 'enrique'. PROLOG tratar de probar ahora el resto del cuerpo de la regla con las instanciaciones actuales: hembra(maria), varon(enrique). Un recorrido de la base de conocimiento, da un resultado positivo en ambos hechos, quedando probado en su totalidad el cuerpo de la regla (3) y por lo tanto su cabeza, que no es ms que una de las soluciones al objetivo inicial. X = enrique More (Y/N): y De esta forma se generarn el resto de las soluciones, si las hubiera. [NOTA: Algunas implementaciones PROLOG incorporan los comandos 'trace' y 'notrace' que activan y desactivan la salida por pantalla del proceso de bsqueda. No es el caso de PDPROLOG.]
Conclusin:
PROLOG utiliza un mecanismo de bsqueda independiente de la base de datos. Aunque pueda parecer algo retorcido, es una buena estrategia puesto que garantiza el proceso de todas las posibilidades. Es til para el programador conocer dicho mecanismo a la hora de depurar y optimizar los programas.
5.3. EL CORTE (!) Hemos visto que el borrado de un trmino del goal se hace en forma no determinista. Esto significa que se tienen en reserva en todo momento los diversos puntos de eleccin que se superaron para un posible retroceso posterior. La introduccin del corte (representado en Turbo Prolog por un !) en una regla permite suprimir algunos de estos puntos de eleccin, e incluso, hacer un programa enteramente determinista. Para comprender esto se deben tener en cuenta dos puntos Cada vez que se borra una meta, sta se coloca en la secuencia de puntos de eleccin, para poder realizar los retrocesos. El borrado de la meta del corte !' devuelve verdadero y suprime todos los puntos de eleccin que estaban almacenados, impidiendo el retroceso de las submetas anteriores a su aparicin.
Pag.23
Por ejemplo, si encerramos entre corchetes los puntos de eleccin que vamos superando y al lado de stos colocamos la lista de metas actual, al caso ya visto lo podemos modificar agregndole un corte como ltima meta :- plato_principal(P), P<>milanesa, !. cuya secuencia de elecciones y metas a borrar ser [] plato_principal(P), P<>milanesa, !. borrando la primer submeta por medio de R6 obtenemos un punto de eleccin y otra submeta [plato_principal(P)] carne(P), P<>milanesa, !. por medio de R1 borramos carne(P) y obtenemos [plato_principal(P) carne(P)] milanesa<>milanesa, !. lo que provoca un fallo y se retrocede al punto de eleccin pre cedente, quitndoselo de la lista [plato_principal(P)] carne(P), P<>milanesa, !. se vuelve a borrar carne(P), esta vez por medio de R2, obteniendo [plato_principal(P) carne(P)] bife_de_chorizo<>milanesa, !. ahora se borra el operador <> sin introducir nuevas elecciones, quedando slo [plato_principal(P), carne(P)] !. El ! se borra suprimiendo todas las elecciones en espera, no queda nada para borrar y, por haberse eliminado todos los puntos de eleccin que haba, no es posible realizar ningn retroceso . Por consiguiente, el rbol anterior se convierte en :
plato principal (p), p<>milanesa, ! C={}
R6
carne (p), p<>milanesa, ! C={}
R1
mil <> mil, ! C = {p= mil}
R2
bif <> mil, ! C = {p= bif Aqu se eliminan todos los puntos de eleccin que se estaban almacenando, por lo que no se podr retroceder por encima de este nodo.
Pag.24
! C = {p= bif}
Falk
xito P = bif
El borrado del ! tiene el efecto de suprimir todas las elecciones en espera, por lo que no se produce ms de una respuesta a la pregunta, que es la primera obtenida. Si el corte en vez de ponerse al final se hubiera ubicado en otro lugar, por ejemplo :- plato_principal(P), !, P<>milanesa. el rbol tendra la siguiente forma:
plato principal (p),!, p<>milanesa C={}
Aqu se eliminan todos los puntos de eleccin que se estaban almacenando, por lo que no se podr retroceder por encima de este nodo.
Falk Cuando se llega al ! se eliminan todos los puntos de eleccin que se almacenaban para poder hacer los retrocesos, por lo que no se pueden buscar ms soluciones y no se encuentra ninguna respuesta que satisfaga la pregunta. El resultado devuelto por esta consulta ser False (Falso).
Pag.25
5.4. LA NEGACIN COMO FRACASO Para comprender cmo trabaja la negacin en Prolog, se debe tener en cuenta que las reglas y el borrado pueden ser vistos de la siguiente manera: Las reglas de un programa son un conjunto de definiciones. Un objetivo que se borra es una frmula verdadera en relacin con estas definiciones. En efecto, borrar un objetivo equivale a demostrar que, para determinados valores de las variables, este objetivo se verifica. Por lo tanto, una consulta como not(P), donde not() es el operador de negacin del Prolog de Edimburgo, se trata como verdadera si el sistema fracasa en borrar P, o sea que equivale a decir 'Si no puedo probarlo debe ser falso'. Esto significa que no existe la definicin de P para el conjunto de valores que posee como argumentos y por lo tanto no puede ser borrado. Debe tenerse en cuenta que not() puede utilizarse nicamente para verificar valores conocidos o que se conocan antes de aplicar el not().
5.5. REALIZANDO EL SEGUIMIENTO DE UN PROGRAMA Turbo Prolog posee cuatro ventanas, una de las cuales est titulada como Trace. Esta ventana sirve para realizar el seguimiento de los pasos que realiza Prolog durante la resolucin de las clusulas objetivos planteadas. Si deseamos seguir paso a paso o realizar la traza de un programa, agregamos la instruccin Trace como primer instruccin al comienzo del cdigo. De esta forma, el programa se parar despus de cada paso realizado y nos mostrar en esta ventana lo que se ha realizado, indicando las llamadas a las distintas reglas, los valores retornados y los puntos donde se realiza el retroceso. Para probar esto, realice el seguimiento de los ejemplos utilizados para explicar el backtracking y el corte.
6. ESTRUCTURA DE UN PROGRAMA EN PROLOG Un programa en turbo-Prolog consta de cuatro secciones: domains, predicates, goal y clauses. Cabe aclarar que todas estas son palabras reservadas, y que toda otra palabra menos las variables deben escribirse en minsculas.
Pag.26
DOMAINS (dominio): Aqu se definen los objetos y los tipos de datos correspondientes que usaremos en las definiciones posteriores: domains objeto = tipo de dato Tipos de datos: Existen cinco tipos predefinidos : symbol : Hay dos tipos de smbolos : Una secuencia de letras, nmeros o caracteres de subrayado en la cual la primera letra es minscula. Ej. : tiene_lindas_piernas. Una secuencia de caracteres encerrados por comillas dobles () usada en el caso que el smbolo contenga espacios o no comience con minsculas. Ej. : Una persona es trabajadora. char : Acepta cualquier carcter, se representa encerrado entre comillas simples () y consta de un solo carcter, por ejemplo A, 2, /. integer : Acepta nmeros enteros en el rango de -32768 al 32767. real : Acepta nmeros reales, pueden contener signo, punto decimal y varios dgitos decimales. Tambin pueden tener una parte exponencial, pudiendo abarcar nmeros desde +1e-307 a +1e+308, por ejemplo : 427054, -25000, 86.25, - 8.525e-203 o - 8411.25658545. string : Acepta una secuencia de caracteres encerrados entre comillas dobles (), por ejemplo : esto tambin es un string. La diferencia entre el tipo symbol en 2, y los strings es la forma de representacin interna de cada uno. El almacenamiento de los smbolos est implementado de tal manera que su bsqueda en las tablas de memoria es ms rpida. Adems, los smbolos, tienen problemas para hacer inserciones en tiempo de ejecucin. Su uso estar determinado por el tipo de aplicacin que se realice. Por ejemplo: domains persona = symbol persona es un objeto de tipo symbol.
PREDICATES (predicados): En esta seccin se definen como sern las relaciones entre los objetos del dominio (domains) y el valor que se les asignar en las clusulas (clauses).
Pag.27
En una relacin no se puede poner nada que no sea del tipo definido para ella, pues el compilador Turbo Prolog dar error al comprobar tipos distintos. Por ejemplo : predicates sabe (persona) Aqu especificamos que el predicado sabe tiene un argumento: persona, que a su vez en el dominio est declarado como symbol. intelijente(persona). trabaja(persona). En este ejemplo hemos definido un objeto como smbolo y luego lo relacionamos con el predicado sabe. Tambin podemos definir un predicado solo con relacionar tipos predefinidos, como por ejemplo : factorial (integer, real) Esto hace que la relacin factorial se establezca entre 2 objetos, uno de tipo entero y otro de tipo real. GOAL (meta u objetivo a buscar): En esta seccin es donde se indica explcitamente cul es el objetivo o propsito del programa. Hay dos formas bsicas de trabajar en Prolog : Goal interno : Especificando en el programa en su seccin Goal un hecho a verificar. En este caso el mecanismo de bsqueda se detiene al encontrar el primer valor que lo cumpla, necesitando una indicacin explcita de impresin en pantalla para su representacin o visualizacin, si no est esa indicacin, responde slo con un mensaje de True o False, o no imprime mensajes. Goal externo : Trabajando a travs de la ventana de dilogo sin la seccin Goal en el programa, verificando y consultando hechos en forma interactiva. En este caso el mecanismo entrega todos los valores que lo verifiquen, y la bsqueda se detendr slo al agotarse las clusulas pertinentes. No necesita de rdenes especiales para vis ualizar los valores de variables hallados. Trabajando de cualquiera de las dos formas los objetivos podrn ser tan complicados como informacin se tenga en las clusulas. Siguiendo con el ejemplo, en nuestro caso el objetivo ser encontrar una persona que trabaja, da acuerdo al criterio de determinacin para ello que se establecer en la seccin Clauses.
Pag.28
trabaja (X) and write (La persona que trabaja es, X) and n1 Aqu vemos que hay algunos predicados que nosotros no definimos, como ser write y n1. Ambos pertenecen a los llamados predicados predefinidos y son propios del lenguaje Prolog. write hace lo mismo que idntica instruccin en Pascal o el print de BASIC : imprime un texto en la pantalla. n1 imprime solamente una secuencia de fin de lnea. El propsito de todo el conjunto es evaluar trabaja (X) e imprimir el resultado de ello con el mensaje entre comillas. Las respuestas se darn a travs de la ventana de dilogos o se deber armar una interfaz diferente. CLAUSES (Clusulas o definiciones de reglas y hechos): Aqu se definen las reglas y hechos que evaluar Turbo Prolog para encontrar las soluciones que se piden en Goal o por la ventana de Dilogos. Poniendo en castellano qu valores asignamos a los predicados de nuestro ejemplo : Jos sabe Ana sabe trabaja el que sabe y en turbo prolog : clauses sabe (Jos) sabe (Ana) trabaja (X) if sabe (X) trabaja (X) if sabe (X) se trata de una regla. Las reglas pueden tambin tener ms de una condicin para verific arse. Si por ejemplo nosotros ahora decidiramos que una persona para trabajar debe ser inteligente adems de saber, reemplazaramos la anterior por la siguiente regla : trabaja (X) if sabe (X) and inteligente (X) Veamos el ejemplo completo, escribie ndo un programa en Prolog en el que determinaremos como tiene que ser una persona para trabajar en una oficina :
domains persona = symbol predicates sabe (persona). trabaja (persona). inteligente (persona).
Pag.29
Universidad Tecnolgica Nacional Facultad Regional Crdoba tiene_lindas_piernas (persona). goal trabaja (X) and write ("La persona que trabaja es ",X). clauses sabe(jose). sabe(ana). inteligente(ana). inteligente(carlos). inteligente(silvia). tiene_lindas_piernas(silvia). trabaja (X) if sabe (X).
Si cargamos en el editor el programa anterior y lo compilamos, veremos los resultados como lo indica la figura siguiente.
Presionando la barra espaciadora volver al men principal. Si en nuestro ejemplo no existiera la seccin Goals, tras compilar el programa se activara la ventana de dilogos en que pondremos los hechos que queremos comprobar o consultar. Nos aparecer en esa ventana lo siguiente : Goal :_ Si nosotros ponemos este objetivo para nuestro ejemplo :
Pag.30
inteligente (Carlos) y presionamos ENTER es como si hubiramos preguntado es Carlos inteligente, o para ser mas exactos con la terminologa de la programacin lgica el objeto Carlos cumple la relacin inteligente. Como existe en la parte de las clusulas un hecho idntico, inmediatamente veremos como respuesta la palabra TRUE y volver a pedirnos otro Goal. Si ponemos ahora : inteligente (Jos) la respuesta ser False pues buscar en las clusulas esa relacin y no la encontrar. Podemos poner adems por ejemplo preguntas como : sabe (Ana) tiene_lindas_piernas (Ana) inteligente (Silvia) Estas preguntas pueden efectuarse siempre y cuando exista esa relacin definida en la seccin de predicados y tenga tambin al menos una clusula con ese nombre y cantidad de argumentos. Todas las preguntas de este tipo se llaman o bjetivos simples de verificacin de hechos pues su respuesta es true o false. Recordando que en Prolog toda palabra que tiene la primera letra en mayscula es una variable, veamos que ocurre si preguntamos lo siguiente : trabaja (Quien) La respuesta ser entonces : Quien = Jos Quien = Ana 2 solutions. La diferencia en la respuesta se debe a la diferencia entre los objetivos internos y externos, como ya vimos: Si el objetivo est incluido en el programa (en la seccin Goal), el mecanismo de bsqueda se detiene al encontrar el primer valor que lo cumpla. Si el objetivo es exterior al programa (ingresando por ventana Dialogo), la bsqueda se detendr slo al agotarse las clusulas pertinentes. En el caso del objetivo sabe (Quien) la mecnica es la siguiente : Prolog busca si la relacin est declarada en los predicados, luego ve que tenga igual cantidad de argumentos y asume que Quien es un smbolo por definicin de la relacin ; va entonces a las clusulas buscando aquellas de mismo nombre de relacin. Entonces Prolog instancia Quien al valor de la clusula. En otras
Pag.31
palabras : la variable Quien asume por primera vez el valor del argumento de la clusula (llamado vinculacin de un valor a una variable o binding), e informa a travs de la ventana de dilogos que ha encontrado una instancia de la pregunta, informa de ella y el valor temporal que ha asumido la variable y continua recorriendo las clusulas hasta el final. Prolog devolver as uno tras otro todos los casos que hagan verdad al objetivo, y su nmero. En el caso que ninguna instancia cumpla con los hechos de las clusulas, Prolog devolver False. Vemos as la importancia del orden en que se registran las clusulas en un programa Prolog. Si hubiramos invertido el orden de los hechos en el programa original, la respuesta hubiera sido : La persona que trabaja es Ana Hagamos ahora la siguiente pregunta : inteligente (Ana) and sabe (Ana) Aqu tenemos una pregunta de dos trminos, inteligente (Ana) y sabe (Ana), unidospor una operacin lgica de multiplicacin , and. La pregunta en lgica es : cumple el objeto Ana las relaciones inteligente y sabe ?. Prolog primero ve si se cumple la primera parte de la pregunta, si da verdadero (True), ve si se cumple la segunda y devuelve el resultado de la multiplicacin lgica (and). En nuestro caso, al cumplirse las dos da True. Si uno de los dos trminos da falso la respuesta es False Otros operadores lgicos son el or que nos da la suma lgica, y el not, negacin lgica. Todas las preguntas de este tipo las llamaremos Objetivos compuestos de verificacin de hechos. Ejemplos de objetivos de verificacin compuestos que dan True para nuestro caso en estudio son, entre otros : inteligente (Carlos) and inteligente (Silvia) trabaja (Jos) o trabaja (Carlos) tiene_lindas_piernas (Silvia) and (not sabe (Silvia)) Formulemos a continuacin la siguiente pregunta : inteligente (X) and not (sabe (X)) Prolog tomar el primer trmino y buscar el primer valor del primer objeto que cumpla esta condicin y lo reemplazar en el segundo trmino. Si comprueba que tambin se cumple devolver True.
Pag.32
En otras palabras : Prolog busca la primera clusula con nombre inteligente y reemplaza X con el valor del argumento de esta clusula, que en este caso es Carlos. Luego trata de comprobar la pregunta not (sabe (Carlos)) ; comprueba sabe (Carlos) , que por no existir da False, y tras aplicar not la respuesta ser True. Este valor, junto con la respuesta del primer trmino que da True, verifica la regla y devuelve la instancia X con el valor asignado temporalmente Carlos. Vemos que la diferencia entre reglas y hechos es que mientras los hechos describen una situacin clara, que no necesita comprobarse, las reglas por lo general son objetivos compuestos que deben verificarse. Por ejemplo las siguientes reglas : jefe (X) if inteligente (X) and not (trabaja (X)) jefe (X) if inteligente (X) and not (sabe (X)) Ambas describen la misma situacin : X es jefe si es inteligente y no trabaja o no sabe, ya que si no sabe no trabaja. Tomemos un segundo ejemplo para otra serie de explicaciones.
domains marca, color = symbol modelo = integer precio, kilometraje = real predicates auto (marca, kilometraje, modelo, color, precio) clauses auto (peugeot_404,90000,1980,azul,15000) auto (ford_taunus,13800,1986,rojo,30000) auto (renault_12,90000,1984,gris,25000) auto (dodge_1500,13000,1983,rojo,12000) auto (volkswagen,39000,1985,rojo,20000)
Podemos ver que hemos relacionado mas de un elemento en un predicado. As un auto tiene marca, kilometraje, modelo, color y precio. Con este ejemplo veremos mejor el tratamiento de variables y objetivos compuestos. Carguemos en memoria y compilemos este programa, y luego formulemos la siguiente pregunta : Cuales son los datos de los autos cuyo precio es menor a 20000 ? En Prolog puede escribirse as : auto (Marca, Kilmetros, Modelos, Color, Precio) and Precio < 20000
Pag.33
Como se ve, Marca, Kilmetros, Modelo, Color y Precio son variables por comenzar con maysculas. Cmo funciona Prolog aqu ?. Toma la primera clusula del predicado auto e instancia cada una de las variables a su correspondiente valor. De no ser compuesta la pregunta nos devolvera los valores hallados, pero en este caso comprobar si el Precio en esta clusula es menor a 20000. De cumplirse emitir la lista de datos, en caso contrario no ; pero de cualquier modo seguir con la clusula siguiente con la misma operacin hasta el fin de las clusulas. La respuesta ser : Marca = peugeot_404 Kilmetros = 90000 Modelo = 1980 Color = azul Marca = dodge_1500 Kilmetros = 13000 Modelo = 1983 Color = rojo Analicemos la forma en que expresamos el objetivo. Aqu utilizamos un objetivo compuesto que consta de dos condiciones : un predicado que debe verificarse comprobando los hechos de la seccin clusulas, y una variable que est limitada en los valores posibles que puede tomar. Esta es una de las formas ms comunes y tiles de utilizar las variables para especificar condiciones adicionales para un objetivo, sin apelar a otros predicados o a formular reglas innecesariamente complejas. Ahora bien, qu puedo hacer si lo nico que quiero saber es la Marca de los autos cuyo precio es mayor a 215000 ? Aqu aparecen las llamadas variables annimas representadas con el signo de subrayado (_) y significa que el argumento con la variable annima no interesa y puede contener cualquier tipo de dato. Entonces la pregunta ser la siguiente : auto (Marca,_,_,_,Precio) and Precio > 21500 La respuesta de Prolog ser : Marca = ford_taunus Precio = 30000 Marca = renault_12 Precio = 25000 Donde nos devuelve slo los valores que nos interesan, obviando los dems parmetros y sus valores. Debemos aqu hacer una advertencia sobre el uso de las llamadas variables nombradas. Estas variables son posicionales, es decir que su valor depender del lugar que ocupan entre los argumentos del predicado. Si pre guntsemos : auto (Marca,Precio,_,_,_) and Precio > 21500 La respuesta que podra tomarse equivocadamente como correcta sera :
Pag.34
Marca = renault_12 Precio = 90000 Marca = ford_taunus Precio = 13800 Otro error frecuente en el uso de estas variables es el siguiente. Supongamos que deseamos exhibir juntos aquellos autos que tengan el mismo color. Supongamos tambin que debemos exhibirlos de a dos a los de color rojo. Escribimos el Goal que genere todos los pares posibles que cumplan con esta condicin : auto (Marca_1,_,_,rojo,_) and auto (Marca_2,_,_,rojo) La respuesta de Prolog ser : Marca_1 = ford_taunus Marca_1 = ford_taunus Marca_1 = ford_taunus Marca_1 = dodge_1500 Marca_1 = dodge_1500 Marca_1 = dodge_1500 Marca_1 = volkswagen Marca_1 = volkswagen Marca_1 = volkswagen Marca_2 = ford_taunus Marca_2 = dodge_1500 Marca_2 = volkswagen Marca_2 = ford_taunus Marca_1 = dodge_1500 Marca_2 = volkswagen Marca_2 = ford_taunus Marca_2 = dodge_1500 Marca_2 = volkswagen
Sin dudas esta no es la solucin que estbamos buscando. En lugar de una nica Intentemos ahora colocar el siguiente objetivo externo : auto (Marca_1,_,_,rojo,_) and auto (Marca_2,_,_,rojo,_) and Marca_1 <> Marca_2 Obteniendo la respuesta : Marca_1 = ford_taunus Marca_1 = ford_taunus Marca_1 = dodge_1500 Marca_1 = dodge_1500 Marca_2 = dodge_1500 Marca_2 = volkswagen Marca_2 = ford_taunus Marca_2 = volkswagen
Pag.35
El Turbo Prolog, adems de trabajar con objetos simples, permite trabajar con argumentos ms complejos, como vimos e el ejemplo anterior. La representacin del conocimiento se puede simplificar utilizando objetos ms complejos. Un hecho simple es de la forma : predicado (arg_1, arg_2, ..., arg_N) Ejemplo. Trabaja (juan, panadera) Trabaja (luis, taller) Hay veces que necesitamos poner ms detalles, por ejemplo, podramos poner el nombre del lugar donde trabajan, el nmero y la categora, para esto es conveniente utilizar los objetos compuestos, el ejemplo quedara : trabaja (juan, panadera (sucursal, 12)) trabaja (luis, taller (seccin, 97, c)) Si observamos detenidamente el ejemplo notaremos que hay argumentos, panadera y taller, que estn actuando como predicados. A estos los denominamos functores y a sus argumentos componentes. Los hechos con objetos compuestos son de la forma : predicado (argumento, functor (componente, componente)) Declaraciones de predicados y dominios para objetos compuestos : Si se decide utilizar objetos compuestos, hay que poner especial atencin en la declaracin de predicados y dominios. Es necesario declarar cada functor y los dominios de todos sus componentes. Programa ejemplo, con la declaracin apropiada para objetos compuestos. domains lugar = panadera (nombre_area, nmero) taller (nombre_area, nmero, categora) nombre, nombre_area, categora = symbol
Pag.36
nmero = integer predicates trabaja (nombre, lugar) clauses trabaja (juan, panadera (sucursal, 12)) trabaja (luis, taller (seccin, 97, c)) - Ahora veremos que obtenemos con algunos objeti vos externos GOAL : trabaja (Quien, Donde) Quien = juan, Donde = panadera (sucursal, 12) Quien = luis, Donde = taller (seccion, 97, c) GOAL : trabaje (Quien, taller (En, Nro, Categora)) Quien = luis, En = seccin, Nro = 97, Categoria = c En estos dos objetivos externos podemos visualizar cmo, utilizando variables, se puede profundizar en los distintos niveles de los functores.
8. RECURSIVIDAD Si del lado derecho de una clusula aparece en algn punto el mismo predicado que figura del lado izquierdo, se dice que la clusula tiene llamado recursivo, es decir se llama a s misma para verificar que se cumple esa misma propiedad como parte de la condicin que define a la regla, y sobre algn posible valor de sus variables. El uso de recursividad es muy comn y suele ser imprescindible para de alguna manera simular esquemas de iteracin implcitos. Por ejemplo, si tenemos : progenitor(X,Y) :- padre(X,Y) progenitor(X,Y) :- madre(X,Y) que expresa que tanto X es padre de Y como X es madre de Y son condiciones suficientes para afirmar que X es progenitor de Y. Podemos definir :
Pag.37
antepasado(X,Y) :- progenitor (X,Y) antepasado(X,Y) :- progenitor (X,Z), antepasado (Z,Y) que dice que X es antepasado de Y si es progenitor de Y, o bien, si es progenitor de algn otro antepasado de Y. La palabra antepasado figura de ambos lados de una de las reglas. Supongamos ahora que contamos con una base de datos (hechos) que son ciudades, y deseamos hacer una lista de todos los caminos existentes de una ciudad a otra. Contamos para eso con rutas simples entre pares de ciudades. Por ejemplo : ruta (BsAs, LaPlata) ruta (BsAs, Jujuy) ruta (Miramar, BahaBlanca) ruta (BsAs, MardelPlata) ruta (BsAs, Miramar) ruta (MardelPlata, Miramar) ruta (LaPlata, Miramar) Digamos ahora que toda ruta es reversible, es decir si puedo ir de C1 a C2 (de la ciudad 1 a la 2), podremos volver por la misma ruta de C2 a C1. Eso se escribe as en Prolog : ruta (C1, C2) :- ruta (C2, C1) Por ltimo, para definir cundo un camino existe, podemos atravesar ciudades intermedias. Escribimos entonces : camino (C1, C2) : - ruta (C1, C2) camino (C1, C2) : - ruta (C1, C3), camino (C3, C2) que dice que existe un camino de la ciudad C1 a la ciudad C2 si hay una ruta (predefinida) entre ambas, o bien si hay una ruta desde la ciudad C1 hacia una ciudad C3, y desde sta hasta la ciudad C2. Vale decir, el llamado recursivo significa resolver el problema original mediante dar un paso hacia una posicin auxiliar y resolver el mismo problema desde e posicin (se supone que el sa problema se simplifica). Con estas definiciones, la respuesta ser afirmativa si consultamos : ? camino (BahaBlanca, Jujuy)
Pag.38
Otro ejemplo, definamos ahora que es un nmero par (positivo). Sabemos que el 0 es par, y que los dems pares se obtienen simplemente al ir sumando 2 a partir de un par conocido. Bien, prolog cuenta con tipos numricos y operaciones elementales predefinidas. Por ello, esto se puede lograr simplemente con : par (0) par (N) :- par (M), N = M + 2 que afirma que el 0 es par, y que si tenemos que M es par, entonces definiendo N = M + 2 ser tambin un nmero par. No siempre la recursividad es buena o garantiza xito en una bsqueda de solucin. Por ejemplo si ponemos: lindo (X) :- lindo (X) muchas versiones de prolog entraran en un ciclo infinito, ya que para buscar algo que sea lindo, la solucin es buscar algo que sea lindo, es decir el mismo problema sin cambio. Los siguientes ejemplos estn tomados del apunte de Paradigmas de programacin de nuestra misma facultad pero de la regional Buenos Aires y estn citados textualmente.
Tengo habitaciones conectadas entre s por puertas (como en el DOOM), y quiero llegar de una habitacin a otra, es decir, hallar un paso entre las habitaciones. Veo entonces las relaciones: puerta(Habitacion1, Habitacion2) paso(Habitacion1, HabitacionN). Como se define el paso? El paso entre dos habitaciones A y B es que haya una puerta entre las habitaciones (este es el CORTE DE LA RECURSIVIDAD), o bien que haya una puerta entre A y otra habitacin C y que desde esta haya paso a B. Por ejemplo: puerta(cuarto, pasillo). puerta(pasillo, banio). puerta(pasillo, cocina). puerta(cocina, living). paso(Habitacion1, Habitacion2):- puerta(Habitacion1, Habitacion2). paso(Habitacion1, Habitacion2):- puerta(Habitacion1, Habitacion3), paso(Habitacion3,Habitacion2). Otros ejemplos de funciones recursivas: Objetos que estn apoyados en objetos:
Pag.39
Un objeto se encuentra sobre otro objeto si: Est apoyado en ese objeto (corte recursivo). Est apoyado en algn objeto que est sobre el otro objeto. predicates apoyado(symbol, symbol). sobre(symbol, symbol). clauses sobre(UnObj, OtroObj):- apoyado(UnObj, OtroObj), !. sobre(UnObj, OtroObj):- apoyado(UnObj, ObjAuxiliar), sobre(ObjAuxiliar, OtroObj). Cosas dentro de cosas (idem). Personas atrs unas de otras (idem): Una persona est detras de otra si Esta "justo atras" de la otra. Est detras de una persona que est "justo atras" de la otra. Yo tengo un amigo que... si los amigos de mis amigos son mis amigos entonces... amigo(Yo, Otro):- MiAmigo(Yo, Otro),!. amigo(Yo, Otro):- MiAmigo(Yo, AlguienMas), amigo(AlguienMas, Otro).
9. LISTAS Listas : es un conjunto de elementos encerrados entre corchetes y separados por comas. Una lista de smbolos sera de la forma [elem_1, elem_2, ..., elem_N]. La lista vaca se representa con dos corchetes, [ ]. La manera ms sencilla de escribir listas es enumerar sus elementos. La lista que consta de tres tomos a, b y c puede escribirse como : [ a, b, c ] Tambin podemos especificar una secuencia inicial de elementos y una lista restante, separadas por |. La lista [a,b,c] tambin puede escribirse como : [a, b, c | [ ] ] [a, b | [c] ] [a, | [b, c] ] Un caso especial de esta notacin es una lista con cabeza H y cola T, representada como [H | T]. La cabeza puede usarse para extraer los componentes de una lista, de manera que no se requieren operadores especficos para extraer la cabeza y la cola. La solucin a la consulta :
Pag.40
? - [H | T] = [a, b, c] T = [b, c] H=a asocia la variable H con la cabeza y la variable T con la cola de la lista [a,b,c]. La consulta : ? - [a | T] = [H, b, c] T = [b, c] H=a ilustra la capacidad de Prolog para manejar trminos especificados parcialmente. El trmino [a | T] es la especificacin parcial de una lista con cabeza a y cola desconocida, denotada por la variable T. En forma similar, [H, b, c] es la especificacin parcial de una lista con cabeza H desconocida y cola [b, c]. Para unificar estas dos especificaciones, H debe denotar a a y T debe denotar a [b, c]. En Turbo Prolog es necesario declarar el dominio de toda lista que se maneje en un programa. No es complicado, solo se agrega un asterisco junto a la definicin del tipo de elementos de la lista. Quedara as : domains lista_enteros = integer * El manejo de listas en Turbo Prolog es muy simple, teniendo en cuenta que divide la lista en solo dos partes : cabeza y cola. - Cabeza : es el primer elemento de la izquierda - Cola : es el resto de la lista (es tambin una lista) Las listas pueden pasarse como argumento, solo hay que encerrarlas entre parntesis, o sea: predicado ([lista_1], [lista_2], ..., [lista_N]) Como vimos anteriormente, en Turbo Prolog se pueden hacer estructuras complejas. Se pueden poner objetos compuestos dentro de objetos compuestos. De la misma manera se pueden poner listas dentro de listas, es decir que cada elemento de la lista puede ser a su vez una lista. Todo esto que aparenta ser un tanto complicado, es en realidad muy simple, de hecho, unas de las grandes ventajas que tiene las listas en prolog es su fasil manejo. En trminos generales, la mecnica es:
Pag.41
Definir en los dominios (domains) la lista con su tipo de datos asociado. Definir un predicado para recorrer la lista. Definir al menos dos clusulas, una recursiva que indica como recorrer la lista pasa como argumentos cabeza y colo de la misma y eventualmente algunas variables mas y... Otra clusula que indica que hacer con una lista vaca.
Todo se ve mas claro cuando cund o vamos a los hechos... veamos un ejemplo de un problema resuelto con listas y sin listas. Supongamos tener una lista de materias del ciclo bsico y del ciclo superior. Ciclo Bsico geografa anatoma historia geometra botnica Ciclo Superior diseo clculo literatura taller tecnologa
Para ver si una materia pertenece a uno u otro ciclo superior, se podra hacer un listado de hechos simples que los describan:
domains materia = symbol predicates ciclo_basico (materia) ciclo_superior (materia) clauses ciclo_basico (geografa) ciclo_basico (anatoma) ciclo_basico (historia) ciclo_basico (geometra) ciclo_basico (botnica) ciclo_superior (diseo) ciclo_superior (clculo) ciclo_superior (literatura) ciclo_superior (taller) ciclo_superior (tecnologa)
Ahora, si nosotros quisiramos agregar ms materias, tendramos que agregar una clusula por cada materia que se agregue.
Pag.42
Trabajando con listas esto no es necesario, adems las definiciones recursivas de miembro hacen lo mismo y en menos espacio. Ejemplo :
domains lista_materia = materia * materia = symbol predicates ciclo_basico (materia). ciclo_superior (materia). miembro (materia, lista_materia). clauses ciclo_basico (X) :- miembro (X, [geografia, anatomia, historia, geometria, botanica]). ciclo_superior (X) :- miembro (X, [diseno, calculo, literatura, taller, tecnologia]). miembro (X, [A|B]) :- X = A or miembro (X,B).
En este ejemplo se ve claramente como las listas reemplazan a los predicados. En las dos primeras clusulas se define una materia como perteneciente a un ciclo, si Las otras dos clusulas son la definicin recursiva de miembro pertenece a la respectiva lista. Introduciendo el objeti vo ciclo_superior(diseo) obtendremos como resultado YES.
Pag.43
No ha sido necesario incluir una clusula que indique que hacer con la lista vaca porque solo necesitamos que de cmo resultado No, pero en los ejemplos resueltos de la parte prctica nmeros 12, 13, 14 y 15 encontrar este tipo de clusulas.
Pag.44
PARTE PRACTICA 1. A partir de los siguientes predicados : PADRE (padre, hijo) MADRE (madre, hijo) CASADO (hombre, mujer) LINDO (X) y considerando los siguientes hechos : mirian es la madre de ricardo. marcelo es el padre de raul y rita. mirian y rita son lindas. juan es padre de marcelo y mara. raul es el padre de sergio. rita es la madre de victor y veronica. Se desean extraer las siguientes respuestas : a. Quien es el abuelo de victor. b. Quien es el nieto de raul. c. Quien es la hermana de victor. d. Quien es la hermana de veronica. e. De quien es hija veronica. f. Quien est casado con alguien linda. g. Que relacin familiar tiene las personas lindas. h. Quienes son tos y cuales son sus sobrinos.
2 A partir de los siguientes predicados : PERSONA (nombre, sexo) AMISTAD (nombre, nombre) SOSPECHOSO (nombre) y considerando : barbara es amiga de roberto. susana es amiga de juan .
Pag.45
barbara es amiga de juan. barbara es amiga de mara. susana es amiga de pedro. Se debe escribir un programa que permita individualizar a los sospechosos del asesinato de susana. Para ello considerar como sospechosos a : a. Los hombres que tuvieron amistad con susana. b. Las mujeres que tuvieron relacin con hombres que susana conoca. c. Los amigos de mujeres que tuvieron relacin con hombres que susana conoca.
3. Considerar los siguientes predicados PERSONA (nombre, sexo, edad) MAYOR_EDAD (nombre, nombre) y sabiendo que : pedro tiene 30 aos ana tiene 10 aos jorge tiene 60 aos juan tiene 20 aos luis tiene 28 aos alejandra tiene 43 aos escribir un programa que permita identificar a las personas mayores de cierta edad, identificndolas como hombres o mujeres.
a. Que hijos tiene Alicia. b. Que hermanos tiene Juan. c. Que hermanas tiene Armando. d. Quines son los antepasados de Monica. e. Quienes son los parientes de Silvia. f. Interpretar lazos como : tos, cuados, primos y matrimonios.
5. Desarrolle un programa que pueda decir quienes son los que llegan seguros a sus casas despus de una fiesta y quienes no, en donde deber probar si puede hacerlo sin ayuda, o con ayuda, siendo este ltimo carcter probable a travs de que : Existe un conductor seguro, que tiene un coche y que existen lazos de amistades entre los individuos. A partir de las siguientes inferencia : juan, jos, jerema s y jorge poseen autos. ada y anala viven cerca de la fiesta para ir caminando. roberto, ral, rodrigo y ana viven demasiado lejos. jos y jeremas solo bebieron jugo. anacleta vive lejos y es amiga de juan. anastasia vive lejos y es amiga de jos. ral y jos no son amigos, pero si roberto y jeremas.
Pag.47
ana es amiga de jos. anala es amiga de juan. ada no conoce a ninguno. juan bebi litros de vino. jorge se dedic a bailar. jorge fu el nico que no trajo el auto. Dada la amistad de cada uno de los personajes, considere que puede ofrecerle a su amigo el hecho de llevarlos en el auto.
6. Desarrolle un programa que pueda, a travs de distintas preguntas, decir que animal es el que esta pensando el usuario que ejecute tal programa, para ello es necesario que el ser humano ante las cuestiones que realice la computadora (tales como : tiene pelos, plumas, garras, cantidad de patas, en donde es su hbitat, tipo de genero, etc.), conteste si o no.
7. Desarrolle un programa que resuelva cual es la alternativa de viaje ms corta y la ms larga para un turista, al cual se le presenta el siguiente mapa :
DESDE Nueva Crdoba Nueva Crdoba Casco Cntrico Alta Crdoba Nueva Crdoba Villa Arguello Nueva Crdoba
HASTA Alta Crdoba Casco Cntrico Villa Allende Villa Allende Villa Arguello Villa Allende Las Palmas
DISTANCIA 3000 ms. 200 ms. 4000 ms. 750 ms. 5000 ms. 3000 ms. 4000 ms.
Pag.48
8. Desarrolle un programa, tal que pueda resolver el factorial de un nmero entero ( que acepte el cero), ingresado desde teclado. 9. Un poderoso virus se ha escapado de un laboratorio y amenaza contagiar a muchas personas. Se sabe que el virus es mortal y que demorar tres das en terminar con la vida de cada persona que infecte. Sabiendo que cada persona contagiada 10. Construyamos en programa en prolog que nos permita predecir las compras que realizarn los clientes de un supermercado, partiendo de la premisa que las siguientes relaciones se cumplen: Los clientes que compran azcar, compran tambin yerba. Los clientes que no compran yerba, compran Te. Los clientes que compran vino, no compran cerveza. Los clientes que compran cerveza, compran pan, man y papitas saladas. Los clientes que no compran azucar, compran edulcorante. Los clientes que compran edulcorante, no compran leche entera. Los clientes que compran azcar, no compran leche descremada. Los clientes que compran man, no compran leche descremada. Considere que estas relaciones son bidireccionales, por ejemplo, cuando decimos que un cliente que compra azcar no compra edulcorante, tambin decimos que si comra edulcorante no compra azucar y asi en todos los casos. El programa en prolog debe ser capaz de responder, en un gola externo, dado un producto, que otros llevar ese cliente y cuales no. 11. Hacer un programa prolog que indique quien es el mximo jefe Juan, (entendiendo por mximo jefe al que ocupa el nivel mas alto en la organizacin), a partir de estos hechos. Marcos es el jefe directo de Juan, Pedro y Rosala.
Pag.49
Alberto es el Jefe directo de todo el sector de compras. Alfredo es el jefe del sector de ventas. Carolina y Roberto trabajan en ventas. Marcos y Adrin trabajan en el sector de compras. Ral es el gerente administrativo. El jefe de compras depende del gerente administrativo. 12. Hacer un programa en prolog que calcule la suma de todos los elementos de una lista de nmeros enteros. 13. Hacer un programa en prolog que calcula la cantidad de elementos que contiene un lista de nmeros. 14. Obtener una lista donde cada elemento sea calculado como la suma sucesiva de los elementos de otra. 15. Obtener una lista de nmeros que represente todos los valores posibles dentro de un determina intervalo.
Pag.50
En este caso hemos colocado un goal interno. Si observamos la salida del programa sorprende el he cho de que no hay soluciones. Evidentemente, lo mismo ocurre si optamos por colocar un goal externo. En principio el hecho de que no existan soluciones estara indicando que los datos del problema no alcanzan para identificar a algn sospechoso, pero en este caso, encontramos que hay mas bien un problema tcnico que podemos arreglar. Ya hemos dicho antes en este apunte, que el orden en que se escriben las clusulas es importante, por ejemplo, en este caso, no es lo mismo decir amistad(susana,juan) que amistad(juan,susana). Sin embargo, si a travs de la relacin amistad identificamos a que personas se ha relacionado con otras, debera ser recproca. En otras palabras, para nuestro ejemplo, si Susana es amiga de Juan, Juan debe serlo tambin de Susana. Lamentablemente, prolog no lo interpretar de esa forma y nosotros tendremos que programar este tipo de relacin. Una alternativa es definir dos veces cada hecho de amistad y colocar, por ejemplo: amistad(susana,juan). amistad(juan,susana). Pero esto, aunque efectivo es poco prctico. Otra alternativa es, en cada clusula sospechoso, considerar ambas combinaciones. Por ejemplo, sospechoso(X) if (amistad(X,susana) or amistad(susana,X)) and persona(X,m). Pero esto resulta un poco engorroso al momento de escribir clusulas mas largas como la ultima del ejemplo. Una tercera solucin muy cmoda y a la vez efectiva es definir una nueva relacin, que podramos llamar amigos de esta forma: amigos(X,Y) if amistad(X,Y) or amistad(Y,X). Esta da un valor verdadero cuando alguien es amigo de Susana sin importar en que orden se halla escrito. Ahora podemos reformular el programa anterior utilizando la relacin amigos en lugar de amistad y ya no debemos preocuparnos del orden en que los hechos han sido declarados. En el cdigo fuente que se muestra a continuacin se ha preferido utilizar un goal externo para que muestre todas las soluciones posibles. Se advierte que el resultado es
Pag.51
muy diferente al obtenido en el caso anterior pese a que en el programa solo cambian unas lneas
domains nombre = symbol sexo = symbol predicates persona(nombre,sexo). amistad(nombre,nombre). sospechoso(nombre). amigos(nombre,nombre). clauses persona(juan,m). persona(pedro,m). persona(barbara,f). persona(maria,f). persona(susana,f). persona(roberto,m). amistad(barbara,juan). amistad(barbara,maria). amistad(susana,pedro). amistad(barbara,roberto). amistad(susana,juan). amigos(X,Y) if amistad(X,Y) or amistad(Y,X). sospechoso(X) if amigos(X,susana) and persona(X,m). sospech oso(X) if persona(X,f) and amigos(X,Y) and persona(Y,m) and amigos(Y,susana). sospechoso(X) if amigos(X,Y) and persona(X,_) and persona(Y,f) and amigos(X,Z) and persona(Z,m) and amigos(Z,susana).
Pag.52
Ejercicio N 4
domains persona=symbol predicates masc (persona) fem (persona) casado (persona, persona) padre (persona, persona) madre (persona, persona) hermanos (persona, persona) hijo (persona, persona) hija (persona, persona) abuelo (persona, persona) nieto (persona, persona) tio (persona, persona) primo (persona, persona) suegro (persona, persona) suegra (persona, persona) sobrino (persona, persona) clauses masc (angel) masc (carlos) masc (eduardo) masc (basilio) masc (michel) masc (mario) fem (ofelia)
Pag.53
Universidad Tecnolgica Nacional Facultad Regional Crdoba fem (ramona) fem (ana) fem (elena) fem (betty) fem (silvia) padre (basilio,angel) padre (basilio,elena) padre (carlos,ofelia) padre (angel,betty) padre (angel,eduardo) padre (michel,mario) padre (michel,silvia) madre (ramona,angel) madre (ramona,elena) madre (ana,ofelia) madre (ofelia,betty) madre (ofelia,eduardo) madre (elena,mario) madre (elena,silvia) hijo (X,Y) if masc (X) and padre (Y,X) hijo (X,Y) if masc (X) and madre (Y,X) hijo (X,Y) if fem (X) and padre (Y,X) hijo (X,Y) if fem (X) and madre (Y,X) hermanos (X,Y) if padre (Z,X) and padre (Z,Y) and X<>Y casado (X,Y) if hijo (Z,Y) and hijo (Z,X) and X<>Y abuelo (X,Y) if padre (X,Z) and padre (Z,Y) abuelo (X,Y) if p adre (X,Z) and madre (Z,Y) nieto (X,Y) if padre (Y,Z) and padre (Z,X) nieto (X,Y) if padre (Y,Z) and madre (Z,X) nieto (X,Y) if madre (Y,Z) and padre (Z,X) nieto (X,Y) if madre (Y,Z) and madre (Z,X) primo (X,Y) if nieto (X,Z) and nieto (Y,Z) and not (hermanos(X,Y)) and X<>Y tio (X,Y) if padre (Z,Y) and hermanos (X,Z) tio (X,Y) if madre (Z,Y) and hermanos (X,Z) tio (X,Y) if casado (X,Z) and madre (W,Y) and hermanos (W,Z) suegro (X,Y) if masc (X) and padre (X,Z) and casado (Y,Z) suegra (X,Y) if fem (X) and madre (X,Z) and casado (Y,Z) sobrino (X,Y) if tio (Y,X) GOAL 1) madre (elena,X) X = mario Y = silvia 2) abuelo (X,eduardo) X = basilio Y = carlos 3) nieto (X,carlos) X = eduardo X = betty 4) primo (X,mario) X = eduardo Y = betty 5) tio (elena,X) X = betty X = eduardo 6) sobrino (X,ofelia) X = mario X = silvia 7) suegro (X,Y) X = basilio Y = ofelia X = carlos Y = angel X = basilio Y = michel
Pag.54
Ejercicio N 5
domains pers = symbol predicates auto (pers) cerca (pers) lejos (pers) amigos (pers,pers) borracho (pers) seguro (pers) no_seguro (pers) clauses lejos (roberto) lejos (raul) lejos (rodrigo) lejos (anacleta) lejos (anastacia) cerca (aida) cerca (ana) cerca (analia) auto (juan) auto (jose) auto (jeremias) auto (jorge) amigos (ana,jose) amigos (analia,juan) amigos (anacleta,juan) amigos (anastacia,jose) borracho (juan) seguro (X) if cerca (X) and not (borracho (X)) seguro (X) if lejos (X) and not (borracho (X)) and auto (X) seguro (X) if auto (X) and not (borracho (X)) seguro (X) if lejos (X) and amigos (X,Y) and auto (Y) and not (borracho (Y)) no_seguro (X) if borracho (X) no_seguro (X) if lejos (X) and amigos (X,Y) and borracho (Y) GOAL 1) seguro (X) X = aida X = jorge X = jose X = jeremias X = analia X = ana X = anastacia 2) no_seguro (X) X = juan X = anacleta
Ejercicio N 6
predicates
Pag.55
Universidad Tecnolgica Nacional Facultad Regional Crdoba tipo (symbol,symbol) goal write ( ) write (Ingrese un animal :), readln (Animal), tipo (Animal,Medio), write (El medio de este animal es : , Medio) clauses tipo (perro, domstico) tipo (gato, domstico) tipo (gallina, corral) tipo (ballena, ocano) tipo (leon, selva) tipo (elefante, sabana) tipo (hornero, monte) tipo (canario, domestico) tipo (vaca, corral) tipo (camello, desierto) tipo (trucha, rio) tipo (rana, laguna) tipo (mono, selva) tipo (caballo, domestico) tipo (mosca, domstico) tipo (condor, cordillera) tipo (tiburon, oceano) Goal 1) Ingrese un animal : perro El medio de este animal es : domestico 2) Ingrese un animal : mono El medio de este animal es : selva 3) Ingrese un animal : elefante El medio de este animal es : sabana
Ejercicio N7
domains Lugar = symbol. Mt = integer. predicates ruta(Lugar,Lugar,Mt). camino(Lugar,Lugar,Mt). clauses ruta(nuevaCordoba,altaCordoba,3000). ruta(nuevaCordoba,centro,200). ruta(centro,villaAllende,4000). ruta(altaCordoba,villaAllende,750). ruta(nuevaCordoba,arguello,5000). ruta(arguello,villaAllende,3000). ruta(nuevaCordoba,lasPalmas,4000). ruta(lasPalmas,villaAllende,3200). ruta(nuevaCordoba,losPlatanos,2000). ruta(losPlatanos,sanFernando,3000). ruta(sanfernando,villaAllende,1700).
Pag.56
camino(X,Y,D) :- ruta(X,Y,D). camino(X,Y,D) :- ruta(X,Z,H) and camino(Z,Y,M) and D = M + H and write("Dirigiendose por: ",Z).
La siguiente es una imagen de los resultados obtenidos al ejecutar el programa en turbo prolog.
Ejercicio N8 La solucin a este ejemplo es un programa extremadamente simple pero muy ingenioso a la vez. Recordemos la definicin de factorial: El factorial de X es la multiplicacin sucesiva de todos los nmeros enteros menores a iguales X y mayores a 0. As, por ejemplo, el factorial de 5 es 5 * 4 * 3 * 2 que es 120. Por definicin el factorial de 0 es uno. En esta simple solucin se utiliza, por un lado, una clusula que establece que el factorial de 0 es uno, pero esta no es til solo para cumplir con la definicin de factorial, ocurre que sirve tambin como elemento para terminar la iteracin recursiva que lleva a cabo la segunda clusula. Veamos el cdigo:
Pag.57
domains Numero = integer. Factorial = integer. predicates fact(Numero,Factorial). clauses fact(0,1). fact(Numero,Factorial) :- N u m > 0, ero N1 = Numero - 1, fact(N1,F1), Factorial = Numero * F1.
La siguiente es una imagen de los resultados obtenidos al ejecutar el programa en turbo prolog.
Ejercicio 10.
domains Producto = symbol. predicates compra(Producto,Producto). nocompra(Producto,Producto). siemprecompra(Producto,Producto). siemprenocompra(Producto,Producto).
Pag.58
Universidad Tecnolgica Nacional Facultad Regional Crdoba nocompratotal(Producto,Producto). compratotal(Producto,Producto). clauses compra(azucar,yerba). compra(cerveza,pan). compra(cerveza,mani). compra(cerveza,papitas). nocompra(yerba,te). nocompra(vino,cerveza). nocompra(azucar,edulcorante). nocompra(edulcorante,lecheentera). nocompra(azucar,lechedescremada). nocompra(mani,lechedescremada). siemprecompra(X,Y) :- compra(X,Y) or compra(Y,X). siemprenocompra(X,Y) :- nocompra(X,Y) or nocompra(Y,X). nocompratotal(X,Y) :- siemprenocompra(X,Y) or siemprecompra(X,Z) and siemprenocompra(Z,Y). compratotal(X,Y) :- siemprecompra(X,Y).
La siguiente es una imagen de los resultados obtenidos al ejecutar el programa en turbo prolog.
Ejercicio 12.
Pag.59
domains numero = integer listanumeros = numero * predicates suma(listanumeros,numero). clauses suma([],0). suma([X|Xs],S) :- suma(Xs,Sc) and S = Sc + X.
La figura siguiente muestra la pantalla con los resultados obtenidos al ejecutar el programa.
Ejercicio 13.
domains numero = integer listanumeros = numero * predicates cantidad(listanumeros,numero). clauses cantidad([],0). cantidad([X|Xs],S) :- cantidad(Xs,Sc) and S = Sc + 1.
Pag.60
Al ejecutar este programa por primera vez en turboprolog aparece el warning 420 que indica que la variable X no se usa. Este es solo un mensaje de advertencia, presionando F10 el programa se compila perfectamente y luego puede ejecutarse cuantas veces sea necesario. La figura siguiente muestra la pantalla con los resultados obtenidos al ejecutar el programa.
Ejercicio 14.
domains numero = integer listanumeros = numero * predicates acumlis(listanumeros,listanumeros). acum(listanumeros,numero,listanumeros). clauses acumlis(Xs,Ys) :- acum(Xs,0,Ys). acum([],S,[]). acum([X|Xs],S1,[S2|Ys]) :- S2 = X + S1 and acum(Xs,S2,Ys).
Al ejecutar este programa por primera vez en turboprolog aparece el warning 420 que indica que la variable S no se usa. Este es solo un mensaje de advertencia, presionando F10 el programa se compila perfectamente y luego puede ejecutarse cuantas veces sea necesario.
Pag.61
La figura siguiente muestra la pantalla con los resultados obtenidos al ejecutar el programa.
Ejercicio 15.
domains numero = integer listanumeros = numero * predicates intervalo(numero,numero,listanumeros). clauses intervalo(Y,Y,[Y]). intervalo(Y,Z,[Y|Ys]) :- Y < Z and N = Y + 1 and intervalo(N,Z,Ys).
Al igual que en casos anteriores, al ejecutar este programa por primera vez en turboprolog aparece el warning 420. Este es solo un mensaje de advertencia, presionando F10 el programa se compila perfectamente y luego puede ejecutarse cuantas veces sea necesario. La figura siguiente muestra la pantalla con los resultados obtenidos al ejecutar el programa.
Pag.62
Pag.63
Referencias y fuentes Apunte de Paradigmas de programacin Universidad Tecnolgica Nacional Facultad Regional Buenos Aires. Apunte de Programacin Prctica en Prolog de la Escuela Universitaria de Ingenieria de la Universidad de Oviedo. De Jos E Labra G. Curso bsico de programacin en Prolog de Angel Fernndez Pineda que se puede descargar de http://www.programacion.com Curso intermedio de programacin en Prolog de Angel Fernndez Pineda que se puede descargar de http://www.programacion.com Curso avanzado de programacion en Prolog de Angel Fernndez Pineda que se puede descargar de http://www.programacion.com
Pag.64