111
|
1 ------------------------------------------------------------------------------
|
|
2 -- --
|
|
3 -- GNAT LIBRARY COMPONENTS --
|
|
4 -- --
|
|
5 -- A D A . C O N T A I N E R S . F O R M A L _ O R D E R E D _ S E T S --
|
|
6 -- --
|
|
7 -- S p e c --
|
|
8 -- --
|
131
|
9 -- Copyright (C) 2004-2018, Free Software Foundation, Inc. --
|
111
|
10 -- --
|
|
11 -- This specification is derived from the Ada Reference Manual for use with --
|
|
12 -- GNAT. The copyright notice above, and the license provisions that follow --
|
|
13 -- apply solely to the contents of the part following the private keyword. --
|
|
14 -- --
|
|
15 -- GNAT is free software; you can redistribute it and/or modify it under --
|
|
16 -- terms of the GNU General Public License as published by the Free Soft- --
|
|
17 -- ware Foundation; either version 3, or (at your option) any later ver- --
|
|
18 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
|
|
19 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
|
|
20 -- or FITNESS FOR A PARTICULAR PURPOSE. --
|
|
21 -- --
|
|
22 -- As a special exception under Section 7 of GPL version 3, you are granted --
|
|
23 -- additional permissions described in the GCC Runtime Library Exception, --
|
|
24 -- version 3.1, as published by the Free Software Foundation. --
|
|
25 -- --
|
|
26 -- You should have received a copy of the GNU General Public License and --
|
|
27 -- a copy of the GCC Runtime Library Exception along with this program; --
|
|
28 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
|
|
29 -- <http://www.gnu.org/licenses/>. --
|
|
30 ------------------------------------------------------------------------------
|
|
31
|
|
32 -- This spec is derived from package Ada.Containers.Bounded_Ordered_Sets in
|
|
33 -- the Ada 2012 RM. The modifications are meant to facilitate formal proofs by
|
|
34 -- making it easier to express properties, and by making the specification of
|
|
35 -- this unit compatible with SPARK 2014. Note that the API of this unit may be
|
|
36 -- subject to incompatible changes as SPARK 2014 evolves.
|
|
37
|
|
38 -- The modifications are:
|
|
39
|
|
40 -- A parameter for the container is added to every function reading the
|
|
41 -- content of a container: Key, Element, Next, Query_Element, Previous,
|
|
42 -- Has_Element, Iterate, Reverse_Iterate. This change is motivated by the
|
|
43 -- need to have cursors which are valid on different containers (typically
|
|
44 -- a container C and its previous version C'Old) for expressing properties,
|
|
45 -- which is not possible if cursors encapsulate an access to the underlying
|
|
46 -- container. The operators "<" and ">" that could not be modified that way
|
|
47 -- have been removed.
|
|
48
|
|
49 with Ada.Containers.Functional_Maps;
|
|
50 with Ada.Containers.Functional_Sets;
|
|
51 with Ada.Containers.Functional_Vectors;
|
|
52 private with Ada.Containers.Red_Black_Trees;
|
|
53
|
|
54 generic
|
|
55 type Element_Type is private;
|
|
56
|
|
57 with function "<" (Left, Right : Element_Type) return Boolean is <>;
|
|
58
|
|
59 package Ada.Containers.Formal_Ordered_Sets with
|
|
60 SPARK_Mode
|
|
61 is
|
|
62 pragma Annotate (CodePeer, Skip_Analysis);
|
|
63
|
|
64 function Equivalent_Elements (Left, Right : Element_Type) return Boolean
|
|
65 with
|
|
66 Global => null,
|
|
67 Post =>
|
|
68 Equivalent_Elements'Result =
|
|
69 (not (Left < Right) and not (Right < Left));
|
|
70 pragma Annotate (GNATprove, Inline_For_Proof, Equivalent_Elements);
|
|
71
|
|
72 type Set (Capacity : Count_Type) is private with
|
|
73 Iterable => (First => First,
|
|
74 Next => Next,
|
|
75 Has_Element => Has_Element,
|
|
76 Element => Element),
|
|
77 Default_Initial_Condition => Is_Empty (Set);
|
|
78 pragma Preelaborable_Initialization (Set);
|
|
79
|
|
80 type Cursor is record
|
|
81 Node : Count_Type;
|
|
82 end record;
|
|
83
|
|
84 No_Element : constant Cursor := (Node => 0);
|
|
85
|
|
86 function Length (Container : Set) return Count_Type with
|
|
87 Global => null,
|
|
88 Post => Length'Result <= Container.Capacity;
|
|
89
|
|
90 pragma Unevaluated_Use_Of_Old (Allow);
|
|
91
|
|
92 package Formal_Model with Ghost is
|
|
93 subtype Positive_Count_Type is Count_Type range 1 .. Count_Type'Last;
|
|
94
|
|
95 package M is new Ada.Containers.Functional_Sets
|
|
96 (Element_Type => Element_Type,
|
|
97 Equivalent_Elements => Equivalent_Elements);
|
|
98
|
|
99 function "="
|
|
100 (Left : M.Set;
|
|
101 Right : M.Set) return Boolean renames M."=";
|
|
102
|
|
103 function "<="
|
|
104 (Left : M.Set;
|
|
105 Right : M.Set) return Boolean renames M."<=";
|
|
106
|
|
107 package E is new Ada.Containers.Functional_Vectors
|
|
108 (Element_Type => Element_Type,
|
|
109 Index_Type => Positive_Count_Type);
|
|
110
|
|
111 function "="
|
|
112 (Left : E.Sequence;
|
|
113 Right : E.Sequence) return Boolean renames E."=";
|
|
114
|
|
115 function "<"
|
|
116 (Left : E.Sequence;
|
|
117 Right : E.Sequence) return Boolean renames E."<";
|
|
118
|
|
119 function "<="
|
|
120 (Left : E.Sequence;
|
|
121 Right : E.Sequence) return Boolean renames E."<=";
|
|
122
|
|
123 function E_Bigger_Than_Range
|
|
124 (Container : E.Sequence;
|
|
125 Fst : Positive_Count_Type;
|
|
126 Lst : Count_Type;
|
|
127 Item : Element_Type) return Boolean
|
|
128 with
|
|
129 Global => null,
|
|
130 Pre => Lst <= E.Length (Container),
|
|
131 Post =>
|
|
132 E_Bigger_Than_Range'Result =
|
|
133 (for all I in Fst .. Lst => E.Get (Container, I) < Item);
|
|
134 pragma Annotate (GNATprove, Inline_For_Proof, E_Bigger_Than_Range);
|
|
135
|
|
136 function E_Smaller_Than_Range
|
|
137 (Container : E.Sequence;
|
|
138 Fst : Positive_Count_Type;
|
|
139 Lst : Count_Type;
|
|
140 Item : Element_Type) return Boolean
|
|
141 with
|
|
142 Global => null,
|
|
143 Pre => Lst <= E.Length (Container),
|
|
144 Post =>
|
|
145 E_Smaller_Than_Range'Result =
|
|
146 (for all I in Fst .. Lst => Item < E.Get (Container, I));
|
|
147 pragma Annotate (GNATprove, Inline_For_Proof, E_Smaller_Than_Range);
|
|
148
|
|
149 function E_Is_Find
|
|
150 (Container : E.Sequence;
|
|
151 Item : Element_Type;
|
|
152 Position : Count_Type) return Boolean
|
|
153 with
|
|
154 Global => null,
|
|
155 Pre => Position - 1 <= E.Length (Container),
|
|
156 Post =>
|
|
157 E_Is_Find'Result =
|
|
158
|
|
159 ((if Position > 0 then
|
|
160 E_Bigger_Than_Range (Container, 1, Position - 1, Item))
|
|
161
|
|
162 and (if Position < E.Length (Container) then
|
|
163 E_Smaller_Than_Range
|
|
164 (Container,
|
|
165 Position + 1,
|
|
166 E.Length (Container),
|
|
167 Item)));
|
|
168 pragma Annotate (GNATprove, Inline_For_Proof, E_Is_Find);
|
|
169
|
|
170 function Find
|
|
171 (Container : E.Sequence;
|
|
172 Item : Element_Type) return Count_Type
|
|
173 -- Search for Item in Container
|
|
174
|
|
175 with
|
|
176 Global => null,
|
|
177 Post =>
|
|
178 (if Find'Result > 0 then
|
|
179 Find'Result <= E.Length (Container)
|
|
180 and Equivalent_Elements (Item, E.Get (Container, Find'Result)));
|
|
181
|
|
182 function E_Elements_Included
|
|
183 (Left : E.Sequence;
|
|
184 Right : E.Sequence) return Boolean
|
|
185 -- The elements of Left are contained in Right
|
|
186
|
|
187 with
|
|
188 Global => null,
|
|
189 Post =>
|
|
190 E_Elements_Included'Result =
|
|
191 (for all I in 1 .. E.Length (Left) =>
|
|
192 Find (Right, E.Get (Left, I)) > 0
|
|
193 and then E.Get (Right, Find (Right, E.Get (Left, I))) =
|
|
194 E.Get (Left, I));
|
|
195 pragma Annotate (GNATprove, Inline_For_Proof, E_Elements_Included);
|
|
196
|
|
197 function E_Elements_Included
|
|
198 (Left : E.Sequence;
|
|
199 Model : M.Set;
|
|
200 Right : E.Sequence) return Boolean
|
|
201 -- The elements of Container contained in Model are in Right
|
|
202
|
|
203 with
|
|
204 Global => null,
|
|
205 Post =>
|
|
206 E_Elements_Included'Result =
|
|
207 (for all I in 1 .. E.Length (Left) =>
|
|
208 (if M.Contains (Model, E.Get (Left, I)) then
|
|
209 Find (Right, E.Get (Left, I)) > 0
|
|
210 and then E.Get (Right, Find (Right, E.Get (Left, I))) =
|
|
211 E.Get (Left, I)));
|
|
212 pragma Annotate (GNATprove, Inline_For_Proof, E_Elements_Included);
|
|
213
|
|
214 function E_Elements_Included
|
|
215 (Container : E.Sequence;
|
|
216 Model : M.Set;
|
|
217 Left : E.Sequence;
|
|
218 Right : E.Sequence) return Boolean
|
|
219 -- The elements of Container contained in Model are in Left and others
|
|
220 -- are in Right.
|
|
221
|
|
222 with
|
|
223 Global => null,
|
|
224 Post =>
|
|
225 E_Elements_Included'Result =
|
|
226 (for all I in 1 .. E.Length (Container) =>
|
|
227 (if M.Contains (Model, E.Get (Container, I)) then
|
|
228 Find (Left, E.Get (Container, I)) > 0
|
|
229 and then E.Get (Left, Find (Left, E.Get (Container, I))) =
|
|
230 E.Get (Container, I)
|
|
231 else
|
|
232 Find (Right, E.Get (Container, I)) > 0
|
|
233 and then E.Get (Right, Find (Right, E.Get (Container, I))) =
|
|
234 E.Get (Container, I)));
|
|
235 pragma Annotate (GNATprove, Inline_For_Proof, E_Elements_Included);
|
|
236
|
|
237 package P is new Ada.Containers.Functional_Maps
|
|
238 (Key_Type => Cursor,
|
|
239 Element_Type => Positive_Count_Type,
|
|
240 Equivalent_Keys => "=",
|
|
241 Enable_Handling_Of_Equivalence => False);
|
|
242
|
|
243 function "="
|
|
244 (Left : P.Map;
|
|
245 Right : P.Map) return Boolean renames P."=";
|
|
246
|
|
247 function "<="
|
|
248 (Left : P.Map;
|
|
249 Right : P.Map) return Boolean renames P."<=";
|
|
250
|
|
251 function P_Positions_Shifted
|
|
252 (Small : P.Map;
|
|
253 Big : P.Map;
|
|
254 Cut : Positive_Count_Type;
|
|
255 Count : Count_Type := 1) return Boolean
|
|
256 with
|
|
257 Global => null,
|
|
258 Post =>
|
|
259 P_Positions_Shifted'Result =
|
|
260
|
|
261 -- Big contains all cursors of Small
|
|
262
|
|
263 (P.Keys_Included (Small, Big)
|
|
264
|
|
265 -- Cursors located before Cut are not moved, cursors located
|
|
266 -- after are shifted by Count.
|
|
267
|
|
268 and (for all I of Small =>
|
|
269 (if P.Get (Small, I) < Cut then
|
|
270 P.Get (Big, I) = P.Get (Small, I)
|
|
271 else
|
|
272 P.Get (Big, I) - Count = P.Get (Small, I)))
|
|
273
|
|
274 -- New cursors of Big (if any) are between Cut and Cut - 1 +
|
|
275 -- Count.
|
|
276
|
|
277 and (for all I of Big =>
|
|
278 P.Has_Key (Small, I)
|
|
279 or P.Get (Big, I) - Count in Cut - Count .. Cut - 1));
|
|
280
|
|
281 function Mapping_Preserved
|
|
282 (E_Left : E.Sequence;
|
|
283 E_Right : E.Sequence;
|
|
284 P_Left : P.Map;
|
|
285 P_Right : P.Map) return Boolean
|
|
286 with
|
|
287 Ghost,
|
|
288 Global => null,
|
|
289 Post =>
|
|
290 (if Mapping_Preserved'Result then
|
|
291
|
|
292 -- Right contains all the cursors of Left
|
|
293
|
|
294 P.Keys_Included (P_Left, P_Right)
|
|
295
|
|
296 -- Right contains all the elements of Left
|
|
297
|
|
298 and E_Elements_Included (E_Left, E_Right)
|
|
299
|
|
300 -- Mappings from cursors to elements induced by E_Left, P_Left
|
|
301 -- and E_Right, P_Right are the same.
|
|
302
|
|
303 and (for all C of P_Left =>
|
|
304 E.Get (E_Left, P.Get (P_Left, C)) =
|
|
305 E.Get (E_Right, P.Get (P_Right, C))));
|
|
306
|
|
307 function Mapping_Preserved_Except
|
|
308 (E_Left : E.Sequence;
|
|
309 E_Right : E.Sequence;
|
|
310 P_Left : P.Map;
|
|
311 P_Right : P.Map;
|
|
312 Position : Cursor) return Boolean
|
|
313 with
|
|
314 Ghost,
|
|
315 Global => null,
|
|
316 Post =>
|
|
317 (if Mapping_Preserved_Except'Result then
|
|
318
|
|
319 -- Right contains all the cursors of Left
|
|
320
|
|
321 P.Keys_Included (P_Left, P_Right)
|
|
322
|
|
323 -- Mappings from cursors to elements induced by E_Left, P_Left
|
|
324 -- and E_Right, P_Right are the same except for Position.
|
|
325
|
|
326 and (for all C of P_Left =>
|
|
327 (if C /= Position then
|
|
328 E.Get (E_Left, P.Get (P_Left, C)) =
|
|
329 E.Get (E_Right, P.Get (P_Right, C)))));
|
|
330
|
|
331 function Model (Container : Set) return M.Set with
|
|
332 -- The high-level model of a set is a set of elements. Neither cursors
|
|
333 -- nor order of elements are represented in this model. Elements are
|
|
334 -- modeled up to equivalence.
|
|
335
|
|
336 Ghost,
|
|
337 Global => null,
|
|
338 Post => M.Length (Model'Result) = Length (Container);
|
|
339
|
|
340 function Elements (Container : Set) return E.Sequence with
|
|
341 -- The Elements sequence represents the underlying list structure of
|
|
342 -- sets that is used for iteration. It stores the actual values of
|
|
343 -- elements in the set. It does not model cursors.
|
|
344
|
|
345 Ghost,
|
|
346 Global => null,
|
|
347 Post =>
|
|
348 E.Length (Elements'Result) = Length (Container)
|
|
349
|
|
350 -- It only contains keys contained in Model
|
|
351
|
|
352 and (for all Item of Elements'Result =>
|
|
353 M.Contains (Model (Container), Item))
|
|
354
|
|
355 -- It contains all the elements contained in Model
|
|
356
|
|
357 and (for all Item of Model (Container) =>
|
|
358 (Find (Elements'Result, Item) > 0
|
|
359 and then Equivalent_Elements
|
|
360 (E.Get (Elements'Result, Find (Elements'Result, Item)),
|
|
361 Item)))
|
|
362
|
|
363 -- It is sorted in increasing order
|
|
364
|
|
365 and (for all I in 1 .. Length (Container) =>
|
|
366 Find (Elements'Result, E.Get (Elements'Result, I)) = I
|
|
367 and
|
|
368 E_Is_Find
|
|
369 (Elements'Result, E.Get (Elements'Result, I), I));
|
|
370 pragma Annotate (GNATprove, Iterable_For_Proof, "Model", Elements);
|
|
371
|
|
372 function Positions (Container : Set) return P.Map with
|
|
373 -- The Positions map is used to model cursors. It only contains valid
|
|
374 -- cursors and maps them to their position in the container.
|
|
375
|
|
376 Ghost,
|
|
377 Global => null,
|
|
378 Post =>
|
|
379 not P.Has_Key (Positions'Result, No_Element)
|
|
380
|
|
381 -- Positions of cursors are smaller than the container's length
|
|
382
|
|
383 and then
|
|
384 (for all I of Positions'Result =>
|
|
385 P.Get (Positions'Result, I) in 1 .. Length (Container)
|
|
386
|
|
387 -- No two cursors have the same position. Note that we do not
|
|
388 -- state that there is a cursor in the map for each position, as
|
|
389 -- it is rarely needed.
|
|
390
|
|
391 and then
|
|
392 (for all J of Positions'Result =>
|
|
393 (if P.Get (Positions'Result, I) = P.Get (Positions'Result, J)
|
|
394 then I = J)));
|
|
395
|
|
396 procedure Lift_Abstraction_Level (Container : Set) with
|
|
397 -- Lift_Abstraction_Level is a ghost procedure that does nothing but
|
|
398 -- assume that we can access the same elements by iterating over
|
|
399 -- positions or cursors.
|
|
400 -- This information is not generally useful except when switching from
|
|
401 -- a low-level, cursor-aware view of a container, to a high-level,
|
|
402 -- position-based view.
|
|
403
|
|
404 Ghost,
|
|
405 Global => null,
|
|
406 Post =>
|
|
407 (for all Item of Elements (Container) =>
|
|
408 (for some I of Positions (Container) =>
|
|
409 E.Get (Elements (Container), P.Get (Positions (Container), I)) =
|
|
410 Item));
|
|
411
|
|
412 function Contains
|
|
413 (C : M.Set;
|
|
414 K : Element_Type) return Boolean renames M.Contains;
|
|
415 -- To improve readability of contracts, we rename the function used to
|
|
416 -- search for an element in the model to Contains.
|
|
417
|
|
418 end Formal_Model;
|
|
419 use Formal_Model;
|
|
420
|
|
421 Empty_Set : constant Set;
|
|
422
|
|
423 function "=" (Left, Right : Set) return Boolean with
|
|
424 Global => null,
|
|
425 Post =>
|
|
426
|
|
427 -- If two sets are equal, they contain the same elements in the same
|
|
428 -- order.
|
|
429
|
|
430 (if "="'Result then Elements (Left) = Elements (Right)
|
|
431
|
|
432 -- If they are different, then they do not contain the same elements
|
|
433
|
|
434 else
|
|
435 not E_Elements_Included (Elements (Left), Elements (Right))
|
|
436 or not E_Elements_Included (Elements (Right), Elements (Left)));
|
|
437
|
|
438 function Equivalent_Sets (Left, Right : Set) return Boolean with
|
|
439 Global => null,
|
|
440 Post => Equivalent_Sets'Result = (Model (Left) = Model (Right));
|
|
441
|
|
442 function To_Set (New_Item : Element_Type) return Set with
|
|
443 Global => null,
|
|
444 Post =>
|
|
445 M.Is_Singleton (Model (To_Set'Result), New_Item)
|
|
446 and Length (To_Set'Result) = 1
|
|
447 and E.Get (Elements (To_Set'Result), 1) = New_Item;
|
|
448
|
|
449 function Is_Empty (Container : Set) return Boolean with
|
|
450 Global => null,
|
|
451 Post => Is_Empty'Result = (Length (Container) = 0);
|
|
452
|
|
453 procedure Clear (Container : in out Set) with
|
|
454 Global => null,
|
|
455 Post => Length (Container) = 0 and M.Is_Empty (Model (Container));
|
|
456
|
|
457 procedure Assign (Target : in out Set; Source : Set) with
|
|
458 Global => null,
|
|
459 Pre => Target.Capacity >= Length (Source),
|
|
460 Post =>
|
|
461 Model (Target) = Model (Source)
|
|
462 and Elements (Target) = Elements (Source)
|
|
463 and Length (Target) = Length (Source);
|
|
464
|
|
465 function Copy (Source : Set; Capacity : Count_Type := 0) return Set with
|
|
466 Global => null,
|
|
467 Pre => Capacity = 0 or else Capacity >= Source.Capacity,
|
|
468 Post =>
|
|
469 Model (Copy'Result) = Model (Source)
|
|
470 and Elements (Copy'Result) = Elements (Source)
|
|
471 and Positions (Copy'Result) = Positions (Source)
|
|
472 and (if Capacity = 0 then
|
|
473 Copy'Result.Capacity = Source.Capacity
|
|
474 else
|
|
475 Copy'Result.Capacity = Capacity);
|
|
476
|
|
477 function Element
|
|
478 (Container : Set;
|
|
479 Position : Cursor) return Element_Type
|
|
480 with
|
|
481 Global => null,
|
|
482 Pre => Has_Element (Container, Position),
|
|
483 Post =>
|
|
484 Element'Result =
|
|
485 E.Get (Elements (Container), P.Get (Positions (Container), Position));
|
|
486 pragma Annotate (GNATprove, Inline_For_Proof, Element);
|
|
487
|
|
488 procedure Replace_Element
|
|
489 (Container : in out Set;
|
|
490 Position : Cursor;
|
|
491 New_Item : Element_Type)
|
|
492 with
|
|
493 Global => null,
|
|
494 Pre => Has_Element (Container, Position),
|
|
495 Post =>
|
|
496 Length (Container) = Length (Container)'Old
|
|
497
|
|
498 -- Position now maps to New_Item
|
|
499
|
|
500 and Element (Container, Position) = New_Item
|
|
501
|
|
502 -- New_Item is contained in Container
|
|
503
|
|
504 and Contains (Model (Container), New_Item)
|
|
505
|
|
506 -- Other elements are preserved
|
|
507
|
|
508 and M.Included_Except
|
|
509 (Model (Container)'Old,
|
|
510 Model (Container),
|
|
511 Element (Container, Position)'Old)
|
|
512 and M.Included_Except
|
|
513 (Model (Container),
|
|
514 Model (Container)'Old,
|
|
515 New_Item)
|
|
516
|
|
517 -- Mapping from cursors to elements is preserved
|
|
518
|
|
519 and Mapping_Preserved_Except
|
|
520 (E_Left => Elements (Container)'Old,
|
|
521 E_Right => Elements (Container),
|
|
522 P_Left => Positions (Container)'Old,
|
|
523 P_Right => Positions (Container),
|
|
524 Position => Position)
|
|
525 and Positions (Container) = Positions (Container)'Old;
|
|
526
|
|
527 procedure Move (Target : in out Set; Source : in out Set) with
|
|
528 Global => null,
|
|
529 Pre => Target.Capacity >= Length (Source),
|
|
530 Post =>
|
|
531 Model (Target) = Model (Source)'Old
|
|
532 and Elements (Target) = Elements (Source)'Old
|
|
533 and Length (Source)'Old = Length (Target)
|
|
534 and Length (Source) = 0;
|
|
535
|
|
536 procedure Insert
|
|
537 (Container : in out Set;
|
|
538 New_Item : Element_Type;
|
|
539 Position : out Cursor;
|
|
540 Inserted : out Boolean)
|
|
541 with
|
|
542 Global => null,
|
|
543 Pre =>
|
|
544 Length (Container) < Container.Capacity
|
|
545 or Contains (Container, New_Item),
|
|
546 Post =>
|
|
547 Contains (Container, New_Item)
|
|
548 and Has_Element (Container, Position)
|
|
549 and Equivalent_Elements (Element (Container, Position), New_Item)
|
|
550 and E_Is_Find
|
|
551 (Elements (Container),
|
|
552 New_Item,
|
|
553 P.Get (Positions (Container), Position)),
|
|
554 Contract_Cases =>
|
|
555
|
|
556 -- If New_Item is already in Container, it is not modified and Inserted
|
|
557 -- is set to False.
|
|
558
|
|
559 (Contains (Container, New_Item) =>
|
|
560 not Inserted
|
|
561 and Model (Container) = Model (Container)'Old
|
|
562 and Elements (Container) = Elements (Container)'Old
|
|
563 and Positions (Container) = Positions (Container)'Old,
|
|
564
|
|
565 -- Otherwise, New_Item is inserted in Container and Inserted is set to
|
|
566 -- True
|
|
567
|
|
568 others =>
|
|
569 Inserted
|
|
570 and Length (Container) = Length (Container)'Old + 1
|
|
571
|
|
572 -- Position now maps to New_Item
|
|
573
|
|
574 and Element (Container, Position) = New_Item
|
|
575
|
|
576 -- Other elements are preserved
|
|
577
|
|
578 and Model (Container)'Old <= Model (Container)
|
|
579 and M.Included_Except
|
|
580 (Model (Container),
|
|
581 Model (Container)'Old,
|
|
582 New_Item)
|
|
583
|
|
584 -- The elements of Container located before Position are preserved
|
|
585
|
|
586 and E.Range_Equal
|
|
587 (Left => Elements (Container)'Old,
|
|
588 Right => Elements (Container),
|
|
589 Fst => 1,
|
|
590 Lst => P.Get (Positions (Container), Position) - 1)
|
|
591
|
|
592 -- Other elements are shifted by 1
|
|
593
|
|
594 and E.Range_Shifted
|
|
595 (Left => Elements (Container)'Old,
|
|
596 Right => Elements (Container),
|
|
597 Fst => P.Get (Positions (Container), Position),
|
|
598 Lst => Length (Container)'Old,
|
|
599 Offset => 1)
|
|
600
|
|
601 -- A new cursor has been inserted at position Position in
|
|
602 -- Container.
|
|
603
|
|
604 and P_Positions_Shifted
|
|
605 (Positions (Container)'Old,
|
|
606 Positions (Container),
|
|
607 Cut => P.Get (Positions (Container), Position)));
|
|
608
|
|
609 procedure Insert
|
|
610 (Container : in out Set;
|
|
611 New_Item : Element_Type)
|
|
612 with
|
|
613 Global => null,
|
|
614 Pre =>
|
|
615 Length (Container) < Container.Capacity
|
|
616 and then (not Contains (Container, New_Item)),
|
|
617 Post =>
|
|
618 Length (Container) = Length (Container)'Old + 1
|
|
619 and Contains (Container, New_Item)
|
|
620
|
|
621 -- New_Item is inserted in the set
|
|
622
|
|
623 and E.Get (Elements (Container),
|
|
624 Find (Elements (Container), New_Item)) = New_Item
|
|
625
|
|
626 -- Other mappings are preserved
|
|
627
|
|
628 and Model (Container)'Old <= Model (Container)
|
|
629 and M.Included_Except
|
|
630 (Model (Container),
|
|
631 Model (Container)'Old,
|
|
632 New_Item)
|
|
633
|
|
634 -- The elements of Container located before New_Item are preserved
|
|
635
|
|
636 and E.Range_Equal
|
|
637 (Left => Elements (Container)'Old,
|
|
638 Right => Elements (Container),
|
|
639 Fst => 1,
|
|
640 Lst => Find (Elements (Container), New_Item) - 1)
|
|
641
|
|
642 -- Other elements are shifted by 1
|
|
643
|
|
644 and E.Range_Shifted
|
|
645 (Left => Elements (Container)'Old,
|
|
646 Right => Elements (Container),
|
|
647 Fst => Find (Elements (Container), New_Item),
|
|
648 Lst => Length (Container)'Old,
|
|
649 Offset => 1)
|
|
650
|
|
651 -- A new cursor has been inserted in Container
|
|
652
|
|
653 and P_Positions_Shifted
|
|
654 (Positions (Container)'Old,
|
|
655 Positions (Container),
|
|
656 Cut => Find (Elements (Container), New_Item));
|
|
657
|
|
658 procedure Include
|
|
659 (Container : in out Set;
|
|
660 New_Item : Element_Type)
|
|
661 with
|
|
662 Global => null,
|
|
663 Pre =>
|
|
664 Length (Container) < Container.Capacity
|
|
665 or Contains (Container, New_Item),
|
|
666 Post => Contains (Container, New_Item),
|
|
667 Contract_Cases =>
|
|
668
|
|
669 -- If New_Item is already in Container
|
|
670
|
|
671 (Contains (Container, New_Item) =>
|
|
672
|
|
673 -- Elements are preserved
|
|
674
|
|
675 Model (Container)'Old = Model (Container)
|
|
676
|
|
677 -- Cursors are preserved
|
|
678
|
|
679 and Positions (Container) = Positions (Container)'Old
|
|
680
|
|
681 -- The element equivalent to New_Item in Container is replaced by
|
|
682 -- New_Item.
|
|
683
|
|
684 and E.Get (Elements (Container),
|
|
685 Find (Elements (Container), New_Item)) = New_Item
|
|
686
|
|
687 and E.Equal_Except
|
|
688 (Elements (Container)'Old,
|
|
689 Elements (Container),
|
|
690 Find (Elements (Container), New_Item)),
|
|
691
|
|
692 -- Otherwise, New_Item is inserted in Container
|
|
693
|
|
694 others =>
|
|
695 Length (Container) = Length (Container)'Old + 1
|
|
696
|
|
697 -- Other elements are preserved
|
|
698
|
|
699 and Model (Container)'Old <= Model (Container)
|
|
700 and M.Included_Except
|
|
701 (Model (Container),
|
|
702 Model (Container)'Old,
|
|
703 New_Item)
|
|
704
|
|
705 -- New_Item is inserted in Container
|
|
706
|
|
707 and E.Get (Elements (Container),
|
|
708 Find (Elements (Container), New_Item)) = New_Item
|
|
709
|
|
710 -- The Elements of Container located before New_Item are preserved
|
|
711
|
|
712 and E.Range_Equal
|
|
713 (Left => Elements (Container)'Old,
|
|
714 Right => Elements (Container),
|
|
715 Fst => 1,
|
|
716 Lst => Find (Elements (Container), New_Item) - 1)
|
|
717
|
|
718 -- Other Elements are shifted by 1
|
|
719
|
|
720 and E.Range_Shifted
|
|
721 (Left => Elements (Container)'Old,
|
|
722 Right => Elements (Container),
|
|
723 Fst => Find (Elements (Container), New_Item),
|
|
724 Lst => Length (Container)'Old,
|
|
725 Offset => 1)
|
|
726
|
|
727 -- A new cursor has been inserted in Container
|
|
728
|
|
729 and P_Positions_Shifted
|
|
730 (Positions (Container)'Old,
|
|
731 Positions (Container),
|
|
732 Cut => Find (Elements (Container), New_Item)));
|
|
733
|
|
734 procedure Replace
|
|
735 (Container : in out Set;
|
|
736 New_Item : Element_Type)
|
|
737 with
|
|
738 Global => null,
|
|
739 Pre => Contains (Container, New_Item),
|
|
740 Post =>
|
|
741
|
|
742 -- Elements are preserved
|
|
743
|
|
744 Model (Container)'Old = Model (Container)
|
|
745
|
|
746 -- Cursors are preserved
|
|
747
|
|
748 and Positions (Container) = Positions (Container)'Old
|
|
749
|
|
750 -- The element equivalent to New_Item in Container is replaced by
|
|
751 -- New_Item.
|
|
752
|
|
753 and E.Get (Elements (Container),
|
|
754 Find (Elements (Container), New_Item)) = New_Item
|
|
755 and E.Equal_Except
|
|
756 (Elements (Container)'Old,
|
|
757 Elements (Container),
|
|
758 Find (Elements (Container), New_Item));
|
|
759
|
|
760 procedure Exclude
|
|
761 (Container : in out Set;
|
|
762 Item : Element_Type)
|
|
763 with
|
|
764 Global => null,
|
|
765 Post => not Contains (Container, Item),
|
|
766 Contract_Cases =>
|
|
767
|
|
768 -- If Item is not in Container, nothing is changed
|
|
769
|
|
770 (not Contains (Container, Item) =>
|
|
771 Model (Container) = Model (Container)'Old
|
|
772 and Elements (Container) = Elements (Container)'Old
|
|
773 and Positions (Container) = Positions (Container)'Old,
|
|
774
|
|
775 -- Otherwise, Item is removed from Container
|
|
776
|
|
777 others =>
|
|
778 Length (Container) = Length (Container)'Old - 1
|
|
779
|
|
780 -- Other elements are preserved
|
|
781
|
|
782 and Model (Container) <= Model (Container)'Old
|
|
783 and M.Included_Except
|
|
784 (Model (Container)'Old,
|
|
785 Model (Container),
|
|
786 Item)
|
|
787
|
|
788 -- The elements of Container located before Item are preserved
|
|
789
|
|
790 and E.Range_Equal
|
|
791 (Left => Elements (Container)'Old,
|
|
792 Right => Elements (Container),
|
|
793 Fst => 1,
|
|
794 Lst => Find (Elements (Container), Item)'Old - 1)
|
|
795
|
|
796 -- The elements located after Item are shifted by 1
|
|
797
|
|
798 and E.Range_Shifted
|
|
799 (Left => Elements (Container),
|
|
800 Right => Elements (Container)'Old,
|
|
801 Fst => Find (Elements (Container), Item)'Old,
|
|
802 Lst => Length (Container),
|
|
803 Offset => 1)
|
|
804
|
|
805 -- A cursor has been removed from Container
|
|
806
|
|
807 and P_Positions_Shifted
|
|
808 (Positions (Container),
|
|
809 Positions (Container)'Old,
|
|
810 Cut => Find (Elements (Container), Item)'Old));
|
|
811
|
|
812 procedure Delete
|
|
813 (Container : in out Set;
|
|
814 Item : Element_Type)
|
|
815 with
|
|
816 Global => null,
|
|
817 Pre => Contains (Container, Item),
|
|
818 Post =>
|
|
819 Length (Container) = Length (Container)'Old - 1
|
|
820
|
|
821 -- Item is no longer in Container
|
|
822
|
|
823 and not Contains (Container, Item)
|
|
824
|
|
825 -- Other elements are preserved
|
|
826
|
|
827 and Model (Container) <= Model (Container)'Old
|
|
828 and M.Included_Except
|
|
829 (Model (Container)'Old,
|
|
830 Model (Container),
|
|
831 Item)
|
|
832
|
|
833 -- The elements of Container located before Item are preserved
|
|
834
|
|
835 and E.Range_Equal
|
|
836 (Left => Elements (Container)'Old,
|
|
837 Right => Elements (Container),
|
|
838 Fst => 1,
|
|
839 Lst => Find (Elements (Container), Item)'Old - 1)
|
|
840
|
|
841 -- The elements located after Item are shifted by 1
|
|
842
|
|
843 and E.Range_Shifted
|
|
844 (Left => Elements (Container),
|
|
845 Right => Elements (Container)'Old,
|
|
846 Fst => Find (Elements (Container), Item)'Old,
|
|
847 Lst => Length (Container),
|
|
848 Offset => 1)
|
|
849
|
|
850 -- A cursor has been removed from Container
|
|
851
|
|
852 and P_Positions_Shifted
|
|
853 (Positions (Container),
|
|
854 Positions (Container)'Old,
|
|
855 Cut => Find (Elements (Container), Item)'Old);
|
|
856
|
|
857 procedure Delete
|
|
858 (Container : in out Set;
|
|
859 Position : in out Cursor)
|
|
860 with
|
|
861 Global => null,
|
|
862 Pre => Has_Element (Container, Position),
|
|
863 Post =>
|
|
864 Position = No_Element
|
|
865 and Length (Container) = Length (Container)'Old - 1
|
|
866
|
|
867 -- The element at position Position is no longer in Container
|
|
868
|
|
869 and not Contains (Container, Element (Container, Position)'Old)
|
|
870 and not P.Has_Key (Positions (Container), Position'Old)
|
|
871
|
|
872 -- Other elements are preserved
|
|
873
|
|
874 and Model (Container) <= Model (Container)'Old
|
|
875 and M.Included_Except
|
|
876 (Model (Container)'Old,
|
|
877 Model (Container),
|
|
878 Element (Container, Position)'Old)
|
|
879
|
|
880 -- The elements of Container located before Position are preserved.
|
|
881
|
|
882 and E.Range_Equal
|
|
883 (Left => Elements (Container)'Old,
|
|
884 Right => Elements (Container),
|
|
885 Fst => 1,
|
|
886 Lst => P.Get (Positions (Container)'Old, Position'Old) - 1)
|
|
887
|
|
888 -- The elements located after Position are shifted by 1
|
|
889
|
|
890 and E.Range_Shifted
|
|
891 (Left => Elements (Container),
|
|
892 Right => Elements (Container)'Old,
|
|
893 Fst => P.Get (Positions (Container)'Old, Position'Old),
|
|
894 Lst => Length (Container),
|
|
895 Offset => 1)
|
|
896
|
|
897 -- Position has been removed from Container
|
|
898
|
|
899 and P_Positions_Shifted
|
|
900 (Positions (Container),
|
|
901 Positions (Container)'Old,
|
|
902 Cut => P.Get (Positions (Container)'Old, Position'Old));
|
|
903
|
|
904 procedure Delete_First (Container : in out Set) with
|
|
905 Global => null,
|
|
906 Contract_Cases =>
|
|
907 (Length (Container) = 0 => Length (Container) = 0,
|
|
908 others =>
|
|
909 Length (Container) = Length (Container)'Old - 1
|
|
910
|
|
911 -- The first element has been removed from Container
|
|
912
|
|
913 and not Contains (Container, First_Element (Container)'Old)
|
|
914
|
|
915 -- Other elements are preserved
|
|
916
|
|
917 and Model (Container) <= Model (Container)'Old
|
|
918 and M.Included_Except
|
|
919 (Model (Container)'Old,
|
|
920 Model (Container),
|
|
921 First_Element (Container)'Old)
|
|
922
|
|
923 -- Other elements are shifted by 1
|
|
924
|
|
925 and E.Range_Shifted
|
|
926 (Left => Elements (Container),
|
|
927 Right => Elements (Container)'Old,
|
|
928 Fst => 1,
|
|
929 Lst => Length (Container),
|
|
930 Offset => 1)
|
|
931
|
|
932 -- First has been removed from Container
|
|
933
|
|
934 and P_Positions_Shifted
|
|
935 (Positions (Container),
|
|
936 Positions (Container)'Old,
|
|
937 Cut => 1));
|
|
938
|
|
939 procedure Delete_Last (Container : in out Set) with
|
|
940 Global => null,
|
|
941 Contract_Cases =>
|
|
942 (Length (Container) = 0 => Length (Container) = 0,
|
|
943 others =>
|
|
944 Length (Container) = Length (Container)'Old - 1
|
|
945
|
|
946 -- The last element has been removed from Container
|
|
947
|
|
948 and not Contains (Container, Last_Element (Container)'Old)
|
|
949
|
|
950 -- Other elements are preserved
|
|
951
|
|
952 and Model (Container) <= Model (Container)'Old
|
|
953 and M.Included_Except
|
|
954 (Model (Container)'Old,
|
|
955 Model (Container),
|
|
956 Last_Element (Container)'Old)
|
|
957
|
|
958 -- Others elements of Container are preserved
|
|
959
|
|
960 and E.Range_Equal
|
|
961 (Left => Elements (Container)'Old,
|
|
962 Right => Elements (Container),
|
|
963 Fst => 1,
|
|
964 Lst => Length (Container))
|
|
965
|
|
966 -- Last cursor has been removed from Container
|
|
967
|
|
968 and Positions (Container) <= Positions (Container)'Old);
|
|
969
|
|
970 procedure Union (Target : in out Set; Source : Set) with
|
|
971 Global => null,
|
|
972 Pre =>
|
|
973 Length (Source) - Length (Target and Source) <=
|
|
974 Target.Capacity - Length (Target),
|
|
975 Post =>
|
|
976 Length (Target) = Length (Target)'Old
|
|
977 - M.Num_Overlaps (Model (Target)'Old, Model (Source))
|
|
978 + Length (Source)
|
|
979
|
|
980 -- Elements already in Target are still in Target
|
|
981
|
|
982 and Model (Target)'Old <= Model (Target)
|
|
983
|
|
984 -- Elements of Source are included in Target
|
|
985
|
|
986 and Model (Source) <= Model (Target)
|
|
987
|
|
988 -- Elements of Target come from either Source or Target
|
|
989
|
|
990 and
|
|
991 M.Included_In_Union
|
|
992 (Model (Target), Model (Source), Model (Target)'Old)
|
|
993
|
|
994 -- Actual value of elements come from either Left or Right
|
|
995
|
|
996 and
|
|
997 E_Elements_Included
|
|
998 (Elements (Target),
|
|
999 Model (Target)'Old,
|
|
1000 Elements (Target)'Old,
|
|
1001 Elements (Source))
|
|
1002 and
|
|
1003 E_Elements_Included
|
|
1004 (Elements (Target)'Old, Model (Target)'Old, Elements (Target))
|
|
1005 and
|
|
1006 E_Elements_Included
|
|
1007 (Elements (Source),
|
|
1008 Model (Target)'Old,
|
|
1009 Elements (Source),
|
|
1010 Elements (Target))
|
|
1011
|
|
1012 -- Mapping from cursors of Target to elements is preserved
|
|
1013
|
|
1014 and Mapping_Preserved
|
|
1015 (E_Left => Elements (Target)'Old,
|
|
1016 E_Right => Elements (Target),
|
|
1017 P_Left => Positions (Target)'Old,
|
|
1018 P_Right => Positions (Target));
|
|
1019
|
|
1020 function Union (Left, Right : Set) return Set with
|
|
1021 Global => null,
|
|
1022 Pre => Length (Left) <= Count_Type'Last - Length (Right),
|
|
1023 Post =>
|
|
1024 Length (Union'Result) = Length (Left)
|
|
1025 - M.Num_Overlaps (Model (Left), Model (Right))
|
|
1026 + Length (Right)
|
|
1027
|
|
1028 -- Elements of Left and Right are in the result of Union
|
|
1029
|
|
1030 and Model (Left) <= Model (Union'Result)
|
|
1031 and Model (Right) <= Model (Union'Result)
|
|
1032
|
|
1033 -- Elements of the result of union come from either Left or Right
|
|
1034
|
|
1035 and
|
|
1036 M.Included_In_Union
|
|
1037 (Model (Union'Result), Model (Left), Model (Right))
|
|
1038
|
|
1039 -- Actual value of elements come from either Left or Right
|
|
1040
|
|
1041 and
|
|
1042 E_Elements_Included
|
|
1043 (Elements (Union'Result),
|
|
1044 Model (Left),
|
|
1045 Elements (Left),
|
|
1046 Elements (Right))
|
|
1047 and
|
|
1048 E_Elements_Included
|
|
1049 (Elements (Left), Model (Left), Elements (Union'Result))
|
|
1050 and
|
|
1051 E_Elements_Included
|
|
1052 (Elements (Right),
|
|
1053 Model (Left),
|
|
1054 Elements (Right),
|
|
1055 Elements (Union'Result));
|
|
1056
|
|
1057 function "or" (Left, Right : Set) return Set renames Union;
|
|
1058
|
|
1059 procedure Intersection (Target : in out Set; Source : Set) with
|
|
1060 Global => null,
|
|
1061 Post =>
|
|
1062 Length (Target) =
|
|
1063 M.Num_Overlaps (Model (Target)'Old, Model (Source))
|
|
1064
|
|
1065 -- Elements of Target were already in Target
|
|
1066
|
|
1067 and Model (Target) <= Model (Target)'Old
|
|
1068
|
|
1069 -- Elements of Target are in Source
|
|
1070
|
|
1071 and Model (Target) <= Model (Source)
|
|
1072
|
|
1073 -- Elements both in Source and Target are in the intersection
|
|
1074
|
|
1075 and
|
|
1076 M.Includes_Intersection
|
|
1077 (Model (Target), Model (Source), Model (Target)'Old)
|
|
1078
|
|
1079 -- Actual value of elements of Target is preserved
|
|
1080
|
|
1081 and E_Elements_Included (Elements (Target), Elements (Target)'Old)
|
|
1082 and
|
|
1083 E_Elements_Included
|
|
1084 (Elements (Target)'Old, Model (Source), Elements (Target))
|
|
1085
|
|
1086 -- Mapping from cursors of Target to elements is preserved
|
|
1087
|
|
1088 and Mapping_Preserved
|
|
1089 (E_Left => Elements (Target),
|
|
1090 E_Right => Elements (Target)'Old,
|
|
1091 P_Left => Positions (Target),
|
|
1092 P_Right => Positions (Target)'Old);
|
|
1093
|
|
1094 function Intersection (Left, Right : Set) return Set with
|
|
1095 Global => null,
|
|
1096 Post =>
|
|
1097 Length (Intersection'Result) =
|
|
1098 M.Num_Overlaps (Model (Left), Model (Right))
|
|
1099
|
|
1100 -- Elements in the result of Intersection are in Left and Right
|
|
1101
|
|
1102 and Model (Intersection'Result) <= Model (Left)
|
|
1103 and Model (Intersection'Result) <= Model (Right)
|
|
1104
|
|
1105 -- Elements both in Left and Right are in the result of Intersection
|
|
1106
|
|
1107 and
|
|
1108 M.Includes_Intersection
|
|
1109 (Model (Intersection'Result), Model (Left), Model (Right))
|
|
1110
|
|
1111 -- Actual value of elements come from Left
|
|
1112
|
|
1113 and
|
|
1114 E_Elements_Included
|
|
1115 (Elements (Intersection'Result), Elements (Left))
|
|
1116 and
|
|
1117 E_Elements_Included
|
|
1118 (Elements (Left), Model (Right), Elements (Intersection'Result));
|
|
1119
|
|
1120 function "and" (Left, Right : Set) return Set renames Intersection;
|
|
1121
|
|
1122 procedure Difference (Target : in out Set; Source : Set) with
|
|
1123 Global => null,
|
|
1124 Post =>
|
|
1125 Length (Target) = Length (Target)'Old -
|
|
1126 M.Num_Overlaps (Model (Target)'Old, Model (Source))
|
|
1127
|
|
1128 -- Elements of Target were already in Target
|
|
1129
|
|
1130 and Model (Target) <= Model (Target)'Old
|
|
1131
|
|
1132 -- Elements of Target are not in Source
|
|
1133
|
|
1134 and M.No_Overlap (Model (Target), Model (Source))
|
|
1135
|
|
1136 -- Elements in Target but not in Source are in the difference
|
|
1137
|
|
1138 and
|
|
1139 M.Included_In_Union
|
|
1140 (Model (Target)'Old, Model (Target), Model (Source))
|
|
1141
|
|
1142 -- Actual value of elements of Target is preserved
|
|
1143
|
|
1144 and E_Elements_Included (Elements (Target), Elements (Target)'Old)
|
|
1145 and
|
|
1146 E_Elements_Included
|
|
1147 (Elements (Target)'Old, Model (Target), Elements (Target))
|
|
1148
|
|
1149 -- Mapping from cursors of Target to elements is preserved
|
|
1150
|
|
1151 and Mapping_Preserved
|
|
1152 (E_Left => Elements (Target),
|
|
1153 E_Right => Elements (Target)'Old,
|
|
1154 P_Left => Positions (Target),
|
|
1155 P_Right => Positions (Target)'Old);
|
|
1156
|
|
1157 function Difference (Left, Right : Set) return Set with
|
|
1158 Global => null,
|
|
1159 Post =>
|
|
1160 Length (Difference'Result) = Length (Left) -
|
|
1161 M.Num_Overlaps (Model (Left), Model (Right))
|
|
1162
|
|
1163 -- Elements of the result of Difference are in Left
|
|
1164
|
|
1165 and Model (Difference'Result) <= Model (Left)
|
|
1166
|
|
1167 -- Elements of the result of Difference are in Right
|
|
1168
|
|
1169 and M.No_Overlap (Model (Difference'Result), Model (Right))
|
|
1170
|
|
1171 -- Elements in Left but not in Right are in the difference
|
|
1172
|
|
1173 and
|
|
1174 M.Included_In_Union
|
|
1175 (Model (Left), Model (Difference'Result), Model (Right))
|
|
1176
|
|
1177 -- Actual value of elements come from Left
|
|
1178
|
|
1179 and
|
|
1180 E_Elements_Included (Elements (Difference'Result), Elements (Left))
|
|
1181 and
|
|
1182 E_Elements_Included
|
|
1183 (Elements (Left),
|
|
1184 Model (Difference'Result),
|
|
1185 Elements (Difference'Result));
|
|
1186
|
|
1187 function "-" (Left, Right : Set) return Set renames Difference;
|
|
1188
|
|
1189 procedure Symmetric_Difference (Target : in out Set; Source : Set) with
|
|
1190 Global => null,
|
|
1191 Pre =>
|
|
1192 Length (Source) - Length (Target and Source) <=
|
|
1193 Target.Capacity - Length (Target) + Length (Target and Source),
|
|
1194 Post =>
|
|
1195 Length (Target) = Length (Target)'Old -
|
|
1196 2 * M.Num_Overlaps (Model (Target)'Old, Model (Source)) +
|
|
1197 Length (Source)
|
|
1198
|
|
1199 -- Elements of the difference were not both in Source and in Target
|
|
1200
|
|
1201 and M.Not_In_Both (Model (Target), Model (Target)'Old, Model (Source))
|
|
1202
|
|
1203 -- Elements in Target but not in Source are in the difference
|
|
1204
|
|
1205 and
|
|
1206 M.Included_In_Union
|
|
1207 (Model (Target)'Old, Model (Target), Model (Source))
|
|
1208
|
|
1209 -- Elements in Source but not in Target are in the difference
|
|
1210
|
|
1211 and
|
|
1212 M.Included_In_Union
|
|
1213 (Model (Source), Model (Target), Model (Target)'Old)
|
|
1214
|
|
1215 -- Actual value of elements come from either Left or Right
|
|
1216
|
|
1217 and
|
|
1218 E_Elements_Included
|
|
1219 (Elements (Target),
|
|
1220 Model (Target)'Old,
|
|
1221 Elements (Target)'Old,
|
|
1222 Elements (Source))
|
|
1223 and
|
|
1224 E_Elements_Included
|
|
1225 (Elements (Target)'Old, Model (Target), Elements (Target))
|
|
1226 and
|
|
1227 E_Elements_Included
|
|
1228 (Elements (Source), Model (Target), Elements (Target));
|
|
1229
|
|
1230 function Symmetric_Difference (Left, Right : Set) return Set with
|
|
1231 Global => null,
|
|
1232 Pre => Length (Left) <= Count_Type'Last - Length (Right),
|
|
1233 Post =>
|
|
1234 Length (Symmetric_Difference'Result) = Length (Left) -
|
|
1235 2 * M.Num_Overlaps (Model (Left), Model (Right)) +
|
|
1236 Length (Right)
|
|
1237
|
|
1238 -- Elements of the difference were not both in Left and Right
|
|
1239
|
|
1240 and
|
|
1241 M.Not_In_Both
|
|
1242 (Model (Symmetric_Difference'Result), Model (Left), Model (Right))
|
|
1243
|
|
1244 -- Elements in Left but not in Right are in the difference
|
|
1245
|
|
1246 and
|
|
1247 M.Included_In_Union
|
|
1248 (Model (Left), Model (Symmetric_Difference'Result), Model (Right))
|
|
1249
|
|
1250 -- Elements in Right but not in Left are in the difference
|
|
1251
|
|
1252 and
|
|
1253 M.Included_In_Union
|
|
1254 (Model (Right), Model (Symmetric_Difference'Result), Model (Left))
|
|
1255
|
|
1256 -- Actual value of elements come from either Left or Right
|
|
1257
|
|
1258 and
|
|
1259 E_Elements_Included
|
|
1260 (Elements (Symmetric_Difference'Result),
|
|
1261 Model (Left),
|
|
1262 Elements (Left),
|
|
1263 Elements (Right))
|
|
1264 and
|
|
1265 E_Elements_Included
|
|
1266 (Elements (Left),
|
|
1267 Model (Symmetric_Difference'Result),
|
|
1268 Elements (Symmetric_Difference'Result))
|
|
1269 and
|
|
1270 E_Elements_Included
|
|
1271 (Elements (Right),
|
|
1272 Model (Symmetric_Difference'Result),
|
|
1273 Elements (Symmetric_Difference'Result));
|
|
1274
|
|
1275 function "xor" (Left, Right : Set) return Set
|
|
1276 renames Symmetric_Difference;
|
|
1277
|
|
1278 function Overlap (Left, Right : Set) return Boolean with
|
|
1279 Global => null,
|
|
1280 Post =>
|
|
1281 Overlap'Result = not (M.No_Overlap (Model (Left), Model (Right)));
|
|
1282
|
|
1283 function Is_Subset (Subset : Set; Of_Set : Set) return Boolean with
|
|
1284 Global => null,
|
|
1285 Post => Is_Subset'Result = (Model (Subset) <= Model (Of_Set));
|
|
1286
|
|
1287 function First (Container : Set) return Cursor with
|
|
1288 Global => null,
|
|
1289 Contract_Cases =>
|
|
1290 (Length (Container) = 0 =>
|
|
1291 First'Result = No_Element,
|
|
1292
|
|
1293 others =>
|
|
1294 Has_Element (Container, First'Result)
|
|
1295 and P.Get (Positions (Container), First'Result) = 1);
|
|
1296
|
|
1297 function First_Element (Container : Set) return Element_Type with
|
|
1298 Global => null,
|
|
1299 Pre => not Is_Empty (Container),
|
|
1300 Post =>
|
|
1301 First_Element'Result = E.Get (Elements (Container), 1)
|
|
1302 and E_Smaller_Than_Range
|
|
1303 (Elements (Container),
|
|
1304 2,
|
|
1305 Length (Container),
|
|
1306 First_Element'Result);
|
|
1307
|
|
1308 function Last (Container : Set) return Cursor with
|
|
1309 Global => null,
|
|
1310 Contract_Cases =>
|
|
1311 (Length (Container) = 0 =>
|
|
1312 Last'Result = No_Element,
|
|
1313
|
|
1314 others =>
|
|
1315 Has_Element (Container, Last'Result)
|
|
1316 and P.Get (Positions (Container), Last'Result) =
|
|
1317 Length (Container));
|
|
1318
|
|
1319 function Last_Element (Container : Set) return Element_Type with
|
|
1320 Global => null,
|
|
1321 Pre => not Is_Empty (Container),
|
|
1322 Post =>
|
|
1323 Last_Element'Result = E.Get (Elements (Container), Length (Container))
|
|
1324 and E_Bigger_Than_Range
|
|
1325 (Elements (Container),
|
|
1326 1,
|
|
1327 Length (Container) - 1,
|
|
1328 Last_Element'Result);
|
|
1329
|
|
1330 function Next (Container : Set; Position : Cursor) return Cursor with
|
|
1331 Global => null,
|
|
1332 Pre =>
|
|
1333 Has_Element (Container, Position) or else Position = No_Element,
|
|
1334 Contract_Cases =>
|
|
1335 (Position = No_Element
|
|
1336 or else P.Get (Positions (Container), Position) = Length (Container)
|
|
1337 =>
|
|
1338 Next'Result = No_Element,
|
|
1339
|
|
1340 others =>
|
|
1341 Has_Element (Container, Next'Result)
|
|
1342 and then P.Get (Positions (Container), Next'Result) =
|
|
1343 P.Get (Positions (Container), Position) + 1);
|
|
1344
|
|
1345 procedure Next (Container : Set; Position : in out Cursor) with
|
|
1346 Global => null,
|
|
1347 Pre =>
|
|
1348 Has_Element (Container, Position) or else Position = No_Element,
|
|
1349 Contract_Cases =>
|
|
1350 (Position = No_Element
|
|
1351 or else P.Get (Positions (Container), Position) = Length (Container)
|
|
1352 =>
|
|
1353 Position = No_Element,
|
|
1354
|
|
1355 others =>
|
|
1356 Has_Element (Container, Position)
|
|
1357 and then P.Get (Positions (Container), Position) =
|
|
1358 P.Get (Positions (Container), Position'Old) + 1);
|
|
1359
|
|
1360 function Previous (Container : Set; Position : Cursor) return Cursor with
|
|
1361 Global => null,
|
|
1362 Pre =>
|
|
1363 Has_Element (Container, Position) or else Position = No_Element,
|
|
1364 Contract_Cases =>
|
|
1365 (Position = No_Element
|
|
1366 or else P.Get (Positions (Container), Position) = 1
|
|
1367 =>
|
|
1368 Previous'Result = No_Element,
|
|
1369
|
|
1370 others =>
|
|
1371 Has_Element (Container, Previous'Result)
|
|
1372 and then P.Get (Positions (Container), Previous'Result) =
|
|
1373 P.Get (Positions (Container), Position) - 1);
|
|
1374
|
|
1375 procedure Previous (Container : Set; Position : in out Cursor) with
|
|
1376 Global => null,
|
|
1377 Pre =>
|
|
1378 Has_Element (Container, Position) or else Position = No_Element,
|
|
1379 Contract_Cases =>
|
|
1380 (Position = No_Element
|
|
1381 or else P.Get (Positions (Container), Position) = 1
|
|
1382 =>
|
|
1383 Position = No_Element,
|
|
1384
|
|
1385 others =>
|
|
1386 Has_Element (Container, Position)
|
|
1387 and then P.Get (Positions (Container), Position) =
|
|
1388 P.Get (Positions (Container), Position'Old) - 1);
|
|
1389
|
|
1390 function Find (Container : Set; Item : Element_Type) return Cursor with
|
|
1391 Global => null,
|
|
1392 Contract_Cases =>
|
|
1393
|
|
1394 -- If Item is not contained in Container, Find returns No_Element
|
|
1395
|
|
1396 (not Contains (Model (Container), Item) =>
|
|
1397 not P.Has_Key (Positions (Container), Find'Result)
|
|
1398 and Find'Result = No_Element,
|
|
1399
|
|
1400 -- Otherwise, Find returns a valid cursor in Container
|
|
1401
|
|
1402 others =>
|
|
1403 P.Has_Key (Positions (Container), Find'Result)
|
|
1404 and P.Get (Positions (Container), Find'Result) =
|
|
1405 Find (Elements (Container), Item)
|
|
1406
|
|
1407 -- The element designated by the result of Find is Item
|
|
1408
|
|
1409 and Equivalent_Elements
|
|
1410 (Element (Container, Find'Result), Item));
|
|
1411
|
|
1412 function Floor (Container : Set; Item : Element_Type) return Cursor with
|
|
1413 Global => null,
|
|
1414 Contract_Cases =>
|
|
1415 (Length (Container) = 0 or else Item < First_Element (Container) =>
|
|
1416 Floor'Result = No_Element,
|
|
1417 others =>
|
|
1418 Has_Element (Container, Floor'Result)
|
|
1419 and
|
|
1420 not (Item < E.Get (Elements (Container),
|
|
1421 P.Get (Positions (Container), Floor'Result)))
|
|
1422 and E_Is_Find
|
|
1423 (Elements (Container),
|
|
1424 Item,
|
|
1425 P.Get (Positions (Container), Floor'Result)));
|
|
1426
|
|
1427 function Ceiling (Container : Set; Item : Element_Type) return Cursor with
|
|
1428 Global => null,
|
|
1429 Contract_Cases =>
|
|
1430 (Length (Container) = 0 or else Last_Element (Container) < Item =>
|
|
1431 Ceiling'Result = No_Element,
|
|
1432 others =>
|
|
1433 Has_Element (Container, Ceiling'Result)
|
|
1434 and
|
|
1435 not (E.Get (Elements (Container),
|
|
1436 P.Get (Positions (Container), Ceiling'Result)) <
|
|
1437 Item)
|
|
1438 and E_Is_Find
|
|
1439 (Elements (Container),
|
|
1440 Item,
|
|
1441 P.Get (Positions (Container), Ceiling'Result)));
|
|
1442
|
|
1443 function Contains (Container : Set; Item : Element_Type) return Boolean with
|
|
1444 Global => null,
|
|
1445 Post => Contains'Result = Contains (Model (Container), Item);
|
|
1446 pragma Annotate (GNATprove, Inline_For_Proof, Contains);
|
|
1447
|
|
1448 function Has_Element (Container : Set; Position : Cursor) return Boolean
|
|
1449 with
|
|
1450 Global => null,
|
|
1451 Post =>
|
|
1452 Has_Element'Result = P.Has_Key (Positions (Container), Position);
|
|
1453 pragma Annotate (GNATprove, Inline_For_Proof, Has_Element);
|
|
1454
|
|
1455 generic
|
|
1456 type Key_Type (<>) is private;
|
|
1457
|
|
1458 with function Key (Element : Element_Type) return Key_Type;
|
|
1459
|
|
1460 with function "<" (Left, Right : Key_Type) return Boolean is <>;
|
|
1461
|
|
1462 package Generic_Keys with SPARK_Mode is
|
|
1463
|
|
1464 function Equivalent_Keys (Left, Right : Key_Type) return Boolean with
|
|
1465 Global => null,
|
|
1466 Post =>
|
|
1467 Equivalent_Keys'Result = (not (Left < Right) and not (Right < Left));
|
|
1468 pragma Annotate (GNATprove, Inline_For_Proof, Equivalent_Keys);
|
|
1469
|
|
1470 package Formal_Model with Ghost is
|
|
1471 function E_Bigger_Than_Range
|
|
1472 (Container : E.Sequence;
|
|
1473 Fst : Positive_Count_Type;
|
|
1474 Lst : Count_Type;
|
|
1475 Key : Key_Type) return Boolean
|
|
1476 with
|
|
1477 Global => null,
|
|
1478 Pre => Lst <= E.Length (Container),
|
|
1479 Post =>
|
|
1480 E_Bigger_Than_Range'Result =
|
|
1481 (for all I in Fst .. Lst =>
|
|
1482 Generic_Keys.Key (E.Get (Container, I)) < Key);
|
|
1483 pragma Annotate (GNATprove, Inline_For_Proof, E_Bigger_Than_Range);
|
|
1484
|
|
1485 function E_Smaller_Than_Range
|
|
1486 (Container : E.Sequence;
|
|
1487 Fst : Positive_Count_Type;
|
|
1488 Lst : Count_Type;
|
|
1489 Key : Key_Type) return Boolean
|
|
1490 with
|
|
1491 Global => null,
|
|
1492 Pre => Lst <= E.Length (Container),
|
|
1493 Post =>
|
|
1494 E_Smaller_Than_Range'Result =
|
|
1495 (for all I in Fst .. Lst =>
|
|
1496 Key < Generic_Keys.Key (E.Get (Container, I)));
|
|
1497 pragma Annotate (GNATprove, Inline_For_Proof, E_Smaller_Than_Range);
|
|
1498
|
|
1499 function E_Is_Find
|
|
1500 (Container : E.Sequence;
|
|
1501 Key : Key_Type;
|
|
1502 Position : Count_Type) return Boolean
|
|
1503 with
|
|
1504 Global => null,
|
|
1505 Pre => Position - 1 <= E.Length (Container),
|
|
1506 Post =>
|
|
1507 E_Is_Find'Result =
|
|
1508
|
|
1509 ((if Position > 0 then
|
|
1510 E_Bigger_Than_Range (Container, 1, Position - 1, Key))
|
|
1511
|
|
1512 and (if Position < E.Length (Container) then
|
|
1513 E_Smaller_Than_Range
|
|
1514 (Container,
|
|
1515 Position + 1,
|
|
1516 E.Length (Container),
|
|
1517 Key)));
|
|
1518 pragma Annotate (GNATprove, Inline_For_Proof, E_Is_Find);
|
|
1519
|
|
1520 function Find
|
|
1521 (Container : E.Sequence;
|
|
1522 Key : Key_Type) return Count_Type
|
|
1523 -- Search for Key in Container
|
|
1524
|
|
1525 with
|
|
1526 Global => null,
|
|
1527 Post =>
|
|
1528 (if Find'Result > 0 then
|
|
1529 Find'Result <= E.Length (Container)
|
|
1530 and Equivalent_Keys
|
|
1531 (Key, Generic_Keys.Key (E.Get (Container, Find'Result)))
|
|
1532 and E_Is_Find (Container, Key, Find'Result));
|
|
1533
|
|
1534 function M_Included_Except
|
|
1535 (Left : M.Set;
|
|
1536 Right : M.Set;
|
|
1537 Key : Key_Type) return Boolean
|
|
1538 with
|
|
1539 Global => null,
|
|
1540 Post =>
|
|
1541 M_Included_Except'Result =
|
|
1542 (for all E of Left =>
|
|
1543 Contains (Right, E)
|
|
1544 or Equivalent_Keys (Generic_Keys.Key (E), Key));
|
|
1545 end Formal_Model;
|
|
1546 use Formal_Model;
|
|
1547
|
|
1548 function Key (Container : Set; Position : Cursor) return Key_Type with
|
|
1549 Global => null,
|
|
1550 Post => Key'Result = Key (Element (Container, Position));
|
|
1551 pragma Annotate (GNATprove, Inline_For_Proof, Key);
|
|
1552
|
|
1553 function Element (Container : Set; Key : Key_Type) return Element_Type
|
|
1554 with
|
|
1555 Global => null,
|
|
1556 Pre => Contains (Container, Key),
|
|
1557 Post =>
|
|
1558 Element'Result = Element (Container, Find (Container, Key));
|
|
1559 pragma Annotate (GNATprove, Inline_For_Proof, Element);
|
|
1560
|
|
1561 procedure Replace
|
|
1562 (Container : in out Set;
|
|
1563 Key : Key_Type;
|
|
1564 New_Item : Element_Type)
|
|
1565 with
|
|
1566 Global => null,
|
|
1567 Pre => Contains (Container, Key),
|
|
1568 Post =>
|
|
1569 Length (Container) = Length (Container)'Old
|
|
1570
|
|
1571 -- Key now maps to New_Item
|
|
1572
|
|
1573 and Element (Container, Key) = New_Item
|
|
1574
|
|
1575 -- New_Item is contained in Container
|
|
1576
|
|
1577 and Contains (Model (Container), New_Item)
|
|
1578
|
|
1579 -- Other elements are preserved
|
|
1580
|
|
1581 and M_Included_Except
|
|
1582 (Model (Container)'Old,
|
|
1583 Model (Container),
|
|
1584 Key)
|
|
1585 and M.Included_Except
|
|
1586 (Model (Container),
|
|
1587 Model (Container)'Old,
|
|
1588 New_Item)
|
|
1589
|
|
1590 -- Mapping from cursors to elements is preserved
|
|
1591
|
|
1592 and Mapping_Preserved_Except
|
|
1593 (E_Left => Elements (Container)'Old,
|
|
1594 E_Right => Elements (Container),
|
|
1595 P_Left => Positions (Container)'Old,
|
|
1596 P_Right => Positions (Container),
|
|
1597 Position => Find (Container, Key))
|
|
1598 and Positions (Container) = Positions (Container)'Old;
|
|
1599
|
|
1600 procedure Exclude (Container : in out Set; Key : Key_Type) with
|
|
1601 Global => null,
|
|
1602 Post => not Contains (Container, Key),
|
|
1603 Contract_Cases =>
|
|
1604
|
|
1605 -- If Key is not in Container, nothing is changed
|
|
1606
|
|
1607 (not Contains (Container, Key) =>
|
|
1608 Model (Container) = Model (Container)'Old
|
|
1609 and Elements (Container) = Elements (Container)'Old
|
|
1610 and Positions (Container) = Positions (Container)'Old,
|
|
1611
|
|
1612 -- Otherwise, Key is removed from Container
|
|
1613
|
|
1614 others =>
|
|
1615 Length (Container) = Length (Container)'Old - 1
|
|
1616
|
|
1617 -- Other elements are preserved
|
|
1618
|
|
1619 and Model (Container) <= Model (Container)'Old
|
|
1620 and M_Included_Except
|
|
1621 (Model (Container)'Old,
|
|
1622 Model (Container),
|
|
1623 Key)
|
|
1624
|
|
1625 -- The elements of Container located before Key are preserved
|
|
1626
|
|
1627 and E.Range_Equal
|
|
1628 (Left => Elements (Container)'Old,
|
|
1629 Right => Elements (Container),
|
|
1630 Fst => 1,
|
|
1631 Lst => Find (Elements (Container), Key)'Old - 1)
|
|
1632
|
|
1633 -- The elements located after Key are shifted by 1
|
|
1634
|
|
1635 and E.Range_Shifted
|
|
1636 (Left => Elements (Container),
|
|
1637 Right => Elements (Container)'Old,
|
|
1638 Fst => Find (Elements (Container), Key)'Old,
|
|
1639 Lst => Length (Container),
|
|
1640 Offset => 1)
|
|
1641
|
|
1642 -- A cursor has been removed from Container
|
|
1643
|
|
1644 and P_Positions_Shifted
|
|
1645 (Positions (Container),
|
|
1646 Positions (Container)'Old,
|
|
1647 Cut => Find (Elements (Container), Key)'Old));
|
|
1648
|
|
1649 procedure Delete (Container : in out Set; Key : Key_Type) with
|
|
1650 Global => null,
|
|
1651 Pre => Contains (Container, Key),
|
|
1652 Post =>
|
|
1653 Length (Container) = Length (Container)'Old - 1
|
|
1654
|
|
1655 -- Key is no longer in Container
|
|
1656
|
|
1657 and not Contains (Container, Key)
|
|
1658
|
|
1659 -- Other elements are preserved
|
|
1660
|
|
1661 and Model (Container) <= Model (Container)'Old
|
|
1662 and M_Included_Except
|
|
1663 (Model (Container)'Old,
|
|
1664 Model (Container),
|
|
1665 Key)
|
|
1666
|
|
1667 -- The elements of Container located before Key are preserved
|
|
1668
|
|
1669 and E.Range_Equal
|
|
1670 (Left => Elements (Container)'Old,
|
|
1671 Right => Elements (Container),
|
|
1672 Fst => 1,
|
|
1673 Lst => Find (Elements (Container), Key)'Old - 1)
|
|
1674
|
|
1675 -- The elements located after Key are shifted by 1
|
|
1676
|
|
1677 and E.Range_Shifted
|
|
1678 (Left => Elements (Container),
|
|
1679 Right => Elements (Container)'Old,
|
|
1680 Fst => Find (Elements (Container), Key)'Old,
|
|
1681 Lst => Length (Container),
|
|
1682 Offset => 1)
|
|
1683
|
|
1684 -- A cursor has been removed from Container
|
|
1685
|
|
1686 and P_Positions_Shifted
|
|
1687 (Positions (Container),
|
|
1688 Positions (Container)'Old,
|
|
1689 Cut => Find (Elements (Container), Key)'Old);
|
|
1690
|
|
1691 function Find (Container : Set; Key : Key_Type) return Cursor with
|
|
1692 Global => null,
|
|
1693 Contract_Cases =>
|
|
1694
|
|
1695 -- If Key is not contained in Container, Find returns No_Element
|
|
1696
|
|
1697 ((for all E of Model (Container) =>
|
|
1698 not Equivalent_Keys (Key, Generic_Keys.Key (E))) =>
|
|
1699 not P.Has_Key (Positions (Container), Find'Result)
|
|
1700 and Find'Result = No_Element,
|
|
1701
|
|
1702 -- Otherwise, Find returns a valid cursor in Container
|
|
1703
|
|
1704 others =>
|
|
1705 P.Has_Key (Positions (Container), Find'Result)
|
|
1706 and P.Get (Positions (Container), Find'Result) =
|
|
1707 Find (Elements (Container), Key)
|
|
1708
|
|
1709 -- The element designated by the result of Find is Key
|
|
1710
|
|
1711 and Equivalent_Keys
|
|
1712 (Generic_Keys.Key (Element (Container, Find'Result)), Key));
|
|
1713
|
|
1714 function Floor (Container : Set; Key : Key_Type) return Cursor with
|
|
1715 Global => null,
|
|
1716 Contract_Cases =>
|
|
1717 (Length (Container) = 0
|
|
1718 or else Key < Generic_Keys.Key (First_Element (Container)) =>
|
|
1719 Floor'Result = No_Element,
|
|
1720 others =>
|
|
1721 Has_Element (Container, Floor'Result)
|
|
1722 and
|
|
1723 not (Key <
|
|
1724 Generic_Keys.Key
|
|
1725 (E.Get (Elements (Container),
|
|
1726 P.Get (Positions (Container), Floor'Result))))
|
|
1727 and E_Is_Find
|
|
1728 (Elements (Container),
|
|
1729 Key,
|
|
1730 P.Get (Positions (Container), Floor'Result)));
|
|
1731
|
|
1732 function Ceiling (Container : Set; Key : Key_Type) return Cursor with
|
|
1733 Global => null,
|
|
1734 Contract_Cases =>
|
|
1735 (Length (Container) = 0
|
|
1736 or else Generic_Keys.Key (Last_Element (Container)) < Key =>
|
|
1737 Ceiling'Result = No_Element,
|
|
1738 others =>
|
|
1739 Has_Element (Container, Ceiling'Result)
|
|
1740 and
|
|
1741 not (Generic_Keys.Key
|
|
1742 (E.Get (Elements (Container),
|
|
1743 P.Get (Positions (Container), Ceiling'Result)))
|
|
1744 < Key)
|
|
1745 and E_Is_Find
|
|
1746 (Elements (Container),
|
|
1747 Key,
|
|
1748 P.Get (Positions (Container), Ceiling'Result)));
|
|
1749
|
|
1750 function Contains (Container : Set; Key : Key_Type) return Boolean with
|
|
1751 Global => null,
|
|
1752 Post =>
|
|
1753 Contains'Result =
|
|
1754 (for some E of Model (Container) =>
|
|
1755 Equivalent_Keys (Key, Generic_Keys.Key (E)));
|
|
1756
|
|
1757 end Generic_Keys;
|
|
1758
|
|
1759 private
|
|
1760 pragma SPARK_Mode (Off);
|
|
1761
|
|
1762 pragma Inline (Next);
|
|
1763 pragma Inline (Previous);
|
|
1764
|
|
1765 type Node_Type is record
|
|
1766 Has_Element : Boolean := False;
|
|
1767 Parent : Count_Type := 0;
|
|
1768 Left : Count_Type := 0;
|
|
1769 Right : Count_Type := 0;
|
|
1770 Color : Red_Black_Trees.Color_Type;
|
|
1771 Element : Element_Type;
|
|
1772 end record;
|
|
1773
|
|
1774 package Tree_Types is
|
|
1775 new Red_Black_Trees.Generic_Bounded_Tree_Types (Node_Type);
|
|
1776
|
|
1777 type Set (Capacity : Count_Type) is
|
|
1778 new Tree_Types.Tree_Type (Capacity) with null record;
|
|
1779
|
|
1780 use Red_Black_Trees;
|
|
1781
|
|
1782 Empty_Set : constant Set := (Capacity => 0, others => <>);
|
|
1783
|
|
1784 end Ada.Containers.Formal_Ordered_Sets;
|