comp.lang.ada
 help / color / mirror / Atom feed
* Arrays and Access types...
@ 2001-10-26  4:46 Eric G. Miller
  2001-10-26  5:39 ` James Rogers
                   ` (5 more replies)
  0 siblings, 6 replies; 12+ messages in thread
From: Eric G. Miller @ 2001-10-26  4:46 UTC (permalink / raw)



New to Ada and trying to figure out how to deal with arbitrary
slices of arrays.  I defined an array type and an access type
for it, but I can't seem to figure out how to take a slice of
the array and assign that slice to an access type.

Type is like:

type My_Array is array (Positive range <>) of Integer;
type My_Array_Ref is access My_Array;

... in body ...

left, right, start : My_Array_Ref;

begin
    start := new My_Array (1 .. 200);
    left  := start(start'first .. 100); -- that doesn't work!
...

The first is allowed, whereas I can't figure out how to
make second an access type assignment (is it possible?).

What I want to do is progressively subset the array, and I
won't know exactly how it'll get broken up until runtime.  The
original array will get divvied up into smaller and smaller
slices of an earlier slice (the remaining can be discarded).

If there's a way to do this with regular arrays (no access
types), that'll work.  I wanted to minimize the number of
"new" arrays -- I'm not quite comfortable with how/when to
use Unconstrained_Deallocation yet...

-- 
Eric G. Miller <egm2@jps.net>



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

* Re: Arrays and Access types...
  2001-10-26  4:46 Arrays and Access types Eric G. Miller
@ 2001-10-26  5:39 ` James Rogers
  2001-10-26  6:45   ` Eric G. Miller
  2001-10-26  6:14 ` tmoran
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 12+ messages in thread
From: James Rogers @ 2001-10-26  5:39 UTC (permalink / raw)


Unlike C, Ada arrays are not directly related to access types or
pointers. 

There are several ways to solve your problem. My personal approach
would be to create a record structure to keep track of your slicing
on a single array element. One such data structure follows:

--- Slicable array package
generic
   Max_Size : Positive;
   type Element is private;
package Slicing_Array is
   
   subtype Array_Index is Positive range 1..Max_Size;
   type Element_Array is array(Array_Index range <>) of Element;
   type Slicable_Array is private;

   function Create(Item : Element_Array) return Slicable_Array;
   function First(Item : Slicable_Array) return Positive;
   function Last(Item : Slicable_Array) return Positive;
   function To_Array(Item : Slicable_Array) return Element_Array;
   procedure Slice(Item : in out Slicable_Array; 
                   First : Positive; Last : Positive);
   Bounds_Error : Exception; -- When slicing beyond the array bounds
private
   type Slicable_Array is record 
      First : Positive := 1;
      Last  : Positive := Max_Size;
      Buffer : Element_Array(Array_Index'Range);
   end record;
end Slicing_Array;

--- Slicable array package

package body Slicing_Array is
   function Create(Item : Element_Array) return Slicable_Array is
      Result : Slicable_Array;
   begin
      Result.Last := Item'Length;
      Result.Buffer(1..Result.Last) := Item;
      return Result;
   end Create;

   function First(Item : Slicable_Array) return Positive is
   begin
      return Item.First;
   end First;

   function Last(Item : Slicable_Array) return Positive is
   begin
      return Item.Last;
   end Last;

   function To_Array(Item : Slicable_Array) return Element_Array is
   begin
      return Item.Buffer(Item.First..Item.Last);
   end To_Array;

   procedure Slice(Item : in out Slicable_Array; 
                   First : Positive; Last : Positive) is
   begin
      if First not in Array_Index or Last not in Array_Index then
         raise Bounds_Error;
      end if;
      Item.First := First;
      Item.Last := Last; 
   end Slice;
end Slicing_Array;
   
Jim Rogers
Colorado Springs, Colorado USA

"Eric G. Miller" wrote:
> 
> New to Ada and trying to figure out how to deal with arbitrary
> slices of arrays.  I defined an array type and an access type
> for it, but I can't seem to figure out how to take a slice of
> the array and assign that slice to an access type.
> ...
> 
> What I want to do is progressively subset the array, and I
> won't know exactly how it'll get broken up until runtime.  The
> original array will get divvied up into smaller and smaller
> slices of an earlier slice (the remaining can be discarded).



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

* Re: Arrays and Access types...
  2001-10-26  4:46 Arrays and Access types Eric G. Miller
  2001-10-26  5:39 ` James Rogers
@ 2001-10-26  6:14 ` tmoran
  2001-10-26 14:26 ` Ted Dennison
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 12+ messages in thread
From: tmoran @ 2001-10-26  6:14 UTC (permalink / raw)


>left, right, start : My_Array_Ref;
> ...
>    left  := start(start'first .. 100); -- that doesn't work!
  "left" is not an array, so you can't assign an array to it - it's an
access type.  I presume you don't want to create a new string with an
initial value that is a copy of start(start'first .. 100), but you want
"left" to rename the leftmost part of "start", and you would prefer to
do this without access values.
  start : string(1 .. 200); -- or whatever
  first_blank:natural;
  left : string renames start(start'first .. 100);
begin
  first_blank := ada.strings.fixed.index(left, " ");  -- assume > 1
  declare
    leftmost_word : string renames left(left'first .. first_blank-1);
  begin
    ...
If you need to divide it into N substrings, where N is not known at
compile time, you'll want a loop or a recursive procedure, of course.



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

* Re: Arrays and Access types...
  2001-10-26  5:39 ` James Rogers
@ 2001-10-26  6:45   ` Eric G. Miller
  2001-10-26 16:40     ` James Rogers
  0 siblings, 1 reply; 12+ messages in thread
From: Eric G. Miller @ 2001-10-26  6:45 UTC (permalink / raw)


On Fri, 26 Oct 2001 05:39:09 GMT, James Rogers <jimmaureenrogers@worldnet.att.net> wrote:

> Unlike C, Ada arrays are not directly related to access types or
> pointers. 

So, I am learning...

> There are several ways to solve your problem. My personal approach
> would be to create a record structure to keep track of your slicing
> on a single array element. One such data structure follows:

I think this type of approach would work, and would avoid multiple
"new" calls.  For the particular problem I'm looking at, I will
have three subsets for each iteration.  I think the other posters
suggestion to use a recursive function would work well since the
initial data size is fairly small and the algorithm will find
the answer in 5 calls or less.

I'm a little confused about the use of generics and what it is
providing here... Is it for the "Element" type, so's the
package doesn't have to care what type of thing it is?  If that's
the case, does the "outside world" have to declare a subtype of
Element to use this generic? or will any type do?  I haven't
really gotten to generics yet (just working on the basics at
the moment).

> --- Slicable array package
> generic
>    Max_Size : Positive;
>    type Element is private;
> package Slicing_Array is
>    
>    subtype Array_Index is Positive range 1..Max_Size;
>    type Element_Array is array(Array_Index range <>) of Element;
>    type Slicable_Array is private;

<snipped>

-- 
Eric G. Miller <egm2@jps.net>



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

* Re: Arrays and Access types...
  2001-10-26  4:46 Arrays and Access types Eric G. Miller
  2001-10-26  5:39 ` James Rogers
  2001-10-26  6:14 ` tmoran
@ 2001-10-26 14:26 ` Ted Dennison
  2001-10-26 19:31 ` chris.danx
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 12+ messages in thread
From: Ted Dennison @ 2001-10-26 14:26 UTC (permalink / raw)


In article <20011025214647.2788a60b.egm2@jps.net>, Eric G. Miller says...
>New to Ada and trying to figure out how to deal with arbitrary
>slices of arrays.  I defined an array type and an access type
>for it, but I can't seem to figure out how to take a slice of

Stop right there. You almost *never* need pointers (access types) in simple Ada
programs. If you find yourself using them, you are almost certianly doing
something wrong. As a beginner, pretend access types don't exist for a while.
Try to do everything without them.

---
T.E.D.    homepage   - http://www.telepath.com/dennison/Ted/TED.html

No trees were killed in the sending of this message. 
However a large number of electrons were terribly inconvenienced.



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

* Re: Arrays and Access types...
  2001-10-26  6:45   ` Eric G. Miller
@ 2001-10-26 16:40     ` James Rogers
  0 siblings, 0 replies; 12+ messages in thread
From: James Rogers @ 2001-10-26 16:40 UTC (permalink / raw)


"Eric G. Miller" wrote:
> 
> On Fri, 26 Oct 2001 05:39:09 GMT, James Rogers <jimmaureenrogers@worldnet.att.net> wrote:
> 
> > --- Slicable array package
> > generic
> >    Max_Size : Positive;
> >    type Element is private;
> > package Slicing_Array is
> >
> >    subtype Array_Index is Positive range 1..Max_Size;
> >    type Element_Array is array(Array_Index range <>) of Element;
> >    type Slicable_Array is private;
> 

Try this example driver program to see how to instantiate a generic
package.

with Slicing_Array;
with Ada.Text_Io;

procedure Slicing_Test is
   Length : Positive := 10;
   package Slicing_Chars is new Slicing_Array
     (Max_Size => Length, Element => Character);

   procedure Print_Chars(Item : Slicable_Array) is
      Temp : Slicing_Chars.Element_Array(First(Item)..Last(Item));
   begin
      Temp := Slicing_Chars.To_Array(Item);
      for index in Temp'Range loop
         Ada.Text_IO.Put(Temp(index));
      end loop;
      Ada.Text_IO.New_Line;
   end Print_Chars;
   My_String : Slicing_Chars.Slicable_Array;
   Simple_String : Slicing_Chars.Element_Array(1..Length);
begin
   for index in 1..10 loop
      Simple_String(index) := character'Val(Character'Pos('a') + index);
   end loop;
   My_String := Slicing_Chars.Create(Simple_String);
   Print_Chars(My_String);
   for num in reverse 1..10 loop
      Slicing_Chars.Slice(Item => My_String, 
                          First => 1, Last => Num);
      Print_Chars(My_String);
   end loop;
end Slicing_Test;

Jim Rogers
Colorado Springs, Colorado USA



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

* Re: Arrays and Access types...
  2001-10-26  4:46 Arrays and Access types Eric G. Miller
                   ` (2 preceding siblings ...)
  2001-10-26 14:26 ` Ted Dennison
@ 2001-10-26 19:31 ` chris.danx
  2001-10-26 23:32 ` Jeffrey Carter
  2001-10-27  1:08 ` Eric G. Miller
  5 siblings, 0 replies; 12+ messages in thread
From: chris.danx @ 2001-10-26 19:31 UTC (permalink / raw)



"Eric G. Miller" <egm2@jps.net> wrote in message
news:20011025214647.2788a60b.egm2@jps.net...
>
> New to Ada and trying to figure out how to deal with arbitrary
> slices of arrays.  I defined an array type and an access type
> for it, but I can't seem to figure out how to take a slice of
> the array and assign that slice to an access type.
>
> Type is like:
>
> type My_Array is array (Positive range <>) of Integer;
> type My_Array_Ref is access My_Array;
>
> ... in body ...
>
> left, right, start : My_Array_Ref;
>
> begin
>     start := new My_Array (1 .. 200);
>     left  := start(start'first .. 100); -- that doesn't work!
> ...

[snip]

> If there's a way to do this with regular arrays (no access
> types), that'll work.  I wanted to minimize the number of
> "new" arrays -- I'm not quite comfortable with how/when to
> use Unconstrained_Deallocation yet...

Try this instead to begin with (it's easier)

-- stuff before types
...

-- unconstrained array type
--
type any_old_integer_array is array (positive range <>) of Integer;

-- array type with 200 elements;
--
subtype my_array is any_old_integer_array (1..200);


   start, left : my_array;

begin
   left(start'first..100) := start(start'first .. 100);

end blah_blah;

Slices of arrays need to be the same length, hence the need for the range
specified at both sides of the assignment.

> What I want to do is progressively subset the array, and I
> won't know exactly how it'll get broken up until runtime.  The
> original array will get divvied up into smaller and smaller
> slices of an earlier slice (the remaining can be discarded).

If I understand you correctly, you want to take slices of an array but you
don't know how large those slices will be, but you do know that no slice
will be bigger than the original array.

You can do that as long as the following is satisfied:

left(slice_range) := right(slice_range)

i.e. the range for the slice is the same on both sides.

Just use big enough arrays, and take smaller slices of them ensuring the
above rule.  Later you can use attributes that can help you deal with any
size array, as long as the passed array is a subtype of an unconstrained
array.  Attributes are especially useful for working with strings of
unspecified size.

for example you could define Put like this (if it were not already defined
for you)

procedure put (str : in string) is
begin
   for count in str'range loop
      put (str(count));
   end loop;
end put;


Hope this is helpful,
Chris.










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

* Re: Arrays and Access types...
  2001-10-26  4:46 Arrays and Access types Eric G. Miller
                   ` (3 preceding siblings ...)
  2001-10-26 19:31 ` chris.danx
@ 2001-10-26 23:32 ` Jeffrey Carter
  2001-10-27  1:08 ` Eric G. Miller
  5 siblings, 0 replies; 12+ messages in thread
From: Jeffrey Carter @ 2001-10-26 23:32 UTC (permalink / raw)


"Eric G. Miller" wrote:
> 
> New to Ada and trying to figure out how to deal with arbitrary
> slices of arrays.  I defined an array type and an access type
> for it, but I can't seem to figure out how to take a slice of
> the array and assign that slice to an access type.
> 
> Type is like:
> 
> type My_Array is array (Positive range <>) of Integer;
> type My_Array_Ref is access My_Array;
> 
> ... in body ...
> 
> left, right, start : My_Array_Ref;
> 
> begin
>     start := new My_Array (1 .. 200);
>     left  := start(start'first .. 100); -- that doesn't work!

I doubt that you really need access types/values at all. Since all the
other responses seem to be overkill, I would suggest something like

   Start : My_Array (1 .. 200);
   ...
begin
   declare 
      Left : [constant] My_Array := Start (Start'First .. 100);
   begin
      ...

-- 
Jeff Carter
"I wave my private parts at your aunties."
Monty Python & the Holy Grail



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

* Re: Arrays and Access types...
  2001-10-26  4:46 Arrays and Access types Eric G. Miller
                   ` (4 preceding siblings ...)
  2001-10-26 23:32 ` Jeffrey Carter
@ 2001-10-27  1:08 ` Eric G. Miller
  2001-10-27  2:09   ` DuckE
  5 siblings, 1 reply; 12+ messages in thread
From: Eric G. Miller @ 2001-10-27  1:08 UTC (permalink / raw)


Thanks all for your comments, suggestions.

For the curious, I was writing a problem that simulated a human solving
the following problem:

Question.  If you have 200 coins and 199 of them weigh the same amount
and 1 is lighter than the others. Using a two pan balancing scale, 
how can you identify the lighter coin in 5 weighings or less?

Don't get me started on how you could possibly have all of this
information a priori and *not* know which coin was lighter...



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

* Re: Arrays and Access types...
  2001-10-27  1:08 ` Eric G. Miller
@ 2001-10-27  2:09   ` DuckE
  2001-10-27  4:23     ` Steven Deller
  0 siblings, 1 reply; 12+ messages in thread
From: DuckE @ 2001-10-27  2:09 UTC (permalink / raw)


Cool!
I figured it out, but it was puzzling.
Thanks for the brain teaser.

SteveD


"Eric G. Miller" <egm2@jps-nospam.net> wrote in message
news:AHnC7.1323$655.42331@nntp3.onemain.com...
> Thanks all for your comments, suggestions.
>
> For the curious, I was writing a problem that simulated a human solving
> the following problem:
>
> Question.  If you have 200 coins and 199 of them weigh the same amount
> and 1 is lighter than the others. Using a two pan balancing scale,
> how can you identify the lighter coin in 5 weighings or less?
>
> Don't get me started on how you could possibly have all of this
> information a priori and *not* know which coin was lighter...





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

* RE: Arrays and Access types...
  2001-10-27  2:09   ` DuckE
@ 2001-10-27  4:23     ` Steven Deller
  2001-10-27 18:30       ` Eric G. Miller
  0 siblings, 1 reply; 12+ messages in thread
From: Steven Deller @ 2001-10-27  4:23 UTC (permalink / raw)
  To: comp.lang.ada

3**5 > 200 -- no problem to solve at all :-)

> -----Original Message-----
> From: comp.lang.ada-admin@ada.eu.org 
> [mailto:comp.lang.ada-admin@ada.eu.org] On Behalf Of DuckE
> Sent: Friday, October 26, 2001 10:10 PM
> To: comp.lang.ada@ada.eu.org
> Subject: Re: Arrays and Access types...
> 
> 
> Cool!
> I figured it out, but it was puzzling.
> Thanks for the brain teaser.
> 
> SteveD
> 
> 
> "Eric G. Miller" <egm2@jps-nospam.net> wrote in message 
news:AHnC7.1323$655.42331@nntp3.onemain.com...
> Thanks all for your comments, suggestions.
>
> For the curious, I was writing a problem that simulated a human 
> solving the following problem:
>
> Question.  If you have 200 coins and 199 of them weigh the same amount

> and 1 is lighter than the others. Using a two pan balancing scale, how

> can you identify the lighter coin in 5 weighings or less?
>
> Don't get me started on how you could possibly have all of this 
> information a priori and *not* know which coin was lighter...


_______________________________________________
comp.lang.ada mailing list
comp.lang.ada@ada.eu.org
http://ada.eu.org/mailman/listinfo/comp.lang.ada




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

* RE: Arrays and Access types...
  2001-10-27  4:23     ` Steven Deller
@ 2001-10-27 18:30       ` Eric G. Miller
  0 siblings, 0 replies; 12+ messages in thread
From: Eric G. Miller @ 2001-10-27 18:30 UTC (permalink / raw)


In <mailman.1004156869.28743.comp.lang.ada@ada.eu.org>, Steven Deller wrote:

> 3**5 > 200 -- no problem to solve at all :-)

Partial credit for an incomplete answer.  Coins are discrete objects.



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

end of thread, other threads:[~2001-10-27 18:30 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-10-26  4:46 Arrays and Access types Eric G. Miller
2001-10-26  5:39 ` James Rogers
2001-10-26  6:45   ` Eric G. Miller
2001-10-26 16:40     ` James Rogers
2001-10-26  6:14 ` tmoran
2001-10-26 14:26 ` Ted Dennison
2001-10-26 19:31 ` chris.danx
2001-10-26 23:32 ` Jeffrey Carter
2001-10-27  1:08 ` Eric G. Miller
2001-10-27  2:09   ` DuckE
2001-10-27  4:23     ` Steven Deller
2001-10-27 18:30       ` Eric G. Miller

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