with Ada.Text_IO;
with Ada.Calendar;
with Ada.Real_Time;
procedure Central_Nuclear is
type Temperatura is range 0 .. 2000; -- Rango de temperaturas posibles
type Estado_Reactor is (Activo, Apagado); -- Estados del reactor
type Reactor is record
Temp: Temperatura;
Actuador_Activo: Boolean;
end record;
type Coordinador is record
Reactor: Reactor;
Ultimo_Mensaje: Ada.Calendar.Time;
end record;
-- Función para generar un número aleatorio en un rango determinado
function Aleatorio return Integer is
Seed: Ada.Real_Time.Time;
begin
Seed := Ada.Real_Time.Clock;
return Aleatorio.Random(Seed);
end Aleatorio;
-- Función para actualizar la temperatura de un reactor
procedure Actualizar_Temperatura(Reactor: in out Reactor) is
begin
if Reactor.Temp < 1500 then
-- No hacer nada
null;
else
-- Abrir compuerta y bajar temperatura
Reactor.Temp := Reactor.Temp - 50;
end if;
end Actualizar_Temperatura;
-- Función para imprimir una alarma en un fichero
procedure Imprimir_Alarma(Reactor: Reactor) is
Fichero: Ada.Text_IO.File_Type;
Mensaje: String := "ALARMA: Reactor " & Reactor'Image' & " - Temperatura: " & Reactor.Temp'Image';
begin
Ada.Text_IO.Open(File => Fichero, Mode => Ada.Text_IO.Append_File, Name => "alarma.txt");
Ada.Text_IO.Put_Line(File => Fichero, Item => Mensaje);
Ada.Text_IO.Close(File => Fichero);
exception
when Ada.Text_IO.Name_Error =>
Ada.Text_IO.Put_Line("Error al abrir el fichero de alarma.");
end Imprimir_Alarma;
-- Proceso principal de la simulación
procedure Simular_Central_Nuclear is
Reactores: array(1 .. 3) of Reactor;
Coordinadores: array(1 .. 3) of Coordinador;
Temperatura_Inicial: Temperatura := 1450;
begin
-- Inicializar los reactores
for I in Reactores'Range' loop
Reactores(I).Temp := Temperatura_Inicial;
Reactores(I).Actuador_Activo := False;
end loop;
-- Inicializar los coordinadores
for I in Coordinadores'Range' loop
Coordinadores(I).Reactor := Reactores(I);
Coordinadores(I).Ultimo_Mensaje := Ada.Calendar.Clock;
end loop;
-- Simulación de los muestreos de temperatura
loop
-- Actualizar la temperatura de cada reactor
for I in Reactores'Range' loop
Actualizar_Temperatura(Reactores(I));
-- Verificar si se supera la temperatura límite
if Reactores(I).Temp > 1750 then
Imprimir_Alarma(Reactores(I));
end
if;
end loop;
-- Mandar mensaje al hilo coordinador indicando que está vivo
for I in Coordinadores'Range' loop
Coordinadores(I).Ultimo_Mensaje := Ada.Calendar.Clock;
end loop;
-- Verificar si algún hilo coordinador no ha recibido mensajes
for I in Coordinadores'Range' loop
if Ada.Calendar.Clock - Coordinadores(I).Ultimo_Mensaje > 3.0 then
Ada.Text_IO.Put_Line("Alerta: No se ha recibido mensaje del hilo coordinador " & I'Image');
end if;
end loop;
-- Esperar 2 segundos antes del siguiente muestreo
delay 2.0;
end loop;
end Simular_Central_Nuclear;
begin
Simular_Central_Nuclear;
exception
when others =>
Ada.Text_IO.Put_Line("Error en la simulación: " & Ada.Exceptions.Exception_Message(Ada.Exceptions.Exception_Name));
end Central_Nuclear;