Está en la página 1de 113

Principios de Programación Lógica

Ingeniería Informática

Departamento de Lenguajes y
Ciencias de la Computación
Universidad de Málaga
Contenido

1) Objetos, Relaciones y Objetivos


2) Datos: Objetos y Términos
3) Procedimientos: Hechos y Reglas
4) Programa Principal: Objetivos
5) Semántica Operacional de Prolog
6) Prolog = Programación Lógica

Principios de Programación Lógica 2


Objetos, Relaciones y Objetivos
Programas lógicos y cómputos

Programa lógico (o relacional): conjunto de relaciones entre


objetos

Cómputo: deducción controlada y constructiva de que un objetivo


O es consecuencia lógica de las relaciones definidas en un
programa lógico P

P  O

Principios de Programación Lógica 4


Objetos, relaciones y objetivos
Objetos:
se corresponden con los datos
se representan mediante términos

Relaciones:
se corresponden con los procedimientos
se definen mediante hechos y reglas

Objetivos:
se corresponden con el programa principal
se definen mediante consultas

Principios de Programación Lógica 5


¿Cómo se escribe un programa lógico?
Para escribir un programa lógico debemos identificar:
qué objetos intervienen en el problema,
cuáles son las relaciones entre éstos, y
qué objetivos queremos alcanzar
Una vez identificados los elementos anteriores debemos:

representar los objetos mediante términos


definir las relaciones mediante hechos y reglas
definir los objetivos mediante consultas

Ilustraremos la metodología anterior mediante un ejemplo


Problema: escribir un programa lógico que defina relaciones de
parentesco y deduzca qué personas están emparentadas
Principios de Programación Lógica 6
La familia a considerar

Antonio María

Elena Carlos Eva David

Fernando Silvia Emilio

Principios de Programación Lógica 7


Identificando objetos y relaciones

objetos

Antonio María
relaciones

Elena Carlos Eva David

Fernando Silvia Emilio

Principios de Programación Lógica 8


Representando objetos mediante términos

Objetos:

son las personas que forman la familia

representados por términos (sus nombres en minúscula)

Ejemplos:
Antonio  antonio
María  maría

Principios de Programación Lógica 9


Definiendo relaciones mediante hechos

Relaciones:

son las relaciones de paternidad y maternidad

definidas mediante hechos (relaciones incondicionales)

Ejemplos:

Antonio es padre de Carlos  padre(antonio,carlos).


María es madre de Carlos  madre(maría,carlos).

Principios de Programación Lógica 10


La familia completa definida en Prolog

padre(antonio,carlos).
padre(antonio,eva).
padre(carlos,fernando).
padre(carlos,silvia).
padre(david,emilio).

madre(maría,carlos).
madre(maría,eva).
madre(elena,fernando).
madre(elena,silvia).
madre(eva,emilio).

Principios de Programación Lógica 11


Deduciendo objetivos
Objetivos:

son preguntas sobre el parentesco

definidas mediante consultas

Ejemplos:

¿es David padre de Emilio?  :- padre(david,emilio).


¿quiénes son los hijos de Eva?  :- madre(eva,X).
¿quién es el padre de Silvia?  :- padre(P,silvia).

Principios de Programación Lógica 12


Identificando relaciones implícitas

abuelo
Antonio María

Elena Carlos Eva David

Fernando Silvia Emilio

hermanos primos

Principios de Programación Lógica 13


Una mala idea...
Definimos las relaciones extra mediante hechos:
hermanos(carlos,eva).
hermanos(fernando,silvia).

Inconvenientes:

tamaño excesivo
propenso a errores
mantenimiento (nacimientos, etc.)
adaptabilidad a otras situaciones (familias)

Sería preferible definir esta relación de forma genérica,


identificando las condiciones bajo las cuales dos personas “A” y
“B” son hermanos

Principios de Programación Lógica 14


Definiendo relaciones mediante reglas
¿Cómo podemos definir la relación “hermanos”?

“A y B son hermanos si comparten los padres”

Definiremos la relación condicional anterior mediante la regla:

hermanos(A,B) :-
padre(P,A),
madre(M,A),
padre(P,B),
madre(M,B),
A \== B.

Principios de Programación Lógica 15


Ejercicios
Define las siguientes relaciones de parentesco:

1. abuelo(A,B) – A es abuelo de B
2. tio(A,B) – A es tío de B
3. primos(A,B) – A y B son primos
4. procrearon(A,B) – A y B tienen algún hijo en común

Principios de Programación Lógica 16


Reglas para identificar objetos y relaciones

Objetos: nombres propios y comunes, en singular o plural

Relaciones: verbos y formas verbales

A veces es posible más de una formalización, y la diferencia entre


objeto y relación no está clara...

Una relación determina un conjunto de objetos: aquéllos que la


satisfacen. Por tanto, una relación puede emplearse para
referirnos a estos objetos.

Ejemplo: “Los hijos de Antonio”  padre(antonio,H)

Principios de Programación Lógica 17


Datos: Objetos y Términos
Datos: objetos y términos
Los objetos (datos) se representan mediante términos:

átomo
constante entero
número
real
término variable

estructura

Los términos son adecuados para el procesamiento simbólico

Principios de Programación Lógica 19


Átomos
Uso: representan objetos concretos mediante un nombre; es
decir, denominan a un objeto en particular

Sintaxis:

secuencias de letras, dígitos y _ comenzando por minúscula


ejemplos: antonio, x, lista_vacía, nil, x25

secuencias de caracteres entre apóstrofos


ejemplos: ‘antonio garcía’, ‘Antonio’

secuencias de símbolos especiales


ejemplos: +, -, =, ===, ::=, :=, <->, :^:

Principios de Programación Lógica 20


Números
Uso: representan números enteros y reales

Sintaxis:

enteros: 2, 34, -56

reales: -0.0092, 4.5e-5

Se aplican las restricciones típicas de rango (enteros y reales) y


precisión (reales)

Principios de Programación Lógica 21


Variables
Uso: representan objetos por determinar. Las variables son
semejantes a incógnitas: no se les puede asignar valores a
voluntad.

Sintaxis:

Secuencia de letras, dígitos y _ comenzando por mayúscula o _

Ejemplos:
X1
Padre
_X
Num_Telef
ListaClientes

Principios de Programación Lógica 22


Estructuras (I)
Uso: representan objetos compuestos que pueden ser concretos
(no contienen variables) o por determinar (contienen variables)

Sintaxis:
sin espacios
átomo(término1,...,términon)

nombre aridad

Al par nombre/aridad se le denomina functor de la estructura


Ejemplos:
fecha(17,agosto,2004) % fecha/3
cita(miguel,fecha(Día,enero,2006)) % cita/2

Principios de Programación Lógica 23


Estructuras (II)

Los functores no se declaran.

Puede emplearse el mismo nombre con diferentes aridades: se


trata de functores distintos

Ejemplo:
fecha(17,agosto,2004) % fecha/3
fecha(14,abril) % fecha/2

Principios de Programación Lógica 24


Sintaxis (simplificada) de los términos

término ::= átomo


| número
| variable
| estructura

estructura ::= átomo(argumentos)

argumentos ::= término


| término , argumentos

Más adelante extenderemos esta sintaxis con operadores y


listas
Principios de Programación Lógica 25
Prolog comprueba la sintaxis de los términos...

Prolog detecta y señala los siguientes errores sintácticos

2pi
fecha(12,,2001)
fecha()
cita(fernando,fecha(2,diciembre,2001)
lista (a,b,c)
F(X,Y)

Principios de Programación Lógica 26


Pero la intención es lo que cuenta...
La intención es representar las fechas por términos de la forma:
fecha(día,mes,año)

donde día ∈ {1,...,31}


mes ∈ {enero,...,diciembre}
año ∈ {2000,...}

Pero Prolog no puede detectar usos inadecuados:


fecha(enro,2,2001)
La sintaxis es correcta, pero el orden de los argumentos no es el
esperado y enro no es un mes válido
Prolog no conoce las intenciones del programador: no hay
declaraciones de tipo

Principios de Programación Lógica 27


Representación física vs. sintáctica

punteros términos
arrays
objeto a constantes
registros
representar
functores
... ...

programador imperativo programador lógico

Principios de Programación Lógica 28


¿Cómo se representa un objeto en Prolog?
El programador lógico debe decidir una sintaxis adecuada para
cada tipo de dato:

Constantes:
qué nombre o número resulta apropiado

Variables:
se emplean para objetos por determinar (plantillas)

Estructuras:
functor
orden y sintaxis de los argumentos, recursión.

Sin embargo, no hay forma de comunicar a Prolog esta intención:


no hay declaraciones de tipo

Principios de Programación Lógica 29


Ejemplo: representación de pilas (I)

Para representar el TAD pila, el programador debe elegir una


sintaxis adecuada

Sintaxis:

tad_pila ::= pila_vacía


| pila(cima,tad_pila)

cima::= término

Pero no es posible comunicar a Prolog esta sintaxis...

Principios de Programación Lógica 30


Ejemplo: representación de pilas (II)

Ejemplos de pilas bien formadas:


pila(a,pila(b,pila(c,pila_vacía)))

pila(a,pila(fecha(2,enero,2001),pila_vacía))

pila(pila_vacía,pila_vacía)

Ejemplos de términos Prolog que no son pilas bien formadas:

pila(pila_vacía)

pila(a,pila(b))

Principios de Programación Lógica 31


Ejemplo: representación de pilas (III)
Las estructuras que contienen variables son plantillas:

Ejemplos:
pilas con 2 elementos y a en la cima
pila(a,pila(X,pila_vacía))

pilas de 3 elementos cualesquiera


pila(X,pila(Y,pila(Z,pila_vacía)))

pilas de al menos un elemento


pila(X,Y)

pilas que tienen una b como segundo elemento


pila(X,pila(b,Y))

Las dos últimas plantillas suponen que Y es una pila


Principios de Programación Lógica 32
Ejemplo: circuitos digitales (I)

x
y

Objetos:
variables de entrada (a,b,c,...,x,y,z)
puertas lógicas (or, and, nand, not)

Principios de Programación Lógica 33


Ejemplo: circuitos digitales (II)
Representación:
entradas -> átomos
puertas -> estructuras or/2,and/2,nand/2,not/1

Sintaxis:
circuito::= entrada
| or(circuito, circuito)
| and(circuito, circuito)
| nand(circuito, circuito)
| not(circuito)

entrada ::= átomo

Principios de Programación Lógica 34


Ejemplo: circuitos digitales (III)
El circuito digital:

x
y

se representa por el término:

or(and(x,y),z)

Principios de Programación Lógica 35


Representando términos mediante árboles
Un término Prolog puede representarse como un árbol:

constantes y variables  hojas


estructuras n-arias  nodos n-arios

Ejemplo: cita(silvia,fecha(Día,diciembre,2005))

cita

silvia fecha

Día diciembre 2004

Principios de Programación Lógica 36


Procedimientos: Hechos y Reglas
Procedimientos: relaciones entre objetos (I)

Los procedimientos en programación lógica se denominan


relaciones o predicados

Cada procedimiento tiene un functor (nombre/aridad) que lo


identifica de manera unívoca

“X es padre de Y”  padre(X,Y)  padre/2


“la pila P es vacía”  es_vacía(P) es_vacía/1

Principios de Programación Lógica 38


Procedimientos: relaciones entre objetos (II)
Los procedimientos pueden satisfacerse o fracasar

padre(antonio,eva) éxito
padre(eva,eva)  fracaso

Los procedimientos no son funciones: no devuelven valores

padre(antonio,padre(carlos,silvia)) error

lo anterior no expresa que antonio es abuelo de silvia.


Las llamadas anidadas no se ejecutan: son argumentos (datos)

Los procedimientos se definen mediante un conjunto de hechos


y reglas

Principios de Programación Lógica 39


Definiendo hechos
Uso: definen relaciones incondicionales

Sintaxis:
sin espacios
átomo.
átomo(término1,...,términon).

Ejemplos:
padre(antonio,eva). % padre/2
es_vacía(pila_vacía). % es_vacía/1
es_par(8). % es_par/1
no_es_vacía(pila(Cima,Resto)).% no_es_vacía/1

Principios de Programación Lógica 40


Definiendo reglas (I)
Uso: definen relaciones condicionales

Sintaxis:
cabeza (conclusión)

átomo(término1,...,términop) :-
átomo1(término11,...,término1n),
..., cuerpo
átomok(términok1,...,términokm). (condiciones)

La conclusión es cierta si se satisfacen todas las condiciones

Principios de Programación Lógica 41


Definiendo reglas (II)
“Los caballeros rescatan a las princesas secuestradas por
dragones”

procedimiento rescata/2:

rescata(C,P) :-
es_caballero(C),
es_princesa(P),
es_dragon(D),
secuestrada(P,D).

Principios de Programación Lógica 42


Un procedimiento puede tener alternativas
“P es un pato si tiene plumas y hace cuac, o si es sobrino de un
pato”

misma variable
procedimiento es_pato/1:

es_pato(P) :- tiene_plumas(P),
hace_cuac(P).

es_pato(P) :- es_pato(T),
sobrino(P,T).
variables distintas

Las variables son locales a las reglas, no a los procedimientos

Principios de Programación Lógica 43


Los procedimientos pueden ser recursivos
“X es progenitor de Y si es su padre o su madre”

procedimiento progenitor/2:

progenitor(X,Y) :- padre(X,Y).
progenitor(X,Y) :- madre(X,Y).

“X es antepasado de Y si es su progenitor o progenitor de uno de


sus antepasados”

procedimiento antepasado/2:

antepasado(X,Y) :- progenitor(X,Y).
antepasado(X,Y) :- progenitor(X,Z),
antepasado(Z,Y).
Principios de Programación Lógica 44
Programa Principal: Objetivos
Programa principal: objetivos

Uso: interrogan al programa lógico para determinar si se


satisfacen ciertas relaciones

Sintaxis:
:- átomo1(término11,...,término1n),
...,
átomok(términok1,...,términokm).

Los objetivos pueden o no tener variables.

Principios de Programación Lógica 46


Objetivos sin variables
Uso: cuestionan si ciertos objetos concretos satisfacen ciertas
relaciones. La respuesta debe ser sí (éxito) o no (fracaso).

Ejemplos:
¿es Antonio padre de Carlos?

:- padre(antonio,carlos).

¿es María antepasado de Silvia?

:- antepasado(maría,silvia).

¿son Antonio y María antepasados de Silvia?

:- antepasado(maría,silvia),
antepasado(antonio,silvia).

Principios de Programación Lógica 47


Objetivos con variables
Uso: cuestionan qué objetos satisfacen ciertas relaciones. El
objetivo se puede interpretar como una ecuación y sus variables
como incógnitas a determinar

Ejemplos:
¿quién es el padre de Silvia?

:- padre(X,silvia).

¿quiénes son los descendientes de María?

:-antepasado(maría,X).

¿quiénes son hermanos?

:- hermanos(X,Y).
Principios de Programación Lógica 48
Semántica Operacional de Prolog
¿Cómo se ejecuta un Programa Prolog?

objetos
relaciones
objetivos
objetivos
Programa
(Hechos y Reglas)
respuestas

Motor de
¿qué es y cómo funciona?...
Inferencia

Principios de Programación Lógica 50


¿Qué es el motor de inferencia?
Básicamente es un mecanismo de invocación de procedimientos

:- hermanos(silvia,X).

objetivo = invocación
hermanos(A,B) :-
padre(P,A),
madre(M,A),
padre(P,B), regla = procedimiento
madre(M,B),
A \== B.

Principios de Programación Lógica 51


Paso de parámetros por unificación

La unificación de términos es el mecanismo empleado por el


motor de inferencia para el paso de parámetros a
procedimientos

Al invocar un procedimiento, hay que unificar los parámetros


actuales y los formales

Dos términos (parámetros) unifican si:


1) son idénticos
2) pueden reemplazarse algunas de sus variables por
términos, de manera que los términos resultantes son
idénticos

Principios de Programación Lógica 52


Unificación de términos (I)
Ejemplo:
unifican tomando:
fecha(Día,Mes,2006)
Día=Ayer
fecha(Ayer,mayo,Año) Mes=mayo
Año=2006

Las variables Mes y Año quedan ligadas o instanciadas a sus


respectivos valores (mayo y 2006)

Las variables Día y Ayer quedan libres (su valor está por
determinar, aunque se sabe que ambas se refieren al mismo valor)

La unificación es la única forma en que se puede instanciar una


variable Prolog (puede recibir un valor)

Principios de Programación Lógica 53


Unificación de términos (II)
Ejemplo:
unifican tomando:
fecha(Día,Mes,2006)
Día=12
fecha(Ayer,mayo,Año) Ayer=12
Mes=mayo
Año=2006
La unificación puede no ser única (Prolog usa la más general: no
hay necesidad de determinar Día ni Ayer)

Puede ser imposible unificar dos términos

Ejemplo: fecha(Día,Mes,2006)
no unifican
fecha(Ayer,mayo,06)

Principios de Programación Lógica 54


Unificación mediante árboles
A veces resulta conveniente representar los términos como árboles

cita cita

silvia fecha Persona fecha

Dia Mes 2006 12 enero 2006

Principios de Programación Lógica 55


Reglas de unificación (informal)
Se pueden aplicar las siguientes reglas para unificar:

1) una variable unifica con cualquier término


2) una constante sólo unifica consigo misma
3) un estructura unifica con otra estructura si:
a) tienen el mismo functor (nombre/aridad)
b) sus respectivos argumentos unifican
c) las sustituciones son compatibles

Sin embargo, lo anterior no es un algoritmo formal...

A continuación formalizaremos las definiciones y presentaremos


un algoritmo de unificación
Principios de Programación Lógica 56
Ligaduras y sustituciones

Una ligadura es un par V/t donde V es una variable y t es un


término distinto de V. Se dice que la variable V queda ligada o
instanciada al término t

Ejemplo: Padre/antonio, X/pila(a,Resto)

Una sustitución es un conjunto finito de ligaduras {Vi/ti}


donde todas las variables ligadas son distintas entre sí; es decir,
i ≠ j ⇒ Vi ≠ Vj

Ejemplo: {Padre/antonio, X/pila(a,Resto)}

Principios de Programación Lógica 57


Aplicación de sustituciones e instancia
Al aplicar una sustitución θ a un término A, todas las variables
ligadas por θ deben reemplazarse en A simultáneamente

Ejemplo: A = p(X,f(Y),a) θ = {X/b, Y/X}

θ = p(X,f(Y),a){X/b, Y/X} = p(b,f(X),a)


θ; es decir,
Un término B es instancia de un término A si B = Aθ
B se obtiene aplicando una sustitución θ a A

En general, una instancia es un caso particular de un término en


que se han determinado (ligado) algunas de sus variables

Principios de Programación Lógica 58


Renombrado de un término (I)

Una sustitución θ se dice que es un renombrado de un término A


si
(i ≠ j ⇒ ti ≠ tj) (1)

∀ Vi/ti ∈ θ ⇒ ti variable ∧
((ti= Vj) ∨ (2)
ti no aparece en A) (3)

Es decir, se reemplazan variables por variables distintas entre sí


(1), de manera que las variables introducidas aparecen entre las
variables a sustituir (2), o no aparecen en el término A (3)

Principios de Programación Lógica 59


Renombrado de un término (II)
Básicamente, un renombrado consiste en cambiar los nombres de
las variables sin modificar la generalidad del término

Ejemplo: A = p(X,f(Y),a) θ = {X/Z, Y/X}


A θ = p(Z,f(X),a)

Los siguientes no son renombrados:


1) A = p(X,f(Y),a) θ = {X/Z, Y/Z}
A θ = p(Z,f(Z),a)

2) A = p(X,f(Y),a) θ = {X/Y}
A θ = p(Y,f(Y),a)

Principios de Programación Lógica 60


Composición de sustituciones (I)

Dadas dos sustituciones θ y τ


θ = {V1/t1, V2/t2,...,Vn/tn}
τ = {U1/s1, U2/s2,...,Um/sm}

su composición es una sustitución θτ tal que

(Aθ)τ (θτ) ∀ A
θ)τ = A(θτ
(θτ)

Básicamente, se trata de reemplazar una secuencia de


sustituciones (primero θ, después τ) por una sola sustitución (θτ
θτ)
θτ

Principios de Programación Lógica 61


Composición de sustituciones (II)
Dadas dos sustituciones θ = {V1/t1, V2/t2,...,Vn/tn} y
τ = {U1/s1, U2/s2,...,Um/sm}
su composición se calcula:

1. aplicando τ a cada ti de θ
2. eliminando las falsas ligaduras Vi/Vi resultantes de 1)
3. eliminando las ligaduras Ui/si tales que Ui=Vj

θτ = {V1/t1τ, V2/t2τ,...,V
τ, n/tnτ,U1/s1, U2/s2,...,Um/sm}

Eliminar Vi/Vi Eliminar Ui/si si Ui=Vj

Ejemplo: θ = {X/f(Y), Y/Z} τ = {X/a,Y/b,Z/Y}


θτ = {X/f(b),Z/Y}
Principios de Programación Lógica 62
Unificador de términos
Una sustitución τ es un unificador de dos términos A y B sii

Aττ = Bττ

Ejemplo: A = p(f(X),Z) B = p(Y,a) τ ={Y/f(a),Z/a,X/a}


=
Aττ = p(f(a),a) = Bττ

Un unificador θ se dice que es más general que otro unificador


τ si existe una sustitución β tal que

τ = θβ

Ejemplo: A = p(f(X),Z) B = p(Y,a)


τ ={Y/f(a),Z/a,X/a}
= θ={Y/f(X),Z/a} β ={X/a}
Aθθ = p(f(X),a) = Bθ
θ

Principios de Programación Lógica 63


Unificador de máxima generalidad (umg)
Se dice que θ es un unificador de máxima generalidad (umg) si
para cualquier otro unificador τ existe una sustitución β tal que

τ = θβ

Si θ y σ son unificadores de máxima generalidad, entonces


existen renombrados δ y γ tales que
θδ = σγ
es decir, pueden existir varios umgs, pero éstos se diferenciarán
sólo en el nombre de las variables

Ejemplo:
A = p(f(X),Z) B = p(f(Y),V) θ ={X/Y,Z/V}
= σ ={Y/X,Z/V}
=
θ = σ{X/Y}
σ σ = θ{Y/X}

Principios de Programación Lógica 64


El algoritmo de unificación (I)
unificar(A,B: término): unificador;
1) K:=0; θ0:= ε (* sustitución vacía *)
θk=Bθ
2) Si Aθ θk entonces
devolver θk;
sino
(Ai,Bi):= primer par de discordancia de Aθθk y Bθ
θk;
3) Si (uno de (Ai,Bi) es una variable V) y
(el otro un término t donde no aparece V) entonces
θk+1:= θk{V/t};
test de ocurrencia
k:= k+1;
ir a 2)
sino
parar(“no unifican”);

Principios de Programación Lógica 65


El algoritmo de unificación (y II)
Ejercicio: unificar los siguientes pares de términos

1) p(a,X,h(g(Z))) p(Z,h(Y),h(Y))
2) p(f(a),g(X)) p(Y,Y)
3) p(X,X) p(Y,f(Y))

Para mejorar la eficiencia, las implementaciones de Prolog


omiten el test de ocurrencia, lo que puede dar lugar a términos
cíclicos:

unificar(X,f(X))= {X/f(X)} ⇒ X= f(f(f...))

Los resultados dependen de la implementación...

Principios de Programación Lógica 66


Invocando procedimientos
Una vez formalizado el paso de parámetros, podemos formalizar
el resto del motor de inferencia

Un objetivo
:- p(X1,...,Xn).

es realmente una invocación al procedimiento p/n

p(Y1, ...,Yn) :- q1(Y11,...,Y1i),


..., cuerpo
cabecera qj(Yj1,...,Yjk).

¿Cómo se ejecuta esta invocación?


Principios de Programación Lógica 67
Pasos para invocar a un procedimiento
1) renombrar las variables del procedimiento invocado p/n
p(Z1, ...,Zn) :- q1(Z11,...,Z1i),
...,
qj(Zj1,...,Zjk).

2) unificar la cabecera del procedimiento renombrado con el


objetivo mediante un umg θ
θ = p(X1,...,Xn)θ
p(Z1, ...,Zn)θ θ

Si no unifican, la invocación no se puede realizar

3) reemplazar la invocación por el cuerpo del procedimiento


renombrado y aplicar el umg θ al nuevo objetivo
θ.
:- q1(Z11,...,Z1i),...,qj(Zj1,...,Zjk)θ
Principios de Programación Lógica 68
Ejemplo de invocación de procedimiento
Ejecutar el objetivo

p(X,Y) :- :-p(Z,b).
r(Y),q(X,Y). 1) renombrar la regla del procedimiento p/2
q(X,Y) :-
p(X1,Y1) :- r(Y1),q(X1,Y1).
r(X),r(Y).
q(X,b) :- 2) unificar parámetros actuales y formales
r(X),t(X). p(X1,Y1)θ = p(Z,b)θ
r(a). θ = {X1/Z,Y1/b}
r(b).
3) obtener el nuevo objetivo
t(b).
:- r(Y1),q(X1,Y1)θ =
:- r(b), q(Z,b).

Principios de Programación Lógica 69


Alternativas en la invocación
Frecuentemente se presentarán alternativas en la invocación...

p(X,Y) :- Al ejecutar el objetivo


r(Y),q(X,Y).
:-r(b), q(Z,b).
q(X,Y) :-
r(X),r(Y). se presentan las siguientes alternativas:
q(X,b) :-
qué subobjetivo ejecutar
r(X),t(X).
qué hecho o regla invocados aplicar
r(a).
dónde colocar el cuerpo renombrado
r(b).
t(b).

¿cómo resuelve el motor de inferencia estas alternativas?

Principios de Programación Lógica 70


Resolviendo las alternativas
Elección de subojetivo: el que esté más a la izquierda

:- p1(X1,...,Xn), p2(Y1,...,Ym),..., pk(Z1,...,Zi).

Elección de hecho o regla: se aplican todos los hechos y reglas


de p1/n cuyas argumentos unifiquen con los de p1(X1,...,Xn);
es decir, la invocación de p1/n puede originar tantas ejecuciones
diferentes como hechos y reglas tenga p1/n

Estas invocaciones alternativas se realizan en el orden en que


aparecen en el programa las definiciones de p1/n, dando lugar a
un árbol de ejecución (o de búsqueda)

Elección del emplazamiento del cuerpo renombrado: a la


izquierda, sustituyendo al subobjetivo que lo invoca

Principios de Programación Lógica 71


Arbol de búsqueda

p1(X1,...,Xn):- C1.
... La invocación de p1/n puede
dar lugar hasta a K ramas...
p1(X1,...,Xn):- Ck.

:- p1(X1,..,Xn),.., p(Z1,..,Zi).

1 .... K

θ1.
:- (C1’,.., p(Z1,..,Zi))θ θk.
:- (Ck’,.., p(Z1,..,Zi))θ

donde Ci’es el cuerpo Ci renombrado.


Observa que θi se aplica a todo el objetivo, no sólo a Ci’
El motor de inferencia construye el árbol primero en profundidad
Principios de Programación Lógica 72
Ejemplo 1 de árbol de búsqueda
Dado el programa Prolog:

/* 1 */ p(X,Y) :- r(Y), q(X,Y).


/* 2 */ q(X,Y) :- r(X), r(Y).
/* 3 */ q(X,b) :- r(X), t(X).
/* 4 */ r(a).
/* 5 */ r(b).
/* 6 */ t(b).

Obtener el árbol de búsqueda para el objetivo:

:- p(Z,b).

[en pizarra/SLD-Draw]

Principios de Programación Lógica 73


Ejemplo 2 de árbol de búsqueda
Dado el programa Prolog:
/* 1 */ p(X,Y) :- r(X),s(X,Y).
/* 2 */ p(X,Y) :- t(Z), p(X,Y).
/* 3 */ p(X,Y) :- q(X,Y).
/* 4 */ q(c,c).
/* 5 */ q(f(X),Y) :- q(X,Y).
/* 6 */ s(X,X).
/* 7 */ s(X,Y) :- t(Y),t(X).
/* 8 */ r(a).
/* 9 */ r(b).
/* 10 */ t(b).
Obtener el árbol de búsqueda para el objetivo:

:- p(A,B).

[en pizarra/SLD-Draw]
Principios de Programación Lógica 74
Ejemplo 3 de árbol de búsqueda
Dado el programa Prolog:

/* 1 */ p(X,Y) :- r(Y), q(X,Y).


/* 2 */ p(X,Y) :- r(Y), p(X,Y).
/* 3 */ q(X,Y) :- r(X), r(Y).
/* 4 */ q(b,b).
/* 5 */ r(a).
/* 6 */ r(b).

Obtener el árbol de búsqueda para el objetivo:

:- p(Z,b).

[en pizarra/SLD-Draw]

Principios de Programación Lógica 75


Ejemplo 4 de árbol de búsqueda
Dado el programa Prolog:
/* 1 */ p(X,Y) :- q(X,Y).
/* 2 */ p(X,Y) :- q(a,X).
/* 3 */ q(a,a).
/* 4 */ q(X,a) :- r(Y), s(X,Y).
/* 5 */ q(X,Y) :- r(X), p(X,Y).
/* 6 */ s(b,b).
/* 7 */ s(b,X) :- r(X).
/* 8 */ r(b).
/* 9 */ r(a).

Obtener el árbol de búsqueda para el objetivo:

:- p(b,Z).

[en pizarra/SLD-Draw]

Principios de Programación Lógica 76


Ejemplo 5 de árbol de búsqueda
Dado el programa Prolog:

/* 1 */ q(X,Y) :- s(Y), r(X,Y).


/* 2 */ q(X,Y) :- q(Y,X).
/* 3 */ r(X,Y) :- t(Y), s(X).
/* 4 */ r(X,Y) :- s(Y).
/* 5 */ s(a).
/* 6 */ s(b).
/* 7 */ t(b).
/* 8 */ t(c).

Obtener el árbol de búsqueda para el objetivo:

:- q(Y,X).

[en pizarra/SLD-Draw]

Principios de Programación Lógica 77


Ejemplo 6 de árbol de búsqueda
Dado el programa Prolog:

/* 1 */ p(X,Y) :- q(X,Y),r(X).
/* 2 */ p(X,Y):-q(X,Y),r(Y).
/* 3 */ q(X,Y):-t(X),t(Y).
/* 4 */ t(X):-r(X),r(Y).
/* 5 */ t(X).
/* 6 */ r(a).
/* 7 */ r(b).

Obtener los árboles de búsqueda para los objetivos:

:- p(c,Y).
:- p(a,Y).

[en pizarra/SLD-Draw]

Principios de Programación Lógica 78


Ejemplo 7 de árbol de búsqueda
Dado el programa Prolog:

/* 1 */ p(X,Y):-q(X,Y),r(Y).
/* 2 */ p(X,Y) :- q(X,Y),r(X).
/* 3 */ q(X,Y):-t(X),t(Y).
/* 4 */ t(X).
/* 5 */ t(X):-r(X),q(c,X).
/* 6 */ r(a).
/* 7 */ r(b).

Obtener los árboles de búsqueda para los objetivos:

:- p(c,Y).
:- p(a,Y).

[en pizarra/SLD-Draw]

Principios de Programación Lógica 79


Ejemplo 8 de árbol de búsqueda
Dado el programa Prolog:
/* 1 */ p(X,Y):- q(X,Y).
/* 2 */ p(X,Y):- q(a,X).
/* 3 */ q(a,a).
/* 4 */ q(X,a):- r(Y),s(X,Y).
/* 5 */ q(X,Y):- r(a),p(X,Y).
/* 6 */ s(b,b).
/* 7 */ s(b,X):- r(X).
/* 8 */ r(b).
/* 9 */ r(a).

Obtener el árbol de búsqueda para el objetivo:

:- p(X,b).

[en pizarra/SLD-Draw]

Principios de Programación Lógica 80


Ramas éxito y fallo
rama éxito: aquélla cuyo nodo hoja es un objetivo vacío.
Corresponden a ejecuciones completas del objetivo inicial, para el
que aportan una solución: la respuesta computada

respuesta computada: la sustitución que se obtiene al aplicar


los unificadores de una rama éxito (desde la raíz a la hoja) a las
variables del objetivo inicial. Cada rama éxito aporta su propia
respuesta computada, que puede ser idéntica a la de otra rama
éxito

rama fallo: aquélla cuyo nodo hoja contiene un subobjetivo a la


izquierda que no unifica con ninguna regla o hecho del programa.
Corresponden a ejecuciones que no pueden avanzar

Principios de Programación Lógica 81


Ramas infinitas, cíclicas y repetidas
rama cíclica: contiene dos nodos A y B tales que A es
predecesor de B y B es un renombrado de A (B=Aθ θ) y los
unificadores de los nodos que los separan no instancian las
variables del objetivo (es decir, el cómputo no avanza)

rama infinita: contiene dos nodos A y B tales que A es


predecesor de B y B es un renombrado de A (B=Aθ θ) y los
unificadores de los nodos que los separan instancian las variables
del objetivo (es decir, el cómputo avanza)

ramas repetidas: contienen dos nodos A y B tales que uno es


renombrado del otro, ninguno es predecesor/antecesor del otro y
las sustituciones de las ramas que contienen a A y B son iguales
módulo renombrado

Principios de Programación Lógica 82


Usos de la unificación (I)
Parámetros de entrada (modo ‘’+’’):
+ +
:- hermanos(fernando,silvia)

hermanos(X,Y) :-
padre(P,X),
madre(M,X),
padre(P,Y),
madre(M,Y),
X \= Y.
Un argumento A se dice que está en modo ‘’+’’ en una invocación
de un procedimiento p/n si la ejecución de p/n no instancia
ninguna de las variables de A
Principios de Programación Lógica 83
Usos de la unificación (II)
Parámetros de salida (modo ‘’-’’):
- -
:- padre(P,H)

padre(antonio,carlos).
padre(antonio,eva).
padre(carlos,fernando).
padre(carlos,silvia).
padre(david,emilio).

Un argumento A se dice que está en modo ‘’-’’ en una invocación


de un procedimiento p/n si la ejecución de p/n instancia alguna
de las variables de A

Principios de Programación Lógica 84


Usos de la unificación (III)
Los modos ‘’+’’ y ‘’-’’ se pueden combinar en una invocación:

+ -
:- padre(antonio,H)

padre(antonio,carlos).
padre(antonio,eva).
padre(carlos,fernando).
padre(carlos,silvia).
padre(david,emilio).

Principios de Programación Lógica 85


Usos de la unificación (IV)
Mecanismo de selección/acceso a estructuras

Ejemplo: una regla para cada caso de pila bien construida

p(pila_vacía) :- ...
p(pila(Cima,Resto)) :- ...

Ejemplo: una regla para cada caso de circuito bien construido

q(or(A,B)) :- ...
q(and(A,B)) :- ...
q(nand(A,B)) :- ...
q(not(A)) :- ...
Principios de Programación Lógica 86
Usos de la unificación (V)
Mecanismo de cómputo

Ejemplo:
puntos representados por el functor punto/2:
punto(2,3)
segmentos representados por el functor seg/2:
seg(punto(1,1),punto(2,5))
procedimientos vertical/1 y horizontal/1:
vertical(seg(punto(X,Y1),punto(X,Y2))).
horizontal(seg(punto(X1,Y),punto(X2,Y))).

?- vertical(S), horizontal(S).
S= seg(punto(A,B),punto(A,B))

Principios de Programación Lógica 87


Prolog = Programación Lógica
Prolog= Programación Lógica

La idea fundamental de la programación lógica es que:

“La lógica puede utilizarse como lenguaje de programación”

Esta idea se fundamenta en tres equivalencias:

términos como estructuras de datos


fórmulas como programas
deducciones como cómputos

Principios de Programación Lógica 89


Términos como estructuras de datos

Sean:
C un conjunto no vacío de constantes
V un conjunto no vacío de variables
F un conjunto no vacío de funciones

El conjunto de términos de primer orden T se define


inductivamente:
1. c ∈ C es un término
2. v ∈ V es un término
3. f(t1,...,tn) es un término sii f ∈ F y ti ∈ T
4. no hay más términos en T que los definidos por 1-3

Los términos Prolog equivalen a los términos de primer orden T

Principios de Programación Lógica 90


Fórmulas como programas (I)
Sean:
P un conjunto no vacío de predicados
el conjunto de conectivas {⊥
⊥ , , ∧ , ∨ , ¬ , ⇒ }
el conjunto de cuantificadores { ∃, ∀ }
el conjunto de signos de puntuación { (, ) }

El conjunto de fórmulas bien formadas (fbfs) se define


inductivamente:
1. p(t1,...,tn) donde ti ∈ T y p ∈ P es una fbf
2. si f y g son fbfs y x ∈ V,
V también son fbfs:
⊥, , f ∧ g, f ∨ g, ¬ f, f ⇒ g,
∃ x.f(x), ∀ x.f(x), (f)
3. No hay más fbfs que las definidas por 1-2

Principios de Programación Lógica 91


Fórmulas como programas (II)

Un átomo es una fbf de la forma p(t1,...,tn)


Un literal es un átomo p(t1,...,tn) o su negación ¬ p(t1,...,tn)
Una cláusula es una disyunción de literales L1∨ ...∨ Ln
Una cláusula de Horn es una cláusula con a lo más un literal
positivo
Una cláusula de Horn definida es una cláusula con
exactamente un literal positivo

Toda regla, hecho u objetivo Prolog puede traducirse a una


cláusula de Horn, definida o no

Principios de Programación Lógica 92


Fórmulas como programas (III)
La regla Prolog:
p(XX):- c1(Y
Y1), ..., cn(Y
Yn).
cabeza = conclusión cuerpo= condiciones
equivale a la implicación universalmente cuantificada:
Y1,..., Yn. (c1(Y
∀ X,Y Y1) ∧ ...∧ Yn)) ⇒ p(X
∧ cn(Y X)

por definición A ⇒ B ≡ ¬ A ∨ B, de donde:


Y1,..., Yn. ¬(c1(Y
∀ X,Y Y1) ∧ ...∧ Yn)) ∨ p(X
∧ cn(Y X)

aplicando De Morgan obtenemos:


∀ X,Y
Y1,..., Yn. ¬c1(YY1) ∨ ...∨
∨ ¬cn(Y
Yn) ∨ p(X
X)
literales negativos literal positivo

Principios de Programación Lógica 93


Fórmulas como programas (IV)
El hecho Prolog
p(XX).

relación incondicional
equivale a la implicación universalmente cuantificada:
∀ X. ⇒ p(X
X)

por definición A ⇒ B ≡ ¬ A ∨ B, de donde:


∀ X. ¬ ∨ p(X
X)

de donde obtenemos:
∀ X. p(XX)
literal positivo

Principios de Programación Lógica 94


Fórmulas como programas (y V)
El objetivo Prolog:
:- c1(YY1), ..., cm(Y
Ym).

cuerpo= preguntas
equivale a la implicación universalmente cuantificada:
∀ Y1,..., Ym. (c1(Y
Y1) ∧ ...∧ Ym)) ⇒ ⊥
∧ cm(Y

por definición A ⇒ B ≡ ¬ A ∨ B, de donde:


Y1,..., Ym. ¬(c1(Y
∀ X,Y Y1) ∧ ...∧ Ym)) ∨ ⊥
∧ cm(Y

aplicando De Morgan obtenemos:


∀ X,Y
Y1,..., Ym. ¬c1(YY1) ∨ ...∨
∨ ¬cm(Y
Y m)
literales negativos

Principios de Programación Lógica 95


Deducciones como cómputos (I)
Un programa y un objetivo Prolog pueden traducirse a un conjunto
de cláusulas de Horn.

Ejemplo:

p(X,Z) :- ∀ x,y,z.¬
¬ q(x,y)∨
∨ ¬ p(y,z)∨
∨ p(x,z)
q(X,Y),
p(Y,Z).
p(X,X). ∀ x. p(x,x)
q(a,b). q(a,b)

:- p(X,b). ∀ x.¬
¬ p(x,b)

La ejecución del programa se corresponde entonces con una


deducción controlada y constructiva; es decir, una deducción que
se ajusta a cierta estrategia e instancia variables
Principios de Programación Lógica 96
Deducciones como cómputos (II)

La deducción se basa en la regla de resolución de Robinson.

U) y una cláusula
Sean una cláusula C1 donde aparece un literal A(U
C2 donde aparece el literal opuesto ¬ A(VV). Sea Θ un umg de C1
y C2 Θ = unificar(A(U U),A(VV)). Si ambas cláusulas son
ciertas se puede deducir que:

U) ∨ B(X
A(U X)
X) ∨ C(Y
(B(X Y))Θ
Θ
¬ A(V
V) ∨ C(Y
Y)

Principios de Programación Lógica 97


Deducciones como cómputos (III)
la invocación del procedimiento Prolog p/2:

:- p(X,b).

p(X1,Z1) :- {X1/X,Z1/b}
q(X1,Y1),
p(Y1,Z1). :- q(X,Y1),p(Y1,b)

equivale a una deducción por resolución:


∀ x,y,z.¬ q(x,y)∨ ¬ p(y,z)∨ p(x,z) ∀ x,y.
∀ x. ¬ p(x,b) (¬q(x,y)∨ ¬p(y,z))Θ

donde unificar(p(x1,z1),p(x,b))= {x1/x,z1/b}= Θ

Principios de Programación Lógica 98


Deducciones como cómputos (IV)
El método de resolución es un método de refutación:

Ω  O ≡ Ω ∪ {¬ O}  

M(¬O
¬O)
¬O M(¬O
¬O)
¬O
M(Ω
Ω)
M(Ω
Ω) M(O
O) M(O
O)

ΩO ΩO
En lugar de demostrar que O es consecuencia lógica de Ω (Ω  O),
demostramos que Ω ∪ {¬ O} es inconsistente (Ω ∪ {¬ O}  )

Principios de Programación Lógica 99


Deducciones como cómputos (V)
Prolog razona por refutación

Dado el programa Prolog, la pregunta :


¿existe algún X que sea hermano de silvia?
se formaliza con el objetivo:
:- hermanos(silvia,X).
que equivale a las fórmulas:
∀x. ¬hermanos(silvia,x) ≡
¬ ∃x. hermanos(silvia,x)

El objetivo se niega y Prolog trata de refutarlo encontrando un


contramodelo (X=fernando).

Principios de Programación Lógica 100


Deducciones como cómputos (VI)
Necesitamos un método que genere una secuencia de resolventes

Resolución por saturación (Robinson)


Ro(ΩΩ ∪ {¬ O})= Ω ∪ {¬ O}, ..., Ri+1=R(Ri(Ω
Ω ∪ {¬ O}))

Resolución lineal (Loveland/Luckham)


Ci Bi
Bi ∈ Ω ∪ {¬ O}}∨ Bi=C
Ck,k<i

Ci+1
Resolución lineal ordenada (Kowalski/Kuenner)
Similar a la anterior, estableciendo un orden en los literales

Estos métodos no son apropiados como motor de inferencia...


Principios de Programación Lógica 101
Deducciones como cómputos (VII)
Necesitamos un método de resolución que genere una secuencia
de resolventes Ci tal que C0 =¬ O y Ci+1=R(Ci,ω), ω ∈ Ω

Ci ω∈Ω

Ci+1

Es decir, los objetivos Ci se va transformando aplicando los


procedimientos definidos en el programa Ω

Esto es posible siempre que las cláusulas de Ω sean cláusulas de


Horn definidas y los Ci tengan todos los literales negativos

Principios de Programación Lógica 102


Deducciones como cómputos (VIII)
SLD-Resolución (Selective Linear for Definite clauses)

Sean:

Ω un conjunto de cláusulas de Horn definidas


O una cláusula de Horn sin literal positivo
O ≡ ¬O1 ∨ ¬ O2 ∨...∨ ¬ On
S una regla de selección que, dada una cláusula de Horn sin
literal positivo, devuelva “uno” de sus literales
S(¬O1 ∨ ¬ O2 ∨...∨ ¬ On) = ¬Oi
B una regla de búsqueda que, dados ¬Oi y Ω devuelva una
cláusula P ∨ ¬C1 ∨ ... ∨ ¬Cn ∈ Ω tal que umg(Oi,P)=Θ

Principios de Programación Lógica 103


Deducciones como cómputos (IX)
Algoritmo Refutación_SLD(Ω O)
Ω,O
1) R:= O
¬O1 ∨ ¬ O2 ∨...∨
2) ObjAtm_i:= S(¬O ∨ ¬ On )
Ω,ObjAtm_i)
3) Cláusula:= B(Ω
donde Cláusula= P ∨ ¬ C1 ∨ ... ∨ ¬ Cm
Si no existe tal cláusula
parar(“refutación acabada en fallo”)
P,ObjAtm_i)
4) Θ:= unificar(P
5) R:= (R – ObjAtm_i ∪ (¬¬ C1 ∨ ... ∨ ¬ Cm))Θ
Θ
6) Si R=

parar(“refutación acabada en éxito”)
sino ir al paso 2)

El algoritmo construye sólo una refutación por SLD-Resolución

Principios de Programación Lógica 104


Deducciones como cómputos (X)
Fijadas una S y una B, un árbol SLD contempla todas las
refutaciones posibles ordenando las cláusulas para resolver Oj
según B :
S

¬O1 ∨...∨ ¬Oj ∨...∨ ¬On


B 1 K
.......

¬O1 ∨...∨ ¬ C1 ∨ ... ∨ ¬ Cm ∨...∨ ¬On)θ


(¬ θ1. ...

Las ramas pueden acabar en fallo, éxito o ser infinitas


S afecta significativamente a la forma del árbol SLD (nº hijos...)
B sólo permuta las ramas del árbol SLD

Principios de Programación Lógica 105


Deducciones como cómputos (XI)

Los árboles de búsqueda Prolog son árboles SLD donde:

La regla de selección S elige el literal más a la izquierda


La regla de búsqueda B elige las cláusulas “de arriba abajo”
El árbol se construye primero en profundidad (se pierde la
completitud por las ramas cíclicas/infinitas)

Cada rama del árbol de búsqueda codifica un intento de


refutación por SLD-Resolución del objetivo O respecto del
programa Ω

Principios de Programación Lógica 106


Capacidad expresiva de las cláusulas de Horn
Para responder a la pregunta:

¿Qué capacidad expresiva tienen las cláusulas de Horn?

codificaremos un autómata finito (AF) en Prolog

Un AF es un quíntupla Q,Q
Q Qo,FF,A
A,δ δ donde:
Q es un conjunto de estados
Q es un estado inicial (Q
Q ∈ Q )
F es un conjunto de estados finales (F F ⊆ Q)
A es un alfabeto
δ es una función de transición δ:Q Q × A → Q

Un AF reconoce cadenas de un lenguaje regular

Principios de Programación Lógica 107


Un ejemplo de autómata finito
El autómata finito de la figura reconoce el lenguaje a*bc (d* | e*)f

c q2 f
a

b
q0 q1 d
q4
e

c
q3 f

Principios de Programación Lógica 108


Objetos del AF
En la definición del AF, identificamos el alfabeto y los estados

alfabeto átomos a,b,c,d,e,f,$


estados átomos q0,q1,q2,q3,q4

Además, el AF recibirá una cadena de entrada en una cinta


cadena functor cinta/2
Cadena::= cinta(átomo,Cadena)
| $

La cadena “abcdf” se representa por el término


cinta(a,cinta(b,cinta(c,(cinta(d,(cinta(f,$)))))))

Principios de Programación Lógica 109


Relaciones del AF
Función de transición δ
definimos el procedimiento delta/3
por cada transición δ(qi,s) = qj
introducimos un hecho delta(qi,s,qj).

Estado inicial Qo
definimos el procedimiento inicial/1
mediante el único hecho inicial(q0).

Estados finales F
definimos el procedimiento final/1
mediante el hecho final(q4).

Principios de Programación Lógica 110


Reconocimiento de la cadena
El reconocimiento es una relación entre una cadena y un estado
reconoce(Q,S) - “El AF reconoce la cadena S desde el estado Q”

El procedimiento reconoce/2 se define recursivamente:

reconoce(Q,'$') :-
final(Q).
reconoce(Q,cinta(C,Resto)) :-
delta(Q,C,QN),
reconoce(QN,Resto).

Principios de Programación Lógica 111


El programa Prolog completo
% delta/3 % reconoce/2
delta(q0,a,q0). reconoce(Q,cinta(C,Resto)) :-
delta(q0,b,q1). delta(Q,C,QN),
delta(q1,c,q2). reconoce(QN,Resto).

delta(q1,c,q3).
reconoce(Q,'$') :-
delta(q2,d,q2). final(Q).
delta(q2,f,q4).
delta(q3,e,q3). % automata/1
delta(q3,f,q4). automata(Cadena) :-
inicial(Q0),
% inicial/1
reconoce(Q0,Cadena),
inicial(q0). write_ln('cadena aceptada').
% final/1
final(q4).

Principios de Programación Lógica 112


Teorema de adecuación y Turing completitud
Cualquier AF puede codificarse en Prolog siguiendo el esquema
anterior.

La anterior codificación permite:


representar un AF como un conjunto de cláusulas de Horn
plantear un reconocimiento de la cadena como una demostración

Teorema de adecuación:
Dado un AF, A, el conjunto de cláusulas de Horn Ω que lo
representan y una cadena S:

A reconoce S sii Ω  inicial(Q) ∧ reconoce(Q,S)

Cualquier máquina de Turing puede codificarse en Prolog


siguiendo un esquema similar al anterior
Principios de Programación Lógica 113

También podría gustarte