❌ About FreshRSS

Normal view

There are new articles available, click to refresh the page.
Yesterday — 27 March 2023Communities

Since MSys2 dropped support for Ada (!), how can I build Ada projects such as sdlada and gprbuild-bootstrap that require command-line tools (e.g. makefiles or bootstrap.sh) on Windows?

I'm several levels down a rabbit hole here, but if you'll bear with me I want to outline the whole chain in case there's a better way to achieve my original goal that I missed.

  • I want to port some old embedded-device Ada code to run in a gtkada application.
    • I have installed GNAT Studio and can build/run simple gtkada projects with it.
  • I downloaded the "sdlada" project to learn more about interfacing Ada with C code
    • Also I might want to use SDL visuals in my GTK app
    • However I can't directly open sdlada's .gpr files with GNAT Studio
      • Because it's missing some Ada source code that's generated in the build
      • Apparently you must use the makefile to build sdlada
      • When I try on MSys2, the makefile fails because my system is missing gprbuild
  • So I tried to follow the Bootstrapping instructions for gprbuild
    • https://github.com/AdaCore/gprbuild/
    • But the gprbuild bootstrap.sh script fails because my system doesn't have gnatmake
      • Facepalm - because MSys2 dropped Ada support
      • "There's a hole in the bucket"
  • On an MSys2 issue it was suggested a user might build gcc from source to get back Ada support
    • I have built gcc before (for a cross-compiler) so... maybe? I could try this...
    • However if the MSys2 maintainer can't get it to build for him why would it work for me?
  • But this is getting off in the weeds considering - I have GNAT Studio and can already build+run Ada programs
    • But how do I run a makefile with gprbuild from GNAT Studio on Windows?
      • Is there a "GNAT Studio Command Line" (terminal) available somewhere? (Like how an install of Visual Studio includes shortcuts to open a command line preloaded with paths to MSVC tools.)
      • Is it possible (and advisable) to try to MSys2 make refer to the tools in "C:\GNAT\2021\bin"?
submitted by /u/valdocs_user
[link] [comments]
Before yesterdayCommunities

"Union" types in Ada

Dear Ada community,

I've just picked up Ada (again) and try to implement a little API client as a first learning project. Currently I'm creating model classes for the entities returned by a JSON API. In the API specs, there is a JSON field, which can contain different data types, which are an ISO timestring *or* an ISO time interval.

Now I'm trying to find out, what is the "Ada way" to define a field, that can handle multiple types. The only thing that comes into my mind for my example is a variant record. Something like

type Time_Or_Interval (Has_End : Boolean) is record Begin_Date : Ada.Calendar.Time; case Has_End is when True => End_Date : Ada.Calendar.Time; when False => null; end case; end record; 

Is this the preferred way?

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

ADA code help (beginner)

By: Harsha
23 March 2023 at 08:56

Hello,
I am learning ADA language at my university and need help with the following question.

  1. Write the iterative version and recursive version of a program that determines whether a given word is a palindrome. For instance, eve is a palindrome

  2. write a program that reads a given word by the user and prints whether it is a palindrome on the screen.

Your help is very much appreciated! Thank you

3 posts - 3 participants

Read full topic

Getting unix command CAT to work on Windows

The issue of getting the equivalent command of the Unix command cat on Windows has been discussed for example here: What is the Windows equivalent of the Unix command cat?

I have looked at the project MinGW here: MinGW - Minimalist GNU for Windows Files

I have installed the file mingw-get-setup.exe and now I have a gui with which I can retrieve necessary Unix tools by downloading from the internet. But I do not know which of these tools has/have the cat command.

I would like to use the cat command to merge Ada specifications and bodies files so as to distribute the codes as just one .ada file on which other users can use the gnatchop command to retrieve the original files again.

If there are other better projects on Windows to obtain the cat command directly in a single Windows installation unlike the MinGW project in which tools have to be installed by downloading from the internet, I am interested.

New release of vscode extension For Ada 23.0.15

VS Code Extension for Ada 23.0.15

In this release we improved Alire integration. Now you don't need the compiler to be in the PATH (only alr) when you are working with a crate, because Alire will configure it for you. Suppose you setup a crate for Rasperry Pico, if you open it in VS Code, then navigation should work out of the box. Also any Alire configuration is skipped altogether if the VSCode was launched with alr edit or alr exec.

We also change auto-detected tasks, so they are use alr exec -- prefix to run gprbuild, gprclean, gnatprove in the correct environment. You can also pass extra option using args property in the tasks.json file.

Renaming tool leaves found renaming problems in the diagnostics, so you can examine them in the "Problems view".

You can install newer version from the marketplace, OpenVSX or download it from GitHub release.

Happy codding!

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

Ada input format issue

I'm new to Ada and not sure how to fix this code. It appears it is about format issue, but don't know what is causing this. I am trying to read two files called a.txt and b.txt then compute the inverse of it. Sorry again am just stuck.

Here is the input files

A.txt

2 -2 4 -2 2 0 
1 0 4 -3 0 0
1 1 1 1 1 1 
1 0 0 -1 0 0
3 0 0 -3 0 2
1 0 0 0 -2 4

B.txt

13
18
51
82
32
12

here is my code

with Ada.Text_IO, Ada.Float_Text_IO, Ada.Integer_Text_IO;
use Ada.Text_IO, Ada.Float_Text_IO, Ada.Integer_Text_IO;

procedure Matrix_Inverse is

   type Matrix is array (1 .. 6, 1 .. 6) of Float;
   type Vector is array (1 .. 6) of Float;
   
   function Get_Matrix_From_File(Filename : String) return Matrix is
      A : Matrix := (others => (others => 0.0));
      File : File_Type;
      Line : String (1 .. 20);
      Last : Natural;
   begin
      Open (File, In_File, Filename);
      for I in A'Range(1) loop
         Get_Line (File, Line, Last);
         for J in A'Range(2) loop
            A (I, J) := Float'Value (Line (1 .. Last));
            Get (File, Line);
            Get_Line (File, Line, Last);
         end loop;
         A (I, 6) := Float'Value (Line (1 .. Last));
      end loop;
      Close (File);
      return A;
   end Get_Matrix_From_File;
   
   function Get_Vector_From_File(Filename : String) return Vector is
      B : Vector := (others => 0.0);
      File : File_Type;
   begin
      Open (File, In_File, Filename);
      for I in B'Range loop
         Get (File, B (I));
      end loop;
      Close (File);
      return B;
   end Get_Vector_From_File;
   
   procedure Print_Matrix(A : Matrix) is
   begin
      for I in A'Range(1) loop
         for J in A'Range(2) loop
            Put (A (I, J), 6, 2);
            Put (" ");
         end loop;
         New_Line;
      end loop;
   end Print_Matrix;
   
   function Inverse(A : Matrix) return Matrix is
      Inv : Matrix := (others => (others => 0.0));
      Identity : Matrix := (others => (others => 0.0));
   begin
      for I in Identity'Range(1) loop
         Identity (I, I) := 1.0;
      end loop;
      
      for I in A'Range(1) loop
         if A (I, I) = 0.0 then
            for J in I + 1 .. A'Range(1)'Last loop
               if A (J, I) /= 0.0 then
                  for K in A'Range(2) loop
                     A (I, K) := A (I, K) + A (J, K);
                     Identity (I, K) := Identity (I, K) + Identity (J, K);
                  end loop;
                  exit;
               end if;
            end loop;
         end if;
    for J in A'Range(1) loop
      if J /= I then
          declare
            Factor : constant Float := A (J, I) / A (I, I);
          begin
            for K in A'Range(2) loop
                A (J, K) := A (J, K) - Factor * A (I, K);
                Identity (J, K) := Identity (J, K) - Factor * Identity (I, K);
            end loop;
          end;
      end if;
    end loop;

    for I in A'Range(1) loop
      declare
          Diagonal : constant Float := A (I, I);
      begin
          for J in A'Range(2) loop
            Identity (I, J) := Identity (I, J) / Diagonal;
          end loop;
      end;
    end loop;

      return Identity;
    end Inverse;

  function Solve(A : Matrix; B : Vector) return Vector is
    Inv_A : Matrix := Inverse(A);
    Result : Vector := (others => 0.0);
  begin
    for I in Result'Range loop
        for J in Result'Range loop
          Result (I) := Result (I) + Inv_A (I, J) * B (J);
        end loop;
    end loop;
    return Result;
  end Solve;

  A : Matrix := Get_Matrix_From_File("a.txt");
  B : Vector := Get_Vector_From_File("b.txt");

  Solution : Vector := Solve(A, B);

  begin
    Put_Line("Solution:");
    for I in Solution'Range loop
        Put(Solution(I), 6, 2);
        Put(" ");
    end loop;
    New_Line;
end Matrix_Inverse;

Variable arglists in Ada

Why does not Ada support variable function/procedure argument lists? Is it hard to implement or does it somehow go against "we should keep things secure" philosophy of the language?

Varargs were over there at least as early as C and allow very handy things like printf, the likes of which can also be found in other languages like Java or C#. Another neat example is logging functions where it is usual to pass information from all kinds of data types, not only strings, in separate arguments.

And even if this is considered non-secure technique, Ada could still make it better than at least in C by e.g. throwing an exception if there is some mismatch between format string and the actually passed arguments.

Ada and C++ interface, avoid duplicated code [closed]

I'm working on a C++ application, Module_A, that has to use a diverse module, Module_B_Ada and Module_B_CPP depending on configuration.

Module_A + Module_B_Language will be compiled in different OS. I want to avoid duplicating Module_A to have a Module_A for Ada compilation and a Module_A for C++ compilation.

For now, the only thing that came to my mind has been to separate the code that uses the Ada module and exclude it from compilation when is compiled for C++ to avoid linking errors for unresolved symbols.

Another thing I'm thinking about is to comment the "extern" statement on the Module_A and define the Ada services to a void implementation when compiling for C++.

Have yoy ever faced a similar problem? How have you solved it?

wolfSSL Ada/SPARK language bindings

17 March 2023 at 05:35

I was looking for DTLS libraries and found this recent post on the wolfSSL website.

Exciting news in wolfSSL language bindings: we are currently exploring the possibility of adding bindings for the Ada and Spark languages!

Ada is a programming language known for its explicitness, strong typing, and abundance of compile-time checks. It is widely used in safety-critical and high-integrity software. Spark, on the other hand, is a smaller subset of Ada that offers the invaluable ability to formally prove the correctness of your software.

We believe that wolfSSL bindings would be immensely valuable to the Ada and Spark communities. These bindings would provide a production-ready, robust, and well-tested TLS stack that supports the latest protocols (TLS1.3/DTLS1.3). Additionally, it would open the door to obtaining FIPS 140-3 and DOI-178C certifications for Ada and Spark applications that use TLS for their encrypted communications, or that want to use our wolfCrypt implementation for their cryptographic operations, such as encrypting data at rest.

As wolfSSL already supports post-quantum TLS 1.3 and DTLS 1.3, these bindings would also naturally allow you to make your Ada and SPARK applications quantum-safe.

Are you interested in an Ada/Spark wrapper? If so, please do not hesitate to contact us at [email protected] with any questions, comments, or suggestions.

Source: wolfSSL ADA/Spark language bindings – wolfSSL

1 post - 1 participant

Read full topic

Ada: Convert float to decimal

This post is linked to this one Ada 2005 access type. The goal is to use Ada decimal type to get similar results as to hand (and calculator) computations in which 6 decimal places have been used in each intermediate step.

As can be seen from the table below, the values obtained with the Ada code starts to differ from the hand calculation in the last digit when further iterations with the Euler method are taken.

One of the issues with the Ada code was with the line in the main code diff.adb: return 2 * Real(XY)*; It doesn't matter if I leave it as return 2 * X * Y as well.

The differential equation (O.D.E.) is being solved using the basic Euler method (which is an approximate method which is not that accurate). The D.E. is dy/dx = 2xy. The initial condition is at y0(x=x0=1) = 1. The analytical solution is y = e^((x^2)-1). The objective is to obtain y(x=1.5).

We start with the point (x0,y0) = (1,1). We use a step size h = 0.1 i.e. x is increased with each iteration in the Euler method to 1.1, 1.2, 1.3,..etc. and the corresponding value of y (the variable whose solution is being sought) is determined from the Euler algorithm which is:

y(n) = y(n-1) + h * f(x(n-1), y(n-1))

Here y(n-1) when we start the algorithm is y(0) = 1. Also x(n-1) is our starting x(0) = 1. The function f is the derivative function dy/dx given above as dy/dx = 2xy.

Briefly, h * f(x(n-1), y(n-1)) is the "horizontal distance between two successive x values" multiplied by the gradient. The gradient formula is dy/dx = delta y /delta x which gives delta y or (the change in y) as

delta y = delta x * dy/dx.

In the Euler formula h is the delta x and dy/dx is the gradient. So h * f(x(n-1), y(n-1)) gives delta y which is the change in the value of y i.e. delta y. This change in y is then added to the previous value of y. The Euler method is basically a first order Taylor approximation with a small change in x. A gradient line is drawn to the curve and the next value of the solution variable y is on this tangent line at the successive value of x i.e. xnew = xold + h where h is the step.

The table next shows the solution values for the variable y by the Euler method when calculated by hand (and calculator), by my Ada code and finally in the last column the exact solution.

x y (hand) Ada code y (exact)
1.1 1.200000 1.200000 1.233678
1.2 1.464000 1.464000 1.552707
1.3 1.815360 1.815360 1.993716
1.4 2.287354 2.287353 2.611696
1.5 2.927813 2.927811 3.490343

By hand and calculator for instance, y(x=1.1) i.e y(1) at x = x(1) is calculated as y(x=1.1) = y(0) + h * f(x=1,y=1) = 1 + 0.1 * (2 * 1* 1) = 1.200000 to 6 d.p.

y(2) is calculated at x = x(2) as y(x=1.2) = y(1) + h * f(x=1.1,y=1.200000) = 1.200000 + 0.1 * (2 * 1.1* 1.200000) = 1.464000 to 6 d.p.

y(3) is calculated at x = x(3) as y(x=1.3) = y(2) + h * f(x=1.2,y=1.464000) = 1.464000 + 0.1 * (2 * 1.2* 1.464000) = 1.815360 to 6 d.p.

y(4) is calculated at x = x(4) as y(x=1.4) = y(3) + h * f(x=1.3,y=1.815360) = 1.815360 + 0.1 * (2 * 1.3* 1.815360) = 2.287354 to 6 d.p.

y(5) is calculated at x = x(5) as y(x=1.5) = y(4) + h * f(x=1.4,y=2.287354) = 2.287354 + 0.1 * (2 * 1.4* 2.287354) = 2.927813 to 6 d.p.

Now I want to modify the codes so that they work with a fixed number of decimal places which is 6 here after the decimal place.

The main code is diff.adb:

with Ada.Text_IO;
with Euler;
procedure Diff is

  type Real is delta 0.000001 digits 9;
  type Vector is array(Integer range <>) of Real;
  type Ptr is access function (X: Real; Y: Real) return Real;
   
  package Real_IO is new Ada.Text_IO.Decimal_IO(Num => Real); 
  use Real_IO; 

  procedure Solve is new Euler(Decimal_Type => Real, Vector_Type => Vector, Function_Ptr => Ptr);

  function Maths_Func(X: Real; Y: Real) return Real is
  begin
    return 2 * Real(X*Y);
  end Maths_Func;

  
  Answer: Vector(1..6);

begin
  Solve(F => Maths_Func'Access, Initial_Value => 1.0, Increment => 0.1, Result => Answer);
  for N in Answer'Range loop
    Put(1.0 + 0.1 * Real(N-1), Exp => 0);
    Put( Answer(N), Exp => 0);
    Ada.Text_IO.New_Line;
  end loop;
end Diff;

Then comes euler.ads:

generic
  type Decimal_Type is delta <> digits <>;
  type Vector_Type is array(Integer range <>) of Decimal_Type;
  type Function_Ptr is access function (X: Decimal_Type; Y: Decimal_Type) return Decimal_Type;
procedure Euler(
  F: in Function_Ptr; Initial_Value, Increment: in Decimal_Type; Result: out Vector_Type);

and the package body euler.adb

procedure Euler
  (F : in Function_Ptr; Initial_Value, Increment : in Decimal_Type; Result : out Vector_Type)
is
   Step : constant Decimal_Type := Increment;
   Current_X : Decimal_Type := 1.0;

begin
   Result (Result'First) := Initial_Value;
   for N in Result'First + 1 .. Result'Last loop
      Result (N) := Result (N - 1) + Step * F(Current_X, Result (N - 1));
      Current_X := Current_X + Step;
   end loop;
end Euler;

On compilation, I get the messages pointing to diff.adb:

type cannot be determined from context

explicit conversion to result type required

for the line return 2.0 times X times Y;

Perhaps the 2.0 is causing the trouble here. How to convert this Float number to Decimal?

I believe that further down in diff.adb, I will get the same issue with the line:

Solve(F => Maths_Func'Access, Initial_Value => 1.0, Increment => 0.1, Result => Answer);

for it contains Floating point numbers as well.

The compilation was done on Windows with the 32-bit GNAT community edition of year 2011. Why 2011? This is because I like the IDE better for that year rather than the pale ones which come in the recent years.

The revised codes based on trashgod codes which work are given next:

The main file diff.adb

with Ada.Numerics.Generic_Elementary_Functions; use Ada.Numerics;
with Ada.Text_IO;                               use Ada.Text_IO;
with Euler;

procedure Diff is

   type Real is digits 7;
   type Vector is array (Positive range <>) of Real;
   type Ptr is access function (X : Real; Y : Real) return Real;
   type Round_Ptr is access function (V : Real) return Real;

   procedure Solve is new Euler (Float_Type => Real, Vector => Vector, Function_Ptr => Ptr, Function_Round_Ptr => Round_Ptr);
   package Real_Functions is new Generic_Elementary_Functions (Real);
   use Real_Functions;
   package Real_IO is new Ada.Text_IO.Float_IO (Real);
   use Real_IO;

   function DFDX (X, Y : Real) return Real is (2.0 * X * Y);
   function F (X : Real) return Real is (Exp (X**2.0 - 1.0));
   function Round (V : in Real) return Real is (Real'Rounding (1.0E6 * V) / 1.0E6);

   XI      : constant Real := 1.0;
   YI      : constant Real := 1.0;
   Step    : constant Real := 0.1;
   Result  : Vector (Positive'First .. 6); --11 if step = 0.05
   X_Value : Real;

begin
   Solve (DFDX'Access, Round'Access, XI, YI, Step, Result);
   Put_line("        x      calc     exact     delta");
   for N in Result'Range loop
      X_Value := 1.0 + Step * Real (N - 1);
      Put (X_Value, Exp => 0);
      Put (" ");
      Put (Result (N), Exp => 0);
      Put (" ");
      Put (F (X_Value), Exp => 0);
      Put (" ");
      Put (Result (N) - F (X_Value), Exp => 0);
      Ada.Text_IO.New_Line;
   end loop;
end Diff;

The file euler.ads

generic
   type Float_Type is digits <>;
   type Vector is array (Positive range <>) of Float_Type;
   type Function_Ptr is access function (X, Y : Float_Type) return Float_Type;
   type Function_Round_Ptr is access function (V : Float_Type) return Float_Type;
procedure Euler
  (DFDX : in Function_Ptr; Round : Function_Round_Ptr; XI, YI, Step : in Float_Type; Result : out Vector);

The file euler.adb

procedure Euler
  (DFDX : in Function_Ptr; Round : Function_Round_Ptr; XI, YI, Step : in Float_Type; Result : out Vector)
is
   H : constant Float_Type := Step;
   X : Float_Type          := XI;
begin
   Result (Result'First) := YI;
   for N in Result'First + 1 .. Result'Last loop
       Result (N) :=  Round(Result (N - 1)) + Round(H * DFDX (X, Result (N - 1)));
       X          := X + Step;
   end loop;
end Euler;

giving the output with **step h = 0.1 **

x calc (Ada) exact delta
1.1 1.200000 1.233678 1.233678
1.2 1.464000 1.552707 -0.033678
1.3 1.815360 1.993716 -0.088707
1.4 2.287354 2.611696 -0.178356
1.5 2.927813 3.490343 -0.562530

The calc (Ada) results agree with hand (and calculator) computations.

❌
❌