PROGRAMACIÓN DECLARATIVA ESTRUCTURAS DE DATOS Listas 1. Definir predicados Prolog referentes a listas con los siguientes significados: miembro(Elem,Lista) "Elem pertenece a Lista" longitud(Lista,Long) "Lista tiene Long elementos" último(Lista,Elem) "Elem es el último elemento de Lista" concatenar(L1,L2,L1L2) "Lista12 es el resultado de concatenar Lista1 y Lista2" suprimir(LElem,Elem,L) "L es la lista LElem con Elem suprimido" invertir(Lista,Atsil) "Atsil es la inversa de Lista" prefijo(Sublista,Lista) "Sublista es prefijo de Lista" sufijo(Sublista,Lista) "Sublista es sufijo de Lista" sublista(Sublista,Lista) "Sublista es una sublista de Lista" adyacentes(X,Y,Lista) "X e Y son adyacentes en Lista" quicksort(Lista,Ailst) "Ailst es Lista ordenada mediante quicksort" burbuja(Lista,Ailst) "Ailst es Lista ordenada mediante el método de la burbuja" sumar(ListaEnteros,Suma) "Suma es el resultado de sumar los elementos de ListaEnteros" producto(Lista1,Lista2,Prod) "Prod es el producto escalar de Lista1 y Lista2" Arboles 2. Se define un árbol del modo siguiente: -la constante vacío es un árbol. -el término compuesto árbol(X,Y,Z) es un árbol si Y y Z son árboles. Definir predicados Prolog referentes a árboles con los siguientes significados: es_árbol(Arbol) "Arbol es un árbol" miembro_árbol(Elem,Arbol) "Elem pertenece a Arbol" árboliso(A1,A2) "A1 y A2 son árboles isomorfos" "A2 se puede obtener reordenando las ramas de A1" sustituir(X,Y,ArbX,ArbY) "ArbY es ArbX donde todo X se sustituye por Y" preorden(Arbol,Pre) "Pre es una lista con el recorrido en preorden de Arbol" inorden(Arbol,In) "In es una lista con el recorrido en inorden de Arbol" postorden(Arbol,Post) "Post es una lista con el recorrido en postorden de Arbol" subárbol(Subárbol,Arbol) "Subárbol es un subárbol de Arbol" insertar(Elem,Arbol,ArbolN) "ArbolN es un árbol ordenado resultante de insertar Elem en el árbol ordenado Arbol. Si Elem pertenece a Arbol, entonces Arbol y ArbolN son idénticos" Grafos 3. Escribir un programa en Prolog que de los distintos recorridos que unen los cinco vértices de la figura según los trazos marcados, sin realizar dos veces el mismo trazo. PRÁCTICAS 1 1 PROGRAMACIÓN DECLARATIVA Matrices 4. Se desean representar las matrices numéricas en Prolog con términos de la forma: [fila1, fila2, _, filan ] donde cada filai se representa por una lista: [elementoi1, elementoi2, _, elementoin] Por ejemplo, la lista [ [1,2,3], [4,5,6], [7,8,9] ] representará la matriz cuya primera fila es (1 2 3), la segunda (4 5 6) y la tercera (7 8 9). Se pide definir los siguientes predicados: es_matriz(T) "se satisface cuanto T es una matriz numérica" suma(M1,M2,S) "S es la matriz suma de M1 y M2. Supóngase que M1 y M2 están ya instanciados a términos de base" simétrica(M) "se satisface cuando M es una matriz simétrica" 5. Consideremos una base de datos conteniendo hechos de la forma array(Ident,Indices,Array). donde: Ident representa el nombre del array. Indices es una lista que contiene la dimensión del array; cada elemento de la lista representa el índice máximo, y se supone que el índice mínimo es siempre 1. Array es una lista de listas, con una profundidad que coincide con la longitud de Indices. Por ejemplo: array(a,[2,3],[[a11,a12,a13],[a21,a22,a23]]). array(b,[2,3,2],[[[b111,b112],[b121,b122],[b131,b132]],[[b211,b212],[b221,b222],[b231,b232]]] Implementar los siguientes predicados Prolog: a) valor/3 b) asignar/3 c) posición/3 2PRÁCTICAS 1 % valor(a,[i,j],aij) % asignar(a,[i,j],a0) _ valor(a,[i,j],a0) % posición(a,aij,[i,j]) 2 PROGRAMACIÓN DECLARATIVA USO DE ACUMULADORES 1. Dar versiones recursivas e iterativas de los predicados. factorial(N,F) F es N! sumar_lista(Xs,Sum) Sum es la suma de los elementos de la lista Xs producto_escalar(Xs,Ys,P) P es el producto escalar de los vectores Xs e Ys (listas) máximo(Xs,Max) Max es el máximo entero de la lista Xs longitud(Xs,Long) Long es el tamaño de la lista Xs INSPECCION DE ESTRUCTURAS 2. Definir en Prolog predicados para: compuesto(Term) Term es un término compuesto linealizar(Xss,Xs) Xs es la lista resultante de linealizar Xss (lista de listas) subtérmino(SubTerm,Term) SubTerm es un subtérmino de Term sustituir(V,N,VT,NT) NT es el resultado de sustituir V por N en VT ocurrencias(Sub,Term,N) N es el número de apariciones de Sub en Term. Supóngase que Term es básico. básico(Term) En Term no aparecen variables 3. Definir un predicado posición(Subterm,Term,Posición) donde Posición es una lista de posiciones que identifican Subtérm dentro de Term. Por ejemplo, la posición de X en Y+sen(X) es [2,1], pues sen(X) es el segundo argumento del operador binario +, y X es el primer argumento de sen(X). 4. Definir el predicado =../2 en función de functor/3 y arg/3. METAPROGRAMACION 5. a) Escribir un predicado Prolog que implemente la siguiente función: aplica : (T→S) → Lista[T] → Lista[S], dada por: aplica(f,[a1,a2,...,an ]) = [f(a1),f(a2),...,f(an )], ai∈T, f∈ (T→S) b) Aplicar el predicado anterior para definir predicados que determinen: b.1) El código BCD de un número decimal expresado como una lista de dígitos. b.2) La primera columna de una matriz representada por: [ [a11, a12,..., a1n ], [a21, a22,..., a2n ], ... [am1, am2,..., amn ] ] b.3) La lista resultante de sustituir 'n' por 'ñ' en una lista compuesta por caracteres. 6. a) Modificar la definición de aplica/3 del ejercicio anterior para generalizar la solución del apartado (5.b.2), de forma que se pueda determinar la i-ésima columna (1 ≤ i ≤ n); y la del apartado (5.b.3) para poder sustituir una letra cualquiera por cualquier otra. b) Aplicar el predicado obtenido en el apartado anterior para obtener el conjunto, L, de todos los subconjuntos de un conjunto dado, X, siguiendo el algoritmo que se especifica a continuación: Si X=Ø entonces L={ Ø } Si x∈X entonces L=L1 ∪ L2, siendo L1 el conjunto de subconjuntos de X-{x}, y L2 = {{x}∪l : l∈L1} (Nota: Los conjuntos se representan mediante una lista de elementos no repetidos). PRÁCTICAS 2 3 PROGRAMACIÓN DECLARATIVA PROGRAMACION DE SEGUNDO ORDEN 7. a) Utilizando el predicado setof/3, definir el predicado paratodo/2, que se verifica cuando todas las instancias del primer argumento verifican la propiedad dada por el segundo. Por ejemplo, paratodo(miembro(X,[2,4,6]),par(X)). b) Comparar la solución anterior con: paratodo(Objetivo,Condición) :- not(Objetivo,not Condición) 8. Usualmente el predicado conectados/2, que determina cuándo dos nodos están unidos mediante un camino en un grafo, se define haciendo uso de una búsqueda primero en profundidad. Utilizar el predicado setof/3 para utilizar una búsqueda primero en amplitud. PREDICADOS EXTRALOGICOS 9. Utilizando un bucle controlado por fallo, implementar en Prolog el predicado consult/1, que permite consultar las cláusulas de un archivo. (NOTA: Una llamada del tipo see(Fichero), convierte a Fichero en la entrada por defecto, mientras que seen vuelve a considerar el dispositivo de entrada estándar). 10. Definir el predicado suprimir/2, de forma que suprimir(F,N) elimina todas las cláusulas que definen el procedimiento F de aridad N. 11. a) Simular variables globales mediante un predicado global(Nombre,Valor), y la asignación a variables globales mediante asig_global(Nombre,NuevoValor). b) Utilizando los predicados anteriores, implementar el predicado generar_símbolo/1, que devuelve sobre el argumento un valor distinto en cada llamada. 12. Resolver los siguientes predicados utilizando funciones memo: fibonacci/2 hanoi/5 ESTRUCTURAS INCOMPLETAS 13. Usando diferencia de listas, implementar en Prolog: a) inversa(ListA,Atsil) b) linealizar(ListaDeListas,Lista) c) quicksort(ListA,Ailst) d) Un predicado que resuelva el problema de la bandera holandesa (Dijkstra), que consiste en reordenar una lista de elementos coloreados (rojo,blanco y azul), de forma que los elementos rojos aparezcan primero, seguidos por los blancos, y terminando por los azules. La reordenación debe hacerse manteniendo el orden relativo original de los elementos del mismo color. Por ejemplo, la lista [rojo(1),blanco(2),azul(3),rojo(4),blanco(5)] debería reordenarse como [rojo(1),rojo(4),blanco(2),blanco(5),azul(3)]. e) El predicado para resolver el problema de las torres de Hanoi. PRÁCTICAS 2 4 PROGRAMACIÓN DECLARATIVA 1. a) Implementar un predicado generar/3 de forma que: generar(Inicio,Num,Final) se satisfaga cuando Num sea un natural comprendido entre Inicio y Final. b) Implementar un predicado sumar/5 de forma que: sumar(Ac,Sum1,Sum2,Suma,AcN) se satisfaga cuando Ac+Sum1+Sum2 = Suma+10AcN. c) Implementar un predicado distinto/1 de forma que: distinto(Lista) se satisfaga cuando los elementos de Lista sean distintos entre sí. d) Escribir un programa Prolog que resuelva la siguiente suma: S E N D + M O R E M O N E Y e) Implementar un predicado Prolog resolversuma(Sumando1,Sumando2,Suma) que resuelva de forma genérica sumas como las anteriores, siendo Sumando1, Sumando2 y Suma listas de variables. Por ejemplo, resolversuma([S,E,N,D],[M,O,R,E],[M,O,N,E,Y]). 2. Escribir un programa Prolog que permita reconocer polinomios en algún término X. 3. Definir el predicado Prolog hanoi(N,A,B,C,Movimientos) que es cierto si Movimientos es la secuencia de movimientos para trasladar una torre de N discos desde el eje A al eje B utilizando el eje C. 4. El problema de laa N reinas consiste en situar N reinas sobre un tablero de ajedrez de N N escaques, de forma que ninguna de ellas esté en una posición que le permita capturar a otra (la misma fila, columna o diagonal). Es obvio que todas las posibles soluciones se pueden representar como listas de longitud N, formaas por los números enteros de 1 a N en cierto orden. Se pide definir los predicados: a) intervalo(X,Y,L), verdadero cuando L es una lista de los números enteros entre X e Y, ambos incluidos. b) permutación(L,P), verdadero si P es una lista permutación de la lista P. c) situación_segura(L), verdadero si L es una lista que representa una situación en la que no hay dos reinas en la misma diagonal. d) n_reinas(N.L), verdadero cuando L es una lista que representa una solución para el problema de las N reinas. 5. Una fórmula booleana es un término definido como sigue: -las constantes cierto y falso son fórmulas booleanas, -si X e Y son fórmulas booleanas, también lo son X o Y, X y Y, X implica Y y no X. Definir en Prolog el predicado: satisfactible(Fórmula) "Existe una instancia verdadera de Formula" NOTA: Para definir los operadores infijos y prefijos, utilizar el predicado op/3. 6. Escribir un programa Prolog que simule una sesión de consultas en un intérprete Prolog. PRÁCTICAS 3 5 PROGRAMACIÓN DECLARATIVA 7. Diseñar un editor de línea simple en Prolog, donde el fichero se represente mediante el término file(Antes,Después), siendo Antes y Después dos listas de líneas (strings) que se consideran separadas por el cursor. Las líneas antes del cursor estarán dispuestas en orden inverso para facilitar su acceso. El editor (visualizado mediante un prompt) debe aceptar una orden del teclado, y aplicarla para producir una versión nueva del fichero. Dichas órdenes son: up sube el cursor una línea up(N) sube el cursor N líneas down baja el cursor una línea insert(Línea) inserta en el fichero una Línea delete suprime la línea que está antes del cursor print imprime la línea que está detrás del cursor print(*) imprime el fichero completo 8. Tres alumnos hacen un examen de Lenguajes de Programación y obtienen tres notas distintas. Cada uno de ellos tiene un nombre diferente, preferencias por un tema distinto y proceden de especialidades de bachillerato distintas. A Francisco le gustan las Prácticas de Laboratorio, y obtuvo mejor nota que el procedente de Letras. Paco, el procedente del bachillerato de Ciencias, fue mejor que el aficionado a la Programación Funcional. El aficionado a la Programación Lógica fue el que mejor calificación obtuvo. ¿Quién es el procedente del bachillerato Mixto? ¿Cuál es el tema preferido por Curro? 9. Considerando la representación de una matriz dada por una lista de listas, implementar en Prolog los predicados: a) matriz(Matriz-,M+,N+) % Genera una matriz (primer argumento) de tamaño M N % con componentes variables b) submatriz(SubMat,Matriz) % Se satisface cuando SubMat es submatriz de Matriz c) Suponiendo que se dispone de tres tipos de piezas como las siguientes: Escribir un programa Prolog que permita construir un cuadrado de tamaño 4, combinando cuatro piezas como las anteriores. (Nota: Cada pieza puede representarse mediante una matriz de 2x3). 10. Escribir un programa Prolog que genere los movimientos que debe realizar un caballo de ajedrez para recorrer todas las casillas de un tablero cuadrado, sin pasar dos veces por la misma. La posición inicial y la dimensión del tablero se pasan como argumentos. PRÁCTICAS 3 6