Está en la página 1de 36

Introduccin al lenguaje PROLOG

NDICE

Bibliografa recomendada. 1.- Introduccin formal al lenguaje Prolog 2.- Clusulas 3.- Trminos 4.- Hechos 5.- Consultas 6.- Equiparacin 7.- Reglas 7.1.- Recursividad 7.2.- Recursividad encubierta 7.3.- Eficiencia 7.4.- Directivas para mejorar la eficiencia 8.- Desigualdad 9.- Operadores lgicos y aritmticos 10.- Igualdad y asignacin 11.- Modos de funcionamiento 12.- Eficiencia y corte 12.1.- Corte Verde 12.2.- Corte Rojo 13.- Fallo 14.- Negacin 15.- Progamacin Determinista/No Determinista 16.- Mecanismo de Resolucin 17.- Listas 18- Ejercicios Bsicos Apndice.- SWI_Prolog

2 3 5 5 6 7 7 8 8 9 9 10 11 11 12 13 14 15 15 17 17 18 19 20 23 31

Introduccin al lenguaje PROLOG

BIBLIOGRAFA

RECOMENDADA

Bibliografa Bsica
Prolog. Programming for artificial Intelligence Ivan Bratko Ed. Addison-Wesley, 1994 The Art of Prolog L.Sterling, E.Shapiro The MIT Press, Cambridge, Massachusetts,1994

Bibliografa Complementaria
Programming in Prolog W.F.Clocksin, C.S.Mellish SpringerVerlag,1987 Prolog. Introduccin a la Programacin de sistemas expertos J.M.Orenga y Ortega, J.P.Snchez y Beltrn Ed. RAMA, 1987

Introduccin al lenguaje PROLOG

1.-

INTRODUCCIN

FORMAL AL LENGUAJE PROLOG


PROLOG es un lenguaje declarativo e interpretado, en este tipo de lenguajes se representan los conocimientos sobre un determinado dominio y sus relaciones. A partir de ese conocimiento, se deducen las respuestas a las cuestiones planteadas, es decir se obtiene una inferencia. El dominio lo constituye un conjunto de objetos. El conocimiento se formaliza mediante un conjunto de relaciones que describen de forma simultnea las propiedades y sus interacciones. Se declara el conocimiento disponible acerca de: OBJETOS: propiedades relaciones REGLAS, que determinan interacciones lgicas del tipo: si ocurre q, r, s y t entonces P Ventaja: No hay que preocuparse de detalles de cmo resolver algo Desventaja: La resolucin no siempre es eficiente. Desde un punto de vista lgico, un programa Prolog est constituido por un conjunto de clusulas de Horn. Una clusula de Horn tiene la forma general: p(t1,t2,.,tn) :- p1(.),p2(.),,pm(.) con m >= 0 Donde tanto p como las pi son smbolos predicados con sus argumentos entre parntesis. A los argumentos de un predicado se les denomina Trminos. Las clusulas de Horn son expresiones condicionales, siendo el smbolo :- el condicional o smbolo de la implicacin (normalmente en lgica se utiliza el smbolo ). As la clusula anterior podra leerse de la siguiente forma:

SI p1(.) Y p2(.) Y Y pm(.) ENTONCES p(t1,t2,,tn) o bien podra leerse


tambin: Es cierto p(t1,t2,,tn) SI es cierto p1(.) Y es cierto p2(.) Y Y es cierto pm(.) Cuando m=0, la clusula no tiene parte derecha, en este caso diremos que se trata de un hecho o afirmacin. p(t1,t2,,tn). Cuando la clusula no tiene parte izquierda (o cabeza), se tiene una clusula negativa o pregunta, este tipo de clusulas se utilizan para realizar la entrada/salida del programa: ?p1(.),p2(.),,pm(.) Un trmino ti puede ser: un tomo (nmero, constante)

Introduccin al lenguaje PROLOG

4 una variable

una estructura (functor): f(t1,t1,tm) donde los argumentos ti son a su vez trminos En la sintaxis estndar de Prolog (la que utilizaremos aqu se conoce como sintaxis de Edimburgo), los smbolos de tomos (constantes), functores y predicados comienzan con una letra minscula, los smbolos de variables comienzan con una letra mayscula o con un subrayado. Un ejemplo de un programa Prolog sera el siguiente: 1. p(a,f(T,b)) :- q(Y,c,a),r(T,b). 2. p(a,b). 3. q(c,c,a). 4. q(a,b,c) :- r(g(a,b),d). 5. r(f(b,a),b). Una computacin en Prolog es un proceso de RESOLUCION LINEAL CON UNIFICACIN aplicado a una clusula negativa (la pregunta) y al conjunto de clusulas que constituyen el programa. As la clusula negativa: ?p(a,X). Tendra la siguiente interpretacin: Para qu valores de la variable X resulta cierto el predicado p(a,X). ? Para que valores de X se deduce p(a,X) del conjunto premisa que componen las clusulas del programa? Para resolver el objetivo ?p(a,X) aplicando resolucin lineal, se intenta su unificacin con la parte izquierda de alguna clusula que contenga el mismo predicado/aridad. Si la unificacin es posible, se sustituye el objetivo original por la lista de objetivos de la parte derecha de la clusula utilizada en la unificacin(con las sustituciones de variables que la unificacin implica). El proceso contina con el primer objetivo de la lista resultante hasta que desaparezcan todos los objetivos. Si en un momento dado resulta imposible resolver un objetivo, se retrocede (backtracking) al objetivo ms reciente con otras alternativas para su resolucin, y se resuelve con la siguiente alternativa. Si no existen alternativas disponibles, el objetivo de partida falla. Si se vaca la lista de objetivos, el objetivo queda resuelto. El proceso desencadenado para el objetivo anterior sera el siguiente: ?p(a,X) ?q(Y,c,a),r(T,b) ?r(T,b) ?[ ] resolviendo con 1, sustitucin X=f(T,b) resolviendo con 3, sustitucin Y=c resolviendo con 5, sustitucin T=f(a,b) clusula vaca

Luego el objetivo original se ha resuelto (es cierto) con X=f(f(a,b),b), que es el resultado (o salida) del clculo realizado por el programa Prolog. La estrategia de resolucin descrita para aplicar el principio de resolucin y que suele utilizarse en el Prolog estndar, se denomina primero_en_profundidad (depth first), pues el rbol de bsqueda de la solucin se recorre en profundidad (se intenta resolver en primer lugar el objetivo ms reciente de la lista de objetivos). El orden de utilizacin de las clusulas para resolver un objetivo en Prolog standard es el determinado por su aparicin en el programa. Nota: Existe alguna otra solucin a la resolucin de ese objetivo?

Introduccin al lenguaje PROLOG

5 2.- CLUSULAS

Un programa en Prolog est constituido por una secuencia de clusulas. Estas clusulas deben representar todo el conocimiento necesario para resolver el problema. Se pueden diferenciar tres tipos de Clusulas: Hechos (afirmaciones), pueden representar: Objetos Propiedades de objetos. Relaciones entre objetos. Reglas. Consultas (clusulas negativas). Como se ha mencionado, un programa Prolog es una secuencia de clusulas, donde cada clusula puede estar formada por uno o varios predicados. Las clusulas deben terminar obligatoriamente en punto.

3.- TRMINOS
En Prolog hay tres tipos de trminos: CONSTANTES, VARIABLES Y ESTRUCTURAS Tipo Constante tomo Comentarios En Minsculas. Nombre de: Objetos Propiedades Relaciones Ejemplos luis pedro edad color padre rey len 63 365.2425 Suma X _Y edad(luis, 63) padre_de(luis, eva) Casos Especiales tomos especiales :?-

Nmero Entero Real Variable Estructura

Slo dgitos, +, Y punto decimal Comienzan con Mayscula o con _ Trmino compuesto por otros Trminos

Variable annima: _

Introduccin al lenguaje PROLOG

6 4.- HECHOS

Es

el

mecanismo bsico para representar: objetos/personas/conceptos. propiedades de los objetos. relaciones entre los objetos.

Ejemplos: padre(luis). padre_de(luis, azul(cielo).

pedro).

Una relacin viene definida por todas las instancias que aparecen con un predicado. tipo de concepto objetos/personas/proposiciones luis Ejemplo pedro cielo padre azul padre_de aridad predicado/0

Propiedades
Relaciones

predicado/1
predicado/2, .../n

Los hechos pueden introducirse en la base de hechos del intrprete de Prolog mediante una asercin: ?- assert(padre_de(luis, pepe)). yes. Base de HECHOS. EJEMPLOS amigos(pedro, antonio). amigos(pedro, flora). amigos(pedro, juan). amigos(pedro, vicente). amigos(luis, felipe). amigos(luis, maria). amigos(luis, vicente). amigos(carlos, paloma). amigos(carlos, lucia). amigos(carlos, juan). amigos(carlos, vicente). amigos(fernando, pedro). millonario(pedro). millonario(antonio). millonario(flora). soltero(pedro). soltero(flora). soltero(eva). soltero(luis). padre_de(carlos, fernando). padre_de(antonio, maria). padre_de(antonio, carlos).

amigos(fernando, eva).

Introduccin al lenguaje PROLOG

5.- CONSULTAS
Es el mecanismo para extraer conocimiento del programa:
?- amigos(pedro, antonio). yes ?- amigos(pedro, eva). no ?- amigos(pedro, pepe). no ?- amigos(pedro, X). X= antonio ; X = flora ; X = juan ; X = vicente ; no ?- amigos(antonio, pedro). no ?- novios(pedro, flora). WARNING Undefined predicate novios/2

Ejemplo: Mi amigo, Vicente, busca amigos/as de mis amigos que sean millonarios/as y estn solteros/as: ?- amigos(X, vicente), amigos(X, Y), millonario(Y), soltero(Y). X = pedro ; No Y = flora

Una consulta estar constituida por una o varias metas que Prolog deber resolver. El intrprete de Prolog nos devuelve ms soluciones si utilizamos el punto y coma ; cuando no existen ms soluciones que unifiquen con el objetivo, el intrprete contesta No.

6.- EQUIPARACIN
Este mecanismo permite comprobar si dos expresiones son equivalentes, produce como resultado una sustitucin de trminos cuando esta es posible. Por ejemplo, si una variable est libre y es equiparada con un valor numrico, se obtiene una instanciacin (asignacin) de la variable con dicho valor. Ejemplos: amigos(pedro, vicente) y amigos(pedro, vicente) son equiparables. amigos(pedro, vicente) y amigos(X, vicente) son equiparables. X = pedro. amigos(pedro, Y) y amigos(X, vicente) son equiparables. X = pedro, Y = vicente. amigos(X, X) y amigos(pedro, vicente) no son equiparables porque X = pedro, X = vicente no es posible. En general, dos trminos T1 y T2 son equiparables: T1, T2 son constantes => idnticas. T1 o T2 es una variable => se equiparan instanciando el otro trmino a la variable. T1, T2 son estructuras => los trminos que los componen son equiparables manteniendo una instanciacin de las variables coherente.

Introduccin al lenguaje PROLOG

87

.- REGLAS

Permiten establecer relaciones ms elaboradas entre objetos, por ejemplo, relaciones generalizadas o particularizadas, o relaciones causa-efecto. A continacin, se muestran un conjunto de ejemplos en Prolog que permiten generalizar conceptos como el de padre, familiar, etc.. padre(X) :- padre_de(X, Y). padre(X) :padre_de(X, _). hijo_de(X,Y) :padre_de(Y, X). hermanos(X,Y) :- padre_de(Z,X), padre_de(Z,Y).% X = Y! familiares(X, Y) :- padre_de(X, Y). familiares(X, Y) :- padre_de(Y, X). familiares(X, Y) :- hermanos(Y, X). practica_suspendida(X) :practica_copiada(X). practica_suspendida(X) :- practica_insuficiente(X). practica_insuficiente(X) :programa_no_funciona(X). practica_insuficiente(X) :- memoria_insuficiente(X). peligro_de_inundacion(X) :- grifo_abierto(X), lleno_de_agua(X). amigos_interesantes(X, Z) :- amigos(Y, X), amigos(Y, Z), millonario(Z), soltero(Z). % Z = X!

7.1.-Reglas. RECURSIVIDAD
Para definir reglas ms generales y flexibles, es necesario un mecanismo adicional. Para ello se utilizar el concepto de recursividad. Para definir el concepto antecesor_de puede definirse de una forma iterativa: antecesor_de(X,Y) :- padre_de(X, Y). antecesor_de(X,Y) :- padre_de(X, Z), padre_de(Z, Y). antecesor_de(X,Y) :- padre_de(X, Z1), padre_de(Z1, Z2), padre_de(Z2, antecesor_de(X,Y) :- padre_de(X, Z1), Y). padre_de(Z1, Z2), padre_de(Z2, Z3), padre_de(Z3, Y). % padre % abuelo % bisabuelo % tatarabuelo

Este mecanismo no es eficiente, dado que no nos permite generalizar fcilmente el concepto de antecesor. Prolog permite utilizar definiciones recursivas, que resuelven el problema de forma elegante.
antecesor_de(X, Y) :- padre_de(X, Y). antecesor_de(X, Y) :- padre_de(X, Z), antecesor(Z, Y).

Introduccin al lenguaje PROLOG

7.2.-

Reglas.

RECURSIVIDAD ENCUBIERTA
Uno de los peligros que conlleva la recursividad, es la de realizar definiciones circulares o que el intrprete de Prolog no sea capaz de resolver. El ejemplo ms simple de un caso problemtico sera: antecesor_de(X, Y) :- antecesor_de(X, Y). % que se puede reducir a la clusula: P => P Esta clusula es declarativamente correcta, pero el intrprete de Prolog no podr resolverla nunca y se quedar atrapado en un bucle infinito. De aqu se pueden observar otros casos problemticos, por ejemplo si se define la siguiente base de hechos sobre las amistades de una persona: amigos(pedro, antonio). amigos(pedro, flora). amigos(fernando, pedro). Si consideramos que el concepto amistad tiene una relacin conmutativa, entonces posiblemente nos interesara definir la relacin de amistad inversa o complementaria: amigos(X, Y) :- amigos(Y, X). % Peligro, recurrencia! Esta definicin aparentemente lgica provoca un error. La forma correcta de definirlo sera a travs de un nuevo predicado: son_amigos(X, Y) :amigos(X, son_amigos(X, Y) :- amigos(Y, X). Y).

7.3.- Reglas. EFICIENCIA


En lgica matemtica no se impone un orden especial de las clusulas y de los trminos que componen los programas. Sin embargo, en Prolog es necesario cuidar el orden de las clusulas dentro de un programa, debido a que el intrprete unifica la reglas en el orden secuencial en el que le han sido proprocionadas. Volviendo a la definicin del predicado antecesor_de podemos ver que consta de dos clusulas, una de las cuales posee dos metas (u objetivos). Esto permite generar cuatro definiciones distintas de antecesor_de, permutando el orden de los trminos y de las clusulas. antecesor1(X, Y) :- padre_de(X, Y). antecesor1(X, Y) :- padre_de(X, Z), antecesor1(Z, Y). antecesor2(X, Y) :- padre_de(X, Z), antecesor2(Z, Y). antecesor2(X, Y) :- padre_de(X, Y). antecesor3(X, Y) :- padre_de(X, Y). antecesor3(X, Y) :- antecesor3(Z, Y), padre_de(X, Z) . antecesor4(X, Y) :- antecesor4(Z, Y), padre_de(X, Z) . antecesor4(X, Y) :- padre_de(X, Y).

Introduccin al lenguaje PROLOG

10 En los ejemplos anteriores se

obtienen resultados distintos. antecesor1 es la ms eficiente y funciona siempre. antecesor2 es menos eficiente. antecesor3 slo funciona para algunos casos. antecesor4 no funciona nunca, siempre se queda atrapado en un bucle infinito. Ejemplos: ?- antecesor3(antonio, carlos). % Verifica que la relacin es cierta. ?- antecesor3(carlos, maria). % La relacin es falsa, pero el programa no puede comprobarlo, quedar atrapado en un bucle % infinito. ?- antecesor3(X, Y). % Es capaz de imprimir algunos resultados, pero cuando la primera regla que define antecesor3 % falle, quedar atrapado en un bucle infinito.

7.4.- Reglas. Directivas para mejorar la eficiencia.


El siguiente conjunto de directivas pueden utilizarse para lograr que la ejecucin de nuestro programa Prolog sea lo ms eficiente posible. Primero los objetivos ms sencillos - Ordenacin de clusulas: 1 las ms especficas. 2 las ms generales (con recursividad). Ejemplo: antecesor(X, Y) :- padre_de(X,Y). antecesor(X, Y) :- padre_de(X,Y), antecesor(Z,Y). - Ordenacin de trminos dentro de una clusula: 1 los trminos ms especficos. 2 los trminos ms generales (recursivos). Ejemplo: antecesor(X, Y) :padre_de(X,Y), antecesor(Z,Y). Acotar el espacio de bsqueda amigos_interesantes(X, Z) :-% Z = X! amigos(Y, X), amigos(Y, Z), millonario(Z), soltero(Z). Sabiendo que los amigos son ms frecuentes que los millonarios y solteros, resultar ms eficiente a la hora de realizar la bsqueda cambiar el orden de las metas: amigos_interesantes(X, Z) :-% Z = X! millonario(Z), soltero(Z), amigos(Y, X), amigos(Y, Z).

Introduccin al lenguaje PROLOG

11

8.-

DESIGUALDAD
Para comprobar si dos trminos son distintos, disponemos de diferentes operadores. Desigualdad \== Comprueba si dos trminos son distintos. Por ejemplo, si dos variables tienen distintos valores instanciados. Desigualdad aritmtica =\= Verifica la desigualdad numrica de dos expresiones. Ejemplos: hermanos(X,Y) :- padre_de(Z,X),padre_de(Z,Y),X \== Y . amigos_interesantes(X, Z) :- millonario(Z), soltero(Z), amigos(Y, X), amigos(Y, Z), X \== Z . no_nulo(X) :- X =\= 0.

9.- OPERADORES LOGICOS Y ARITMETICOS


Otros operadores de comparacin aritmtica son: < ; > ; =< ; >= Operadores y funciones aritmticas vlidas en Prolog son: + * divisin real. / // divisin entera. mod resto de divisin entera. abs valor absoluto. potencia. ** potencia. ^ max valor mximo de dos. min valor mnimo de dos. round redondea al entero ms prximo. integer trunca a la parte entera. float convierte en un valor real.

Introduccin al lenguaje PROLOG

12

10.- IGUALDAD Y ASIGNACION


Disponemos de cuatro tipos de operadores de igualdad: Igualdad aritmtica igual1(X, Y) :- X =:= Y. Identidad [==]. Comprueba si los trminos argumento son idnticos. [=:=]. Comprueba la igualdad numrica de las expresiones argumento.

igual2(X, Y) :- X == Y. Unificacin[ = ]. Comprueba si los trminos argumento son unificables (equiparables). Es equivalente a la asignacin directa entre variables en un lenguaje procedimental. Da fallo si la unificacin no es posible. igual3(X, Y) :- X = Y. Una definicin equivalente sera: igual4(X,X). Asignacin [is]. Evala la segunda expresin e intenta asignar el valor obtenido a la variable. No es conmutativo! incremento(X,Y) :- Y is X+1. Una definicin similar a la de igualdad sera: igual5(X, Y) :- X is Y. Los operadores antes mencionados, aunque parten de conceptos muy distintos, poseen comportamientos similares, lo cul puede inducir a errores. A continuacin se muestra una tabla comparativa de todas las posibilidades existentes. Operador =:= == Ejemplo igual1 igual2 Igual?(3,3). yes yes Igual?(1,3). no no Igual?(1+2,3). yes no Igual?(3,1+2). yes no Igual?(X,1+2). * no Igual?(1+2,X). * no Igual?(3,X). * no Igual?(X,3). * no Igual?(hola,hola). ** yes Igual?(1.0,1). yes no Igual?(1,1.0). yes no Igual?(1.0,1.0). yes yes Igual?(1.1,1.1). yes yes * Excepcin: Variable X libre. ** Error: hola no es funcin (o expresin) vlida. Prolog tiene tendencia a convertir valores reales a enteros. En puede convertir en entero. = igual3 yes no no no X=1+2 X=1+2 X=3 X=3 yes no no yes yes = igual4 yes no no no X=1+2 X=1+2 X=3 X=3 yes no no yes yes is igual5 yes no no yes X=3 * * X=3 yes no*** yes*** no*** yes***

el segundo argumento del operador is detecta que se

Introduccin al lenguaje PROLOG

13

11.-

MODOS

DE

FUNCIONAMIENTO
Un predicado puede ser utilizado con diversos tipos de argumentos, pero no siempre est garantizado que funcione. Los tipos de argumentos ms comunes son: Trminos (constantes o variables instanciadas). Representados con + Variables libres. Representado con dos. representado con ? Cualquiera de los Posibilidades: igual1(X, Y) :- X =:= Y. igual1(constante, constante) igual1(vlibre, constante) igual1(constante, vlibre) igual1(vlibre, vlibre) igual4(X,X). igual4(constante, constante) igual4(vlibre, constante) igual4(constante, vlibre) igual4(vlibre, vlibre) igual5(X, Y) :- X is Y. igual5(constante, constante) igual5(vlibre, constante) igual5(constante, vlibre) igual5(vlibre, vlibre) funciona no funciona no funciona no funciona Resumen : igual1(+,+). funciona funciona funciona funciona Resumen : igual4(?, ?) funciona funciona no funciona no funciona ==> igual5(+, +) ==> igual5(-, +) ==> igual4(+, +) ==> igual4(-, +) ==> igual4(+, -) ==> igual4(-, -) ==> igual1(+, +)

Resumen : igual5(?,+). Se puede incluir ms informacin sobre el tipo concreto de argumento, por ejemplo: nmero, expresin, carcter,... igual1(X, Y) :- X =:= Y. Resumen : igual1(+,+). Los argumentos deben ser expresiones numricas: ==> igual1(+expresin,+expresin). igual4(X,X). Resumen : igual4(?, ?) Los argumentos pueden ser cualquier tipo de trmino: ==> igual4(?trmino,?trmino).

igual5(X, Y) :- X is Y. Resumen : igual5(?,+). El primer argumento pueden ser una variable libre o constante numrica, el segundo debe ser una expresin numrica:
==> igual5(?nmero,+expresin). Es conveniente incluir informacin de este tipo en los programas cada vez que se define un predicado.

Introduccin al lenguaje PROLOG

14 12.-

EFICIENCIA Y

CORTE
Supongamos que se desea programar en Prolog la siguiente funcin matemtica:
Funcin escaln

20

-6

-3

f (x)

0, 2, 4,

3 6

x x x

3 6

Una posible solucin (la ms intuitiva) sera la mostrada a continuacin: f(X,Y) :- X < 3, Y is 0. % f(+,?) f(X,Y) :- 3 =< X, X < 6. Y is 2. f(X,Y) :- 6 =< X, Y is 4. Se puede optimizar adelantando la equiparacin: f(X,0) :- X < 3. % f(+,?) f(X,2) :- 3 =< X, X < 6. f(X,4) :6 =< X. Si analizamos el problema, resulta que las soluciones mostradas son poco eficientes debido a que se hacen demasiadas comprobaciones. Por ejemplo, al intentar calcular ?-f(2,Y),Y =:= 2. Se comprueban las 3 clusulas cuando slo hara falta comprobar una.

f(2,Y), Y =:= 2.

No. f(X,4) :- X>=6. X=2, Y=4, X>=6. fallo!

X=2,

f(X,0) :- X < 3. X<3, fallo! f(X,2) :- 3=<X, X<6. X=2,

Y=2, X>=3. fallo!

Introduccin al lenguaje PROLOG

15

12.1.-

CORTE

VERDE
Existe un predicado que capaz de cortocircuitar la bsqueda una vez que es evaluado: el corte, representado con el smbolo de admiracin !.El corte, es un predicado que siempre se evala como cierto y que impide que se continen evaluando el resto de reglas. f(X,0) :- X < 3, !. % f(+,?) f(X,2) :- 3 =< X, X < 6, !. f(X,4) :6 =< X. Basndonos en un programa semnticamente correcto hemos aadido el operador de corte para obtener un programa ms eficiente. => Corte Verde. Esto quiere decir que si eliminamos el predicado de corte, el programa funcionar tambin, pero tendr el defecto de carecer de una interpretacin lgica o declarativa. Es necesario una interpretacin procedimental para entender este predicado. f(2,Y), Y =:= 2. X=2, f(X,0) :- X < 3, !. Y=0, X<3, !, fallo! f(X,2) :- 3=<X, !, X<6. X=2, Y=2, fallo! f(X,4) :- X>=6. X=2, X>=3. Y=4, X>=6. fallo! No.

12.2.- CORTE ROJO


Partiendo del ejemplo anterior: f(X,0) :- X < 3, !. f(X,2) :- 3 =< X, X < 6, !. f(X,4) :6 =< X. Se puede cuestionar porqu debemos comprobar algunas condiciones en el programa, si el corte las hace superfluas. En ejemplo, la segunda clusula slo se alcanza cuando X>3 y la tercera cuando X>6. Podemos reescribir el programa de siguiente forma: f(X,0) :- X < 3, !. f(X,2) :- X < 6, !. f(X,4). Curiosamente deja de funcionar en modo f(+,+), por ejemplo el caso f(0,4) dara cierto. Qu se ha hecho mal?. El problema que el nuevo programa se basa en un programa semnticamente incorrecto, si eliminsemos el corte, observaramos que eliminar el operador de corte obtenemos un programa incorrecto: f(X,0) :- X < 3. f(X,2) :- X < 6. f(X,4). % MAL!

el la

es al

Introduccin al lenguaje PROLOG 16 Este tipo de corte (Corte Rojo)

debe emplearse con sumo cuidado! Partiendo del ejemplo anterior:


f(X,0) :- X < 3, !. !. f(X,4). % f(+,-) f(X,2) :- X < 6,

El motivo de perder el modo f(+,+) es debido a una interaccin poco obvia entre la equiparacin, las condiciones y el corte. El programa realmente debera ser: f(X,Y) :- X < 3, !, Y is 0. % f(+,?) f(X,Y) :- X < 6, !, Y is 2. f(X,Y) :Y is 4. No obstante este programa sigue basndose en un programa semnticamente incorrecto; al eliminar nuevamente el operador de corte se sigue obteniendo un programa incorrecto: f(X,Y) :- X < 3, Y is 0. % MAL! f(X,Y) :- X < 6, Y is 2. f(X,Y) :- Y is 4. ?- f(2, X). X=0; X=2; X =4 Supongamos que se desea programar otra funcin matemtica en Prolog::
Funcin rampa
6 5 4 32

1 0 -3 -2 -1 -1 -2 0 1 2 3 4 5 6 7 8 9 10

( )

a Una primera solucin, sin utilizar el corte podra ser: g(X,Y) :- X < 3, Y is 3 - X. g(X,Y) :- 3 =< X, X < 6, Y is X - 3. g(X,Y) :- X >= 6, Y is 9 - X. Incluyendo el corte se obtendra:

3 x 9

x, 3, x,

3 6

x x x

3 6

g(X,Y) :- X < 3, !, Y is 3 - X. g(X,Y) :- 3 =< X, X < 6, !, Y is X - 3. g(X,Y) :- X >= 6, Y is 9 - X.

Introduccin al lenguaje PROLOG

17 Si se trazan algunos ejemplos

sencillos se pueden observar los posibles casos que pueden presentarse con esta solucin: 1 se evala la primera clusula, por ejemplo para g(4,Z). El primer trmino es falso: X<3. El intrprete pasa a verificar la segunda clusula. 2 El primer trmino es cierto y se aplica el corte, pero el ltimo trmino es falso. Por ejemplo, en g(2,3). El intrprete retrocede con falso; debido al corte no se intenta verificar otra clusula. El intrprete responde: No. 3 El primer trmino es cierto y se aplica el corte, el ltimo trmino es cierto o equiparable. Por ejemplo, en g(2,1) o g(2, Z). El intrprete retrocede con cierto; debido al corte no se intenta verificar otra clusula. El intrprete responde: S.

13.- FALLO
fail (fallo) es un predicado que siempre produce fallo. Es til cuando queremos detectar casos explcitos que invalidan un predicado. Ejemplo: Programa que simule una puerta lgica nand de 7 entradas (equivale a not and). Esta puerta lgica slo da falso en su salida cuando todas las entradas son ciertas (en este caso vamos a suponer que entrada=1 equivale a cierto). nand7(0, _, _, _, _, _, _). nand7(_, 0, _, _, _, _, _). nand7(_, _, 0, _, _, _, _). nand7(_, _, _, 0, _, _, _). nand7(_, _, _, _, 0, _, _). nand7(_, _, _, _, _, 0, _). nand7(_, _, _, _, _,_, _0). La solucin queda ms sencilla si se utiliza el fallo: nand7(1, 1, 1, 1, 1, 1, 1) :- !, fail. nand7(_, _, _, _, _, _, _). Nota: fail suele utilizarse en combinacin con el corte.

14.- NEGACIN
Existe un predicado de negacin en Prolog (not) que est implementado como negacin por fallo, esto quiere decir que se evala como falso cualquier cosa que Prolog sea incapaz de verificar que su predicado argumento es cierto. no_nulo(X) :- not (X =:= 0). Otros ejemplos: saldo_cuenta(maria,1000). saldo_cuenta(flora,3000000). saldo_cuenta(antonio,2000000). padre_de(antonio, maria). millonario(X) :- saldo_cuenta(X, Y), Y > 1000000. pobre(X) :- not millonario(X).

Introduccin al lenguaje PROLOG

18 ?- millonario(X). X = flora ;

X = antonio ?pobre(X). No. persona_interesante(X) :persona_interesante(X). No. ?- persona_interesante(flora). Yes.


persona_interesante(X) persona_interesante(X). X = flora :-

not

padre_de(X,

_),

millonario(X).

?-

millonario(X),

not

padre_de(X,

_).

?-

pudiente(X) :- not pobre(X).% No equivale a millonario! 15.- PROGRAMACION DETERMINISTA/NO DETERMINISTA Los programas que se han visto hasta ahora definan una serie de situaciones que podan darse, y qu haba que hacer en cada caso (programa determinista). Ejemplo: programa para calcular el mnimo de dos nmeros: min(X,Y, Z) :- X < Y, Z is X. min(X,Y, Z) :- X >= Y, Z is Y. % min(+,+,?)

Ejemplo: dados tres hechos que describen los lados de un tringulo, escribir un programa que devuelva las longitudes ordenadas de forma ascendente: ordena(-,-,-). lado(a, 5). lado(b, 3). lado(c, 4). ordena2(X,Y, X1,Y1) :- X<Y, X1 is X, Y1 is Y. ordena2(X,Y, X1,Y1) :- X>=Y, X1 is Y, Y1 is X. ordena3 (X, Y, Z) :- lado(a, X1), lado(b, Y1), lado(c, Z1), ordena2(X1,Y1, X2,Y2), ordena2(X2,Z1, X,Z2), ordena2(Y2,Z2, Y,Z). Para obtener un programa no determinista, lo que se puede plantear es; generar de forma combinatoria soluciones posibles y comprobar si son correctas. El mtodo de bsqueda de Prolog se encarga de retroceder cuando una solucin no es vlida. ordena3 (X, Y, Z) :- lado(Xn, X), lado(Yn, Y), lado(Zn, Z), Xn \= Yn, Xn \= Zn, Yn \= Zn, X =< Y, Y =< Z.

Introduccin al lenguaje PROLOG 19

16.-

MECANISMO

DE RESOLUCION
Como se explic en la introduccin, Prolog utiliza un mecanismo conocido como Resolucin lineal con unificacin para resolver las preguntas que se le plantean (clusulas negativas), el mecanismo consiste en realizar una bsqueda en profundidad y retroceso(backtracking) tratando de unificar la clusula objetivo con las contenidas en la base de hechos, hasta lograr alcanzar la clusula vaca. A continuacin, se muestra de forma simplificada el algoritmo utilizado: 1. 2. 3. 4. Se extraen las metas de la consulta y se introducen en orden en la lista de metas. Se realiza una llamada recursiva al procedimiento de bsqueda con la lista de metas pendientes. Si se encuentra solucin, imprimirla Si no hay solucin, imprimir false.

PROCEDIMIENTO DE BSQUEDA: 1 Se extrae la primera meta eliminndola de la lista. 2 Mientras sea posible: 3 Buscar un hecho o una regla que satisfaga la meta. 4 Si se encuentra: 5 Si ListaMetas no est vaca llamar al procedimiento de bsqueda de forma recursiva con ListaMetas y las variables equiparadas. 6 Si ListaMetas est vaca provocar un retorno con las metas satisfechas y las variables equiparadas. 7 Si hay solucin de las metas al volver de la llamada en 5, provocar un retorno con las soluciones. 8 En caso contrario, seguir en bucle, paso 3. 9 Si no se ha encontrado solucin alguna, provocar un retroceso, e.d. un retorno sin solucin. Ejemplo. Base de hechos: primoroso(zorro). primoroso(oso). amoroso(oso). astuto(zorro). Consulta: ?-primoroso(X), amoroso(X). Mecanismo de resolucin: ListaMetas = { primoroso(X), amoroso(X) } Resultado = Proc_Busqueda (ListaMetas, X) Pmeta = primera (ListaMetas) = primoroso(X) ListaMetas = resto (ListaMetas) = { amoroso(X) } Mientras sea posible: Primer hecho: primoroso(zorro) satisface PMeta?, si; ==> Resultado = Proc_Busqueda (ListaMetas)

Introduccin al lenguaje PROLOG

20 PMeta = primera (ListaMetas)

= amoroso(X), X = zorro. ListaMetas = resto (ListaMetas) = { } Mientras sea posible: Primer hecho: amoroso(oso) satisface PMeta?, no; Retroceso sin solucin para amoroso(X). Resultado = Proc_Busqueda (ListaMetas) = False. Siguiente hecho: primoroso(oso) satisface PMeta?, si; ==> Resultado = Proc_Busqueda (ListaMetas, X = oso) PMeta = primera (ListaMetas) = amoroso(X), X = oso. ListaMetas = resto (ListaMetas) = { } Mientras sea posible: Primer hecho: amoroso(oso) satisface PMeta?, si; ListaMetas vacia => Provocar retorno con Solucin { X = oso } Provocar retorno con Solucin { X = oso } Imprimir Solucin X = oso.

17.- LISTAS
Una lista es una secuencia ordenada de elementos que pueden tener cualquier longitud. Los elementos de una lista puede ser cualquier tipo de trminos(constantes, variables o estructuras), o incluso otra lista. Las listas en Prolog pueden representarse como un caso particular de rbol, una lista est formada por dos elementos: la cabeza (primer elemento de la lista) y la cola (resto de elementos de la lista). Ambos elementos se consideran componentes de la estructura cuyo functor es el punto . Ejemplos: 1. Lista con un nico elemento a Notacin en Prolog Representacin grfica .(a,[ ]) a [] %lista vaca

2. Lista con tres tomos a,b,c Notacin en Prolog .(a,.(b,.(c,[]))) Representacin grfica a

[]

%lista vaca

Debido al frecuente uso de este tipo de estructura, Prolog permite una notacin abreviada para representar listas. Los elementos de la lista aparecen separados por comas, y la lista completa aparece entre corchetes. [a, b, c] [] [a | L] Lista con los tres elementos a, b y c Lista vaca. Lista con el elemento a en la cabecera y el resto en la variable L (cola).

En la definicin de predicados se pueden usar adems variables y un separador:

Introduccin al lenguaje PROLOG

21

[a, b | L] [X | L] [X, Y | L]

Lista con los elementos a y b en la cabecera y el resto en la variable L (cola). Lista con el primer elemento instanciado en la variable X y el resto en la variable L (cola). Lista con el primer elemento instanciado en la variable X, el segundo en Y y el

resto en la variable L (cola). Ejemplos de predicados tiles en el manejo de


listas. 1.- Nmero de elementos de una lista: longitud(Xs, N) longitud([ ], 0). longitud([X | Xs], N) :- longitud(Xs, N1), N is N1+1. 2.- Pertenencia a una lista:

pertenece(X, L)
% 1 forma pertenece(X, [ ]) :- fail. pertenece(X, [X|L]). :- X\=Y, pertenece(X, L). pertenece(X, [Y|L]) % 2 forma pertenece(X, [X|L]). pertenece(X, [Y|L]) :- pertenece(X, L). 3.- Creacin de una lista a partir de dos listas (concatenar dos listas: Append). concatenar(L1,L2,L3) concatenar([ ], L, L). concatenar([X|C1],L2, [X|C3]) :- concatenar(C1,L2,C3). 4.- Eliminacin de un elemento X de una lista L1, como consecuencia se obtiene la lista L2 (se elimina la primera aparicin del elemento). elimina(X,L1,L2) % 1 forma elimina(X,[]) :fail. elimina(X,[X|Cola],Cola). :- elimina(X,C1,C2). elimina(X,[Y|C1],[Y|C2]) % 2 forma elimina(X,[X|Cola],Cola). elimina(X,[Y|C1],[Y|C2]) :- elimina(X,C1,C2).

Introduccin al lenguaje PROLOG

22 5.- Eliminacin de todas las

apariciones de un elemento X en una lista L1, como consecuencia se obtiene la lista L2. borrar(X,L1,L2) borrar(_,[ ],[ ]). borrar(X,[X|C],M) :! , borrar(X,C,M). borrar(X,[Y|L1],[Y|L2]) :- borrar(X,L1,L2). 6.- Invertir todos los elementos de una lista. invertir(L1,L2) invertir([],[]). invertir([X|C],Z) :- invertir(C,C1),concatenar(C1,[X],Z). Ejemplos de unificacin de listas.

Lista 1 [X,Y,Z] [mustang] [X,Y|Z] [X,busca,Z] [X,[actor,Z]] [[el,Y]|Z]

Lista 2 [esto,es,prolog] [X|Y] [cuando,harry,encontro,a,sally] [harry,Y,sally] [cine,[Y,meg]] [[X,libro],esta,aqu]

Instanciaciones X=esto, Y=es, Z=prolog X=mustang, Y=[] X=cuando, Y=harry, Z=[encontro,a,sally] X=harry, Y=busca, Z=sally X=cine, Y=actor, Z=meg X=el, Y=libro, Z=[esta,aqu]

Si se tienen dudas de la posible unificacin de dos listas o de trminos en general, se puede asegurar el resultado de la unificacin utilizando el predicado interno = del intrprete de Prolog. Ejemplos: ?-[X,libro]=[lapiz,Y]. X=lapiz Y=libro Yes ?-[X,libro]=[Y,lapiz]. No

Introduccin al lenguaje PROLOG

23

18.- EJERCICIOS

BSICOS
Ejercicio 1 Enunciado: Programar en Prolog una clusula que calcule el factorial de n. SolucionesEjercicio 1 Solucin 1 factorial(0, 1). factorial(N, X) :-N1 is N - 1, factorial(N1, X1),X is X1 * N. La solucin anterior no funciona bien si le pasamos un nmero negativo, para evitar este problema podemos utilizar el fallo y el corte: Solucin 2 factorial2(N, _) :- N < 0, fail. factorial2(0, 1). :- N > 1, N1 is N - 1, factorial(N1, X1), X is X1 * N. factorial2(N, X) Solucin 3 factorial3(N, _) :- N < 0, !, fail. factorial3(0, 1) :- !.N > 1, N1 is N - 1, factorial(N1, X1), X is X1 * N. factorial3(N, X) :Solucin 4 factorial4(N, _) :- N < 0, !, fail. factorial4(0, 1) :- !.N1 is N - 1, factorial(N1, X1), X is X1 * N. factorial4(N, X) :-

Introduccin al lenguaje PROLOG 24 Ejercicio 2

Enunciado: Programar la siguiente funcin matemtica en Prolog.


Funcin Sierra
8 7 6 5 4 3 2 1 0 -1 -2 -3 0 3 6 9 12

h(x)

nodefinida x, 0 x 3, 3 x 6, 6 nodefinida

x 0 x 3 x 6 x 9 x 9

SolucionesEjercicio 2 Solucin 1 h(X,X) :- 0 =< X, X < 3. h(X,Y) :- 3 =< X, X < 6, Y is X - 3. h(X,Y) :- 6 =< X, X < 9, Y is X - 6. En esta solucin se emplea el predicado de corte y el de fallo para mejorar la eficiencia. Solucin 2 h2(X,0) :- X < 0, !. h2(X,0) :- 9 =< X, !. =< X, X < 3, !. h2(X,X) :- 0 h2(X,Y) :- 3 =< X, X < 9, Z is X - 3, h(Z, Y). Solucin 3 h3(X,0) :- X < 0, fail. h3(X,0) :- 9 =< X, fail. h3(X,X) :- X < 3, !. h3(X,Y) :- X < 6, !, Y is X - 3. h3(X,Y) :X < 9, Y is X - 6. Solucin 4 h4(X,0) :- X < 0, fail. h4(X,0) :- 9 =< X, fail. h4(X,X) :- X < 3, !. h4(X,Y) :- 3 =< X, X < 9, Z is X - 3, h(Z, Y).

Introduccin al lenguaje PROLOG 25 Ejercicio 3

Enunciado: Programacin determinista/no determinista del ejemplo visto en el apartado 15. SolucionesEjercicio 3 Solucin no determinista (ms eficiente) ordena3 (X, Y, Z) :- lado(Xn, X), lado(Yn, Y), Xn \= Yn, X =< Y, lado(Zn, Z), Xn \= Zn, Yn \= Zn, Y =< Z. Solucin determinista ordena2(X,Y, X,Y) :X<Y. ordena2(X,Y, Y,X) :- X>=Y. ordena3 (A,B,C X, Y, Z) :- ordena2(A,B, X1,Y1), ordena2(X1,C, X,Z1), ordena2(Y1,Z1, Y,Z). Solucin no determinista

permuta2(X,Y, X,Y). permuta2(X,Y, Y,X). permuta3(X,Y,Z, X,Y1,Z1) :- permuta2(Y,Z, Y1,Z1). permuta3(X,Y,Z, Y,X1,Z1) :- permuta2(X,Z, X1,Z1). permuta3(X,Y,Z, Z,X1,Y1) :permuta2(X,Y, X1,Y1). ordena3 (A, B, C) :- permuta3(A,B,C, X,Y,Z), X =< Y, Y =< Z.

Introduccin al lenguaje PROLOG 26 Ejercicio 4

Enunciado: Implementar la estructura de hechos en Prolog que nos permita trabajar y representar datos estructurados. Para ello, se pide obtener una representacin vlida para un tringulo, donde podremos representar las tres coordenadas de los puntos que lo forman. SolucionesEjercicio 4 triangulo(X1,Y1, X2,Y2, triangulo(0,0, 3,1, 2,2). v(2,2)). triangulo(v(0,0), v(3,1), v(X,Y) :- vertice(X,Y). ?- triangulo(v(X,Y), v(3,1), v(2,2)). X=0, Y=0 Ejercicio 5 Enunciado: Escribir un programa procedimental que, dados tres valores: [a, b y c], responda si es posible construir un tringulo cuyos lados tenganindicar tambin c. tipo de tringulo: escaleno, issceles o equiltero. De ser as, deber longitud a, b y el La caberecera que se definira en Pascal sera: FUNCTION TrianguloQ (X, Y, Z : REAL) : BOOLEAN ; Escribir un programa equivalente en Prolog. trianguloq(A,B,C) ... SolucionesEjercicio 5 Solucin en PASCAL
FUNCTION TrianguloQ (X, Y, Z : REAL) : BOOLEAN ; PROCEDURE Ordena3 (VAR X, Y, Z : REAL) ; PROCEDURE Swap2 (VAR V1, V2 : REAL) ; VAR AUX : REAL ; BEGIN AUX := V1 ; V1 := V2 ; V2 := AUX END; BEGIN IF (X > Y) THEN Swap2 (X, Y) ; IF (X > Z) THEN Swap2 (X, Z) ; IF (Y > Z) THEN Swap2 (Y, Z) ; END; BEGIN (* Ordena2 *)

X3,Y3).

Ordena3 (X, Y, Z); IF (X > 0) AND (X + Y > Z) THEN BEGIN IF (X = Z) THEN

(* Es_triangulo *)

Introduccin al lenguaje PROLOG

27 WRITELN (Equilatero); ELSE IF (X = Y) OR (Y = Z) WRITELN


(Issceles); ELSE

END;

WRITELN (TRUE); END ELSE RETURN (FALSE);

(Escaleno);

RETURN

Planteamiento 1 En primer lugar, se plantean las condiciones necesarias para poder construir un tringulo T(a,b,c) a partir de las magnitudes a, b y c. Condiciones previas para que T(a,b,c) sea tringulo: [a>0, b>0, c>0] Restriccin necesaria para que T(a,b,c) sea tringulo: a+b>c si c>a,b a+c>b si b>a,c b+c>a si a>b,c T(a,b,c) es equiltero si a = b = c T(a,b,c) es issceles si se cumple a=c, b!=a a=b, c!=a c=b, a!=c T(a,b,c) es escaleno si se cumplen a!=b b!=c a!=c $Solucin 1 lados_positivos(A,B,C) :- A>0, B>0, C>0. lados_adecuados(A,B,C) :- A=<C, B=<C, A+B>C. lados_adecuados(A,B,C) :- A=<B, C=<B, A+C>B. lados_adecuados(A,B,C) :- C=<A, B=<A, B+C>A. es_triangulo(A,B,C):- lados_positivos(A,B,C), lados_adecuados(A,B,C). equilatero(A,B,C) :es_triangulo(A,B,C), A==B, A==C. isosceles(A,B,C) :- es_triangulo(A,B,C), A==C, A=\=B. isosceles(A,B,C) :- es_triangulo(A,B,C), A==B, B=\=C. isosceles(A,B,C) :- es_triangulo(A,B,C), B==C, B=\=A. escaleno(A,B,C) :- es_triangulo(A,B,C), A=\=B, B=\=C, A=\=C. trianguloq(A,B,C) :- equilatero(A,B,C), write(equilatero). trianguloq(A,B,C) :- isosceles(A,B,C), write(isosceles). trianguloq(A,B,C) :- escaleno(A,B,C), write(escaleno). Solucin 2 lados_positivos(A,B,C) :- A>0, B>0, C>0. lados_adecuados(A,B,C) :- A=<C, B=<C, A+B>C. lados_adecuados(A,B,C) :- A=<B, C=<B, A+C>B. lados_adecuados(A,B,C) :- C=<A, B=<A, B+C>A. es_triangulo(A,B,C):- lados_positivos(A,B,C), lados_adecuados(A,B,C). equilatero(A,B,C) :A==B, A==C. :- A==C, A=\=B. isosceles(A,B,C)

Introduccin al lenguaje PROLOG

28 isosceles(A,B,C) :- A==B,

B=\=C. isosceles(A,B,C) :- B==C, B=\=A. escaleno(A,B,C) :- A=\=B, B=\=C, A=\=C. tipo_triangulo(A,B,C) :- equilatero(A,B,C), write(equilatero). tipo_triangulo(A,B,C) :isosceles(A,B,C), write(isosceles). tipo_triangulo(A,B,C) :- escaleno(A,B,C), write(escaleno). trianguloq(A,B,C) :- es_triangulo(A,B,C), tipo_triangulo(A,B,C). Planteamiento 2 La solucin anterior es efectiva, pero no capta la toda la informacin que disponemos sobre el problema porque no se ha estructurado del todo bien. La solucin propuesta enumeran todos los casos posibles considerando las magnitudes a, b y c. La segunda restriccin consiste en una enumeracin de casos posibles disjuntos entre s. Si realizamos una proyeccin de los smbolos a, b y c sobre la terna x, y y z, de tal forma que x<y<z, podemos simplificar dicha restriccin. De paso podremos simplificar las dems tambin. Condicin previa para que T(x,y,z) sea tringulo: x>0 (puesto que x<y<z => y,z >0) Restriccin necesaria para que T(x,y,z) sea tringulo: x+y>z (puesto que x,y<z) T(x,y,z) es equiltero si x=z (puesto que x<y<z, si x=z => x=y=z) T(x,y,z) es issceles si se cumple x=y, y!=z x!=y, y=z T(x,y,z) es escaleno si se cumplen x!=y y!=z Solucin 3 ordena2(X,Y, X,Y) :X=<Y. ordena2(X,Y, Y,X) :- X>Y. ordena3(A,B,C, X,Y,Z) :- ordena2(A, B, X1, Y1), ordena2(X1, C, X, Z1), ordena2(Y1, Z1, Y, Z). lados_positivos(X, _, _) :X>0. lados_adecuados(X,Y,Z) :- X+Y>Z. es_triangulo(X,Y,Z):- lados_positivos(X,Y,Z), lados_adecuados(X,Y,Z). equilatero(X,Y,Z) :X==Z. isosceles(X,Y,Z) :X==Y, Y=\=Z. isosceles(X,Y,Z) :X=\=Y, Y==Z. escaleno(X,Y,Z) :- X=\=Y, Y=\=Z. tipo_triangulo(X,Y,Z) :- equilatero(X,Y,Z), write(equilatero). tipo_triangulo(X,Y,Z) :- isosceles(X,Y,Z), write(isosceles). tipo_triangulo(X,Y,Z) :- escaleno(X,Y,Z), write(escaleno). trianguloq(A,B,C):-ordena3(A,B,C,X,Y,Z), es_triangulo(X,Y,Z), lados_positivos(X) :- tipo_triangulo(X,Y,Z). X>0. si x!=y, y!=z => x!=z puesto que x<y<z

Introduccin al lenguaje PROLOG 29 Ejercicio 6

Enunciado: A).- Dado el siguiente rbol genealgico (ver figura 1), crear un base de hechos que lo represente y el conjunto de clusulas necesarias que me permitan establecer las relaciones habituales en cualquier familia, como por ejemplo: hermanos(X,Y). padre(X,Y). abuelos(X,Y). primos(X,Y). es hermano/a de Y ? X es padre de Y ? X es abuelo/a de Y ? X es primo/a de Y ?

Tambin se disearn clusulas que nos permitan relacionar diferentes familias, por ejemplo: X es cuado/a de Y ? cuados(X,Y). Se crearn clusulas de carcter recursivo como: antepasado(X,Y). X es antepasado/a de Y ? B).- Se modificar el programa anterior, para permitir la insercin de nuevos hechos en nuestra base. Como caracterstica bsica se considerar la insercin de este nuevo conocimiento: Juan, cuyos padres son Pilar y Mario, decide casarse con Sara (sus padres no son conocidos para nuestra base de hechos). Como efecto de este matrimonio tienen una hija a la que deciden ponerle el nombre de Sonia. rbol Genealgico: Familia 1 Antonio---Cndida Familia 2 Jos---MAngeles

Juan---Mara Rosa---------------------------David
Jos Mara----Antonio Mara Lus Elena----Juan Antonio Ana Alberto----Rosa Pilar--------------Mario Juan------Sara Sonia

Lucio---Pilar
Enrique Rosa

C).- En este apartado se pretende modelizar la Computacin del Parentesco entre dos personas de una familia, en primer lugar definiremos un conjunto de conceptos necesarios para poder realizar el clculo: Lnea es el conjunto o serie de grados que pueden existir entre dos personas; puede ser recta o colateral. Lnea recta es la integrada por individuos que descienden unos de otros: padres, hijos, nietos,etc. Lnea colateral es la formada por personas que no descienden unas de otras pero tienen ascendientes comunes: hermanos, tos, primos, sobrinos, etc.

Introduccin al lenguaje PROLOG

30 GRADO es, en materia de

parentesco, cada una de las generaciones existentes entre dos personas relacionadas por vnculos de sangre. As del padre al hijo hay una generacin o grado, entre abuelo y nieto existen dos grados. Para calcular el grado existen dos sistemas diferentes: Derecho Civil: existen tantos grados como generaciones, as en la lnea recta entre el nieto y el abuelo existen dos grados de parentesco. Si utilizamos la lnea colateral, para calcular el grado de parentesco entre dos individuos, se asciende hasta el primer antepasado comn y luego se desciende hasta la persona respecto de la cual se computa el parentesco. La suma del n de generaciones de ambas ramas nos proporcionar el grado que existe entre los individuos, por ejemplo, con este sistema el hermano se halla en segundo grado con cualquier otro hermano, los primos hermanos distan cuatro grados, etc. Derecho Cannico: en el caso de la lnea recta el cmputo es idntico que en el caso del derecho civil. En la lnea colateral se cuentan las generaciones o grados de la lnea ms larga y no se suman como en el derecho civil. De esta forma, el hermano se encuentra en primer grado con sus hermanos, y los primos hermanos se encontraran en segundo grado. Esta computacin rige solamente para el matrimonio cannico a efecto del impedimento de parentesco que ha de ser estimado conforme a ella. Se pide construir un conjunto de reglas en Prolog que me permitan obtener los anteriores conceptos, por ejemplo: recta(X,Y,Z) :- nos dice si X tiene un parentesco directo con Y. colateral(X,Y) :- nos dice si X tiene un parentesco colateral con Y grado_civil(X,Y,Z) :- calcula el grado existente entre las personas X e Y aplicando las leyes del derecho civil, Z estar instanciada al valor de ese grado. grado_canonico(X,Y,Z) :- calcula el grado existente entre las personas X e Y aplicando las leyes del derecho civil, Z estar instanciada al valor de ese grado. SolucionesEjercicio 6

1. linea_recta(X,Y).
linea_recta(X,Y) :- padre(X,Y). linea_recta(X,Y) :- padre(X,Z), linea_recta(Z,Y).

Tiene el problema de que no es simtrica. La circunstancia de que linea_recta(X,X) sea cierto es discutible a efectos de calcular el grado de parentesco (sera un grado 0). 2. linea_recta(X,Y), simtrico.
antecesor(X,Y) :antecesor(X,Y) :padre(X,Y). padre(X,Z), antecesor(Z,Y).

linea_recta(X,Y) :antecesor(X,Y). linea_recta(X,Y) :- antecesor(Y,X). hemos tenido que crear un nuevo predicado antecesor para evitar la recursividad infinita.

Introduccin al lenguaje PROLOG

31

Apndice.-

SWI_Prolog
A continuacin, se muestran un conjunto de predicados bsicos para el manejo del intrprete SWI-Prolog Para una informacin ms detallada, consultar la direccin Web:

http://grial.uc3m.es/~docweb/pl2/index.html
Software y Manuales: http://grial.uc3m.es/~docweb/pl2/software.html

1.- Creacin de un programa Prolog


El programa Prolog debe editarse en modo texto y contener la extensin .pl Ejemplo: program1.pl

2.- Cargar un programa


Una vez arrancado el intrprete Prolog , utilizaremos el predicado consult/1 Para cargar el conjunto de hechos y reglas que contiene el fichero. No debe utilizarse la extensin .pl

Si el fichero se ha ledo correctamente por el intrprete, nos responder algo similar a:

Una forma abreviada de cargar el programa puede realizarse utilizando los corchetes [program1].

Introduccin al lenguaje PROLOG

32 3.- Efectuar preguntas simples

Para realizar preguntas simples al intrprete, podemos utilizar predicados simples que hayamos predefinido en el programa, dejando alguno de sus trminos sin instanciar. Ejemplo: ?-p(a,X). ?-saldo_cuenta(maria,Z).

4.- Ayuda online del intrprete


El intrprete SWI_Prolog nos proporciona una pequea ayuda online sobre determinados predicados, para ello pueden utilizarse las distintas versiones del predicado help. help Equivalente a utilizar (help/1). help(+What) muestra el predicado especificado del manual. Puede describirse mediante: <Name>/<Arity> Muestra la ayuda existente del Muestra la ayuda existente de ese predicado con cualquier predicado. <Name> aridad. <Section> Muestra la seccin especificada, las secciones se identifican por nmeros separados por un guin: 2-3 (seccin 2.3 del manual). Los nmeros de una determinada seccin pueden obtenerse utilizando apropos/1. Ejemplos: ?- help(assert). /*muestra la informacin del predicado assert */ ?- help(3-4)./*muestra la informacin de la seccin 3.4 */ ?- help('PL_retry'). /*muestra la ayuda de la funcin PL_retry() */

apropos(+Pattern) Muestra todos los predicados, funciones y secciones que coinciden con el patrn de entrada (en minsculas). Ejemplo: ?- apropos(file). /*muestra los predicados, funciones y secciones que contienen file (o File, etc) en su ayuda. */ objeto (cualquier tipo de dato

explain(+ToExplain) Obtenemos una explicacin acerca de un determinado permitido en Prolog). Ejemplo: ?- explain(p). "p" is an atom is a predicate defined in user:p/2 c:/david/docencia/carlos iii/pl2/prolog/ejemplo0.pl:5 Yes

Introduccin al lenguaje PROLOG

33 5.- Salida del intrprete

halt/0 Termina la ejecucin del intrprete Prolog, cerrando todos los ficheros abiertos. halt(+Status)
Termina la ejecucin del intrprete con un determinado estado, el estado es un nmero entero.

6.- Entrada/Salida Estndar


A continuacin, se muestran algunos predicados bsicos para poder realizar operaciones de entrada/salida desde/sobre el terminal de salida de la computadora. current_op(?Precedence,?Type,?Name): Devuelve xito cuando Name est definido como un operador de tipo Type cuya precedencia es Precedence. (Otros predicados relacionados con este, op/3).
display(+Term):

Escribe el trmino Term sobre la salida estndar del dispositivo. Este predicado suele emplearse normalmente para examinar la representacin interna de un trmino. flush: Vuelca la salida de un programa sobre la salida estndar actual flush_output/1). (ver

get(-Char): Lee de la entrada actual caracteres y unifica Char con el prximo carcter introducido (distinto al carcter blanco). Char se unifica con -1 si se trata del final de un fichero. get0(-Char): Lee de la entrada actual caracteres y unifica Char con el prximo carcter introducido. Char se unifica con 1 si se trata del final de un fichero. $nl: Escribe una lnea en blando (carcter newline) sobre la salida estndar actual . op(+Precedence,+Type,+Name): Declara a Name como un operador de tipo Type con una precedencia Precedence.
put(+Char):

Escribe el carcter Char sobre la salida estndar del dispositivo. read(-Term): Lee un trmino

desde la entrada estndar del dispositivo. skip(+Char): Lee y salta caracteres desde la entrada estndar hasta que encuentra el carcter Char. tab(+Amount): Escribe un nmero dado (Amount) de espacios en blanco en la salida estndar del dispositivo (Amount debe ser una expresin que pueda evaluarse como un entero positivo). write(+Term): Escribe el trmino Term sobre la salida estndar. writeq(+Term): Escribe el trmino Term sobre la salida estndar (sita el trmino entre comillas). En este predicado, los trminos pueden ser vueltos a leer con el predicado read/1.

Introduccin al lenguaje PROLOG 34

7.-

Entrada/Salida

desde

Fichero
close(+Stream): Cierra el fichero especificado por Stream. display(+Stream,+Term): Muestra un trmino Term que se encuentra en el fichero especificado por Stream. get(+Stream, -Char): Lee el siguiente carcter imprimible de un fichero y unifica su correspondiente valor ASCII con Char. get0(+Stream, -Char): Lee el siguiente carcter de un fichero y unifica su correspondiente valor ASCII con Char. nl(+Stream): Escribe una lnea en blanco en el fichero especificado. open(+SrcDest,+Mode,?Stream):Apertura del fichero especificado por SrcDest (especifica un fichero Unix), el Mode puede ser de lectura (read), escritura (write) o para realizar una ampliacin del mismo (append). El trmino Stream puede ser una variable (se instanciar a un entero que identifica mi fichero), o un tomo (en este caso se trata de un identificador de fichero). En caso de no existir el fichero lo crea. put(+Stream,+Char): Escribe el carcter Char, en el fichero Stream. read(+Stream,-Term): Lee un trmino desde un fichero. see(+SrcDest): Abre un fichero para lectura y se sita al comienzo del mismo. seeing(?SrcDest): Unifica el nombre del fichero abierto actualmente con SrcDest . seen: Cierra el fichero actualmente abierto, y devuelve la entrada estndar del dispositivo al teclado del terminal. skip(+Stream,+Char): Lee y salta caracteres desde un fichero encuentra el carcter Char. tab(+Stream,+Amount): Escribe un nmero dado (Amount) de espacios en blanco un fichero (Stream). tell(+SrcDest): Abre un fichero para escritura como si se tratase de la salida estndar. telling(?SrcDest): Devuelve el nombre de el fichero abierto por tell (unifica el nombre del actual fichero de salida con SrcDest). told: Cierra el fichero que se encuentre actualmente abierto, y devuelve la salida estndar del dispositivo a la pantalla del terminal. write(+Stream,+Term): Escribe el trmino Term sobre el fichero Stream. writeq(+Term): Escribe el trmino Term sobre el fichero Stream entrecomillados). (los inserta (Stream) hasta que

Introduccin al lenguaje PROLOG

35 8.- Funciones del Sistema

[+Filespec: Lee las clusulas contenidas en el fichero especificado y las inserta en la base de datos (es una accin similar a ejecutar el predicado consult). chdir(+Path): Cambia el directorio de trabajo al directorio Path.
consult(+File):

Lee un fichero con formato Prolog (el fichero va sin extensin aunque por defecto buscar el fichero File o File.pl, toma las clusulas que encuentre en ese fichero y las inserta en la base de datos delete_file(+File): Borra el fichero especificado. exists_file(+File): Produce xito cuando el fichero especificado existe (esto no implica que el usuario disponga de permiso de lectura o escritura sobre ese fichero). halt: Finaliza la ejecucin del intrprete de Prolog o de la aplicacin compilada. listing: Lista todos los predicados de la base de datos. listing(+Pred): Lista todos los predicados especificados por Pred. rename_file(+File1,+File2): Renombra File1 como File2. size_file(+File,-Size): Unifica la variable Size con el nmero de caracteres contenidos en File. shell: Inicia un shell interactivo con Unix. El shell finaliza al teclear exit. shell(+Command): Ejecuta un comando de Unix. statistics: Muestra una tabla con informacin estadstica acerca de la utilizacin del sistema.

Introduccin al lenguaje PROLOG 36

9.-

Funciones

para

la

Depuracin de Programas
debug: Arranca el depurador (detendr la ejecucin de los programas en los puntos espas). debugging: Imprime el estado del depurador y los puntos espas sobre la salida actual. $nodebug: Detiene el depurador (quita el modo traza y no se detiene en ningn punto espa). nospy(+Pred): Borra el punto espa situado en el predicado especificado. nospyall: Borra todos los puntos espa del programa. notrace: Detiene el proceso de traza del programa. spy(+Pred): Sita un punto espa en el todos los predicados especificados por Pred. trace: Arranca el proceso de traza del programa. tracing: Devuelve xito cuando el proceso de traza est activado. Opciones de - : no spy . : repeat find A : alternatives c (return,space) : creep e : exit from Prolog [depth g : goals i : ignore L : listing p : print s : skip w : write goal depuracin: + : spy /c|e|r|f|u|a} goal : find a : abort b : break d : display goal f : fail h (?) : help l : leap n : nodebug r : retry u : up C : toggle show context

También podría gustarte