Universidad Politécnica de Madrid Escuela Universitaria de Informática Departamento de Lenguajes, Proyectos y Sistemas Informáticos Asignatura PROGRAMACIÓN II EXAMEN DE LA CONVOCATORIA DE FEBRERO Plan: 92 / Curso: 2009-2010 Madrid, a 9 de Febrero de 2010 APELLIDOS: .................................. NOMBRE: ................................................. Nº DE MATRÍCULA: ........ DNI:................. GRUPO: ......................................... CALIFICACIONES TEORÍA PROB_1 PROB_2 TOTAL CUESTIONES TEÓRICAS Valoración: 3 puntos. Pregunta correcta:....................................0'2 puntos. Pregunta no contestada o incorrecta: .... -0'15 puntos I. PROGRAMACIÓN CONCURRENTE 1. Dibuje el diagrama de estados de un proceso. Preparado Ejecución Bloqueado 2. Responda SI o NO a las siguientes preguntas: a) ¿Puede un proceso bloquearse a sí mismo? SI b) ¿Puede un proceso bloquear a otro proceso? NO c) ¿Puede un proceso desbloquearse a sí mismo? NO d) ¿Puede un proceso desbloquear a otro proceso? SI Página 1 de 11 Programación II Febrero 2010 3. Dado el siguiente monitor y los siguientes procesos concurrentes: MONITOR M; PROCESS TProceso; EXPORT P; BEGIN PROCEDURE P; WRITE('SNC'); BEGIN WRITE('SNC'); WRITE('SC'); WRITE('SNC'); WRITE('SC'); M.P; WRITE('SC') WRITE('SNC'); END WRITE('SNC'); END; WRITE('SNC') END; Si desde un programa concurrente se invoca a N procesos de tipo TProceso, ¿se pueden intercalar en pantalla mensajes ‘SC’ con mensajes ‘SNC’? Razone la respuesta Sí se pueden intercalar, porque mientras un proceso está ejecutando el procedimiento del monitor, otos procesos pueden ejecutar el resto de instrucciones. 4. Escriba las relaciones que existen entre procesos concurrentes e indique con qué modo de interacción se resuelve cada una de ellas. Independencia: sin interacción Competencia: mediante Sincronización Cooperación: mediante Sincronización y Comunicación 5. Escriba en PASCAL-FC un monitor llamado SemaforoFIFO, que exporte los procedimientos Initial, Wait y Signal, según la semántica de estas operaciones aplicadas sobre un semáforo con política FIFO. MONITOR SemaforoFifo; EXPORT Initial, Wait, Signal; VAR contador:INTEGER cola:CONDITION; PROCEDURE Initial (valor:INTEGER); BEGIN contador := valor; END; PROCEDURE Wait; BEGIN IF contador = 0 THEN DELAY(cola) ELSE contador := contador - 1 END; PROCEDURE Signal; BEGIN IF NOT EMPTY(cola) THEN RESUME(cola) ELSE contador := contador + 1 END; Página 2 de 11 Programación II Febrero 2010 II. PROGRAMACIÓN ORIENTADA A OBJETOS 6. ¿Qué características ayudan a definir una relación de composición entre clases? Visibilidad: privada. Temporalidad: permanente Versatilidad: nula 7. En el análisis de una aplicación aparecen las clases siguientes: CLASS INTERFACE cPilaEnteros; PUBLIC METHODS CONSTRUCTOR cPilaEnteros; PROCEDURE Sacar (VAR Elemento : INTEGER); PROCEDURE Meter (Elemento : INTEGER); FUNCTION Vacia : BOOLEAN; END CLASS INTERFACE cPilaEnteros; CLASS INTERFACE cColaEnteros; PUBLIC METHODS CONSTRUCTOR cColaEnteros; PROCEDURE Sacar (VAR Elemento : INTEGER); PROCEDURE Meter (Elemento : INTEGER); FUNCTION Vacia : BOOLEAN; END CLASS INTERFACE cColaEnteros; Ambas clases tienen la misma implementación, excepto el método Sacar que es diferente en ambas clases. Codifique únicamente los interfaces de la solución que explote la reusabilidad del código y la integridad de la arquitectura del software. CLASS INTERFACE cDispensadorEnteros; PUBLIC METHODS CONSTRUCTOR cDispensadorEnteros; DEFERRED PROCEDURE Sacar (VAR Elemento : INTEGER); PROCEDURE Meter (Elemento : INTEGER); FUNCTION Vacia : BOOLEAN; END CLASS INTERFACE cDispensadorEnteros; CLASS INTERFACE cPilaEnteros; INHERITS FROM cDispensadorEnteros; PUBLIC METHODS CONSTRUCTOR cPilaEnteros; REDEFINED PROCEDURE Sacar (VAR Elemento : INTEGER); END CLASS INTERFACE cPilaEnteros; CLASS INTERFACE cColaEnteros; INHERITS FROM cDispensadorEnteros; PUBLIC METHODS CONSTRUCTOR cColaEnteros; REDEFINED PROCEDURE Sacar (VAR Elemento : INTEGER); END CLASS INTERFACE cColaEnteros Página 3 de 11 Programación II Febrero 2010 8. Dadas las vistas públicas de las siguientes clases: CLASS INTERFAZ cA; CLASS INTERFAZ cC; PUBLIC METHODS INHERITS FROM cB; PROCEDURE Metodo1; PUBLIC METHODS DEFERRED PROCEDURE Metodo2; REDEFINED PROCEDURE Metodo2; END CLASS INTERFACE cA; END CLASS INTERFACE cC; CLASS INTERFAZ cB; INHERITS FROM cA; PUBLIC METHODS REDEFINED PROCEDURE Metodo1; PROCEDURE Metodo3; END CLASS INTERFACE cB; Responda razonadamente la posible incorrección de las siguientes sentencias y, en caso correcto, qué método de qué clase se ejecuta suponiendo declarado: pA:POLYMORPHIC ^cA; a) NEW (pA, cB); pA^.Metodo1; INCORRECTO. Se instancia una clase abstracta b) NEW (pA, cC); pA^.Metodo1; CORRECTO. Se ejecuta el método heredado de la clase cB 9.¿En qué se diferencia la ley estricta de la ley flexible de Demeter? Con la ley flexible de Demeter, en la implantación de un método de una clase se tiene acceso también a los objetos definidos como atributos en la clase madre. Esto NO ocurre con la ley estricta. 10. Atendiendo al siguiente diagrama de clases, codifique en PIIPOO los atributos y métodos de las clases cA y cB necesarios para la implantación de sus relaciones. CLASS INTERFACE cA; PUBLIC METHODS CONSTRUCTOR cA; END CLASS INTERFACE cA; cA Composición cB Composición cC Asociación CLASS IMPLEMENTATION cA; ATTRIBUTES mpC: ^cC; mpB: ^cB; METHODS DEFINITION CONSTRUCTOR cA; BEGIN NEW (mpC, cC); NEW (mpB, cB(mpC) END; END CLASS IMPLEMENTATION cA; CLASS INTERFACE cB; PUBLIC METHODS CONSTRUCTOR cB (pC: ^cC); END CLASS INTERFACE cB; CLASS IMPLEMENTATION cB; ATTRIBUTES mpC: ^cC; METHODS DEFINITION CONSTRUCTOR cB (pC: ^cC); BEGIN mpC:=pC; END; END CLASS IMPLEMENTATION cB; Página 4 de 11 Programación II Febrero 2010 III. PROGRAMACIÓN FUNCIONAL 11. Defina el concepto de función polimórfica en Programación Funcional. Ponga un ejemplo. Son funciones que no establecen a priori un tipo de dominio o de rango concreto. Ej: hd: ‘a list->’a 12. ¿Cuáles de las siguientes líneas responden a posibles tipos de una función CAML?. Razone la respuesta. a) char -> char list SI, dominio tipo carácter -> rango tipo lista de caracteres b) (int , int) -> int NO, error en el tipo del dominio, el tipo tupla sería int*int c) _ * _ NO, el comodín es un patrón, no un tipo d) int -> _ -> bool SI, dominio tipo entero -> rango tipo booleano 13. Dado el siguiente valor ([(true, false)], true)y las funciones f1, f2, f3 y f4, indique sobre cuáles de ellas puede aplicarse. a) f1 : ‘a * ’b -> bool SI b) f2 : ‘a list * ’b -> bool SI c) f3 : (‘a * ’b) list * ’c -> bool SI d) f4 : (int * int) list * int -> bool NO 14. ¿Son correctos los siguientes patrones en CAML? En caso afirmativo, indique qué valores satisfacen el patrón. En caso negativo, razone la respuesta. a) (a::b)::_::c c) (a,false)::[]::b b) (a,false)::b::_ d) _::0::int list a) Correcto. Se satisface con cualquier lista formada por al menos dos listas de elementos de cualquier tipo, en la que la primera lista debe no estar vacía. b) Correcto. Se satisface con cualquier lista formada por al menos dos tuplas de dos elementos, en las que el primer elemento puede ser de cualquier tipo y en las que el segundo elemento debe ser un valor lógico. Además, el segundo elemento de la primera tupla debe ser el valor false. c) Incorrecto. Los elementos de una lista deben ser del mismo tipo, y este patrón describe una lista cuyo primer elemento es una tupla y el segundo elemento es la lista vacía. d) Incorrecto. Un tipo, en este caso int list, no puede formar parte de un patrón. 15. Defina qué es la evaluación perezosa. Ponga un ejemplo de un operador CAML con evaluación perezosa y explique su semántica La evaluación de las subexpresiones que la forman depende de la necesidad de su evaluación en tiempo de ejecución. El operador if condición then expresión_1 else expresión_2. Si la evaluación de la condiciión booleana es true sólo se evalúa la expresión_1, y si es false, sólo se evalúa la expresión_2. Página 5 de 11 Programación II Febrero 2010 Universidad Politécnica de Madrid Escuela Universitaria de Informática Departamento de Lenguajes, Proyectos y Sistemas Informáticos Asignatura PROGRAMACIÓN II ENUNCIADOS DE LOS PROBLEMAS DEL EXAMEN DE LA CONVOCATORIA DE FEBRERO Plan: 92 / Curso: 2009-2010 Madrid, a 9 de Febrero de 2010 Fechas de Publicación de Notas y de Revisión de Exámenes Publicación de Notas: Lunes 22 de Febrero de 2010 Revisión de Examen y Prácticas: Miércoles 24 de Febrero de 2010 en horario que será publicado en el tablón de la Asignatura a la publicación de las notas Puede consultar sus notas en: www.lpsi.eui.upm.es/webprog2/Notas.htm PROBLEMA 1: PROGRAMACIÓN CONCURRENTE Puntuación: 2'5 puntos En un cierto concurso participan N concursantes. El concurso se compone de una serie de eliminatorias, en cada una de las cuales se trata de eliminar a un concursante. En cada eliminatoria, el presentador del concurso genera un número secreto fatídico al azar entre 1 y 3, ambos inclusive. Los concursantes generan sus respuestas con su identificador y las meten en una urna. Entonces el presentador decide qué concursante es eliminado, sacando aleatoriamente de una en una las respuestas de la urna hasta que una coincida con el número secreto fatídico; entonces ese concursante es eliminado y debe abandonar el concurso, y el resto repiten el proceso con un nuevo número secreto hasta que sólo quede un concursante, que será el ganador del concurso. En el caso de que ningún concursante acierte el número secreto en una eliminatoria, se mantienen todos los concursantes en la siguiente eliminatoria. Este escenario se ha simulado con el siguiente diseño: TYPE tRespuesta = RECORD … END; (* Ya codificado e inalterable *) tConcurso = RECORD ... END; (* Ya codificado e inalterable *) (* Ya codificados e inalterables *) PROCEDURE GenerarSecreto (VAR concurso : tConcurso); … PROCEDURE DecidirEliminado (VAR concurso : tConcurso); … PROCEDURE SiguienteEliminatoria (VAR concurso : tConcurso); … FUNCTION ConcursantesEnEliminatoria (concurso : tConcurso) : INTEGER; … PROCESS TYPE tPresentador (VAR concurso : tConcurso); BEGIN REPEAT GenerarSecreto(concurso); DecidirEliminado(concurso); SiguienteEliminatoria(concurso) UNTIL ConcursantesEnEliminatoria(concurso) = 1 END; Página 6 de 11 Programación II Febrero 2010 (* Ya codificados e inalterables *) PROCEDURE GenerarRespuesta (id : INTEGER; VAR respuesta : tRespuesta); … PROCEDURE MeterEnUrna (respuesta : tRespuesta; VAR concurso : tConcurso); … FUNCTION EsEliminado (respuesta : tRespuesta; concurso : tConcurso) : BOOLEAN; … FUNCTION EsGanador (respuesta : tRespuesta; concurso : tConcurso) : BOOLEAN; … PROCESS TYPE tConcursante (id : INTEGER; VAR concurso : tConcurso); VAR ganador, eliminado : BOOLEAN; respuesta : tRespuesta; BEGIN REPEAT GenerarRespuesta(id, respuesta); MeterEnUrna (respuesta, concurso); eliminado := EsEliminado(respuesta, concurso); ganador := EsGanador(respuesta, concurso) UNTIL eliminado OR ganador END; Para el correcto funcionamiento del programa, se requiere cumplir las siguientes sincronizaciones entre los procesos en cada eliminatoria del concurso: 1. El presentador genera un número secreto. 2. Una vez terminada la acción anterior, los concursantes generan sus respuestas concurrentemente, pero las meten en la urna bajo exclusión mutua. 3. Cuando todos los concursantes han terminado de meter sus respuestas en la urna, el presentador decide qué concursante es eliminado. 4. Después de que el presentador haya decidido el concursante eliminado, los concursantes pueden comprobar concurrentemente si han sido eliminados y si son el ganador del concurso. Si se cumple alguna de estas dos condiciones, los concursantes terminan su ejecución; si no, pasan a la siguiente eliminatoria. 5. Después de que todos los concursantes hayan evaluado si son el eliminado y si son el ganador, el presentador puede preparar el concurso para pasar a la siguiente eliminatoria, si queda más de un concursante; o para terminar su ejecución, si queda un único concursante. SE PIDE: 1. Codificar un MONITOR llamado Sincronización para cumplir las sincronizaciones requeridas entre las acciones del presentador y los concursantes. 2. Reescribir los procesos tPresentador y tConcursante incorporando la sincronizaciones requeridas, usando el monitor anterior. NOTA: Los procedimientos, funciones y tipos tConcurso y tRespuesta dados ya están codificados y, por tanto, no se pueden modificar. Página 7 de 11 Programación II Febrero 2010 SOLUCION: PROCESS TYPE tPresentador (VAR concurso:tConcurso); VAR i:INTEGER; BEGIN REPEAT GenerarSecreto(concurso); Sincronizacion.PreDecidirEliminado(ConcurantesEnEliminatoria(concurso)); DecidirEliminado(concurso); Sincronizacion.PostDecidirEliminado(ConcurantesEnEliminatoria(concurso)); SiguienteEliminatoria(concurso); UNTIL ConcurantesEnEliminatoria(concurso) = 1 END; PROCESS TYPE tConcursante (id:INTEGER; VAR concurso:tConcurso); VAR eliminado, ganador :BOOLEAN; respuesta:tRespuesta; BEGIN REPEAT Sincronizacion.PreGenerarRespuesta; GenerarRespuesta(id, respuesta); Sincronizacion.PreMeterEnUrna; MeterEnUrna(respuesta, concurso); Sincronizacion.PostMeterEnUrna(ConcurantesEnEliminatoria(concurso)); eliminado := EsEliminado(respuesta, concurso); ganador := EsGanador(respuesta, concurso); Sincronizacion.PostComprobarResultado(ConcurantesEnEliminatoria(concurso)); UNTIL eliminado or ganador END; (****************************************************************************) MONITOR Sincronizacion; EXPORT PreDecidirEliminado, PostDecidirEliminado, PreGenerarRespuesta, PreMeterEnUrna, PostMeterEnUrna, PostComprobarResultado; VAR generadoSecreto : BOOLEAN; esperaSecreto : CONDITION; respuestasMetidas : INTEGER; esperaMetidas : CONDITION; decididoEliminado : BOOLEAN; esperaDecidido : CONDITION; comprobados : INTEGER; esperaComprobados : CONDITION; libreUrna : BOOLEAN; esperaUrna : CONDITION; PROCEDURE PreDecidirEliminado (concursantes : INTEGER); BEGIN generadoSecreto := TRUE; WHILE NOT EMPTY(esperaSecreto) DO RESUME(esperaSecreto); IF respuestasMetidas < concursantes THEN DELAY(esperaMetidas); respuestasMetidas := 0; generadoSecreto := FALSE END; Página 8 de 11 Programación II PROCEDURE PostDecidirEliminado (concursantes : INTEGER); BEGIN decididoEliminado := TRUE; WHILE NOT EMPTY(esperaDecidido) DO RESUME(esperaDecidido); Febrero 2010 IF comprobados < concursantes THEN DELAY(esperaComprobados); comprobados := 0; decididoEliminado := FALSE END; PROCEDURE PreGenerarRespuesta; BEGIN IF NOT generadoSecreto THEN DELAY(esperaSecreto) END; PROCEDURE PreMeterEnUrna; BEGIN IF NOT libreUrna THEN DELAY(esperaUrna); libreUrna := FALSE END; PROCEDURE PostMeterEnUrna (concursantes : INTEGER); BEGIN libreUrna := TRUE; RESUME(esperaUrna); respuestasMetidas := respuestasMetidas + 1; IF respuestasMetidas = concursantes THEN RESUME(esperaMetidas); IF NOT decididoEliminado THEN DELAY(esperaDecidido) END; PROCEDURE PostComprobarResultado (concursantes : INTEGER); BEGIN comprobados := comprobados + 1; IF comprobados = concursantes THEN RESUME(esperaComprobados) END; BEGIN generadoSecreto := FALSE; respuestasMetidas := 0; libreUrna := TRUE; decididoEliminado := FALSE; comprobados := 0 END; Página 9 de 11 Programación II PROBLEMA 2: PROGRAMACIÓN FUNCIONAL Febrero 2010 Puntuación: 2'5 puntos En una aplicación de gestión bibliográfica se dispone de la información de los libros citados en las páginas de un cierto libro. Esta información se representa mediante una lista de tuplas de dos elementos, en la que el primer elemento de cada tupla es un número de página, y el segundo elemento es una lista de los libros citados en esa página. Cada libro se representa mediante una tupla de dos elementos, el primer elemento es el nombre del autor y el segundo elemento es el año de publicación. Una página nunca aparece repetida en la lista, y un libro nunca aparece repetido en la misma página. Ej.: [ (21, [("Burns", 1987); ("Burns", 1991); ("Stroustrup", 1993)]); (10, [("Booch", 1995); ("Burns", 1991); ("Gamma", 1983)]); (15, []); (12, [("Gamma", 1983); ("Booch", 1995); ("Stroustrup", 1993)]); ( 7, [("Rumbaugh", 1991); ("Booch", 1995)]) ] SE PIDE: Escribir una función llamada PorAutor que, a partir de una lista como la descrita, devuelva otra lista formada por tuplas de dos elementos, en la que el primer elemento sea un libro y el segundo elemento sea la lista de las páginas donde se cita a ese libro. Un libro no puede aparecer repetido en la lista resultado, y una página no puede aparecer repetida en el mismo libro. Para la lista del ejemplo, el resultado debe ser el siguiente: [ (("Booch", 1995), [10; 12; 7]); (("Rumbaugh", 1991), [7]); (("Stroustrup", 1993), [21; 12]); (("Gamma", 1983), [10; 12]); (("Burns", 1991), [21; 10]); (("Burns", 1987), [21]) ] NOTA: El orden en el que deben aparecen los libros y las páginas en la lista resultado es irrelevante. Página 10 de 11 Programación II Febrero 2010 SOLUCION: let rec AnadirLibro = function pagina, libro, [] -> [(libro, [pagina])] | pagina1, libro1, (libro2, listaPaginas)::restoLibros -> if libro1 = libro2 then (libro2, pagina1::listaPaginas)::restoLibros else (libro2, listaPaginas)::AnadirLibro(pagina1, libro1, restoLibros);; let rec AnadirPagina = function (_, []), listaLibros -> listaLibros | (pagina, libro::restoLibros), listaLibros -> AnadirLibro(pagina, libro, AnadirPagina((pagina, restoLibros), listaLibros));; let rec PorAutor = function [] -> [] | tuplaPagina::restoTuplas -> AnadirPagina(tuplaPagina, PorAutor(restoTuplas));; Página 11 de 11