material de prolog para el laboratorio 2 de fundamentos de programación.pdf

28
INF220 – Fundamentos de Programación 1 Problemas de aplicación Un juego de restricciones. A continuación se presentan una serie de restricciones que debemos modelar como un programa en Prolog, de forma que se deduzca la solución a partir de una meta solicitada. Cinco hermanas nacieron en diferentes meses del año y en diferentes días de la semana. Empleando los predicados en Prolog y basados en las siguientes pistas, determine el mes y día en que nació cada una de las hermanas: - Paula nació en marzo pero no en sábado. Abigail no nació ni en viernes ni en miércoles. - La chica que nació un lunes, nació un mes que es anterior a los meses en los que nacieron Brenda y Mary. - Tara no nació ni en febrero ni en julio, pero si en fin de semana. - Mary no nació en diciembre ni en un día laborable (de lunes a viernes). - La chica que cumple años en junio nació un domingo. - Tara nació antes Brenda, la cual no nació en viernes. La solución a este acertijo tomará la siguiente forma: Sol=[[abigail,M1,D1],[brenda,M2,D2],[mary,M3,D3],[paula,M4,D4],[tara,M5,D5]] Donde cada tríada de valores identifica, en este orden, el nombre, mes y día de nacimiento de cada hermana. Además los valores posibles para mes y día son: Mes ϵ[febrero,marzo,junio,julio,diciembre] Día ϵ[domingo, lunes, miércoles, viernes, sábado] como dice el enunciado los valores que tomen las tuplas en mes y día no deben repetirse. Solución: Esta primera solución no es la más eficiente, pero nos servirá como punto de partida. Básicamente la idea consiste en proporcionar todos los valores posibles a M i y D i (en la lista Sol), para todo i entre 1 y 5. Este primer paso podemos lograrlo con el predicado built-in member(), que haciendo uso del backtracking permite ligar los distintos valores de la lista en una variable libre. Luego exigimos que estos valores sean diferentes, como lo especifican las condiciones del problema, por último verificamos que cumpla las reglas arriba descritas. Como se puede observar el corazón del problema está en construir las reglas tal como están especificadas. En todo momento debemos recordar que en Prolog las variables son locales a la regla, es decir una regla1 con la variable X no reconoce a la variable X de la regla2, a pesar de que ambas tengan el mismo nombre. Para ejecutar este programa en SWI-Porlog desde el prompt solo escriba: acertijo(L). A continuación el programa: Laboratorio 2 Prof. A. Bello

Upload: fabian-orccon

Post on 13-Dec-2014

211 views

Category:

Documents


3 download

TRANSCRIPT

Page 1: Material de Prolog para el Laboratorio 2 de Fundamentos de Programación.pdf

INF220 – Fundamentos de Programación 1

Problemas de aplicación

Un juego de restricciones.

A continuación se presentan una serie de restricciones que debemos modelar como un programaen Prolog, de forma que se deduzca la solución a partir de una meta solicitada.

Cinco hermanas nacieron en diferentes meses del año y en diferentes días de la semana.Empleando los predicados en Prolog y basados en las siguientes pistas, determine el mes y díaen que nació cada una de las hermanas:

- Paula nació en marzo pero no en sábado. Abigail no nació ni en viernes ni enmiércoles.

- La chica que nació un lunes, nació un mes que es anterior a los meses en los quenacieron Brenda y Mary.

- Tara no nació ni en febrero ni en julio, pero si en fin de semana.

- Mary no nació en diciembre ni en un día laborable (de lunes a viernes).

- La chica que cumple años en junio nació un domingo.

- Tara nació antes Brenda, la cual no nació en viernes.

La solución a este acertijo tomará la siguiente forma:

Sol=[[abigail,M1,D1],[brenda,M2,D2],[mary,M3,D3],[paula,M4,D4],[tara,M5,D5]]

Donde cada tríada de valores identifica, en este orden, el nombre, mes y día de nacimiento decada hermana. Además los valores posibles para mes y día son:

Mes ϵ[febrero,marzo,junio,julio,diciembre]

Día ϵ[domingo, lunes, miércoles, viernes, sábado]

como dice el enunciado los valores que tomen las tuplas en mes y día no deben repetirse.

Solución:

Esta primera solución no es la más eficiente, pero nos servirá como punto de partida.Básicamente la idea consiste en proporcionar todos los valores posibles a Mi y Di (en la listaSol), para todo i entre 1 y 5. Este primer paso podemos lograrlo con el predicado built-inmember(), que haciendo uso del backtracking permite ligar los distintos valores de la lista enuna variable libre. Luego exigimos que estos valores sean diferentes, como lo especifican lascondiciones del problema, por último verificamos que cumpla las reglas arriba descritas. Comose puede observar el corazón del problema está en construir las reglas tal como estánespecificadas.

En todo momento debemos recordar que en Prolog las variables son locales a la regla, es deciruna regla1 con la variable X no reconoce a la variable X de la regla2, a pesar de que ambastengan el mismo nombre.

Para ejecutar este programa en SWI-Porlog desde el prompt solo escriba:

acertijo(L).

A continuación el programa:

Laboratorio 2 Prof. A. Bello

Page 2: Material de Prolog para el Laboratorio 2 de Fundamentos de Programación.pdf

INF220 – Fundamentos de Programación 2

Encontrar la respuesta le tomará a Prolog un tiempo considerable.

Laboratorio 2 Prof. A. Bello

Page 3: Material de Prolog para el Laboratorio 2 de Fundamentos de Programación.pdf

INF220 – Fundamentos de Programación 3

El predicado select(X,L,Resto).

Este predicado es útil para generar combinaciones diferentes de valores, por ejemplo si se deseagenerar ternas de dígitos diferentes entre 1 y 3 podemos escribir este predicado.

Observe los valores de X, Y y Z son combinaciones diferentes de [1,2,3]. Este predicado puedeser empleado en lugar de member() y de esta forma nos evitaría el predicado diferentes(). Porsupuesto obtenemos un mejor tiempo.

Laboratorio 2 Prof. A. Bello

Page 4: Material de Prolog para el Laboratorio 2 de Fundamentos de Programación.pdf

INF220 – Fundamentos de Programación 4

A continuación el programa

Ahora al ejecutar el programa la respuesta toma mucho menos tiempo, casi es inmediata.

Como conclusión a este primer ejercicio podemos decir que el uso eficiente de las reglaspermitirá que Prolog analice menos casos, eliminando varias ramas recursivas, con elconsiguiente ahorro de tiempo.

Laboratorio 2 Prof. A. Bello

Page 5: Material de Prolog para el Laboratorio 2 de Fundamentos de Programación.pdf

INF220 – Fundamentos de Programación 5

Un pequeño crucigrama de sumas

Se pide un programa en Prolog para resolver el crucigrama de sumas mostrado en la figura:

El objetivo debe ser invocado de la siguiente forma:

? crucigrama([11,21,8],[24,10,6],F1,F2,F3).

Y Prolog debe responder:

F1 = [8, 9, 7],F2 = [2, 7, 1],F3 = [1, 5]

Que corresponde a la siguiente figura:

Como se puede observar el objetivo es rellenar las casillas vacías con valores comprendidosentre 1 y 9. De modo que la suma de los valores de cada fila y de cada columna sea igual a losnúmeros colocados en las casillas sombreados. Además los valores en cada fila y columnadeben ser diferentes.

Esta última restricción es diferente al ejercicio anterior. Anteriormente se pedía que todos losvalores sean distintos, en este ejercicio sólo por fila o por columna. A continuación el programa:

Laboratorio 2 Prof. A. Bello

Page 6: Material de Prolog para el Laboratorio 2 de Fundamentos de Programación.pdf

INF220 – Fundamentos de Programación 6

En este caso las restricciones han sido aplicadas apenas se tenían los valores. Es decir no seesperaban a tener un juego de valores para podarlos, sino que se iban podando a medida que seiban obteniendo. Entiéndase por podar al hecho de aplicar las restricciones. Esto permitirá queel tiempo de ejecución sea mínimo.

Laboratorio 2 Prof. A. Bello

Page 7: Material de Prolog para el Laboratorio 2 de Fundamentos de Programación.pdf

INF220 – Fundamentos de Programación 7

Sudoku simple

Elabore las reglas necesarias para resolver el siguiente sudoku de nivel sencillo (1/5). Usted nodebe resolver el sudoku. Usted debe proporcionarle las reglas a Prolog y este debe resolverlo.Las reglas del sudoku mostrado abajo, son muy sencillas:

a) Todas las filas deben tener valores diferentes.b) Todas las columnas deben tener valores diferentes.c) Los rectángulos de 2x3 deben tener valores diferentes.

Solución

Laboratorio 2 Prof. A. Bello

Page 8: Material de Prolog para el Laboratorio 2 de Fundamentos de Programación.pdf

INF220 – Fundamentos de Programación 8

El tiempo de ejecución es bastante aceptable, apenas unas milésimas de segundo, la demora escasi imperceptible.

Aunque no es un problema, pero si constituye una molestia, es ver las listas incompletas. Eneste caso no es culpa de la IDE, sino de Prolog. Para ver las listas de cualquier longitud escribalo siguiente al inicio del programa:

:­set_prolog_flag(toplevel_print_options,    [quoted(true),     portray(true),     max_depth(120),     priority(699)]).

Al volver a ejecutar el objetivo se mostrarán las listas completas.

Laboratorio 2 Prof. A. Bello

Page 9: Material de Prolog para el Laboratorio 2 de Fundamentos de Programación.pdf

INF220 – Fundamentos de Programación 9

Un juego de criptografía aritmética.1

Un ejemplo muy conocido de un juego de criptografía aritmética es

D O N A L D + G E R A L D

R O B E R T

El problema aquí es asignar dígitos a las letras D, O, N, etc., de modo que la suma de arriba seaválida. A todas las letras se le deben asignar diferentes dígitos, de otra manera una solucióntrivial siempre es posible – por ejemplo, si todas las letras son iguales a cero.

Nosotros definiremos la relación

suma(N1,N2,N)

donde N1, N2 y N representan los tres números de un juego de criptografía aritmética. Elobjetivo suma(N1,N2,N) es true si hay una asignación de dígitos a las letras de modo que N =N1 + N2.

El primer paso hacia una solución es decidir cómo representar los números N1, N2 y N en elprograma. Una manera de hacer esto es representar cada número como una lista de dígitosdecimales. Por ejemplo, el número 225 debería ser representado por la lista [2,2,5]. Comotodos estos dígitos no son conocidos de antemano, una variable libre será usada por cada dígito.

Usando esta idea, el problema puede ser representado como:

[D, O, N, A, L, D] + [G, E, R, A, L, D] = [R, O, B, E, R, T]

Luego la tarea es encontrar valores para las variables D, O, N, etc., tal que la suma arribamostrada sea válida. Cuando la relación suma haya sido programada el juego puede sersolicitado a Prolog como la consulta:

suma([D,O,N,A,L,D],[G,R,A,L,D],[R,O,B,E,R,T]).

Para definir la relación suma en lista de dígitos, nosotros tenemos que implementar las reglascomunes que se usan para llevar a cabo la adición en el sistema de números decimales. Laadición se lleva a cabo dígito a dígito, empezando con el dígito más a la derecha, continuandohacia la izquierda, y siempre tomando en cuenta el dígito de acarreo de la derecha.

Para este propósito también es necesario mantener un conjunto de dígitos disponibles; esto es,dígitos que aún no han sido usados por variables libres ya encontradas. Así en general, entre lostres números N1, N2 y N3, alguna información adicional se debe considerar, tal como se ilustraen la Figura 1.

1 Los siguientes ejercicios son una traducción libre del libro Prolog Programming for IntelligenceArticial de Ivan Bratko

Laboratorio 2 Prof. A. Bello

Page 10: Material de Prolog para el Laboratorio 2 de Fundamentos de Programación.pdf

INF220 – Fundamentos de Programación 10

Número1 = [D11, D12, . . .,D1i,. . .]Número2 = [D21, D22, . . .,D2i,. . .]Número3 = [D31, D32, . . .,D3i,. . .]

Aquí el acarreo Acarreo de Aquí el acarreo es 0 debe ser 0 la derecha

0 C C1 0

Número1 . . . . . . .D1i. . . . . .

+ Número2 . . . . . . .D2i. . . . . .

= Número3 . . . . . . .D3i. . . . . .

Figura 1.

• Un dígito de acarreo antes de la adición de los números.• Un dígito de acarreo después de la adición.• Un conjunto de dígitos disponibles antes de la adición.• El resto de dígitos no usados en la adición.

Para formular la relación suma nosotros usaremos el principio de generalización del problema:introduciremos una relación auxiliar más general, suma1. La relación suma1 posee algunosargumentos extras, la cual corresponde a la ya mencionada información adicional.

suma1(N1,N2,N,C1,C,Digitos1,Digitos)

N1, N2 y N son nuestros tres números, como en la relación suma, C1 es el acarreo de la derecha(antes de la adición de N1 y N2), y C es el acarreo de la izquierda (después de la adición). Elsiguiente ejemplo lo ilustra:

suma1([H,E],[6,E],[U,S],1,1,[1,3,4,7,8,9],Digitos).

H = 8E = 3S = 7U = 4

Digitos = [1,9]

Esto corresponde a la siguiente adición:

1 ← ← 18 3

6 3 4 7

Como muestra la Figura 1, C1 y C tienen que ser 0 si N1, N2 y N son los que satisfacen larelación suma. Digitos1 es la lista de dígitos disponibles para las variables que separticularizaran en N1, N2 y N; Digitos es la lista de dígitos que no fueron usados en laparticularización de estas variables. Debido a que nosotros permitimos el uso de algún dígitodecimal en la satisfacción de la relación suma, la definición de la relación suma en términos desuma1 es como sigue:

suma(N1,N2,N):-suma1(N1,N2,N,0,0,[0,1,2,3,4,5,6,7,8,9,_).

Laboratorio 2 Prof. A. Bello

Page 11: Material de Prolog para el Laboratorio 2 de Fundamentos de Programación.pdf

INF220 – Fundamentos de Programación 11

El peso del problema ahora se ha desplazado a la relación suma1. Esta relación es, sin embargo,suficientemente genérica como para ser definida recursivamente. Asumiremos sin perdida degeneralidad, que las tres listas que representan los tres números son de igual longitud. Nuestroejemplo, por supuesto, satisface esta exigencia; si no es así, al número se le puede anteceder porceros de modo que los tres tengan la misma longitud.

La definición de suma1 puede ser dividida en dos casos:

a) Los tres números son representados por listas vacías. Entonces:

suma1([],[],[],C,C,Digitos,Digitos).

b) Todos los números tienen algún dígito más a la izquierda y el resto de dígitos a laderecha. Así ellos tienen la forma:

[D1|N1] [D2|N2] [D|N]

En este caso dos condiciones se deben satisfacer:

i) Los tres números N1, N2 y N tienen que satisfacer la relación suma1,dando algún dígito de acarreo: C2, a la izquierda, y dejando algún sub conjuntode dígitos decimales no usados: Digitos2.

ii) Los dígitos más a la izquierda D1, D2 y D, y el dígito de acarreo C2 tienenque satisfacer la relación indicada en la Figura 1. C2, D1 y D2 son sumadosdando como resultado D y un acarreo a la izquierda. Esta condición seráformulada en nuestro programa como la relación sumadigitos.

Traduciendo este caso a Prolog tenemos:

suma1([D1|N1],[D2|N2],[D|N],C1,C,Digitos1,Digitos):-suma1(N1,N2,N,C1,C2,Digitos1,Digitos2),sumadigitos(D1,D2,C2,D,C,Digitos2,Digitos).

Lo único que resta definir en Prolog es la relación sumadigitos. Hay un detalle sutil queinvolucra el uso del predicado nonvar. Este predicado tiene éxito si su argumento ya estáacotada con valor alguno. D1, D2 y D tienen que ser dígitos decimales. Si alguno de ellos aúnno está particularizado entonces tiene que llegar a ser particularizado a uno de los dígitos de lalista Digitos2. Además estos dígitos tienen que ser eliminados del conjunto de dígitosdisponibles.

Si D1, D2 o D ya están particularizados entonces, por supuesto ninguno de los dígitosdisponibles será usado. Esto se realiza en el programa como un borrado de un ítem de una lista.Si este ítem no es una variable no se borra dígito alguno (no ocurre la particularización). Esto seprograma como:

borra(Item,Lista,Lista):-nonvar(Item),!. %Item ya instanciadoborra(Item,[Item | Lista], Lista). %Borra la cabezaborra(Item,[A | Lista], [A | Lista1]):-

borra(Item,Lista,Lista1). %Borra Item de la cola

El programa completo que resuelve el juego de criptografía aritmética será:

Laboratorio 2 Prof. A. Bello

Page 12: Material de Prolog para el Laboratorio 2 de Fundamentos de Programación.pdf

INF220 – Fundamentos de Programación 12

La consulta a Prolog sobre DONALD, GERALD y ROBERT, usando este programa debería ser:

puzzle([D,O,N,A,L,D],[G,E,R,A,L,D],[R,O,B,E,R,T]).

Otra posible consulta es la siguiente:

puzzle([0,S,E,N,D],[0,M,O,R,E],[M,O,N,E,Y]).

Laboratorio 2 Prof. A. Bello

Page 13: Material de Prolog para el Laboratorio 2 de Fundamentos de Programación.pdf

INF220 – Fundamentos de Programación 13

El problema de las N reinas

En el problema de las N reinas, el objeto es colocar N reinas en un tablero de ajedrez de talmanera que dos reinas cualesquiera no puedan atacarse una con otra. De acuerdo a esto, dosreinas no pueden colocarse en la misma fila, columna ni diagonal.

La solución se programará como el predicado unario solucion(Pos) el cual es verdad sí ysolo sí Pos representa una posición con ocho reinas que no se atacan unas a otras. Seráinteresante comparar varias ideas para programar este problema. Para esto presentaremos tresprogramas basados en diferentes representaciones del problema.

Programa 1

Primero nosotros tenemos que elegir una representación de la posición del tablero. Una elecciónnatural es representar la posición por una lista de ocho elementos (para un tablero de 8x8, porejemplo), cada uno de ellos correspondientes a una reina. Cada ítem en la lista especificará uncuadrado del tablero en la cual la correspondiente reina está ubicada.

Además cada cuadrado puede ser especificado por un par de coordenadas (X e Y) en el tablero,donde cada coordenada es un entero entre 1 y 8. En el programa podemos escribir tal par como:X/Y donde por supuesto, / no es el operador que indica la división. La Fig. 2 muestra unasolución del problema de las ocho reinas y su lista de representación.

1 2 3 4 5 6 7 8

Fig. 2

[1/2,2/5,3/7,4/4,5/1,6/8,7/6,8/3]

Habiendo elegido esta representación, el problema es encontrar una lista de la forma:

[X1/Y1,X2/Y2,X3/Y3,...,X8/Y8]

El cual satisface el requerimiento de no ataque. Nuestro procedimiento solucion() tendrá quebuscar una adecuada acotación de las variables X1,Y1,X2,Y2,... ,X8,Y8. Como sabemos, todaslas reinas tendrán que estar en diferentes columnas para evitar el ataque vertical, podemos portanto fijar las coordenadas X de modo que la lista solución quedará como sigue:

[1/Y1,2/Y2,3/Y3,...,8/Y8]

Laboratorio 2 Prof. A. Bello

Page 14: Material de Prolog para el Laboratorio 2 de Fundamentos de Programación.pdf

INF220 – Fundamentos de Programación 14

Nosotros estamos interesados en la solución de un tablero de tamaño 8 por 8. Sin embargo, en laprogramación, la clave para una solución a menudo consiste en considerar un problema másgeneral.

Paradójica mente, se da con frecuencia el caso en que la solución para un problema más generales más fácil de formular que para el problema original especifico. El problema original entoncesresulta como un caso especial del problema más general.

La parte creativa del problema es encontrar la correcta generalización del problema original. Ennuestro caso, una buena idea es generalizar el número de reinas (el número de columnas en lalista) de 8 a algún número, incluyendo 0.

La relación solucion() puede ser formulada considerando dos casos:

Caso 1 La lista de reinas está vacía: la lista vacía es ciertamente una solución por que no hayataque alguno.

Caso 2 La lista de reinas no está vacía, entonces se muestra algo como esto:

[X/Y|Otros]

En el caso 2, la primera reina está en algún cuadrado X/Y y las otras reinas están en loscuadrados especificados por la lista Otros. Si este va a ser una solución entonces las siguientescondiciones deben cumplirse:

(1) En la lista Otros no se deben atacar entre reinas; esto es, Otros en sí misma debe seruna solución.

(2) X e Y deben ser enteros entre 1 y 8.

(3) Una reina en un cuadrado X/Y no debe atacar a alguna de las reinas de la lista Otros.

Para programar la primera condición nosotros podemos simplemente usar la relaciónsolucion() en sí misma.

La segunda condición puede ser especificada como sigue: Y tendrá que ser un miembro de lalista de enteros entre 1 y 8 –esto es [1,2,3,4,5,6,7,8].

De otro lado, nosotros no tenemos que preocuparnos acerca de los valores que X puede tomar,desde el momento que hemos fijado estos valores tendrá que coincidir con la plantilla en la cualla coordenadas X ya están especificadas. Por tanto X estará garantizada de tener un valorapropiado entre 1 y 8.

Podemos implementar la tercera condición como la relación noataca(). Todo esto puede serescrito en Prolog como sigue:

solucion([]). solucion([X/Y|Otros]) :-

solucion(Otros),pertenece(Y,[1,2,3,4,5,6,7,8]), noataca(X/Y,Otros).

Ahora solo resta definir la relación noataca(): noataca(Q,Qlista).

Nuevamente esto puede ser dividido en dos casos:

Laboratorio 2 Prof. A. Bello

Page 15: Material de Prolog para el Laboratorio 2 de Fundamentos de Programación.pdf

INF220 – Fundamentos de Programación 15

1) Si la lista Qlista es vacía entonces la relación es ciertamente verdadera por que nohay reina a ser atacada.

2) Si Qlista es no vacía entonces tiene la forma [Q1|Qlista1] y dos condicionesdeben ser satisfechas:

(a) la reina en Q no debe atacar a la reina en Q1, y

(b) la reina en Q no debe atacar a alguna de las reinas en Qlista1

Para especificar que una reina en algún cuadrado no ataca a otra, es fácil: los dos cuadrados nodeben estar en la misma fila, la misma columna o la misma diagonal.

Nuestra plantilla de solución garantiza que todas las reinas están en diferentes columnas, así quesólo resta especificar explícitamente que:

- Las coordenadas Y de las reinas son diferentes, y

- Ellas no están en la misma diagonal, ya sea que suban o bajen; esto es, la distanciaentre los cuadrados en la dirección X no debe ser igual a esa, en la dirección Y.

A continuación presentamos el programa completo:

La meta a ejecutar será:

En este caso habrá más de una solución . Por tanto deberá presionar punto y coma (;) después deque Prolog presente alguna solución.

Laboratorio 2 Prof. A. Bello

Page 16: Material de Prolog para el Laboratorio 2 de Fundamentos de Programación.pdf

INF220 – Fundamentos de Programación 16

Programa 2

En la representación del tablero del programa 1, cada solución tomaba la forma:

[1/Y1,2/Y2,3/Y3,...,8/Y8]

Porque simplemente las reinas fueron colocadas en columnas consecutivas. Ningunainformación se pierde si las x-coordenadas se omiten. De esta manera, se puede usar unarepresentación más económica de las posiciones en el tablero, dejando explicita sólo las y-coordenadas de las reinas:

[Y1, Y2, Y3,..., Y8]

Para evitar el ataque horizontal, dos reinas no pueden estar en la misma fila. Esto impone unarestricción en las y-coordenadas. Las reinas tienen que ocupar todas las filas 1, 2, 3,.., 8. Laelección que resta es determinar el orden de los ocho números. Cada solución además puede serrepresentada por una permutación de la lista:

[1, 2, 3,..., 8]

Como tal, una permutación S, es una solución si todas las reinas son seguras. De modo quenosotros podemos escribir:

solución(S):- permutación([1,2,3,4,5,6,7,8],S), segura(S).

Nosotros ya hemos programado las reglas para el predicado permutación(), se encuentran enuna sección anterior, pero la relación segura() aún queda por especificar. Podemos dividir sudefinición en dos casos:

(1) Si S es la lista vacía: esta es ciertamente segura, como allí no hay nada que atacar.

(2) Si S es una lista no vacía de la forma [Reina|Otras]. Esta es segura si la lista Otras essegura, y Reina no ataca a alguna reina en la lista Otras.

En Prolog, la cláusula es:

segura([]).segura([Reina|Otras]):- segura(Otras), noataca(Reina,Otras).

La relación noataca() aquí es levemente complicada. La dificultad estriba en que lasposiciones de las reinas sólo están definidas por sus y-coordenadas, y las x-coordenadas noestán explícitamente presentes. Este problema puede ser evitado con una pequeñageneralización de la relación noataca(), como se ilustra en la presente figura.

Fig. 1 (a) la distancia entre Queen y Others es 1. b) la distancia entre Queen y Others es 3.

Laboratorio 2 Prof. A. Bello

Page 17: Material de Prolog para el Laboratorio 2 de Fundamentos de Programación.pdf

INF220 – Fundamentos de Programación 17

El objetivonoataca(Reina,Otras).

Nos está expresando la seguridad que Reina no ataca a Otras cuando la x-distancia entreReina y Otras es igual a 1. Lo que sí es realmente necesario es la generalización de la x-distancia entre Reina y Otras.

Así que añadiremos esta distancia como el tercer argumento de la relación noataca():

noataca(Reina,Otras,Xdist).

Por consiguiente, el predicado noataca() en la relación segura() tiene que ser modificado a

noataca(Reina,Otras,1)

La relación noataca() puede ser formulada de acuerdo a dos casos, dependiendo de la listaOtras: si Otras es vacía entonces no hay destino y ciertamente no hay ataque; si Otras es novacía entonces Reina no debe atacar a la primera reina de la lista Otras (la cual es Xdistcolumnas de Reina) y tampoco al resto de Otras en Xdist+1. Esto nos conduce al siguienteprograma en Prolog:

En este caso el objetivo a consultar será reinas2(Tablero).

Por supuesto, en este problema de las 8 reinas siempre hay más de una solución.

Laboratorio 2 Prof. A. Bello

Page 18: Material de Prolog para el Laboratorio 2 de Fundamentos de Programación.pdf

INF220 – Fundamentos de Programación 18

Programa 3

Un tercer programa para el programa de las ocho reinas estará basado en el siguienterazonamiento. Cada reina tiene que estar colocada en algún cuadrado; esto es, en algunacolumna, alguna fila, alguna diagonal izquierda y alguna diagonal derecha. Para asegurar quetodas las reinas estén seguras, cada reina debe ser colocada en una columna, fila, diagonalizquierda y diagonal derecha diferente. Así, es natural considerar una rica representación concuatro coordenadas.

x columnasy filas u diagonal izquierda

v diagonal derecha

Las coordenadas no son independientes: dado un x e y, u y v son determinadas. Por ejemplo:

u = x – y v = x + y

Fig. 2 la relación entre columnas, filas, diagonales izquierda, diagonales derecha. El cuadrado indicado tiene coordenadas: x = 2, y = 4, u = -2, v = 6.

El dominio, para las cuatro dimensiones, es:

Dx = [1, 2, 3, 4, 5, 6, 7, 8]Dy = [1, 2, 3, 4, 5, 6, 7, 8]Du = [-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7]

Dv = [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]

El problema de las ocho reinas puede ser presentado como sigue: seleccionar 8 4-tuplas (X, Y, U,V) de los dominios (X de Dx, Y de Dy, etc.) nunca usando el elemento dos veces desde algunosde sus dominios. Por supuesto, una vez que X e Y son elegidos, U y V son determinados.

Laboratorio 2 Prof. A. Bello

Page 19: Material de Prolog para el Laboratorio 2 de Fundamentos de Programación.pdf

INF220 – Fundamentos de Programación 19

La solución entonces puede ser, informalmente hablando, como se expresa a continuación: dadocuatro dominios, seleccionar la posición de la primera reina, borrar los correspondienteselementos de los cuatro dominios, y entonces use el resto de los dominios para colocar el restode las reinas. Un programa basado en esta idea se muestra a continuación:

Como se observa las posiciones del tablero son, nuevamente, representados por una lista de y–coordenadas. El tipo de relación en este programa es:

sol(Ylist,Dx,Dy,Du,Dv). el cual particulariza la y–coordenada (en Ylist) de las reinas, asumiendo que ellas estáncolocadas en columnas consecutivas tomadas de Dx. Todas las y-coordenadas y lascorrespondientes a u y v-coordenadas son tomadas de la lista Dy, Du y Dv. El predicadoprincipal, solución(), puede ser invocado por la consulta:

solucion(S).

Esto causará la invocación de sol() con los dominios completos que corresponden al problemade las ocho reinas, como se muestra en el programa de arriba.

La cláusula sol() en el sentido más general, puede ser usada para resolver el problema de lasn-reinas (en un tablero de n por n). Para ello sólo es necesario colocar apropiadamente losdominios Dx, Dy, etc.

Es práctico mecanizar la generación de los dominios. Para ello nosotros necesitamos unpredicado

gen(N1,N2,List).

El cual, para dos enteros N1 y N2 dados, producirá la siguiente lista:

List = [N1,N1+1,N1+2,...,N2–2,N2–1,N2]

Tal cláusula es:

gen(N,N,[N]). gen(N1,N2,[N1|Lista]):- N1<N2,

M is N1+1,gen(M,N2,Lista).

Laboratorio 2 Prof. A. Bello

Page 20: Material de Prolog para el Laboratorio 2 de Fundamentos de Programación.pdf

INF220 – Fundamentos de Programación 20

La relación del nivel superior, solución() tiene que ser generalizada, por tanto a:

solucion(N,S).

Donde N es el tamaño del tablero y S es una solución representada como una lista de las y-coordenadas delas n-reinas. La relación solución() generalizada será:

solucion(N,S):– gen(1,N,Dxy), %Dxy – dominio para X e YNu1 is 1–N,Nu2 is N–1,gen(Nu1,Nu2,Du),Nv2 is N+N,gen(2,Nv2,Dv),sol(S,Dxy,Dxy,Du,Dv).

El programa completo será:

Por ejemplo una solución al problema de las 12-reinas debería ser generado por la siguienteconsulta:

Queda claro que el primer termino del predicado reinas3 es la dimensión del tablero.

Laboratorio 2 Prof. A. Bello

Page 21: Material de Prolog para el Laboratorio 2 de Fundamentos de Programación.pdf

INF220 – Fundamentos de Programación 21

Programación Gráfica en Prolog

En SWI-Prolog la librería XPCE implementa la programación gráfica en Prolog. Los predicadosque nos proporcionan XPCE para realizar gráficos en pantalla, siguen un paradigma orientado aobjetos en lugar de programación lógica.

El manual completo lo puede encontrar en:

www.swi-prolog.org/download/ xpce /doc/userguide/userguide.pdf

El objetivo es adaptar una solución gráfica a algunos de los problemas expuestos en estematerial.

El problema de las 8 reinas de forma gráfica

A continuación presentamos un programa que muestra un ventana con tres botones que permitemostrar todas las soluciones de las ocho reinas de forma gráfica, limpiar el tablero y terminar.

Laboratorio 2 Prof. A. Bello

Page 22: Material de Prolog para el Laboratorio 2 de Fundamentos de Programación.pdf

INF220 – Fundamentos de Programación 22

Al ejecutar el objetivo:

Aparecerá la siguiente ventana con los botones para controlar el programa:

Laboratorio 2 Prof. A. Bello

Page 23: Material de Prolog para el Laboratorio 2 de Fundamentos de Programación.pdf

INF220 – Fundamentos de Programación 23

Es importante señalar que los archivos tablero-ajedrez.jpg y reina.jpg deben encontrarse en eldirectorio indicado en el predicado pce_image_directory(), de lo contrario Prolog no encontrarálas imágenes y mostrará un mensaje de error. Para que usted pueda repetir este programa, juntocon este archivo se han adjuntado los archivos jpg empaquetados en un zip.

El programa muestra un botón con las opciones: Limpiar, Siguiente y Finalizar. Para mostrarlas configuraciones una a una en su pantalla, emplee el segundo botón. Es importante señalarque si desea acabar, no debe cerrar las ventanas, sino presionar la opción Finalizar, si no haceesto cuando vuelva a ejecutar el programa obtendrá un error.

TAREA

1.- Analice y entienda como funciona el programa 8reinasGrafico.pl

2.- Modifique el programa para que muestre un número que indique el orden de las soluciones.

3.- Modifique el programa de modo que se le agregue otras funcionalidades.

Laboratorio 2 Prof. A. Bello

Page 24: Material de Prolog para el Laboratorio 2 de Fundamentos de Programación.pdf

INF220 – Fundamentos de Programación 24

El sudoku en forma gráfica

Se pide elaborar un programa en Prolog que implemente el predicado sudokuGraf. A estepredicado se le invoca pasándole una lista, y debe mostrar en forma gráfica el sudokucorrespondiente al que representa, tal como se muestra a continuación

sudokuGraf([[_,_,1,5,_,_],[_,_,2,6,_,_],

[_,6,_,_,3,_],[_,1,_,_,4,_],[_,_,3,4,_,_],[_,4,_,_,5,_]]).

Laboratorio 2 Prof. A. Bello

Page 25: Material de Prolog para el Laboratorio 2 de Fundamentos de Programación.pdf

INF220 – Fundamentos de Programación 25

TAREA

1.- Analice y entienda como funciona el programa sudoku_grafico.pl

2.- Modifique el programa para que determine dos comportamientos distintos. Si la lista querecibe como argumento están incompletas, el programa debe mostrar dos imágenes. La primeradebe ser la representación gráfica del sudoku aún no solucionado y en la segunda la imagenque corresponde a la solución. Si la lista que recibe está completa, entonces solo debe mostrar laimagen que representa.

sudokuGraf([[_,_,1,5,_,_],[_,_,2,6,_,_],

[_,6,_,_,3,_],[_,1,_,_,4,_],[_,_,3,4,_,_],[_,4,_,_,5,_]]).

3.- Modifique el programa de modo que se le agregue otras funcionalidades.

Laboratorio 2 Prof. A. Bello

Page 26: Material de Prolog para el Laboratorio 2 de Fundamentos de Programación.pdf

INF220 – Fundamentos de Programación 26

Ejercicios

1. Escriba un predicado, usando el predicado añadir(), para borrar los tres últimoselementos de una lista L produciendo otra lista L1.

Sugerencia: L es la concatenación de L1 y una lista de tres elementos.

2. Escriba un predicado para borrar los primeros tres elementos y los últimos tres elementosde una lista L produciendo una lista L2.

3. Defina un predicado último(Item,L) de modo que Item es el último elemento de unalista L. Escriba dos versiones: (a) usando el predicado añadir, (b) sin añadir.

4. Defina la relación:

desplaza(Lista1,Lista2)

De modo que Lista2 es Lista1 desplazado rotacionalmente por un elemento por laizquierda. Por ejemplo:

desplaza([1,2,3,4,5],L1),desplaza(L1,L2).

ProduceL1 = [2,3,4,5,1]L2 = [3,4,5,1,2]

5. Defina la relación

subconjunto(Conjunto,Subconjunto).

Donde Conjunto y Subconjunto son dos listas representando conjuntos. Debería serposible usar esta relación no sólo para chequear la relación subconjunto, sino también paragenerar todos los posibles subconjuntos de un conjunto dado. Por ejemplo:

subconjunto([1,2,3],S).

ProduceS = [1,2,3]S = [1,2]S = [1,3]S = [2,3]S = [1]S = [2]S = [3]S = []

6. Defina la relación

dividelista(Lista,Lista1,Lista2).

De modo que los elementos de Lista sean partidos entre Lista1 y Lista2, y Lista1y Lista2 deben ser aproximadamente de la misma longitud.

Laboratorio 2 Prof. A. Bello

Page 27: Material de Prolog para el Laboratorio 2 de Fundamentos de Programación.pdf

INF220 – Fundamentos de Programación 27

Por ejemplo,

dividelista([1,2,3,4,5],L1,L2).Produce

L1 = [1,2,3]L2 = [4,5]

7. Defina el predicado

subsuma(Conjunto,Suma,Subconjunto).

De modo que Conjunto sea una lista de números, Subconjunto es un subconjunto de estosnúmeros, y la suma de los números en Subconjunto es Suma.

8. Defina el predicado

between(N1,N2,X).

El cual para dos números dados N1 y N2, genere a través del bactracking todos los enterosX que satisfagan la restricción N1 ≤ X ≤ N2.

9. Un alumno de Ingeniería Informática debido al nerviosismo del primer día de clases, sólorecuerda el nombre de sus profesores: Neymar, Messi y Tévez, las asignaturas que se impartenson: Algoritmos, Programación Lógica y Arquitectura de Computadoras y el día de la semanade las distintas clases son: lunes, miércoles y jueves. Además recuerda que:

a) La clase de Programación Lógica, impartida por Neymar, es posterior a la deAlgoritmos.

b) A Tévez no le gusta trabajar los lunes, día en que no se imparte Algoritmos.

Elabore un programa en Prolog que sea capaz de relacionar cada profesor con su asignatura, asícomo el día de la semana que se imparte.

NOTA: Se sabe que cada profesor imparte una única asignatura, y que las clases se dan en díasdiferentes. 10. Se dice que el siguiente problema fue escrito por Einstein en el siglo pasado. Ha sidotraducido y mejorado desde entonces, pero la lógica es la misma.

DATOS 1. Tenemos 5 casas de colores distintos. 2. Hay 5 personas de diferente nacionalidad, siendo, cada una dueña de una casadistinta. 3. Estas cinco personas toman alguna bebida, fuman cigarrillos de una marca y tienenmascota, todas respectivamente distintas. PREMISAS: 1. El inglés vive en la casa roja. 2. La mascota del sueco es un perro. 3. El danés bebe té. 4. La casa verde es la inmediata de la izquierda de la casa blanca. 5. El dueño de la casa verde toma café. 6. La persona que fuma Pall Mall cría pájaros.

Laboratorio 2 Prof. A. Bello

Page 28: Material de Prolog para el Laboratorio 2 de Fundamentos de Programación.pdf

INF220 – Fundamentos de Programación 28

7. El dueño de la casa amarilla fuma Dunhill. 8. El hombre que vive en la casa del centro toma leche. 9. El noruego vive en la primera casa. 10. La persona que fuma Blend vive junto a la que tiene gatos. 11. El hombre que tiene caballos vive junto al que fuma Dunhill. 12. La persona que fuma Blue Master bebe cerveza. 13. El alemán fuma Prince 14. El noruego vive junto a la casa azul. 15. El hombre que fuma Blend tiene un vecino que bebe agua.

Se pide un programa en Prolog que proporcionándole las reglas correspondientes devuelva enlistas los datos de los que viven en cada casa.

El objetivo debe ser invocado como una lista

?- puzzle_einstein([L1,L2,L3,L4,L5]).

El resultado deberá presentar la siguiente forma:

L1 = [aaa, . . . , bbb ],L2 = [ccc, . . . , ddd ],L3 = [eee, . . . , fff ],L4 = [ggg, . . . , hhh ],L5 = [iii, . . . , jjj ],

11.- Elaborar un programa en Prolog para solucionar un sudoku de 3x3. El tiempo que tome elprograma en obtener la solución debe ser razonable.

Objetivos del laboratorio

La evaluación del laboratorio tendrá por objetivo evaluar las siguientes :

1) El alumno es capaz de obtener una solución a problemas nuevos o semejantes(modificados) a los mostrados en esta guía.

2) El alumno es capaz de implementar una solución gráfica a uno de los problemascontenidos en esta guía.

Laboratorio 2 Prof. A. Bello