Examen II - Universidad Simón Bolívar

Anuncio
Universidad Simón Bolívar
Departamento de Computación y Tecnología de la Información
CI2612 – Algoritmos y Estructuras II
Abril-Julio 2011
Carnet:
Nombre:
Examen II
(35 puntos)
Antes de empezar, revise bien el examen, el cual consta de 3 (tres) preguntas.
Pregunta 0
Pregunta 1
Pregunta 2
Total
8 puntos
10 puntos
17 puntos
35 puntos
Pregunta 0 - 8 puntos
En relación con los textos sobre tipos abstractos de datos (TADs) recomendados en el curso, responda las
siguientes preguntas:
(0.0) En el texto de Barbara Liskov (con John Guttag), “Program Development in Java – Abstraction, Specification, and Object-Oriented Design”, la autora sugiere que la “abstraction function” y la “representation
invariant” sean implementadas para mejorar la confiabilidad de los programas. Explique muy brevemente
qué son estas dos componentes y cómo sugiere Liskov implementarlas.
(0.1) En el texto de Richard Mitchell, “Abstract Data Types and Modula-2”, el autor utiliza el lenguaje OBJ
además de otros. Explique qué tipo de lenguaje es OBJ e indique cuáles TADs son trabajados por Mitchell
con este lenguaje.
(0.2) Continuando con el texto de Richard Mitchell, el autor sugiere tres posibilidades para llevar operaciones
de la especificación de un TAD hacia subrutinas de una implementación. Explique dos de ellas.
Pregunta 1 - 10 puntos
En esta pregunta trabajaremos con un tipo abstracto de datos (TAD) para multiconjuntos, cuyos elementos
serán de algún tipo cualquiera T , con la restricción de que se debe disponer de una relación de orden total “v”
sobre T . Para implementar el TAD, se decide utilizar un arreglo ordenado como estructura de datos.
A continuación se presentan una especificación de este TAD con modelo abstracto con sólo una de sus operaciones
y la re-especificación correspondiente del TAD con el modelo concreto propuesto:
Especificación A de TAD MultiCjto (T )
Modelo de Representación
const tmax : int
var m : bag (T )
Invariante de Representación
tmax > 0 ∧ # m 6 tmax
Operaciones
..
.
proc intersectar ( in-out a : MultiCjto ; in b : MultiCjto )
{ Pre : true }
{ Post : a.m = a 0 .m ∩ b.m }
..
.
Fin TAD
Especificación B de TAD MultiCjto (T ) , refinamiento de A
Modelo de Representación
const tmax : int
var elems : array [ 0..tmax ) of T
tam : int
Invariante de Representación
tmax > 0 ∧ 0 6 tam 6 tmax
∧
( ∀ i, j : 0 6 i < j < tam : elems[i] v elems[j] )
Relación de Acoplamiento
m = bb i : 0 6 i < tam : elems[i] cc
Operaciones
..
.
proc intersectar ( in-out a : MultiCjto ; in b : MultiCjto )
{ Pre : true }
{ Post : bb i : 0 6 i < a.tam : a.elems[i] cc
= bb i : 0 6 i < a 0 .tam : a 0 .elems[i] cc ∩ bb i : 0 6 i < b.tam : b.elems[i] cc }
..
.
Fin TAD
En las especificaciones presentadas, consideramos que el operador unario # da la cantidad de elementos de
un multiconjunto. También consideramos que la operación de intersección de multiconjuntos corresponde a la
definición dada por Morgan en la referencia bibliográfica recomendada para este curso, que toma la cantidad
mínima de ocurrencias de cada elemento. Por ejemplo: bb 2, 2, 4, 5, 8, 8, 8 cc ∩ bb 2, 3, 3, 4, 4, 8, 8 cc = bb 2, 4, 8, 8 cc .
Se desea entonces, específicamente, que Ud. implemente la operación intersectar de la especificación B con modelo
concreto. Su solución debe ser iterativa, y debe indicar cota variante de terminación de toda iteración que utilice.
No hace falta que indique invariantes de sus iteraciones.
Note que una buena manera de implementar esta operación se logra mediante una variante del auxiliar mezclar
del algoritmo de ordenamiento por mezcla, por lo que se exige que su implementación tenga tiempo de ejecución
cuyo peor caso sea de complejidad O (a.tam + b.tam) .
Pregunta 2 - 17 puntos
En esta pregunta trabajaremos con un tipo abstracto de datos (TAD) para colas, cuyos elementos serán de algún
tipo cualquiera T .
A continuación se presenta una especificación de este TAD con modelo abstracto basado en una secuencia de
tamaño acotado. Las operaciones sobre secuencias que se utilizan en la especificación son las del texto de Morgan
recomendado como referencia bibliográfica para este curso.
Especificación A de TAD Cola (T )
Modelo de Representación
const tmax : int
var contenido : seq (T )
Invariante de Representación
tmax > 0 ∧ # contenido 6 tmax
Operaciones
proc vacia ( out c : Cola )
{ Pre : true }
{ Post : c.tmax > 0 ∧ c.contenido = h i }
proc encolar ( in-out c : Cola ; in e : T )
{ Pre : # c.contenido < c.tmax }
{ Post : c.contenido = c0 .contenido ++ hei }
proc desencolar ( in-out c : Cola )
{ Pre : c.contenido 6= h i }
{ Post : c.contenido = tl (c0 .contenido) }
proc primero ( in c : Cola ; out e : T )
{ Pre : c.contenido 6= h i }
{ Post : e = hd (c.contenido) }
proc esVacia ( in c : Cola ; out v : boolean )
{ Pre : true }
{ Post : v ≡ (c.contenido = h i) }
Fin TAD
Continúa. . .
Para la implementación de nuestro TAD, utilizaremos arreglos de manera análoga a la implementación de colas
mediante arreglos presentada en el texto de Cormen et al. que utilizamos como referencia bibliográfica en este
curso. Note que en esta implementación el arreglo es declarado de tamaño tmax +1 , desperdiciándose así una
casilla de éste.
La nueva especificación del TAD con el modelo concreto propuesto basado en arreglos sería la siguiente:
Especificación B de TAD Cola (T ) , refinamiento de A
Modelo de Representación
const tmax : int
var a : array [ 0..tmax +1 ) of T
inic, fin : int
Invariante de Representación
tmax > 0 ∧ 0 6 inic 6 tmax
∧
0 6 fin 6 tmax
Relación de Acoplamiento
( inic 6 fin ⇒ contenido = h i : inic → fin • a[i] i )
∧
( inic > fin ⇒ contenido = h i : inic → tmax +1 • a[i] i ++ h i : 0 → fin • a[i] i )
Operaciones
proc vacia ( out c : Cola )
{ Pre : true }
{ Post : c.tmax > 0 ∧ c.inic = 0 ∧ c.fin = 0 }
proc encolar ( in-out c : Cola ; in e : T )
{ Pre : c.inic 6= (c.fin + 1) mod (c.tmax +1) }
{ Post : c.a = c0 .a(c0 .fin : e)
∧ c.inic = c0 .inic
∧ c.fin = (c0 .fin + 1) mod (c.tmax +1) }
proc desencolar ( in-out c : Cola )
{ Pre : c.inic 6= c.fin }
{ Post : . . . }
proc primero ( in c : Cola ; out e : T )
{ Pre : c.inic 6= c.fin }
{ Post : e = c.a[c.inic] }
proc esVacia ( in c : Cola ; out v : boolean )
{ Pre : true }
{ Post : v ≡ (c.inic = c.fin) }
Fin TAD
Recuerde que en la notación utilizada por Morgan para definición de secuencias por comprensión, teniendo
a x como variable generadora, teniendo enteros n y m, y teniendo una expresión E sobre x, la expresión
h x : n → m • E i define la secuencia resultante de tomar valores en orden para x del rango [ n..m ) y obtener elementos para la secuencia a partir de la expresión E. Así, por ejemplo, tenemos que h x : 2 → 5 • x2 i = h 4, 9, 16 i
y que h x : 1 → 5 • −x i = h −1, −2, −3, −4 i .
Continúa. . .
Basándose entonces en las especificaciones anteriores, responda las siguientes preguntas:
(2.0) Complete la postcondición de la operación desencolar en la especificación B con modelo concreto.
(2.1) Dé una implementación para la operación encolar de la especificación B con modelo concreto.
(2.2) Demuestre formalmente que las postcondiciones de la operación esVacia en las dos especificaciones se
corresponden adecuadamente, según la noción de refinamiento de datos.
Ayuda – Le puede resultar útil la siguiente propiedad de “secuencia por comprensión vacía”:
n6m
⇒
( h x : n→m • E i = h i ≡ n = m ) ,
con variable generadora x cualquiera, enteros n y m cualesquiera, y expresión E cualquiera. También le
puede resultar útil la siguiente propiedad de “concatenación vacía de secuencias”:
s0 +
+ s1 = h i
≡
s0 = h i ∧ s1 = h i ,
con s0 y s1 secuencias cualesquiera.
(2.3) En la implementación propuesta en el texto de Cormen et al., recién presentada en la especificación B, se
desperdicia una casilla del arreglo al declararlo con tamaño tmax +1.
La razón por la que se desperdicia una casilla es para evitar que se confundan las situaciones de “cola vacía”
y “cola llena”. Esto se debe a que, de contar sólo con tmax casillas, al llenarse la cola con tmax elementos
el índice fin volvería a alcanzar al índice inic, esto es, ambos índices volverían a ser iguales como cuando
no hay ningún elemento en la cola.
De allí que Cormen et al. opten por tener un arreglo con una casilla de exceso para diferenciar las dos
situaciones extremas. Sin embargo, hay otra manera de diferenciar las situaciones extremas sin necesidad
de la casilla de exceso, que es teniendo un atributo booleano que indique si la cola está llena o no. Esto
correspondería a tener el siguiente nuevo modelo concreto:
const tmax : int
var a : array [ 0..tmax ) of T
inic, fin : int
llena : boolean
en el que no hay casilla de exceso pero se tiene un nuevo atributo booleano.
Indique parcialmente qué le cambiaría al resto de la especificación con modelo concreto, señalando específicamente lo siguiente: qué le agregaría al invariante de representación y cómo cambiaría la relación de
acoplamiento.
Descargar