Práctica 5 Especificación con tipos compuestos Algoritmos y Estructura de Datos I Primer Cuatrimestre 2008 1. Tipo Racional Sea el tipo de datos compuesto Racional que representa los números racionales. tipo Racional{ observador numerador(t : Racional) : Z observador denominador(t : Racional) : Z invariante denominador(r) 6= 0 invariante mcd(denominador(r), numerador(r)) == 1 aux mcd(a, b : Z) : Z = max[i|i ← Z, a mod i == 0, b mod i == 0] } ; Ejercicio 1. ¿Es correcta la siguiente especificación para el producto entre dos números racionales r1 y r2 ? problema producto(r1 , r2 : Racional) = res : Racional{ asegura : denominador(res) = denominador(r1 ) ∗ denominador(r2 ); asegura : numerador(res) = numerador(r1 ) ∗ numerador(r2 ); } Ejercicio 2. Especificar las siguientes operaciones: 1. problema nuevoRac(r1 , r2 : Z) = res : Racional que dados dos enteros, obtiene el racional a b. 2. problema menor(r1 , r2 : Racional) = res : Bool, que devuelve verdadero si y sólo si r1 es menor que r2 . 3. problema suma(r1 , r2 : Racional) = res : Racional, que devuelve la suma de r1 y r2 . 4. problema representacionEntera(r : Racional) = res : Z, que devuelve, en caso de que sea posible, el número entero equivalente a r. 2. Tipo Vector tipo Vector{ observador abscisa(t : V ector) : R observador ordenada(t : V ector) : R } Ejercicio 3. Sobre este tipo, especificar las siguientes operaciones: 1 1. problema igualX(v1 , v2 : Vector) = result : Bool, que devuelve True sii v1 y v2 tienen la misma componente x. 2. problema igualY(v1 , v2 : Vector) = result : Bool, que devuelve True sii v1 y v2 tienen la misma componente y. 3. problema colineales(v1 , v2 : Vector) = result : Bool, que devuelve True sii v1 y v2 son linealmente dependientes. 4. problema módulo(v : Vector) = result : R, que devuelve el módulo de v. 5. problema productoEscalar(v1 , v2 : Vector) = result : R. 6. problema todosColineales(V : [Vector]) = result : Bool, que dice si todos los vectores de la lista son colineales tomados de a pares. 7. problema resultante(V : [Vector]) = result : Vector, que calcula la resultante entre todos los vectores de la lista. 8. problema primerCuadrante(V : [Vector]) = result : [Vector], que devuelve una lista con todos los vectores de V que están en el primer cuadrante. 9. problema equilibrio(V : [Vector]) = result : Bool, que indica si la resultante entre todos los vectores de la lista es cero. 3. Tipo Pirámide Ejercicio 4. Sea el tipo Piramide definido de la siguiente forma: tipo Piramide{ observador altura(Piramide) : Z Devuelve un entero no negativo que indica la altura de una pirámide. observador valor(p : Piramide, f : Z, c : Z) : Z{ Permite saber el valor en una casilla de fila f y columna c. requiere : 1 ≤ c ≤ f ≤ altura(p); } invariante altura(p) ≥ 0 } Ejemplos de Pirámides y sus observadores son: 11 21 31 41 39 22 32 42 43 22 17 13 9 8 33 44 5 8 P1 1 7 P2 altura(P1 ) valor(P1 , 1, 1) = 4 = 11 valor(P2 , 3, 2) = 9 Especificar los siguientes problemas sobre el tipo Piramide: 1. problema todosIguales(P : Piramide) = result : Bool, que es True si todos los elementos de la pirámide son iguales. 2 2. problema esAscendente(P : Piramide) = result : Bool, que devuelve True sii los valores de todas las casillas que se encuentran en un piso son menores que aquellos que se encuentran en las casillas de los pisos que están más abajo. 3. problema sumarTodos(P : Piramide) = result : Z, que devuelve la suma de los valores de todas las casillas de P . 4. problema mayoresQueN(P : Piramide, n : Z) = result : [Z], que dada P y un entero n, devuelve el conjunto de los valores de las casillas de P que son mayores que n. 5. problema subpiramides(P : Piramide, n : Z) = result : [Piramide], que dada una pirámide P y un entero n positivo y menor que la altura de P , devuelva un conjunto con todas las subpirámides de P de altura n. 6. Un camino en una pirámide P es una secuencia de al menos 2 y a lo sumo altura(P ) casillas válidas distintas, tal que en cada par de casillas consecutivas en la secuencia, la primera está apoyada sobre la segunda. Las casillas las representaremos como pares ordenados: (fila, columna). Por ejemplo, tanto en P1 como en P2 , [(1, 1), (2, 2), (3, 2), (4, 3)] y [(2, 1), (3, 2)] son caminos. Especificar el problema hayCaminoDeIguales(P : Piramide, n : Z) = result : Bool, que devuelve True sii P tiene un camino de longitud n en el que todos sus elementos tienen el mismo valor (n debe ser una longitud posible para un camino en P ). 7. Se dice que una pirámide está bien formada cuando el valor de cada celda es igual a la suma de las dos celdas inferiores (si es que existen). Es decir, cuando en todas sus celdas se verifica: A+B A B Por ejemplo, P1 no está bien formada porque valor(P1 , 1, 1) 6= valor(P1 , 2, 1) + valor(P1 , 2, 2). En cambio, P2 está bien formada. Se pide especificar: problema bienFormada(P : Pir0 amide) = result : Bool, que indique si P está bien formada. 4. Trenes y Terminales Se cuenta con el tipo enumerado TipoVagon = hLocomotora, Pasajero, Cargai y con el tipo compuesto Vagon: tipo Vagon{ observador tipo(v : V agon) : T ipoV agon observador peso(v : V agon) : Z observador carga(v : V agon) : Z{ requiere : tipo(v) 6= Locomotora; } observador potencia(v : V agon) : Z{ requiere : tipo(v) == Locomotora; } invariante peso(v) > 0 invariante carga(v) > 0 invariante potencia(v) > 0 } Un vagón puede ser una locomotora, un coche de pasajeros o un vagón de carga. Todos los vagones tienen peso (en Toneladas). Una locomotora tiene una determinada potencia que se refleja en la 3 cantidad de Toneladas que puede arrastrar. La carga en un coche de pasajeros es la cantidad máxima de pasajeros que puede transportar, mientras que en uno de carga, representa el tonelaje máximo que puede cargar. También tenemos el tipo Tren que es un sinónimo de [Vagon]. En un tren pueden aparecer más de una locomotora y no necesariamente encabezando el convoy. Por último, se tiene el tipo compuesto Terminal: tipo Terminal{ observador cantA(t : Terminal) : Z Devuelve la cantidad de andenes observador longA(t : Terminal) : Z Devuelve la cantidad máxima de vagones por andén observador iesimoTren(i : Z, t : Terminal) : Tren{ requiere : 0 ≤ i < cantA(t); } Devuelve el tren en el i-ésimo andén invariante cantA(t) > 0 invariante longA > 0 invariante V agonesN oDemasiadoLargos(t) } Notar que si en un andén hay un tren de longitud cero, significa que el andén está vacı́o. Ejercicio 5. Sobre el tipo Terminal especificar el invariante VagonesNoDemasiadoLargos(t), que indica que en la terminal no hay vagones más largos que la longitud del anden. Ejercicio 6. Especificar los siguientes problemas: 1. problema cabeEn(t, u : Tren) = result : Bool donde t y u son trenes conformados por vagones del tipo Carga. Devuelve True en caso de que el tren t tenga menor carga que el tren u. 2. Dado un tren, decidir si el tren se puede mover. Para que un tren se mueva, la suma de las potencias de las locomotoras tiene que ser mayor o igual a la suma de los pesos de todos los vagones suponiendo que todas las personas pesan 80kg. 4