❌ About FreshRSS

Reading view

There are new articles available, click to refresh the page.

Problem with subtype usage in concurrent Ada program

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.

How to use Ada testing frameworks in VS Code (or with some other test runner)?

I got Alire based build & debug working in VS Code (on Windows), but how to configure AUnit (or any other Ada testing framework) based testing in VS Code? Alternatively, I am okay with other testing systems that would provide fluent setup and coding experience. Link to a complete example project with working test setup would be nice.

I am looking for a smooth experience in exploring my own code and libraries using tests, so being able to run a specific test and subset of tests would be very useful.

submitted by /u/anyfreename123
[link] [comments]

Generating Ada bindings for C headers (Gem #59) doesn't work any more

When I used this method a few years ago, with Ada from the Ubuntu repository, it worked fine. Now, with my installation from Adacore, not so anymore.

The method consists of 2 commands (time.h as example)

  1. g++ -c -fdump-ada-spec -C /usr/include/time.h
  2. gcc -c -gnat05 *.ads

While the first command executes without any problem, the second one returns:

gcc: fatal error: cannot execute ‘gnat1’: execvp: No such file or directory

It doesn't depend on the -gnat05 option. There is indeed no gnat1 in the bin directory of the Ada installation. Mine is version 2021. I am reluctant to install the GNU version in parallel, I might mix up things.

Any other idea?

Elaboration circularity detected

Hi, I am new in this forum.
I have a problem porting ada code from Red Hat 8 (gnat 8.5.0) to Red Hat 9 (gnat 11.3.1).
The linking phase on RHEL9 fails for “Elaboration circularity detected”.
I let the ada compiler to choose the module compilation order using the following instruction:
gnatmake -c
The reason is: “unit depends on its own elaboration”
The circularity detected is: "unit invokes a construct of unit at elaboration time.
What shall I do to find the exact location of the problem?
And why this problem was not detected before using other gnat versions?
Thanks a lot

6 posts - 3 participants

Read full topic

Possible compiler bug?

I have some code that is running fine for me at home using gnat/gcc 12.2. I decided to test it out on various versions of gnat, so I fired up godbolt and tried a few. I found that starting with version 13, my code throws an exception when the program ends:

raised PROGRAM_ERROR : example.adb:4 finalize/adjust raised exception

I wanted to double check and make sure I am not doing anything illegal and 13 catches it vs 13 just having a bug. I had to make a kinda convoluted example since the original code was from a much larger code base, so apologies if the generic formals and code don’t look too practical. I spent a few hours whittling it down from the original. Full code on godbolt is here:

Code is below:

example.adb:

with Ada.Text_IO; use Ada.Text_IO;
with Test;

procedure Example is

    package B is 
        type Instance is limited interface;
        function Make return Instance is abstract;
    end B;

    package C is
        type Instance is new B.Instance with null record;
        function Make return Instance is (null record);
    end C; use C;

    package T is new Test(B.Instance, C.Instance, C.Make);

    Thing : B.Instance'Class := T.Make(2);

begin
    Put_Line("Hello World");
end Example;

test.ads:

generic
    type First(<>) is abstract tagged limited private;
    type Second(<>) is new First with private;
    with function Make return Second is <>;
package Test is

    function Make(Key : Integer) return First'Class;

private

    type Some_Access is not null access function return First'Class;

    function Make_Delegate return First'Class;

    Thing_Access : constant Some_Access := Make_Delegate'Access;

end Test;

test.adb:

with Ada.Containers.Indefinite_Ordered_Maps;

package body Test is

    package Maps is new Ada.Containers.Indefinite_Ordered_Maps
        (Key_Type     => Integer,
         Element_Type => Some_Access);

    Map : Maps.Map;

    function Make(Key : Integer) return First'Class is
    begin
        return Map(Key).all;
    end Make;

    function Make_Delegate return First'Class is
    begin
        return Make;
    end Make_Delegate;

begin
    Map.Insert(2,Thing_Access);
end Test;

It’s essentially a map of function pointers (only one in this example). I had to use a wrapper function (Make_Delegate) in order to have correct accessibility to it within the generic.

7 posts - 3 participants

Read full topic

Type not visible in child package

I have the following parent package which defines several types

aes.ads

package AES is    
    type Byte is range 0..2**8  - 1;
    type Input_Buffer is array(Natural range <>) of Byte;
    type Output_Buffer is array(Natural range <>) of Byte;
    type Key is array(Natural range <>) of Byte;
    subtype AES_128_Key is Key(0..127);
    subtype AES_192_Key is Key(0..191);
    subtype AES_256_Key is Key(0..255);
    type Operation is (Encrypt, Decrypt);

    function AES_CBC_128(Input: Input_Buffer; Key: AES_128_Key; Op: Operation) return Output_Buffer;
    function AES_CBC_192(Input: Input_Buffer; Key: AES_192_Key; Op: Operation) return Output_Buffer;
    function AES_CBC_256(Input: Input_Buffer; Key: AES_256_Key; Op: Operation) return Output_Buffer;

private
    type Word is range 0..2**32 - 1;
    type State is array(0..3, 0..3) of Byte;
    type States is array(Natural range <>) of State;
    type Round_Key is array(0..16) of Byte;
    type Key_Schedule is array(Natural range <>) of Round_Key;
end AES;

aes.adb

with AES.AES_Cipher; use AES.AES_Cipher;
with AES.AES_Inv_Cipher; use AES.AES_Inv_Cipher;

package body AES is

-- other definitions

function AES_Common(St: State; K: Key; Op: Operation) return State is
    Schedule: Key_Schedule := Key_Expansion(K);
begin
    return (case Op is
        when Encrypt => Cipher(St, Schedule),
        when Decrypt => Inv_Cipher(St, Schedule)
    );
end AES_Common;

-- more definitions

end AES;

and then two child packages (aes-aes_inv_cipher is very similar to aes-aes_cipher so has been omitted)

aes-aes_cipher.ads

package AES.AES_Cipher is
    function Cipher(St: State; Schedule: Key_Schedule) return State;
end AES.AES_Cipher;

aes-aes_cipher.adb

package body AES.AES_Cipher is

function Cipher(St: State; Schedule: Key_Schedule) return State is
begin
    
    return St;
end Cipher;

end AES.AES_Cipher;

These are called from main.adb

with AES; use AES;

procedure Main is
    Input: Input_Buffer(0..35) := (others => Byte(44));
    K: AES_128_Key := (others => Byte(55));
    Output: Output_Buffer(0..35);
begin
    Output := AES_CBC_128(Input, K, Encrypt);
end Main;

This does not compile with the following error

aes-aes_cipher.ads:2:25: error: "State" is not visible (more references follow)
aes-aes_cipher.ads:2:25: error: non-visible (private) declaration at aes.ads:17
aes-aes_cipher.ads:2:42: error: "Key_Schedule" is not visible (more references follow)
aes-aes_cipher.ads:2:42: error: non-visible (private) declaration at aes.ads:20

I thought because aes-aes_cipher is a child package of aes it could access the private definitions in aes.ads but the error suggests otherwise. If this is not possible, how can I restructure the program so it works as expected? Removing private fixes it but those types should be private outside the package. I am using gnatmake version 13.2.0 on Windows.

Managing Multiple Projects

How do you go about organizing a bunch of different projects? I have several Ada (and other) projects, some of which depend on other projects and am looking for suggestions of how best to organize them.

My current approach is to have one "root" project that provides a top level package namespace (bbs) for all of my other projects. Thus, for example, my tiny Lisp interpreter is in the package bbs.lisp, with sub packages off of that. Each project is also in its own GitHub repository. Most projects also include some testing or use code that is not shared with other projects, and this code is outside of the bbs package hierarchy. Does this sound like a sensible approach? What is your approach?

submitted by /u/BrentSeidel
[link] [comments]

AEiC 2024 - Ada-Europe conference - 2nd Call for Contributions

The 28th Ada-Europe International Conference on Reliable Software Technologies (AEiC 2024) will take place in Barcelona, Spain from 11 to 14 June, and comprises different tracks and co-located events.

Submission deadlines: 15 January for journal track papers; 26 February for industrial track and work-in-progress track papers, tutorial and workshop proposals. Submit early: tutorial/workshop proposals will be evaluated ASAP, with decisions from 1 January 2024!

More information on the conference site, including an extensive list of topics, and details on the call for contributions for the various tracks.

www.ada-europe.org/conference2024

#AEiC2024 #AdaEurope #AdaProgramming

1 post - 1 participant

Read full topic

AEiC 2024 - Ada-Europe conference - 2nd Call for Contributions

The 28th Ada-Europe International Conference on Reliable Software Technologies (AEiC 2024) will take place in Barcelona, Spain from 11 to 14 June, and comprises different tracks and co-located events.

Submission deadlines: 15 January for journal track papers; 26 February for industrial track and work-in-progress track papers, tutorial and workshop proposals. Submit early: tutorial/workshop proposals will be evaluated ASAP, with decisions from 1 January 2024!

More information on the conference site, including an extensive list of topics, and details on the call for contributions for the various tracks.

www.ada-europe.org/conference2024

#AEiC2024 #AdaEurope #AdaProgramming

submitted by /u/Dirk042
[link] [comments]

Gnatd.v elaboration

I wonder. Is gnatd.v a better option than
pragma preelaborate

Is preelaborate more compiler portable? Though I do not use the features that it protects against such as dynamic dispatch, so it is simply an unneeded restriction for me with Gnat. However gnatd.v seems to offer more such as in regard to uninitialised variables? Assuming it works as I had no compile issues :joy:.

see 7.7

https://docs.adacore.com/spark2014-docs/html/lrm/packages.html

2 posts - 2 participants

Read full topic

❌