Mercurial > hg > CbC > CbC_gcc
comparison 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 |
comparison
equal
deleted
inserted
replaced
68:561a7518be6b | 111:04ced10e8804 |
---|---|
1 -- CXA5012.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) 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). | |
41 -- | |
42 -- TEST DESCRIPTION: | |
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 | |
57 -- expected values. | |
58 -- | |
59 -- | |
60 -- CHANGE HISTORY: | |
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 | |
65 -- changes. | |
66 | |
67 --! | |
68 | |
69 with Ada.Numerics.Float_Random; | |
70 with Ada.Numerics.Discrete_Random; | |
71 with Ada.Strings.Bounded; | |
72 with ImpDef; | |
73 with Report; | |
74 | |
75 procedure CXA5012 is | |
76 | |
77 begin | |
78 | |
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"); | |
83 | |
84 Test_Block: | |
85 declare | |
86 | |
87 use Ada.Numerics, Ada.Strings.Bounded; | |
88 | |
89 -- Declare an integer subtype and an enumeration subtype, and use them | |
90 -- to instantiate the discrete random number generator generic package. | |
91 | |
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); | |
97 | |
98 -- Declaration of random number generator objects. | |
99 | |
100 DGen_1, DGen_2 : Discrete_Pack.Generator; | |
101 EGen_1, EGen_2 : Card_Pack.Generator; | |
102 FGen_1, FGen_2 : Float_Random.Generator; | |
103 | |
104 -- Variables declared to hold random numbers over the inclusive range | |
105 -- of their corresponding type. | |
106 | |
107 DVal_1, DVal_2 : Discrete_Range; | |
108 EVal_1, EVal_2 : Suit_Of_Cards; | |
109 FVal_1, FVal_2 : Float_Random.Uniformly_Distributed; | |
110 | |
111 -- Declaration of State variables used to hold the state of the | |
112 -- random number generators. | |
113 | |
114 DState_1, DState_2 : Discrete_Pack.State; | |
115 EState_1, EState_2 : Card_Pack.State; | |
116 FState_1, FState_2 : Float_Random.State; | |
117 | |
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. | |
121 | |
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); | |
128 | |
129 use DString_Pack, EString_Pack, FString_Pack; | |
130 | |
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; | |
137 | |
138 -- Test variables. | |
139 | |
140 TC_Count : Natural; | |
141 TC_Discrete_Check_Failed, | |
142 TC_Enum_Check_Failed, | |
143 TC_Float_Check_Failed : Boolean := False; | |
144 TC_Seed : Integer; | |
145 | |
146 begin | |
147 | |
148 Objective_1: | |
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. | |
153 declare | |
154 | |
155 First_Row : constant := 1; | |
156 Second_Row : constant := 2; | |
157 TC_Max_Values : constant := 100; | |
158 | |
159 TC_Discrete_Array : array (First_Row..Second_Row, 1..TC_Max_Values) | |
160 of Discrete_Range; | |
161 TC_Enum_Array : array (First_Row..Second_Row, 1..TC_Max_Values) | |
162 of Suit_Of_Cards; | |
163 TC_Float_Array : array (First_Row..Second_Row, 1..TC_Max_Values) | |
164 of Float_Random.Uniformly_Distributed; | |
165 begin | |
166 | |
167 -- The state of the random number generators are saved to state | |
168 -- variables using the procedure Save. | |
169 | |
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); | |
173 | |
174 -- Random number generators are used to fill the first half of the | |
175 -- first row of the arrays with randomly generated values. | |
176 | |
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); | |
181 end loop; | |
182 | |
183 -- The random number generators are reset to the states saved in the | |
184 -- state variables, using the procedure Reset. | |
185 | |
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); | |
189 | |
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. | |
192 | |
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); | |
197 end loop; | |
198 | |
199 -- Run the random number generators many times (not using results). | |
200 | |
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); | |
205 end loop; | |
206 | |
207 -- The states of the random number generators are saved to state | |
208 -- variables using the procedure Save. | |
209 | |
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); | |
213 | |
214 -- The last half of the first row of the arrays are filled with | |
215 -- values generated from the same random number generators. | |
216 | |
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); | |
221 end loop; | |
222 | |
223 -- The random number generators are reset to the states saved in the | |
224 -- state variables, using the procedure Reset. | |
225 | |
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); | |
229 | |
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. | |
234 | |
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); | |
239 end loop; | |
240 | |
241 -- Check that the values in the two rows of the arrays are identical. | |
242 | |
243 for i in 1..TC_Max_Values loop | |
244 if TC_Discrete_Array(First_Row,i) /= | |
245 TC_Discrete_Array(Second_Row,i) | |
246 then | |
247 TC_Discrete_Check_Failed := True; | |
248 exit; | |
249 end if; | |
250 end loop; | |
251 | |
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; | |
255 exit; | |
256 end if; | |
257 end loop; | |
258 | |
259 for i in 1..TC_Max_Values loop | |
260 if TC_Float_Array(First_Row,i) /= TC_Float_Array(Second_Row,i) | |
261 then | |
262 TC_Float_Check_Failed := True; | |
263 exit; | |
264 end if; | |
265 end loop; | |
266 | |
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; | |
271 end if; | |
272 | |
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 " & | |
276 "same"); | |
277 TC_Enum_Check_Failed := False; | |
278 end if; | |
279 | |
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; | |
284 end if; | |
285 | |
286 end Objective_1; | |
287 | |
288 | |
289 | |
290 Objective_2: | |
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. | |
296 begin | |
297 | |
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 | |
301 -- random values). | |
302 | |
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); | |
310 | |
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); | |
318 end loop; | |
319 | |
320 -- Use the Procedure Save to save the states of the generators | |
321 -- to state variables. | |
322 | |
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); | |
329 | |
330 -- Use the Function Image to produce a representation of the state | |
331 -- codes as (bounded) string objects. | |
332 | |
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)); | |
345 | |
346 -- Compare the bounded string objects for equality. | |
347 | |
348 if DString_1 /= DString_2 then | |
349 Report.Failed("String values returned from Function Image " & | |
350 "depict different states of Discrete generators"); | |
351 end if; | |
352 if EString_1 /= EString_2 then | |
353 Report.Failed("String values returned from Function Image " & | |
354 "depict different states of Enumeration " & | |
355 "generators"); | |
356 end if; | |
357 if FString_1 /= FString_2 then | |
358 Report.Failed("String values returned from Function Image " & | |
359 "depict different states of Float generators"); | |
360 end if; | |
361 | |
362 -- The string representation of a state code is transformed back | |
363 -- to a state code variable using the Function Value. | |
364 | |
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)); | |
369 | |
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. | |
373 | |
374 for i in 1..100 loop | |
375 DVal_1 := Discrete_Pack.Random(DGen_1); | |
376 EVal_1 := Card_Pack.Random(EGen_1); | |
377 FVal_1 := Float_Random.Random (FGen_1); | |
378 end loop; | |
379 | |
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. | |
383 | |
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); | |
387 | |
388 -- All generators should now be in the same state, so the | |
389 -- random values they produce should be the same. | |
390 | |
391 for i in 1..1000 loop | |
392 if Discrete_Pack.Random(DGen_1) /= Discrete_Pack.Random(DGen_2) | |
393 then | |
394 TC_Discrete_Check_Failed := True; | |
395 exit; | |
396 end if; | |
397 end loop; | |
398 | |
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; | |
402 exit; | |
403 end if; | |
404 end loop; | |
405 | |
406 for i in 1..1000 loop | |
407 if Float_Random.Random(FGen_1) /= Float_Random.Random(FGen_2) | |
408 then | |
409 TC_Float_Check_Failed := True; | |
410 exit; | |
411 end if; | |
412 end loop; | |
413 | |
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"); | |
418 end if; | |
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"); | |
423 end if; | |
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"); | |
428 end if; | |
429 | |
430 end Objective_2; | |
431 | |
432 | |
433 | |
434 Objective_3: | |
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). | |
439 declare | |
440 Not_A_State : constant String := ImpDef.Non_State_String; | |
441 begin | |
442 | |
443 begin | |
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 " & | |
450 "generator"); | |
451 else | |
452 Report.Comment("All strings represent states for Function " & | |
453 "Ada.Numerics.Discrete_Random.Value"); | |
454 end if; | |
455 Discrete_Pack.Reset(DGen_1, DState_1); | |
456 exception | |
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 " & | |
462 "generator"); | |
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 " & | |
468 "generator"); | |
469 when others => | |
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 " & | |
474 "generator"); | |
475 end; | |
476 | |
477 begin | |
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"); | |
485 else | |
486 Report.Comment("All strings represent states for Function " & | |
487 "Ada.Numerics.Discrete_Random.Value"); | |
488 end if; | |
489 Card_Pack.Reset(EGen_1, EState_1); | |
490 exception | |
491 when Constraint_Error => null; -- OK, expected exception. | |
492 when Program_Error => null; -- OK, expected exception. | |
493 when others => | |
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"); | |
499 end; | |
500 | |
501 begin | |
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 " & | |
509 "generator"); | |
510 else | |
511 Report.Comment("All strings represent states for Function " & | |
512 "Ada.Numerics.Float_Random.Value"); | |
513 end if; | |
514 Float_Random.Reset(FGen_1, FState_1); | |
515 exception | |
516 when Constraint_Error => null; -- OK, expected exception. | |
517 when Program_Error => null; -- OK, expected exception. | |
518 when others => | |
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 " & | |
524 "generator"); | |
525 end; | |
526 | |
527 end Objective_3; | |
528 | |
529 | |
530 exception | |
531 when others => Report.Failed ("Exception raised in Test_Block"); | |
532 end Test_Block; | |
533 | |
534 Report.Result; | |
535 | |
536 end CXA5012; |