Академический Документы
Профессиональный Документы
Культура Документы
email: jaime@sip.ucm.es
PROLOG
1 / 101
Sintaxis de Prolog
Un programa Prolog es un conjunto de clusulas de Hernndez a Jaime Snchez Horn (hechos Departamento de Sistemas Informticos y Computacin y reglas) donde: Universidad Complutense de Madrid email: jaime@sip.ucm.es Todas las clasulas acaban con . u El s mbolo se escribe como :- que se lee como si (condicional). En los hechos no es necesario (basta poner el tomo y .) a Los nombres de predicado y funcin siguen las pautas o habituales de los identicadores pero comienzan con minscula . u Los nombres de variable tambin siguen esas pautas, pero e comienzan por mayscula . u Los tomos en el cuerpo de las reglas se separan mediante a comas , que se leen como y. Ejecutar un programa no tiene sentido como tal (en principio). Lo que se hace es plantear objetivos a resolver. A partir de ahora utilizaremos esta notacin. o
2 / 101
La funcin de seleccin devuelve siempre el primer tomo del o o a objetivo empezando por la izquierda. email: jaime@sip.ucm.es Para resolver un objetivo G el algoritmo elemental ser a: mientras G no sea cierto elegir una (variante de una) regla de P aplicable a G reducir G por resolucin o
Pero en un paso de reduccin pueden existir varias (variantes o de) clasulas aplicables a G . Por ello surgue el concepto de u rbol de bsqueda: Prolog ensaya las distintas clasulas a u u aplicables a G de manera secuencial y cada uno de estos ensayos da lugar a una rama de dicho rbol. a
3 / 101
Arboles de bsqueda u
Dado un programa Prolog y un objetivo G (asumimos seleccin del Jaime Snchez Hernndez o Departamento de Sistemas Informticos y Computacin primer tomo de la izquierda), el rbol de bsqueda paraMadrides un a a u G Universidad Complutense de email: jaime@sip.ucm.es rbol que: a tiene G como ra z para cada clusula C de P aplicable a G existe una rama a correspondiente al rbol de bsqueda del SLD-resolvente de G a u y (una variante cualquiera de) C . Adems etiquetaremos las a ramas con la sustitucin correspondiente y la clasula C o u aplicada. En otras palabras: un rbol de bsqueda es un rbol con objetivos a u a en los nodos y cuyas ramas representan los posibles cmputos, i.e., o las posibles clasulas a aplicar. u
Nota: no confundir rbol de bsqueda con los rboles de derivacin SLD que hemos a u a o visto anteriormente (los rboles de resolucin corresponden solo a una rama de los a o rboles de bsqueda). a u
4 / 101
Ejemplo
Jaime Snchez Hernndez
Departamento de Sistemas Informticos y Computacin Universidad Complutense de Madrid
A1 A2 A3 A4
: : : :
5 / 101
Ejemplo (cont.)
camino(X,d) C1 , [X/d, X1 /d] xito e
email: jaime@sip.ucm.es
A1 ,[X/a,Z1 /b]
[X/a,Z1 /c]
A2
A3
[X/a,Z1 /d]
A4 ,[X/c,Z1 /d]
camino(b,d)
camino(c,d)
xito e
fallo
fallo
fallo
fallo
6 / 101
Prolog: el sistema
Jaime Snchez Hernndez email: jaime@sip.ucm.es Disponible en: http://www.swi-prolog.org/ para distintas plataformas.
Departamento de Sistemas Informticos y Computacin Universidad Complutense de Madrid
7 / 101
Resolviendo objetivos
Jaime Snchez Hernndez email: jaime@sip.ucm.es Qu respuesta(s) debemos obtenter para los siguientes objetivos: e
Departamento de Sistemas Informticos y Computacin Universidad Complutense de Madrid
9 / 101
multiplicacin o resta (X Y debe ser 0 si X < Y ). menor (X es menor que Y) potencia X Y division entera factorial calcular el N-simo nmero de la serie de bonacci e u
10 / 101
Supongamos que tenemos las siguientes relaciones de email: jaime@sip.ucm.es parentesco: Javier & Mar a Pedro (&Carmen) Alfonso Juan
11 / 101
Algunos predicados: padre(X,Y):- progenitor(X,Y), hombre(X). madre(X,Y):- progenitor(X,Y), mujer(X). Cmo se pueden representar las siguientes relaciones de parentesco: o hijo(X,Y), abuelo(X,Y), hermano(X,Y), tio(X,Y), descendiente(X,Y)?
12 / 101
email: jaime@sip.ucm.es
hijo(X,Y):- progenitor(Y,X), hombre(X). abuelo(X,Y):- progenitor(Z,Y), padre(X,Z). hermano(X,Y):- progenitor(Z,X), progenitor(Z,Y). tio(X,Y):- progenitor(Z,Y), hermano(Z,X). descendiente(X,Y) :- progenitor(Y,X). descendiente(X,Y) :- progenitor(Y,Z), descendiente(X,Z).
13 / 101
???????-
Universidad Complutense de Madrid hijo(juan,pedro). email: jaime@sip.ucm.es abuelo(javier,teresa). hijo(javier,X). hijo(X,pedro). descendiente(X,javier). hijo(pedro,X). hermano(pedro,X). % Pedro es hermano de Pedro?
En el primer ejemplo:
1) Se aplica la regla (renombrada) hijo(X1,Y1) :progenitor(Y1,X1), hombre(X1). 2) Se generan nuevos objetivos. Se comprueba que existe el hecho progenitor(pedro,juan). 3) Por ultimo, se resuelve el ultimo objetivo pendiente: hombre(juan).
email: jaime@sip.ucm.es
hombre(juan)
exito
15 / 101
Se aaden los nuevos objetivos n generados. Se pueden aplicar dos hechos diferentes para progenitor: progenitor(jorge,alicia) y progenitor(teresa,alicia) (*). Si se utiliza el primer hecho, se puede aplicar la regla padre(X2,Y2) :progenitor(X2,Y2), hombre(X2). pero no es posible resolver uno de los nuevos objetivos generados (progenitor(javier,jorge)). Por ello, debe replantearse (backtracking) la decisin tomada en o (*).
X1/javier Y1/alicia progenitor(Z1,alicia),padre(javier,Z1) Z1/jorge padre(javier,jorge) X2/javier Y2/jorge progenitor(javier,jorge), hombre(javier) Z1/teresa
fallo
exito
16 / 101
progenitor(maria,Z2),descendiente(X,Z2) Z2/pedro descendiente(X,pedro) X3/X Y3/pedro X4/X Y4/pedro progenitor(pedro,Z2),descendiente(X,Z2) Z2/alfonso descendiente(X,alfonso) X5/X Y5/alfonso Z2/juan descendiente(X,juan) (en varios X6/X pasos) Y6/alfonso fallo Z2/teresa descendiente(X,teresa) (en varios pasos) exito
exito
exito
X = pedro
X = teresa
X = alicia
exito
exito
X = alfonso
X = juan
progenitor(alfonso,X)
progenitor(alfonso,Z2), descendiente(X,Z2)
fallo
fallo
17 / 101
progenitor(maria,Z2),descendiente(X,Z2) Z2/pedro descendiente(X,pedro) X3/X Y3/pedro X4/X Y4/pedro progenitor(pedro,Z2),descendiente(X,Z2) Z2/alfonso descendiente(X,alfonso) X5/X Y5/alfonso Z2/juan descendiente(X,juan) (en varios X6/X pasos) Y6/alfonso fallo Z2/teresa descendiente(X,teresa) (en varios pasos) exito
exito
exito
X = pedro
X = teresa
X = alicia
exito
exito
X = alfonso
X = juan
progenitor(alfonso,X)
progenitor(alfonso,Z2), descendiente(X,Z2)
fallo
fallo
18 / 101
Si siempre se utiliza la primera regla, y los objetivos siempre se evaluan de izquierda a derecha, se genera un rbol innito. a En Prolog debe tenerse esto en cuenta: puede existir solucin en otra rama del o rbol que no es alcanzable. a
descendiente(X,maria) X1/X Y1/maria descendiente(X,Z1),progenitor(maria,Z1) X2/X Y2/Z1 descendiente(X,Z2),progenitor(maria,Z2) X3/X Y3/Z2 descendiente(X,Z3),progenitor(maria,Z3)
En el espacio de bsqueda de un objetivo, Prolog realiza u bsqueda en profundidad y por la izquierda, con u backtracking en caso de fallo o de peticin de ms respuestas. o a
19 / 101
Listas II
La notacin de corchetes es azcar sintctico:Snchez Hernndez o u a Jaime Prolog por debajo Departamento utiliza los functores (s mbolos de funcin) de Sistemas Informticos y Computacin oUniversidad Complutense de Madrid
email: jaime@sip.ucm.es
[] (lista vac aridad 0) y . (de aridad 2). a, En los ejemplos anteriores tenemos: [a,b,c] .(a, .(b, .(c, []))) .(X+5, .(s(s(c)), []))
[X+5,s(s(c))]
[el,[gato],[sobre,[el],tejado]] .(el, .(.(gato,[]), .(.(sobre, .( .(el, []), .(tejado, []))), []))) (se ve ms fcil en forma arbrea) a a o
21 / 101
Listas III
La notacin con el functor . es complicada. Hay una notacin o Jaime Snchez Hernndez o Departamento de Sistemas Informticos y Computacin ms cmoda, reemplazando . por el operador Complutense| de Madrid a o Universidad injo
email: jaime@sip.ucm.es
[] sigue igual .(X,Xs) se escribe como [X|Xs] Esta notacin es util para denir predicados sobre listas. Es util o asimilar: [ X | Xs ]
cabeza (elemento) resto/cola (lista)
| [b,c]]
resto
22 / 101
Listas III
Prolog tambin admite la siguiente notacin de listas (azcar e o u Jaime Snchez Hernndez Departamento de Sistemas Informticos y Computacin sintctico): a Universidad Complutense de Madrid email: jaime@sip.ucm.es [e1 , e2 , . . . , en1 , en | resto] donde e1 , e2 , . . . , en son elementos y resto es una lista. Esto es equivalente a: [e1 |[e2 | . . . [en1 |[en |resto]] . . .]]
Por ejemplo: [1, 2, 3|[4, 5]] es equivalente a [1, 2, 3, 4, 5] y a [1|[2|[3|[4|[5|[]]]]]] [1, 2|3] no tiene sentido!! la unicacion [1, 2|R] = [X , Y , Z ] produce X /1, Y /2, R/[Z ] la unicacion [1, 2|R] = [X , Y , Z , U, V ] produce X /1, Y /2, R/[Z , U, V ] la unicacion [1, 2|R] = [X , Y ] produce X /1, Y /2, R/[] la unicacion [1, 2|R] = [X ] falla
23 / 101
(Nota: esta est predenido en swi-prolog como member) a Tambin podemos utilizar variables annimas e o
esta(X,[X| ]). esta(X,[ |Xs]):- esta(X,Xs).
y escribir:
Ejercicio: utilizando esta denir el predicado intersec(X,Xs,Ys)::=X pertenece a ambas listas Xs e Ys. Pregunta: que obtenemos con el objetivo esta(a,Xs)?
24 / 101
Concatenacin de listas o
Jaime Snchez Hernndez
Es muy frecuente en Prolog concatenar dos listas (poner la email: jaime@sip.ucm.es segunda a continuacin de la primera). Por ejemplo, la o concatenacion de [a, b, c] con [d, e] dar la lista [a, b, c, d, e]. a Cmo se puede denir? o
concatena([],Xs,Xs). concatena([X|Xs],Ys,[X|Zs]):- concatena(Xs,Ys,Zs).
Qu ocurre si resolvemos concatena([1,2,3],As,[1,2,3,5,6])? Y e concatena(As,Bs,[1,2,3,4])? Y concatena([1,2],Ks,[2,3,4])?. Este predicado est predenido (built-in) en el sistema como a append.
25 / 101
Aritmtica e
Jaime Snchez Hernndez
Departamento de Sistemas Informticos y Computacin Universidad Complutense de Madrid
Segn hemos visto es posible y fcil denir los nmeros en u a email: jaime@sip.ucm.es u Prolog (por ejemplo, los naturales con cero y sucesor), pero esto es poco prctico y poco eciente. a
Prolog proporciona los operadores arimticos habituales e (+, , , /, <, , . . . , sin, cos, . . . , log , . . . consultar manual) y el predicado built-in is para manipular nmeros: u
?- X is 2+3*5. X = 17 ? 17 is 2+3*5. Yes
26 / 101
-Number is +Expr tiene xito si Number unica con el valor obtenido al e email: jaime@sip.ucm.es evaluar Expr.
Los predicados se especican indicando el modo de uso de los argumentos: + El argumento debe estar completamente instanciado a un trmino (sin variables): argumento de entrada e - El argumento debe ser variable: argumento de salida ? El argumento puede estar parcialmente instanciado (variable o trmino con variables): argumento de entrada/salida e is no es reversible:
?- 6 is X+X. ERROR: is/2: Arguments are not sufficiently instantiated
27 / 101
Observacin: esta es una denicin recursiva no nal. o o Podr amos hacer una denicin recursiva nal? o
long(Xs,N):- longAc(Xs,0,N). longAc([],N,N). longAc([X|Xs],Ac,N):- Ac1 is Ac+1, longAc(Xs,Ac1,N).
Esta versin es ms eciente. Podemos utilizar variables annimas o a o en las deniciones anteriores?
28 / 101
(a1 , . . . , an ) (b1 , . . . , bn ) =
email: jaime@sip.ucm.es
ai bi
i=1
Lo natural parece representar cada vector como una lista con las componentes.
prodEsc([],[],0). prodEsc([X|Xs],[Y|Ys],N):- prodEsc(Xs,Ys,N1), N is N1+X*Y.
Esta denicin no es recursiva nal... ejercicio: hacer otra versin o o recursiva nal. Qu ocurre si las dos listas tienen distinta longitud (vectores con e distinto nmero de componentes)? u
29 / 101
Mapping
Jaime aplicar una En Prolog (y en Haskell) es muy habitualSnchez Hernndez Computacin Departamento de Sistemas Informticos y Universidad una lista Madrid operacin a cada uno de los elementos de Complutense de y obtener o email: jaime@sip.ucm.es una nueva lista resultado. Por ejemplo, incrementar en 1 cada uno de los elementos de la lista [5,4,7,8,9]. O ms en general, a incrementar en 1 los elementos de una lista L dada:
Mapping II
Jaime Snchez Hernndez
Departamento de Sistemas Informticos y Computacin Universidad Complutense de Madrid
email: jaime@sip.ucm.es
Esta idea es generalizable a rboles o cualquier otra estructura a de datos recursiva. Tambin es generalizable la operacin a e o aplicar (utilizando orden superior). Ejercicio: implementar parLst(+Xs,?Ys)::= obtiene en Ys una lista de booleanos correspondiente a la paridad/imparidad de cada elemento de la lista Xs Qu producir el objetivo parLst([1,2,3],[X,true|R]).? e a
31 / 101
incLst2([],[]). incLst2([X|Xs],[Y|Ys]):-
incLst2([X|Xs],[X|Ys]):-
Qu producir el objetivo incLst2([2,gato],L)? e a Hay soluciones indeseadas? Para evitar explorar ramas del rbol de bsqueda (podar) veremos predicados de control ms a u a adelante.
32 / 101
Qu produce lstPos([-5,2,3,-6,0,2],L)? e En este caso (a diferencia del anterior), las soluciones son las esperadas... por qu ahora ocurre as podr e ? amos aplicar la misma idea al predicado anterior incLst2?
33 / 101
Ms procesamiento de listas a
Jaime Snchez Hernndez
Departamento de Sistemas Informticos y Computacin Universidad Complutense de Madrid
Denir el predicado
email: jaime@sip.ucm.es
separa(+Xs,-Ys,-Zs)::= dada una lista de enteros Xs devuelve en Ys los mayores o iguales que 0 y en Zs los negativos (respetando el orden de la lista de entrada)
34 / 101
Ms listas a
Sosticando un poco la particin que acabamos de hacer: o Jaime Snchez Hernndez parte(+X,+Xs,-Men,-May)::= devuelve en Men los elementos de email: jaime@sip.ucm.es Xs menores o iguales que X y en May los mayores que X
parte( ,[],[],[]). parte(X,[Y|Ys],[Y|Men],May):- Y=<X, parte(X,Ys,Men,May). parte(X,[Y|Ys],Men,[Y|May]):- Y>X, parte(X,Ys,Men,May).
Departamento de Sistemas Informticos y Computacin Universidad Complutense de Madrid
Quicksort en C++
Jaime Snchez Hernndez
void particion(int v[], int ini, & int inf, sup, piv, tmp; email: jaime@sip.ucm.es piv=v[ini]; inf=ini+1; sup=fin; while (inf<=sup) { while (v[inf]<=piv) inf++; while (v[sup] >piv) sup--; if (inf<sup) { tmp=v[inf]; v[inf]=v[sup]; v[sup]=tmp; inf++; } v[ini]=v[sup]; v[sup]=piv; p=sup; } void quickSort(int v[], int ini, int fin) { int p; if (ini<=fin) { particion(v,ini,fin,p); quickSort(v,ini,p-1); quickSort(v,p+1,fin); } }
int Departamento de Sistemas Informticos y Computacin fin, int p) { Universidad Complutense de Madrid
sup--;}
36 / 101
email: jaime@sip.ucm.es
si la lista es vac la unica permutacin es la lista vac a o a si la lista tiene cabeza y resto, i.e., es de la forma [X |Xs], entonces una permutacin consiste en insertar X en cualquier o posicin de una permutacin de Xs o o Por ejemplo, para permutar [1, 2, 3, 4]:
dejamos el 1 fuera, permutamos (*) [2, 3, 4] obteniendo (por ejemplo) [3, 4, 2] y ahora insertamos el 1 en un lugar cualquiera (**) de esa lista, por ejemplo entre el 4 y el 2, obteniendo [3, 4, 1, 2]
Ntese que (*) y (**) son eleccione indeterministas!!... las o distintas ramas de cmputo darn lugar a todas las permutaciones o a posibles y solo ellas?
37 / 101
email: jaime@sip.ucm.es
Ser este problema igual de sencillo en C++ o en Java? a Ser fcil implementar una versin recursiva nal para permuta? a a o
38 / 101