Introducción a Prolog y Programación Lógica
Introducción a Prolog y Programación Lógica
1
La lógica de Prolog
2
La demostración en Prolog
3
La demostración en Prolog II
► Mientras la pila de objetivos no esté vac´ıa, sea Obj su primer
elemento. Entonces busca la primera cláusula del programa
cuya cabeza unifique con Obj. Quita Obj de la pila de
objetivos e introduce en su lugar el cuerpo de la cláusula. En
tanto que puede haber más de una cláusula cuya cabeza
unifique con Obj, se crean puntos de elección a los que
será posible volver si la alternativa seguida no tiene éxito
(backtracking).
► El procedimiento sigue hasta que la pila de objetivos quede
vac´ıa (éxito de la prueba, responde s i ) o hasta que haya
objetivos que no pueden probarse tras intentar todas las
opciones (fallo en la prueba, responde no)
► El procedimiento puede representarse mediante árboles de
prueba
► Prolog permite seguir la traza de los objetivos que se lanzan
► Cuando pedimos soluciones adicionales, se exploran nuevas
ramas del árbol de prueba 4
Ejemplos
% e s c r i b i o ( ? A u t o r , ? E s c r i t o ) t iene ´exito s i Autor escribi´o E s c r i t o
escribio(gottlob, begriffsschrift). % C1
escribio(bertrand, principia). % C2
escribio(alfred, principia). % C3
escribio(terry, shrdlu). % C4
e s c r i b i o ( b i l l , lunar). % C5
e s c r i b i o ( r o g e r , sam). % C6
% l i b r o ( ? L i b r o ) t iene ´exito s i L i b r o es un l i b r o
libro(begriffsschrift). % C7
libro(principia). % C8
% programa(?Prog) t iene ´exito s i Prog es un programa
programa(lunar). % C9
programa(sam). % C10
programa(shrdlu). % C11
% autor(?Persona) t iene ´exito s i Persona ha e s c r i t o un l i b r o
autor(Persona) : - % C12
libro(Libro),
e s c r i b i o ( Pe r s o na , L i b r o ) .
% autor_de(?Persona, ? L i b r o ) t iene ´exito s i Persona ha e s c r i t o Libro
autor_de(Persona, L i b r o ) : - % C13
libro(Libro), 5
e s c r i b i o ( Pe r s o na , L i b r o ) .
Llamada a a utor(ber tr a nd).
6
Llamada a a u t o r ( t e r r y ) .
7
Llamada a autor de(bertrand, Obra).
8
Seguimiento de la traza
? - t r a c e , autor(bertrand).
C a l l : ( 9 ) autor(bertrand) ?
C a l l : ( 1 0 ) l i b r o ( _ L 1 80 ) ?
E x i t : (10) l i b r o ( b e g r i f f s s c h r i f t ) ?
C a l l : (10) escribio(bertrand, b e g r i f f s s c h r i f t ) ?
F a i l : (10) escribio(bertrand, b e g r i f f s s c h r i f t ) ?
Redo: ( 1 0 ) l i b r o ( _ L 1 80 ) ?
E x i t : (10) l i b ro ( p ri n c i p i a ) ?
C a l l : (10) escribio(bertrand, p r i n ci p i a ) ?
E x i t : (10) escribio(bertrand, p r i n ci p i a ) ?
E x i t : ( 9 ) autor(bertrand) ?
Yes
9
Advertencias
10
Definición recursiva de predicados
11
Definición recursiva de predicados II
padreomadre(dora, k a t e ) . padreomadre(bertrand, k a t e ) .
padreomadre(dora, j o h n ) . padreomadre(bertrand, j o h n ) .
padreomadre(peter, conrad). padreomadre(bertrand, conrad).
mujer(katherine). hombre(amberley).
mujer(rachel). hombre(frank).
mujer(dora). hombre(bertrand).
mujer(peter). hombre(conrad).
mujer(kate). hombre(john).
14
Terminación
► La forma de definir un predicado puede influir en la
terminación de las llamadas que se realizan a dicho predicado.
Por ejemplo, podr´ıamos haber intentado definir ancestro/2
como:
ancestro(Mayor, J o v e n ) : -
ancestro(Mayor, Medio),
ancestro(Medio, Joven).
ancestro(Mayor, J o v e n ) : -
padreomadre(Mayor, Joven).
► La definición es semánticamente equivalente a la primera,
pero ahora, cuando Prolog trata de probar una llamada a
ancestro/2 nunca termina, porque siempre usa la primera
cláusula, construyendo una secuencia infinita de instancias de
ancestro/2.
► Seguir la traza de la llamada a ancestro(katherine,
k a t e ) . con esta definición 15
Terminación II
16
Terminación III
17
Términos y unificación
► Hasta ahora, los argumentos de los predicados han sido
constantes o variables
► Sin embargo, Prolog permite términos arbitrarios como
argumentos
► Definición del conjunto de términos:
) Las constantes y las variables son términos
) Si t1, t2, . . . , tn son términos y f es un functor n-ario, entonces
f (t1, t2, . . . , tn ) es un término
) Nada más es un término
► Para ilustrar la notación, el siguiente programa axiomatiza la
suma usando recursividad y la función sucesor:
% suma(A, B , C) se v e r i f i c a cuando A+B=C
suma(0,Y,Y). % C1
s u m a ( s u c ( X ) , Y , s u c ( Z ) ) : - suma(X, Y , Z ) . % C2
► El término elemental (constante) 0 representa el número 0;
s u c ( 0 ) el 1; s u c ( s u c ( 0 ) ) el 2 y as´ı sucesivamente 18
Términos y unificación II
► Cada una de las cláusulas se corresponde con uno de los
axiomas de la suma:
0+ y = y
xr + y = (x + y )r
► Observación: cuando Prolog encuentra un término como
s u c ( 0 ) no lo iguala al término 1 ni ningún otro. La ú nica
relación entre los términos y sus valores es el significado que
nosotros le concedamos
► Algunas llamadas a suma/3:
? - suma(0, s u c ( 0 ) , Suma).
Suma = su c ( 0 )
Yes
? - suma(suc(suc(0)), s u c ( s u c ( 0 ) ) , Suma).
Suma = s u c ( s u c ( s u c ( s u c ( 0 ) ) ) )
Yes
? - suma(suc(0), Sumando, s u c ( s u c ( s u c ( 0 ) ) ) ) .
Sumando = s u c ( s u c ( 0 ) )
Yes 19
Términos y unificación III
► Ejercicio: usar el predicado suma/3 y la misma notación
sucesor para definir un predicado recursivo producto(A,B,C)
que sea verdadero cuando A × B = C. Tener en cuenta que:
0×y = 0
xr × y = (x × y ) + y
► Ahora, la operación de unificación se aplica a términos
compuestos (en Prolog, la relación “=” se da entre dos
términos, o predicados, que unifican):
? - suma(suc(suc(0)), s u c ( s u c ( 0 ) ) , Suma) = suma(suc(X), Y , s u c ( Z ) ) .
Suma = suc(_G184)
X = suc(0 )
Y = suc(suc(0))
Z = _G184
Yes
► G184 es el nombre interno que Prolog asigna a la variable Z
► La sustitución ha transformado los dos términos en:
su ma(suc(suc(0)), s u c ( s u c ( 0 ) ) , s u c ( Z ) ) . 20
Operaciones aritméticas
21
Operaciones aritméticas II
► Expresiones numéricas:
? - 2*3 < 5.
No
? - 2*3 < 8.
Yes
? - 2*3 =< 6 .
Yes
? - 2*3 = 6.
No
22
Operaciones aritméticas III
? - X i s 2*3.
X = 6
Yes
? - 6 i s 2+3.
No
? - 5 i s 8 - 3.
Yes
? - 2*3 i s 6 .
No
? - 2*3 i s X .
ERROR: i s / 2 : Arguments are not s u f f i c i e n t l y inst ant iat ed
? - X i s 3 / (5 +2).
X = 0.428571
Yes
? - Y i s 3^2.
Y = 9
Yes
23
Observación: tipos de igualdad
24
Listas
► La lista vac´ıa se representa mediante la constante [ ] .
► La secuencia (e, s) con cabeza e y cola s se representa
mediante [e|s]
► Generalizando, la secuencia (e1, (. . . (en, s) . . .)) se representa
mediante [e 1 , . . . , en | s]. Cuando s es la secuencia vac´ıa,
se simplifica [e 1 , . . . , en]
► Ejemplos:
) [Cabeza | Cola], representa una lista con al menos un
elemento Cabeza
) [ a , b | X ] representa una lista cuyos dos primeros elementos
son a y b. La cola puede ser vac´ıa si X = [ ]
) [ a , b ] es la lista con sólo dos elementos a y b
► En tanto que los elementos de una lista pueden ser a su vez
otras listas, podemos definir recursivamente la noción de lista:
lista([]).
lista([_Cabeza | Cola]) : - l i s t a ( C o l a )
25
Listas II
26
Manejo de listas
27
Ejemplo: concetenación de listas
28
Ejemplo: concetenación de listas II
► Ejemplo:
? - c o n c ( [ a , b ] , [ c , d ] , Conc).
Conc = [ a , b , c , d]
Yes
?- conc([a,b], L2, [a,b,1,2]).
L2 = [ 1 , 2]
Yes
?- conc([a,b], L2, [ a , c , d ] ) .
No
► Prolog dispone del predicado predefinido append/3 que
realiza esta función
► Carácter reversible del predicado conc/3:
? - co nc(L 1, L 2 , [ a , b , c , d ] ) .
L1 = [ ]
L2 = [ a , b , c , d] ;
L1 = [ a ]
L2 = [ b , c , d] ;
L1 = [ a , b]
L2 = [ c , d]
Yes 29
Control mediante corte
30
Control mediante corte
► Prolog encuentra que la nota correspondiente es aprobado.
Para demostrarlo, Prolog ha recorrido las dos primeras ramas
del árbol de prueba hasta encontrar una demostración.
Cuando le preguntamos si hay más soluciones, responde que
no. Pero ha tenido que explorar las dos ramas restantes:
? - t r a c e , n o t a ( 6 , Nota).
C a l l : ( 8 ) n o t a ( 6 , _G171) ?
^ C a l l : ( 9 ) 6<5 ?
^ F a i l : ( 9 ) 6<5 ?
Redo: ( 8 ) n o t a ( 6 , _G171) ?
^ C a l l : ( 9 ) 6>=5 ?
^ E x i t : ( 9 ) 6>=5 ?
^ C a l l : ( 9 ) 6<7 ?
^ E x i t : ( 9 ) 6<7 ?
E x i t : ( 8 ) n o t a ( 6 , aprobado) ?
Nota = aprobado ;
Redo: ( 8 ) n o t a ( 6 , _G171) ?
^ C a l l : ( 9 ) 6>=7 ?
^ F a i l : ( 9 ) 6>=7 ?
Redo: ( 8 ) n o t a ( 6 , _G171) ?
^ C a l l : ( 9 ) 6>=9 ?
^ F a i l : ( 9 ) 6>=9 ?
31
No
Control mediante corte
► En ocasiones nos interesará que Prolog no recorra todas las
ramas del árbol de prueba, podando algunas de ellas que
sabemos que no serán prometedoras. En predicados como
nota/2 que sabemos que sólo tiene una solución, una vez
encontrada ésta, no tiene sentido seguir buscando otras.
► El corte ! es un predicado que Prolog siempre evalúa como
verdadero y que tiene el efecto de podar todas las ramas
alternativas en el subárbol de prueba correspondiente al
predicado en cuya definición se ha introducido el corte.
► Ejemplo:
nota2(N, suspenso) : - N < 5, ! .
nota2(N, aprobado) : - N < 7, ! .
nota2(N, notable) : - N < 9, ! .
nota2(_N, s o b r e s a l i e n te ) .
32
Control mediante corte
► Ahora en el árbol de prueba de n ota(6, Nota), cuando se
obtiene Nota = aprobado, se podan las dos ramas restantes:
? - t r a c e , nota2(6, Nota).
C a l l : ( 8 ) nota2(6, _G171) ?
^ C a l l : ( 9 ) 6<5 ?
^ F a i l : ( 9 ) 6<5 ?
Redo: ( 8 ) nota2(6, _G171) ?
^ C a l l : ( 9 ) 6<7 ?
^ E x i t : ( 9 ) 6<7 ?
E x i t : ( 8 ) nota2(6, aprobado) ?
Nota = aprobado ;
No
► Si el corte se usa adecuadamente puede reducir
considerablemente la búsqueda, pero también debemos
conocer sus consecuencias:
? - nota2(6, n o t a b l e ) .
Yes
► Se pierde carácter declarativo. En nota2/2, ahora el segundo
argumento es exclusivamente de salida, debe ser una variable 33
Control mediante corte
Ejercicio: Cuando hacemos una llamada al predicado member(E,
L), Prolog nos devuelve todos los elementos de la lista L que
unifican con E:
? - member(X, [ a , b , a ] ) .
X = a ;
X = b ;
X = a ;
No
? - memberc(X, [ a , b , a ] ) .
X = a ;
No
34
Negación por fallo
35
Negación por fallo
► Ejemplo: podemos definir un predicado member d i f ( E , L 1,
L 2 ) que sea verdadero cuando E sea un elemento de la lista
L1 pero no de L2 (es decir, pertenece a la diferencia L1-L2):
member_dif(E, L 1 , L 2 ) : -
member(E, L 1 ) ,
\+ member(E, L 2 ) .
► Obsérvese cómo se han ordenado los literales. De esta forma,
la negación actúa sobre valores concretos. Ver qué pasa si se
ordenan de la otra forma.
► Veamos un ejemplo:
? - member_dif(E, [ a , b , c , d , e , f ] , [ a , c , e ] ) .
E = b ;
E = d ;
E = f ;
No
36
Ejemplo
Considérese la siguiente base de conocimientos:
mayor_edad(juan).
mayor_edad(ana).
mayor_edad(pedro).
mayor_edad(maria).
trabaja(ana).
trabaja(pedro).
busca_trabajo(X): -
mayor_edad(X),
\+ t r a b a j a ( X ) .
38
Condicional (ejemplos)
39
Ejercicio
? - ndias(12,N).
N = 31
Yes
? - n d i a s ( 6 ,N) .
N = 30
Yes
40
Solución
ndias(NMes, NDias): -
member(NMes, [ 1 , 3 , 5 , 7 , 8 , 1 0 , 1 2 ] ) -> NDias = 31;
member(NMes, [ 4 , 6 , 9 , 1 1 ] ) -> NDias = 30;
NMes = 2 -> NDias = 28.
Uso:
? - n d ias(3,NDias).
NDias = 31.
?- ndias(6,30).
Yes
?- ndias(6,31).
No
? - ndias(13,N).
No
41
Predicados metalógicos
42
Predicados metalógicos
43
Ayuda de SWI-Prolog
Tecleando ? - h e l p . accedemos a la ayuda de SWI-Prolog.
Obtenemos información del uso de todos los predicados
predefinidos.
44
Modificación dinámica de la base de conocimientos
45
Ejemplo
v u e l a ( X ) : - p a j a r o ( X ) , \+ ping¨uino(X).
47
Ejemplo (continuación)
48
Comentarios
► El ejemplo anterior muestra cómo los cambios en la base de
conocimiento pueden afectar a las inferencias que se realizan.
► Cuando sólo sab´ıamos que piol´ın es un pájaro, pudimos
inferir vuela(piol´ın), pero al incorporar nuevo
conocimiento, tras saber que es un pingüino, ya no podemos
inferir que vuela.
► Cuando un sistema formal puede invalidar ciertas inferencias
tras añadir nuevo conocimiento, se dice que no es monótono
► El razonamiento de sentido común no es monótono.
► El carácter no monótono de Prolog viene dado por el uso de la
negación por fallo y la posibilidad de modificar la base de
conocimiento en tiempo de ejecución.
► Recordemos que la negación por fallo considera que algo es
falso cuando no hay constancia de que sea verdadero
(hipótesis del mundo cerrado)
► Es una negación diferente de la que se usa en lógica clásica 49
Interacción con el usuario
50
Uso de format/1 y format/2
Uso de format(Cadena):
► El argumento Cadena es una cadena de caracteres encerrada
entre comillas simples.
► Cuando Prolog lo evalúa muestra la cadena en pantalla.
► El carácter de control ~n imprime una nueva l´ınea.
Uso de format(Cadena, L i s t a ) :
► El argumento Cadena es una cadena de caracteres y L i s t a
una lista de términos.
► Además de ~n, aparecen en Cadena ocurrencias de ~w (tantas
como elementos tenga Lista).
► Cuando Prolog lo evalúa, imprime en pantalla Cadena,
sustituyendo cada ocurrencia de ~w por el elemento de L i s t a
que ocupa su mismo lugar.
51
Uso de read/1
Uso de read(Term):
► Cuando Prolog lo evalúa muestra en pantalla | :
(se puede cambiar si antes se usó format para producir una
salida distinta)
► Entonces Prolog se para esperando una entrada del usuario.
► El usuario introduce un término seguido de un punto y nueva
l´ınea.
► Finalmente Prolog unifica Term con el término introducido
por el usuario.
► No hay ninguna restricción en cuanto al término que
introduce el usuario, puede ser un átomo, término complejo,
lista, número, etc.
► Para más detalles y opciones, consultar la ayuda de
SWI-Prolog.
52
Ejemplo
calcula : -
format(’Introduzca un n´umero: ’ ) ,
read(A),
format(’Introduzca otro n´umero: ’ ) ,
read(B),
format(’Operaciones:’),
format(’~n - Suma (s)’),
format(’~n - Resta (r)’),
format(’~n - Producto ( p ) ’ ) ,
format(’~n - D i v i s i o n ( d ) ’ ) ,
f o r m a t ( ’ ~ n E l j a una de e l l a s ( s , r , p , d ) : ’ ) ,
read(O),
operador(O,Op),
operar(Op,A,B,Res),
format(’Resultado: ~w~w~w = ~ w ’ , [ A , Op, B , R e s ] ) .
o p e r a d o r (s , + ) . o p e r a d o r ( r , - ). operador(p,*). operador(d,/).
?- calcula.
Introduzca un numero: 5 .
Introduzca otro numero: 4 .
Operaciones:
- Suma (s)
- Resta (r)
- Producto ( p )
- Division (d)
E l j a una de e l l a s ( s , r , p , d ) : d .
Resultado: 5/4 = 1.25
true.
54