You are on page 1of 32

Prácticas de Lógica en aula informática (Curso 2010-11)

Práctica 1: Lógica y lenguaje Prolog, parte I.


Febrero: 10 y 17.

Práctica 2: Lógica y lenguaje Prolog, parte II.


Febrero: 24; Marzo: 3

Práctica 3: Lógica y lenguaje Prolog, parte III.


Marzo:10, 17

Práctica 4: Lógica y lenguaje Prolog, parte IV.


Marzo: 24, 31

Práctica 5: Deducción natural con ADN. Proposiciones.


Abril: 6, 14

Práctica 6: Deducción natural con ADN. Predicados.


Mayo: 5, 12

Nota: El trabajo realizado en cada práctica se deberá entregar al fina-


lizar la misma o con una demora máxima de 7 dı́as (por ejemplo, si una
práctica se realiza en Jueves el tiempo de entrega acaba a las 24 horas del
Miércoles siguiente).
La entrega se realizará exclusivamente a través del servidor belenus. No
se valorarán las entregas realizadas fuera de plazo, en disquetes o correo
electrónico, salvo que problemas técnicos impidieran la entrega a través del
servidor.
Los alumnos que no hayan asistido al menos a cinco prácticas informáti-
cas, o los que habiendo asistido hayan presentado soluciones incompletas o
incorrectas, deberán realizar en el examen final de prácticas, que se valo-
rará también hasta un máximo de un punto.
Los alumnos que no hayan aprobado las prácticas informáticas mediante
asistencia y entrega de las prácticas realizadas y hayan suspendido el exámen
final de prácticas informáticas podrán presentarse a la segunda convocatoria
(examen de Julio).
El actual sistema de evaluación no permite “guardar”las prácticas de un
curso al siguiente. De modo que el alumno que no hay superado la segunda
convocatoria si se matricula de nuevo en la asignatura se le aplicará de nuevo
el sistema de evalación descrito anteriormente.
Prácticas de Lógica en aula informática (Curso 2010-11) — Práctica 1

PROLOG Y EL LENGUAJE DE LA LÓGICA DE PRIMER ORDEN

1. Creando mi primer programa prolog


Vamos a realizar nuestro primer programa prolog (gprolog). Para ello,
utilizando la aplicación XGP, crea un documento que se llamará familia.pl

(NO TECLEES EL PROGRAMA EN LA CONSOLA)


(ACUERDATE DE ACABAR EN PUNTO LA LÍNEA)
(NO HAY ESPACIO BLANCO ANTES DEL PARÉNTESIS)

%Empezamos creando una base de datos con predicados monádicos:


mujer(maria).
mujer(laura).
mujer(teresa).
mujer(elena).
hombre(pablo).
hombre(juan).
hombre(luis).
hombre(carlos).

%Continuamos con predicados binarios (2-ádicos, 2-arios)


progenitor(pablo,juan).
progenitor(juan,luis).
progenitor(juan,maria).
progenitor(luis,carlos).
progenitor(luis,laura).
progenitor(laura,teresa).
progenitor(laura,elena).

%Ahora guarda el documento con el nombre de familia. La aplicación XGP


%creará un documento llamado familia.pl

2. Consultando mi primer programa


Utiliza ‘Open’ del menu ‘File’ para abrir el documento.
Si el código era correcto contesta en la consola con una expresión del si-
guiente tipo:
.../prolog/proyectos/familia.pl compiled, 27 lines read - 1203 bytes written,
14 ms
Si el codigo fuente no es correcto, en la consola aparece un mensaje de la
forma:
.../prolog/proyectos/familia.pl:8 error: syntax error: . or operator expected
after expression (char:1)
1 error(s)
compilation failed
Entonces en la ventana de edición puedes introducir el número de lı́nea,
el 8 en este caso, y después intentar corregir el error. Después de salvar el
documento, lo puedes reconsultar desde el menu ‘Tools’. Repite el proceso
hasta que se pueda compilar el programa.
Nota: Si se ha utilizado utilizado un editor externo, puede haber problemas
si no se ha creado un documento con finales de lı́nea de tipo UNIX.

3. Realizando consultas
Respuestas: Sı́ o no.
Tras compilar un programa desde el intérprete, se pueden realizar consultas
relacionadas con el programa. En la subventana superior introduce:
progenitor(juan, luis).
El la inferior se obtiene:
?- progenitor(juan, luis).
Success
Si se repite el proceso con
progenitor(juan, laura).
Se obtiene:
?- progenitor(juan, laura).
Failure
Consultas y variables
Si alguno de los atributos es una variable, el intérprete retornará los valo-
res que puede tomar para ser satisfecha. El nombre de una variable ha de
comenzar con mayúscula, o con guión bajo:
Si realizas la consulta
progenitor(juan,X).
El interface gráfico del interprete puede responder de varias formas: Pulsan-
do el botón ‘Once’ responde:
?- progenitor(juan,X).
X = luis
Pulsando el botón ‘First’ y a continuación pulsamos ‘Next’ dos veces se
obtiene
?-progenitor(juan,X)
Soln: 1
X = luis
;
Soln: 2
X = maria
;
No More Solutions.

El punto y coma hay que interpretarlo como el conector lógico ∨ . En este


caso significa que a la consulta realizada son soluciones la primera o (; , ∨)
la segunda. Se puede seguir pulsando ‘Next’ hasta que se agoten las posibles
soluciones. Si directamente pulsamos ‘All’, el interprete responde:
?- progenitor(juan,X).
Soln 1: Success
X = luis
Soln 2: Success
X = maria
Soln 3: No More Solutions.
Significa que hay dos soluciones y cuando intenta busca la tercera no en-
cuentra más soluciones.
Varias variables
En consultas con varias variables, se retornarán todas las combinaciones de
valores posibles. Si se realiza la consulta:
?- progenitor(X,Y).
se obtienen las soluciones:
?-progenitor(X,Y)
Soln: 1 X = pablo Y = juan ;
Soln: 2 X = juan Y = luis ;
Soln: 3 X = juan Y = maria ;
Soln: 4 X = luis Y = carlos ;
Soln: 5 X = luis Y = laura ;
Soln: 6 X = laura Y = teresa ;
Soln: 7 X = laura Y = elena ; No More Solutions.
Consultas con varios predicados
Es posible combinar varios predicados en la misma consulta. En este caso,
para satisfacer la consulta deberán satisfacerse todos ellos:
La consulta
progenitor(juan,Y), progenitor(Y,carlos).
es contestada ası́:
?- progenitor(juan,Y), progenitor(Y,carlos).
Soln 1: Success
Y = luis
;
No More Solutions.
Es importante observar que la coma es interpretada como el conector lógico
conjuntivo (y , ∧).
La pregunta (ATENCIÓN PONE PUNTO Y COMA)
progenitor(juan,Y) ; progenitor(Y,carlos).
es contestada del modo siguiente:
?- progenitor(juan,Y) ; progenitor(Y,carlos).
Soln 1: Success
Y = luis
Soln 2: Success
Y = maria
Soln 3: Success
Y = luis
;
No More Solutions.
En este caso el punto y coma es interpretado como el conector lógico dis-
yuntivo.
Ejercicios
Formula en prolog las siguientes consultas:
¿Quién es el progenitor de Luis?
¿Quién es el abuelo de Laura?
¿Quién es hermano de Carlos?
¿Quién es tı́o o tı́a de Carlos?

4. Reglas
Si tenemos una formula conteniendo variables libres que describen un domi-
nio finito, podemos considerar la tuplas que satisfacen dicha fórmula. Por
otro lado una fórmula implica otra si cada tupla que satisface la primera,
también satisface la segunda.
El el programa familia podrı́amos introducir todos los hechos inversos acerca
de quién es hijo de quién:
hijo(luis,juan).
hijo(maria,juan).
Una manera más sencilla serı́a introducir una regla:
Para todo X e Y, si X es progenitor de Y, entonces Y es hijo de X .
Que se formula como
∀X∀Y (progenitor(X, Y ) →hijo(Y, X)) .
En la sintaxis de prolog, lo que se hace es considerar la siguiente regla
asociada
hijo(Y,X):-progenitor(X,Y).
Notemos, que este tipo de programas prolog las variables toman finitos va-
lores buscando en la base de datos formada por los hechos.
Ahora tenemos dos opciones o ampliar nuestro documento familia con la
lı́nea anterior o crear un nuevo programa con la linea adicional. Si quieres
crea un nuevo documento ampliacion.pl con la regla anterior. Si consultas
ambos documentos familia.pl y apliacion.pl tendrás a tu disposición los he-
chos y reglas que contienen ambos. Por ejemplo, puedes consultar
hijo(X,juan).
Varios antecedentes
Si quieres distinguir hijo de hija lo puedes hacer utilizando la conjuncion de
varios antecedentes. Borra la lı́nea anterior de ampliacion.pl e introduce las
dos siguientes:
hija(Y,X) :- progenitor(X,Y),mujer(Y).
hijo(Y,X) :- progenitor(X,Y),hombre(Y).
Salva el documento y ahora realiza la consulta
hijo(X,juan).
La respuesta es
?- hijo(X,juan).
Success
X = luis
Es posible que obtengas otra respuesta. Puede deberse a que anteriormente
hijo(Y,X) estaba definido de otro modo. Si has (re) consultado el docu-
mento amplicacion.pl obtendrás la respuesta correcta, en otro caso seguirás
obteniendo la que tenı́as con la regla antigua.
Es interesante que te fijes si en la ventana ‘Evaluate Query ...’ esta activado
o no el botón ‘Consult Changes Before Evaluating ...’ . Si está activado XGP
se encarga de (re) consultar las reglas y hechos por si ha habido cambios.
Volviendo a la sintaxis de prolog, hay que observar que la conjunción de
predicados se expresa mediante comas y que los caracteres ‘:-’ corresponden
al conector condicional ← .
Por ejemplo, ahora puedes introducir el predicado binario (2-ario) hermano
mediante
hermano(X,Y) :- progenitor(Z,X), progenitor(Z,Y).
Ejercicios
Escribe en prolog: Todo aquel que tiene un hijo es feliz.
Define las relaciones “abuelo” y “nieto”
Describe (informalmente) cómo modificarı́as el predicado hermano para que
no saliera uno hermano de sı́ mismo.
En vez de conjunción de predicados se puede trabajar con disyunción de
predicados. Si queremos averiguar el universo que describen las variables,
podemos buscar los hechos descritos por predicados monádicos (1-arios) y
hacer la reunión de los dominios de cada predicado monádico (1-ario).
universo(X):-hombre(X); mujer(X).
Si en algún otro lugar de los documentos consultados o predicados predefi-
nidos en el sistema existe otra regla con cabeza (consecuente), universo(X),
el universo puede hacerse aún mayor de lo que permite la regla anterior.
Por ejemplo podemos considerar las dos reglas
trozouniverso(X):-hombre(X).
trozouniverso(X):-mujer(X).
Ahora la consultas
universo(X).
trozouniverso(X).
obendran idéntica respuesta.

Ejercicio para entregar. Amplia el programa familia.pl del modo siguien-


te:
a) Aumenta el número de hombres y mujeres que forman la base de hechos.
b) Introduce en la base de hechos algunos matrimonios (matrimonio/2)
d) Define los predicados binarios: suegro, suegra, yerno, nuera, cuñado,
cuñada.
e) Introduce en la base de hechos algunos divorcios y redefine el predicado
matrimonio.
f) Define los siguientes nuevos predicados: exmarido, exmujer, ....
Antes de entregar la práctica comprueba que el código fuente funciona co-
rrectamente.
Para la práctica 1 se entregaran en dos ficheros: memoria y código. Se entre-
gara utilizando la zona de envı́o del servidor belenus (http://belenus.unirioja.es/).
El código fuente entregado tendrá todo lo necesario para que se pueda eje-
cutar los diferentes procedimientos. El código deberá estar adecuadamente
comentado.
La memoria constará de las siguientes secciones:
1. Introducción (una hoja de descripción de lo que hay que hacer desde
vuestro punto de vista y no copiando el enunciado).
2. Descripción a alto nivel de lo realizado: qué predicados se han definido
qué problema resuelve cada uno de ellos y cómo se relacionan unos con otros,
etc
3. Código fuente completo con comentarios (el código final no deberı́a ser
muy largo)
4. Unas cuantas consultas y los resultados obtenidos
5. Conclusiones (qué se ha aprendido, dificultades encontradas, comentarios
sobre gprolog, etc).
Prácticas de Lógica en aula informática (Curso 2010-11) — Práctica 2

PROLOG Y PROGRAMACIÓN CON VARIABLES CON


RESTRICCIONES

5. Introducción a la programación con variables


de domino finito
Esta práctica explicará brevemente algunas funciones que se utilizan en
Gprolog para resolución de restricciones, veremos cómo se utilizan y unos
ejemplos resueltos para facilitar la comprensión.
Para trabajar con las funciones de dominio finito se necesita un nuevo tipo de
datos, estas son las variables FD que tienen asociado un dominio que acota
los valores que pueden tomar. Inicialmente este dominio comprende el rango
de 0..fd max integer, siendo la constante el valor máximo que puede tomar
la variable. Estas variables son totalmente compatibles con las variables y
enteros de prolog, si un predicado de restricciones espera una variable fd,
se le puede pasar una variable de prolog que tomara los valores de todo el
rango o un entero que sera considerado como un rango de un solo valor.
Vamos a describir los predicados FD más importantes que se han utilizado
en los problemas de ejemplo resueltos. Estos predicados son:
fd domain/2, fd domain/3
fd labeling/1, fd labeling/2
fd all different/1
Predicados : fd domain/2, fd domain/3
Los predicados fd domain restringen una variable a tomar valores dentro de
un dominio. Definiendo una restricción para una variable común de prolog
creamos una variable con un dominio finito (variable FD).
Veamos unos ejemplos:
fd domain/3
Este predicado se utilizará para definir variables con un dominio finito que
es un rango continuo.
fd domain(A,B,C)
A – variable FD
B – cota inferior del rango del dominio finito
C – cota superior del rango del dominio finito
Ejemplo: Queremos definir una variable con un dominio finito que es el rango
[5..25].

| ? fd_domain(VariableFD,5,25).
VariableFD = _#3(5..25)
(En la invocación al fd domain VariableFD era una variable normal, que
finalmente se mapea a una variable #3 con un dominio finito [5..25]. Aunque
ponga (5..25), los valores 5 y 25 forman parte del dominio.)
En el siguiente ejemplo vemos que fd domain establece restricciones sobre el
dominio y que su acción es consistente con otras restricciones que hayamos
podido definir antes.
Ejemplo: Definimos una restricción sobre la variable X, no puede tomar el
valor 5, con ello implı́citamente hemos declarado una variable FD con domi-
nio [0..4,6..127]. Para a continuación, agregar otra restricción con fd domain,
reduciendo el dominio de X a [0..4,6..10].

| ?X#\=5, fd_domain(X,1,10).
X = _#2(1..4:6..10)

fd domain/2
Este predicado se utilizará para definir variables con un dominio finito for-
mado por un conjunto de valores arbitrarios que se representarán por una
lista.
fd domain(A,B)
A – variable FD
B – lista de valores que representa el dominio
Ejemplo: Queremos definir una variable con un dominio finito que es el rango
[2..4]. Algo, que podı́amos tambien haber hecho con fd domain(VariableFD,2,4).

| ?fd_domain(VariableFD,[2,3,4]).
VariableFD = _#2(2..4)

Como curiosidad vemos que podemos definir el mismo rango, desordenando


los valores. El dominio resultante es el mismo que en el ejemplo anterior.

| ?fd_domain(VariableFD,[2,4,3]).
VariableFD = _#2(2..4)

Predicados : fd labeling/2, fd labeling/1


Aplicando el mecanismo de resolución de restricciones integrado en gprolog,
podemos encontrarnos en 3 escenarios:
– Se obtiene el dominio vacı́o para una o más variables FD. Esto signifi-
cará que el problema es insatisfactible.
– Los dominios de todas las variables FD se han reducido a un sólo elemento
(pueden ser valores distintos para cada variable). Esta situación se define
como “valuation domain”. De esta situación se deduce una asignación a las
variables que representa una solución del problema.
– No hay dominios vacı́os, pero algunos dominios tienen más de un elemento.
Esta situación no nos permite saber si el problema es satisfactible (en un
primer momento).
El tercer escenario da lugar a la conclusión de que el mecanismo de resolución
intergrado basado en restricciones sin más es incompleto. Necesitamos un
procedimiento que nos permita iterar sobre esos dominios multivaluados,
reduciendo en cada iteración el dominio de cada variable al sucesivo valor
y volviendo a propagar las restricciones esperando obtener un “valuation
domain”. Cada “valuation domain” representará una solución al problema.
Este procedimiento viene implementado en gprolog con el predicado fd labeling
(fd labeling/1 y fd labeling/2) (que por otro lado se puede programar fácil-
mente haciendo uso de varios predicados sencillos de fd, como fd dom). Con
el uso de fd labeling ya obtenemos un mecanismo de resolución de restric-
ciones sobre dominios finitos completo.
El predicado fd labeling/1 recibe como primer parámetro la lista con las va-
riables con dominio finito y prueba a asignar a cada variable un valor dentro
de su dominio y realiza backtracking sobre esas asignaciones permitiendo
encontrar todas las posibles soluciones.
Ejemplo: Tenemos un problema con dos variables A y B que tienen ambas
dominios de más de un elemento [1..3], a aparte de la restricción del dominio
a [1..3], también definimos por ejemplo que A debe ser distinta de B. La
resolución intergrada en gprolog basada sólo en restricciones, lo máximo
que ha podido es reducir los dominios de las variables a los que se ven [1..3],
pero no es capaz de proporcionarnos una respuesta concreta determinista.
Necesitamos que el dominio de cada variable se reduzca a un sólo valor,
obteniendo una asignación que representa una solución al problema.

| ?fd_domain([A,B],1,3),A#\=B.
A = _#3(1..3)
B = _#25(1..3)

Ahora aplicamos fd labeling sobre las lista de variables FD (A y B) y vemos


que se realiza un backtracking sobre la reducción de cada dominio a los suce-
sivos valores que lo formaban, en cada iteración se propagan las restricciones
en función de los monovalores concretos a los que quedan restringidas las
variables y se obtienen todas las soluciones.

| ?fd_domain([A,B],1,3),A#\=B, fd_labeling([A,B]).
A = 1
B = 2 ? ;
A = 1
B = 3 ? ;
A = 2
B = 1 ? ;
A = 2
B = 3 ? ;
A = 3
B = 1 ? ;
A = 3
B = 2

El orden de la selección de los valores a los que quedará reducido el dominio,


ası́ como por qué variable empezará la acción del etiquetado pueden tener un
efecto notable en el rendimiento de la búsqueda. El predicado fd labeling/2
permite definir con su segundo parámetro distintas estrategias para la se-
lección del valor y la variable. Algunas de estas estrategias son por ejemplo
empezar por las variables cuyo dominio es el más reducido de todos o por
las variables que intervienen en un mayor número de restricciones,... En
fd labeling/1 se omite la especificación de las estrategias lo que supone uti-
lizar las estrategias establecidas por defecto.
Para más información remitimos al manual de gprolog y el ejemplo del pro-
blema de resolución de Sudoku. Normalmente la metodologı́a más eficiente
para la definición de los predicados que resuelven un problema con res-
tricciones es generar las restricciones y despues aplicar el “etiquetado” con
fd labeling (“constrain and generate methodology”). El establecimiento de
restricciones hace que el solver basado en restricciones reduzca los dominios
de las variables como consecuencia de las mismas. Tras lo cual, el espacio
de valores sobre los que tendrá que trabajar fd labeling será normalmente
mucho menor.
fd all different/1
Este predicado sirve para establecer la restricción de que todas las variables
tomen valores distintos entre sı́. Como único parámetro recibe la lista con las
variables FD sobre las que se quiere establecer dicha restricción. Ejemplo:
Tenemos 3 (A,B,C) variables con rango [1:3] y queremos que tomen valores
distintos entre sı́ (A
=B and B
=C and A
=C).

| ?fd_domain([A,B,C],1,3),fd_all_different([A,B,C]),
fd_labeling([A,B,C]).
A = 1
B = 2
C = 3 ? ;
A = 1
B = 3
C = 2 ? ;
A = 2
B = 1
C = 3 ? ;
A = 2
B = 3
C = 1 ? ;
A = 3
B = 1
C = 2 ? ;
A = 3
B = 2
C = 1

Restricciones Aritméticas:
Son expresiones que representan funciones aritméticas compuestas por va-
riables o enteros y los operadores. Se pueden utilizar los siguientes, siendo
Exp$ donde $ es el número de la expresión FD que se utiliza:
“+ Exp1”: El mismo valor.
“- Exp1”: El valor opuesto.
“Exp1 + Exp2”: La suma de las 2 expresiones.
“Exp1 – Exp2”: La resta de las 2 expresiones.
“Exp1 * Exp2”: El producto de las 2 expresiones.
“Exp1 / Exp2”: El cociente de las 2 expresiones, solo se cumple si el resto
es 0.
“Exp1 ** Exp2”: La Exp1 elevada a Exp2, una de las 2 debe ser entera.
“min(Exp1, Exp2)”: El mı́nimo de las 2 expresiones.
“max(Exp1, Exp2)”: El máximo de las 2 expresiones.
“dist(Exp1, Exp2)”: La distancia entre las 2 expresiones, |Exp1–Exp2|.
“Exp1 // Exp2”: El cociente de la división entera de las expresiones.
“Exp1 rem Exp2”: El resto de la división entera de las expresiones.
“quot rem(Exp1,Exp2,R)”: Cociente de la división entera de las expresiones
devolviendo el resto en la variable R.
Las siguientes restricciones pueden utilizarse con arco consistencia completa
o parcial, se puede utilizar la parcial para reducir el dominio de las va-
riables complejas. Hay una menor propagación de las variables en la arco
consistencia parcial, pero aumenta la eficiencia y es mejor para las variables
aritméticas. Cuando se utiliza una arco consistencia completa es a la inver-
sa. Estos operadores se colocan entre las 2 expresiones como los operadores
aritméticos anteriores.

#= (#=# )Las expresiones deben ser iguales.


#\= (#\=#) Las expresiones deben ser diferentes.
#< (#<#) La primera expresión debe ser menor ala segunda.
#=< (#=<#) La primera expresión debe ser menor o igual a la segunda.
#> (#>#) La primera expresión debe ser mayor a lasegunda.
#>= (#>=#) La primera expresión debe ser mayor o igual a la segunda.

Ejemplos:
| ?A#\= 5, B#>=6, A#>=B+7.
A = _#2(13..127@)
B = _#27(6..120)

| ?A#\= 5, B#>=6, A#>=B.


A = _#2(6..127@)
B = _#27(6..127)

6. Un programa para resolver sudokus

% Sudoku
%
% (para GNU Prolog)
%
% versión en castellano de un program prolog realizado de Jerome Cornet
%

% --------------------------------------

%El objetivo de este program prolog es definir el siguiente predicado/81.


%Se trata de compilar el programa y realizar una consulta que sustiya las
%correspondientes variables por los valores conocidos del sudoku que queremos
%resolver. La respuesta a la consulta será la solución del sudoku

%sudoku(A1, A2, A3, A4, A5, A6, A7, A8, A9,


% B1, B2, B3, B4, B5, B6, B7, B8, B9,
% C1, C2, C3, C4, C5, C6, C7, C8, C9,
% D1, D2, D3, D4, D5, D6, D7, D8, D9,
% E1, E2, E3, E4, E5, E6, E7, E8, E9,
% F1, F2, F3, F4, F5, F6, F7, F8, F9,
% G1, G2, G3, G4, G5, G6, G7, G8, G9,
% H1, H2, H3, H4, H5, H6, H7, H8, H9,
% I1, I2, I3, I4, I5, I6, I7, I8, I9)

% por ejemplo, si se consulta


%sudoku(A1, 2, A3, A4, 6, 7, 8, 4, A9,
% 4, B2, B3, B4, B5, B6, 3, 5, B9,
% 5, 9, C3, C4, C5, C6, C7, C8, C9,
% D1, 1, 4, D4, D5, D6, 5, D8, 8,
% E1, E2, E3, 4, E5, E6, 9, 2, 7,
% 6, F2, F3, F4, F5, 5, 4, 1, F9,
% 9, G2, 6, 7, 4, 2, G7, 8, 5,
% H1, 5, 1, 6, 8, 3, 2, H8, 4,
% I1, I2, 2, I4, I5, 1, 7, 3, I9).
%Se obtiene como respuesta (en la consola)

%-------------------------
%| 1 2 3 | 5 6 7 | 8 4 9 |
%| 4 6 7 | 1 9 8 | 3 5 2 |
%| 5 9 8 | 2 3 4 | 6 7 1 |
%-------------------------
%| 2 1 4 | 3 7 9 | 5 6 8 |
%| 3 8 5 | 4 1 6 | 9 2 7 |
%| 6 7 9 | 8 2 5 | 4 1 3 |
%-------------------------
%| 9 3 6 | 7 4 2 | 1 8 5 |
%| 7 5 1 | 6 8 3 | 2 9 4 |
%| 8 4 2 | 9 5 1 | 7 3 6 |
%-------------------------

% X es una variable con dominio finito (fd) que toma valores enteros del 1 al 9.

validez(X) :- fd_domain(X, 1, 9).

%Comprueba que dos elementos cualquiera de la lista L son distinto entre sı́.

todosdistintos(L) :- fd_all_different(L).
%---------------------------------------
% fila toma una lista de nueve términos y los escribe
%en una fila separados de tres en tres.

fila(X1, X2, X3, X4, X5, X6, X7, X8, X9) :-


write(’| ’),
write(X1), write(’ ’), write(X2), write(’ ’), write(X3), write(’ | ’), write(X4),
write(’ ’), write(X5), write(’ ’), write(X6), write(’ | ’), write(X7), write(’ ’),
write(X8), write(’ ’), write(X9), write(’ |’), nl.
%Escribe una lı́nea horizontal con giones.
lineahorizontal :- write(’-------------------------’), nl.

% cuadrodesudoku escribe un 81 terminos en un cuadro


%de 9 por 9 dividos en cuadraditos 3 por 3.

cuadrodesudoku(A1, A2, A3, A4, A5, A6, A7, A8, A9,


B1, B2, B3, B4, B5, B6, B7, B8, B9,
C1, C2, C3, C4, C5, C6, C7, C8, C9,
D1, D2, D3, D4, D5, D6, D7, D8, D9,
E1, E2, E3, E4, E5, E6, E7, E8, E9,
F1, F2, F3, F4, F5, F6, F7, F8, F9,
G1, G2, G3, G4, G5, G6, G7, G8, G9,
H1, H2, H3, H4, H5, H6, H7, H8, H9,
I1, I2, I3, I4, I5, I6, I7, I8, I9) :-

nl,
lineahorizontal,
fila(A1, A2, A3, A4, A5, A6, A7, A8, A9),
fila(B1, B2, B3, B4, B5, B6, B7, B8, B9),
fila(C1, C2, C3, C4, C5, C6, C7, C8, C9),
lineahorizontal,
fila(D1, D2, D3, D4, D5, D6, D7, D8, D9),
fila(E1, E2, E3, E4, E5, E6, E7, E8, E9),
fila(F1, F2, F3, F4, F5, F6, F7, F8, F9),
lineahorizontal,
fila(G1, G2, G3, G4, G5, G6, G7, G8, G9),
fila(H1, H2, H3, H4, H5, H6, H7, H8, H9),
fila(I1, I2, I3, I4, I5, I6, I7, I8, I9),
lineahorizontal.

%---------------------------------------

%sudoku: Primero hace que las 81 variables tengan dominio finito de enteros entre 1 y 9.
%El predicado fd_labeling/1 recibe como primer parámetro la lista con las variables
%con dominio finito y prueba a asignar a cada variable un valor dentro de su
%dominio y realiza backtracking sobre esas asignaciones permitiendo encontrar
%todas las posibles soluciones. Una vez encontrada la solución
%la visualiza en un cuadrado de sudoku

sudoku(A1, A2, A3, A4, A5, A6, A7, A8, A9,


B1, B2, B3, B4, B5, B6, B7, B8, B9,
C1, C2, C3, C4, C5, C6, C7, C8, C9,
D1, D2, D3, D4, D5, D6, D7, D8, D9,
E1, E2, E3, E4, E5, E6, E7, E8, E9,
F1, F2, F3, F4, F5, F6, F7, F8, F9,
G1, G2, G3, G4, G5, G6, G7, G8, G9,
H1, H2, H3, H4, H5, H6, H7, H8, H9,
I1, I2, I3, I4, I5, I6, I7, I8, I9) :-

% tous les nombres compris entre 1 et 9


validez(A1), validez(A2), validez(A3),
validez(A4), validez(A5), validez(A6),
validez(A7), validez(A8), validez(A9),
validez(B1), validez(B2), validez(B3),
validez(B4), validez(B5), validez(B6),
validez(B7), validez(B8), validez(B9),
validez(C1), validez(C2), validez(C3),
validez(C4), validez(C5), validez(C6),
validez(C7), validez(C8), validez(C9),
validez(D1), validez(D2), validez(D3),
validez(D4), validez(D5), validez(D6),
validez(D7), validez(D8), validez(D9),
validez(E1), validez(E2), validez(E3),
validez(E4), validez(E5), validez(E6),
validez(E7), validez(E8), validez(E9),
validez(F1), validez(F2), validez(F3),
validez(F4), validez(F5), validez(F6),
validez(F7), validez(F8), validez(F9),
validez(G1), validez(G2), validez(G3),
validez(G4), validez(G5), validez(G6),
validez(G7), validez(G8), validez(G9),
validez(H1), validez(H2), validez(H3),
validez(H4), validez(H5), validez(H6),
validez(H7), validez(H8), validez(H9),
validez(I1), validez(I2), validez(I3),
validez(I4), validez(I5), validez(I6),
validez(I7), validez(I8), validez(I9),

% distintos en cada fila


todosdistintos([A1, A2, A3, A4, A5, A6, A7, A8, A9]),
todosdistintos([B1, B2, B3, B4, B5, B6, B7, B8, B9]),
todosdistintos([C1, C2, C3, C4, C5, C6, C7, C8, C9]),
todosdistintos([D1, D2, D3, D4, D5, D6, D7, D8, D9]),
todosdistintos([E1, E2, E3, E4, E5, E6, E7, E8, E9]),
todosdistintos([F1, F2, F3, F4, F5, F6, F7, F8, F9]),
todosdistintos([G1, G2, G3, G4, G5, G6, G7, G8, G9]),
todosdistintos([H1, H2, H3, H4, H5, H6, H7, H8, H9]),
todosdistintos([I1, I2, I3, I4, I5, I6, I7, I8, I9]),

% distintos en cada subcuadrado 3x3


todosdistintos([A1, A2, A3, B1, B2, B3, C1, C2, C3]),
todosdistintos([D1, D2, D3, E1, E2, E3, F1, F2, F3]),
todosdistintos([G1, G2, G3, H1, H2, H3, I1, I2, I3]),
todosdistintos([A4, A5, A6, B4, B5, B6, C4, C5, C6]),
todosdistintos([D4, D5, D6, E4, E5, E6, F4, F5, F6]),
todosdistintos([G4, G5, G6, H4, H5, H6, I4, I5, I6]),
todosdistintos([A7, A8, A9, B7, B8, B9, C7, C8, C9]),
todosdistintos([D7, D8, D9, E7, E8, E9, F7, F8, F9]),
todosdistintos([G7, G8, G9, H7, H8, H9, I7, I8, I9]),

% distintos en cada columna


todosdistintos([A1, B1, C1, D1, E1, F1, G1, H1, I1]),
todosdistintos([A2, B2, C2, D2, E2, F2, G2, H2, I2]),
todosdistintos([A3, B3, C3, D3, E3, F3, G3, H3, I3]),
todosdistintos([A4, B4, C4, D4, E4, F4, G4, H4, I4]),
todosdistintos([A5, B5, C5, D5, E5, F5, G5, H5, I5]),
todosdistintos([A6, B6, C6, D6, E6, F6, G6, H6, I6]),
todosdistintos([A7, B7, C7, D7, E7, F7, G7, H7, I7]),
todosdistintos([A8, B8, C8, D8, E8, F8, G8, H8, I8]),
todosdistintos([A9, B9, C9, D9, E9, F9, G9, H9, I9]),

% busca todas las soluciones posibles


fd_labelingff([A1, A2, A3, A4, A5, A6, A7, A8, A9,
B1, B2, B3, B4, B5, B6, B7, B8, B9,
C1, C2, C3, C4, C5, C6, C7, C8, C9,
D1, D2, D3, D4, D5, D6, D7, D8, D9,
E1, E2, E3, E4, E5, E6, E7, E8, E9,
F1, F2, F3, F4, F5, F6, F7, F8, F9,
G1, G2, G3, G4, G5, G6, G7, G8, G9,
H1, H2, H3, H4, H5, H6, H7, H8, H9,
I1, I2, I3, I4, I5, I6, I7, I8, I9]),

% visualiza en un cuadrado la solución encontrada


cuadrodesudoku(A1, A2, A3, A4, A5, A6, A7, A8, A9,
B1, B2, B3, B4, B5, B6, B7, B8, B9,
C1, C2, C3, C4, C5, C6, C7, C8, C9,
D1, D2, D3, D4, D5, D6, D7, D8, D9,
E1, E2, E3, E4, E5, E6, E7, E8, E9,
F1, F2, F3, F4, F5, F6, F7, F8, F9,
G1, G2, G3, G4, G5, G6, G7, G8, G9,
H1, H2, H3, H4, H5, H6, H7, H8, H9,
I1, I2, I3, I4, I5, I6, I7, I8, I9).

Practica 2: Utilizando Prolog y si preferiblemente variables con restricciones


escribe un programa para resolver el siguiente puzle de la cebra.
Para la práctica 2 se entregaran en dos ficheros: memoria y código. Se entre-
gara utilizando la zona de envı́o del servidor belenus (http://belenus.unirioja.es/).
El código fuente entregado tendrá todo lo necesario para que se pueda eje-
cutar los diferentes procedimientos. El código deberá estar adecuadamente
comentado.
La memoria constará de las siguientes secciones:
1. Introducción (una hoja de descripción de lo que hay que hacer desde
vuestro punto de vista y no copiando el enunciado).
2. Descripción a alto nivel de lo realizado: qué predicados se han definido
qué problema resuelve cada uno de ellos y cómo se relacionan unos con otros,
etc
3. Código fuente completo con comentarios (el código final no deberı́a ser
muy largo)
4. Unas cuantas consultas y los resultados obtenidos
5. Conclusiones (qué se ha aprendido, dificultades encontradas, comentarios
sobre gprolog, etc).
Modelar y resolver el Puzle de la Cebra: cinco personas de diferente na-
cionalidad viven en cinco casas de la misma calle. Estas personas tienen
profesiones distintas, y cada una de ellas tiene una bebida favorita y un
animal favorito, todos distintos. Las cinco casas están pintadas de colores
distintos. Se conocen los siguientes hechos:
a. La persona inglesa vive en una casa roja.
b. La persona española tiene un perro.
c. La persona japonesa pinta como profesión.
d. La persona italiana bebe té.
e. La persona noruega vive en la primera casa.
f. El dueño de la casa verde bebe café.
g. La casa verde va a continuación de la casa blanca.
h. El escultor crı́a caracoles.
i. El diplomático vive en la casa amarilla.
j. Se bebe leche en la tercera casa.
k. La casa de la persona noruega está al lado de la casa azul.
l. El violinista bebe zumo.
m. El zorro está en la casa de al lado del doctor.
n. El caballo está en la casa de al lado del diplomático.
o. La cebra está en la casa verde.
p. Una de las personas bebe agua.
El programa debe responder a la siguiente pregunta: ¿Quién vive en cada
casa?
Prácticas de Lógica en aula informática (Curso 2010-11) — Práctica 3

MODELOS CONSECUENCIA LÓGICA E INCONSISTENCIA

Modelos de una proposición

%Funciones auxiliares pertenece y concatena.


%concatena(A,B,C) se verifica si C es la lista A seguida de la lista B
concatena([],L,L).
concatena([X|L1], L, [X|L2]):-concatena(L1,L,L2).
%pertenece(X,L) se verifica si X está en la lista L
pertenece(X,[X|L]).
pertenece(X,[ |L]):-pertenece(X,L).
%Funciones para calcular el valor de verdad de una proposición.
%Hay dos valores de verdad.
%Se definen cuatro operadores/conectores mediante sus tablas de verdad
valor de verdad(0).
valor de verdad(1).
%Declaración de los operadores lógicos
:-op(610,fx,no).
:-op(620,xfy, y).
:-op(630,xfy,o).
:-op(640,xfy,im).
:-op(650,xfy,sii).
funcion de verdad(no,1,0).
funcion de verdad(no,0,1).
funcion de verdad(y,1,1,1).
funcion de verdad(y,1,0,0).
funcion de verdad(y,0, ,0).
funcion de verdad(o,1, ,1).
funcion de verdad(o,0,1,1).
funcion de verdad(o,0,0,0).
funcion de verdad(im,1,1,1).
funcion de verdad(im,1,0,0).
funcion de verdad(im,0, ,1).
funcion de verdad(sii,X,X,1).
funcion de verdad(sii,1,0,0).
funcion de verdad(sii,0,1,0).
%Este es un modo alternativo de definir la función pertenece.
comprueba pertenece(X,[X| ]):-!.
comprueba pertenece(X,[ |L]):-comprueba pertenece(X,L).
%Valor de una fórmula en una interpretacion.
valor(F,I,V):-comprueba pertenece((F,V),I).
valor(no A, I, V):-valor(A,I,VA), funcion de verdad(no, VA,V).
valor(F,I,V):-F=..[Op,A,B], valor(A,I,VA), valor(B,I,VB),
funcion de verdad(Op,VA,VB,V).
%La relación interpretaciones formula(F,L) se verifica si L es el conjunto
%de todas las interpretaciones de la fórmula F.
interpretaciones formula(F,U) :- findall(I,interpretacion formula(I,F),U).
%findall(+T, +O, -S) Se verifica si la lista de todos los T que satisfacen el
%objetivo O es la misma que la lista de resultados S.
%La relación interpretacion formula(I,F) se verifica si I es una
%interpretación de la formula F.
interpretacion formula(I,F):-simbolos formula(F,U),
interpretacion simbolos(U,I).
%simbolos formula(F,U) se verifica si U es el conjunto ordenado de los
%sı́mbolos proposicionales de F
%interpretacion simbolos(L,I) se verifica si I es una interpretación de la
%lista de átomos L
simbolos formula(F,U):-simbolos formula aux(F,U1), sort(U1,U).
%sort(+Lista, -Ordenados) Se satisface si Ordenados es la lista que
%resulta al ordenar los miembros de Lista y además removiemdo los
%elementos duplicados.
simbolos formula aux(F,[F]):- atom(F).
simbolos formula aux(no F,U):-simbolos formula aux(F,U).
simbolos formula aux(F,U):- F=..[ Op,A,B],
simbolos formula aux(A,UA), simbolos formula aux(B,UB),
concatena(UA,UB,U).
interpretacion simbolos([],[]).
interpretacion simbolos([A|L],[(A,V)|IL]):- valor de verdad(V),
interpretacion simbolos(L,IL).
%La relacion es modelo formula(I,F) se verifica si la interpretación I es un
%modelo de F.
es modelo formula(I,F):- valor(F,I,V), V=1.
%Los modelos principales de un fórmula son las interpretaciones
%principales de F que son modelos de F.
%modelos formula(+F,-L) se verifica si L es el conjunto de los modelos
%principales de una fórmula F.
modelo formula(I,F):-interpretacion formula(I,F), es modelo formula(I,F).
modelos formula(F,L):-findall(I,modelo formula(I,F),L1), sort(L1,L).
%es satisfacible(+F) se verifica si F tiene un modelo.
es satisfacible(F):-interpretacion formula(I,F), es modelo formula(I,F).
%contramodelos es una interpretación tal que I(F)=0.
contramodelo formula(I,F):- interpretacion formula(I,F),
\+ es modelo formula(I,F).
%F es válida es lo mismo que F es tautologı́a
es tautologia(F):- \+ contramodelo formula( I,F).

Modelos de un conjunto de proposiciones

%Simbolos comjunto(+S,?U) se verifica si U es el conjunto ordenado de lod


%sı́mbolos proposiocinales de las proposiciones de S
simbolos conjunto(S,U):- simbolos conjunto aux(S,U1), sort(U1,U).
simbolos conjunto aux([],[]).
simbolos conjunto aux([F|S],U):- simbolos formula(F,A),
simbolos conjunto aux(S,B), concatena(A,B,U).
%interpretacion conjunto(?I, +S) se verifica si I es una interpretación del
%conjunto de fórmulas S
interpretacion conjunto(I,S):- simbolos conjunto(S,U),
interpretacion simbolos(U,I).
%Interpretaciones conujunto(+S,-L) se verifica si L es el conjunto de todas
%las interpretaciones principales de un conjunto de proposiciones S.
interpretaciones conjunto(S,U):-findall(I,interpretacion conjunto(I,S), U).
%La relación es modelo conjunto(+I,+S) se verifica si la interpretación I
%es modelo del conjunto de fórmulas S.
es modelo conjunto(I,[]).
es modelo conjunto(I,[F|S]):- es modelo formula(I,F),
es modelo conjunto(I,S).
%modelo conjunto(?I,+S) se verifica si I es un modelo principal de un
%conjunto de fórmulas S
modelo conjunto(I,S):- interpretacion conjunto(I,S),
es modelo conjunto(I,S).
%modelos conjunto(S,L) se verifica si L es el conjunto de modelos del
%conjunto de formulas S
modelos conjunto(S,L):- findall(I,modelo conjunto(I,S), L).
%consistente(S) se verifica si al menos tiene un modelo.
consistente(S):- modelo conjunto( I,S),!.
%inconsistente((S) se verifica si el conjunto S de proposiciones no tiene
%modelos.
inconsistente(S):- \+ modelo conjunto( I,S).
%es consecuencia(S,F) se verifica si F es una consecuencia del conjunto de
%fórmulas S
es consecuencia(S,F):- inconsistente([ no F|S]).

Resolución

complementario(no A,A):- !.
complementario(A, no A).
resolvente(C1,C2,C):- pertenece(L1,C1),
complementario(L1,L2), pertenece(L2,C2),
delete(C1, L1, C1P), delete(C2, L2, C2P),
concatena(C1P, C2P, C3), sort(C3,C).
apply(Termino,Lista) :- Termino =..[Pred|Arg1],
concatena(Arg1,Lista,Arg2),
Atomo =.. [Pred|Arg2], Atomo.
maplist( ,[],[]).
maplist(R,[X1|L1],[X2|L2]) :- apply(R,[X1,X2]), maplist(R,L1,L2).
refutacion(S,R):- maplist(sort,S,S1), refutacion aux(S1,R).
refutacion aux(S,R) :-pertenece([],S), !, reverse(S,R).
refutacion aux(S,R) :-pertenece(C1,S), pertenece(C2,S),
resolvente(C1,C2,C), \+ pertenece(C, S),
%format(’ N w resolvente de w y w n’,[C,C1,C2]),
refutacion aux([C|S],R).
Prácticas de Lógica en aula informática (Curso 2010-11) — Práctica 4

Pequeño manual de lp.lp


Este programa prolog puede ser utilizado para el calculo de proposiciones.
Se utiliza la siguiente sintaxis
¬ ∧ ∨ → ↔
no y o im sii
y el orden de la tabla indica el orden de precedencia de los conectores utili-
zados.
Ejemplo.
La proposición b ↔ ((a ∧ c) → (b ∨ c) le corresponde
b sii a y c im b o c
Recordamos a continuación los principales functores del programa con la
descripción de las propiedades que se deben satisfacer para poderse verificar.
interpretaciones formula(F,L). La relación interpretaciones formula(F,L)
se verifica si L es el conjunto de todas las interpretaciones de la fórmula F.
Ejemplo.
?- interpretaciones formula(b sii (a y c im b y c y (no a)),L). Success
L = [[(a, 0), (b, 0), (c, 0)], [(a, 0), (b, 0), (c, 1)], [(a, 0), (b, 1), (c, 0)], [(a,
0), (b, 1), (c, 1)], [(a, 1), (b, 0), (c, 0)], [(a, 1), (b, 0), (c, 1)], [(a, 1), (b, 1),
(c, 0)], [(a, 1), (b, 1), (c, 1)]]
interpretacion formula(I,F). La relación interpretacion formula(I,F) se
verifica si I es una interpretación de la fórmula F.
Ejemplo.
?- interpretacion formula([(a, 0), (b, 0), (c, 0)],b sii a y c im b y c y no a).
Success
simbolos formula(F,U). Se verifica si U es el conjunto ordenado de los
sı́mbolos proposicionales de F
Ejemplo.
?- simbolos formula(b sii a y c im b y c y no a, S).
Success
S = [a, b, c]
es modelo formula(I,F). La relacion es modelo formula(I,F) se verifica si
la interpretación I es un modelo de F.
Ejemplo.
?- es modelo formula([(a, 0), (b, 0), (c, 0)],b sii a y c im b y c y no a).
Failure
modelos formula(+F,-L). Se verifica si L es el conjunto de los modelos
principales de una fórmula F. A veces se utiliza la notación +F para indicar
que es una entrada (un término sin variables libre) y con -L la salida.
Ejemplo.
?- modelos formula(b sii (a y c im b y c y (no a)),L).
Success
L = [[(a, 0), (b, 1), (c, 0)], [(a, 0), (b, 1), (c, 1)], [(a, 1), (b, 0), (c, 1)], [(a,
1), (b, 1), (c, 0)]]
es satisfacible(+F) Se verifica si F tiene un modelo.
Ejemplo.
?- es satisfacible(b sii (a y c im b y c y (no a))).
Success
contramodelo formula(I,F). Se satisface si I es una interpretación de la
fórmula F tal que I(F)=0.
es tautologia(F). Se verifica si F es una tautologı́a.
Existen los análogos de los funtores anteriores para conjuntos de formulas
interpretaciones conjunto(S,L). La relación interpretaciones conjunto(S,L)
se verifica si L es el conjunto de todas las interpretaciones del conjunto de
fórmulas S. Se consideran todos los diferentes átomos que aparecen en las
diversas fórmulas de S.
interpretacion conjunto(I,S). La relación interpretacion conjunto(I,S) se
verifica si I es una interpretación de alguna fórmula del conjunto S.
simbolos conjunto(S,U). Se verifica si U es el conjunto ordenado de los
sı́mbolos proposicionales de las fórmulas de S.
es modelo conjunto(I,S). La relacion es modelo conjunto(I,F) se verifica
si la interpretación I es un modelo de cada una de las fórmulas del conjunto
S.
modelos conjunto(+S,-L). Se verifica si L es el conjunto de los modelos
principales de la lista de fórmulas S.
consistente(S). Se verifica si al menos tiene un modelo.
inconsistente(S). Se verifica si el conjunto S de proposiciones no tiene
modelos.
es consecuencia(S,F). Se verifica si F es una consecuencia del conjunto
de fórmulas S
refutacion(+S,-R). La relación refutacion(+S,-R) se verifica si R es una
refutación por resolución del conjunto de cláusulas S. Una cláúsula se intro-
duce como una lista de literales, un átomo o su negación.
Ejemplos:
?- refutacion([[no p,no q],[p,q],[no p,q],[no q,p]],R). R = [[p, no q],[q,no
p],[p,q],[no p,no q], [q,no q],[p,no p],[no p],[q],[p],[]]
Success
?- refutacion([[p,q],[-p,q],[-q,p]],R).
Failure
Aplicaciones del razonamiento proposicional
Vamos aplicar los procedimientos anteriores a la resolución de problemas.

1. El problema de los veraces y los mentirosos. En una isla hay


dos tribus, la de los veraces (que siempre dicen la verdad) y la de los
mentirosos (que siempre mienten). Un viajero se encuentra con tres
isleños A, B y C y cada uno le dice una frase:
A dice “B y C son veraces sii C es veraz”
B dice “Si A y C son veraces, entonces B y C son veraces y A es
mentiroso”
C dice “B es mentiroso sii A o B es veraz”
Determinar a qué tribu pertenecen A, B y C.
Solución: Representaremos por a, b y c que A, B y C son veraces. Por
tanto, (no a), (no b) y (no c) representan que A, B y C son menti-
rosos. Para determinar las tribus calculamos los modelos del conjunto
de fórmulas correspondientes a las tres frases. Una vez que abras el
programa lp.pl se puede utilizar el funtor modelosconjunto(S,L), que
determina el conjunto de modelos L de un conjunto de fórmulas S.
modelos conjunto([a sii (b y c sii c), b sii (a y c im b y c y (no a)), c
sii ((no b) sii a o b)], L).
L = [[ (a, 1), (b, 1), (c, 0)]]
Por tanto, A y B son veraces y C es mentiroso.

2. Problema de los trabajos. Juan, Sergio y Carlos trabajan de pro-


gramador, ingeniero y administrador (aunque no necesariamente en
este orden). Juan le debe 1000 euros al programador. La esposa del
administrador le ha prohibido a su marido pedir dinero prestado (y
éste le obedece). Sergio está soltero. Determinar el trabajo de cada
uno.
Solución: Usaremos los siguientes sı́mbolos proposicionales cp (Carlos
es programador), ci (Carlos es ingeniero), ca (Carlos es administra-
dor), jp (Juan es programador), ji (Juan es ingeniero), ja (Juan es
administrador), sp (Sergio es programador), si (Sergio es ingeniero) y
sa (Sergio es administrador). Calculamos los modelos del conjunto de
fórmulas correspondiente al problema (hemos comentado el significado
de cada fórmula). Veamos como se pueden encontar un conjunto de
proposiciones que recoja la información anterior. Después de le aplica,
el modelosconjunto.
modelos conjunto( [
% Juan es programador, ingeniero o administrador:
jp o ji o ja,
% Sergio es programador, ingeniero o administrador:
sp o si o sa,
% Carlos es programador, ingeniero o administrador:
cp o ci o ca,
% No hay más de un programador:
(jp y (no sp) y (no cp)) o ((no jp) y sp y (no cp)) o ((no jp) y (no sp)
y cp),
% No hay más de un ingeniero:
(ji y (no si) y (no ci)) o ((no ji ) y si y (no ci)) o ((no ji) y (no si) y
ci),
% No hay más de un administrador:
(ja y (no sa) y (no ca)) o ((no ja) y sa y (no ca)) o ((no ja) y (no sa)
y ca),
% Juan le debe 1000 pesetas al programador
% [Luego, Juan no es el programador]:
(no jp),
% La esposa del administrador le ha prohibido a
% su marido pedir dinero prestado (y éste le obedece)
% [Luego, Juan no es el administrador]:
(no ja),
% Sergio está soltero [Luego, no es el adminitrador]:
(no sa)], L).
Eliminado los comentarios, puedes realizar la siguiente consulta:
modelos conjunto([(jp o ji) o ja , (sp o si) o sa , (cp o ci) o ca ,(((jp y
(no sp)) y (no cp)) o (((no jp) y sp) y (no cp))) o (((no jp) y (no sp))
y cp), (ji y (no si) y (no ci)) o ((no ji ) y si y (no ci)) o ((no ji) y (no
si) y ci), (ja y (no sa) y (no ca)) o ((no ja) y sa y (no ca)) o ((no ja)
y (no sa) y ca), (no jp), (no ja),(no sa)], L).
En la que se obtiene la siguiente respuesta:
L = [[(ca,1),(ci,0),(cp,0),(ja,0),(ji,1),(jp,0),(sa,0),(si,0),(sp,1)]]
A continuación damos una lista de problemas para que intentes resol-
verlos mediante la aplicación de los predicados definidos en el programa
lp.pl
3. El problema de los cuadrados. Existe nueve sı́mbolos proposicio-
nales que se pueden ordenar en un cuadrado:
a1 a2 a3
b1 b2 b3
c1 c2 c3
Se sabe que existe alguna letra tal que para todos los números las
fórmulas son verdaderas (es decir, existe una fila de fórmulas verda-
deras). El objetivo de este ejercicio demostrar que para cada número
existe una letra cuya fórmula es verdadera (es decir, en cada columna
existe una fórmula verdadera).

4. Problema del coloreado del pentágono Demostrar que es impo-


sible colorear los vértices de un pentágono de rojo o azul de forma que
los vértices adyacentes tengan colores distintos.
Nota: Denota por a1 , a2 , a3 , a4 , a5 sı́mbolos proposicionales que se
interpretan afirmando que el vértice i es azul ai. Análogamente para
el rojo puedes utilizar r1 , r2 , r3 , r4 , r5 . Construye un conjunto de
proposiciones con los sı́mbolos anteriores cuya veracidad sea equiva-
lente a que existe una coloración de los vértices de un pentágono de
rojo o azul de forma que los vértices adyacentes tengan colores distin-
tos. Prueba ahora que ese conjunto de proposiciones en inconsistente
(contradictorio). Utiliza el functor inconsistente del programa lp.pl

5. Problema del coloreado del pentágono (con tres colores). De-


mostrar que es posible colorear los vértices de un pentágono de rojo,
azul o negro de forma que los vértices adyacentes tengan colores dis-
tintos.

6. Problema del palomar. Cuatro palomas comparten tres huecos y


no hay más de dos palomas en cada hueco. Demostrar que dos palomas
tienen que estar en el mismo hueco.

7. El problema de las 4 reinas. Calcular las formas de colocar 4 reinas


en un tablero de 4 × 4 de forma que no haya más de una reina en cada
fila, columna o diagonal.

8. El problema de hermano mentiroso. Trata de resolver el siguien-


te problema mediante la creación de un conjunto de proposiciones y
encontrando modelos para dicho conjunto.
Los tres hermanos Lezaum tienen la curiosa costumbre de que cada
vez que se les hace una pregunta, dos dicen la verdad y el otro miente.
Cuando les pregunté quién habı́a nacido primero me contestaron:
Andoni: “Benito nació en primer lugar”.
Benito: “Yo no soy el mayor”.
Carlos:“Andoni nació el primero”
¿Cuál es el mayor de ellos?
Notas: Se supone que dos hermanos no pueden nacer simultáneamente.
Para la construcción de las proposiciones puedes utilizar los siguientes
átomos:
-a: Andoni dice la verdad
-b: Benito dice la verdad
-c: Carlos dice la verdad
-am: Andoni es el mayor
-bm: Benito es el mayor
-cm: Carlos es el mayor
9. El robo del libro de recetas de la Duquesa. Trata de resolver
el siguiente problema1 mediante la creación de un conjunto de propo-
siciones y encontrando modelos para dicho conjunto. La solución se
debe encontrar mediante el uso Prolog.
“-Aquı́ están los moldes - dijo el Rey - ya puedes hacerme los pasteles.
-¿Sin la receta?- preguntó la Reina.
-Hazlos como siempre- gritó el Rey con impaciencia-, la última vez
estaban riquı́simos.
-No puedo- dijo la Reina-. La receta está en el libro de cocina y me lo
acaban de robar.
El principal sospechoso era la Cocinera y el libro fue encontrado en
efecto en la cocina de la Duquesa. Los únicos posibles sospechosos eran
la Cocinera, la Duquesa y el Gato de Cheshire.
-¡ Lo robó el gato de Cheshire! - dijo la Duquesa en el juicio-.
-Sı́, yo lo robé - dijo el Gato con una sonrisa-.
-¡Yo no lo robe! -dijo la Cocinera.
El ladrón habı́a mentido y al menos uno de los otros dos habı́a dicho
la verdad.
¿Quién robó el libro a la cocinera?”.
Nota: Para la construcción de las proposiciones asociadas a la infor-
mación anterior puedes utilizar los siguientes átomos

-g: el gato dice la verdad -c: la cocinera dice la verdad


-d: la duquesa dice la verdad -gl: el gato es el ladrón
-cl: la cocinera es la ladrona -dl: la duquesa es la ladrona
1
Del libro “Alicia en el pais de las adivinanzas”, de Raymond Smullyan, Ed. Cátedra,
1982.
Prácticas de Lógica en aula informática (Curso 2010-11) — Práctica 5

DEDUCCIÓN NATURAL CON ((ADN)). PROPOSICIONES

ADN significa Asistente para la Deducción Natural. Es una herramien-


ta diseñada por F. Llorens y S. Mira en la Universidad de Alicante,
que han pretendido fabricar ((un instrumento didáctico que ayude a los
estudiantes a escribir fórmulas lógicas bien formadas y a realizar de-
ducciones correctamente)). Sirve para trabajar con proposiciones y con
predicados. En esta primera práctica tomaremos contacto con ADN y
lo usaremos con proposiciones. En la siguiente práctica continuaremos
con ADN incorporando predicados. Una limitación de ADN es que
no permite almacenar lo ya probado para que sea utilizado en nuevas
demostraciones, de modo que todas deben hacerse ı́ntegramente a par-
tir de las reglas primitivas, pudiendo algunas exceder el tamaño de la
pizarra.

1.—ADN incorpora su propia AYUDA, que debe ser leı́da al iniciar la


práctica y acudir a ella cuando sea necesario a medida que se va tra-
bajando. Es conveniente consultar en la AYUDA la forma de escribir
los conectores lógicos y los nombres que reciben las reglas primitivas.
En la ayuda hay ejercicios resueltos que se pueden estudiar antes de
abordar los que aquı́ se proponen.

2.—Escritura de proposiciones y visualización de árboles. Ir a la barra


de fórmulas ((Objetivo)), escribir una fórmula y pulsar ((intro)). Si la
fórmula no está bien formada aparece la explicación del error abajo
a la derecha (en la versión 2.1, a la derecha) y la fórmula se puede
reparar. Si la fórmula está bien formada se puede visualizar su árbol
sintáctico. Ejemplos (cada estudiante puede crearse otros):

P ¬ ∧ Q, P ∧ Q ∨ R, P ∧ ¬Q, P ∧ (¬Q).
(P → ¬(Q ∧ R)) ∨ ¬R ∧ (P → Q).

3.—Construir deducciones mediante las reglas de deducción natural.

P → (Q → R) (P ∧ Q) → R P
a) b) c) (RI¬¬)
(P ∧ Q) → R P → (Q → R) ¬¬P
¬P 1 ∨ ¬Q1
P ∨Q P ∨ Q1
P → P1
d) ¬P (RE∨) e) f) ¬P ∨ Q2
Q → Q1
Q Q1 ∨ Q2
¬P ∨ ¬Q
(RR)

P →Q
g)
¬(P ∧ ¬Q

4.—Las dos equivalencias de De Morgan dan dan lugar a cuatro reglas


(dos a dos recı́procas), a saber:
a) ¬P ∧ ¬Q ` ¬(P ∨ Q)
b) ¬(P ∧ Q) ` ¬P ∨ ¬Q
c) ¬(P ∨ Q) ` ¬P ∧ ¬Q
d) ¬P ∨ ¬Q ` ¬(P ∧ Q)
Demostrad cada una de ellas.

5.—También se pueden demostrar las tautologı́as, como si fueran reglas


pero sin premisas. Por ejemplo, los tres axiomas de Lukasiewicz:

(L1) P → (Q → P )
(L2) (P → (Q → R)) → ((P → Q) → (P → R))
(L3) (¬P → ¬Q) → (Q → P )

Nótese que a cada una de estas proposiciones le podemos asociar una


regla de la siguiente forma:

P P → (Q → R)
(RL1) (RL2) (RL3)
Q→P (P → Q) → (P → R)
¬P → ¬Q
Q→P

Compárese la demostración de una de estas reglas con la de la corres-


pondiente tautologı́a.

6.—Terminamos con un ejemplo de tautologı́a a demostrar cuyo co-


nector raı́z no es el condicional: P ∨ ¬(Q ∧ P ).
Prácticas de Lógica en aula informática (Curso 2010-11) — Práctica 6

DEDUCCIÓN NATURAL CON ((ADN)). PREDICADOS

1.— Las expresiones P (x), R(x, y), etc. son siempre fórmulas atómicas.
Sin embargo ADN no permite introducir fórmulas con variables libres.
En los apuntes de teorı́a se suele utilizar expresiones del tipo (∀x)P (x) ,
no obstante, ADN prefiere la expresión ∀xP (x) .

2.—Escritura de proposiciones y visualización de árboles. Si la fórmula


está bien formada se puede visualizar su árbol sintáctico. En otro caso
hay que repararla hasta que se pueda visualizar su árbol sintáctico:
Mal formada : ∀(x)(Q(x) → ∃y(P (y) ∧ (R(x, y)
Bien formada : ∀x(Q(x) → ∃y(P (y) ∧ (R(x, y)))
3.—Demostrar mediante las reglas de deducción natural los silogismos
siguientes:

∀x(P (x) → Q(x)) ∀x(P (x) → ¬Q(x))


a) ∀x(R(x) → ¬Q(x)) b) ∃x(R(x) ∧ Q(x))
∀x(R(x) → ¬P (x)) ∃x(R(x) ∧ ¬P (x))

4.—Las dos equivalencias de De Morgan cuantificadas dan cuatro re-


glas (dos a dos recı́procas), por ejemplo, ¬∀xP (x) ` ∃x¬P (x), etc..
Demostrad la anterior regla.

5.—También se pueden demostrar las tautologı́as, como si fueran reglas


pero no hay premisas. Por ejemplo:

(∀x(P → Q(x)) → (P → ∀xQ(x))

y también su recı́proco.

Nótese que a la fórmula anterior le podemos asociar la regla:

∀x(P → Q(x))
P → ∀xQ(x)

y análogamente con la fórmula recı́proca. Compárese la demostración


de estas reglas con las de las correspondientes leyes lógicas.
6.— En la fórmulas pueden intervenir más variables como en caso de
las siguientes que se deben demostrar mediante la aplicación ADN
∃x(P 1(x) ∧ ∀y(P 2(y) → P 3(x, y)))
a) ∀x∀y(P 1(x) ∧ P 4(y) → ¬P 3(x, y))
∀x(P 2(x) → ¬P 4(x))

b) Probad la siguiente ley lógica

¬(¬∃x¬P (x) ∧ ¬∀xP (x))

You might also like