Está en la página 1de 74

Unidad 4: Programación

Lógica y Funcional
m a c ión
progra a
Lógic
Un trabajito propuesto en 1970
¿Como programar un sistema como el siguiente?
 Usuario > Los gatos matan ratones.
 Usuario > Tom es un gato al que no le gustan los ratones

que comen queso.


 Usuario > Jerry es un rat´on que come queso.
 Usuario > Max no es un gato.
 Usuario > ¿Qué hace Tom?
 Sistema > A Tom no le gustan los ratones que comen

queso.
 Sistema > Tom mata ratones.
 Usuario > ¿Quíen es un gato?
 Sistema > Tom.
 Usuario > ¿Qué come Jerry?
 Sistema > Queso.
1965. Alan Robinson [3] formula el principio de
resolución.
Reglas de inferencias menos humanas, pero mas
eficientes.
1970. Alain Colmerauer, Philippe Roussel y Robert
Pasero trabajan en traducción automática y
procesamiento de lenguaje natural.
1971. Robert Kowalski [2] dene la resolución-SL.
1974. El lenguaje Prolog.
Siglo XIX. En su segunda mitad, Gottlob Frege
introduce la lógica de primer orden. Modificada a su
forma actual por Giuseppe Peano y Bertrand Russell.
1930's. Kurt GŐedel y Jacques Herbrand estudiaron la
noción de computabilidad basada en derivaciones.
1965. La resolución y unificación por Alain Robinson.
1974. La resolución-SL de Kowalski: debate (en ese
momento) sobre representaciones declarativas y
procedimentales. Prolog.
1983. La máquina abstracta de Warren (WAM).
Compilación independiente al procesador usado.
La programación lógica es una herramienta y un sujeto
de estudio de la inteligencia artificial.
La lógica de primer orden es fundamental para entender
este paradigma de programación.
La programación lógica es un paradigma de
programación, que difiere de otros paradigmas como la
programación imperativa (Algol, C, Pascal, etc.), la
orientada a objetos (Simula, Smalltalk, Eiel, C++, Java,
etc.), o la funcional (ML, Haskell, Lisp, etc.).
Prolog <> programación lógica, pero es su realización
práctica más usada en la actualidad.
La clase más general de objeto manejado en
programación lógica es el término.
Suelen indicarse mediante un
identificador cuyo primer carácter es
una letra mayúscula

Una constante lógica


no es otra cosa que una
función de aridad cero

Los términos compuestos son los


objetos estructurados del lenguaje.
Los términos compuestos
Se componen de un funtor y una secuencia de uno o
más términos llamados argumentos.
Un funtor se caracteriza por su firma, formada por su
nombre, que es un átomo, y su aridad o número de
argumentos.
Cuando el término compuesto no expresa ningún tipo
de relación lógica, suele dársele el nombre de función.
Cuando si expresa ese tipo de relación, lo denominamos
predicado.
Estructuralmente, un objeto se representa mediante un
árbol que responde al esquema indicado por su firma, y
en el que la raíz está etiquetada con el nombre del funtor
y los hijos con los argumentos del mismo. Un término
establece una relación entre el funtor y el conjunto de
sus argumentos.

Esta relación, junto con el término al que se asocia,


viene fijada por el programador y constituirá el elemento
básico dotado de significado de un programa,
denominado: átomo.
La unidad fundamental de un programa lógico es el
átomo: un tipo especial de término compuesto,
distinguido sólo por el contexto en el cual aparece en
el programa.
Literal: un átomo o su negación.
Cláusula: conjunto de literales ligados por conectores
y cuantificadores lógicos.
Prolog trabaja con un tipo especial de cláusulas
denominadas cláusulas de Horn.
Una cláusula de Horn es una estructura compuesta por
una cabeza y un cuerpo.
La cabeza consiste de un simple átomo, o bien está
vacía.
El cuerpo está formado por una secuencia de cero o
más literales ligados mediante conectivas conjuntivas
o disyuntivas.
El final del cuerpo suele indicarse mediante un punto.
Todas las variables de la cláusula están cuantificadas
universalmente y son locales a la misma.
Cuando la cabeza está vacía se dice que la cláusula es
una pregunta.
La cabeza y el cuerpo de una misma cláusula están
separados por un símbolo de implicación lógica cuya
representación notacional puede variar.
En prolog :-
Leer declarativamente

Leer operacionalmente

Donde el átomo de cabeza y los literales de la cola


suelen referirse como objetivos.

Un programa lógico se define simplemente como


una secuencia de cláusulas de Horn.
El siguiente programa define recursivamente el conjunto de los
números naturales:
natural(0).
natural(suc(X)) :- natural(X).

Resulta obvio que suc no expresa ningún tipo de relación


lógica, en contra de lo que, por tanto, suc refiere a una
función y no a un predicado, que si sería el caso de natural.
Declarativamente, podemos leer ambas cláusulas en la
forma:
 “El cero es natural.”
 “El número X es natural, si X también lo es.”
Una sustitución es una lista de pares (variable,
término).

para representar la sustitución que asocia las variables


Xi a los términos:

La aplicación de una sustitución θ a un término lógico


T será denotada Tθ y se dirá que es una instancia del
término T .
Definición formal recursiva de la semántica
declarativa de las cláusulas:
“Un objetivo es cierto si es una instancia de la cabeza de
alguna de las cláusulas del programa lógico considerado y
cada uno de los objetivos que forman el cuerpo de la
cláusula instanciada son a su vez ciertos.”
Las sustituciones son utilizadas en programación
lógica para, mediante su aplicación a las variables
contenidas en una cláusula, obtener la expresión de la
veracidad de una relación lógica particular a partir de
la veracidad de una relación lógica más general
incluida en el programa.
Unificación
Definición:
Un unificador de dos términos lógicos T1 y T2 es una
sustitución θ, tal que Tθ1 = Tθ2. Cuando al menos existe
un unificador para dos términos lógicos T1 y T2, existe
un unificador particular θ llamado el unificador más
general (umg) de T1 y T2, tal que para cualquier otro
unificador θ′, existe una sustitución tal que θ′ = θ σ.
Tautología
Proposición molecular que SIEMPRE es cierta,
independientemente de los valores de certeza de las
proposiciones atómicas que la componen.
 Deducción proposicional
 Demostrar que un razonamiento es válido

 1.- Líneas de demostración numeradas (premisas o deducciones).


 2.- Cada línea debe ser justificada por una línea de inferencia.
 3.- Indicar la información utilizada en cada regla.
P
r
o
l
o
g
Prolog
Disponemos de una base de conocimiento compuesta
de reglas sobre clasificación de animales y hechos
sobre características de un animal.
 Regla 1: Si un animal es ungulado y tiene rayas negras,
entonces es una cebra.
 Regla 2: Si un animal rumia y es mamífero, entonces es
ungulado.
 Regla 3: Si un animal es mamífero y tiene pezuñas, entonces
es ungulado.
 Hecho 1: El animal es mamífero.
 Hecho 2: El animal tiene pezuñas.
 Hecho 3: El animal tiene rayas negras.
Demostrar a partir de la base de conocimientos que el
animal es una cebra.
Demostración: Una forma de demostrarlo es
razonando hacia atrás.
 El problema inicial consiste en demostrar que el animal es
una cebra.
 Por la regla 1, el problema se reduce a demostrar que el animal
es ungulado y tiene rayas negras.
 Por la regla 3, el problema se reduce a demostrar que el animal
es mamífero, tiene pezuñas y tiene rayas negras.
 Por el hecho 1, el problema se reduce a demostrar que el
animal tiene pezuñas y tiene rayas negras.
 Por el hecho 2, el problema se reduce a demostrar que el
animal tiene rayas negras. Que es cierto por el hecho 3.
Formando reglas…
Empecemos por elegir los símbolos para los átomos que
aparecen en la regla.
Para la regla 1 podemos elegir los símbolos es_angulado,
tiene_rayas_negras, y es_cebra, entoces podemos
representar esta regla como:

Si es_angulado y tiene_rayas_negras entonces es_cebra

 Usando conectores lógicos: Condicional y Conjunción

es_angulado ^ tiene_rayas_negras → es_cebra

Conjunción Condicional
Prolog es la realización más utilizada del paradigma de
programación lógica.
Escribir un programa en Prolog tiene menos que ver
con la tarea de especificar un algoritmo, como es el
caso de la programación imperativa; y más con la
especificación de los objetos y las relaciones que
ocurren entre ellos, en el contexto de un problema.
Representación en prolog:

Condicional Conjunción
Inversa

es_cebra :- es_angulado, tiene_rayas_negras

Cabeza Cuerpo

El átomo a la izquierda de :- se llama la cabeza y los


átomos a la derecha se llama el cuerpo de la regla.
Para representar los hechos
elegir los símbolos de los átomos. Por ejemplo, el hecho
2 se representa en Prolog:

tiene_rayas_negras.

es decir, el símbolo del átomo terminado en un punto.


Los hechos pueden verse como cláusulas con el cuerpo
vacío.
Base de Conocimiento en Prolog:

Esto se escribe en un archivo y se guarda con la


extensión .pl, por ejemplo, animales.pl
Para iniciar una sesión de Prolog (con SWI Prolog) se usa la
orden pl .
El programa se carga en la sesión Prolog escribiendo el
nombre entre corchetes y terminado en un punto.
 La pregunta se plantea escribiendo el átomo y un punto.

La respuesta yes significa que ha demostrado que el animal


es una cebra.
¿Como obtiene prolog la deducción?
Prolog ha obtenido la demostración mediante el árbol
de deducción.
La búsqueda de la prueba es una búsqueda en
profundidad en un espacio de estados, donde cada
estado es una pila de problemas por resolver.
A partir de la rama de éxito podemos extraer la
demostración por resolución LSD
Ampliando la presentación del sistema deductivo de
Prolog a la lógica relacional (con variables,
cuantificadores, constantes y símbolos de relación).
Hechos:
6 y 12 son divisibles por 2 y por 3.
 4 es divisible por 2.

Regla: Los números divisibles por 2 y por 3 son divisibles


por 6.

Para representar la base de conocimiento usaremos las


constantes 2,3,6 y 12, y el predicado binario divide(X,Y)
que se verifica si X divide a Y .
La regla, se puede expresar como para todo X: si X es
divisible por 2 y X es divisible por 3, entonces X es
divisible por 6.

Representación en prolog:
divide(6,X):- divide(2,X), divide(3,X).

variables
 EL mecanismo operacional adoptado por los sistemas que
implementan la versión pura del leguaje prolog es la estrategia de
resolución SLD con las siguientes propiedades:
 La regla de computación de prolog trata los objetivos como secuencia de
átomos y siempre selecciona para resolver el átomo situado mas a la
izquierda dentro del objetivo.
 Prolog intenta unificar el átomo seleccionado por la regla de computación
con las cabezas de las clausulas del programa considerándolas en el orden
textual en el que éstas aparecen dentro del programa.
 Prolog usa una regla de búsqueda en profundidad con vuelta atrás
(backtracking):
 visita los descendientes de un nodo antes de visitar un nodo hermano
 recorre primero la rama más a la izquierda del árbol de búsqueda antes de recorrer
el resto.
 Prolog permite sintaxis ambivalente. Un mismo símbolo de función o
predicado puede utilizarse con diferentes aridades en un mismo programa.
Para estudiar el comportamiento operacional de
prolog, éste proporciona el predicado trace

Trazar (trace): proceso


que visualiza la
información relativa a
los pasos de resolución
efectuados para
satisfacer ese objetivo,
incluyendo los valores
de los argumentos y el
éxito o fallo de los
objetivos.
Supongamos que queremos razonar sobre la
genealogía de una familia
El sistema está en un ciclo Read-Eval-Print (REPL).
Se pueden hacer preguntas más interesantes usando
variables:
Quien es el abuelo de Jim?
Resumiendo …
 Es sencillo definir en Prolog una relación especificando las n-
tuplas de objetos que la satisfacen. n es conocido como aridad.
 Un programa Prolog consiste de cláusulas.
 Los argumentos de una relación pueden ser: objetos
concretos o constantes como tom y ann; objetos generales o
variables como X e Y.
 Las preguntas planteadas a Prolog consisten en una o más
metas. Una secuencia de metas significa conjunción.
 La respuesta a una pregunta puede ser positiva o negativa,
dependiendo de si la meta se puede satisfacer o no.
 Si varias respuestas satisfacen una pregunta, Prolog encontrara
tantas como el usuario quiera.
Las reglas tienen dos partes:
Una parte condicional (el lado derecho de la regla o
cuerpo de la regla).
Una conclusión (el lado izquierdo de la regla o cabeza de
la regla).
Resumiendo ….
Los programas Prolog pueden extenderse fácilmente
agregando nuevas cláusulas.
Las cláusulas en Prolog son de tres tipos: hechos,
reglas y metas.
Los hechos declaran cosas que son verdaderas
siempre, incondicionalmente.
Las reglas declaran cosas que son verdaderas
dependiendo de ciertas condiciones.
Por medio de las preguntas el usuario puede
computar que cosas son verdaderas.
Resumiendo …
Las cláusulas de Prolog tienen cabeza y cuerpo. El
cuerpo es una lista de metas separadas por comas. Las
comas ‘ , ’ implican conjunción (AND).
Los hechos son cláusulas con el cuerpo vacío; las
preguntas tienen la cabeza vacía y las reglas tienen
cabeza y cuerpo.
En el curso de una computación, las variables pueden
ser substituidas por otros objetos.
Las variables se asumen cuantificadas
universalmente. La cuantificación existencial solo es
posible en las variables que aparecen en el cuerpo de
una cláusula.
Programas lógicos como matemáticas
Prolog acepta hechos y reglas como un conjunto de
axiomas.
El usuario plantea preguntas teoremas.
Prolog trata de probar este teorema, es decir,
demostrar que el teorema se sigue lógicamente de los
axiomas.
progenitor(pam,bob).
progenitor(tom,bob).
progenitor(tom,liz).
progenitor(bob,ann).
progenitor(bob,pat).
progenitor(pat,jim). hechos

mujer(pam).
mujer(liz).
mujer(pat).
mujer(ann). Predicados
hombre(tom).
hombre(bob).
hombre(jim).

vastago(Y,X) :- progenitor(X,Y).

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


Reglas
abuela(X,Y) :- progenitor(X,Z), progenitor(Z,Y), mujer(X).

hermana(X,Y) :- progenitor(Z,X), progenitor(Z,Y), mujer(X).


hermana(X,Y) :-
progenitor(Z,X),
progenitor(Z,Y),
mujer(X),
dif(X,Y).

tienehijo(X) :- progenitor(X,Y)

ancestro(X,Z) :- progenitor(X,Z).

ancestro(X,Z) :- progenitor(X,Y), ancestro(Y,Z).

tio(X,Y):-
primo(X,Y):-
sobrino(X,Y):-
cuñada(X,Y):-
Ejemplo: la carta de un restaurante
entrada(paella).
entrada(gazpacho).
entrada(consome).
carne(filete_de_cerdo).
carne(pollo_asado).
pescado(trucha).
pescado(bacalao).
postre(flan).
postre(nueces_con_miel).
postre(naranja).
 Definir la relación "plato_principal(X)" que indicara que un plato
principal es un plato de carne o de pescado.

plato_principal(X):- carne(X).
plato_principal(X):- pescado(X).

Definir la relación "comida(X,Y,Z)" que indicara que la comida consta


de tres platos, una entrada "X", un plato principal "Y" y un postre "Z".
Pidiéndole respuestas sucesivas a la pregunta ?- comida(X,Y,Z).
podemos generar todas las posibles comidas del restaurante.

comida(X, Y, Z):- entrada(X),


plato_principal(Y),
postre(Z).
¿Cómo se pregunta por las comidas con pescado sin
modificar el programa?
¿Cómo se pregunta por las comidas con naranja sin
modificar el programa?
 Para completar un poco la información que tenemos sobre las
comidas del restaurante vamos a mirar la lista de las calorías que
aporta cada plato:
 Una ración de paella aporta 200 calorías
 Una ración de gazpacho aporta 150 calorías
 Una ración de consomé aporta 300 calorías
 Una ración de filete de cerdo aporta 400 calorías
 Una ración de pollo asado aporta 280 calorías
 Una ración de trucha aporta 160 calorías
 Una ración de bacalao aporta 300 calorías
 Una ración de flan aporta 200 calorías
 Una ración de nueces con miel aporta 500 calorías
 Una ración de naranja aporta 50 calorías

 Definir la relacion "calorias(X,N)" que indicará que una ración de


"X" tiene "N" calorías.
calorias(paella, 200).
calorias(gazpacho, 150).
calorias(consome, 300).
calorias(filete_de_cerdo, 300).
calorias(pollo_asado, 280).
calorias(trucha, 160).
calorias(bacalao, 300).
calorias(flan, 200).
calorias(nueces_con_miel, 500).
calorias(naranja, 50).
Definir la relacion "valor_calorico(X,Y,Z,V)" que
indicará que la comida comida(X,Y,Z) suma en total
"V" calorías.
valor_calorico(X, Y, Z, V):- comida(X, Y, Z),
calorias(X, V1),
calorias(Y, V2),
calorias(Z, V3),
V is V1+V2+V3.
Definir la relación comida_equilibrada(X,Y,Z)" que
indicará que la comida comida(X,Y,Z) no supera las
800 calorías.
comida_equilibrada(X, Y, Z):-
valor_calorico(X, Y, Z, V),
V<800.
Términos
Constantes
 Números
 Átomos: se utilizan para dar nombre a objetos específicos.
 Cadenas formadas por letras, dígitos y el símbolo de

subrayado, deben empezar con una letra minúscula. Eje.


inteligencia, ia2, i_a2.
 Cadenas de caracteres encerrada entre comillas simples. Eje:

`Inteligencia Artificial`
Variables:
 cadenas formadas por letras, dígitos y el símbolo de
subrayado, deben empezar por una letra mayúscula o por un
símbolo de subrayado
Términos Compuestos (o estructuras)
Se construyen mediante un símbolo de función
(functor), que se denota mediante un átomo, seguido,
entre paréntesis, por una serie de términos separados
por comas, denominados argumentos.
 Ejemplos: fecha(1,mayo,2001), punto(X,Y)
Uso: listas
 Lista vacía []
 toda lista no vacía tiene una cabeza (que sería cualquier
término) y un resto (que sería una lista), y se representa
mediante un término compuesto de aridad 2, cuyo functor es
un punto. y cuyos argumentos son, respectivamente, la
cabeza y el resto de la lista.
 Ejemplo. .(a; []).
Operadores Aritméticos
Prolog es un lenguaje orientado a la manipulación
simbólica, por lo tanto el repertorio de operaciones
aritméticas suele ser limitado.
X+Y suma de X e Y
X-Y X menos Y
X*Y producto de X por Y
X/Y cociente real de la división de X por Y
X//Y cociente entero de la división de X por Y
X mod Y resto de la división entera de X por Y
abs(X) valor absoluto de X
sqrt(X) raíz cuadrada de X
Ejemplos de expresiones aritméticas
I. 3 +3 * 5
II. 3 mod 2
III. Y + 10 / 2
IV. 3/2+2*5
V. 6/2
VI. 6 div 2
VII. 50 + 10 / 3 mod 2
 En prolog las expresiones no se evalúan automáticamente,
contrariamente a lo que sucede en otros lenguajes, es preciso
forzar su evaluación mediante el operador ‘is’ (operador infijo
binario)
 Dado un objetivo
‘?-Expresion1 is Expresion2’
Expresiones Aritméticas
 Ejemplo
?- X is 3 + 2 * 5.
X=13
?- X is 3 / 2 + 2 * 5.
X=11.500000 Se produce el error
?- X is 6 div 2. porque la variable y no
X= 3 esta instanciada en el
momento en que se
?- X is 3 mod 2
evalúa la expresión
X= 1
?- X is 6 / 2.
X=3.0
?- X is 50 + 10 / 3 mod 2.
X= 60.0
?- X is Y + 10 / 2.
Illegal argument to is.
_1<Illegal arg> : (1:0) _0 is _1 + 10 / 2. : a
“is”
Su uso puede dar lugar a un error en los dos
siguientes casos:
cuando la parte derecha no es una expresión
aritmética:
 ?- X is a+1.
{DOMAIN ERROR: _157 is a+1 - arg 2: expected
expression, found a}
cuando la parte derecha es una expresión
aritmética pero no se puede evaluar:
 ?-X is 4*Z.
 {INSTANTIATION ERROR: _157 is 4*_155 - arg 2}
Salvo en los casos anteriores, el resultado del predicado
dependería de si la parte izquierda unifica o no con el
resultado obtenido al evaluar la parte derecha:
Comparaciones Aritméticas
 X =:= Y cierto si los valores numéricos de X e Y son iguales
 X =\= Y cierto si los valores numéricos de X e Y son distintos
 X < Y cierto si el valor numérico de X es menor que el de Y
 X =< Y cierto si el valor numérico de X es menor o igual que el
de Y
 X > Y cierto si el valor numérico de X es mayor que el de Y
 X >= Y cierto si el valor numérico de X es mayor o igual que el
de Y
Ejemplos:
Obtener el mayor de 2 números.
maximo(X,Y,X) :- X >= Y.
maximo(X,Y,Y) :- X < Y.

 En Prolog está definida la función max(X,Y), que devuelve


el máximo de X e Y. Por ejemplo:

Obtener el factorial de un número N


La sucesión de fibonacci es 0,1,1,2,3,5,8,… escribir una
función fibonacci(X, Y), tal que Y es n-esimo elemento
de la sucesión.
Definir nota(X,Y) tal que X es la calificación correspondiente a
la Nota X; es decir, Y es suspenso Si X es menor que 5 , Y es
aprobado Si X es mayor o igual que 5 pero menor que 7 , Y es
notable si X es mayor que 7 pero menor que 9 e Y es
sobresaliente si X es mayor que 9 . Por ejemplo
Ejercicios:
Definir el Maximo de 3 números max3 (X,Y,Z,W), donde
W es el máximo de los 3.
?- max3 (3,7,12,Z).
Z= 12

Definir la relación MCD(X,Y,Z) tal que es Z es el máximo


común divisor de X e Y.
Comentarios
 Los comentarios en Prolog se escriben comenzando la línea con
un símbolo de porcentaje. Ejemplo:

% Hola, esto es un comentario.


% Y esto también.

 La variable anónima
 Existen variables sin nombre, y todas ellas se representan
mediante el símbolo de subrayado _.
 Aunque todas las variables anónimas se escriben igual, son
todas distintas.
 Es decir, mientras que dos apariciones de la secuencia de
caracteres Hola se refieren a la misma variable, dos apariciones
de la secuencia _ se refieren a variables distintas.
Entrada y Salida
Predicados para la E / S de términos (sobre el “stream”
por defecto):
read(X) lee un término y lo unifica con X (el término
debe terminar en punto).
write(T) escribe el término T (en particular,
write(‘texto’) para escribir texto).
display(T) escribe el término T (sin expandir los
operadores)
%lee un valor
lee(X) :- write('Introduzca un número: '), nl, read(X).

% imprime el cuadrado de un número


imprime(X) :- X2 is X*X, write('El cuadrado de '),
write(X), write(' es '), write(X2).

cuadrado :- lee(X), imprime(X).


Predicados para la E / S de caracteres (sobre el
“stream” por defecto):
get0(X) : lee un carácter y unifica su código con X.
get(X): análogo, pero salta los caracteres no imprimibles
(por ejemplo, los blancos) skip(Char):lee hasta
encontrar el carácter Char. Una llamada a get0(X) detrás
leerá el siguiente carácter a Char.
put(Char): escribe el carácter Char (o lo ejecuta si no es
imprimible).
Nl: produce una nueva línea.
tab(N): escribe N espacios en blanco.

También podría gustarte