David Camacho Fernández Temas Avanzados en Ingeniería Informática I (Lógica) Listas Listas y Corte en Prolog David Camacho Fernández Departamento de Ingenería Informática Despacho: B-306 e-mail: [email protected] http://www.ii.uam.es/~dcamacho Una lista es una secuencia de elementos. Estos elementos pueden ser términos (constantes, variables, estructuras) o incluso otra lista Representación: [Head|Tail] Functor . /2 [a,b,c,d] ; [a| [b,c,d]] ; Listas Listas Hay dos formas de definir listas en Prolog: (A,B) : Donde “A” es el primer elemento y “B” es la cola (resto de elementos de la lista). ) Ejemplos: También puede utilizarse la notación abreviada: ) ) Lógica [a,b,c] [] 1. Lista con un único elemento “a” Notación en Prolog ⇒ .(a,[ ]) Representación gráfica ⇒ . a • (a,[ ]) Es una lista con sólo el elemento “a” • (a,.(b,.(c,[ ]))) Es la lista formada por “a,b,c” Ejemplos: Lista formada por “a,b,c”. Lista vacía [ ] %lista vacía 2. Lista con tres átomos “a,b,c” Notación en Prolog ⇒ .(a,.(b,.(c,[]))) Representación gráfica ⇒ a . . b . c [ ] %lista vacía 1 David Camacho Fernández Listas También puede utilizarse el separador “|” [a|L] Lista con “a” en la cabeza y el resto en la variable L (cola) [a,b|L] Lista con los elementos “a” y “b” en la cabecera y el resto en la variable L (cola) [X|L] Lista con el primer elemento instanciado en la variable X y el resto en la variable L (cola) [X,Y|L] Lista con el primer elemento instanciado en la variable X, el segundo en Y, y el resto en la variable L (cola) Unificación de Listas Ejemplos: ?- [X,libro]=[lapiz,Y]. X=lapiz Y=Libro Yes ?- [X,libro]=[Y,lapiz]. No Lógica Listas Representación de listas Unificación de Listas • Ejemplos de unificación de listas. Lista 1 Lista 2 Instanciaciones [X,Y,Z] [esto,es,prolog] X=esto, Y=es, Z=prolog [mustang] [X|Y] [X,Y|Z] [cuando,harry,encontro,a,sal ly] X=mustang, Y=[] X=cuando, Y=harry, Z=[encontro,a,sally] [X,busca,Z] [harry,Y,sally] X=harry, Y=busca, Z=sally [X,[actor,Z]] [cine,[Y,meg]] X=cine, Y=actor, Z=meg [[el,Y],Z] [[X,libro],esta,aqui] X=el, Y=libro, Z=[esta,aqui] 2 David Camacho Fernández Unificación de Listas Ejemplos: p1(X,[a,X,b]). p2(X,[c|X]). p3(X,[X|d]). Consulta Resultado ?- p1(s,Y). Y = [a, s, b] ?- p2([u,v,w],Z). Z = [c, u, v, w] ?- p3(a,Y). Y = [a|d] ?- p3(a,[a,d]). No ?- p3(a,[a|d]). Yes ?- p1(X,[a,m,b]). X=m ?- p1(X,[a,b,c]). No Ejercicios Ejercicios 1) Eliminar el primer elemento de una lista 2) Añadir “zzz” como primer elemento a una lista 3) Escribir los elementos de una lista 4) Escribir los elementos de una lista del último al primero 5) Contar los elementos de una lista. 6) Buscar un elemento X en L 7) Concatenar dos cadenas L1 y L2 8) Eliminar la primera aparición de un elemento X en una lista L1, obteniendo L2 9) Eliminar todas las apariciones de un elemento X en una lista L1, obteniendo L2 10) Invertir el orden de los elementos en una lista Ejercicios 1) Eliminar el primer elemento de una lista. elimina([Z|L],L). 2) Añadir “zzz” como primer elemento a una lista. add(L,[zzz|L]). 3) Escribir los elementos de una lista. escribir([]). escribir([X|L]):-write(X),escribir(L). 4) Escribir los elementos de una lista del último al primero. escribir([]). escribir([X|L]):-escribir(L), write(X). 5) Contar los elementos de una lista. longitud([],0). longitud([X|Xs],N):-longitud(Xs,N1),N is N1+1. Lógica 6) Buscar un elemento X en L. pertenece(X,[X|L]). pertenece(X,[Y|L]):-pertenece(X,L). 7) Concatenar dos cadenas L1 y L2. concatenar([],L,L). concatenar([X|C1],L2,[X|C3]):-concatenar(C1,L2,C3). 8) Eliminar la primera aparición de un elemento X en una lista L1, obteniendo L2. elimina(X,[X|cola],cola). elimina(X,[Y|C1],[Y|C2]):-elimina(X,C1,C2). 9) Eliminar todas las apariciones de un elemento X en una lista L1, obteniendo L2. borrar(_,[],[]). borrar(X,[X|C],M):-!,borrar(X,C,M). borrar(X,[Y|L1],[Y|L2]):- borrar(X,L1,L2). 10) Invertir el orden de los elementos en una lista invertir([],[]). invertir([X|C],Z):- invertir(C,C1),concatenar(C1,[X],Z). 3 David Camacho Fernández Predicados útiles con listas Predicados útiles con listas 1º.- Número de elementos de una lista: longitud(Xs, N) 3º.- Creación de una lista a partir de dos listas (concatenar dos listas: Append). longitud([ ], 0). longitud([X | Xs], N) :- longitud(Xs, N1), N is N1+1. 2º.- Pertenencia a una lista: pertenece(X, L) concatenar([ ], L, L). concatenar([X|C1],L2, [X|C3]) :- concatenar(C1,L2,C3). 4º.- Eliminación de un elemento X de una lista L1, como consecuencia se obtiene la lista L2 (se elimina la primera aparición del elemento). % 1ª forma pertenece(X, [ ]) :- fail. pertenece(X, [X|L]). pertenece(X, [Y|L]) :- X\=Y, pertenece(X, L). % 2ª forma pertenece(X, [X|L]). pertenece(X, [Y|L]) :- pertenece(X, L). Predicados útiles con listas 5º.- Eliminación 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). Lógica concatenar(L1,L2,L3) 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). Modos de funcionamiento en Prolog Un predicado puede ser utilizado con diversos tipos de argumentos, pero no siempre está garantizado que funcione. Los tipos de argumentos más comunes son: Términos (constantes o variables instanciadas). Representados con + Variables libres. Representado con – Cualquiera de los dos. representado con ? 4 David Camacho Fernández Modos de funcionamiento en Prolog Modos de funcionamiento en Prolog Posibilidades: ) ) ) ) igual1(constante, constante) igual1(vlibre, constante) igual1(constante, vlibre) igual1(vlibre, vlibre) Resumen : igual1(+,+). igual4(X,X). ) ) ) ) igual1(X, Y) :- X =:= Y. funciona ==> igual1(+, +) no funciona no funciona no funciona igual4(constante, constante) igual4(vlibre, constante) funciona igual4(constante, vlibre) funciona igual4(vlibre, vlibre) funciona funciona ==> igual4(+, +) ==> igual4(-, +) ==> igual4(+, -) ==> igual4(-, -) igual5(X, Y) :- igual5(constante, constante) igual5(vlibre, constante) igual5(constante, vlibre) igual5(vlibre, vlibre) Resumen : igual5(?,+). Eficiencia y Corte Programar en Prolog la siguiente función matemática: Función escalón ⎧0, ⎪ f ( x) = ⎨2, ⎪4, ⎩ 4 2 0 -6 Lógica funciona ==> igual5(+, +) funciona ==> igual5(-, +) no funciona no funciona Resumen : igual4(?, ?) Eficiencia y Corte X is Y. -3 0 3 6 9 x<3 3≤ x<6 6≤x Una posible solución (la más intuitiva) sería la mostrada a continuación: f(X,Y) :- X < 3, Y is 0. f(X,Y) :- 3 =< X, X < 6. Y is 2. f(X,Y) :- 6 =< X, Y is 4. % f(+,?) Se puede optimizar adelantando la equiparación: f(X,0) :- X < 3. f(X,2) :- 3 =< X, X < 6. f(X,4) :- 6 =< X. % f(+,?) 5 David Camacho Fernández Eficiencia y Corte Eficiencia y Corte Las soluciones mostradas son poco eficientes debido a que se hacen demasiadas comprobaciones f(2,Y), Y =:= 2. f(X,4) :- X>=6. f(X,0) :- X < 3. Ejemplo, al intentar calcular No. X=2, Y=0, X<3, Y=:=2. ¡fallo! f(X,2) :- 3=<X, X<6. ?- f(2,Y),Y =:= 2. Se comprueban las 3 cláusulas cuando sólo haría falta comprobar una X=2, Y=4, X>=6. ¡fallo! X=2, Y=2, X>=3. ¡fallo! Eficiencia y Corte Corte (verde) Existe un predicado que capaz de ‘cortocircuitar’ la búsqueda una vez que es evaluado El corte, representado con el símbolo de admiración “!” Lógica Def: El corte, es un predicado que siempre se evalúa como cierto y que impide que se continúen evaluando el resto de reglas Eficiencia y Corte Corte (verde) Def2: El corte es un predicado que cuando se ejecuta la primera vez se satisface, pero si se vuelve a él como consecuencia de una vuelta atrás (backtracking) no sólo falla él sino que también lo hace el objetivo que utilizó la cláusula que contenía el corte En términos de Prolog podríamos definirlo de la siguiente forma: corte :- true. corte :- fail (el objetivo padre). Cuando se ejecuta un corte se descartan todas las alternativas de los subojetivos comprendidos entre el que utilizó la cláusula que contenía el corte (objetivo padre) y la inmediatamente anterior al corte, ambos subobjetivos incluidos 6 David Camacho Fernández Eficiencia y Corte Ejemplo: f(X,0) :- X < 3, !. f(X,2) :- 3 =< X, X < 6, !. f(X,4) :- 6 =< X. Eficiencia y Corte Corte (verde) => si se elimina el programa sigue funcionando % f(+,?) f(2,Y), Y =:= 2. f(X,0) :- X < 3, !. No. f(X,4) :- X>=6. X=2, Y=0, X<3, !, Y=:=2. X=2, Y=4, X>=6. ¡fallo! Basándonos en un programa semánticamente correcto hemos añadido el operador de corte para obtener un programa más eficiente => Corte Verde f(X,2) :- 3=<X, !, X<6. ¡fallo! X=2, Y=2, X>=3. ¡fallo! Eficiencia y Corte Corte (rojo) Eficiencia y Corte f(X,0) :- X < 3, !. f(X,2) :- X < 6, !. f(X,4). f(X,0) :- X < 3, !. f(X,2) :- 3 =< X, X < 6, !. f(X,4) :- 6 =< X. Lógica Puede reescribirse el programa de la siguiente forma: Utilizando el ejemplo anterior: Porqué comprobar algunas condiciones en el programa, si el corte las hace superfluas. En el ejemplo, la segunda cláusula sólo se alcanza cuando X>3 y la tercera cuando X>6 Deja de funcionar en modo f(+,+) Por ejemplo el caso f(0,4) daría cierto 7 David Camacho Fernández Eficiencia y Corte Eficiencia y Corte El problema es que el nuevo programa se basa en un programa semánticamente incorrecto Ejemplo 2: utilizando la función anterior evaluar: ?- f(1,Y),2<Y. Si eliminásemos el corte, observaríamos que al eliminar el operador de corte obtenemos un programa incorrecto: f(X,0) :- X < 3. f(X,2) :- X < 6. f(X,4). 1. Sin corte 2. Con corte (propuesto…..) % ¡MAL! Eficiencia y Corte Ejemplo 2: ?- f(1,Y),2<Y. 1. Eficiencia y Corte (1) (2) (3) (4) (5) (6) (7) (8) Sin corte ? f (1,Y) , 2 < Y Cláusula 1 Y=0 1 < 3, 2 < 0 2<0 no Lógica Cláusula 2 Y=2 3 ≤ 1, 1 < 6, 2 < 2 no Ejemplo 3: (sin corte) Cláusula 3 Y=4 C :- P,Q,R,S,T,U. C :- V. A :- B,C,D. A :- P. B. P. Q. V. 6 ≤ 1, 2 < 4 no Consulta: ?-A. 8 David Camacho Fernández Eficiencia y Corte Eficiencia y Corte Ejemplo 3: (sin corte) Ejemplo 3: (con corte) ?- A. ?- B,C,D. (1) (2) (3) (4) (5) (6) (7) (8) ?-P. ?- C,D. si ?- P,Q,R,S,T,U. ?- V,D. ?- Q,R,S,T,U. ?- D. ?- R,S,T,U. no Consulta: ?-A. no Eficiencia y Corte Ejemplo 3: (con corte) C :- P,Q,!,R,S,T,U. C :- V. A :- B,C,D. A :- P. B. P. Q. V. Eficiencia y Corte Ejercicio: Programar la siguiente función matemática: ?- A. ?- B,C,D. Función rampa ?-P. 6 ?- C,D. si 5 ⎧3 − x , ⎪ g ( x ) = ⎨ x − 3, ⎪9 − x , ⎩ 4 ?- P,Q,!,R,S,T,U. 3 2 ?- Q,!,R,S,T,U. 1 ?- R,S,T,U. no Lógica 0 -3 -2 -1 -1 0 1 2 3 4 5 6 7 8 9 x<3 3≤ x < 6 6≤ x 10 -2 9 David Camacho Fernández Eficiencia y Corte Solución: Eficiencia y Corte sin utilizar el corte podría ser: p(1). p(2) :- !. 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 obtendría: 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. Sea el siguiente programa Prolog: p(3). Escribir las respuestas a las siguientes consultas: ?- p(X). ?- p(X), p(Y). ?- p(X), !, p(Y). Eficiencia y Corte Escribir las respuestas a las siguientes consultas: ?- p(X). X=1; X=2; no ?- p(X), p(Y). X=1 Y=1; X=1 Y=2; X=2 Y=1; X=2 Y=2; no ?- p(X), !, p(Y). X=1 Y=1; X=1 Y=2; no Lógica 10