1-- CXA5011.A 2-- 3-- Grant of Unlimited Rights 4-- 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 14-- to do so. 15-- 16-- DISCLAIMER 17-- 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. 24--* 25-- 26-- OBJECTIVE: 27-- Check that, for both Float_Random and Discrete_Random packages, 28-- the following are true: 29-- 1) two objects of type Generator are initialized to the same state. 30-- 2) when the Function Reset is used to reset two generators 31-- to different time-dependent states, the resulting random values 32-- from each generator are different. 33-- 3) when the Function Reset uses the same integer initiator 34-- to reset two generators to the same state, the resulting random 35-- values from each generator are identical. 36-- 4) when the Function Reset uses different integer initiator 37-- values to reset two generators, the resulting random numbers are 38-- different. 39-- 40-- TEST DESCRIPTION: 41-- This test evaluates components of the Ada.Numerics.Float_Random and 42-- Ada.Numerics.Discrete_Random packages. 43-- This test checks to see that objects of type Generator are initialized 44-- to the same state. In addition, the functionality of Function Reset is 45-- validated. 46-- For each of the objectives above, evaluation of the various generators 47-- is performed using each of the following techniques. When the states of 48-- two generators are to be compared, each state is saved, then 49-- transformed to a bounded-string variable. The bounded-strings can 50-- then be compared for equality. In this case, matching bounded-strings 51-- are evidence that the states of two generators are the same. 52-- In addition, two generators are compared by evaluating a series of 53-- random numbers they produce. A matching series of random numbers 54-- implies that the generators were in the same state prior to producing 55-- the numbers. 56-- 57-- 58-- CHANGE HISTORY: 59-- 20 Apr 95 SAIC Initial prerelease version. 60-- 07 Jul 95 SAIC Incorporated reviewer comments/suggestions. 61-- 22 Apr 96 SAIC Incorporated reviewer comments for ACVC 2.1. 62-- 17 Aug 96 SAIC Deleted Subtest #2. 63-- 09 Feb 01 RLB Repaired to work on implementations with a 16-bit 64-- Integer. 65 66--! 67 68with Ada.Exceptions; 69with Ada.Numerics.Float_Random; 70with Ada.Numerics.Discrete_Random; 71with Ada.Strings.Bounded; 72with ImpDef; 73with Report; 74 75procedure CXA5011 is 76begin 77 78 Report.Test ("CXA5011", "Check the effect of Function Reset on the " & 79 "state of random number generators"); 80 81 Test_Block: 82 declare 83 84 use Ada.Exceptions; 85 use Ada.Numerics; 86 use Ada.Strings.Bounded; 87 88 -- Declare an modular subtype, and use it to instantiate the discrete 89 -- random number generator generic package. 90 91 type Discrete_Range is mod 2**(Integer'Size-1); 92 package Discrete_Package is new Discrete_Random(Discrete_Range); 93 94 -- Declaration of random number generator objects. 95 96 Discrete_Generator_1, 97 Discrete_Generator_2 : Discrete_Package.Generator; 98 Float_Generator_1, 99 Float_Generator_2 : Float_Random.Generator; 100 101 -- Declaration of bounded string packages instantiated with the 102 -- value of Max_Image_Width constant from each random number generator 103 -- package, and bounded string variables used to hold the image of 104 -- random number generator states. 105 106 package Discrete_String_Pack is 107 new Generic_Bounded_Length(Discrete_Package.Max_Image_Width); 108 109 package Float_String_Pack is 110 new Generic_Bounded_Length(Float_Random.Max_Image_Width); 111 112 use Discrete_String_Pack, Float_String_Pack; 113 114 TC_Seed : Integer; 115 TC_Max_Loop_Count : constant Natural := 1000; 116 Allowed_Matches : constant Natural := 2; 117 -- 118 -- In a sequence of TC_Max_Loop_Count random numbers that should 119 -- not match, some may match by chance. Up to Allowed_Matches 120 -- numbers may match before the test is considered to fail. 121 -- 122 123 124 procedure Check_Float_State (Gen_1, Gen_2 : Float_Random.Generator; 125 Sub_Test : Integer; 126 States_Should_Match : Boolean) is 127 128 use type Float_Random.State; 129 130 State_1, 131 State_2 : Float_Random.State; 132 133 State_String_1, 134 State_String_2 : Float_String_Pack.Bounded_String := 135 Float_String_Pack.Null_Bounded_String; 136 begin 137 138 Float_Random.Save(Gen => Gen_1, To_State => State_1); 139 Float_Random.Save(Gen_2, State_2); 140 141 State_String_1 := 142 Float_String_Pack.To_Bounded_String(Source => 143 Float_Random.Image(Of_State => State_1)); 144 145 State_String_2 := 146 Float_String_Pack.To_Bounded_String(Float_Random.Image(State_2)); 147 148 case States_Should_Match is 149 when True => 150 if State_1 /= State_2 then 151 Report.Failed("Subtest #" & Integer'Image(Sub_Test) & 152 " State values from Float generators " & 153 "are not the same"); 154 end if; 155 if State_String_1 /= State_String_2 then 156 Report.Failed("Subtest #" & Integer'Image(Sub_Test) & 157 " State strings from Float generators " & 158 "are not the same"); 159 end if; 160 when False => 161 if State_1 = State_2 then 162 Report.Failed("Subtest #" & Integer'Image(Sub_Test) & 163 " State values from Float generators " & 164 "are the same"); 165 end if; 166 if State_String_1 = State_String_2 then 167 Report.Failed("Subtest #" & Integer'Image(Sub_Test) & 168 " State strings from Float generators " & 169 "are the same"); 170 end if; 171 end case; 172 end Check_Float_State; 173 174 175 176 procedure Check_Discrete_State (Gen_1, 177 Gen_2 : Discrete_Package.Generator; 178 Sub_Test : Integer; 179 States_Should_Match : Boolean) is 180 181 use type Discrete_Package.State; 182 183 State_1, State_2 : Discrete_Package.State; 184 185 State_String_1, 186 State_String_2 : Discrete_String_Pack.Bounded_String := 187 Discrete_String_Pack.Null_Bounded_String; 188 begin 189 190 Discrete_Package.Save(Gen => Gen_1, 191 To_State => State_1); 192 Discrete_Package.Save(Gen_2, To_State => State_2); 193 194 State_String_1 := 195 Discrete_String_Pack.To_Bounded_String(Source => 196 Discrete_Package.Image(Of_State => State_1)); 197 198 State_String_2 := 199 Discrete_String_Pack.To_Bounded_String(Source => 200 Discrete_Package.Image(Of_State => State_2)); 201 202 case States_Should_Match is 203 when True => 204 if State_1 /= State_2 then 205 Report.Failed("Subtest #" & Integer'Image(Sub_Test) & 206 " State values from Discrete " & 207 "generators are not the same"); 208 end if; 209 if State_String_1 /= State_String_2 then 210 Report.Failed("Subtest #" & Integer'Image(Sub_Test) & 211 " State strings from Discrete " & 212 "generators are not the same"); 213 end if; 214 when False => 215 if State_1 = State_2 then 216 Report.Failed("Subtest #" & Integer'Image(Sub_Test) & 217 " State values from Discrete " & 218 "generators are the same"); 219 end if; 220 if State_String_1 = State_String_2 then 221 Report.Failed("Subtest #" & Integer'Image(Sub_Test) & 222 " State strings from Discrete " & 223 "generators are the same"); 224 end if; 225 end case; 226 end Check_Discrete_State; 227 228 229 230 procedure Check_Float_Values (Gen_1, Gen_2 : Float_Random.Generator; 231 Sub_Test : Integer; 232 Values_Should_Match : Boolean) is 233 Matches : Natural := 0; 234 Check_Failed : Boolean := False; 235 begin 236 case Values_Should_Match is 237 when True => 238 for i in 1..TC_Max_Loop_Count loop 239 if Float_Random.Random(Gen_1) /= Float_Random.Random(Gen_2) 240 then 241 Check_Failed := True; 242 exit; 243 end if; 244 end loop; 245 if Check_Failed then 246 Report.Failed("Sub_Test # " & Integer'Image(Sub_Test) & 247 " Random numbers from Float generators " & 248 "Failed check"); 249 end if; 250 when False => 251 for i in 1..TC_Max_Loop_Count loop 252 if Float_Random.Random(Gen_1) = Float_Random.Random(Gen_2) 253 then 254 Matches := Matches + 1; 255 end if; 256 end loop; 257 end case; 258 259 if (Values_Should_Match and Check_Failed) or 260 (not Values_Should_Match and Matches > Allowed_Matches) 261 then 262 Report.Failed("Sub_Test # " & Integer'Image(Sub_Test) & 263 " Random numbers from Float generators " & 264 "Failed check"); 265 end if; 266 267 end Check_Float_Values; 268 269 270 271 procedure Check_Discrete_Values (Gen_1, 272 Gen_2 : Discrete_Package.Generator; 273 Sub_Test : Integer; 274 Values_Should_Match : Boolean) is 275 Matches : Natural := 0; 276 Check_Failed : Boolean := False; 277 begin 278 case Values_Should_Match is 279 when True => 280 for i in 1..TC_Max_Loop_Count loop 281 if Discrete_Package.Random(Gen_1) /= 282 Discrete_Package.Random(Gen_2) 283 then 284 Check_Failed := True; 285 exit; 286 end if; 287 end loop; 288 when False => 289 for i in 1..TC_Max_Loop_Count loop 290 if Discrete_Package.Random(Gen_1) = 291 Discrete_Package.Random(Gen_2) 292 then 293 Matches := Matches + 1; 294 end if; 295 end loop; 296 end case; 297 298 if (Values_Should_Match and Check_Failed) or 299 (not Values_Should_Match and Matches > Allowed_Matches) 300 then 301 Report.Failed("Sub_Test # " & Integer'Image(Sub_Test) & 302 " Random numbers from Discrete generators " & 303 "Failed check"); 304 end if; 305 306 end Check_Discrete_Values; 307 308 309 310 begin 311 312 Sub_Test_1: 313 -- Check that two objects of type Generator are initialized to the 314 -- same state. 315 begin 316 317 -- Since the discrete and float random generators are in the initial 318 -- state, using Procedure Save to save the states of the generator 319 -- objects, and transforming these states into strings using 320 -- Function Image, should yield identical strings. 321 322 Check_Discrete_State (Discrete_Generator_1, 323 Discrete_Generator_2, 324 Sub_Test => 1, 325 States_Should_Match => True); 326 327 Check_Float_State (Float_Generator_1, 328 Float_Generator_2, 329 Sub_Test => 1, 330 States_Should_Match => True); 331 332 -- Since the two random generator objects are in their initial 333 -- state, the values produced from each (upon calls to Random) 334 -- should be identical. 335 336 Check_Discrete_Values (Discrete_Generator_1, 337 Discrete_Generator_2, 338 Sub_Test => 1, 339 Values_Should_Match => True); 340 341 Check_Float_Values (Float_Generator_1, 342 Float_Generator_2, 343 Sub_Test => 1, 344 Values_Should_Match => True); 345 346 end Sub_Test_1; 347 348 349 350 Sub_Test_3: 351 -- Check that when the Function Reset uses the same integer 352 -- initiator to reset two generators to the same state, the 353 -- resulting random values and the state from each generator 354 -- are identical. 355 declare 356 use Discrete_Package, Float_Random; 357 begin 358 359 -- Reset the generators to the same states, using the version of 360 -- Function Reset with both generator parameter and initiator 361 -- specified. 362 363 TC_Seed := Integer(Random(Discrete_Generator_1)); 364 Reset(Gen => Discrete_Generator_1, Initiator => TC_Seed); 365 Reset(Discrete_Generator_2, Initiator => TC_Seed); 366 Reset(Float_Generator_1, TC_Seed); 367 Reset(Float_Generator_2, TC_Seed); 368 369 -- Since the random generators have been reset to identical states, 370 -- bounded string images of these states should yield identical 371 -- strings. 372 373 Check_Discrete_State (Discrete_Generator_1, 374 Discrete_Generator_2, 375 Sub_Test => 3, 376 States_Should_Match => True); 377 378 Check_Float_State (Float_Generator_1, 379 Float_Generator_2, 380 Sub_Test => 3, 381 States_Should_Match => True); 382 383 -- Since the random generators have been reset to identical states, 384 -- the values produced from each (upon calls to Random) should 385 -- be identical. 386 387 Check_Discrete_Values (Discrete_Generator_1, 388 Discrete_Generator_2, 389 Sub_Test => 3, 390 Values_Should_Match => True); 391 392 Check_Float_Values (Float_Generator_1, 393 Float_Generator_2, 394 Sub_Test => 3, 395 Values_Should_Match => True); 396 397 end Sub_Test_3; 398 399 400 401 Sub_Test_4: 402 -- Check that when the Function Reset uses different integer 403 -- initiator values to reset two generators, the resulting random 404 -- numbers and states are different. 405 begin 406 407 -- Reset the generators to different states. 408 409 TC_Seed := 410 Integer(Discrete_Package.Random(Discrete_Generator_1)); 411 412 Discrete_Package.Reset(Gen => Discrete_Generator_1, 413 Initiator => TC_Seed); 414 415 -- Set the seed value to a different value for the second call 416 -- to Reset. 417 -- Note: A second call to Random could be made, as above, but that 418 -- would not ensure that the resulting seed value was 419 -- different from the first. 420 421 if TC_Seed /= Integer'Last then 422 TC_Seed := TC_Seed + 1; 423 else 424 TC_Seed := TC_Seed - 1; 425 end if; 426 427 Discrete_Package.Reset(Gen => Discrete_Generator_2, 428 Initiator => TC_Seed); 429 430 Float_Random.Reset(Float_Generator_1, 16#FF#); -- 255 431 Float_Random.Reset(Float_Generator_2, 2#1110_0000#); -- 224 432 433 -- Since the two float random generators are in different 434 -- states, the bounded string images depicting their states should 435 -- differ. 436 437 Check_Discrete_State (Discrete_Generator_1, 438 Discrete_Generator_2, 439 Sub_Test => 4, 440 States_Should_Match => False); 441 442 Check_Float_State (Float_Generator_1, 443 Float_Generator_2, 444 Sub_Test => 4, 445 States_Should_Match => False); 446 447 -- Since the two discrete random generator objects were reset 448 -- to different states, the values produced from each (upon calls 449 -- to Random) should differ. 450 451 Check_Discrete_Values (Discrete_Generator_1, 452 Discrete_Generator_2, 453 Sub_Test => 4, 454 Values_Should_Match => False); 455 456 Check_Float_Values (Float_Generator_1, 457 Float_Generator_2, 458 Sub_Test => 4, 459 Values_Should_Match => False); 460 461 end Sub_Test_4; 462 463 exception 464 when The_Error : others => 465 Report.Failed ("The following exception was raised in the " & 466 "Test_Block: " & Exception_Name(The_Error)); 467 end Test_Block; 468 469 Report.Result; 470 471end CXA5011; 472