I'm going over Ada code "cloned" from the Rosetta Code web site; I think this topic was discussed earlier, but couldn't find it

Hi;

There is a Rosetta Code task for which the Ada solution fails to compile for me.

I have not added any pragma to the code nor have I used any GNAT flags.

I think that this topic was discussed here previously, but I can’t seem to find it…

Here is the result from gnatmake:

test_amb.adb:18:04: warning: type "Amb" is frozen by body [enabled by default]
test_amb.adb:18:04: warning: an equality operator cannot be declared after this point [enabled by default]
test_amb.adb:39:13: error: equality operator must be declared before type "Amb" is frozen (RM 4.5.2 (9.8)) (Ada 2012)

So, is the code as written on the web site correct and I have add the appropriate GNAT flag(s) and/or an Ada pragma; or is the code incorrect?

Here’s the code as it currently stands on the Rosetta Code web site:

with Ada.Strings.Unbounded;  use Ada.Strings.Unbounded;
with Ada.Text_IO;            use Ada.Text_IO;

procedure Test_Amb is
   type Alternatives is array (Positive range <>) of Unbounded_String;

   type Amb (Count : Positive) is record
      This : Positive := 1;
      Left : access Amb; 
      List : Alternatives (1..Count);
   end record;
   
   function Image (L : Amb) return String is
   begin
      return To_String (L.List (L.This));
   end Image;

   function "/" (L, R : String) return Amb is
      Result : Amb (2);
   begin
      Append (Result.List (1), L);
      Append (Result.List (2), R);
      return Result;
   end "/";
   
   function "/" (L : Amb; R : String) return Amb is
      Result : Amb (L.Count + 1);
   begin
      Result.List (1..L.Count) := L.List ;
      Append (Result.List (Result.Count), R);
      return Result;
   end "/";

   function "=" (L, R : Amb) return Boolean is
      Left : Unbounded_String renames L.List (L.This);
   begin
      return Element (Left, Length (Left)) = Element (R.List (R.This), 1);
   end "=";
   
   procedure Failure (L : in out Amb) is
   begin
      loop
         if L.This < L.Count then
            L.This := L.This + 1;
         else
            L.This := 1;
            Failure (L.Left.all);
         end if;
         exit when L.Left = null or else L.Left.all = L;
      end loop;
   end Failure;

   procedure Join (L : access Amb; R : in out Amb) is
   begin
      R.Left := L;
      while L.all /= R loop
         Failure (R);
      end loop;
   end Join;

   W_1 : aliased Amb := "the" / "that" / "a";
   W_2 : aliased Amb := "frog" / "elephant" / "thing";
   W_3 : aliased Amb := "walked" / "treaded" / "grows";
   W_4 : aliased Amb := "slowly" / "quickly";
begin
   Join (W_1'Access, W_2);
   Join (W_2'Access, W_3);
   Join (W_3'Access, W_4);
   Put_Line (Image (W_1) & ' ' & Image (W_2) & ' ' & Image (W_3) & ' ' & Image (W_4));
end Test_Amb;

I’m on MacOS (Apple Silicon).

/opt/gnat-aarch64-darwin-15.1.0-2/bin/gnatmake

gnat --version
GNAT 15.0.1 20250418 (prerelease)
Copyright (C) 1996-2025, Free Software Foundation, Inc.

Thanks,
RBE

It was here:

1 Like

Thank you for providing the link to the prior desparate call for help which I completely missed.

RBE

I have re-read the original thread and finally grokked it well enough to provide my alternative version of the Ada code posted Rosetta Code web site which does compile and execute correctly.

Thanks,
RBE

2 Likes