1. Sinónimos de tipo tipo tipo tipo tipo tipo String = [Char] ; Nick = String ; Topico = String ; Nombre = String ; Fecha = Z ; 2. Tipo Mensaje tipo Mensaje observador observador observador } { firma (m : Mensaje) : Nick ; fecha (m : Mensaje) : Fecha ; cuerpo (m : Mensaje) : String ; problema firmaM (m : Mensaje) = result : Nick { asegura result == f irma(m) ; } problema fechaM (m : Mensaje) = result : Fecha { asegura result == f echa(m) ; } problema cuerpoM (m : Mensaje) = result : String { asegura result == cuerpo(m) ; } problema nuevoM (n : Nick, f : Fecha, t : String) = result : Mensaje { asegura f irma(result) == n ; asegura f echa(result) == f ; asegura cuerpo(result) == t ; } 3. Tipo Tema tipo Tema { observador observador observador observador invariante invariante } topico (t : Tema) : Topico ; creador (t : Tema) : Nick ; fechaInicio (t : Tema) : Fecha ; mensajes (t : Tema) : [Mensaje] ; MensajesPosterioresALaFechaDeInicio : (∀x ← mensajes(t))(f echa(x) > f echaInicio(t)) ; MensajesOrdenadosPorFecha : mensajesOrdenados(mensajes(t)) ; problema topicoT (m : Tema) = result : Topico { asegura result == topico(m) ; } problema creadorT (m : Tema) = result : Nick { asegura result == creador(m) ; } problema fechaT (m : Tema) = result : Fecha { asegura result == f echaInicio(m) ; } problema mensajesT (m : Tema) = result : [Mensaje] { asegura result == mensajes(m) ; } problema nuevoT (t : Topico, c : Nick, f : fecha) = result : Tema { asegura topico(result) == t ; 1 asegura creador(result) == c ; asegura f echaInicio(result) == f ; asegura mensajes(result) == [ ] ; } problema agregarMensajeT (t : Tema, m : Mensaje) = result : Tema { requiere f echa(m) > f echaInicio(t) ; asegura topico(result) == topico(t) ; asegura creador(result) == creador(t) ; asegura f echaInicio(result) == f echaInicio(t) ; asegura mismos(m : mensajes(t), mensajes(result)) ; } problema participanteSpeedyGonzalezT (t : Tema) = result : Nick { requiere cantidadMensajesDelTema(t) > 1 ; asegura result ∈ obtenerFirmasDeTema(t) ; asegura (∀n ∈ obtenerFirmasDeTema(t), n 6= result) menorTRtaN(result, t) ≤ menorTRtaN(n, t) ; } aux aux aux aux aux aux aux aux aux aux aux aux aux 4. obtenerFechas (mensajes : [Mensaje]) : [Fecha] = [ f echa(m) | m ← mensajes ] ; obtenerFechasDeTema (t : Tema) : [Fecha] = obtenerFechas(mensajesT (t)) ; ordenadosFecha (fs : [Fecha]) : Bool = (∀j ← [0.. |f s| − 1])(f sj ≤ f sj+1 ) ; mensajesOrdenados (ms : [Mensaje]) : Bool = ordenadosFecha(obtenerFechas(ms)) ; cantidadMensajesDelTema (t : Tema) : Z = if mensajes(t) == [ ] then 0 else |mensajes(t)| ; obtenerNicks (ms : [Mensaje]) : [Nick] = [ f irma(m) | m ← ms ] ; obtenerFirmasDeTema (t : Tema) : [Nick] = obtenerNicks(mensajes(t)) ; todosDistintos< T > (s : [T]) : Bool = (∀i ← [0.. |s| − 1], j ← [0..lens − 1], i 6= j)(si 6= sj ) ; tiempoRta (m : mensaje, ms :[Mensaje]) : Z = f echa(m) − f echa(mspos<Mensaje>(m,ms)−1 ) ; pos< T > (t : T, ts : [T]) : Z = cab([ j | j ← [0.. |ts| − 1], tsj == t ]) ; min (z : [Z]) : Z = acum(if a ≤ s then a else s | s : Z = z0 , a ← z,) ; max (z : [Z]) : Z = acum(if a ≥ s then a else s | s : Z = z0 , a ← z,) ; menorTRtaN (n : Nick, t : Tema) : Z = min([ tiempoRta(m, mensajes(t)) | m ← mensajes(t), f irma(m) == n ]) ; Tipo Canal tipo Canal { observador nombre (c : Canal) : Nombre ; observador moderador (c : Canal) : Nick ; observador participantes (c : Canal) : [Nick] ; observador temas (c : Canal) : [Tema] ; observador mensajesPendientes (c : Canal, t : Topico) : [Mensaje] ; requiere t ∈ losTopicos(temas(c)) ; observador mensajesRechazados (c : Canal, t : Topico) : [Mensaje] ; requiere t ∈ losTopicos(temas(c)) ; invariante NoHayNicksRepetidos : (∀i ← [0.. |participantes(c)| − 1], j ← [0.. |participantes(c)| − 1], i 6= j)(participantes(c)i 6= participantes(c)j ) ; invariante NoHayTopicosRepetidos : (∀i ← [0.. |participantes(c)| − 1], j ← [0.. |participantes(c)| − 1], i 6= j) (losTopicosC(c)i 6= losTopicosC(c)j ) ; invariante ElModeradorEsParticipante : moderador(c) ∈ participantes(c) ; invariante PendientesYRechazadosDeParticipantes : ((∀t ← losTopicosC(c), m ← mensajesP endientes(c, t)) firmanteEsParticipante(m, c)) ∧ ((∀t ← losTopicosC(c), m ← mensajesRechazados(c, t)) firmanteEsParticipante(m, c)) ; } problema nombreC (c : Canal) = result : Nombre { asegura result == nombre(c) ; } problema moderadorC (c : Canal) = result : Nick { asegura result == moderador(c) ; } problema participantesC (c : Canal) = result : [Nick] { 2 asegura result == participantes(c) ; } problema topicosC (c : Canal) = result : [Topico] { asegura result == losT opicos(temas(c)) ; } problema temaC (c : Canal, t : Topico) = result : Tema { requiere t ∈ losT opicos(temas(c)) ; asegura result == cab([ tm | tm ← temas(c), topico(tm) == t ]) ; } problema temasC (c : Canal) = result : [Tema] { asegura result == temas(c) ; } problema mensajesPendientesC (c : Canal, t : Topico) = result : [Mensaje] { asegura result == mensajesP endientes(c, t) ; } problema mensajesRechazadosC (c : Canal, t : Topico) = result : [Mensaje] { asegura result == mensajesRechazados(c, t) ; } problema nuevoC (n : Nombre, m : Nick) = result : Canal { asegura nombre(result) == n ; asegura moderador(result) == m ; asegura participantes(result) = m : [ ] ; asegura temas(result) == [ ] ; } problema ingresarC (c : Canal, n : Nick) = result : Canal { asegura nombre(result) = nombre(c) ; asegura moderador(result) == moderador(c) ; asegura mismos(temas(result), temas(c)) ; asegura mismosPendientes(result, c) ; asegura mismosRechazados(result, c) ; asegura n ∈ participantes(c) → mismos(participantes(result), participantes(c)) ; asegura n ∈ / participantes(c) → mismos(n : participantes(c), participantes(result)) ; } problema salirC (c : Canal, n : Nick) = result : Canal { requiere n ∈ participantes(c) ; requiere n 6= moderador(c) ; asegura nombre(result) = nombre(c) ; asegura moderador(result) == moderador(c) ; asegura mismos(n : participantes(result), participantes(c)) ; asegura mismos(temas(result), temas(c)) ; asegura mismosPendientesMenosDelQueSeVa(c, result, n) ; asegura mismosRechazadosMenosDelQueSeVa(c, result, n) ; } problema registrarTemaC (c : Canal, n : Nick, t : Topico, f : Fecha) = result : Canal { requiere n ∈ participantes(c) ; requiere t ∈ / losTopicosC(c) ; asegura nombre(result) = nombre(c) ; asegura moderador(result) == moderador(c) ; asegura participantes(result) == participantes(c) ; asegura (∃x ← temas(result), topico(x) == t) creador(x) == n ; asegura (∃x ← temas(result), topico(x) == t) f echaInicio(x) == f ; asegura (∃x ← temas(result), topico(x) == t) mensajes(x) = [ ] ; asegura (∃x ← temas(result), topico(x) == t) mismos(temas(result), x : temas(c)) ; asegura (∀x ← losTopicosC(c)) mismos(mensajesP endientes(result, t), mensajesP endientes(c, t)) ; asegura (∀x ← losTopicosC(c)) mismos(mensajesRechazados(result, t), mensajesRechazados(c, t)) ; asegura mensajesP endientes(result, t) == [ ] ; asegura mensajesRechazados(result, t) == [ ] ; 3 } problema enviarMensajeC (c : Canal, t : Topico, n : Nick, m : String, f : Fecha) = result : Canal { requiere t ∈ losTopicosC(c) ; requiere f > f echaInicio(temaT(t, c)) ; asegura n ∈ / participantes(c) → result == c ; asegura n ∈ participantes(c) → nombre(result) = nombre(c) ; asegura n ∈ participantes(c) → moderador(result) == moderador(c) ; asegura n ∈ participantes(c) → mismos(participantes(result), participante(c)) ; asegura n ∈ participantes(c) → mismos(temas(result) == temas(c)) ; asegura n ∈ participantes(c) → mismosRechazados(result, c) ; asegura n ∈ participantes(c) → mismosPendientesExceptoUnTema(c, result, t) ; asegura (∀x ← mensajesP endientes(c, t)) cuenta(mensajesP endientes(c, t), x) == cuenta(mensajesP endientes(result, t), x) ; asegura |mensajesP endientes(result, t)| == |mensajesP endientes(c, t)| + 1 ; asegura n ∈ participantes(c) → armarYAgregarAPend(c, result, t, n, m, f ) ; } problema obtenerNMensajesPendientesC (c : Canal, t : Topico, n : Int) = result : [Mensaje] { requiere t ∈ losT opicosC(c) ; asegura n ≥ |mensajesP endientes(c, t)| → mismos(result, mensajesP endientes(c, t)) ; asegura n < |mensajesP endientes(c, t)| → |result| == n ; asegura n < |mensajesP endientes(c, t)| → (∀m ∈ result) m ∈ mensajesP endientes(c, t) ; asegura n < |(mensajesP endientes(c, t)| → (∀m ∈ result)cuenta(m, result) ≤ cuenta(m, mensajesP endientes(c, t)) ; asegura n < |(mensajesP endientes(c, t)| → min(obtenerFechas(result)) ≥ máx([ f echa(m) | m ← mensajesP endientes(c, t), m ∈ / result ]) ; } problema aprobarMensajeC (c : Canal, t : Topico, m : Mensaje, n : Nick) = result : Canal { requiere t ∈ losTopicosC(c) ; requiere m ∈ mensajesP endientes(c, t) ; asegura n 6= moderador(c) → result == c ; asegura n == moderador(c) → nombre(result) == nombre(c) ; asegura n == moderador(c) → moderador(result) == moderador(c) ; asegura n == moderador(c) → mismos(participantes(result), participantes(c)) ; asegura n == moderador(c) → |temas(result)| == |temas(c)| ; asegura n == moderador(c) → mismos(losTopicosC(c), losTopicosC(result)) ; asegura n == moderador(c) → (∀x ∈ losTopicosC(c)) creador(temaT(t, c)) == creador(temaT(t, result)) ; asegura n == moderador(c) → (∀x ∈ losTopicosC(c)) f echaInicio(temaT(t, c)) == f echaInicio(temaT(t, result)) ; asegura n == moderador(c) → (∀x ∈ losTopicosC(c), x 6= t) mismos(mensajes(temaT(t, c)), mensajes(temaT(t, result))) ; asegura n == moderador(c) → (∀x ∈ losTopicosC(c)) mensajesOrdenados(mensajes(temaT(t, result))) ; asegura n == moderador(c) → mismosPendientesExceptoUnTema(c, result, t) ; asegura n == moderador(c) → mismosRechazados(result, c) ; asegura n == moderador(c) → mismos(m : mensajesP endientes(result, t), mensajesP endientes(c, t)) ; asegura n == moderador(c) → mismos(m : mensajes(temaT(t, c)), mensajes(temaT(t, result))) ; } problema rechazarMensajeC (c : Canal, t : Topico, m : Mensaje, n : Nick) = result : Canal { requiere m ∈ mensajesP endientes(c, t) ; requiere t ∈ losTopicosC(c) ; asegura n 6= moderador(c) → result == c ; asegura n == moderador(c) → nombre(result) == nombre(c) ; asegura n == moderador(c) → moderador(result) == moderador(c) ; asegura n == moderador(c) → mismos(participantes(result), participantes(c)) ; asegura n == moderador(c) → mismos(temas(result), temas(c)) ; asegura n == moderador(c) → (∀x ∈ temas(c), topico(x) 6= t) mismos(mensajesP endientes(result, topico(x)), mensajesP endientes(c, topico(x))) ; asegura n == moderador(c) → (∀x ∈ temas(c), topico(x) 6= t) mismos(mensajesRechazados(result, topico(x)), mensajesRechazados(c, topico(x))) ; asegura n == moderador(c) → mismos(m : mensajesP endientes(result, t), mensajesP endientes(c, t)) ; 4 asegura n == moderador(c) → mismos(m : mensajesRechazados(c, t), mensajesRechazados(result, t)) ; } problema masRechazadoC (c : Canal) = result : Nick { requiere listaNicksMensajesRechazados(c) 6= [ ] ; asegura result ∈ listaNicksMensajesRechazados(c) ; asegura (∀x ∈ listaNicksMensajesRechazados(c)) cuenta(x, listaNicksMensajesRechazados(c)) ≤ cuenta(result, listaNicksMensajesRechazados(c)) ; } problema opinologosC (c : Canal) = result : [Nicks] { asegura (∀n ← result)n ∈ participantes(c) ; asegura (∀n ← result, t ← temas(c))(∃m ∈ mensajes(t))n == f irma(m) ; asegura (∀n ← participantes(c), n ∈ / result)(∃t ∈ temas(c))¬((∃m ∈ mensajes(t))n == f irma(m)) ; } problema temasDondeMasSeExplayoC (c : Canal, n : Nick) = result : [Tema] { asegura (∀t ← result)t ∈ temas(c) ; asegura (∀t ← result)(∃m ∈ mensajes(t), f irma(m) == n) |cuerpo(m)| >= |cuerpo(mensajeMasLargoDe(n, c)|) ; asegura (∀t ← temas(c), t ∈ / result)¬(∃m ∈ mensajes(t), f irma(m) == n) |cuerpo(m)| >= |cuerpo(mensajeMasLargoDe(n, c)|) ; } problema ocupanMasEspacioC (c : Canal) = result : [Nick] { asegura (∀n ← result)n ∈ participantes(c) ; asegura (∀n1 ← result, n2 ← participantes(c))(espacioDeMensajes(n1, c) >= (espacioDeMensajes(n2, c))) ; asegura (∀n1 ← participantes(c), n2 ← result, n1 ∈ / result)(espacioDeMensajes(n1, c) < (espacioDeMensajes(n2, c))) ; } aux temaT (t : Topico, c : Canal) : Tema = cab([ x | x ← temas(c), topico(x) == t ]) ; aux firmadorEsParticipante (m : Mensaje, c : Canal) : Bool = f irma(m) ∈ participantes(c) ; aux losTopicos (ts : [Tema]) : [Topico] = [ topico(t) | t ← ts ] ; aux losTopicosC (c : Canal) : [Topico] = losTopicos(temas(c)) ; aux mismosPendientes (nuevo , viejo : Canal) : Bool = (∀t ← losTopicosC(viejo)) mismos(mensajesP endientes(nuevo, t), mensajesP endientes(viejo, t)) ; aux mismosRechazados (nuevo , viejo : Canal) : Bool = (∀t ← losTopicosC(viejo)) mismos(mensajesRechazados(nuevo, t), mensajesRechazados(viejo, t)) ; aux todosLosPendientes (c : Canal) : [Mensaje] = concat([ mensajesP endientes(c, topico(t)) | t ← temas(c) ]) ; aux todosLosRechazados (c : Canal) : [Mensaje] = concat([ mensajesRechazados(c, topico(t)) | t ← temas(c) ]) ; aux listaNicksMensajesRechazados (c : Canal) : [Nick] = obtenerNicks(todosLosRechazados(c)) ; aux esSubconjunto< T > (s : [T], u : [T]) : Bool = (∀x ← s) x ∈ u ; aux mismosPendientesMenosDelQueSeVa (c : Canal, d : Canal, n : Nick) : Bool = ((∀t ∈ losTopicosC(c), m ∈ mensajesP endientes(c, t), f irma(m) 6= n) cuenta(m, mensajesP endientes(d, t)) == cuenta(m, mensajesP endientes(c, t))) ∧ |mensajesP endientes(d, t)| == |mensajesP endientes(c, t)| − cuenta(n, obtenerNicks(mensajesP endientes(c, t))) ; aux mismosRechazadosMenosDelQueSeVa (c : Canal, d : Canal, n : Nick) : Bool = ((∀t ∈ losTopicosC(c), m ∈ mensajesRechazados(c, t), f irma(m) 6= n) cuenta(m, mensajesRechazados(d, t)) == cuenta(m, mensajesRechazados(c, t))) ∧ |mensajesRechazados(d, t)| == |mensajesRechazados(c, t)| − cuenta(n, obtenerNicks(mensajesRechazados(c, t))) ; aux armarYAgregarAPend (c : Canal, d : Canal, t : Topico, n : Nick, m : String, f : Fecha) : Canal = |[ x | x ← mensajesP endientes(d, t), f irma(x) == n, cuerpo(x) == m, f echa(x) == f ]| == |[ x | x ← mensajesP endientes(c, t), f irma(x) == n, cuerpo(x) == m, f echa(x) == f ]| + 1 ; aux espacioDeMensajes (n : Nick, c: Canal) : Z = acum(x + |cuerpo(m)| | x : Z = 0, t ← temas(c), m ← mensajes(t), f imar(m) == n,) ; aux mensajeMasLargoDe (n : Nick, c: Canal) : Mensaje = cab[ m1 | m1 ∈ obtenerM ensajes(c, n), m2 ∈ obtenerM ensajes(c, n), |cuerpo(m1)| >= |cuerpo(m2)| ] ; aux mismosPendientesExceptoUnTema (c : Canal, d : Canal, t : Topico) : Bool = (∀x ← losTopicosC(c), x 6= t) mismos(mensajesP endientes(c, x), mensajesP endientes(d, x)) ; aux obtenerMensajes (c : Canal, n : Nick) : [Mensaje] = [ m | t ← temas(c), m ← mensajes(t), n == f irma(m) ] ; 5