I am working on a concurrent programming problem in Ada. The task is to simulate a bridge over which different cars can pass from different directions. The complication lies in the fact that, if an ambulance is present, the cars must give it absolute priority.
Here is the code I have developed:
with Ada.Text_IO; use Ada.Text_IO;
procedure Main is
type Direccion is (Norte, Sur);
task type Vehiculo (ID : Integer; Acceso : Direccion);
task type Ambulancia;
protected type Puente is
entry Entrar (ID : Integer; Acceso : Direccion);
entry Salir (ID : Integer);
private
Puente_Ocupado : Boolean := False;
Ambulancia_Esperando : Boolean := False;
Ambulancia_En_Puente : Boolean := False;
Coches_En_Espera : Integer := 0;
Ambulancia_En_Espera : Boolean := False;
procedure Entrar_Ambulancia;
procedure Entrar_Coche(ID : Integer; Acceso : Direccion);
end Puente;
task body Vehiculo is
begin
Put_Line ("El coche" & Integer'Image(ID) & " está en ruta en dirección " & Direccion'Image(Acceso) & "!");
Puente.Entrar(ID, Acceso);
delay(1.0); -- Simula el tiempo que tarda en cruzar el puente
Puente.Salir(ID);
end Vehiculo;
task body Ambulancia is
begin
Put_Line ("La ambulancia 112 está en ruta");
Puente.Entrar(112, Norte); -- Cambiado a un acceso específico, puedes ajustar según tus necesidades
delay(0.5); -- Simula el tiempo que tarda en cruzar el puente
Puente.Salir(112);
end Ambulancia;
protected body Puente is
entry Entrar (ID : Integer; Acceso : Direccion) when not Puente_Ocupado is
begin
if ID = 112 then
Entrar_Ambulancia;
else
Entrar_Coche(ID, Acceso);
end if;
end Entrar;
entry Salir (ID : Integer) when Puente_Ocupado is
begin
if ID = 112 then
Ambulancia_En_Puente := False;
else
Puente_Ocupado := False;
Coches_En_Espera := 0;
end if;
end Salir;
procedure Entrar_Ambulancia is
begin
if Puente_Ocupado then
Ambulancia_Esperando := True;
Ambulancia_En_Espera := True;
Put_Line ("+++++Ambulancia 112 espera para entrar");
else
Puente_Ocupado := True;
Ambulancia_En_Puente := True;
Put_Line ("+++++Ambulancia 112 está en el puente");
end if;
end Entrar_Ambulancia;
procedure Entrar_Coche(ID : Integer; Acceso : Direccion) is
begin
if Puente_Ocupado or Ambulancia_En_Puente then
Coches_En_Espera := Coches_En_Espera + 1;
Put_Line ("El coche" & Integer'Image(ID) & " espera a la entrada " & Direccion'Image(Acceso) & ". Esperan " & Integer'Image(Coches_En_Espera) & " coches.");
else
Puente_Ocupado := True;
Put_Line ("El coche" & Integer'Image(ID) & " entra en el puente. Esperan en la " & Direccion'Image(Acceso) & ": " & Integer'Image(Coches_En_Espera) & " coches.");
end if;
end Entrar_Coche;
end Puente;
-- Creación de instancias
Coche1 : Vehiculo(1, Norte);
Coche2 : Vehiculo(2, Sur);
Coche3 : Vehiculo(3, Norte);
Coche4 : Vehiculo(4, Sur);
Coche5 : Vehiculo(5, Norte);
Amb : Ambulancia;
begin
-- Esperar la finalización de los procesos
while not (Coche1'Terminated and Coche2'Terminated and Coche3'Terminated and Coche4'Terminated and Coche5'Terminated and Amb'Terminated) loop
null;
end loop;
-- Mensajes finales
Put_Line("Todos los vehículos han cruzado el puente y la ambulancia ha completado su ruta.");
end Main;
The current code generates errors indicating "invalid use of subtype mark in expression or call". I am using subtypes to represent directions (North, South), "(Norte, Sur)", and there seems to be a problem when trying to use them in certain expressions or calls.
I would appreciate any guidance on how to fix this problem and any suggestions on how to improve the efficiency or clarity of the code.
Compiler Error:
main.adb:27:7: error: invalid use of subtype mark in expression or call
main.adb:29:7: error: invalid use of subtype mark in expression or call
main.adb:35:7: error: invalid use of subtype mark in expression or call
main.adb:37:7: error: invalid use of subtype mark in expression or call
- I have tried to review the Ada documentation, but I have not been able to identify the specific problem in my code.
- I am using subtypes to represent addresses, and I suspect the error might be related to their use in procedure calls within tasks. Thanks in advance for any help provided.
Your problem is the use of
Puente
within the body of the tasks.The definition
protected type Puente is
creates a type calledPuente
.Maybe you meant to create a protected object instead, like so
protected Puente is
?Inside type definitions (like
Puente
), the name of the type refers to the current instance (object) of the type, which is the reason you don't get similar errors in the body ofPuente