1. Introducci´on a la Programaci´on L´ogica en
Prolog
Fernando Soler Toscano
Centro Asociado de Sevilla -
UNED
2. La l´ogica de
Prolog
►Tres tipos de cl´ausulas de Horn:
1. Cl´ausulas unitarias (hechos): s´oloun literal positivo,
sin literales negativos, p0, o bien → p0
2. Cl´ausulas no unitarias (reglas): un literal positivo y al menos
un literal negativo, p0 ∨ ¬n0 ∨ ¬n1 ∨ . . ., o bien n0 ∧ n1 ∧ . .
. → p0
3. Cl´ausulas negativas (consultas): s´olotienen literales
negativos:
¬n0 ∨ ¬n1 ∨ . . ., o bien n0 ∧ n1 ∧ . . . →
►Los dos primeros tipos reciben el nombre de cl´ausulas
definidas
3. La demostraci´on en
Prolog
►Prolog emplea resoluci´on para demostrar los objetivos que
se solicitan en las consultas
►Prolog mantiene una pila de objetivos. Cuando se lanza
una consulta, la introduce en la pila. Los objetivos se
an˜adeny se quitan siempre del mismo extremo de la pila
►Se emplea la operaci´on de unificaci´on. Dos literales unifican
si existe una sustituci´on que aplicada a sus variables los
transforma en el mismo literal. Una vez que unifican dos
literales, la operaci´on no es reversible (salvo que se vuelva
sobre un punto de elecci´on)
►Cuando Prolog recibe un objetivo para demostrar
, lo
introduce en la pila de objetivos.
4. La demostraci´on en Prolog
II ►Mientras la pila de objetivos no est´evac´ıa, sea Obj su
primer elemento. Entonces busca la primera cl´ausula del
programa cuya cabeza unifique con Obj. Quita Obj de la
pila de objetivos e introduce en su lugar el cuerpo de la cl
´ausula. En tanto que puede haber m´asde una cl´ausula
cuya cabeza unifique con Obj, se crean puntos de elecci´on
a los que
ser´aposible volver si la alternativa seguida no tiene ´exito
(backtracking).
►El procedimiento sigue hasta que la pila de objetivos
quede vac´ıa(´exito de la prueba, responde si) 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 ´arboles
de prueba
►Prolog permite seguir la traza de los objetivos que se
5. Ejemplo
s % escribio(?Autor, ?Escrito) tiene ´exito s i Autor escribi´o Escrito
escribio(gottlob, b e g r i ffs s c h r i f t ) . % C1
escribio(bertrand, p rincip ia). %
C2 escribio(alfred, pri ncip ia). %
C3
escrib io (terry, shrdlu). %
C4
es cr i b i o (b i l l , lu nar). %
C5
escribio(roger, sam). %
C6
% libro(?Libro) tiene ´exito s i Libro es un
lib ro
l ib ro ( b eg ri ff ss ch r if t ).
li bro (pr incip ia).
%
C7
%
C8
% programa(?Prog) tiene ´exito s i Prog es un programa
programa(lunar).
programa(sam).
programa(shrdlu).
% C9
%
C10
%
C11
% autor(?Persona) tiene ´exito s i Persona ha escrito un lib ro
%
C12
autor(Persona) : -
libro(Libro),
escribio(Persona, Libro).
% autor_de(?Persona, ?Libro) tiene ´exito s i Persona ha escrito Libro
%
C13
autor_de(Persona, Libro) : -
libro(Libro),
escribio(Persona, Libro).
8. Llamada a autor de(bertrand,
Obra).
Tiene ´exitoy unifica Obra con principia:
9. Seguimiento de la
traza
?- t r a c e , autor(bertrand).
Call: (9) autor(bertrand) ?
Call: (10) libro(_L180) ?
Exit: (10)
libro(begriffssc hrift) ?
Call: (10) escribio(bertrand, begriffsschrift) ?
Fa i l: (10) escribio(bertrand, begriffsschrift) ?
Redo: (10) libro(_L180) ?
Exit: (10) libro(principia) ?
Call: (10) escribio(bertrand, principia) ?
Exit: (10) escribio(bertrand, principia) ?
Exit: (9) autor(bertrand) ?
Yes
10. Advertencia
s
►El orden de las cl´ausulas en el programa no cambia su
sentido sem´antico, pero puede afectar mucho a las
pruebas
►Tener en cuenta el renombramiento de variables
entre diferentes cl´ausulas
Ejercicio: experimentar con el guitracer de SWI-
Prolog
11. Definicio´n recursiva de
predicados
► Hasta ahora hemos definido los predicados complejos a
partir de otros m´as simples. En u´ltimo t´ermino, los
predicados m´as elementales constitu´ıan la propia base de
datos
►Para otros predicados, esta t´ecnica no basta, necesitamos
hacer definiciones recursivas, en t´erminos de sı́mismos.
Ocurre cuando las definiciones implican cadenas de
relaciones de longitud arbitraria
12. Definicio´n recursiva de predicados
II
►Ejemplo (´arbol familiar de Bertrand Russell):
padreomadre(katherine, bertrand). padreomadre(amberley, bertrand).
padreomadre(katherine, frank).
padreomadre(katherine, rach el ).
padreomadre(amberley, frank).
padreomadre(amberley, rach el ).
padreomadre(dora, k ate).
padreomadre(dora, john).
padreomadre(peter, conrad).
padreomadre(bertrand, kate).
padreomadre(bertrand, john).
padreomadre(bertrand, conrad).
mujer(katherine).
mujer(rachel).
mujer(dora).
mujer(peter).
mujer(kate).
hombre(amberley).
hombre(frank).
hombre(bertrand).
hombre(conrad).
hombre(john).
► Ejercicio: escribir cl´ausulas que definan las relaciones
de padre, abuela, t´ıo, primo, etc., a partir de los
predicados primitivos padreomadre/2, mujer/1 y
hombre/1.
13. Definicio´n recursiva de predicados
III
►Supongamos quequeremos definir una relaci´on de
ancestro/2. Intuitivamente, una persona Mayor es
ancestro de una persona Joven si est´anconectados
mediante una cadena de instancias de padreomadre/2
de longitud arbitraria. Podr´ıamos intentar:
ancestro(Mayor, Joven):-
padreomadre(Mayor, Joven).
ancestro(Mayor, Joven):-
padreomadre(Mayor, Medio),
padreomadre(Medio,
Joven).
ancestro(Mayor, Joven):-
padreomadre(Mayor, Medio),
padreomadre(Medio, Medio2),
padreomadre(Medio2, Joven).
. . .
14. Definicio´n recursiva de predicados
IV
►Necesitar´ıamos infinitas cl´ausulas. Afortunadamente
podemos definir la relaci´on recursivamente. Son
ancestros de Joven:
►Los padres de Joven
►Los ancestros de los padres de Joven
► Entonces:
ancestro(Mayor, Joven):-
padreomadre(Mayor, Joven).
ancestro(Mayor, Joven):-
padreomadre(Mayor, Medio),
ancestro(Medio, Joven).
►Seguir la traza de la llamada a ancestro(katherine,
kate).
15. Terminaci
´on
►La forma de definir un predicado puede influir en la
terminaci´on de las llamadas que se realizan a dicho
predicado. Por ejemplo, podr´ıamos haber intentado
definir ancestro/2 como:
ancestro(Mayor, Joven):-
ancestro(Mayor, Medio),
ancestro(Medio,
Joven).
ancestro(Mayor, Joven):-
padreomadre(Mayor, Joven).
►La definici´onessem´anticamente equivalente a la primera,
pero ahora, cuando Prolog trata de probar una llamada a
ancestro/2 nunca termina, porque siempre usa la
primera cl´ausula, construyendo una secuencia infinita de
instancias de ancestro/2.
►Seguir la traza de la llamada a ancestro(katherine,
kate). con esta definici´on
16. Terminaci´on
II
►Sin embargo, la llamada terminar´ıa simplemente
cambiando el orden de las cl´ausulas:
ancestro(Mayor, Joven):-
padreomadre(Mayor, Joven).
ancestro(Mayor, Joven):-
ancestro(Mayor, Medio),
ancestro(Medio,
Joven).
►Ahora sı́termina una llamada a ancestro/2, pero si
pedimos m´assoluciones (mediante “;”), volvemos a caer
en un bucle infinito
►Esto ocurre porque una de las cl´ausulas usa recursividad
izquierda, es decir, el primer literal es una referencia al
propio predicado, cosa que por lo general causa
problemas en el mecanismo deductivo de Prolog.
17. Terminaci´on
III
►Al escribir cl´ausulas recursivas debemos tener en cuenta la
forma en que Prolog las emplear´a, para evitar estos
problemas. Por lo general, conviene poner primero los
casos b´asicos de las cl´ausulas de un mismo predicado, y
dejar para el final las cl´ausulas que contienen llamadas
recursivas, evitando la recursividad izquierda. Por ello, la
mejor definici´on de ancestro/2 es la que dimos al
principio:
ancestro(Mayor, Joven):-
padreomadre(Mayor, Joven).
ancestro(Mayor, Joven):-
padreomadre(Mayor, Medio),
ancestro(Medio, Joven).
18. T´erminos y unificaci
´on ►Hasta ahora, los argumentos de los predicados han
sido constantes o variables
►Sin embargo, Prolog permite t´erminos arbitrarios
como argumentos
►Definici´on del conjunto de t´erminos:
►Las constantes y las variables son t´erminos
►Si t1, t2, . . . , tn son t´erminos y f es un functor n-ario,
entonces
f (t1, t2, . . . , tn ) es un t´ermino
►Nada m´ases un t´ermino
►Para ilustrar la notaci´on, el siguiente programa axiomatiza
la suma usando recursividad y la funci´on sucesor:
% suma(A, B, C) se verifica cuando A+B=C
suma(0,Y,Y). %
C1
suma(suc(X),Y,suc(Z)) : - suma(X, Y, Z). %
C2
19. T´erminos y unificaci´on
II ►Cada una de las cl´ausulas se corresponde con uno de
los axiomas de la suma:
0 + y =
y
x'
+ y =
(x + y )'
►Observaci´on: cuando Prolog encuentra un t´ermino como
suc(0) no lo iguala al t´ermino 1 ni ningu´notro. La u´nica
relaci´on entre los t´erminos y sus valores es el significado
que nosotros le concedamos
►Algunas llamadas a suma/3:
?- suma(0, suc(0), Suma).
Suma = suc(0)
Yes
?- suma(suc(suc(0)), suc(suc(0)), Suma).
Suma = suc(suc(suc(suc(0))))
Yes
?- suma(suc(0), Sumando, suc(suc(suc(0)))).
20. T´erminos y unificaci´on
III ►Ejercicio: usar el predicado suma/3 y la misma notaci´on
sucesor para definir un predicado recursivo
producto(A,B,C) que sea verdadero cuando A × B = C .
Tener en cuenta que:
0 × y = 0
x'
× y = (x × y ) +
y
►Ahora, la operaci´on de unificaci´on se aplica a t´erminos
compuestos (en Prolog, la relaci´on “=” se da entre
dos t´erminos, o predicados, que unifican):
?- suma(suc(suc(0)), suc(suc(0)), Suma) = suma(suc(X), Y,
suc(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´on ha transformado los dos t´erminos
en:
21. Operaciones aritm
´eticas
►Dentro de las constantes permitidas por Prolog est´an
los nu´meros. Operadores de comparaci´on:
►<, menor que: 3<7
► >, mayor que:
7>3
► =<, menor o igual que: 3=<7, 7=<7
► >=, mayor o igual que: 7>=3, 7>=7
►Atenci´on: estos operadores tienen restricciones: + < + (igual
para el resto, siempre debe haber dos expresiones nu
´mericas sin variables a cada lado). En otro caso, Prolog
tendr´ıa que hacer recursi´on sobre todas las parejas
posibles (X,Y) de nu´meros tales que X< Y.Esto no est´a
permitido por el compilador.
22. Operaciones aritm´eticas
II
►Expresiones num´ericas:
?- 2*3 < 5 .
No
?- 2*3 < 8 .
Yes
?- 2*3 =< 6 .
Yes
?- 2*3 = 6 .
No
►El u´ltimo caso ilustra que la identidad = no sirve para la
evaluaci´on num´erica de expresiones. Para eso est´ael
predicado is(?Result, +Expr), que puede ser usado de
forma infija, donde Expr es una expresi´on aritm´etica (debe
tenerse en cuenta la precedencia de los operadores aritm
´eticos),y Result bien un nu´mero o una variable:
23. Operaciones aritm´eticas
III
?- Xi 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
sufficiently
instantiated
?- Xi s 3/(5+2).
X= 0.428571
Yes
?- Yi s 3^2.
Y= 9
24. Observacio´n: tipos de
igualdad
Tipos de igualdad que usamos en Prolog:
►?A= ?B. Tiene ´exitosi Ay B unifican.
►+A== +B. Tiene ´exito si Ay Bson t´erminos id´enticos (sin
unificar, deben tener las mismas variables).
►?Ai s +B. Tiene ´exito si Aunifica con la evaluaci´on de la
expresi´on aritm´etica B.
►+A=:= +B. Tiene ´exito si las dos expresiones aritm´eticas Ay
Bse evalu´an al mismo nu´mero.
Probar cada una de las igualdades viendo que no tienen ´exito
en los mismos casos.
25. Lista
s
►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 [e1 , . . ., en| s]. Cuando s es la
secuencia vac´ıa, se simplifica [e1 , . . ., 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 puedeser vac´ıasi X= [ ]
►[ a,b ] es la lista con s´olodos elementos a y b
►En tanto que los elementos de una lista pueden ser a su vez
otras listas, podemos definir recursivamente la noci´on de
lista:
l i s t a ( [ ] ) .
26. Listas
II
►En el programa anterior hemos usado la variable Cabeza
para indicar que no nos importa cu´alsea su valor
concreto.
Podemos construir variables de este tipo uniendo “ ”
a cualquier cadena de caracteres
►Prolog dispone incluso de la variable an´onima “ ”
► Cada ocurrencia de es independiente de las dem
´as. Por ello, podemos unificar p( , ) con p(a,X) y au´n
unificar Xcon b. No ocurre lo mismo con las variables
como Cabeza, donde todas las apariciones de la misma
variable deben unificar con el mismo t´ermino
27. Manejo de
listas
►Al definir predicados que tengan listas entre sus
argumentos, usualmente daremos una definici´on
recursiva a partir de dos cl´ausulas:
►Una que se usar´acuando la lista est´evac´ıa [ ]
►Otra para listas no vac´ıas de la forma [Cabeza | Cola]
►De esta forma, hacemos recursi´on sobre la cola de la lista,
que cada vez ser´am´aspequen˜a y as´ı evitamos los
problemas de no-terminaci´on, yaque cuando la lista es vac
´ıa s´oloes aplicable el caso base
28. Ejemplo: concetenaci´on de
listas
►Definimos el predicado conc(L1, L2, L3) de forma que L3
sea la lista resultante de concatenar las listas L1 y L2
►Recursivamente, definimos la operaci´on de concatenaci´on:
►Si L1 es la lista vac´ıa,su concatenaci´on con L2 produce L2,
►En otro caso, sea L1 = [Cabeza | Cola]; entonces la
concatenaci´on de L1 con L2 es una lista que tiene como
primer elemento Cabeza y como resto el resultado de
concatenar Cola con L2
conc([], L2, L2).
conc([Cabeza|Cola], L2, [Cabeza|ConcResto]):-
conc(Cola, L2, ConcResto).
29. Ejemplo: concetenaci´on de listas
II ► Ejemplo:
?- conc([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´on
►Car´acter reversible del predicado conc/3:
?- conc(L1, L2, [ a , b , c , d ] ) . L1
= [ ]
L2 = [ a , b, c , d] ; L1
= [a ]
L2 = [ b , c , d] ; L1
= [ a , b]
L2 = [ c , d]
Yes
30. Control mediante
corte
►Ejemplo sin corte: nota(+Cuantit, ?Cualit)
ser´averdadero cuando Cualit sea la calificaci´on cualitativa
(suspenso, aprobado, notable, sobresaliente)
correspondiente a la nota cuantitativa Cuantit (un nu
´mero de 0 a 10).
nota(N, suspenso)
nota(N,
aprobado)
nota(N, notable)
: - N< 5.
: - N >=5, N <
7.
: - N >=7, N <
9.
nota(N, sobresaliente) : - N>= 9.
►Ejemplo: calculamos la calificaci´on correspondiente a un
6
?- nota(6, Nota).
Nota = aprobado ;
No
31. Control mediante
corte►Prolog encuentra que la nota correspondiente es aprobado.
Para demostrarlo, Prolog ha recorrido las dos primeras
ramas del ´arbol de prueba hasta encontrar una
demostraci´on.
Cuando le preguntamos si hay m´assoluciones, responde
que no. Pero ha tenido que explorar las dos ramas
restantes:
? - t r a c e , no t a (6 , Nota).
C a l l : ( 8 ) no t a (6, _G171) ?
^ C a l l : ( 9 ) 6<5 ?
^ F a i l : ( 9 ) 6<5 ?
Redo: ( 8 ) no 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 ) no t a (6 , aprobado) ?
Nota = aprobado ;
Redo: ( 8 ) no t a (6, _G171) ?
^ C a l l : ( 9 ) 6>=7 ?
^ F a i l : ( 9 ) 6>=7 ?
Redo: ( 8 ) no t a (6, _G171) ?
32. Control mediante
corte
►En ocasiones nos interesar´a que Prolog no recorra todas
las ramas del ´arbol de prueba, podando algunas de ellas
que sabemos que no ser´anprometedoras. En predicados
como nota/2 que sabemos que s´olotiene una soluci´on,
una vez encontrada ´esta,no tiene sentido seguir
buscando otras.
►El corte ! es un predicado que Prolog siempre evalu´a
como verdadero y que tiene el efecto de podar todas
las ramas alternativas en el sub´arbol de prueba
correspondiente al predicado en cuya definici´onse ha
introducido el corte.
► Ejemplo:
nota2(N,
nota2(N,
nota2(N,
suspenso)
aprobado)
notable)
: - N < 5, ! .
: - N < 7, ! .
: - N < 9, ! .
nota2(_N, sobresaliente).
33. Control mediante
corte►Ahora en el ´arbol de prueba de nota(6, Nota), cuando se
obtiene Nota = aprobado, se podan las dos ramas
restantes:
?- t r ac e, nota2(6, Nota).
Call: (8) nota2(6, _G171) ?
^ Call: (9) 6<5 ?
^ F ai l : (9) 6<5 ?
Redo: (8) nota2(6, _G171) ?
^ Call: (9) 6<7 ?
^ Exit: (9) 6<7 ?
Exit: (8) nota2(6, aprobado) ?
Nota = aprobado ;
No
►Si el corte se usa adecuadamente puede reducir
considerablemente la bu´squeda, pero tambi´en
debemos conocer sus consecuencias:
?- nota2(6, notable).
Yes
►Se pierde car´acter declarativo. En nota2/2, ahora el
34. Control mediante
corte
Ejercicio: Cuando hacemos una llamada al predicado
member(E, L), Prolog nos devuelve todos los elementos de la
lista Lque unifican con E:
?- member(X, [ a , b , a ] ) .
X= a ;
X=
b ; X
= a ;
No
se pide definir un predicado memberc(E,L) que realice un corte
en el ´arbol de prueba de modo que cuando encuentre el primer
elemento de Lque unifique con E ya no busque otros, de
modo que responda No si se piden m´as soluciones:
?- memberc(X, [ a , b , a ] ) .
X= a ;
No
35. Negacio´n por
fallo
►Hasta ahora no hemos tenido forma de indicar negaciones.
Prolog maneja la hip´otesis del mundo cerrado: todo lo que
no puede probarse se considera falso. Para ello tenemos
el predicado not/1. Se define a partir del corte:
not(C) : - C, ! , f a i l .
not(_).
►Es decir, si puede demostrarse el objetivo C(al ser una
variable podr´aser cualquier cosa), entonces no se busca
ninguna prueba alternativa para not(C) y falla (el
predicado f a i l es siempre falso, as´ı como true es
siempre verdadero). En otro caso (cuando no se ha
podido probar C), se considera probado not(C).
►El predicado not/1 est´apredefinido en SWI-Prolog, y tambi
´en puede escribirse +
36. Negacio´n por
fallo
►Ejemplo: podemos definir un predicado member dif(E,
L1, L2) 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, L1, L2) : -
member(E, L1),
+ member(E, L2).
► Obs´ervese c´omo se han ordenado los literales. De esta
forma, la negaci´on actu´a sobre valores concretos. Ver qu´e
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
37. Ejempl
o Consid´erese la siguiente basede conocimientos:
mayor_edad(juan).
mayor_edad(ana).
mayor_edad(pedro).
mayor_edad(maria).
trabaja(ana).
trabaja(pedro).
Definimos un predicado busca trabajo(X) que es
verdadero cuando Xes mayorde edad y no trabaja:
busca_trabajo(X):-
mayor_edad(X),
+ trabaja(X).
Probar an˜adir y quitar hechos de la basede
conocimiento. Observar car´acter no mon´otono de la
38. Condicion
al
►En Prolog disponemos del condicional -> que podemos
usar de dos formas posibles:
►I f -> Then; Else. Prolog evalu´a primero la condici´on If. Si
se cumple, evalu´a Then. En otro caso, ignora Then y evalu´a
Else. El condicional es verdadero cuando:
►Es verdadero I f y Then
►No es verdadero I f pero sı́ Else
►I f -> Then. Equivale a I f -> Then; fail. Es decir, si I f es
verdadero se evalu´a Then que debe ser verdadero tambi´en.
En otro caso, el condicional es falso.
39. Condicional
(ejemplos)
►Definici´on de max(+X,+Y,?Z) que tiene ´exito si Z es el mayor
de los nu´meros Xy Y:
max(X,Y,Z) : -
( X =< Y
-> Z = Y
; Z = X
) .
►Pueden anidarse
varios
condicionales.
Ejemplo:
nota(Numero,
Calif) : -
Numero < 5 -> Calif = suspenso;
Numero < 7 -> Calif = aprobado;
40. Ejercici
o
Definir usando el condicional un predicado ndias(+NMes,
-NDias) al que se le d
´
eel nu´mero NMes que representa un mes
(entre 1 y 12) y devuelva en NDias el nu´mero de d´ıasque tiene
el mes (suponer que febrero siempre tiene 28 d´ıas).
?- ndias(12,N).
N= 31
Yes
?- ndias(6,N).
N= 30
Yes
42. Predicados metal
´ogicos
►El predicado maplist(Pred, L1, L2) se verifica si se prueba
el predicado di´adico Pred sobre los sucesivos pares de
elementos de L1 y L2:
?- maplist(member,[a,b,c],
[ [ p , a , p ] , [ p , b ,p ] , [ p , c , p ] ] ) .
Yes
►El predicado findall(Term, Objet, List) se verifica si L
es la lista de instancias de Term que verifican Objet:
?- findall(X, (mayor_edad(X),
+ trabaja(X)), Li s ta ).
Lista = [juan, maria] Yes
43. Predicados metal
´ogicos
►El predicado setof(Term, Objet, List) se comporta igual
que findall/3 salvo que devuelve la lista List ordenada
y sin repeticiones. Adem´as, si no existe ninguna instancia
de Term que verifique Objet, falla (a diferencia de
findall/3 que devuelve la lista vac´ıa.
►El predicado T= . . Lse verifica si dado el t´ermino T, la lista
Ltiene como primer elemento el functor de Ty como resto
los argumentos de T:
?- lee(ana, li b ro ) = . . L. L
= [ l e e , ana, l ib ro ]
Yes
?- lee(madre(ana), l ib ro ) = . . L. L
= [ l e e , madre(ana), l ib ro ]
Yes
44. Ayuda de SWI-
Prolog
Tecleando ?- help. accedemos a la ayuda de SWI-
Prolog. Obtenemos informaci´on del uso de todos los
predicados predefinidos.
45. Modificaci´on din´amica de la base de
conocimientos
►En ciertas ocasiones nos interesa que una consulta
pueda modificar la base de conocimiento en tiempo
de ejecuci´on
►Para ello, Prolog dispone de la opci´on de declarar
ciertos predicados como din´amicos
►Disponemos de predicados que nos permiten an˜adir nuevas
cl´ausulas de los predicados din´amicos, as´ıcomo borrar
algunas o todas las existentes.
►El predicado dynamic/1 permite declarar una lista de
predicados din´amicos, dando la aridad de cada uno de
ellos.
46. Ejempl
o
:-dynamic([pajaro/1, ping¨uino/1]).
:-set_prolog_flag(unknown, f a i l ) .
vuela(X):- pajaro(X), + ping¨uino(X).
►Hemos declarado como din´amicos los predicados pajaro/1
y
ping¨uino/1.
►La instrucci´on se t prolog flag(unknown, f a i l ) hace que
cuando aparezca una llamada a un predicado del que no
hay definidas instancias, se produzca un fallo, en vez de
un mensaje de error (opci´on por defecto)
►Definimos el predicado vuela/1, que abarca todos
los individuos que son p´ajaros pero no pingu¨inos
►Observar el uso de la negaci´on por fallo
47. Predicados assert y
retract
►El predicado assert/1 an˜adea la basede conocimiento
una nueva instancia de un predicado din´amico, que
recibe como argumento.
►El predicado r et ra c t/ 1 elimina de la basede conocimiento
la primera cl´ausula de un predicado din´amico que unifique
con el argumento que recibe.
►El predicado r e t r a c t a l l / 1 elimina de la basede
conocimiento todas las instancias de un predicado din
´amico que unifiquen con el argumento que recibe.
►Estos predicados pueden usarse tanto en las consultas
como en el cuerpo de las cl´ausulas de la base de
conocimiento.
48. Ejemplo (continuaci
´on)
Compilamos la basede conocimiento
anterior:
?- assert(pajaro(piol´ın)).
t r u e .
?- vuela(piol´ın).
t r u e .
?- assert(ping¨uino(piol´ın)).
t r u e .
?- vuela(piol´ın).
f a i l .
?- assert(pajaro(p)).
t r u e .
?- assert(ping¨uino(p)).
t r u e .
?- retract(p ajaro (_ )).
true
?- findall(X,pajaro(X),Conj).
Conj = [ p ] .
?- retract(p ajaro (p )).
t r u e .
?- findall(X,pajaro(X),Conj).
Conj = [ ] .
?- findall(X,ping¨uino(X),Conj).
Conj = [piol´ın, p ] .
?- retractall(ping¨uino(_)).
t r u e .
?- findall(X,pajaro(X),Conj). ?- findall(X,ping¨uino(X),Conj).
Conj = [piol´ın, p ] . Conj = [ ] .
49. Comentario
s ►El ejemplo anterior muestra c´omolos cambios en la basede
conocimiento pueden afectar a las inferencias que se
realizan.
►Cuando s´olosab´ıamos que piol´ın es un p´ajaro, pudimos
inferir vuela(piol´ın), pero al incorporar nuevo
conocimiento, tras saber que es un pingu¨ino, ya no
podemos inferir que vuela.
►Cuando un sistema formal puede invalidar ciertas
inferencias tras an˜adir nuevo conocimiento, se dice que
no es mon´otono
►El razonamiento de sentido comu´nno es mon´otono.
►El car´acter no mon´otono de Prolog viene dado por el uso de
la negaci´on por fallo y la posibilidad de modificar la base
de conocimiento en tiempo de ejecuci´on.
►Recordemos que la negaci´on por fallo considera que algo
es falso cuando no hay constancia de que sea
50. Interaccio´n con el
usuario
►Hasta ahora, cuando realizamos una consulta, damos a
Prolog todos los datos que necesita para tratar de
demostrarla.
Prolog continu´a sin nuestra ayuda hasta dar una
respuesta afirmativa o negativa.
►En ocasiones, puede ser interesante pedir datos al
usuario, y en funci´on de dichos datos, tomar un camino
u otro en las pruebas.
►Igualmente, es interesante dar informaci´on en pantalla m
´as all´ade la respuesta afirmativa o negativa de las
pruebas.
►El predicado read/1 lee un t´ermino introducido por
el terminal.
►Los predicados format/1 y format/2 muestran informaci
´on en pantalla.
51. 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 evalu´amuestra la cadena en pantalla.
►El car´acter de control ~n imprime una nueva l´ınea.
Uso de format(Cadena, Lista):
►El argumento Cadena es una cadena de caracteres y Lista
una lista de t´erminos.
►Adem´as de ~n, aparecen en Cadena ocurrencias de ~w
(tantas como elementos tenga Lista).
►Cuando Prolog lo evalu´a, imprime en pantalla Cadena,
sustituyendo cada ocurrencia de ~wpor el elemento de
Lista que ocupa su mismo lugar.
52. Uso de
read/1
Uso de read(Term):
►Cuando Prolog lo evalu´a muestra en pantalla | :
(se puede cambiar si antes se us´oformat para producir
una salida distinta)
►Entonces Prolog se para esperando una entrada del
usuario.
►El usuario introduce un t´ermino seguido de un punto y
nueva l´ınea.
►Finalmente Prolog unifica Term con el t´ermino
introducido por el usuario.
►No hay ninguna restricci´on en cuanto al t´ermino que
introduce el usuario, puede ser un ´atomo, t´ermino
complejo, lista, nu´mero, etc.
►Para m´asdetalles y opciones, consultar la ayuda
de SWI-Prolog.
53. Ejempl
o
calcula : -
format(’Introduzca un n´umero: ’ ) ,
read(A),
format(’Introduzca otro n´umero: ’ ) ,
read(B),
format(’Operaciones:’),
format(’~n - Suma
format(’~n - Resta
( s ) ’ ) ,
( r ) ’ ) ,
format(’~n - Producto ( p ) ’ ) ,
format(’~n - Division ( d ) ’ ) ,
format(’~nElja una de el l as ( s , r , p , d ) : ’ ) ,
read(O),
operador(O,Op),
operar(Op,A,B,Res),
format(’Resultado:
~w~w~w= ~w’,[A, Op,
B, Res]).
operador(s,+).
operador(r,-).
operador(p,*).
54. Ejemplo
(uso)
?- calcula.
Introduzca un numero: 5.
Introduzca otro numero: 4.
Operaciones:
- Suma
- Resta
( s )
( r )
- Producto (p)
- Division (d)
Elja una de e ll as ( s , r , p, d) : d.
Resultado: 5/4 = 1.25
t r u e .