Prolog de Primer Orden • Prolog es un ejemplo de un paradigma de programación llamado programación en lógica. • Un programa en Prolog puro de primer orden es un conjunto de cláusulas de horn definitivas de primer orden. • Una cláusula de horn definitiva de primer orden es una cláusula, cuantificada universalmente y que contiene exactamente un literal positivo. Por ejemplo: ∀xyz (P (x, y) ∨ ¬Q(x, y) ∨ ¬R(x, y, z)) • En programación en lógica, esta cláusula se anota simplemente como: P (x, y) ← Q(x, y), R(x, y, z) • Los predicados se anotan con letras minúsculas. Si p de aridad n, se acostumbra a llamarlo por p/n. Jorge Baier Aranda, PUC << Atrás 174 • Al igual que en lógica de predicados, un término puede ser: Constantes: Estas pueden ser: Átomos: Sı́mbolos que comienzan con letra minúscula, por ej. x, y, a, etc. Sı́mbolos encerrados en comillas simples, por ej. ’X’, ’ 5’, ’ x23’, ’a’,, etc. Números: Enteros y/o reales. Por ej. 4, 9.5, etc.. Caracteres y textos (strings): Los carácteres y los strings se encierran entre comillas dobles. Por ej. "f", "fam", etc. Variables: Sı́mbolos que comiencen con letra mayúscula o con un guión bajo ’ ’. Por ej., X, 5, x23. Functores: Son términos de función. Por ej., padre(X,bonifacio), etc. Un functor tiene una aridad asociada. Si f es el nombre de un functor, f /m denota que f tiene aridad m. • Un programa prolog está compuesto por cláusulas de horn con la siguiente sintaxis l:-l1, . . . , ln, donde l, y l1, ..., ln son literales positivos. Jorge Baier Aranda, PUC << Atrás 175 En el caso en que n = 0, la cláusula se llama hecho y se anota simplemente como l. Cuando n > 0 se acostumbra a llamar reglas a las cláusulas. • Por ejemplo, la siguiente cláusula (o regla) Prolog: ancestro(X,Y) :- progenitor(X,Z),ancestro(Z,Y). corresponde a la siguiente cláusula de primer orden: ∀x∀y∀z (progenitor(x, z) ∧ ancestro(z, y) → ancestro(x, y)) que, a su vez, es equivalente a: ∀x∀y (∃z (progenitor(x, z) ∧ ancestro(z, y)) → ancestro(x, y)) Esto significa que toda variable que no se menciona en forma explı́cita en la cabeza de una regla se debe suponer como cuantificada existencialmente en la cola de ella. Jorge Baier Aranda, PUC << Atrás 176 • El siguiente ejemplo se puede ver como una base de datos de una familia. padre(alberto,juan). madre(julia,juan). padre(pedro,maria). madre(helena,maria). padre(juan,olga). madre(maria,olga). padre(juan,’Alberto Jr.’). progenitor(X,Y) :- padre(X,Y). progenitor(X,Y) :- madre(X,Y). ancestro(X,Y) :- progenitor(X,Y). ancestro(X,Y) :- progenitor(X,Z),ancestro(Z,Y). • Este programa es una teorı́a de primer orden. Prolog permite consultar qué cosas se deducen de él. La respuesta la entrega usando un mecanismo de demostración que veremos más adelante. Jorge Baier Aranda, PUC << Atrás 177 • Las siguientes son consultas que se pueden hacer al intérprete. ?- progenitor(juan,olga). Yes. ?- progenitor(X,juan). X = alberto Yes • La segunda consulta se progenitor(X,juan)?”. puede leer como “¿existe un X tal que obtienen de la consulta • Al ingresar ; Prolog busca otra respuesta. • Estas son todas las progenitor(X,juan). respuestas que se X = alberto ; X = julia ; No Jorge Baier Aranda, PUC << Atrás 178 • La siguiente consulta pregunta por todos los X que son descendientes de alberto, ?- ancestro(alberto,X). X = juan ; X = olga ; X = ’Alberto Jr.’ ; No • ¿Qué significa la siguiente consulta? ?- ancestro(p,q). No • ¿Qué significa este comportamiento desde el punto de vista lógico? • Si un intérprete de Prolog logra demostrar una consulta φ dado un programa P, entonces diremos que: P `p φ • La pregunta anterior se puede reformular como: ¿Podemos establecer una correspondencia entre |= y `p? Jorge Baier Aranda, PUC << Atrás 179 Algoritmo de Resolución de P ROLOG • A continuación presentamos una simplificación del algoritmo de resolución de Prolog de primer orden. • En el pseudo código del algoritmo se utiliza las siguientes convenciones. GL0: Lista de literales correspondientes al objetivo o consulta inicial. GL: Lista de objetivos (literales positivos). ren: Un procedimiento que recibe una lista de literales y renombra las variables con nombres nuevos. Es usual que estos nombres sean de la forma n donde n es un número entero. PP y PP aux: Dos procedimientos que reciben una lista de objetivos y retornan una sustitución o #Falso si no hay sustitución posible. PP aux recibe además de la lista de objetivos, un ı́ndice a una cláusula dentro del programa. UMG Prolog: El procedimiento UMG sin occurs check (ya veremos de que se trata esto). Jorge Baier Aranda, PUC << Atrás 180 c1, c2, . . . cm: Las cláusulas del programa. #m: Constante que se inicializa como el número de cláusulas del programa. Cabeza y Cola: dos funciones sobre reglas o listas de objetivos. Si x es una lista, entonces Cabeza(x) es el primer literal de x y Cola(x) es el resto de la lista. Si x es una cláusula, Cabeza(x) es la cabeza de la cláusula y Cola(x) es el cuerpo. aplicarSust : Aplica una sustitución a un conjunto de variables cláusulas. composición: Permite componer dos sustituciones. • Dado que GL0 es el objetivo inicial, el procedimiento prolog se invoca como: PP(ren(GL0), nil) Jorge Baier Aranda, PUC << Atrás 181 • A continuación se muestra la implementación de las funciones necesarias para la resolución: function PP(GL,S) /* devuelve una sustitución que satisfaga GL o devuelve #Falso */ { if GL=nil return(S); PP_aux(GL,S,1) } function PP aux(GL,S,i) /* devuelve sustitución que satisfaga GL o #Falso */ { cláusula C’; /* variables auxiliares */ sustitución S’, S’’; if i>#m return(#Falso); C’:= ren(C[i]); S’:= UMG_Prolog(Cabeza(GL),Cabeza(C’)); if S’=#Falso return(PP_aux(GL,S,i+1)); S’’:=PP(aplicarSust(S’,append(Cola(C’),Cola(GL))), composición(S,S’)); if S’’=#Falso return(PP_aux(GL,S,i+1)); return(S’’); Jorge Baier Aranda, PUC << Atrás 182 } • Tal como sugerimos en resolución de primer orden, este algoritmo renombra variables antes de aplicar la regla de resolución. • Si Prolog responde NO cuando este algoritmo retorna #Falso, ¿qué significa que Prolog responda NO? • ¿qué le falta a este algoritmo? – Resatisfacción de consultas. ¿cómo podemos implementar esto? – ¿Cómo podemos incorporar negación? Jorge Baier Aranda, PUC << Atrás 183 Árboles de demostración • En Prolog es posible rastrear la demostración de un objetivo a través del comando trace. • Una vez que el intérprete está en modo trace, toda demostración de una consulta es mostrada paso a paso. • Volvamos a considerar el ejemplo de la base de datos familiar. • El siguiente ejemplo muestra un trace de la ejecución de la consulta ancestro(alberto,olga). [trace] ?- progenitor(maria,X). Call: Call: Fail: Redo: Call: Exit: Exit: (6) (7) (7) (6) (7) (7) (6) progenitor(maria, G384) ? creep padre(maria, G384) ? creep padre(maria, G384) ? creep progenitor(maria, G384) ? creep madre(maria, G384) ? creep madre(maria, olga) ? creep progenitor(maria, olga) ? creep X = olga ; Jorge Baier Aranda, PUC << Atrás 184 Fail: Fail: No (7) madre(maria, G384) ? creep (6) progenitor(maria, G384) ? creep • Esta demostración se puede resumir en el siguiente árbol de demostración: progenitor(maria,X) X= G384 progenitor(maria, G384) .... .......... ..................... .......... ...... .......... .......... .......... .......... . . . . . . . . . . .......... .......... .......... .......... .......... . . . . . . . . . ... .......... .......... .......... padre(maria, G384) ........... ........... ........... ........... ........... ........... ........... ........... ........... ........... ........... ........... ........... ..... madre(maria, G384) . × G384=olga • En forma resumida, en un árbol de demostración: – Cada nodo no hoja tiene como etiqueta un objetivo a demostrar o los sı́mbolos. – Los nodos hoja están etiquetados con o ×. – Si un nodo n es padre de un nodo h, entonces h es el resultado de aplicar la regla de resolución entre n y alguna cláusula del programa. Jorge Baier Aranda, PUC << Atrás 185 – La etiqueta que une a n con h es la sustitución aplicada en la resolución. – Una demostración exitosa de un objetivo está dada por las resoluciones que dan origen a una rama que termina en un nodo hoja etiquetado con (cláusula vacı́a). – Ejercicio: construya un árbol de demostración para ancestro(olga,X). • Una observación interesante es que Prolog siempre recorre el árbol de demostración en profundidad. Jorge Baier Aranda, PUC << Atrás 186 ¿Es un Programa Prolog un Programa en Lógica? • ¿Por que nos hacemos esta pregunta? • Serı́a ideal que Prolog el método de resolución de Prolog representara exactamente la noción de consecuencia lógica. • Es decir, si P es un programa, entonces P |= ϕ ssi P `p ϕ • Supongamos que en el ejemplo de la familia, preguntamos por padre(hugo,X) • Prolog responderá que NO. ¿Significa esto que del programa se deduce ¬∃X padre(hugo, X)? La respuesta es no, porque hay un modelo del programa en el cual dicha fórmula es satisfacible! Jorge Baier Aranda, PUC << Atrás 187 • De hecho, si P es un programa Prolog puro, entonces, nunca es posible que P |= ¬`, donde ` es un literal de primer orden. • Esto es una conclusión directa del siguiente teorema. Teorema 7. Un conjunto de cláusulas de Horn de primer orden es siempre consistente. Demostración: Basta con encontrar una interpretación con un dominio A en que las extensiones de todo predicado n-ario contiene exactamente a An. Tal interpretación es un modelo para el conjunto, porque todas las cláusulas tienen un literal positivo. • Cabe preguntarnos qué relación hay entre la lógica de primer orden y Prolog. • Si la correspondencia no es exacta, ¿podemos, al menos dar a Prolog una semántica precisa? Jorge Baier Aranda, PUC << Atrás 188 • A continuación veremos cómo hacer esto. Jorge Baier Aranda, PUC << Atrás 189 Significado Declarativo de una Respuesta de P ROLOG • Hasta el momento hemos visto que Prolog puede responder a preguntas con variables libres. • ¿Qué significa desde el punto de vista lógico que Prolog demuestre p(X,Y)? • Recordemos que en lógica de primer orden es posible tener un sinfin de interpretaciones distintas. • Para dar semántica a Prolog, utilizaremos una noción restringida de interpretación. • Estas interpretaciones tendran como universo a los universos de Herbrand. Jorge Baier Aranda, PUC << Atrás 190 Modelos de Herbrand • Un universo de Herbrand es una estructura que se origina de la sintaxis del lenguaje. • Veamos antes un par de definiciones. Definición 26. Un término instanciado (ground term) de un lenguaje de primer orden, es un término que no contiene variables. Definición 27. Un universo de Herbrand está formado por todos los términos instanciados del lenguaje. • Veamos un ejemplo Supongamos el programa: p(f(X)):- q(g(X)). p(f(X)):- p(X). p(a). q(a). Jorge Baier Aranda, PUC << Atrás 191 • En este programa tenemos los términos de función f y g y las constantes a y b. • El universo de Herbrand es: {a, b, f (a), g(a), f (b), g(b), f (f (a)), f (g(a)), g(f (a)), g(g(b)), . . .} • Desde el punto de vista intuitivo un universo de Herbrand es un universo mı́nimo pues no tiene elementos que no se pueden nombrar usando la sintaxis del lenguaje. • Si P es un programa construido sobre h{R1, . . . , Rn}, {f1, . . . , fn}, {C1, . . . , Cn}i, entonces los sı́mbolos S = H = hDH, {R1H, . . . , RnH}, {f1H, . . . , fnH}, {C1H, . . . , CnH}i, donde DH es el universo de Herbrand de P, es una estructura de Herbrand para ese lenguaje. • La interpretación de los términos del lenguaje da una correspondencia unı́voca entre los términos del lenguaje y los objetos del universo. Ası́, una interpretación Jorge Baier Aranda, PUC << Atrás 192 de Herbrand es tal que: I(Cn) = Cn I(fn(t1, . . . , tn)) = fn(I(t1), . . . , I(tn)) • La pregunta clave es qué es lo que se deduce de un programa en un universo de Herbrand. • No podemos deducir más que propiedades acerca de los objetos del universo. • Por ejemplo, si tenemos el programa P: numero(0). numero(s(X)) :- numero(X). suma(X,0,X). suma(X,s(Y),Z) :- suma(s(X),Y,Z). Los únicos hechos que podrı́amos llegar a deducir son: {numero(0), suma(0, 0, 0), numero(s(0)), suma(s(0), 0, 0), suma(s(0), s(0), 0), suma(s(0), s(0), s(0)), . . .} Jorge Baier Aranda, PUC << Atrás 193 • Esta secuencia de propiedades de objetos concretos es lo que se conoce como una base de Herbrand. • Formalmente, Definición 28. [Base de Herbrand] Sea P un programa en lógica construido sobre los sı́mbolos S = h{R1, . . . , Rn}, {f1, . . . , fn}, {C1, . . . , Cn}i B(P) = {Ri(t1, . . . , tn) | Ri es un sı́mbolo de predicado de aridad n y tj es un término instanciado (1 ≤ j ≤ n)} • Un Modelo de Herbrand mı́nimo para P, escrito por IH (P), es un subconjunto de B(P), pero que contiene exactamente los hechos que se deducen de un programa. Jorge Baier Aranda, PUC << Atrás 194 • En el programa ejemplo, un modelo mı́nimo de Herbrand es: {numero(0), numero(s(0)), numero(s(s(0))), . . . suma(0, 0, 0), numero(0, s(0), s(0)), numero(s(0), s(0), s(s(0))), . . .} • Formalmente, Definición 29. Un Modelo mı́nimo de Herbrand IH (P) para un programa en lógica P es un subconjunto de B(P) tal que si r ∈ IH (P) entonces existe una clausula ch : −c1, . . . , cn en P y una sustitucion θ tal que: – chθ ≡ r – ciθ ∈ IH (P) con 1 ≤ i ≤ n • Ahora si preguntamos a Prolog por una lista de objetivos GL, entonces GL es verdadero si existe una sustitución θ tal que para cada g ∈ GL, se cumple que gθ ∈ IH (P) Jorge Baier Aranda, PUC << Atrás 195 • Este es el que se conoce como significado declarativo de un programa Prolog. • También podemos decir que lo que Prolog hace, en el fondo, al demostrar un objetivo p(X,Y) es encontrar una demostración constructiva ∃X∃Y p(X, Y) • La demostración es constructiva porque Prolog encuentra valores para X e Y para los que p(X,Y) es consecuencia lógica del programa. • En el área de bases de datos deductivas es común tratar a las consultas que requieren valores como respuesta como consultas con variables libres. De esta manera la consulta ∃Rut alumno(N ombre, Rut, Dir) Se interpreta como una consulta en la que se pregunta por el N ombre y Dir de las tuplas de la tabla alumno. Jorge Baier Aranda, PUC << Atrás 196 Propiedades de la Resolución Prolog • ¿Es Prolog correcto? La resolución Prolog serı́a correcta si es que corresponde exactamente a la regla de primer orden. Lamentablemente, el mecanismo de resolución de Prolog no realiza occurs check .Esto hace que el intérprete no reconozca casos en los cuales no se puede realizar unificación: ?- X=f(X). X = f(f(f(f(f(f(f(f(f(f(...)))))))))) Nota: de hecho, algunos Prolog se ’caen’ con la consulta X=f(X),write(X). Para ver más claro el poblema, consideremos el siguiente programa: q :- p(X,X). p(X,Y) :- X=f(Y). La respuesta a la consulta q es, incorrectamente, Yes. Jorge Baier Aranda, PUC << Atrás 197 • Prolog tampoco es completo. • La fuente de incompleción de Prolog es: – La manera en que se recorre el árbol (en profundidad) de demostración hace que Prolog pueda caer en loops infinitos. Consideremos el siguiente programa: numero(s(X)) :- numero(X). numero(0). sin embargo, observen el comportamiento frente a la siguiente consulta. ?- numero(X). ERROR: Out of local stack Si cambiamos el programa original por: numero(0). numero(s(X)) :- numero(X). obtenemos ?- numero(X). X = 0 ; X = s(0) ; X = s(s(0)) ; X = s(s(s(0))) ; ... Jorge Baier Aranda, PUC << Atrás 198 En otras palabras, esto significa que el significado declarativo de Prolog es distinto al significado procedural de prolog.En ambos programas, el significado declarativo es el mismo, pero el intérprete no entrega las mismas respuestas. Jorge Baier Aranda, PUC << Atrás 199 Negación como Falla • Hasta ahora, nuestros programas Prolog son incapaces de representar la noción de negación. • Por ejemplo, supongamos que quisiéramos agregar la siguiente información como una regla: “Maria adora a los animales, excepto a las gatos” • Una forma natural de hacer esto en primer orden serı́a: ∀x (animal(x) ∧ ¬gato(x) → adora(M aria, x)) • En Prolog, usaramos la siguiente regla: adora(maria,X) :- animal(X), not gato(X). • En general, el intérprete de Prolog responde SI para un objetivo not G si es que no pudo demostrar G usando resolución a partir del programa. Jorge Baier Aranda, PUC << Atrás 200 Problemas con Negación como Falla • Es necesario ser extremadamente cuidadoso cuando se utiliza negación como falla. • En general, hay que evitar que hayan variables no unificadas en objetivos precedidos por not. • Supongamos el siguiente ejemplo: animal(piolin). animal(silvestre). animal(porky). pajaro(piolin). gato(silvestre). chancho(porky). adora(maria,X) :- animal(X), not(gato(X)). • ¿Qué respuestas da Prolog a la consulta adora(maria,X). • Exactamente las que esperábamos, X=piolin, X=porky. Jorge Baier Aranda, PUC << Atrás 201 • Cambiemos ahora la última regla por: adora(maria,X) :- not(gato(X)),animal(X). • ¿Qué obtenemos ahora como respuesta a adora(maria,X)? • Inesperadamente, la respuesta que da Prolog es NO. ¿Por qué? Jorge Baier Aranda, PUC << Atrás 202 Estructuras de Datos en Prolog • La semántica de modelos mı́nimos subyacente de Prolog, permite expresar en forma sencilla estructuras de datos que no se pueden modelar en primer orden. • Por ejemplo, más adelante veremos que no es posible construir un conjunto de axiomas tales que fuercen a tener modelos cuyo dominio sean los naturales. • En Prolog cosas como estas son muy sencillas de expresar. • De hecho, ya hemos visto algo de esto. Supongamos que utilizamos el predicado numero para identificar a los naturales. • Podemos considerar al primer número como 0, al sucesor de 0 como s(0), al sucesor de éste como s(s(0)). • Si bien los nombres que usamos para los números son distintos (no usamos 1, 2, 3, . . .), esta representación es suficiente. • El predicado numero se puede expresar fácilmente como: Jorge Baier Aranda, PUC << Atrás 203 numero(0). numero(s(X)) :- numero(X). • Supongamos ahora que queremos construir un predicado suma(X,Y,Z) que es verdadero cuando Z es la suma de X e Y en esta representación. • Una posibilidad es la siguiente: suma(0,X,X). suma(s(X),Y,Z):- suma(X,s(Y),Z). • Esto se basa en la siguiente propiedad de la suma: (x + 1) + y = x + (y + 1) • Un ejemplo de ejecución es el siguiente: ?- suma(s(s(0)),s(s(s(0))),X). X = s(s(s(s(s(0))))) ; No • Notable es el hecho que parámetros que podrı́amos haber pensado como entradas, también pueden ser parámetros de salida. Jorge Baier Aranda, PUC << Atrás 204 • Por ejemplo la consulta suma(s(s(0)),X,s(s(s(0)))) significa “¿qué número debo sumarle a 2 para que de 3?” puede ser respondida por Prolog usando la implementación que hemos visto: ?- suma(s(s(0)),X,s(s(s(0)))). X = s(0) ; No • Esto se debe a que la regla de alguna manera expresa “como funciona” la suma en los naturales. Prolog se limita simplemente a demostrar. • ¿Cómo podemos implementar la multiplicación? mult(0,X,0). mult(s(X),Y,Z) :- mult(X,Y,U),suma(U,Y,Z). • ¿En qué propiedad de la multiplicación está basada esta regla? • Podremos ahora usar a Prolog para resolver la ecuación: 3x + 1 = 7 Jorge Baier Aranda, PUC << Atrás 205 • La respuesta es sı́! Con la siguiente consulta: ?- suma(U,s(0),s(s(s(s(s(s(s(0)))))))),mult(X,s(s(s(0))),U). U = s(s(s(s(s(s(0)))))) X = s(s(0)) Yes • ¿Podrá encontrar las soluciones de x2 − 3x + 2 = 0? • Primer intento. Usando la consulta: mult(X,X,U),mult(s(s(s(0))),X,V),suma(Z,V,U),suma(Z,s(s(0)),0). Resultado: Prolog no responde. ¿Por qué ocurre esto? • Segundo intento: Usando la consulta mult(X,X,U),mult(s(s(s(0))),X,V),suma(U,s(s(0)),Z),suma(V,0,Z). Jorge Baier Aranda, PUC << Atrás 206 Resultado: X = s(0) U = s(0) V = s(s(s(0))) Z = s(s(s(0))) ; X = s(s(0)) U = s(s(s(s(0)))) V = s(s(s(s(s(s(0)))))) Z = s(s(s(s(s(s(0)))))) Funciona! • Como conclusión: Prolog no resuelve todo (esto es consecuencia de que es incompleto). • Para que encuentre las respuestas es necesario que el programador se preocupe de ordenar la búsqueda, que no es lo ideal. Jorge Baier Aranda, PUC << Atrás 207 Manejo de Listas • Es posible también manejar listas en Prolog. • La siguiente es una definición inductiva de lista. – La lista vacı́a nil, es una lista. – Si L es una lista, entonces a · L también es una lista. • De esta manera, la lista formada por los números 1,2 y 3 se ve bajo esta definición como 1 · 2 · 3 · nil y que en la representación gráfica usual se verı́a como: 1 ........... ...... 2 ........... ...... 3 . ..... ..... ..... .... . . . . .... ..... ..... ..... ..... . . . . .. ..... ..... • En Prolog, representaremos el constructor de listas · por el functor cons. Ası́: lista(nil). lista(cons(X,L)) :- lista(L). Jorge Baier Aranda, PUC << Atrás 208 Concatenación de Listas • La operación de concatenación de lista ◦ sirve para juntar dos listas en una sola. • La concatenación se puede definir inductivamente por: – nil ◦ L = L, con L lista. – (a · L1) ◦ L2 = a · (L1 ◦ L2), con L1 y L2 listas. • La implementación de esta definición es directa: conc(nil,L,L). conc(L,L2,Z) :- L=cons(X,L1),conc(L1,L2,U),Z=cons(X,U). • Esta última definición se puede reemplazar por: conc(nil,L,L). conc(cons(X,L1),L2,cons(X,U)) :- conc(L1,L2,U). • La siguiente es una muestra de ejecución: Jorge Baier Aranda, PUC << Atrás 209 ?- conc(cons(a,nil),cons(b,cons(c,nil)),L). L = cons(a, cons(b, cons(c, nil))) ; No • Nuevamente, podemos usar los parámetros como entrada salida, como en la siguiente consulta: ?- conc(X,Y,cons(1,cons(2,cons(3,nil)))). X = nil Y = cons(1, cons(2, cons(3, nil))) ; X = cons(1, nil) Y = cons(2, cons(3, nil)) ; X = cons(1, cons(2, nil)) Y = cons(3, nil) ; X = cons(1, cons(2, cons(3, nil))) Y = nil ; Jorge Baier Aranda, PUC << Atrás 210 No • Siguiendo estas mismas ideas es posible implementar otras estructuras de datos, como por ejemplo árboles o colas. Jorge Baier Aranda, PUC << Atrás 211 Otra Aplicación: Búsqueda y Cálculo de Situaciones • El cálculo de situaciones es una familia de lenguajes lógicos de primer orden más inducción. • Es una familia de lenguajes con tipos. • En las lógicas con tipos las variables pertenecen a un tipo especı́fico. • Este lenguaje ha sido usado en inteligencia artificial para modelar mundos dinámicos. • En el cálculo de situaciones se distinguen los siguientes elementos: – Situaciones. Hay una única situación inicial, S0. Todas las situaciones siguientes se obtienen como resultado de ejecutar alguna secuencia de acciones en S0. Si s es una situación, diremos que do(a, s) es la situación que resulta de ejecutar a en s. – Acciones. Son los elementos que sirven para cambiar de una situación a otra. Jorge Baier Aranda, PUC << Atrás 212 – Predicado especial P oss. P oss(a, s) es verdadero ssi la acción a es posible en la situación s. – Fluentes. Son predicados que sirven para representar las propiedades del mundo. Estos predicados tienen siempre un único argumento de situación. Por ejemplo, sobreElP iso(x, s) Puede significar que el objeto x se encuentra sobre el piso en la situación s. • Tal como en los lenguajes ordinarios de primer orden tenemos objetos del dominio y predicados sin términos de situación. • Éstos últimos se utilizan para especificar propiedades que no cambian al ejecutar acciones. Jorge Baier Aranda, PUC << Atrás 213 El mundo de Bloques • Modelaremos el mundo de bloques de la figura en el Cálculo de Situaciones y veremos qué tareas de razonamiento podemos realizar. C B A D M1 M2 M3 • En el mundo de bloques de la figura, existen tres mesas (M1, M2 y M3 y un conjunto de bloques. • Siempre es posible tomar un bloque libre (que no tiene bloques sobre él) y ubicarlo sobre otro bloque. • Las mesas M1, M2 y M3 no son manipulables. Jorge Baier Aranda, PUC << Atrás 214 • Llamaremos objeto tanto a mesas como bloques. • Para el modelo en el cálculo de situaciones usaremos los el siguiente fluente: – sobre(x, y, s): Verdadero ssi el bloque x está sobre el objeto y en la situación s. • Y la siguiente acción – mover(x, y): Mueve el objeto x sobre y. • La teorı́a consta de una serie de axiomas. • Axiomas para propiedades estáticas: manipulable(x) ↔ x = A ∨ x = B ∨ x = C ∨ x = D objeto(x) ↔ x = A ∨ x = B ∨ x = C ∨ x = D ∨ x = M1 ∨ x = M2 ∨ x = M3 Jorge Baier Aranda, PUC << Atrás 215 • Axiomas de precondición para acciones: P oss(mover(x, y), s) ↔¬x = y ∧ ¬∃zsobre(z, x, s)∧ ¬∃zsobre(z, y, s) ∧ manipulable(x) • Axiomas de efecto para el fluente sobre. Estos axiomas se usan para especificar cuando cambian las propiedades dinámicas del dominio. ∀axyzs (P oss(a, s) ∧ a = mover(x, y, s) ∧ sobre(x, z, s) → sobre(x, y, do(a, s))). ∀axyzs (P oss(a, s) ∧ a = mover(x, y, s) ∧ sobre(x, z, s) → ¬sobre(x, z, do(a, s))). • Estos axiomas no son suficientes para especificar completamente como cambia el fluente sobre(x, y, s) (¿por qué?) Para ello, escribimos el siguiente axioma de estado sucesor : Jorge Baier Aranda, PUC << Atrás 216 ∀as (P oss(a, s) → (sobre(x,y, do(a, s)) ↔ a = mover(x, y)∨ sobre(x, y, s) ∧ ¬∃ za = mover(y, z))) • Axiomas para determinar la situación inicial. ∀xy sobre(x, y, S0) ↔ (x = A ∧ y = M1∨ x = B ∧ y = A∨ x = C ∧ y = B∨ x = A ∧ y = M1 ∨ x = D ∧ y = M2 ) • Además es necesario agregar axiomas de nombres únicos para objetos del dominio. ¿por qué? Jorge Baier Aranda, PUC << Atrás 217 • Si agrupamos todos estos axiomas dentro de una teorı́a Σ, es sencillo verificar que: Σ |=sobre(C, D, do(mover(C, D), S0))∧ ¬∃x sobre(x, B, do(mover(C, D), S0)) Jorge Baier Aranda, PUC << Atrás 218 La especificación en Prolog • La traducción de esta teorı́a a un programa Prolog es directa. • El siguiente es el programa Prolog correspondiente: % Predicados estáticos manipulable(X) :- X=a; X=b; X=c; X=d. objeto(X) :- X=a; X=b; X=c; X=d; X=m1; X=m2;X=m3. % Axioma de precondicion poss(mover(X,Y),S) :manipulable(X), objeto(Y), \+ X=Y, \+ sobre(Z,X,S), \+ sobre(Z,Y,S). % Axioma de estado sucesor Jorge Baier Aranda, PUC << Atrás 219 sobre(X,Y,do(A,S)) :poss(A,S), sobre(X,Y,S), \+ A=mover(X,Z). sobre(X,Y,do(A,S)) :poss(A,S), A=mover(X,Y). % Descripción de la situación inicial sobre(a,m1,s0). sobre(b,a,s0). sobre(c,b,s0). sobre(d,m2,s0). % Situaciones legales legal(s0). legal(do(A,S)) :legal(S), Jorge Baier Aranda, PUC << Atrás 220 poss(A,S). • Ahora podemos hacer las siguientes consultas: ?- sobre(X,Y,do(mover(c,d),s0)). X = a Y = m1 ; X = b Y = a ; X = d Y = m2 ; X = c Y = d ; No Jorge Baier Aranda, PUC << Atrás 221 ?- legal(S),sobre(b,m1,S),sobre(a,b,S). S = do(mover(a, b), do(mover(b, m1), do(mover(a, m3), do(mover(b, c), do(mover(c, d), s0))))) ; S = do(mover(a, b), do(mover(b, m1), do(mover(a, c), do(mover(b, m3), do(mover(c, d), s0))))) ; S = do(mover(a, b), do(mover(b, m1), do(mover(a, d), do(mover(b, c), do(mover(c, m3), s0))))) • ¿Hay inteligencia detrás de esto? Jorge Baier Aranda, PUC << Atrás 222