1 Programación lógica - LDC

Anuncio
Universidad Simón Bolívar
Dpto. de Computación y Tecnología de la Información
CI2661 - Laboratorio de Lenguajes I
Enero-Abril 2009
Primer Proyecto:
Programación lógica en Haskell
1
Programación lógica
De…niciones preliminares. Asumimos inicialmente la existencia de cuatro
alfabetos distintos que forman el conjunto de símbolos no-lógicos:
–> Constantes: fa; b; c; :::g
–> Variables: fX; Y; Z; :::g
–> Funciones: ff; g; h; :::g
–> Predicados: fp; q; r; :::g
Además de un conjunto de símbolos lógicos:
–> Conectores: f:; ^; _; ); (; ,g:
–> Cuanti…cadores: f8; 9g:
Cada función y cada predicado tiene asociado un número …nito n de argumentos o n-aridad.
Presentamos una de…nición de la lógica de predicados usando el tipo árbol.
Un término es un árbol T que satisface las siguientes condiciones:
i) las hojas de T son variables o constantes,
ii) todo nodo no-terminal de T es un término de la forma f ( 1 ; :::; n )
y tiene los términos 1 ; :::; n como sus n sucesores inmediatos.
Si 1 ; :::; n son símbolos que designan términos y p es un predicado, entonces
la fórmula atómica p( 1 ; :::; n ) es un árbol y sus n sucesores son los subárboles
1 ; :::; n :
Una fórmula bien formada (o simplemente fórmula) es un árbol tal que:
1) las hojas son fórmulas atómicas,
2) un nodo no-terminal con una única fórmula sucesora es alguno entre
:
8X[ (X)]
9X[ (X)]
negación
cuanti…cación universal
cuanti…cación existencial
3) un nodo no-terminal con dos fórmulas sucesoresa
^ 2
1_ 2
1 ) 2
1 ( 2
1 ()
1
2
conjunción
disyunción
implicación
condicional
equivalencia
1
1
y
2,
es alguno entre
Figure 1:
La …gura muestra un ejemplo del árbol que representa la fórmula
9X[p(a; X; f (a; X)) ! : = (X; a)]
La forma normal de cláusulas es el sublenguaje del lenguaje de la lógica
de predicados en el cual se expresa la programación lógica convencional, y el
lenguaje PROLOG en particular.
Existe un algoritmo ([2] y [1]) que convierte cualquier fórmula en la forma
normal, usando un procedimiento de reducción semántica (llamado "escolemización" en honor al lógico noruego Th. A. Skolem) que permite eliminar todos
los cuanti…cadores existenciales: omitiendo la presencia de los cuanti…cadores
universales, la fórmula inicial es transformada en una conjunción de disyunciones
11
..
.
^
(t11 ) _ ::: _
n1
t1ii _ :
1i1
(tn1 ) _ ::: _
nin
1i1 +1
tnin _ :
t1ii +1 _ ::: _ :
nin +1
1t1
t1in +1 _ ::: _ :
t1 k 1
^
ntn
t n kn
donde tjr es una lista de términos para todo 1 j n y 1 r nkn .
Se escribe la expresión línea por línea, sin referencia explícita a las conjunciones, donde cada línea es un grupo disyuntivo aparte llamado cláusula
11
(t11 ) _ ::: _
1i1
n1
(tn1 ) _ ::: _
nin
..
.
t1ii _ :
1i1 +1
tnin _ :
2
t1i1 +1 _ ::: _ :
nin +1
1 k1
t1in +1 _ ::: _ :
t1 k1
nk n
t n kn
Luego, cada cláusula , por las leyes de implicación y de De Morgan, adquiere
la forma
j1
(tj1 ) _ ::: _
jij
tjij
(=
tjij +1 ^ ::: ^
jij +1
jkj
tjkj
para todo 1 j n.
Una cláusula de Horn es una cláusula donde a lo sumo una fórmula
atómica es positiva. Las cláusulas de Horn se clasi…can en:
1) Reglas; cuando una fórmula atómica es positiva y al menos una fórmula
atómica es negativa
j1
(tj1 ) (=
j2
(tj2 ) ^ ::: ^
tjkj
jkj
a j1 (tj1 ) se le llama cabeza y a la conjunción j2 (tj2 ) ^ ::: ^
cuerpo.
2) Hechos; fórmulas atómicas positivas j1 (tj1 ), sin cuerpo.
3) Metas, fórmulas atómicas negativas
:
j1
(tj1 ) _ ::: _ :
jkj
jkj
tjkj
tjkj
que se convierte en la expresión
f alse (
j1
(tj1 ) ^ ::: ^
jkj
tjkj
Una cláusula vacía no tiene fórmulas atómicas y por de…nición no satisface
ninguna interpretación, es siempre f alse.
Las reglas y los hechos, que son fórmulas atómicas positivas con o sin cuerpo,
son cláusulas de…nidas. Una fórmula lógica expresada como una conjunción
de cláusulas de…nidas se llama programa lógico. Una fórmula lógica expresada
como una cláusulas de Horn del tipo meta se llama pregunta.
El lenguaje (muy reducido) de los programas lógicos y las preguntas se genera
con una gramática en forma de Backus-Naur extendida del tipo:
P rolog ::=
AtomF orm ::=
ListaT erm ::=
T erm ::=
F un ::=
V ar ::=
Const ::=
T ail ::=
P reg ::=
fAtomF orm 0 (0 T ail 0 :0 j AtomF orm 0 :0 g
1
fa zg [0 (0 ListaT erm0 )0 ]
0
0 0
T erm f ; T ermg
Const j V ar j F un
1
fa zg 0 (0 ListaT erm 0 )0
1
fA Zg
1
1
0
fa zg j f1 9g f0 9g
0
AtomF orm f0 ;0 AtomF ormg
0
(0 T ail
0
El tipo de datos en Haskell para un programa lógico a partir de esta gramática
simpli…cada podría ser:
3
data
I Int
j B Bool
j F F loat
j Ch Char
j St String
data T erm = Const String
j V ar String
j F un String [T erm]
data Atom = (String; [T erm])
type T ail = [Atom]
data Def inite = F act Atom
j Rule Atom T ail
data P rogram = P rolog [Def inite]
Newtype Question = Q T ail
type Subs = [(T erm; T erm)]
2
V alue =
Regla de inferencia lógica SLD-Resolución
Una sustitución es un conjunto de remplazos de variables por términos en una
fórmula atómica
= fXi1
ti1 ; : : : ; X ik
tik g
donde X1 ; : : : ; Xn son las variables que ocurren en la fórmula. Nótese que
una sustitución no afecta necesariamente todas las variables de la fórmula. La
fórmula atómica ( ) que resulta de una sustitución se llama instancia de
la fórmula original .
Las sustituciones deben cumplir dos condiciones:
1) Funcionalidad: Xiu 6= Xiv para todo 1 u; v k con u 6= v.
2) Idempotencia: ( ( )) = ( ).
Dada la fórmula y las sustituciones
1
2
= fXi1
= fYi1
t i1 ; : : : ; X ik
si1 ; : : : ; Yim
t ik g
sim g
se de…ne su composición como la sustitución
2
1
=f
2
(Xi1
ti1 ) ; : : : ;
2
(Xik
tik )g[ Yij
sij j Yij 2
= fXi1 ; : : : ; Xik g
que se interpreta de la siguiente manera: la aplicación de 1 a introduce,
eventualmente, nuevas variables que provienen de los términos ti1 ; : : : ; tik , luego,
la aplicación de 2 a 1 ( ) debe darse tanto en las nuevas variables como en
aquellas otras que no afecta la primera sustitución.
Un uni…cador para las fórmulas 1 y 2 es una sustitución , de…nida sobre
la unión de las variables de ambas, tal que
(
1)
=
4
(
2)
Un uni…cador se dice general cuando, para cualquier uni…cador
una sustitución tal que
=
existe
Un uni…cador general es la mínima sustitución que iguala las instancias de ambas
fórmulas y permite, eventualmente, otras sustituciones posteriores que remplacen las variables restantes.
La regla de inferencia SLD-resolución usa como premisas una pregunta y
una regla del programa lógico: Se instancian ambas fórmulas (la pregunta y la
regla) con el uni…cador general de la primera fórmula atómica de la pregunta y
la cabeza de la regla, que por supuesto, deben compartir el mismo predicado y
tener la misma aridad.
Formalmente, sean la pregunta (llamada en este contexto padre central)
:'1 t11 ; ; t1k1 _ :'2 t21 ; ; t2k2 _
_ :'m tm1 ; ; tmkm
y el programa lógico cuya primera cláusula de…nida (de allí la D, por def inida)
en el orden secuencial de las cláusulas (llamada en este contexto padre lateral)
es,
^ n sn1 ; ; snjn
1 s11 ; ; s1j1 ( 2 s21 ; ; s2j2 ^
cumpliendo las condiciones;
i) el predicado de la primera fórmula atómica de la pregunta (de allí la S,
por selectiva) es el mismo predicado de la cabeza de la cláusula de…nida, es
decir, '1 = 1 , y
ii) la aridad del predicado '1 es la misma que la del predicado 1 es decir,
k1 = j1 ,
Se construye entonces la conclusión, llamada resolvente, como otra pregunta
:
2
s21 ; ; s2j2 _
_:
n
sn1 ; ; snjn _:'2 t21 ; ; t2k2 _
_:'m tm1 ; ; tmkm
que, de nuevo, será sometida al programa (de allí la L ; por lineal).
Si se busca una respuesta a…rmativa cuando se somete la pregunta ' al
programa , el proceso sistemático del empleo de la regla SLD-resolución debe
culminar con una última un…cación cuyo resolvente es la meta cláusula vacía
f alse (recuérdese que f alse es el elementro neutro del conector lógico binario
_), es decir, el sistema de inferencia despliega una prueba por contradicción, por
ello tiene éxito cuando se concluye f alse. Si ninguna instancia de la pregunta
' puede ser derivada lógicamente de , por medio de SLD-resolución, entonces
se produce la respuesta N o. En el lenguaje de la teoría de pruebas esto es
^ :' 0 f alse
3
Algoritmo de Robinson
Dadas dos fórmulas atómicas:
1
(t1 ; : : : ; tn ) y
5
2
(s1 ; : : : ; sm )
donde t1 ; : : : ; tn ; s1 ; : : : ; sm son términos (i.e. constantes, variables o funciones),
el algoritmo de Robinson permite saber si ambas fórmulas atómicas son uni…cables, en cuyo caso devuelve el uni…cador general. En caso contrario, devuelve
un mensaje de error razonando la falla. El algoritmo se implementa con dos
pilas; la primera, , para guardar los pares de términos (ti ; si ) según aparecen,
componente a componente, en las tuplas que forman los argumentos de los predicados comparados, es decir, (t1 ; s1 ) en el tope de la pila y (tn ; sn ) en el fondo;
la segunda, ; para guardar las sutituciones sucesivas cuya composición constituye el uni…cador general, una entrada por variable a remplazar. Obviamente,
el algoritmo falla si 1 6= 2 o n 6= m.
Para facilitar la comprensión del algoritmo, categorizamos el álgebra de los
términos T en tres clases; C para las constantes, V para las variables, F para
las funciones. A continuación describimos informalmente el algoritmo:
.
Algoritmo de Robinson
(in ( 1 (t1 ; : : : ; tn ) ; 2 (s1 ; : : : ; sm )) / out :: fV
T g)
if 1 6= 2 then mensaje de error
else if n 6= m then mensaje de error
else while 6= ? do
pop (ti ; si )
(t; s)
instancia (ti ; si )
if (t; s) 2 C C ^ t 6= s
else if (t; s) = (f (: : :) ; g (: : :)) 2 F F ^ f 6= g
else if (t; s) = (f (: : :) ; s) 2 F C_
(t; s) = (t; g (: : :)) 2 C F
else if (t; s) = f u1 ; : : : ; unf ; g v1 ; : : : ; vng 2 F
^f = g ^ nf = ng
else if (t; s) 2 V V
else if (t; s) = (t; g (: : :)) 2 V F ^
occurs-check (t; s) = true
else if (t; s) = (f (: : :) ; s) 2 F V
occurs-check (t; s) = true
else if (t; s) 2 V C [ V F
else if (t; s) 2 C V [ F V
end while
idemp ( )
F
then
then
then
mensaje de error
mensaje de error
mensaje de error
then
then
then
push (u1 ; v1 ) ;
: : : ; push unf ; vng
push (t
s)
mensaje de error
then
mensaje de error
then
then
push (t
push (s
.
El algoritmo llama a tres procedimientos;
1) instancia (ti ; si ) es la función que aplica al par (ti ; si ), en cada ciclo, las
sustituciones que se van acumulando en y devuelve el par actualizado (t; s).
2) occurs-check (t; s) es la función booleana que busca dentro del término t
la ocurrencia de la variable s, o viceversa.
3) idemp ( ) garantiza que sea idempotente calculando el mínimo n para
6
s)
t)
el cual
n
n
por lo cual
4
=
n+1
será el único uni…cador general.
Backtracking
Todas las cláusulas de…nidas que comparten el predicado de la fórmula atómica
positiva constituyen una de…nición (o procedimiento). La regla de inferencia
SLD-resolución busca las soluciones (i.e. la uni…cación general) que se derivan
de la uni…cación de la primera fórmula atómica con la primera cláusula de…nida
en la de…nición que se corresponde con el predicado. El proceso de uni…car
secuencialmente todas las cláusulas de una de…nición se llama backtracking.
Posiblemente, algunas de las cláusulas produzcan soluciones positivas (uni…caciones generales) y otras no lo hagan. La estructura que describe este proceso
de búsqueda de soluciones se llama SLD-árbol.
5
Ejemplo
En Prolog, como en Haskell, la estrutura de datos básica es la lista, y se entiende
como una función algebraica
dispar ([]; list) :
dispar ([]; list) ( ) =
dispar ([]; list) (head; tail) =
1 j a (Lista a) ! Lista a
[]
list (head; tail)
Sea el programa lógico
c1:
c2:
append ([]; X; X) :
append (list (A; X) ; Y; list (A; Z)) ( append (X; Y; Z) :
y la pregunta
?append (list (Head; T ail1) ; T ail2; list (Head; list (a; [])))
El sistema de inferencia SLD-resolución trata primero de resolver la pregunta con la cláusula c1 pero fracasa porque no puede uni…car el par de términos
([]; list (H; T 1)). Intenta luego uni…car las fórmulas atómicas
append (list (Head; T ail1) ; T ail2; list (Head; list (a; [])))
append (list (A; X) ; Y; list (A; Z))
devolviendo el uni…cador general
1
= fA
Head; X
T ail1; Y
T ail2; Z
El proceso de la inferencia lógica es el siguiente:
7
list (a; [])g
padre central: :append (list (Head; T ail1) ; T ail2; list (Head; list (a; [])))
padre lateral: append (list (Head; T ail1) ; T ail2; list (Head; list (a; []))) _ :append (T ail1; T ail2; list (a;
resolvente:
:append (T ail1; T ail2; list (a; []))
con lo cual el sistema debe ahora resolver la pregunta
?append (T ail1; T ail2; list (a; [])) :
uni…cando las fórmulas atómicas
append (T ail1; T ail2; list (a; []))
append ([]; X; X)
con el uni…cador general
2
= fT ail1
[]; T ail2
list (a; [])g
en el proceso de refutación
padre central: :append ([]; list (a; []) ; list (a; []))
padre lateral: append ([]; list (a; []) ; list (a; []))
resolvente:
f alse
Si se aplica backtracking, el sistema busca otra solución a partir de la última
elección de padre lateral, es decir, intentará uni…car ahora las fórmulas atómicas
append (T ail1; T ail2; list (a; []))
append (list (A; X) ; Y; list (A; Z))
consiguiendo el uni…cador general
3
= fT ail1
list (A; X) ; Y
T ail2; A
a; Z
[]g
en el proceso de inferencia
padre central: :append (list (a; X) ; T ail2; list (a; []))
padre lateral: append (list (a; X) ; T ail2; list (a; [])) _ :append (X; T ail2; [])
resolvente:
:append (X; T ail2; [])
Finalmente, la pregunta
?append (X; T ail2; [])
con el uni…cador general
4
= fX
[]; T ail2
se resuelve en el proceso de refutación
padre central: :append ([]; []; [])
padre lateral: append ([]; []; [])
resolvente:
f alse
Las soluciones a la consulta son, primero
Head =?
8
[]g
T ail1 = []
T ail2 = list (a; [])
Luego del backtracking,
Head =?
T ail1 = list (a; [])
T ail2 = []
Todo el proceso de inferencia se suele representar en el SLD-árbol
:append (list (Head; T ail1) ; T ail2; list (Head; list (a; [])))
1 =fA
2 =fT ail1
[];T ail2
Head;X
T ail1;Y
T ail2;Z
list(a;[])g
#
:append (T ail1; T ail2; list (a; []))
list(a;[])g
#
f alse
3 =fT ail1
list(A;X);Y
T ail2;A
a;Z
[]g
#
:append (X; T ail2; [])
4 =fX
[];T ail2
[]g
#
f alse
Observación: Para evitar la repetición en los nombres de las variables entre
el padre central y el padre lateral, el interpretador debe renombrar las variables
de la cláusula del programa lógico con nombres de variables que se sepa no estan
en uso.
En la estructura de tipos de datos sugerida antes, tanto el programa lógico
como la pregunta se expresan así:
app :: Program
app =
Prolog [ Fact ("append",[Fun "list" [ ], Var "X", Var "X"]),
Rule ("append",[Fun "list" [Var "A",Var "X"], Var "Y", Fun "list" [Var "A",Var "
[("append",[Var"X",Var"Y",Var"Z"])]
]
y
query :: Question
query =
Q [ ("append", [Fun "list" [Var "H",Var "T1"],
Var "T2",
Fun "list" [Var "H",Fun "list" [Const (Ch ’a’),Fun "list" [ ]]
]
)
]
]
9
6
Enunciado del proyecto
Se debe programar en haskell las siguientes funciones
substitucion
robinson
resolucion
backtracking
:
:
:
:
: Atom ! Subs ! Atom
: Atom ! Atom ! Subs
: P rogram ! Question ! Subs
: P rogram ! Question ! [Subs]
donde Subs es el tipo de datos que implementa los uni…cadores generales
type
Subs =
[(T erm; T erm)]
Su programa deben manejar correctamente los mensajes de error cuando
no sea posible uni…car dos fórmulas atómicas, o cuando SLD-resolución
no pueda llegar a la cláusula vacía.
Su programa debe incorporar funciones de pretty-print para presentar las
fórmulas, los términos, las sustituciones y todas las soluciones del backtracking de manera legible.
Documentación a entregar:
El módulo P rologs:hs conteniendo el código fuente Haskell que implementa las funciones que se piden, correctamente documentado utilizando
la herramienta Haddock.
Un M akef ile que permita compilar el programa y generar la documentación.
El programa principal será compilado y utilizado desde la línea de comandos.
Fecha de Entrega. Viernes 20 de Febrero de 2009 (Semana 6).
Valor de Evaluación. Treinta (30) puntos.
References
[1] Lloyd, J. W. (1984)
Foundations of Logic Programming
Springer-Verlag
[2] Hogger, C. J. (1990)
Essentials of Logic Programming
Oxford University Press
10
Descargar