400 likes | 589 Views
III. Exploración en Prolog. Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria. La exploración en Prolog. Exploración en profundidad. Estrategias. Exploración sistemática de todas las posibilidades.
E N D
III. Exploración en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria Prolog III
La exploración en Prolog Exploración en profundidad Estrategias Exploración sistemática de todas las posibilidades Exploración secuencial de izquierda a derecha de las condiciones and,tanto en las reglas como en el teorema Exploración secuencial de arriba a abajo de las condiciones or, desde el principio al final de la base de datos Prolog III
La exploración en Prolog Consideremos el siguiente programa a(X) :- b(X). a(w). b(X) :- c(X), d(X). b(y). b(w). c(w). d(z). a1 (X) :- b(X). a2 (w). b1 (X) :- c(X), d(X). b2 (y). b3 (w). c(w). d(z). ?- a(X). y la pregunta: Prolog III
La exploración en Prolog [ a(X) ] [[ a1(X) ] [ a2(X) ] ] [ [ [ b1(X) ] [ b2(X) ] [ b3(X) ] ] [ a2(X) ] ] [ [ [ c(X), d(X) ] [ b2(X) ] [ b3(X) ] ] [ a2(X) ] ] X = w [ [ [ c(w), d(w) ] [ b2(X) ] [ b3(X) ] ] [ a2(X) ] ] [ [ [ d(w) ] [ b2(X) ] [ b3(X) ] ] [ a2(X) ] ] Fail, backtrack [ [ [ b2(X) ] [ b3(X) ] ] [ a2(X) ] ] X = y [ [ [ b2(y) ] [ b3(X) ] ] [ a2(X) ] ] [ [ [] [ b3(X) ] ] [ a2(X) ] ] 1. Solución X = y [ [ [ b3(X) ] ] [ a2(X) ] ] Prolog III
La exploración en Prolog 1. Solución X = y [ [ [ b3(X) ] ] [ a2(X) ] ] X = w [ [ [ b3(w) ] ] [ a2(X) ] ] [ [ [] ] [ a2(X) ] ] 2. Solución X = w [ [ a2(X) ] ] X = w [ [ a2(w) ] ] [ [] ] 3. Solución X = w Prolog III
?- a(X). T Call a1: ( 7) a(_G93) T Call b1: ( 8) b(_G93) T Call c : ( 9) c(_G93) T Exit c : ( 9) c(w) T Call d : ( 9) d(w) T Fail d : ( 9) d(w) T Redo b2: ( 8) b(_G93) T Exit b2: ( 8) b(y) T Exit a1: ( 7) a(y) X = y ; T Redo b3: ( 8) b(_G93) T Exit b3: ( 8) b(w) T Exit: a1: ( 7) a(w) X = w ; T Redo a2: ( 7) a(_G93) T Exit a2: ( 7) a(w) X = w ; No a1 (X) :- b(X). a2 (w). b1 (X) :- c(X), d(X). b2 (y). b3 (w). c(w). d(z). 1. Solución X = y 2. Solución X = w 3. Solución X = w Prolog III
El predicado cut (!) Consideremos la siguiente base de conocimiento ... a(X) :- b(X). a(w). b(X) :- c(X), d(X). b(y). b(w). c(w). d(z). a1 (X) :- b(X). a2 (w). b1 (X) :- c(X), d(X). b2 (y). b3 (w). c(w). d(z). ?- a(X). 1. Solución X = y 2. Solución X = w 3. Solución X = w Prolog III
El predicado cut (!) Introduzcamos una “ligerísima” variación ... a(X) :- b(X). a(w). b(X) :- c(X), !, d(X). b(y). b(w). c(w). d(z). a1 (X) :- b(X). a2 (w). b1 (X) :- c(X), !, d(X). b2 (y). b3 (w). c(w). d(z). Prolog III
La exploración en Prolog [ a(X) ] [[ a1(X) ] [ a2(X) ] ] [ [ [ b1(X) ] [ b2(X) ] [ b3(X) ] ] [ a2(X) ] ] [ [ [ c(X), !, d(X) ] [ b2(X) ] [ b3(X) ] ] [ a2(X) ] ] X = w [ [ [ c(w), !, d(w) ] [ b2(X) ] [ b3(X) ] ] [ a2(X) ] ] [ [ [ !, d(w) ] [ b2(X) ] [ b3(X) ] ] [ a2(X) ] ] [ [ [ d(w) ] ] [ a2(X) ] ] Fail, backtrack [ [ a2(X) ] ] X = w [ [ a2(w) ] ] [ [] ] 1. Solución X = w ¡¡¡ Una única solución !!! Prolog III
El predicado cut (!) ?- a(X). T Call a1: ( 7) a(_G93) T Call b1: ( 8) b(_G93) T Call c : ( 9) c(_G93) T Exit c : ( 9) c(w) ----- PODA b: ------ T Call d : ( 9) d(w) T Fail d : ( 9) d(w) T Fail b1: ( 8) b(_G93) --- b2 y b3 han sido podadas --- T Redo a2: ( 7) a(_G93) T Exit a2: ( 7) a(w) X = w ; No a1 (X) :- b(X). a2 (w). b1 (X) :- c(X), !, d(X). b2 (y). b3 (w). c(w). d(z). Prolog III
?- a(X). T Call a1: ( 7) a(_G93) T Call b1: ( 8) b(_G93) T Call c : ( 9) c(_G93) T Exit c : ( 9) c(w) T Call d : ( 9) d(w) T Fail d : ( 9) d(w) T Redo b2: ( 8) b(_G93) T Exit b2: ( 8) b(y) T Exit a1: ( 7) a(y) X = y ; T Redo b3: ( 8) b(_G93) T Exit b3: ( 8) b(w) T Exit: a1: ( 7) a(w) X = w ; T Redo a2: ( 7) a(_G93) T Exit a2: ( 7) a(w) X = w ; No ?- a(X). T Call a1: ( 7) a(_G93) T Call b1: ( 8) b(_G93) T Call c : ( 9) c(_G93) T Exit c : ( 9) c(w) ----- PODA b: ------ T Call d : ( 9) d(w) T Fail d : ( 9) d(w) --- b2 y b3 han sido podadas --- no hay backtracking posible para la llamada ( 8) por lo que falla. T Fail b1: ( 8) b(_G93) T Redo a2: ( 7) a(_G93) T Exit a2: ( 7) a(w) X = w ; No Prolog III
El predicado cut (!) (como ejercicio) ¿Qué diferencias se presentan cuando introducimos otra “ligerísima” variación añadiendo una nueva definición del predicado c/1 en estas dos versiones del programa ? a1 (X) :- b(X). a2 (w). b1 (X) :- c(X), d(X). b2 (y). b3 (w). c1 (y). c2 (z). d(z). a1 (X) :- b(X). a2 (w). b1 (X) :- c(X), !, d(X). b2 (y). b3 (w). c1 (y). c2 (z). d(z). Prolog III
[ a(X) ] [[ a1(X) ] [ a2(X) ] ] [ [ [ b1(X) ] [ b2(X) ] [ b3(X) ] ] [ a2(X) ] ] [ [[[ c1(X), d(X) ] [ c2(X), d(X) ]] [ b2(X) ] [ b3(X) ] ] [ a2(X) ] ] X = y [ [[[ c1(y), d(y) ] [ c2(X), d(X) ]] [ b2(X) ] [ b3(X) ] ] [ a2(X) ] ] [ [[[ d(y) ] [ c2(X), d(X) ]] [ b2(X) ] [ b3(X) ] ] [ a2(X) ] ] Fail, backtrack [ [ [ c2(X), d(X) ] [ b2(X) ] [ b3(X) ] ] [ a2(X) ] ] X = z [ [ [c2(z), d(z) ] [ b2(X) ] [ b3(X) ] ] [ a2(X) ] ] [ [ [d(z) ] [ b2(X) ] [ b3(X) ] ] [ a2(X) ] ] [ [ [] [ b2(X) ] [ b3(X) ] ] [ a2(X) ] ] 1. Solución X = z Prolog III
[ [ [ b2(X) ] [ b3(X) ] ] [ a2(X) ] ] X = y [ [ [ b2(y) ] [ b3(X) ] ] [ a2(X) ] ] [ [ [] [ b3(X) ] ] [ a2(X) ] ] 2. Solución X = y [ [ [ b3(X) ] ] [ a2(X) ] ] X = w [ [ [ b3(w) ] ] [ a2(X) ] ] [ [ [] ] [ a2(X) ] ] 3. Solución X = w [ [ a2(X) ] ] X = w [ [ a2(w) ] ] [ [] ] 4. Solución X = w Prolog III
Cut: • Es un predicado extra-lógico que siempre se evalúa a cierto. • Provoca la poda o eliminación de alternativas. • Concretamente impide que se intente la verificación de las opciones pendientes de los predicados a la izquierda del mismo Prolog III
Ejemplo incluido( X, [X | _ ] ). incluido( X, [_ | Y ] ) :- incluido( X, Y). incluido( X, [X | Y], Y). incluido( X, [_ | Y ], Z) :- incluido( X, Y, Z). ?- incluido(a,[a,b,a,c,o]). true; true; false. ?- incluido(a,[a,b,a,c,o],R). R = [b, a, c, o] ; R = [c, o] ; false. Prolog III
Ejemplo incluido( X, [X | _ ] ). incluido( X, [_ | Y ] ) :- incluido( X, Y). incluido( X, [X | Y], Y). incluido( X, [_ | Y ], Z) :- incluido( X, Y, Z). ?- incluido(a,[a,b,a,c,o],R). R = [b, a, c, o] ; R = [c, o] ; false. ?- incluido(a,[a,b,a,c,o],R),!. R = [b, a, c, o] ; false. Prolog III
Ejemplo Generación de estructuras alternativas predicado :- condicion, !, accion1. predicado :- accion2 max( X, Y, Z):- X>Y, Z is X. max( X, Y, Z):- Z is Y. max( X, Y, Z):- X>Y, !, Z is X. max( X, Y, Z):- Z is Y. ?- max( 2, 3, Z). Z = 3 ; No ?- max( 2, 3, Z). Z = 3 ; No ?- max( 3, 2, Z). Z = 3 ; Z = 2 ; No ?- max( 3, 2, Z). Z = 3 ; No Prolog III
Generación de estructuras alternativas En muchas implementaciones de Prolog se dispone del operador ‘->’, cuya semántica es equivalente a la construcción: (Condición, !, Acción1; Acción2) Más concretamente, su definición en muchos sistemas es la siguiente: Condición -> Acción1 ; _ :- Condición, !, Acción1. Condición -> _ ; Acción2 :- !, Acción2. Condición -> Acción :- Condición, !, Acción. Prolog III
El operador ‘->’ puede encadenarse para simular la construcción “case”, presente en otros lenguajes imperativos: case :- ( Condición1 -> Acción1 ; Condición2 -> Acción2 ; … ; CondiciónN –> AcciónN ; OtroCaso ). Prolog III
Definición libro('Todos los nombres', 'Saramago'). libro('Cuadernos de Lanzarote', 'Saramago'). libro('Ensayo sobre la ceguera', 'Saramago'). libro('El Evangelio según Jesucristo', 'Saramago'). un_libro_de(X) :- libro(Y,X),write(Y),nl. todos_los_libros_de(X) :- libro(Y,X), write(Y), nl, fail. El predicado Fail Prolog III
?- un_libro_de('Saramago'). Todos los nombres Yes ?- todos_los_libros_de('Saramago'). Todos los nombres Cuadernos de Lanzarote Ensayo sobre la ceguera El Evangelio según Jesucristo No Prolog III
todos_los_libros_de(X) :- libro(Y,X), write(Y), nl, fail. T Redo: ( 8) libro(_L143, 'Saramago') T Exit: ( 8) libro('El Evangelio según Jesucristo', 'Saramago') T Call: ( 8) write('El Evangelio según Jesucristo') El Evangelio según Jesucristo T Exit: ( 8) write('El Evangelio según Jesucristo') T Call: ( 8) nl T Exit: ( 8) nl T Call: ( 8) fail T Fail: ( 8) fail No T Redo: ( 8) libro(_L143, 'Saramago') T Exit: ( 8) libro('Ensayo sobre la ceguera', 'Saramago') T Call: ( 8) write('Ensayo sobre la ceguera') Ensayo sobre la ceguera T Exit: ( 8) write('Ensayo sobre la ceguera') T Call: ( 8) nl T Exit: ( 8) nl T Call: ( 8) fail T Fail: ( 8) fail T Redo: ( 8) libro(_L143, 'Saramago') T Exit: ( 8) libro('Cuadernos de Lanzarote', 'Saramago') T Call: ( 8) write('Cuadernos de Lanzarote') Cuadernos de Lanzarote T Exit: ( 8) write('Cuadernos de Lanzarote') T Call: ( 8) nl T Exit: ( 8) nl T Call: ( 8) fail T Fail: ( 8) fail ?- todos_los_libros_de('Saramago'). T Call: ( 8) libro(_L143, 'Saramago') T Exit: ( 8) libro('Todos los nombres', 'Saramago') T Call: ( 8) write('Todos los nombres') Todos los nombres T Exit: ( 8) write('Todos los nombres') T Call: ( 8) nl T Exit: ( 8) nl T Call: ( 8) fail T Fail: ( 8) fail Prolog III
Fail: • Es un predicado que nunca se evalúa a cierto. • Provoca la “vuelta atrás” o backtracking y • por tanto, que se explore la siguiente • alternativa. Prolog III
La negación: el operador Not “A María le gustan todos los animales excepto las serpientes” ¿Cómo podemos decir esto en Prolog? Veamos la parte fácil: gusta(maría, X):- animal(X). Ahora es necesario excluir a las serpientes: Si X es una serpiente entonces “gusta(maría, X)” no es verdadero, en otro caso si X es un animal entonces a María le gusta X Prolog III
La negación: el operador Not Si X es una serpiente entonces “gusta(maría, X)” no es verdadero, en otro caso si X es un animal entonces a María le gusta X gusta( maría, X) :- serpiente(X), !, fail. gusta( maría, X) :- animal(X). gusta( maría, X) :- serpiente(X), !, fail ; animal(X). Prolog III
La negación: el operador Not Consideremos otro caso: Intentemos definir el predicado diferente(X,Y): Si X e Y son unificables entonces “diferente( X, Y)” falla, en otro caso “diferente( X, Y)” es verdadero diferente(X, Y) :- X = Y, !, fail ; true. Prolog III
La negación: el operador Not Estos dos ejemplos sugieren la posible utilidad de un operador Not, de manera que not(Objetivo) sea verdadero si Objetivo es falso not(P) :- P, !, fail ; true gusta( maría, X) :- serpiente(X), !, fail ; animal(X). diferente(X, Y) :- X = Y, !, fail ; true. Prolog III
La negación: el operador Not diferente(X, Y) :- X = Y, !, fail ; true. gusta( maría, X) :- serpiente(X), !, fail ; animal(X). diferente(X, Y) :- not( X = Y ). gusta( maría, X) :- animal(X), not( serpiente( X )). gusta( maría, X) :- animal(X), not serpiente( X ). gusta( maría, X) :- animal(X), \+ serpiente( X ). Prolog III
Un uso interesante de not: forall(A,B) :- \+ (A, \+B). forall(:Cond, :Action) [semidet] For all alternative bindings of Cond, Action can be proven. 3 ?- forall(member(Result = Formula, [2 = 1 + 1, 4 = 2 * 2]), Result =:= Formula). true. 4 ?- forall(member(Atom, [ejem, aja, ojú]), name(Atom,[_,106|_])). true. Prolog III
Problemas con cut y not Consideremos el siguiente ejemplo p :- a, b. p :- c. El significado declarativo de este programa es: p es cierto si a y b son ciertos o si c es cierto p <==> (a b) c Podemos cambiar el orden de las cláusulas sin afectar el significado declarativo del programa Prolog III
Problemas con cut y not Si ahora insertamos una poda: p :- a, !, b. p :- c. El significado declarativo de este programa es ahora: p es cierto si a y b son ciertos o si a no es cierto y c es cierto p <==> (a b) (~a c) Prolog III
Problemas con cut y not Si se intercambia el orden de las cláusulas: p :- c. p :- a, !, b. El significado declarativo de este programa cambia a: p es cierto si c es cierto o si a y b son ciertos p <==> c (a b) Prolog III
Problemas con cut y not La base de datos contiene nombres de personajes cuya inocencia o culpabilidad es conocida. inocente( peter_pan). inocente( X) :- ocupación(X, duende). inocente( winnie_the_pooh). inocente( mary_poppins). culpable(X) :- ocupación(X, ladrón). culpable(joe_bloggs). Prolog III
Problemas con cut y not inocente( peter_pan). inocente( X) :- ocupación(X, duende). inocente( winnie_the_pooh). inocente( mary_poppins). ocupación(david_el_gnomo, duende). culpable(X) :- ocupación(X, ladrón). culpable(joe_bloggs). inocente( peter_pan). inocente( X) :- ocupación(X, duende). inocente( winnie_the_pooh). inocente( mary_poppins). ocupación(david_el_gnomo, duende). culpable(X) :- ocupación(X, ladrón). culpable(joe_bloggs). culpable(X) :- \+ inocente(X). Considérese el siguiente diálogo sobre heidi, cuya inocencia es conocida por todos excepto por la base de datos de la Policía. ?- inocente( heidi). No. ?- culpable( heidi). Yes. Prolog III
Problemas con cut y not Consideremos ahora este programa: buena_comida( jean_luis). caro(jean_luis). buena_comida(francesco). aceptable(Restaurante) :- not(caro(Restaurante)). ?- buena_comida(X), aceptable(X). X = francesco. ?- aceptable(X), buena_comida(X). No. Prolog III
Problemas con cut y not ?- aceptable(X),buena_comida(X). T Call: ( 8) aceptable(_G237) T Call: ( 9) not(caro(_G237)) T Call: ( 10) caro(_G237) T Exit: ( 10) caro(jean_luis) T Fail: ( 9) not(caro(_G237)) T Fail: ( 8) aceptable(_G237) No buena_comida( jean_luis). caro(jean_luis). buena_comida(francesco). aceptable(Restaurante) :- not(caro(Restaurante)). Prolog III
Problemas con cut y not Es mala práctica desarrollar programas que destruyen la correspondencia entre el significado lógico y procedimental de un programa sin una buena razón para hacerlo. Una solución: especificar la negación como indefinida cuando se realiza el intento de negar un término que contiene variables no instanciadas. Prolog III
Problemas con cut y not buena_comida( jean_luis). caro(jean_luis). buena_comida(francesco). aceptable(Restaurante) :- ground(caro(Restaurante)), !, \+ caro(Restaurante) ; write('No puedo negar algo Indefinido'), nl, fail. ?- buena_comida(X), aceptable(X). X = francesco ; No ?- aceptable(X), buena_comida(X). No puedo negar algo Indefinido No Prolog III
Sumario. • True siempre se verifica y Fail siempre falla. • Cut previene la exploración de alternativas. • Cut puede mejorar la eficiencia de un programa. • Cut permite formular conclusiones mutuamente • excluyentes mediante reglas de la forma: • If Condición then Conclusión1 else Conclusión2 • Cut permite introducir el operador not: La negación • como fallo. • Cut y Not deben ser utilizados con prudencia. Prolog III