comp.lang.ada
 help / color / mirror / Atom feed
* Q: Trouble creating array and discriminated type
@ 2017-01-20 22:55 b.mcguinness747
  2017-01-20 23:48 ` gautier_niouzes
                   ` (4 more replies)
  0 siblings, 5 replies; 9+ messages in thread
From: b.mcguinness747 @ 2017-01-20 22:55 UTC (permalink / raw)


First, gnatmake complains about two constant arrays I am trying to create.  I have:

  subtype Int2 is Integer range -32768..32767;
  type    Real is digits 16;

...

    a_napl_t : constant array (0..677,0..13) of Int2 := (
      ( 0,  0,  0,  0,  0,  0,  0,  8,-16,  4,  5,  0,  0,  0),
      ( 0,  0,  0,  0,  0,  0,  0, -8, 16, -4, -5,  0,  0,  2),

...
    ));

...

    a_cpl_t : constant array (0..677,0..3) of Real := (
      ( 1440.0,          0.0,          0.0,          0.0),
      (   56.0,       -117.0,        -42.0,        -40.0),
      (  125.0,        -43.0,          0.0,        -54.0),

...
    ));

and I get the messages:

novas.adb:8111:57: warning: upper bound of aggregate out of range
novas.adb:8111:57: warning: Constraint_Error will be raised at run time
novas.adb:8806:55: warning: upper bound of aggregate out of range
novas.adb:8806:55: warning: Constraint_Error will be raised at run time

I'm not sure what this means.  My array bounds are certainly within the range of any reasonable integer type.


Second, I have this record type:

  type Real_Matrix is array (Natural range<>, Natural range<>) of Real;
  type Real_Vector is array (Natural range<>) of Real;

...

  type Ephemeris_Data (Offset_Maximum, Record_Maximum : Positive) is tagged record
    -- Data describing the ephemeris
    Constants               : Maps.Map;
    Database_Name           : UString;
    Earth_Moon_Ratio        : Real;
    First_Valid_Julian_Date : Real;
    Last_Valid_Julian_Date  : Real;
    Julian_Date_Interval    : Real;
    Offsets                 : Offset_Matrix(0..Offset_Maximum, 0..2);
    Record_Length           : Integer := Record_Maximum + 1;

    -- Options currently selected
    Center                  : Center_Point := SUN;
    Units                   : Output_Units := AU;

    -- Stored data from previous method calls, if any
    Last_Record_Read        : Integer := -1;  -- initialize to impossible value
    Record_Buffer           : Real_Vector(0..Record_Maximum);
    Position_Velocity_Sun   : Real_Matrix(0..1, 0..2);
  end record;

While I can create an instance of this type in a function and return it, I can't create such an instance as a member of a package.  I can't specify the dimensions of the offsets array and the record buffer ahead of time; I have to read a text file describing the data before I can determine their values.  So I want to declare the variable in the package and then call an initialization procedure to assign a value to it.  The compiler won't allow this; it insists that the discriminators be specified when the variable is declared.

I have tried declaring the package member as access Ephemeris_Data, which the compiler seems to accept, but then I can't find a way to determine an address to assign to the variable.  For example, the compiler won't let me do this:

JPL_Data : access JPL_Ephemeris.Ephemeris_Data;

procedure initialize (header_file_pathname, coefficient_file_pathname : String) is
begin
  Real_IO.Open (File, Real_IO.In_File, coefficient_file_pathname);
  JPL_Data := JPL_Ephemeris.Make (header_file_pathname)'Access;
end initialize;


I would appreciate help in solving these problems.  One of the main purposes for creating this code is for me to become more familiar with the Ada language.  I am much more familiar with Java, so I may not be looking at this with an Ada mindset.

--- Brian McGuinness

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Q: Trouble creating array and discriminated type
  2017-01-20 22:55 Q: Trouble creating array and discriminated type b.mcguinness747
@ 2017-01-20 23:48 ` gautier_niouzes
  2017-01-21  7:23 ` Simon Wright
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 9+ messages in thread
From: gautier_niouzes @ 2017-01-20 23:48 UTC (permalink / raw)


>     a_napl_t : constant array (0..677,0..13) of Int2 := (
>       ( 0,  0,  0,  0,  0,  0,  0,  8,-16,  4,  5,  0,  0,  0),
>       ( 0,  0,  0,  0,  0,  0,  0, -8, 16, -4, -5,  0,  0,  2),
>
> ...
>    ));

Are there exactly 678 rows of these data ?
You get that warning if you accidentally have 679 or more rows.
_________________________
Gautier's Ada programming
http://gautiersblog.blogspot.com/search/label/Ada 
NB: Pour une réponse directe, adresse e-mail valable par le lien ci-dessus


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Q: Trouble creating array and discriminated type
  2017-01-20 22:55 Q: Trouble creating array and discriminated type b.mcguinness747
  2017-01-20 23:48 ` gautier_niouzes
@ 2017-01-21  7:23 ` Simon Wright
  2017-01-21  9:41 ` Jeffrey R. Carter
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 9+ messages in thread
From: Simon Wright @ 2017-01-21  7:23 UTC (permalink / raw)


b.mcguinness747@gmail.com writes:

> First, gnatmake complains about two constant arrays I am trying to
> create.  I have:
>
>   subtype Int2 is Integer range -32768..32767;
>   type    Real is digits 16;
>
> ...
>
>     a_napl_t : constant array (0..677,0..13) of Int2 := (
>       ( 0,  0,  0,  0,  0,  0,  0,  8,-16,  4,  5,  0,  0,  0),
>       ( 0,  0,  0,  0,  0,  0,  0, -8, 16, -4, -5,  0,  0,  2),
>
> ...
>     ));

Addressing the first problem only (for the moment) --

It's more normal Ada to let the compiler work out the size of the array
from the size of the data, something like this:

=============OX===============
with Ada.Text_IO; use Ada.Text_IO;

procedure B_M_1 is

   subtype Int2 is Integer range -32768 .. 32767;
   type    Real is digits 6; -- shorter string representation, see at end

   --  Declare an unconstrained array type, indexed from 0 (you
   --  probably don't want to use Integer here, because initialization
   --  with an aggregate will result in an object with indices running
   --  from Integer'First, -2**31, leading to confusion)
   type Napl_Data is array (Natural range <>, Natural range <>) of Int2;

   A_Napl_T : constant Napl_Data :=
     (
      ( 0,  0,  0,  0,  0,  0,  0,  8,-16,  4,  5,  0,  0,  0),
      ( 0,  0,  0,  0,  0,  0,  0, -8, 16, -4, -5,  0,  0,  2)
     );

   --  This time, make the indices run from 1 (many Ada programmers
   --  think this more natural :-)
   type Cpl_Data is array (Positive range <>, Positive range <>) of Real;

   A_Cpl_T : constant Cpl_Data :=
     (
      ( 1440.0,          0.0,          0.0,          0.0),
      (   56.0,       -117.0,        -42.0,        -40.0),
      (  125.0,        -43.0,          0.0,        -54.0)
     );

begin
   --  Print out the ranges (NB 'Img is a GNAT extension, not standard Ada)
   Put_Line ("A_Napl_T range: " & A_Napl_T'First (1)'Img
               & " .. " & A_Napl_T'Last (1)'Img
               & ", " & A_Napl_T'First (2)'Img
               & " .. " & A_Napl_T'Last (2)'Img);
   Put_Line ("A_Cpl_T range: " & A_Cpl_T'First (1)'Img
               & " .. " & A_Cpl_T'Last (1)'Img
               & ", " & A_Cpl_T'First (2)'Img
               & " .. " & A_Cpl_T'Last (2)'Img);

   --  Print out the values (of the shorter array!)
   for J in A_Cpl_T'Range (1) loop
      for K in A_Cpl_T'Range (2) loop
         Put (A_Cpl_T (J, K)'Img & " ");
      end loop;
      New_Line;
   end loop;
end B_M_1;
=============OX===============

which gives

$ ./b_m_1 
A_Napl_T range:  0 ..  1,  0 ..  13
A_Cpl_T range:  1 ..  3,  1 ..  4
 1.44000E+03  0.00000E+00  0.00000E+00  0.00000E+00 
 5.60000E+01 -1.17000E+02 -4.20000E+01 -4.00000E+01 
 1.25000E+02 -4.30000E+01  0.00000E+00 -5.40000E+01 

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Q: Trouble creating array and discriminated type
  2017-01-20 22:55 Q: Trouble creating array and discriminated type b.mcguinness747
  2017-01-20 23:48 ` gautier_niouzes
  2017-01-21  7:23 ` Simon Wright
@ 2017-01-21  9:41 ` Jeffrey R. Carter
  2017-01-21 17:05 ` Stephen Leake
  2017-01-21 18:55 ` b.mcguinness747
  4 siblings, 0 replies; 9+ messages in thread
From: Jeffrey R. Carter @ 2017-01-21  9:41 UTC (permalink / raw)


On 01/20/2017 11:55 PM, b.mcguinness747@gmail.com wrote:
>
> I would appreciate help in solving these problems.  One of the main purposes
> for creating this code is for me to become more familiar with the Ada
> language.  I am much more familiar with Java, so I may not be looking at this
> with an Ada mindset.

It's very rare in Ada to have arrays with lower bounds of zero; code with lots 
of that usually reflects thinking warped by a poorly designed language in which 
all arrays have a lower bound of zero. Except when an array is serving as a map, 
it is usually more intuitive to use a lower bound of 1: we talk of being "1st in 
line" when at the head of a queue, or the 1st letter of a word.

Another way to put this is that having a fixed lower bound forces a translation 
from the problem concept to the language index concept, introducing an 
opportunity for error. Ada allows the problem concept to be used as the index, 
eliminating that opportunity.

My 1st (not 0th) programming job involved a language in which all arrays had 
lower bounds of 1, and we had data for the years 1600-1960. Translating from 
years to indices was a source of errors, so this is not just an academic problem.

It's also useful sometimes to have non-numeric indices, so Ada allows 
enumeration types as indices, too.

In addition to using index ranges that reflect your problem rather than the 
constraints of some language (I suspect your problem domain has identifying 
values other than 0 .. 677 for those indices), I'd also recommend eliminating 
all anonymous types; having to explicitly define and name all types often has a 
clarifying effect on one's thinking. This is especially true for anonymous 
access types, which have complicated rules no one completely understands.

Gautier has explained a likely reason for your constant-array declaration 
errors, and Wright has shown the typical way such things are declared in Ada. 
It's probably a good idea to defer the discussion of discriminated records, 
constrained and unconstrained variables, and function results as objects until 
after you've digested what you've had so far.

-- 
Jeff Carter
"Mr. President, we must not allow a mine-shaft gap!"
Dr. Strangelove
33


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Q: Trouble creating array and discriminated type
  2017-01-20 22:55 Q: Trouble creating array and discriminated type b.mcguinness747
                   ` (2 preceding siblings ...)
  2017-01-21  9:41 ` Jeffrey R. Carter
@ 2017-01-21 17:05 ` Stephen Leake
  2017-01-22  5:12   ` Robert Eachus
  2017-01-23  8:02   ` G.B.
  2017-01-21 18:55 ` b.mcguinness747
  4 siblings, 2 replies; 9+ messages in thread
From: Stephen Leake @ 2017-01-21 17:05 UTC (permalink / raw)


On Friday, January 20, 2017 at 4:55:52 PM UTC-6, b.mcgui...@gmail.com wrote:

Addressing the second problem:

>   type Ephemeris_Data (Offset_Maximum, Record_Maximum : Positive) is tagged record

If you add defaults to the discriminants, Ada will let you declare an uninitialized object. On the other hand, it might try to allocate all of memory for it, in which case the access object is a better solution.

 
> JPL_Data : access JPL_Ephemeris.Ephemeris_Data;
> 
> procedure initialize (header_file_pathname, coefficient_file_pathname : String) is
> begin
>   Real_IO.Open (File, Real_IO.In_File, coefficient_file_pathname);
>   JPL_Data := JPL_Ephemeris.Make (header_file_pathname)'Access;

This should be:

   JPL_Data := new JPL_Ephemeris.Ephemeris_Data'(JPL_Ephemeris.make (file);

It might be better to not declare this object in the package, but rather in the subprogram where it is needed; then you could avoid the access type. On the other hand, if it is shared among many subprograms, this is the right way.

--  Stephe


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Q: Trouble creating array and discriminated type
  2017-01-20 22:55 Q: Trouble creating array and discriminated type b.mcguinness747
                   ` (3 preceding siblings ...)
  2017-01-21 17:05 ` Stephen Leake
@ 2017-01-21 18:55 ` b.mcguinness747
  4 siblings, 0 replies; 9+ messages in thread
From: b.mcguinness747 @ 2017-01-21 18:55 UTC (permalink / raw)


Thank you for your replies.  They have been very helpful to me.  I have gotten the code to compile properly now.

It is also good to have your advice on how to approach these problems.  Although for my current purposes there is no significant difference between starting indices at 0 or starting them at 1, I can now see where this sort of flexibility could be a major advantage; for example, in one algorithm for converting between Julian days and calendar dates it would be convenient to have an array of integers with indices ranging from 3 to 14.  I also take your point about avoiding anonymous arrays.

--- Brian McGuinness


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Q: Trouble creating array and discriminated type
  2017-01-21 17:05 ` Stephen Leake
@ 2017-01-22  5:12   ` Robert Eachus
  2017-01-23  8:02   ` G.B.
  1 sibling, 0 replies; 9+ messages in thread
From: Robert Eachus @ 2017-01-22  5:12 UTC (permalink / raw)


On Saturday, January 21, 2017 at 12:05:34 PM UTC-5, Stephen Leake wrote:
> On Friday, January 20, 2017 at 4:55:52 PM UTC-6, b.mcgui...@gmail.com wrote:
> 
> Addressing the second problem:
> 
> >   type Ephemeris_Data (Offset_Maximum, Record_Maximum : Positive) is tagged record
> 
> If you add defaults to the discriminants, Ada will let you declare an 
> uninitialized object. On the other hand, it might try to allocate all of 
> memory for it, in which case the access object is a better solution.

Since you are trying to learn Ada, it is worth noting that you can declare subtypes for the index ranges, since you seem to have maximums that are set when you run the program:

 subtype Offset is Positive range 1..Offset_Maximum;
 subtype Record_type is Positive range 1..Record_Maximum;
 -- or you can have one subtype if the bounds are the same...

 type Ephemeris_Data (Offset := Offset_Maximum, Record_type := Record_Maximum)
    is tagged record...

 Now even if the compiler allocates the maximum size for each object, that's likely to be fine with you.  Note that there is no requirement in Ada for the values Offset_Maximum and Record_Maximum to be static.  You can read them in or get them from the keyboard, and no one will complain.

One other "learning" type point.  I always used to teach students that if they needed something that eventually made sense as a standalone package, nest it within the main program until you get it running, then move toward greater abstraction.  In this particular case, your complaints about package initialization seem to indicate that the package want to create should actually be a generic package, instantiated inside the main program in a nested scope.  I don't really expect you to understand what I just said, until you actually have a working program and transform it to have a separately compiled generic package. ;-)





^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Q: Trouble creating array and discriminated type
  2017-01-21 17:05 ` Stephen Leake
  2017-01-22  5:12   ` Robert Eachus
@ 2017-01-23  8:02   ` G.B.
  2017-01-23  8:19     ` Simon Wright
  1 sibling, 1 reply; 9+ messages in thread
From: G.B. @ 2017-01-23  8:02 UTC (permalink / raw)


On 21.01.17 18:05, Stephen Leake wrote:
>>   type Ephemeris_Data (Offset_Maximum, Record_Maximum : Positive) is tagged record
> If you add defaults to the discriminants, Ada will let you declare an uninitialized object.

Defaults for discriminants of tagged types would not be permitted,
only if objects of the type can not have their discriminants changed
after creation (tagged limited). The reason is stated in AARM 3.7(9.*)
and it seems to say "It's complicated".

The paragraph suggest that for some use cases, one can declare a subtype
that sets the discriminants to default values. IIUC, these subtypes
can then be used in derivations also.

-- 
"HOTDOGS ARE NOT BOOKMARKS"
Springfield Elementary teaching staff


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Q: Trouble creating array and discriminated type
  2017-01-23  8:02   ` G.B.
@ 2017-01-23  8:19     ` Simon Wright
  0 siblings, 0 replies; 9+ messages in thread
From: Simon Wright @ 2017-01-23  8:19 UTC (permalink / raw)


"G.B." <bauhaus@notmyhomepage.invalid> writes:

> Defaults for discriminants of tagged types would not be permitted,
> only if objects of the type can not have their discriminants changed
> after creation (tagged limited). The reason is stated in AARM 3.7(9.*)
> and it seems to say "It's complicated".
>
> The paragraph suggest that for some use cases, one can declare a
> subtype that sets the discriminants to default values. IIUC, these
> subtypes can then be used in derivations also.

Not sure about use in derivations, but I have

   generic
      Maximum_Size : Positive;
   package BC.Containers.Collections.Bounded is

      type Unconstrained_Collection
        (Maximum_Size : Positive) is new Abstract_Collection with private;

      subtype Collection
         is Unconstrained_Collection (Maximum_Size => Maximum_Size);

I've never been happy about Maximum_Size there, but that's the sort of
thing that happens when you already have a published interface that
you're reluctant to change!

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2017-01-23  8:19 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-01-20 22:55 Q: Trouble creating array and discriminated type b.mcguinness747
2017-01-20 23:48 ` gautier_niouzes
2017-01-21  7:23 ` Simon Wright
2017-01-21  9:41 ` Jeffrey R. Carter
2017-01-21 17:05 ` Stephen Leake
2017-01-22  5:12   ` Robert Eachus
2017-01-23  8:02   ` G.B.
2017-01-23  8:19     ` Simon Wright
2017-01-21 18:55 ` b.mcguinness747

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox