view gcc/testsuite/ada/acats/tests/cxa/cxa5012.a @ 111:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents
children
line wrap: on
line source

-- CXA5012.A
--
--                             Grant of Unlimited Rights
--
--     Under contracts F33600-87-D-0337, F33600-84-D-0280, MDA903-79-C-0687,
--     F08630-91-C-0015, and DCA100-97-D-0025, the U.S. Government obtained
--     unlimited rights in the software and documentation contained herein.
--     Unlimited rights are defined in DFAR 252.227-7013(a)(19).  By making
--     this public release, the Government intends to confer upon all
--     recipients unlimited rights  equal to those held by the Government.
--     These rights include rights to use, duplicate, release or disclose the
--     released technical data and computer software in whole or in part, in
--     any manner and for any purpose whatsoever, and to have or permit others
--     to do so.
--
--                                    DISCLAIMER
--
--     ALL MATERIALS OR INFORMATION HEREIN RELEASED, MADE AVAILABLE OR
--     DISCLOSED ARE AS IS.  THE GOVERNMENT MAKES NO EXPRESS OR IMPLIED
--     WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING THE CONDITIONS OF THE
--     SOFTWARE, DOCUMENTATION OR OTHER INFORMATION RELEASED, MADE AVAILABLE
--     OR DISCLOSED, OR THE OWNERSHIP, MERCHANTABILITY, OR FITNESS FOR A
--     PARTICULAR PURPOSE OF SAID MATERIAL.
--*
--
-- OBJECTIVE:
--      Check that, for both Float_Random and Discrete_Random packages,
--      the following are true:
--      1) the procedures Save and Reset can be used to save the
--         specific state of a random number generator, and then restore
--         the specific state to the generator following some intermediate
--         generator activity.
--      2) the Function Image can be used to obtain a string
--         representation of the state of a generator; and that the
--         Function Value will transform a string representation of the
--         state of a random number generator into the actual state object.
--      3) a call to Function Value, with a string value that is
--         not the image of any generator state, is a bounded error. This
--         error either raises Constraint_Error or Program_Error, or is
--         accepted. (See Technical Corrigendum 1).
--
-- TEST DESCRIPTION:
--      This test evaluates components of the Ada.Numerics.Float_Random and
--      Ada.Numerics.Discrete_Random packages.
--      The first objective block of this test uses Procedure Save to
--      save the particular state of a random number generator.  The random
--      number generator then generates a series of random numbers.  The
--      saved state variable is then used to reset (using Procedure Reset)
--      the generator back to the state it was in at the point of the call
--      to Save.  Random values are then generated from this restored
--      generator, and compared with expected values.
--      The second objective block of this test uses Function Image to
--      provide a string representation of a state code.  This string is
--      then transformed back to a state code value, and used to reset a
--      random number generator to the saved state.  Random values are
--      likewise generated from this restored generator, and compared with
--      expected values.
--
--
-- CHANGE HISTORY:
--      25 Apr 95   SAIC    Initial prerelease version.
--      17 Jul 95   SAIC    Incorporated reviewer comments.
--      17 Dec 97   EDS     Change subtype upper limit from 100_000 to 10_000.
--      16 Sep 99   RLB     Updated objective 3 for Technical Corrigendum 1
--                          changes.

--!

with Ada.Numerics.Float_Random;
with Ada.Numerics.Discrete_Random;
with Ada.Strings.Bounded;
with ImpDef;
with Report;

procedure CXA5012 is

begin

   Report.Test ("CXA5012", "Check the effect of Procedures Save and " &
                           "Reset, and Functions Image and Value "    &
                           "from the Ada.Numerics.Discrete_Random "   &
                           "and Float_Random packages");

   Test_Block:
   declare

      use Ada.Numerics, Ada.Strings.Bounded;

      -- Declare an integer subtype and an enumeration subtype, and use them
      -- to instantiate the discrete random number generator generic package.

      subtype Discrete_Range is Integer range 1..10_000;
      type    Suit_Of_Cards  is (Ace, One, Two, Three, Four, Five, Six,
                                 Seven, Eight, Nine, Ten, Jack, Queen, King);
      package Discrete_Pack is new Discrete_Random(Discrete_Range);
      package Card_Pack     is new Discrete_Random(Suit_Of_Cards);

      -- Declaration of random number generator objects.

      DGen_1, DGen_2 : Discrete_Pack.Generator;
      EGen_1, EGen_2 : Card_Pack.Generator;
      FGen_1, FGen_2 : Float_Random.Generator;

      -- Variables declared to hold random numbers over the inclusive range
      -- of their corresponding type.

      DVal_1, DVal_2 : Discrete_Range;
      EVal_1, EVal_2 : Suit_Of_Cards;
      FVal_1, FVal_2 : Float_Random.Uniformly_Distributed;

      -- Declaration of State variables used to hold the state of the
      -- random number generators.

      DState_1, DState_2 : Discrete_Pack.State;
      EState_1, EState_2 : Card_Pack.State;
      FState_1, FState_2 : Float_Random.State;

      -- Declaration of bounded string packages instantiated with the
      -- value of Max_Image_Width constant, and bounded string variables
      -- used to hold the image of random number generator states.

      package DString_Pack is
        new Generic_Bounded_Length(Discrete_Pack.Max_Image_Width);
      package EString_Pack is
        new Generic_Bounded_Length(Card_Pack.Max_Image_Width);
      package FString_Pack is
        new Generic_Bounded_Length(Float_Random.Max_Image_Width);

      use DString_Pack, EString_Pack, FString_Pack;

      DString_1, DString_2 : DString_Pack.Bounded_String :=
                               DString_Pack.Null_Bounded_String;
      EString_1, EString_2 : EString_Pack.Bounded_String :=
                               EString_Pack.Null_Bounded_String;
      FString_1, FString_2 : FString_Pack.Bounded_String :=
                               FString_Pack.Null_Bounded_String;

      -- Test variables.

      TC_Count                  : Natural;
      TC_Discrete_Check_Failed,
      TC_Enum_Check_Failed,
      TC_Float_Check_Failed     : Boolean := False;
      TC_Seed                   : Integer;

   begin

      Objective_1:
         -- Check that the procedures Save and Reset can be used to save the
         -- specific state of a random number generator, and then restore the
         -- specific state to the generator following some intermediate
         -- generator activity.
      declare

         First_Row     : constant :=   1;
         Second_Row    : constant :=   2;
         TC_Max_Values : constant := 100;

         TC_Discrete_Array : array (First_Row..Second_Row, 1..TC_Max_Values)
                               of Discrete_Range;
         TC_Enum_Array     : array (First_Row..Second_Row, 1..TC_Max_Values)
                               of Suit_Of_Cards;
         TC_Float_Array    : array (First_Row..Second_Row, 1..TC_Max_Values)
                               of Float_Random.Uniformly_Distributed;
      begin

         -- The state of the random number generators are saved to state
         -- variables using the procedure Save.

         Discrete_Pack.Save(Gen => DGen_1, To_State => DState_1);
         Card_Pack.Save    (Gen => EGen_1, To_State => EState_1);
         Float_Random.Save (Gen => FGen_1, To_State => FState_1);

         -- Random number generators are used to fill the first half of the
         -- first row of the arrays with randomly generated values.

         for i in 1..TC_Max_Values/2 loop
            TC_Discrete_Array(First_Row, i) := Discrete_Pack.Random(DGen_1);
            TC_Enum_Array(First_Row, i)     := Card_Pack.Random(EGen_1);
            TC_Float_Array(First_Row, i)    := Float_Random.Random(FGen_1);
         end loop;

         -- The random number generators are reset to the states saved in the
         -- state variables, using the procedure Reset.

         Discrete_Pack.Reset(Gen => DGen_1, From_State => DState_1);
         Card_Pack.Reset    (Gen => EGen_1, From_State => EState_1);
         Float_Random.Reset (Gen => FGen_1, From_State => FState_1);

         -- The same random number generators are used to fill the first half
         -- of the second row of the arrays with randomly generated values.

         for i in 1..TC_Max_Values/2 loop
            TC_Discrete_Array(Second_Row, i) := Discrete_Pack.Random(DGen_1);
            TC_Enum_Array(Second_Row, i)     := Card_Pack.Random(EGen_1);
            TC_Float_Array(Second_Row, i)    := Float_Random.Random(FGen_1);
         end loop;

         -- Run the random number generators many times (not using results).

         for i in Discrete_Range'Range loop
             DVal_1 := Discrete_Pack.Random(DGen_1);
             EVal_1 := Card_Pack.Random(EGen_1);
             FVal_1 := Float_Random.Random(FGen_1);
         end loop;

         -- The states of the random number generators are saved to state
         -- variables using the procedure Save.

         Discrete_Pack.Save(Gen => DGen_1, To_State => DState_1);
         Card_Pack.Save(Gen => EGen_1, To_State => EState_1);
         Float_Random.Save (Gen => FGen_1, To_State => FState_1);

         -- The last half of the first row of the arrays are filled with
         -- values generated from the same random number generators.

         for i in (TC_Max_Values/2 + 1)..TC_Max_Values loop
            TC_Discrete_Array(First_Row, i) := Discrete_Pack.Random(DGen_1);
            TC_Enum_Array(First_Row, i)     := Card_Pack.Random(EGen_1);
            TC_Float_Array(First_Row, i)    := Float_Random.Random(FGen_1);
         end loop;

         -- The random number generators are reset to the states saved in the
         -- state variables, using the procedure Reset.

         Discrete_Pack.Reset(Gen => DGen_1, From_State => DState_1);
         Card_Pack.Reset(Gen => EGen_1, From_State => EState_1);
         Float_Random.Reset (Gen => FGen_1, From_State => FState_1);

         -- The last half of the second row of the arrays are filled with
         -- values generated from the same random number generator.
         -- These values should exactly mirror the values in the last half
         -- of the first row of the arrays that had been previously generated.

         for i in (TC_Max_Values/2 + 1)..TC_Max_Values loop
            TC_Discrete_Array(Second_Row, i) := Discrete_Pack.Random(DGen_1);
            TC_Enum_Array(Second_Row, i)     := Card_Pack.Random(EGen_1);
            TC_Float_Array(Second_Row, i)    := Float_Random.Random(FGen_1);
         end loop;

         -- Check that the values in the two rows of the arrays are identical.

         for i in 1..TC_Max_Values loop
            if TC_Discrete_Array(First_Row,i) /=
               TC_Discrete_Array(Second_Row,i)
            then
               TC_Discrete_Check_Failed := True;
               exit;
            end if;
         end loop;

         for i in 1..TC_Max_Values loop
            if TC_Enum_Array(First_Row,i) /= TC_Enum_Array(Second_Row,i) then
               TC_Enum_Check_Failed := True;
               exit;
            end if;
         end loop;

         for i in 1..TC_Max_Values loop
            if TC_Float_Array(First_Row,i) /= TC_Float_Array(Second_Row,i)
            then
               TC_Float_Check_Failed := True;
               exit;
            end if;
         end loop;

         if TC_Discrete_Check_Failed then
            Report.Failed("Discrete random values generated following use " &
                          "of procedures Save and Reset were not the same");
            TC_Discrete_Check_Failed := False;
         end if;

         if TC_Enum_Check_Failed then
            Report.Failed("Enumeration random values generated following " &
                          "use of procedures Save and Reset were not the " &
                          "same");
            TC_Enum_Check_Failed := False;
         end if;

         if TC_Float_Check_Failed then
            Report.Failed("Float random values generated following use " &
                          "of procedures Save and Reset were not the same");
            TC_Float_Check_Failed := False;
         end if;

      end Objective_1;



      Objective_2:
         -- Check that the Function Image can be used to obtain a string
         -- representation of the state of a generator.
         -- Check that the Function Value will transform a string
         -- representation of the state of a random number generator
         -- into the actual state object.
      begin

         -- Use two discrete and float random number generators to generate
         -- a series of values (so that the generators are no longer in their
         -- initial states, and they have generated the same number of
         -- random values).

         TC_Seed := Integer(Discrete_Pack.Random(DGen_1));
         Discrete_Pack.Reset(DGen_1, TC_Seed);
         Discrete_Pack.Reset(DGen_2, TC_Seed);
         Card_Pack.Reset    (EGen_1, TC_Seed);
         Card_Pack.Reset    (EGen_2, TC_Seed);
         Float_Random.Reset (FGen_1,  TC_Seed);
         Float_Random.Reset (FGen_2,  TC_Seed);

         for i in 1..1000 loop
            DVal_1 := Discrete_Pack.Random(DGen_1);
            DVal_2 := Discrete_Pack.Random(DGen_2);
            EVal_1 := Card_Pack.Random(EGen_1);
            EVal_2 := Card_Pack.Random(EGen_2);
            FVal_1 := Float_Random.Random(FGen_1);
            FVal_2 := Float_Random.Random(FGen_2);
         end loop;

         -- Use the Procedure Save to save the states of the generators
         -- to state variables.

         Discrete_Pack.Save(Gen => DGen_1, To_State => DState_1);
         Discrete_Pack.Save(DGen_2, To_State => DState_2);
         Card_Pack.Save    (Gen => EGen_1, To_State => EState_1);
         Card_Pack.Save    (EGen_2, To_State => EState_2);
         Float_Random.Save (FGen_1, To_State => FState_1);
         Float_Random.Save (FGen_2, FState_2);

         -- Use the Function Image to produce a representation of the state
         -- codes as (bounded) string objects.

         DString_1 := DString_Pack.To_Bounded_String(
                        Discrete_Pack.Image(Of_State => DState_1));
         DString_2 := DString_Pack.To_Bounded_String(
                        Discrete_Pack.Image(DState_2));
         EString_1 := EString_Pack.To_Bounded_String(
                        Card_Pack.Image(Of_State => EState_1));
         EString_2 := EString_Pack.To_Bounded_String(
                        Card_Pack.Image(EState_2));
         FString_1 := FString_Pack.To_Bounded_String(
                        Float_Random.Image(Of_State => FState_1));
         FString_2 := FString_Pack.To_Bounded_String(
                        Float_Random.Image(FState_2));

         -- Compare the bounded string objects for equality.

         if DString_1 /= DString_2 then
            Report.Failed("String values returned from Function Image " &
                          "depict different states of Discrete generators");
         end if;
         if EString_1 /= EString_2 then
            Report.Failed("String values returned from Function Image " &
                          "depict different states of Enumeration "     &
                          "generators");
         end if;
         if FString_1 /= FString_2 then
            Report.Failed("String values returned from Function Image " &
                          "depict different states of Float generators");
         end if;

         -- The string representation of a state code is transformed back
         -- to a state code variable using the Function Value.

         DState_1 := Discrete_Pack.Value(Coded_State =>
                                          DString_Pack.To_String(DString_1));
         EState_1 := Card_Pack.Value(EString_Pack.To_String(EString_1));
         FState_1 := Float_Random.Value(FString_Pack.To_String(FString_1));

         -- One of the (pair of each type of ) generators is used to generate
         -- a series of random values, getting them "out of synch" with the
         -- specific generation sequence of the other generators.

         for i in 1..100 loop
            DVal_1 := Discrete_Pack.Random(DGen_1);
            EVal_1 := Card_Pack.Random(EGen_1);
            FVal_1 := Float_Random.Random (FGen_1);
         end loop;

         -- The "out of synch" generators are reset to the previous state they
         -- had when their states were saved, and they should now have the same
         -- states as the generators that did not generate the values above.

         Discrete_Pack.Reset(Gen => DGen_1, From_State => DState_1);
         Card_Pack.Reset    (Gen => EGen_1, From_State => EState_1);
         Float_Random.Reset (Gen => FGen_1, From_State => FState_1);

         -- All generators should now be in the same state, so the
         -- random values they produce should be the same.

         for i in 1..1000 loop
            if Discrete_Pack.Random(DGen_1) /= Discrete_Pack.Random(DGen_2)
            then
               TC_Discrete_Check_Failed := True;
               exit;
            end if;
         end loop;

         for i in 1..1000 loop
            if Card_Pack.Random(EGen_1) /= Card_Pack.Random(EGen_2) then
               TC_Enum_Check_Failed := True;
               exit;
            end if;
         end loop;

         for i in 1..1000 loop
            if Float_Random.Random(FGen_1) /= Float_Random.Random(FGen_2)
            then
               TC_Float_Check_Failed := True;
               exit;
            end if;
         end loop;

         if TC_Discrete_Check_Failed then
            Report.Failed("Random values generated following use of "     &
                          "procedures Image and Value were not the same " &
                          "for Discrete generator");
         end if;
         if TC_Enum_Check_Failed then
            Report.Failed("Random values generated following use of "     &
                          "procedures Image and Value were not the same " &
                          "for Enumeration generator");
         end if;
         if TC_Float_Check_Failed then
            Report.Failed("Random values generated following use of "     &
                          "procedures Image and Value were not the same " &
                          "for Float generator");
         end if;

      end Objective_2;



      Objective_3:
         -- Check that a call to Function Value, with a string value that is
         -- not the image of any generator state, is a bounded error. This
         -- error either raises Constraint_Error or Program_Error, or is
         -- accepted. (See Technical Corrigendum 1).
      declare
         Not_A_State : constant String := ImpDef.Non_State_String;
      begin

         begin
            DState_1 := Discrete_Pack.Value(Not_A_State);
            if Not_A_State /= "**NONE**" then
               Report.Failed("Exception not raised by Function " &
                             "Ada.Numerics.Discrete_Random.Value when " &
                             "provided a string input that does not "   &
                             "represent the state of a random number "  &
                             "generator");
            else
               Report.Comment("All strings represent states for Function " &
                             "Ada.Numerics.Discrete_Random.Value");
            end if;
            Discrete_Pack.Reset(DGen_1, DState_1);
         exception
            when Constraint_Error => null;  -- OK, expected exception.
               Report.Comment("Constraint_Error raised by Function " &
                             "Ada.Numerics.Discrete_Random.Value when " &
                             "provided a string input that does not "   &
                             "represent the state of a random number "  &
                             "generator");
            when Program_Error => -- OK, expected exception.
               Report.Comment("Program_Error raised by Function " &
                             "Ada.Numerics.Discrete_Random.Value when " &
                             "provided a string input that does not "   &
                             "represent the state of a random number "  &
                             "generator");
            when others =>
               Report.Failed("Unexpected exception raised by Function " &
                             "Ada.Numerics.Discrete_Random.Value when " &
                             "provided a string input that does not "   &
                             "represent the state of a random number "  &
                             "generator");
         end;

         begin
            EState_1 := Card_Pack.Value(Not_A_State);
            if Not_A_State /= "**NONE**" then
               Report.Failed("Exception not raised by Function " &
                             "Ada.Numerics.Discrete_Random.Value when " &
                             "provided a string input that does not "   &
                             "represent the state of an enumeration "   &
                             "random number generator");
            else
               Report.Comment("All strings represent states for Function " &
                             "Ada.Numerics.Discrete_Random.Value");
            end if;
            Card_Pack.Reset(EGen_1, EState_1);
         exception
            when Constraint_Error => null;  -- OK, expected exception.
            when Program_Error => null; -- OK, expected exception.
            when others =>
               Report.Failed("Unexpected exception raised by Function " &
                             "Ada.Numerics.Discrete_Random.Value when " &
                             "provided a string input that does not "   &
                             "represent the state of an enumeration "   &
                             "random number generator");
         end;

         begin
            FState_1 := Float_Random.Value(Not_A_State);
            if Not_A_State /= "**NONE**" then
               Report.Failed("Exception not raised by an "      &
                             "instantiated version of "                &
                             "Ada.Numerics.Float_Random.Value when "   &
                             "provided a string input that does not "  &
                             "represent the state of a random number " &
                             "generator");
            else
               Report.Comment("All strings represent states for Function " &
                             "Ada.Numerics.Float_Random.Value");
            end if;
            Float_Random.Reset(FGen_1, FState_1);
         exception
            when Constraint_Error => null;  -- OK, expected exception.
            when Program_Error => null; -- OK, expected exception.
            when others =>
               Report.Failed("Unexpected exception raised by an "      &
                             "instantiated version of "                &
                             "Ada.Numerics.Float_Random.Value when "   &
                             "provided a string input that does not "  &
                             "represent the state of a random number " &
                             "generator");
         end;

      end Objective_3;


   exception
      when others => Report.Failed ("Exception raised in Test_Block");
   end Test_Block;

   Report.Result;

end CXA5012;