Está en la página 1de 5

Universidad de Santiago de Chile

Facultad de Ingeniería
Departamento de Ingeniería Informática
Paradigmas de programación

Programando con relaciones

Como vimos en la clase pasada, un programa lógico es un conjunto de clásulas de


Horn. Sobre estas cláusulas podemos definir nuevas relaciones sobre las cuales
podemos hacer consultas. En este sentido, podemos pensar en un programa lógico
como una base de datos relacional, donde los hechos corresponden a la información
almacenada en tablas.

CONJUNCIÓN, DISYUNCIÓN Y NEGACIÓN


El siguiente ejemplo define un conjunto de hechos que relacionan a conductores con
trenes, así como qué conductores están habilitados para manejar los distintos tipos de
trenes de una red ferroviaria.

Hechos en Prolog para caracterizar la red ferroviaria

% Hechos
% Chofer y su especializacion
conductor(tipo_A, juan).
conductor(tipo_A, pedro).
conductor(tipo_B, rodrigo).
conductor(tipo_B, jose).
conductor(tipo_C, maria).

% trenes y su tipo: empresa_modelo


tren(alstom_A22, 24).
tren(alstom_A22, 29).
tren(alstom_A22, 43).
tren(caf_az32t, 44).
tren(caf_az32t, 55).

% especializacion y tipo
especialidad(tipo_A, alstom_A22).
especialidad(tipo_A, caf_az32t).
especialidad(tipo_B, alstom_A22).
especialidad(tipo_C, caf_az32t).

Se pueden realizar las siguientes consultas:

 ¿De qué tipo es el tren ID = 29?

Ya hemos estudiado este tipo de consulta. Tenemos dos posibilidades:

1
Unidad 2 – Programación lógica 2-2013
Universidad de Santiago de Chile
Facultad de Ingeniería
Departamento de Ingeniería Informática
Paradigmas de programación
% Al hacer la sustitución de TIPO por alstom_A22, la aserción es
% verdadera.
tren(TIPO, 29).
% Al hacer la sustitución de TIPO por alstom_A22 (Y) TREN por 29 la
% aserción es verdadera.
tren(TIPO, TREN), TREN=29.

En la segunda aserción se puede apreciar el operador conjunción (AND) el cual, como


ya hemos visto en la clase anterior, se denota con el símbolo coma (,).

 ¿Cuáles conductores pueden manejar los trenes de tipo A?

conductor(tipo_A, PERSONA).
conductor(TIPO, PERSONA), TIPO=tipo_A.

 ¿Cuáles conductores pueden manejar los trenes de tipo A y B?

Para resolver esta consulta introducimos el operador disyunción (OR) el cual


corresponde al símbolo punto y coma (;). Note el uso de paréntesis en la cláusula.

conductor(TIPO, PERSONA), (TIPO=tipo_A; TIPO=tipo_B).

Por otro lado, también podemos definir una nueva cláusula que responda la pregunta
anterior:

tipo_AyB(CONDUCTOR):-
conductor(tipo_A, CONDUCTOR);
conductor(tipo_B, CONDUCTOR).

 ¿Qué conductores no pueden manejar los trenes CAF?

Podemos construir la pregunta utilizando el operador negación (NOT):

conductor(TIPO, PERSONA), not(especialidad(TIPO, caf_az32t)).

¿Cómo sería la cláusula?

RELACIONES ARITMÉTICAS
Es posible definir relaciones aritméticas las cuales pueden ser comparadas con los
operadores booleanos. Supongamos que la aserción punto(X, Y) representa al par
ordenado (x, y), un punto en un espacio bidimensional.

2
Unidad 2 – Programación lógica 2-2013
Universidad de Santiago de Chile
Facultad de Ingeniería
Departamento de Ingeniería Informática
Paradigmas de programación
origen(punto(X, Y)):-
X=0, Y=0.

pertenece(punto(X,Y), R):-
X*X+Y*Y<R*R.

Supongamos que la aserción punto está definida para X e Y enteros. En la primer


cláusula, origen será verdadero si X=0 e Y=0 son verdaderas. En la segunda cláusula,
pertenece será verdadero si se cumple la desigualdad triangular para un R dado.
Note que la cláusula no solo será verdadera cuando se cumplan la desigualdad, también
es necesario que X, Y y R sean valores numéricos para poder operar.

LISTAS Y RELACIONES RECURSIVAS


Para poder representar listas de elementos en lógica simbólica, podemos utilizar lo visto
en las primeras clases: Estructuras de datos recursivas. Para ello, debemos definir
relaciones que se definen a sí mismas.

Una lista es un caso especial de estructura o aserción. Está definida como la estructura
[X|Xs] donde X es la cabeza de la fila y Xs el resto o “cola” de la lista. El átomo [ ]
denota la lista vacía. Luego, una lista puede ser definida como una estructura recursiva:

[X1, X2, …, Xn] = [X1, [X2, …, [Xn, []] … ]]

Definamos cláusulas para buscar si un elemento pertenece a la lista:

contiene([X|Xs], X).
contiene([X|Xs], Y):-
contiene(Xs, Y).

Informalmente se puede decir que la primera cláusula es verdadera si X es un elemento


de la lista con cabeza X y resto Xs. de la misma manera, la segunda cláusula es
verdadera cuando Y es un elemento de la lista con cabeza X y resto Xs si Y es un
elemento de Xs.

Luego, para contiene([1, 2, 3], 3). ocurre lo siguiente:

 contiene([1, [2, [3, []]]], 3)


 contiene([2, [3, []]], 3)
 contiene([3, []], 3)
 true

Una vez alcanzado el caso base, se resuelven las relaciones pendientes.

3
Unidad 2 – Programación lógica 2-2013
Universidad de Santiago de Chile
Facultad de Ingeniería
Departamento de Ingeniería Informática
Paradigmas de programación

¿Qué ocurre si hacemos la consulta contiene([1, 2, 3], NUM).?

Ahora, definamos cláusulas para agregar un elemento a una lista:

agregar([], [ELEM], ELEM).


agregar([X|Xs], [X|Ys], ELEM):-
agregar(Xs, Ys, ELEM).

Al realizar la consulta agregar([1, 2, 3], L, 4). Prolog retorna L = [1, 2, 3, 4]. La


traza del programa sería la siguiente:

 agregar([1, [2, [3, []]]], [1|Ys], 4)


 agregar([2, [3, []]], [2|Ys], 4)
 agregar([3, []], [3|Ys], 4)
 agregar([], [4], 4)
 true

Luego se resuelven las relaciones pendientes:

Ys => [Y|Ys]
 [4]
 [3|[4, []]]
 [2|[3, [4, []]]]
 [1|[2, [3, [4, []]]]]
 [1, 2, 3, 4]

¿Qué ocurre si consultamos ([1, 2, 3], L, ELEM).? Explique.

THE CLOSED WORLD ASSUMPTION


El supuesto del mundo cerrado
Como podrá haber notado en los distintos ejemplos y en la práctica con Prolog, muchas
veces el resultado obtenido es falso. Sin embargo, dado que se cuenta con una cantidad
limitada de aserciones como hechos (como base de datos) es posible que muchas de
las consultas no puedan ser derivadas de las cláusulas. Prolog devolverá como
resultado falso, pero no necesariamente implica que se haya llegado a esa respuesta:
En otras palabras, cuando la consulta falla, significa que el resultado es desconocido o
falso.

Esto se conoce como el supuesto del mundo cerrado, donde una aserción es falsa
cuando no puede inferirse que es verdadera. Prolog asume que toda la información
relevante del problema se encuentra contenida en las cláusulas definidas por el
programador (el mundo).

4
Unidad 2 – Programación lógica 2-2013
Universidad de Santiago de Chile
Facultad de Ingeniería
Departamento de Ingeniería Informática
Paradigmas de programación

Suponga que definimos aserciones unarias para caracterizar planetas y satélites en el


sistema solar. Sobre esta base de conocimiento podemos definir la siguiente cláusula:

cometa (C) :-
not(planeta(C)), not(satelite(C)).

Luego, si hacemos la siguiente consulta:

cometa(cometa_halley).

¡Retornado verdadero solo por coincidencia! Dado el supuesto, y con aserciones unarias
solo para planetas y satélites, Prolog asume que si no es planeta y no es satélite,
entonces es cometa. Por lo anterior, se debe tener precaución en el sentido que se les
da a las cláusulas y como son escritas.

5
Unidad 2 – Programación lógica 2-2013

También podría gustarte