Documentos de Académico
Documentos de Profesional
Documentos de Cultura
PROLOG
PROLOG
NDICE
Bibliografa recomendada.
2.- Clusulas
3.- Trminos
4.- Hechos
5.- Consultas
6.- Equiparacin
7.- Reglas
7.1.- Recursividad
7.3.- Eficiencia
10
8.- Desigualdad
11
11
12
13
14
15
15
13.- Fallo
17
14.- Negacin
17
18
19
17.- Listas
20
23
Apndice.- SWI_Prolog
31
BIBLIOGRAFA RECOMENDADA
Bibliografa Bsica
Bibliografa Complementaria
Programming in Prolog
W.F.Clocksin, C.S.Mellish
Springer-Verlag,1987
Prolog. Introduccin a la Programacin de sistemas expertos
J.M.Orenga y Ortega, J.P.Snchez y Beltrn
Ed. RAMA, 1987
OBJETOS:
propiedades
relaciones
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:
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.
2.
3.
4.
5.
p(a,f(T,b)) :- q(Y,c,a),r(T,b).
p(a,b).
q(c,c,a).
q(a,b,c) :- r(g(a,b),d).
r(f(b,a),b).
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?
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
Comentarios
Ejemplos
Casos Especiales
En Minsculas.
luis
Nombre de:
pedro
tomos especiales
:?-
Constante
tomo
Objetos
edad
Propiedades
color
Relaciones
padre
rey len
Nmero
Entero
Slo dgitos, +, -
63
Real
Y punto decimal
365.2425
Variable
Suma
_Y
Estructura
edad(luis, 63)
padre_de(luis, eva)
Variable annima:
_
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, pedro).
azul(cielo).
Una relacin viene definida por todas las instancias que aparecen con un predicado.
tipo de concepto
Ejemplo
aridad
objetos/personas/proposiciones
luis
predicado/0
pedro
cielo
Propiedades
padre
predicado/1
azul
Relaciones
padre_de
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.
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).
5.- CONSULTAS
Es el mecanismo para extraer conocimiento del programa:
?- amigos(pedro, antonio).
yes
?- amigos(pedro, eva).
no
?- amigos(pedro, pepe).
no
X = juan ;
X = vicente ;
no
?- amigos(pedro, X).
X= antonio ;
X = flora ;
?- novios(pedro, flora).
WARNING Undefined predicate
novios/2
?- amigos(antonio, pedro).
no
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 Y = flora ;
No
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.
7 .- 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!
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, Y).
antecesor_de(X,Y) :- padre_de(X, Z1),
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).
10
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.
- 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).
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).
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.
*
divisin real.
divisin entera.
resto de divisin entera.
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.
12
igual1(X, Y) :- X =:= Y.
Identidad
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
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
Igual?(3,3).
Igual?(1,3).
Igual?(1+2,3).
Igual?(3,1+2).
Igual?(X,1+2).
Igual?(1+2,X).
Igual?(3,X).
Igual?(X,3).
Igual?(hola,hola).
Igual?(1.0,1).
Igual?(1,1.0).
Igual?(1.0,1.0).
Igual?(1.1,1.1).
*
**
=:=
igual1
yes
no
yes
yes
*
*
*
*
**
yes
yes
yes
yes
==
igual2
yes
no
no
no
no
no
no
no
yes
no
no
yes
yes
=
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***
***
13
14
Posibilidades:
igual1(X, Y) :- X =:= Y.
igual1(constante, constante)
igual1(vlibre, constante)
igual1(constante, vlibre)
igual1(vlibre, vlibre)
funciona
no funciona
no funciona
no funciona
==> igual1(+, +)
Resumen : igual1(+,+).
igual4(X,X).
igual4(constante, constante)
igual4(vlibre, constante)
igual4(constante, vlibre)
igual4(vlibre, vlibre)
funciona
funciona
funciona
funciona
==> igual4(+, +)
==> igual4(-, +)
==> igual4(+, -)
==> igual4(-, -)
Resumen : igual4(?, ?)
igual5(X, Y) :- X is Y.
igual5(constante, constante)
igual5(vlibre, constante)
igual5(constante, vlibre)
igual5(vlibre, vlibre)
funciona
funciona
no funciona
no funciona
==> igual5(+, +)
==> igual5(-, +)
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.
15
Funcin escaln
4
2
0
-6
-3
0,
f ( x) = 2,
4,
x<3
3 x<6
6 x
% f(+,?)
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.
f(X,0) :- X < 3.
No.
f(X,4) :- X>=6.
fallo!
f(X,2) :- 3=<X, X<6.
fallo!
16
% f(+,?)
f(2,Y), Y =:= 2.
No.
f(X,4) :- X>=6.
f(X,0) :- X < 3, !.
X=2, Y=0, X<3, !, Y=:=2.
fallo!
f(X,2) :- 3=<X, !, X<6.
% MAL!
17
f(X,4).
Este tipo de corte (Corte Rojo) debe emplearse con sumo cuidado!
Partiendo del ejemplo anterior:
f(X,0) :- X < 3, !.
f(X,2) :- X < 6, !.
f(X,4).
% f(+,-)
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(X,Y) :- X < 6, !, Y is 2.
f(X,Y) :- Y is 4.
% f(+,?)
% MAL!
?- f(2, X).
X=0;
X=2;
X=4
Supongamos que se desea programar otra funcin matemtica en Prolog::
Funcin rampa
6
5
4
3
2
1
0
-3
-2
-1
-1
10
-2
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:
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.
3 x ,
g ( x ) = x 3,
9 x ,
x<3
3 x < 6
6 x
18
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.
19
% No equivale a millonario!
% 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.
20
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)
21
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 .(a,[ ])
Representacin grfica
.
a
[ ] %lista vaca
.
.
b
.
c
[ ] %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]
[]
22
[a, b | L]
[X | L]
[X, Y | 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,[Y|C1],[Y|C2]) :- elimina(X,C1,C2).
% 2 forma
elimina(X,[X|Cola],Cola).
elimina(X,[Y|C1],[Y|C2]) :- elimina(X,C1,C2).
23
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).
Lista 1
[X,Y,Z]
[mustang]
[X,Y|Z]
Lista 2
[esto,es,prolog]
[X|Y]
[cuando,harry,encontro,a,sally]
[X,busca,Z]
[X,[actor,Z]]
[[el,Y]|Z]
[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]
24
Ejercicio 1
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
Solucin 3
Solucin 4
25
Ejercicio 2
12
nodefinida x < 0
x,
0 x<3
h( x) = x 3, 3 x < 6
x 6, 6 x < 9
nodefinida x 9
SolucionesEjercicio 2
Solucin 1
Solucin 2
h2(X,0) :- X < 0, !.
h2(X,0) :- 9 =< X, !.
h2(X,X) :- 0 =< X, X < 3, !.
h2(X,Y) :- 3 =< X, X < 9, Z is X - 3, h(Z, Y).
Solucin 3
Solucin 4
26
Ejercicio 3
SolucionesEjercicio 3
Solucin determinista
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.
27
Ejercicio 4
SolucionesEjercicio 4
triangulo(X1,Y1, X2,Y2, X3,Y3).
triangulo(0,0, 3,1, 2,2).
triangulo(v(0,0), v(3,1), v(2,2)).
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 tengan longitud a, b y c.
De ser as, deber indicar tambin el tipo de tringulo: escaleno, issceles o equiltero.
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;
(* Ordena2 *)
BEGIN
Ordena3 (X, Y, Z);
IF (X > 0) AND (X + Y > Z) THEN
BEGIN
IF (X = Z) THEN
(* Es_triangulo *)
28
WRITELN (Equilatero);
ELSE IF (X = Y) OR (Y = Z)
WRITELN (Issceles);
ELSE
WRITELN (Escaleno);
RETURN (TRUE);
END
ELSE RETURN (FALSE);
END;
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.
isosceles(A,B,C) :- A==C, A=\=B.
29
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
si x!=y, y!=z => x!=z puesto que x<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), tipo_triangulo(X,Y,Z).
lados_positivos(X) :- X>0.
30
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:
cuados(X,Y).
X es cuado/a de 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
Familia 2
Antonio---Cndida
Juan---Mara
Jos
Rosa---------------------------David
Mara----Antonio Lus
Mara
Jos---MAngeles
Lucio---Pilar
Pilar--------------Mario
Enrique
Rosa
Juan------Sara
Sonia
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.
31
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) :linea_recta(X,Y) :-
padre(X,Y).
padre(X,Z),
linea_recta(Z,Y).
padre(X,Y).
padre(X,Z),
linea_recta(X,Y) :linea_recta(X,Y) :-
antecesor(X,Y).
antecesor(Y,X).
antecesor(Z,Y).
hemos tenido que crear un nuevo predicado antecesor para evitar la recursividad infinita.
32
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
Una forma abreviada de cargar el programa puede realizarse utilizando los corchetes
[program1].
33
help
Equivalente a utilizar (help/1).
help(+What)
muestra el predicado especificado del manual. Puede describirse mediante:
<Name>/<Arity> Muestra la ayuda existente del predicado.
<Name>
Muestra la ayuda existente de ese predicado con cualquier
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. */
explain(+ToExplain)
Obtenemos una explicacin acerca de un determinado objeto (cualquier tipo de dato
permitido en Prolog).
Ejemplo:
?- explain(p).
"p" is an atom
user:p/2 is a predicate defined in
c:/david/docencia/carlos iii/pl2/prolog/ejemplo0.pl:5
Yes
34
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 (ver
flush_output/1).
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 .
skip(+Char): Lee y salta caracteres desde la entrada estndar hasta que encuentra el
carcter Char.
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.
35
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.
seen: Cierra el fichero actualmente abierto, y devuelve la entrada estndar del dispositivo
al teclado del terminal.
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.
36
[+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).
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
shell: Inicia un shell interactivo con Unix. El shell finaliza al teclear exit.
statistics: Muestra una tabla con informacin estadstica acerca de la utilizacin del
sistema.
37
debugging: Imprime el estado del depurador y los puntos espas sobre la salida actual.
spy(+Pred): Sita un punto espa en el todos los predicados especificados por Pred.
Opciones de 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
- : 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