¡Esta es una revisión vieja del documento!
Tabla de Contenidos
Consolidando conceptos de programación lógica
En esta clase vamos a consolidar los conceptos que vimos en la clase anterior. Para ello, vamos a profundizar en el ejercicio de definir las relaciones familiares, tal como lo planteamos en los ejercicios de la clase anterior. Para profundizar, vamos a usar algunas de las herramientas que nos ofrece prolog y SWIProlog en particular para observar cómo el intérprete de prolog trata de solucionar las preguntas que le planteamos, con una base de conocimiento dada.
Para empezar la clase, vamos a crear una base de conocimiento con una de las posibles soluciones al problema de definir relaciones familiares. Abran el editor de texto, creen un archivo y copien esta solución al problema. Después, ejecuten el intérprete de prolog, con el comando swipl
en la terminal. Carguen en memoria la base de conocimiento sobre relaciones familiares, y empecemos.
Consultando la traza de la ejecución
Cuando prolog trata de resolver una pregunta o objetivo
, busca una cláusula de Horn que tenga ese objetivo en la cabeza, y sustituye el objetivo por el cuerpo de la cláusula. Entonces, los objetivos del intérprete pasan a ser cada una de las cláusulas del cuerpo. Por ejemplo, si preguntamos:
?- madre(pepa,blanca).
el intérprete encuentra la cláusula que tiene madre(X,Y)
en la cabeza: madre(X,Y) :- mujer(X), progenitor(X,Y).
, y sustituye por a nuestro objetivo inicial por los objetivos en el cuerpo de la regla.
mujer(pepa). progenitor(pepa,blanca).
El intérprete repite esta procedimiento hasta que puede llegar a true
para cada uno de los objetivos que tiene que resolver. ¿Cuándo sucede eso? Recordemos que los hechos
no son más que cláusulas de Horn con un true en el cuerpo, por lo tanto son equivalentes:
llueve.
y
llueve :- true.
En el ejemplo de madre(pepa,blanca).
, los dos objetivos en que se desdobla el objetivo inicial se encuentran como hechos en nuestra base de conocimiento, por lo tanto el intérprete encuentra un true
para todos sus objetivos.
Si alguno de los objetivos es falso o no se encuentra en la base de conocimiento, el intérprete no puede llegar a un true
y el objetivo falla.
Pero a veces sucede que un objetivo tiene respuesta y falla a la vez: ante una pregunta, el intérprete nos puede devuelve true
, y, si le escribimos ;
para que nos siga dando opciones, nos devuelve false
. Esto es así porque para resolver un objetivo, el intérprete explora todas las posibles opciones, es decir, todas las cláusulas que tengan al objetivo en la cabeza, que puede ser más de una. Cada una de estas posibilidades se denomina punto de elección
.
En caso de ser falso entra en juego el backtracking
, que consiste en deshacer todo lo ejecutado situando el programa en el mismo estado en el que estaba justo antes de llegar al punto de elección. Entonces se toma el siguiente punto de elección que estaba pendiente y se repite de nuevo el proceso. Todos los objetivos terminan su ejecución bien en éxito
(“verdadero”), bien en fracaso
(“falso”).
Más sobre cláusulas de Horn y hechos
Los programas en Prolog se componen de cláusulas de Horn
que constituyen reglas del tipo “modus ponendo ponens”, es decir, “Si es verdad el antecedente
, entonces es verdad el consecuente
”. No obstante, la forma de escribir las cláusulas de Horn es al contrario de lo habitual. Primero se escribe el consecuente y luego el antecedente. El antecedente puede ser una conjunción de condiciones que se denomina secuencia de objetivos
. Cada objetivo
se separa con una coma y puede considerarse similar a una instrucción o llamada a procedimiento de los lenguajes imperativos.
En Prolog no existen instrucciones de control. Su ejecución se basa en dos conceptos: la unificación y el backtracking.