3 -- Grant of Unlimited Rights
5 -- Under contracts F33600-87-D-0337, F33600-84-D-0280, MDA903-79-C-0687,
6 -- F08630-91-C-0015, and DCA100-97-D-0025, the U.S. Government obtained
7 -- unlimited rights in the software and documentation contained herein.
8 -- Unlimited rights are defined in DFAR 252.227-7013(a)(19). By making
9 -- this public release, the Government intends to confer upon all
10 -- recipients unlimited rights equal to those held by the Government.
11 -- These rights include rights to use, duplicate, release or disclose the
12 -- released technical data and computer software in whole or in part, in
13 -- any manner and for any purpose whatsoever, and to have or permit others
18 -- ALL MATERIALS OR INFORMATION HEREIN RELEASED, MADE AVAILABLE OR
19 -- DISCLOSED ARE AS IS. THE GOVERNMENT MAKES NO EXPRESS OR IMPLIED
20 -- WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING THE CONDITIONS OF THE
21 -- SOFTWARE, DOCUMENTATION OR OTHER INFORMATION RELEASED, MADE AVAILABLE
22 -- OR DISCLOSED, OR THE OWNERSHIP, MERCHANTABILITY, OR FITNESS FOR A
23 -- PARTICULAR PURPOSE OF SAID MATERIAL.
27 -- Check that, for both Float_Random and Discrete_Random packages,
28 -- the following are true:
29 -- 1) the procedures Save and Reset can be used to save the
30 -- specific state of a random number generator, and then restore
31 -- the specific state to the generator following some intermediate
32 -- generator activity.
33 -- 2) the Function Image can be used to obtain a string
34 -- representation of the state of a generator; and that the
35 -- Function Value will transform a string representation of the
36 -- state of a random number generator into the actual state object.
37 -- 3) a call to Function Value, with a string value that is
38 -- not the image of any generator state, is a bounded error. This
39 -- error either raises Constraint_Error or Program_Error, or is
40 -- accepted. (See Technical Corrigendum 1).
43 -- This test evaluates components of the Ada.Numerics.Float_Random and
44 -- Ada.Numerics.Discrete_Random packages.
45 -- The first objective block of this test uses Procedure Save to
46 -- save the particular state of a random number generator. The random
47 -- number generator then generates a series of random numbers. The
48 -- saved state variable is then used to reset (using Procedure Reset)
49 -- the generator back to the state it was in at the point of the call
50 -- to Save. Random values are then generated from this restored
51 -- generator, and compared with expected values.
52 -- The second objective block of this test uses Function Image to
53 -- provide a string representation of a state code. This string is
54 -- then transformed back to a state code value, and used to reset a
55 -- random number generator to the saved state. Random values are
56 -- likewise generated from this restored generator, and compared with
61 -- 25 Apr 95 SAIC Initial prerelease version.
62 -- 17 Jul 95 SAIC Incorporated reviewer comments.
63 -- 17 Dec 97 EDS Change subtype upper limit from 100_000 to 10_000.
64 -- 16 Sep 99 RLB Updated objective 3 for Technical Corrigendum 1
69 with Ada
.Numerics
.Float_Random
;
70 with Ada
.Numerics
.Discrete_Random
;
71 with Ada
.Strings
.Bounded
;
79 Report
.Test
("CXA5012", "Check the effect of Procedures Save and " &
80 "Reset, and Functions Image and Value " &
81 "from the Ada.Numerics.Discrete_Random " &
82 "and Float_Random packages");
87 use Ada
.Numerics
, Ada
.Strings
.Bounded
;
89 -- Declare an integer subtype and an enumeration subtype, and use them
90 -- to instantiate the discrete random number generator generic package.
92 subtype Discrete_Range
is Integer range 1..10_000
;
93 type Suit_Of_Cards
is (Ace
, One
, Two
, Three
, Four
, Five
, Six
,
94 Seven
, Eight
, Nine
, Ten
, Jack
, Queen
, King
);
95 package Discrete_Pack
is new Discrete_Random
(Discrete_Range
);
96 package Card_Pack
is new Discrete_Random
(Suit_Of_Cards
);
98 -- Declaration of random number generator objects.
100 DGen_1
, DGen_2
: Discrete_Pack
.Generator
;
101 EGen_1
, EGen_2
: Card_Pack
.Generator
;
102 FGen_1
, FGen_2
: Float_Random
.Generator
;
104 -- Variables declared to hold random numbers over the inclusive range
105 -- of their corresponding type.
107 DVal_1
, DVal_2
: Discrete_Range
;
108 EVal_1
, EVal_2
: Suit_Of_Cards
;
109 FVal_1
, FVal_2
: Float_Random
.Uniformly_Distributed
;
111 -- Declaration of State variables used to hold the state of the
112 -- random number generators.
114 DState_1
, DState_2
: Discrete_Pack
.State
;
115 EState_1
, EState_2
: Card_Pack
.State
;
116 FState_1
, FState_2
: Float_Random
.State
;
118 -- Declaration of bounded string packages instantiated with the
119 -- value of Max_Image_Width constant, and bounded string variables
120 -- used to hold the image of random number generator states.
122 package DString_Pack
is
123 new Generic_Bounded_Length
(Discrete_Pack
.Max_Image_Width
);
124 package EString_Pack
is
125 new Generic_Bounded_Length
(Card_Pack
.Max_Image_Width
);
126 package FString_Pack
is
127 new Generic_Bounded_Length
(Float_Random
.Max_Image_Width
);
129 use DString_Pack
, EString_Pack
, FString_Pack
;
131 DString_1
, DString_2
: DString_Pack
.Bounded_String
:=
132 DString_Pack
.Null_Bounded_String
;
133 EString_1
, EString_2
: EString_Pack
.Bounded_String
:=
134 EString_Pack
.Null_Bounded_String
;
135 FString_1
, FString_2
: FString_Pack
.Bounded_String
:=
136 FString_Pack
.Null_Bounded_String
;
141 TC_Discrete_Check_Failed
,
142 TC_Enum_Check_Failed
,
143 TC_Float_Check_Failed
: Boolean := False;
149 -- Check that the procedures Save and Reset can be used to save the
150 -- specific state of a random number generator, and then restore the
151 -- specific state to the generator following some intermediate
152 -- generator activity.
155 First_Row
: constant := 1;
156 Second_Row
: constant := 2;
157 TC_Max_Values
: constant := 100;
159 TC_Discrete_Array
: array (First_Row
..Second_Row
, 1..TC_Max_Values
)
161 TC_Enum_Array
: array (First_Row
..Second_Row
, 1..TC_Max_Values
)
163 TC_Float_Array
: array (First_Row
..Second_Row
, 1..TC_Max_Values
)
164 of Float_Random
.Uniformly_Distributed
;
167 -- The state of the random number generators are saved to state
168 -- variables using the procedure Save.
170 Discrete_Pack
.Save
(Gen
=> DGen_1
, To_State
=> DState_1
);
171 Card_Pack
.Save
(Gen
=> EGen_1
, To_State
=> EState_1
);
172 Float_Random
.Save
(Gen
=> FGen_1
, To_State
=> FState_1
);
174 -- Random number generators are used to fill the first half of the
175 -- first row of the arrays with randomly generated values.
177 for i
in 1..TC_Max_Values
/2 loop
178 TC_Discrete_Array
(First_Row
, i
) := Discrete_Pack
.Random
(DGen_1
);
179 TC_Enum_Array
(First_Row
, i
) := Card_Pack
.Random
(EGen_1
);
180 TC_Float_Array
(First_Row
, i
) := Float_Random
.Random
(FGen_1
);
183 -- The random number generators are reset to the states saved in the
184 -- state variables, using the procedure Reset.
186 Discrete_Pack
.Reset
(Gen
=> DGen_1
, From_State
=> DState_1
);
187 Card_Pack
.Reset
(Gen
=> EGen_1
, From_State
=> EState_1
);
188 Float_Random
.Reset
(Gen
=> FGen_1
, From_State
=> FState_1
);
190 -- The same random number generators are used to fill the first half
191 -- of the second row of the arrays with randomly generated values.
193 for i
in 1..TC_Max_Values
/2 loop
194 TC_Discrete_Array
(Second_Row
, i
) := Discrete_Pack
.Random
(DGen_1
);
195 TC_Enum_Array
(Second_Row
, i
) := Card_Pack
.Random
(EGen_1
);
196 TC_Float_Array
(Second_Row
, i
) := Float_Random
.Random
(FGen_1
);
199 -- Run the random number generators many times (not using results).
201 for i
in Discrete_Range
'Range loop
202 DVal_1
:= Discrete_Pack
.Random
(DGen_1
);
203 EVal_1
:= Card_Pack
.Random
(EGen_1
);
204 FVal_1
:= Float_Random
.Random
(FGen_1
);
207 -- The states of the random number generators are saved to state
208 -- variables using the procedure Save.
210 Discrete_Pack
.Save
(Gen
=> DGen_1
, To_State
=> DState_1
);
211 Card_Pack
.Save
(Gen
=> EGen_1
, To_State
=> EState_1
);
212 Float_Random
.Save
(Gen
=> FGen_1
, To_State
=> FState_1
);
214 -- The last half of the first row of the arrays are filled with
215 -- values generated from the same random number generators.
217 for i
in (TC_Max_Values
/2 + 1)..TC_Max_Values
loop
218 TC_Discrete_Array
(First_Row
, i
) := Discrete_Pack
.Random
(DGen_1
);
219 TC_Enum_Array
(First_Row
, i
) := Card_Pack
.Random
(EGen_1
);
220 TC_Float_Array
(First_Row
, i
) := Float_Random
.Random
(FGen_1
);
223 -- The random number generators are reset to the states saved in the
224 -- state variables, using the procedure Reset.
226 Discrete_Pack
.Reset
(Gen
=> DGen_1
, From_State
=> DState_1
);
227 Card_Pack
.Reset
(Gen
=> EGen_1
, From_State
=> EState_1
);
228 Float_Random
.Reset
(Gen
=> FGen_1
, From_State
=> FState_1
);
230 -- The last half of the second row of the arrays are filled with
231 -- values generated from the same random number generator.
232 -- These values should exactly mirror the values in the last half
233 -- of the first row of the arrays that had been previously generated.
235 for i
in (TC_Max_Values
/2 + 1)..TC_Max_Values
loop
236 TC_Discrete_Array
(Second_Row
, i
) := Discrete_Pack
.Random
(DGen_1
);
237 TC_Enum_Array
(Second_Row
, i
) := Card_Pack
.Random
(EGen_1
);
238 TC_Float_Array
(Second_Row
, i
) := Float_Random
.Random
(FGen_1
);
241 -- Check that the values in the two rows of the arrays are identical.
243 for i
in 1..TC_Max_Values
loop
244 if TC_Discrete_Array
(First_Row
,i
) /=
245 TC_Discrete_Array
(Second_Row
,i
)
247 TC_Discrete_Check_Failed
:= True;
252 for i
in 1..TC_Max_Values
loop
253 if TC_Enum_Array
(First_Row
,i
) /= TC_Enum_Array
(Second_Row
,i
) then
254 TC_Enum_Check_Failed
:= True;
259 for i
in 1..TC_Max_Values
loop
260 if TC_Float_Array
(First_Row
,i
) /= TC_Float_Array
(Second_Row
,i
)
262 TC_Float_Check_Failed
:= True;
267 if TC_Discrete_Check_Failed
then
268 Report
.Failed
("Discrete random values generated following use " &
269 "of procedures Save and Reset were not the same");
270 TC_Discrete_Check_Failed
:= False;
273 if TC_Enum_Check_Failed
then
274 Report
.Failed
("Enumeration random values generated following " &
275 "use of procedures Save and Reset were not the " &
277 TC_Enum_Check_Failed
:= False;
280 if TC_Float_Check_Failed
then
281 Report
.Failed
("Float random values generated following use " &
282 "of procedures Save and Reset were not the same");
283 TC_Float_Check_Failed
:= False;
291 -- Check that the Function Image can be used to obtain a string
292 -- representation of the state of a generator.
293 -- Check that the Function Value will transform a string
294 -- representation of the state of a random number generator
295 -- into the actual state object.
298 -- Use two discrete and float random number generators to generate
299 -- a series of values (so that the generators are no longer in their
300 -- initial states, and they have generated the same number of
303 TC_Seed
:= Integer(Discrete_Pack
.Random
(DGen_1
));
304 Discrete_Pack
.Reset
(DGen_1
, TC_Seed
);
305 Discrete_Pack
.Reset
(DGen_2
, TC_Seed
);
306 Card_Pack
.Reset
(EGen_1
, TC_Seed
);
307 Card_Pack
.Reset
(EGen_2
, TC_Seed
);
308 Float_Random
.Reset
(FGen_1
, TC_Seed
);
309 Float_Random
.Reset
(FGen_2
, TC_Seed
);
311 for i
in 1..1000 loop
312 DVal_1
:= Discrete_Pack
.Random
(DGen_1
);
313 DVal_2
:= Discrete_Pack
.Random
(DGen_2
);
314 EVal_1
:= Card_Pack
.Random
(EGen_1
);
315 EVal_2
:= Card_Pack
.Random
(EGen_2
);
316 FVal_1
:= Float_Random
.Random
(FGen_1
);
317 FVal_2
:= Float_Random
.Random
(FGen_2
);
320 -- Use the Procedure Save to save the states of the generators
321 -- to state variables.
323 Discrete_Pack
.Save
(Gen
=> DGen_1
, To_State
=> DState_1
);
324 Discrete_Pack
.Save
(DGen_2
, To_State
=> DState_2
);
325 Card_Pack
.Save
(Gen
=> EGen_1
, To_State
=> EState_1
);
326 Card_Pack
.Save
(EGen_2
, To_State
=> EState_2
);
327 Float_Random
.Save
(FGen_1
, To_State
=> FState_1
);
328 Float_Random
.Save
(FGen_2
, FState_2
);
330 -- Use the Function Image to produce a representation of the state
331 -- codes as (bounded) string objects.
333 DString_1
:= DString_Pack
.To_Bounded_String
(
334 Discrete_Pack
.Image
(Of_State
=> DState_1
));
335 DString_2
:= DString_Pack
.To_Bounded_String
(
336 Discrete_Pack
.Image
(DState_2
));
337 EString_1
:= EString_Pack
.To_Bounded_String
(
338 Card_Pack
.Image
(Of_State
=> EState_1
));
339 EString_2
:= EString_Pack
.To_Bounded_String
(
340 Card_Pack
.Image
(EState_2
));
341 FString_1
:= FString_Pack
.To_Bounded_String
(
342 Float_Random
.Image
(Of_State
=> FState_1
));
343 FString_2
:= FString_Pack
.To_Bounded_String
(
344 Float_Random
.Image
(FState_2
));
346 -- Compare the bounded string objects for equality.
348 if DString_1
/= DString_2
then
349 Report
.Failed
("String values returned from Function Image " &
350 "depict different states of Discrete generators");
352 if EString_1
/= EString_2
then
353 Report
.Failed
("String values returned from Function Image " &
354 "depict different states of Enumeration " &
357 if FString_1
/= FString_2
then
358 Report
.Failed
("String values returned from Function Image " &
359 "depict different states of Float generators");
362 -- The string representation of a state code is transformed back
363 -- to a state code variable using the Function Value.
365 DState_1
:= Discrete_Pack
.Value
(Coded_State
=>
366 DString_Pack
.To_String
(DString_1
));
367 EState_1
:= Card_Pack
.Value
(EString_Pack
.To_String
(EString_1
));
368 FState_1
:= Float_Random
.Value
(FString_Pack
.To_String
(FString_1
));
370 -- One of the (pair of each type of ) generators is used to generate
371 -- a series of random values, getting them "out of synch" with the
372 -- specific generation sequence of the other generators.
375 DVal_1
:= Discrete_Pack
.Random
(DGen_1
);
376 EVal_1
:= Card_Pack
.Random
(EGen_1
);
377 FVal_1
:= Float_Random
.Random
(FGen_1
);
380 -- The "out of synch" generators are reset to the previous state they
381 -- had when their states were saved, and they should now have the same
382 -- states as the generators that did not generate the values above.
384 Discrete_Pack
.Reset
(Gen
=> DGen_1
, From_State
=> DState_1
);
385 Card_Pack
.Reset
(Gen
=> EGen_1
, From_State
=> EState_1
);
386 Float_Random
.Reset
(Gen
=> FGen_1
, From_State
=> FState_1
);
388 -- All generators should now be in the same state, so the
389 -- random values they produce should be the same.
391 for i
in 1..1000 loop
392 if Discrete_Pack
.Random
(DGen_1
) /= Discrete_Pack
.Random
(DGen_2
)
394 TC_Discrete_Check_Failed
:= True;
399 for i
in 1..1000 loop
400 if Card_Pack
.Random
(EGen_1
) /= Card_Pack
.Random
(EGen_2
) then
401 TC_Enum_Check_Failed
:= True;
406 for i
in 1..1000 loop
407 if Float_Random
.Random
(FGen_1
) /= Float_Random
.Random
(FGen_2
)
409 TC_Float_Check_Failed
:= True;
414 if TC_Discrete_Check_Failed
then
415 Report
.Failed
("Random values generated following use of " &
416 "procedures Image and Value were not the same " &
417 "for Discrete generator");
419 if TC_Enum_Check_Failed
then
420 Report
.Failed
("Random values generated following use of " &
421 "procedures Image and Value were not the same " &
422 "for Enumeration generator");
424 if TC_Float_Check_Failed
then
425 Report
.Failed
("Random values generated following use of " &
426 "procedures Image and Value were not the same " &
427 "for Float generator");
435 -- Check that a call to Function Value, with a string value that is
436 -- not the image of any generator state, is a bounded error. This
437 -- error either raises Constraint_Error or Program_Error, or is
438 -- accepted. (See Technical Corrigendum 1).
440 Not_A_State
: constant String := ImpDef
.Non_State_String
;
444 DState_1
:= Discrete_Pack
.Value
(Not_A_State
);
445 if Not_A_State
/= "**NONE**" then
446 Report
.Failed
("Exception not raised by Function " &
447 "Ada.Numerics.Discrete_Random.Value when " &
448 "provided a string input that does not " &
449 "represent the state of a random number " &
452 Report
.Comment
("All strings represent states for Function " &
453 "Ada.Numerics.Discrete_Random.Value");
455 Discrete_Pack
.Reset
(DGen_1
, DState_1
);
457 when Constraint_Error
=> null; -- OK, expected exception.
458 Report
.Comment
("Constraint_Error raised by Function " &
459 "Ada.Numerics.Discrete_Random.Value when " &
460 "provided a string input that does not " &
461 "represent the state of a random number " &
463 when Program_Error
=> -- OK, expected exception.
464 Report
.Comment
("Program_Error raised by Function " &
465 "Ada.Numerics.Discrete_Random.Value when " &
466 "provided a string input that does not " &
467 "represent the state of a random number " &
470 Report
.Failed
("Unexpected exception raised by Function " &
471 "Ada.Numerics.Discrete_Random.Value when " &
472 "provided a string input that does not " &
473 "represent the state of a random number " &
478 EState_1
:= Card_Pack
.Value
(Not_A_State
);
479 if Not_A_State
/= "**NONE**" then
480 Report
.Failed
("Exception not raised by Function " &
481 "Ada.Numerics.Discrete_Random.Value when " &
482 "provided a string input that does not " &
483 "represent the state of an enumeration " &
484 "random number generator");
486 Report
.Comment
("All strings represent states for Function " &
487 "Ada.Numerics.Discrete_Random.Value");
489 Card_Pack
.Reset
(EGen_1
, EState_1
);
491 when Constraint_Error
=> null; -- OK, expected exception.
492 when Program_Error
=> null; -- OK, expected exception.
494 Report
.Failed
("Unexpected exception raised by Function " &
495 "Ada.Numerics.Discrete_Random.Value when " &
496 "provided a string input that does not " &
497 "represent the state of an enumeration " &
498 "random number generator");
502 FState_1
:= Float_Random
.Value
(Not_A_State
);
503 if Not_A_State
/= "**NONE**" then
504 Report
.Failed
("Exception not raised by an " &
505 "instantiated version of " &
506 "Ada.Numerics.Float_Random.Value when " &
507 "provided a string input that does not " &
508 "represent the state of a random number " &
511 Report
.Comment
("All strings represent states for Function " &
512 "Ada.Numerics.Float_Random.Value");
514 Float_Random
.Reset
(FGen_1
, FState_1
);
516 when Constraint_Error
=> null; -- OK, expected exception.
517 when Program_Error
=> null; -- OK, expected exception.
519 Report
.Failed
("Unexpected exception raised by an " &
520 "instantiated version of " &
521 "Ada.Numerics.Float_Random.Value when " &
522 "provided a string input that does not " &
523 "represent the state of a random number " &
531 when others => Report
.Failed
("Exception raised in Test_Block");