annotate gcc/ada/libgnat/a-cfhase.ads @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 ------------------------------------------------------------------------------
kono
parents:
diff changeset
2 -- --
kono
parents:
diff changeset
3 -- GNAT LIBRARY COMPONENTS --
kono
parents:
diff changeset
4 -- --
kono
parents:
diff changeset
5 -- A D A . C O N T A I N E R S . F O R M A L _ H A S H E D _ S E T S --
kono
parents:
diff changeset
6 -- --
kono
parents:
diff changeset
7 -- S p e c --
kono
parents:
diff changeset
8 -- --
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
9 -- Copyright (C) 2004-2019, Free Software Foundation, Inc. --
111
kono
parents:
diff changeset
10 -- --
kono
parents:
diff changeset
11 -- This specification is derived from the Ada Reference Manual for use with --
kono
parents:
diff changeset
12 -- GNAT. The copyright notice above, and the license provisions that follow --
kono
parents:
diff changeset
13 -- apply solely to the contents of the part following the private keyword. --
kono
parents:
diff changeset
14 -- --
kono
parents:
diff changeset
15 -- GNAT is free software; you can redistribute it and/or modify it under --
kono
parents:
diff changeset
16 -- terms of the GNU General Public License as published by the Free Soft- --
kono
parents:
diff changeset
17 -- ware Foundation; either version 3, or (at your option) any later ver- --
kono
parents:
diff changeset
18 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
kono
parents:
diff changeset
19 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
kono
parents:
diff changeset
20 -- or FITNESS FOR A PARTICULAR PURPOSE. --
kono
parents:
diff changeset
21 -- --
kono
parents:
diff changeset
22 -- As a special exception under Section 7 of GPL version 3, you are granted --
kono
parents:
diff changeset
23 -- additional permissions described in the GCC Runtime Library Exception, --
kono
parents:
diff changeset
24 -- version 3.1, as published by the Free Software Foundation. --
kono
parents:
diff changeset
25 -- --
kono
parents:
diff changeset
26 -- You should have received a copy of the GNU General Public License and --
kono
parents:
diff changeset
27 -- a copy of the GCC Runtime Library Exception along with this program; --
kono
parents:
diff changeset
28 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
kono
parents:
diff changeset
29 -- <http://www.gnu.org/licenses/>. --
kono
parents:
diff changeset
30 ------------------------------------------------------------------------------
kono
parents:
diff changeset
31
kono
parents:
diff changeset
32 -- This spec is derived from package Ada.Containers.Bounded_Hashed_Sets in the
kono
parents:
diff changeset
33 -- Ada 2012 RM. The modifications are meant to facilitate formal proofs by
kono
parents:
diff changeset
34 -- making it easier to express properties, and by making the specification of
kono
parents:
diff changeset
35 -- this unit compatible with SPARK 2014. Note that the API of this unit may be
kono
parents:
diff changeset
36 -- subject to incompatible changes as SPARK 2014 evolves.
kono
parents:
diff changeset
37
kono
parents:
diff changeset
38 -- The modifications are:
kono
parents:
diff changeset
39
kono
parents:
diff changeset
40 -- A parameter for the container is added to every function reading the
kono
parents:
diff changeset
41 -- content of a container: Element, Next, Query_Element, Has_Element, Key,
kono
parents:
diff changeset
42 -- Iterate, Equivalent_Elements. This change is motivated by the need to
kono
parents:
diff changeset
43 -- have cursors which are valid on different containers (typically a
kono
parents:
diff changeset
44 -- container C and its previous version C'Old) for expressing properties,
kono
parents:
diff changeset
45 -- which is not possible if cursors encapsulate an access to the underlying
kono
parents:
diff changeset
46 -- container.
kono
parents:
diff changeset
47
kono
parents:
diff changeset
48 with Ada.Containers.Functional_Maps;
kono
parents:
diff changeset
49 with Ada.Containers.Functional_Sets;
kono
parents:
diff changeset
50 with Ada.Containers.Functional_Vectors;
kono
parents:
diff changeset
51 private with Ada.Containers.Hash_Tables;
kono
parents:
diff changeset
52
kono
parents:
diff changeset
53 generic
kono
parents:
diff changeset
54 type Element_Type is private;
kono
parents:
diff changeset
55
kono
parents:
diff changeset
56 with function Hash (Element : Element_Type) return Hash_Type;
kono
parents:
diff changeset
57
kono
parents:
diff changeset
58 with function Equivalent_Elements
kono
parents:
diff changeset
59 (Left : Element_Type;
kono
parents:
diff changeset
60 Right : Element_Type) return Boolean is "=";
kono
parents:
diff changeset
61
kono
parents:
diff changeset
62 package Ada.Containers.Formal_Hashed_Sets with
kono
parents:
diff changeset
63 SPARK_Mode
kono
parents:
diff changeset
64 is
kono
parents:
diff changeset
65 pragma Annotate (CodePeer, Skip_Analysis);
kono
parents:
diff changeset
66
kono
parents:
diff changeset
67 type Set (Capacity : Count_Type; Modulus : Hash_Type) is private with
kono
parents:
diff changeset
68 Iterable => (First => First,
kono
parents:
diff changeset
69 Next => Next,
kono
parents:
diff changeset
70 Has_Element => Has_Element,
kono
parents:
diff changeset
71 Element => Element),
kono
parents:
diff changeset
72 Default_Initial_Condition => Is_Empty (Set);
kono
parents:
diff changeset
73 pragma Preelaborable_Initialization (Set);
kono
parents:
diff changeset
74
kono
parents:
diff changeset
75 type Cursor is record
kono
parents:
diff changeset
76 Node : Count_Type;
kono
parents:
diff changeset
77 end record;
kono
parents:
diff changeset
78
kono
parents:
diff changeset
79 No_Element : constant Cursor := (Node => 0);
kono
parents:
diff changeset
80
kono
parents:
diff changeset
81 function Length (Container : Set) return Count_Type with
kono
parents:
diff changeset
82 Global => null,
kono
parents:
diff changeset
83 Post => Length'Result <= Container.Capacity;
kono
parents:
diff changeset
84
kono
parents:
diff changeset
85 pragma Unevaluated_Use_Of_Old (Allow);
kono
parents:
diff changeset
86
kono
parents:
diff changeset
87 package Formal_Model with Ghost is
kono
parents:
diff changeset
88 subtype Positive_Count_Type is Count_Type range 1 .. Count_Type'Last;
kono
parents:
diff changeset
89
kono
parents:
diff changeset
90 package M is new Ada.Containers.Functional_Sets
kono
parents:
diff changeset
91 (Element_Type => Element_Type,
kono
parents:
diff changeset
92 Equivalent_Elements => Equivalent_Elements);
kono
parents:
diff changeset
93
kono
parents:
diff changeset
94 function "="
kono
parents:
diff changeset
95 (Left : M.Set;
kono
parents:
diff changeset
96 Right : M.Set) return Boolean renames M."=";
kono
parents:
diff changeset
97
kono
parents:
diff changeset
98 function "<="
kono
parents:
diff changeset
99 (Left : M.Set;
kono
parents:
diff changeset
100 Right : M.Set) return Boolean renames M."<=";
kono
parents:
diff changeset
101
kono
parents:
diff changeset
102 package E is new Ada.Containers.Functional_Vectors
kono
parents:
diff changeset
103 (Element_Type => Element_Type,
kono
parents:
diff changeset
104 Index_Type => Positive_Count_Type);
kono
parents:
diff changeset
105
kono
parents:
diff changeset
106 function "="
kono
parents:
diff changeset
107 (Left : E.Sequence;
kono
parents:
diff changeset
108 Right : E.Sequence) return Boolean renames E."=";
kono
parents:
diff changeset
109
kono
parents:
diff changeset
110 function "<"
kono
parents:
diff changeset
111 (Left : E.Sequence;
kono
parents:
diff changeset
112 Right : E.Sequence) return Boolean renames E."<";
kono
parents:
diff changeset
113
kono
parents:
diff changeset
114 function "<="
kono
parents:
diff changeset
115 (Left : E.Sequence;
kono
parents:
diff changeset
116 Right : E.Sequence) return Boolean renames E."<=";
kono
parents:
diff changeset
117
kono
parents:
diff changeset
118 function Find
kono
parents:
diff changeset
119 (Container : E.Sequence;
kono
parents:
diff changeset
120 Item : Element_Type) return Count_Type
kono
parents:
diff changeset
121 -- Search for Item in Container
kono
parents:
diff changeset
122
kono
parents:
diff changeset
123 with
kono
parents:
diff changeset
124 Global => null,
kono
parents:
diff changeset
125 Post =>
kono
parents:
diff changeset
126 (if Find'Result > 0 then
kono
parents:
diff changeset
127 Find'Result <= E.Length (Container)
kono
parents:
diff changeset
128 and Equivalent_Elements
kono
parents:
diff changeset
129 (Item, E.Get (Container, Find'Result)));
kono
parents:
diff changeset
130
kono
parents:
diff changeset
131 function E_Elements_Included
kono
parents:
diff changeset
132 (Left : E.Sequence;
kono
parents:
diff changeset
133 Right : E.Sequence) return Boolean
kono
parents:
diff changeset
134 -- The elements of Left are contained in Right
kono
parents:
diff changeset
135
kono
parents:
diff changeset
136 with
kono
parents:
diff changeset
137 Global => null,
kono
parents:
diff changeset
138 Post =>
kono
parents:
diff changeset
139 E_Elements_Included'Result =
kono
parents:
diff changeset
140 (for all I in 1 .. E.Length (Left) =>
kono
parents:
diff changeset
141 Find (Right, E.Get (Left, I)) > 0
kono
parents:
diff changeset
142 and then E.Get (Right, Find (Right, E.Get (Left, I))) =
kono
parents:
diff changeset
143 E.Get (Left, I));
kono
parents:
diff changeset
144 pragma Annotate (GNATprove, Inline_For_Proof, E_Elements_Included);
kono
parents:
diff changeset
145
kono
parents:
diff changeset
146 function E_Elements_Included
kono
parents:
diff changeset
147 (Left : E.Sequence;
kono
parents:
diff changeset
148 Model : M.Set;
kono
parents:
diff changeset
149 Right : E.Sequence) return Boolean
kono
parents:
diff changeset
150 -- The elements of Container contained in Model are in Right
kono
parents:
diff changeset
151
kono
parents:
diff changeset
152 with
kono
parents:
diff changeset
153 Global => null,
kono
parents:
diff changeset
154 Post =>
kono
parents:
diff changeset
155 E_Elements_Included'Result =
kono
parents:
diff changeset
156 (for all I in 1 .. E.Length (Left) =>
kono
parents:
diff changeset
157 (if M.Contains (Model, E.Get (Left, I)) then
kono
parents:
diff changeset
158 Find (Right, E.Get (Left, I)) > 0
kono
parents:
diff changeset
159 and then E.Get (Right, Find (Right, E.Get (Left, I))) =
kono
parents:
diff changeset
160 E.Get (Left, I)));
kono
parents:
diff changeset
161 pragma Annotate (GNATprove, Inline_For_Proof, E_Elements_Included);
kono
parents:
diff changeset
162
kono
parents:
diff changeset
163 function E_Elements_Included
kono
parents:
diff changeset
164 (Container : E.Sequence;
kono
parents:
diff changeset
165 Model : M.Set;
kono
parents:
diff changeset
166 Left : E.Sequence;
kono
parents:
diff changeset
167 Right : E.Sequence) return Boolean
kono
parents:
diff changeset
168 -- The elements of Container contained in Model are in Left and others
kono
parents:
diff changeset
169 -- are in Right.
kono
parents:
diff changeset
170
kono
parents:
diff changeset
171 with
kono
parents:
diff changeset
172 Global => null,
kono
parents:
diff changeset
173 Post =>
kono
parents:
diff changeset
174 E_Elements_Included'Result =
kono
parents:
diff changeset
175 (for all I in 1 .. E.Length (Container) =>
kono
parents:
diff changeset
176 (if M.Contains (Model, E.Get (Container, I)) then
kono
parents:
diff changeset
177 Find (Left, E.Get (Container, I)) > 0
kono
parents:
diff changeset
178 and then E.Get (Left, Find (Left, E.Get (Container, I))) =
kono
parents:
diff changeset
179 E.Get (Container, I)
kono
parents:
diff changeset
180 else
kono
parents:
diff changeset
181 Find (Right, E.Get (Container, I)) > 0
kono
parents:
diff changeset
182 and then E.Get
kono
parents:
diff changeset
183 (Right, Find (Right, E.Get (Container, I))) =
kono
parents:
diff changeset
184 E.Get (Container, I)));
kono
parents:
diff changeset
185 pragma Annotate (GNATprove, Inline_For_Proof, E_Elements_Included);
kono
parents:
diff changeset
186
kono
parents:
diff changeset
187 package P is new Ada.Containers.Functional_Maps
kono
parents:
diff changeset
188 (Key_Type => Cursor,
kono
parents:
diff changeset
189 Element_Type => Positive_Count_Type,
kono
parents:
diff changeset
190 Equivalent_Keys => "=",
kono
parents:
diff changeset
191 Enable_Handling_Of_Equivalence => False);
kono
parents:
diff changeset
192
kono
parents:
diff changeset
193 function "="
kono
parents:
diff changeset
194 (Left : P.Map;
kono
parents:
diff changeset
195 Right : P.Map) return Boolean renames P."=";
kono
parents:
diff changeset
196
kono
parents:
diff changeset
197 function "<="
kono
parents:
diff changeset
198 (Left : P.Map;
kono
parents:
diff changeset
199 Right : P.Map) return Boolean renames P."<=";
kono
parents:
diff changeset
200
kono
parents:
diff changeset
201 function Mapping_Preserved
kono
parents:
diff changeset
202 (E_Left : E.Sequence;
kono
parents:
diff changeset
203 E_Right : E.Sequence;
kono
parents:
diff changeset
204 P_Left : P.Map;
kono
parents:
diff changeset
205 P_Right : P.Map) return Boolean
kono
parents:
diff changeset
206 with
kono
parents:
diff changeset
207 Ghost,
kono
parents:
diff changeset
208 Global => null,
kono
parents:
diff changeset
209 Post =>
kono
parents:
diff changeset
210 (if Mapping_Preserved'Result then
kono
parents:
diff changeset
211
kono
parents:
diff changeset
212 -- Right contains all the cursors of Left
kono
parents:
diff changeset
213
kono
parents:
diff changeset
214 P.Keys_Included (P_Left, P_Right)
kono
parents:
diff changeset
215
kono
parents:
diff changeset
216 -- Right contains all the elements of Left
kono
parents:
diff changeset
217
kono
parents:
diff changeset
218 and E_Elements_Included (E_Left, E_Right)
kono
parents:
diff changeset
219
kono
parents:
diff changeset
220 -- Mappings from cursors to elements induced by E_Left, P_Left
kono
parents:
diff changeset
221 -- and E_Right, P_Right are the same.
kono
parents:
diff changeset
222
kono
parents:
diff changeset
223 and (for all C of P_Left =>
kono
parents:
diff changeset
224 E.Get (E_Left, P.Get (P_Left, C)) =
kono
parents:
diff changeset
225 E.Get (E_Right, P.Get (P_Right, C))));
kono
parents:
diff changeset
226
kono
parents:
diff changeset
227 function Mapping_Preserved_Except
kono
parents:
diff changeset
228 (E_Left : E.Sequence;
kono
parents:
diff changeset
229 E_Right : E.Sequence;
kono
parents:
diff changeset
230 P_Left : P.Map;
kono
parents:
diff changeset
231 P_Right : P.Map;
kono
parents:
diff changeset
232 Position : Cursor) return Boolean
kono
parents:
diff changeset
233 with
kono
parents:
diff changeset
234 Ghost,
kono
parents:
diff changeset
235 Global => null,
kono
parents:
diff changeset
236 Post =>
kono
parents:
diff changeset
237 (if Mapping_Preserved_Except'Result then
kono
parents:
diff changeset
238
kono
parents:
diff changeset
239 -- Right contains all the cursors of Left
kono
parents:
diff changeset
240
kono
parents:
diff changeset
241 P.Keys_Included (P_Left, P_Right)
kono
parents:
diff changeset
242
kono
parents:
diff changeset
243 -- Mappings from cursors to elements induced by E_Left, P_Left
kono
parents:
diff changeset
244 -- and E_Right, P_Right are the same except for Position.
kono
parents:
diff changeset
245
kono
parents:
diff changeset
246 and (for all C of P_Left =>
kono
parents:
diff changeset
247 (if C /= Position then
kono
parents:
diff changeset
248 E.Get (E_Left, P.Get (P_Left, C)) =
kono
parents:
diff changeset
249 E.Get (E_Right, P.Get (P_Right, C)))));
kono
parents:
diff changeset
250
kono
parents:
diff changeset
251 function Model (Container : Set) return M.Set with
kono
parents:
diff changeset
252 -- The high-level model of a set is a set of elements. Neither cursors
kono
parents:
diff changeset
253 -- nor order of elements are represented in this model. Elements are
kono
parents:
diff changeset
254 -- modeled up to equivalence.
kono
parents:
diff changeset
255
kono
parents:
diff changeset
256 Ghost,
kono
parents:
diff changeset
257 Global => null,
kono
parents:
diff changeset
258 Post => M.Length (Model'Result) = Length (Container);
kono
parents:
diff changeset
259
kono
parents:
diff changeset
260 function Elements (Container : Set) return E.Sequence with
kono
parents:
diff changeset
261 -- The Elements sequence represents the underlying list structure of
kono
parents:
diff changeset
262 -- sets that is used for iteration. It stores the actual values of
kono
parents:
diff changeset
263 -- elements in the set. It does not model cursors.
kono
parents:
diff changeset
264
kono
parents:
diff changeset
265 Ghost,
kono
parents:
diff changeset
266 Global => null,
kono
parents:
diff changeset
267 Post =>
kono
parents:
diff changeset
268 E.Length (Elements'Result) = Length (Container)
kono
parents:
diff changeset
269
kono
parents:
diff changeset
270 -- It only contains keys contained in Model
kono
parents:
diff changeset
271
kono
parents:
diff changeset
272 and (for all Item of Elements'Result =>
kono
parents:
diff changeset
273 M.Contains (Model (Container), Item))
kono
parents:
diff changeset
274
kono
parents:
diff changeset
275 -- It contains all the elements contained in Model
kono
parents:
diff changeset
276
kono
parents:
diff changeset
277 and (for all Item of Model (Container) =>
kono
parents:
diff changeset
278 (Find (Elements'Result, Item) > 0
kono
parents:
diff changeset
279 and then Equivalent_Elements
kono
parents:
diff changeset
280 (E.Get (Elements'Result,
kono
parents:
diff changeset
281 Find (Elements'Result, Item)),
kono
parents:
diff changeset
282 Item)))
kono
parents:
diff changeset
283
kono
parents:
diff changeset
284 -- It has no duplicate
kono
parents:
diff changeset
285
kono
parents:
diff changeset
286 and (for all I in 1 .. Length (Container) =>
kono
parents:
diff changeset
287 Find (Elements'Result, E.Get (Elements'Result, I)) = I)
kono
parents:
diff changeset
288
kono
parents:
diff changeset
289 and (for all I in 1 .. Length (Container) =>
kono
parents:
diff changeset
290 (for all J in 1 .. Length (Container) =>
kono
parents:
diff changeset
291 (if Equivalent_Elements
kono
parents:
diff changeset
292 (E.Get (Elements'Result, I),
kono
parents:
diff changeset
293 E.Get (Elements'Result, J))
kono
parents:
diff changeset
294 then I = J)));
kono
parents:
diff changeset
295 pragma Annotate (GNATprove, Iterable_For_Proof, "Model", Elements);
kono
parents:
diff changeset
296
kono
parents:
diff changeset
297 function Positions (Container : Set) return P.Map with
kono
parents:
diff changeset
298 -- The Positions map is used to model cursors. It only contains valid
kono
parents:
diff changeset
299 -- cursors and maps them to their position in the container.
kono
parents:
diff changeset
300
kono
parents:
diff changeset
301 Ghost,
kono
parents:
diff changeset
302 Global => null,
kono
parents:
diff changeset
303 Post =>
kono
parents:
diff changeset
304 not P.Has_Key (Positions'Result, No_Element)
kono
parents:
diff changeset
305
kono
parents:
diff changeset
306 -- Positions of cursors are smaller than the container's length
kono
parents:
diff changeset
307
kono
parents:
diff changeset
308 and then
kono
parents:
diff changeset
309 (for all I of Positions'Result =>
kono
parents:
diff changeset
310 P.Get (Positions'Result, I) in 1 .. Length (Container)
kono
parents:
diff changeset
311
kono
parents:
diff changeset
312 -- No two cursors have the same position. Note that we do not
kono
parents:
diff changeset
313 -- state that there is a cursor in the map for each position, as
kono
parents:
diff changeset
314 -- it is rarely needed.
kono
parents:
diff changeset
315
kono
parents:
diff changeset
316 and then
kono
parents:
diff changeset
317 (for all J of Positions'Result =>
kono
parents:
diff changeset
318 (if P.Get (Positions'Result, I) = P.Get (Positions'Result, J)
kono
parents:
diff changeset
319 then I = J)));
kono
parents:
diff changeset
320
kono
parents:
diff changeset
321 procedure Lift_Abstraction_Level (Container : Set) with
kono
parents:
diff changeset
322 -- Lift_Abstraction_Level is a ghost procedure that does nothing but
kono
parents:
diff changeset
323 -- assume that we can access the same elements by iterating over
kono
parents:
diff changeset
324 -- positions or cursors.
kono
parents:
diff changeset
325 -- This information is not generally useful except when switching from
kono
parents:
diff changeset
326 -- a low-level, cursor-aware view of a container, to a high-level,
kono
parents:
diff changeset
327 -- position-based view.
kono
parents:
diff changeset
328
kono
parents:
diff changeset
329 Ghost,
kono
parents:
diff changeset
330 Global => null,
kono
parents:
diff changeset
331 Post =>
kono
parents:
diff changeset
332 (for all Item of Elements (Container) =>
kono
parents:
diff changeset
333 (for some I of Positions (Container) =>
kono
parents:
diff changeset
334 E.Get (Elements (Container), P.Get (Positions (Container), I)) =
kono
parents:
diff changeset
335 Item));
kono
parents:
diff changeset
336
kono
parents:
diff changeset
337 function Contains
kono
parents:
diff changeset
338 (C : M.Set;
kono
parents:
diff changeset
339 K : Element_Type) return Boolean renames M.Contains;
kono
parents:
diff changeset
340 -- To improve readability of contracts, we rename the function used to
kono
parents:
diff changeset
341 -- search for an element in the model to Contains.
kono
parents:
diff changeset
342
kono
parents:
diff changeset
343 end Formal_Model;
kono
parents:
diff changeset
344 use Formal_Model;
kono
parents:
diff changeset
345
kono
parents:
diff changeset
346 Empty_Set : constant Set;
kono
parents:
diff changeset
347
kono
parents:
diff changeset
348 function "=" (Left, Right : Set) return Boolean with
kono
parents:
diff changeset
349 Global => null,
kono
parents:
diff changeset
350 Post =>
kono
parents:
diff changeset
351 "="'Result =
kono
parents:
diff changeset
352 (Length (Left) = Length (Right)
kono
parents:
diff changeset
353 and E_Elements_Included (Elements (Left), Elements (Right)))
kono
parents:
diff changeset
354 and
kono
parents:
diff changeset
355 "="'Result =
kono
parents:
diff changeset
356 (E_Elements_Included (Elements (Left), Elements (Right))
kono
parents:
diff changeset
357 and E_Elements_Included (Elements (Right), Elements (Left)));
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
358 -- For each element in Left, set equality attempts to find the equal
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
359 -- element in Right; if a search fails, then set equality immediately
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
360 -- returns False. The search works by calling Hash to find the bucket in
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
361 -- the Right set that corresponds to the Left element. If the bucket is
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
362 -- non-empty, the search calls the generic formal element equality operator
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
363 -- to compare the element (in Left) to the element of each node in the
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
364 -- bucket (in Right); the search terminates when a matching node in the
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
365 -- bucket is found, or the nodes in the bucket are exhausted. (Note that
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
366 -- element equality is called here, not Equivalent_Elements. Set equality
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
367 -- is the only operation in which element equality is used. Compare set
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
368 -- equality to Equivalent_Sets, which does call Equivalent_Elements.)
111
kono
parents:
diff changeset
369
kono
parents:
diff changeset
370 function Equivalent_Sets (Left, Right : Set) return Boolean with
kono
parents:
diff changeset
371 Global => null,
kono
parents:
diff changeset
372 Post => Equivalent_Sets'Result = (Model (Left) = Model (Right));
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
373 -- Similar to set equality, with the difference that the element in Left is
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
374 -- compared to the elements in Right using the generic formal
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
375 -- Equivalent_Elements operation instead of element equality.
111
kono
parents:
diff changeset
376
kono
parents:
diff changeset
377 function To_Set (New_Item : Element_Type) return Set with
kono
parents:
diff changeset
378 Global => null,
kono
parents:
diff changeset
379 Post =>
kono
parents:
diff changeset
380 M.Is_Singleton (Model (To_Set'Result), New_Item)
kono
parents:
diff changeset
381 and Length (To_Set'Result) = 1
kono
parents:
diff changeset
382 and E.Get (Elements (To_Set'Result), 1) = New_Item;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
383 -- Constructs a singleton set comprising New_Element. To_Set calls Hash to
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
384 -- determine the bucket for New_Item.
111
kono
parents:
diff changeset
385
kono
parents:
diff changeset
386 function Capacity (Container : Set) return Count_Type with
kono
parents:
diff changeset
387 Global => null,
kono
parents:
diff changeset
388 Post => Capacity'Result = Container.Capacity;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
389 -- Returns the current capacity of the set. Capacity is the maximum length
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
390 -- before which rehashing in guaranteed not to occur.
111
kono
parents:
diff changeset
391
kono
parents:
diff changeset
392 procedure Reserve_Capacity
kono
parents:
diff changeset
393 (Container : in out Set;
kono
parents:
diff changeset
394 Capacity : Count_Type)
kono
parents:
diff changeset
395 with
kono
parents:
diff changeset
396 Global => null,
kono
parents:
diff changeset
397 Pre => Capacity <= Container.Capacity,
kono
parents:
diff changeset
398 Post =>
kono
parents:
diff changeset
399 Model (Container) = Model (Container)'Old
kono
parents:
diff changeset
400 and Length (Container)'Old = Length (Container)
kono
parents:
diff changeset
401
kono
parents:
diff changeset
402 -- Actual elements are preserved
kono
parents:
diff changeset
403
kono
parents:
diff changeset
404 and E_Elements_Included
kono
parents:
diff changeset
405 (Elements (Container), Elements (Container)'Old)
kono
parents:
diff changeset
406 and E_Elements_Included
kono
parents:
diff changeset
407 (Elements (Container)'Old, Elements (Container));
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
408 -- If the value of the Capacity actual parameter is less or equal to
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
409 -- Container.Capacity, then the operation has no effect. Otherwise it
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
410 -- raises Capacity_Error (as no expansion of capacity is possible for a
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
411 -- bounded form).
111
kono
parents:
diff changeset
412
kono
parents:
diff changeset
413 function Is_Empty (Container : Set) return Boolean with
kono
parents:
diff changeset
414 Global => null,
kono
parents:
diff changeset
415 Post => Is_Empty'Result = (Length (Container) = 0);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
416 -- Equivalent to Length (Container) = 0
111
kono
parents:
diff changeset
417
kono
parents:
diff changeset
418 procedure Clear (Container : in out Set) with
kono
parents:
diff changeset
419 Global => null,
kono
parents:
diff changeset
420 Post => Length (Container) = 0 and M.Is_Empty (Model (Container));
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
421 -- Removes all of the items from the set. This will deallocate all memory
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
422 -- associated with this set.
111
kono
parents:
diff changeset
423
kono
parents:
diff changeset
424 procedure Assign (Target : in out Set; Source : Set) with
kono
parents:
diff changeset
425 Global => null,
kono
parents:
diff changeset
426 Pre => Target.Capacity >= Length (Source),
kono
parents:
diff changeset
427 Post =>
kono
parents:
diff changeset
428 Model (Target) = Model (Source)
kono
parents:
diff changeset
429 and Length (Target) = Length (Source)
kono
parents:
diff changeset
430
kono
parents:
diff changeset
431 -- Actual elements are preserved
kono
parents:
diff changeset
432
kono
parents:
diff changeset
433 and E_Elements_Included (Elements (Target), Elements (Source))
kono
parents:
diff changeset
434 and E_Elements_Included (Elements (Source), Elements (Target));
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
435 -- If Target denotes the same object as Source, then the operation has no
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
436 -- effect. If the Target capacity is less than the Source length, then
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
437 -- Assign raises Capacity_Error. Otherwise, Assign clears Target and then
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
438 -- copies the (active) elements from Source to Target.
111
kono
parents:
diff changeset
439
kono
parents:
diff changeset
440 function Copy
kono
parents:
diff changeset
441 (Source : Set;
kono
parents:
diff changeset
442 Capacity : Count_Type := 0) return Set
kono
parents:
diff changeset
443 with
kono
parents:
diff changeset
444 Global => null,
kono
parents:
diff changeset
445 Pre => Capacity = 0 or else Capacity >= Source.Capacity,
kono
parents:
diff changeset
446 Post =>
kono
parents:
diff changeset
447 Model (Copy'Result) = Model (Source)
kono
parents:
diff changeset
448 and Elements (Copy'Result) = Elements (Source)
kono
parents:
diff changeset
449 and Positions (Copy'Result) = Positions (Source)
kono
parents:
diff changeset
450 and (if Capacity = 0 then
kono
parents:
diff changeset
451 Copy'Result.Capacity = Source.Capacity
kono
parents:
diff changeset
452 else
kono
parents:
diff changeset
453 Copy'Result.Capacity = Capacity);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
454 -- Constructs a new set object whose elements correspond to Source. If the
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
455 -- Capacity parameter is 0, then the capacity of the result is the same as
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
456 -- the length of Source. If the Capacity parameter is equal or greater than
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
457 -- the length of Source, then the capacity of the result is the specified
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
458 -- value. Otherwise, Copy raises Capacity_Error. If the Modulus parameter
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
459 -- is 0, then the modulus of the result is the value returned by a call to
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
460 -- Default_Modulus with the capacity parameter determined as above;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
461 -- otherwise the modulus of the result is the specified value.
111
kono
parents:
diff changeset
462
kono
parents:
diff changeset
463 function Element
kono
parents:
diff changeset
464 (Container : Set;
kono
parents:
diff changeset
465 Position : Cursor) return Element_Type
kono
parents:
diff changeset
466 with
kono
parents:
diff changeset
467 Global => null,
kono
parents:
diff changeset
468 Pre => Has_Element (Container, Position),
kono
parents:
diff changeset
469 Post =>
kono
parents:
diff changeset
470 Element'Result =
kono
parents:
diff changeset
471 E.Get (Elements (Container), P.Get (Positions (Container), Position));
kono
parents:
diff changeset
472 pragma Annotate (GNATprove, Inline_For_Proof, Element);
kono
parents:
diff changeset
473
kono
parents:
diff changeset
474 procedure Replace_Element
kono
parents:
diff changeset
475 (Container : in out Set;
kono
parents:
diff changeset
476 Position : Cursor;
kono
parents:
diff changeset
477 New_Item : Element_Type)
kono
parents:
diff changeset
478 with
kono
parents:
diff changeset
479 Global => null,
kono
parents:
diff changeset
480 Pre => Has_Element (Container, Position),
kono
parents:
diff changeset
481 Post =>
kono
parents:
diff changeset
482 Length (Container) = Length (Container)'Old
kono
parents:
diff changeset
483
kono
parents:
diff changeset
484 -- Position now maps to New_Item
kono
parents:
diff changeset
485
kono
parents:
diff changeset
486 and Element (Container, Position) = New_Item
kono
parents:
diff changeset
487
kono
parents:
diff changeset
488 -- New_Item is contained in Container
kono
parents:
diff changeset
489
kono
parents:
diff changeset
490 and Contains (Model (Container), New_Item)
kono
parents:
diff changeset
491
kono
parents:
diff changeset
492 -- Other elements are preserved
kono
parents:
diff changeset
493
kono
parents:
diff changeset
494 and M.Included_Except
kono
parents:
diff changeset
495 (Model (Container)'Old,
kono
parents:
diff changeset
496 Model (Container),
kono
parents:
diff changeset
497 Element (Container, Position)'Old)
kono
parents:
diff changeset
498 and M.Included_Except
kono
parents:
diff changeset
499 (Model (Container),
kono
parents:
diff changeset
500 Model (Container)'Old,
kono
parents:
diff changeset
501 New_Item)
kono
parents:
diff changeset
502
kono
parents:
diff changeset
503 -- Mapping from cursors to elements is preserved
kono
parents:
diff changeset
504
kono
parents:
diff changeset
505 and Mapping_Preserved_Except
kono
parents:
diff changeset
506 (E_Left => Elements (Container)'Old,
kono
parents:
diff changeset
507 E_Right => Elements (Container),
kono
parents:
diff changeset
508 P_Left => Positions (Container)'Old,
kono
parents:
diff changeset
509 P_Right => Positions (Container),
kono
parents:
diff changeset
510 Position => Position)
kono
parents:
diff changeset
511 and Positions (Container) = Positions (Container)'Old;
kono
parents:
diff changeset
512
kono
parents:
diff changeset
513 procedure Move (Target : in out Set; Source : in out Set) with
kono
parents:
diff changeset
514 Global => null,
kono
parents:
diff changeset
515 Pre => Target.Capacity >= Length (Source),
kono
parents:
diff changeset
516 Post =>
kono
parents:
diff changeset
517 Length (Source) = 0
kono
parents:
diff changeset
518 and Model (Target) = Model (Source)'Old
kono
parents:
diff changeset
519 and Length (Target) = Length (Source)'Old
kono
parents:
diff changeset
520
kono
parents:
diff changeset
521 -- Actual elements are preserved
kono
parents:
diff changeset
522
kono
parents:
diff changeset
523 and E_Elements_Included (Elements (Target), Elements (Source)'Old)
kono
parents:
diff changeset
524 and E_Elements_Included (Elements (Source)'Old, Elements (Target));
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
525 -- Clears Target (if it's not empty), and then moves (not copies) the
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
526 -- buckets array and nodes from Source to Target.
111
kono
parents:
diff changeset
527
kono
parents:
diff changeset
528 procedure Insert
kono
parents:
diff changeset
529 (Container : in out Set;
kono
parents:
diff changeset
530 New_Item : Element_Type;
kono
parents:
diff changeset
531 Position : out Cursor;
kono
parents:
diff changeset
532 Inserted : out Boolean)
kono
parents:
diff changeset
533 with
kono
parents:
diff changeset
534 Global => null,
kono
parents:
diff changeset
535 Pre =>
kono
parents:
diff changeset
536 Length (Container) < Container.Capacity
kono
parents:
diff changeset
537 or Contains (Container, New_Item),
kono
parents:
diff changeset
538 Post =>
kono
parents:
diff changeset
539 Contains (Container, New_Item)
kono
parents:
diff changeset
540 and Has_Element (Container, Position)
kono
parents:
diff changeset
541 and Equivalent_Elements (Element (Container, Position), New_Item),
kono
parents:
diff changeset
542 Contract_Cases =>
kono
parents:
diff changeset
543
kono
parents:
diff changeset
544 -- If New_Item is already in Container, it is not modified and Inserted
kono
parents:
diff changeset
545 -- is set to False.
kono
parents:
diff changeset
546
kono
parents:
diff changeset
547 (Contains (Container, New_Item) =>
kono
parents:
diff changeset
548 not Inserted
kono
parents:
diff changeset
549 and Model (Container) = Model (Container)'Old
kono
parents:
diff changeset
550 and Elements (Container) = Elements (Container)'Old
kono
parents:
diff changeset
551 and Positions (Container) = Positions (Container)'Old,
kono
parents:
diff changeset
552
kono
parents:
diff changeset
553 -- Otherwise, New_Item is inserted in Container and Inserted is set to
kono
parents:
diff changeset
554 -- True.
kono
parents:
diff changeset
555
kono
parents:
diff changeset
556 others =>
kono
parents:
diff changeset
557 Inserted
kono
parents:
diff changeset
558 and Length (Container) = Length (Container)'Old + 1
kono
parents:
diff changeset
559
kono
parents:
diff changeset
560 -- Position now maps to New_Item
kono
parents:
diff changeset
561
kono
parents:
diff changeset
562 and Element (Container, Position) = New_Item
kono
parents:
diff changeset
563
kono
parents:
diff changeset
564 -- Other elements are preserved
kono
parents:
diff changeset
565
kono
parents:
diff changeset
566 and Model (Container)'Old <= Model (Container)
kono
parents:
diff changeset
567 and M.Included_Except
kono
parents:
diff changeset
568 (Model (Container),
kono
parents:
diff changeset
569 Model (Container)'Old,
kono
parents:
diff changeset
570 New_Item)
kono
parents:
diff changeset
571
kono
parents:
diff changeset
572 -- Mapping from cursors to elements is preserved
kono
parents:
diff changeset
573
kono
parents:
diff changeset
574 and Mapping_Preserved
kono
parents:
diff changeset
575 (E_Left => Elements (Container)'Old,
kono
parents:
diff changeset
576 E_Right => Elements (Container),
kono
parents:
diff changeset
577 P_Left => Positions (Container)'Old,
kono
parents:
diff changeset
578 P_Right => Positions (Container))
kono
parents:
diff changeset
579 and P.Keys_Included_Except
kono
parents:
diff changeset
580 (Positions (Container),
kono
parents:
diff changeset
581 Positions (Container)'Old,
kono
parents:
diff changeset
582 Position));
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
583 -- Conditionally inserts New_Item into the set. If New_Item is already in
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
584 -- the set, then Inserted returns False and Position designates the node
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
585 -- containing the existing element (which is not modified). If New_Item is
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
586 -- not already in the set, then Inserted returns True and Position
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
587 -- designates the newly-inserted node containing New_Item. The search for
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
588 -- an existing element works as follows. Hash is called to determine
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
589 -- New_Item's bucket; if the bucket is non-empty, then Equivalent_Elements
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
590 -- is called to compare New_Item to the element of each node in that
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
591 -- bucket. If the bucket is empty, or there were no equivalent elements in
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
592 -- the bucket, the search "fails" and the New_Item is inserted in the set
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
593 -- (and Inserted returns True); otherwise, the search "succeeds" (and
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
594 -- Inserted returns False).
111
kono
parents:
diff changeset
595
kono
parents:
diff changeset
596 procedure Insert (Container : in out Set; New_Item : Element_Type) with
kono
parents:
diff changeset
597 Global => null,
kono
parents:
diff changeset
598 Pre => Length (Container) < Container.Capacity
kono
parents:
diff changeset
599 and then (not Contains (Container, New_Item)),
kono
parents:
diff changeset
600 Post =>
kono
parents:
diff changeset
601 Length (Container) = Length (Container)'Old + 1
kono
parents:
diff changeset
602 and Contains (Container, New_Item)
kono
parents:
diff changeset
603 and Element (Container, Find (Container, New_Item)) = New_Item
kono
parents:
diff changeset
604
kono
parents:
diff changeset
605 -- Other elements are preserved
kono
parents:
diff changeset
606
kono
parents:
diff changeset
607 and Model (Container)'Old <= Model (Container)
kono
parents:
diff changeset
608 and M.Included_Except
kono
parents:
diff changeset
609 (Model (Container),
kono
parents:
diff changeset
610 Model (Container)'Old,
kono
parents:
diff changeset
611 New_Item)
kono
parents:
diff changeset
612
kono
parents:
diff changeset
613 -- Mapping from cursors to elements is preserved
kono
parents:
diff changeset
614
kono
parents:
diff changeset
615 and Mapping_Preserved
kono
parents:
diff changeset
616 (E_Left => Elements (Container)'Old,
kono
parents:
diff changeset
617 E_Right => Elements (Container),
kono
parents:
diff changeset
618 P_Left => Positions (Container)'Old,
kono
parents:
diff changeset
619 P_Right => Positions (Container))
kono
parents:
diff changeset
620 and P.Keys_Included_Except
kono
parents:
diff changeset
621 (Positions (Container),
kono
parents:
diff changeset
622 Positions (Container)'Old,
kono
parents:
diff changeset
623 Find (Container, New_Item));
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
624 -- Attempts to insert New_Item into the set, performing the usual insertion
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
625 -- search (which involves calling both Hash and Equivalent_Elements); if
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
626 -- the search succeeds (New_Item is equivalent to an element already in the
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
627 -- set, and so was not inserted), then this operation raises
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
628 -- Constraint_Error. (This version of Insert is similar to Replace, but
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
629 -- having the opposite exception behavior. It is intended for use when you
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
630 -- want to assert that the item is not already in the set.)
111
kono
parents:
diff changeset
631
kono
parents:
diff changeset
632 procedure Include (Container : in out Set; New_Item : Element_Type) with
kono
parents:
diff changeset
633 Global => null,
kono
parents:
diff changeset
634 Pre =>
kono
parents:
diff changeset
635 Length (Container) < Container.Capacity
kono
parents:
diff changeset
636 or Contains (Container, New_Item),
kono
parents:
diff changeset
637 Post =>
kono
parents:
diff changeset
638 Contains (Container, New_Item)
kono
parents:
diff changeset
639 and Element (Container, Find (Container, New_Item)) = New_Item,
kono
parents:
diff changeset
640 Contract_Cases =>
kono
parents:
diff changeset
641
kono
parents:
diff changeset
642 -- If an element equivalent to New_Item is already in Container, it is
kono
parents:
diff changeset
643 -- replaced by New_Item.
kono
parents:
diff changeset
644
kono
parents:
diff changeset
645 (Contains (Container, New_Item) =>
kono
parents:
diff changeset
646
kono
parents:
diff changeset
647 -- Elements are preserved modulo equivalence
kono
parents:
diff changeset
648
kono
parents:
diff changeset
649 Model (Container) = Model (Container)'Old
kono
parents:
diff changeset
650
kono
parents:
diff changeset
651 -- Cursors are preserved
kono
parents:
diff changeset
652
kono
parents:
diff changeset
653 and Positions (Container) = Positions (Container)'Old
kono
parents:
diff changeset
654
kono
parents:
diff changeset
655 -- The actual value of other elements is preserved
kono
parents:
diff changeset
656
kono
parents:
diff changeset
657 and E.Equal_Except
kono
parents:
diff changeset
658 (Elements (Container)'Old,
kono
parents:
diff changeset
659 Elements (Container),
kono
parents:
diff changeset
660 P.Get (Positions (Container), Find (Container, New_Item))),
kono
parents:
diff changeset
661
kono
parents:
diff changeset
662 -- Otherwise, New_Item is inserted in Container
kono
parents:
diff changeset
663
kono
parents:
diff changeset
664 others =>
kono
parents:
diff changeset
665 Length (Container) = Length (Container)'Old + 1
kono
parents:
diff changeset
666
kono
parents:
diff changeset
667 -- Other elements are preserved
kono
parents:
diff changeset
668
kono
parents:
diff changeset
669 and Model (Container)'Old <= Model (Container)
kono
parents:
diff changeset
670 and M.Included_Except
kono
parents:
diff changeset
671 (Model (Container),
kono
parents:
diff changeset
672 Model (Container)'Old,
kono
parents:
diff changeset
673 New_Item)
kono
parents:
diff changeset
674
kono
parents:
diff changeset
675 -- Mapping from cursors to elements is preserved
kono
parents:
diff changeset
676
kono
parents:
diff changeset
677 and Mapping_Preserved
kono
parents:
diff changeset
678 (E_Left => Elements (Container)'Old,
kono
parents:
diff changeset
679 E_Right => Elements (Container),
kono
parents:
diff changeset
680 P_Left => Positions (Container)'Old,
kono
parents:
diff changeset
681 P_Right => Positions (Container))
kono
parents:
diff changeset
682 and P.Keys_Included_Except
kono
parents:
diff changeset
683 (Positions (Container),
kono
parents:
diff changeset
684 Positions (Container)'Old,
kono
parents:
diff changeset
685 Find (Container, New_Item)));
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
686 -- Attempts to insert New_Item into the set. If an element equivalent to
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
687 -- New_Item is already in the set (the insertion search succeeded, and
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
688 -- hence New_Item was not inserted), then the value of New_Item is assigned
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
689 -- to the existing element. (This insertion operation only raises an
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
690 -- exception if cursor tampering occurs. It is intended for use when you
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
691 -- want to insert the item in the set, and you don't care whether an
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
692 -- equivalent element is already present.)
111
kono
parents:
diff changeset
693
kono
parents:
diff changeset
694 procedure Replace (Container : in out Set; New_Item : Element_Type) with
kono
parents:
diff changeset
695 Global => null,
kono
parents:
diff changeset
696 Pre => Contains (Container, New_Item),
kono
parents:
diff changeset
697 Post =>
kono
parents:
diff changeset
698
kono
parents:
diff changeset
699 -- Elements are preserved modulo equivalence
kono
parents:
diff changeset
700
kono
parents:
diff changeset
701 Model (Container) = Model (Container)'Old
kono
parents:
diff changeset
702 and Contains (Container, New_Item)
kono
parents:
diff changeset
703
kono
parents:
diff changeset
704 -- Cursors are preserved
kono
parents:
diff changeset
705
kono
parents:
diff changeset
706 and Positions (Container) = Positions (Container)'Old
kono
parents:
diff changeset
707
kono
parents:
diff changeset
708 -- The element equivalent to New_Item in Container is replaced by
kono
parents:
diff changeset
709 -- New_Item.
kono
parents:
diff changeset
710
kono
parents:
diff changeset
711 and Element (Container, Find (Container, New_Item)) = New_Item
kono
parents:
diff changeset
712 and E.Equal_Except
kono
parents:
diff changeset
713 (Elements (Container)'Old,
kono
parents:
diff changeset
714 Elements (Container),
kono
parents:
diff changeset
715 P.Get (Positions (Container), Find (Container, New_Item)));
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
716 -- Searches for New_Item in the set; if the search fails (because an
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
717 -- equivalent element was not in the set), then it raises
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
718 -- Constraint_Error. Otherwise, the existing element is assigned the value
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
719 -- New_Item. (This is similar to Insert, but with the opposite exception
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
720 -- behavior. It is intended for use when you want to assert that the item
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
721 -- is already in the set.)
111
kono
parents:
diff changeset
722
kono
parents:
diff changeset
723 procedure Exclude (Container : in out Set; Item : Element_Type) with
kono
parents:
diff changeset
724 Global => null,
kono
parents:
diff changeset
725 Post => not Contains (Container, Item),
kono
parents:
diff changeset
726 Contract_Cases =>
kono
parents:
diff changeset
727
kono
parents:
diff changeset
728 -- If Item is not in Container, nothing is changed
kono
parents:
diff changeset
729
kono
parents:
diff changeset
730 (not Contains (Container, Item) =>
kono
parents:
diff changeset
731 Model (Container) = Model (Container)'Old
kono
parents:
diff changeset
732 and Elements (Container) = Elements (Container)'Old
kono
parents:
diff changeset
733 and Positions (Container) = Positions (Container)'Old,
kono
parents:
diff changeset
734
kono
parents:
diff changeset
735 -- Otherwise, Item is removed from Container
kono
parents:
diff changeset
736
kono
parents:
diff changeset
737 others =>
kono
parents:
diff changeset
738 Length (Container) = Length (Container)'Old - 1
kono
parents:
diff changeset
739
kono
parents:
diff changeset
740 -- Other elements are preserved
kono
parents:
diff changeset
741
kono
parents:
diff changeset
742 and Model (Container) <= Model (Container)'Old
kono
parents:
diff changeset
743 and M.Included_Except
kono
parents:
diff changeset
744 (Model (Container)'Old,
kono
parents:
diff changeset
745 Model (Container),
kono
parents:
diff changeset
746 Item)
kono
parents:
diff changeset
747
kono
parents:
diff changeset
748 -- Mapping from cursors to elements is preserved
kono
parents:
diff changeset
749
kono
parents:
diff changeset
750 and Mapping_Preserved
kono
parents:
diff changeset
751 (E_Left => Elements (Container),
kono
parents:
diff changeset
752 E_Right => Elements (Container)'Old,
kono
parents:
diff changeset
753 P_Left => Positions (Container),
kono
parents:
diff changeset
754 P_Right => Positions (Container)'Old)
kono
parents:
diff changeset
755 and P.Keys_Included_Except
kono
parents:
diff changeset
756 (Positions (Container)'Old,
kono
parents:
diff changeset
757 Positions (Container),
kono
parents:
diff changeset
758 Find (Container, Item)'Old));
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
759 -- Searches for Item in the set, and if found, removes its node from the
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
760 -- set and then deallocates it. The search works as follows. The operation
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
761 -- calls Hash to determine the item's bucket; if the bucket is not empty,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
762 -- it calls Equivalent_Elements to compare Item to the element of each node
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
763 -- in the bucket. (This is the deletion analog of Include. It is intended
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
764 -- for use when you want to remove the item from the set, but don't care
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
765 -- whether the item is already in the set.)
111
kono
parents:
diff changeset
766
kono
parents:
diff changeset
767 procedure Delete (Container : in out Set; Item : Element_Type) with
kono
parents:
diff changeset
768 Global => null,
kono
parents:
diff changeset
769 Pre => Contains (Container, Item),
kono
parents:
diff changeset
770 Post =>
kono
parents:
diff changeset
771 Length (Container) = Length (Container)'Old - 1
kono
parents:
diff changeset
772
kono
parents:
diff changeset
773 -- Item is no longer in Container
kono
parents:
diff changeset
774
kono
parents:
diff changeset
775 and not Contains (Container, Item)
kono
parents:
diff changeset
776
kono
parents:
diff changeset
777 -- Other elements are preserved
kono
parents:
diff changeset
778
kono
parents:
diff changeset
779 and Model (Container) <= Model (Container)'Old
kono
parents:
diff changeset
780 and M.Included_Except
kono
parents:
diff changeset
781 (Model (Container)'Old,
kono
parents:
diff changeset
782 Model (Container),
kono
parents:
diff changeset
783 Item)
kono
parents:
diff changeset
784
kono
parents:
diff changeset
785 -- Mapping from cursors to elements is preserved
kono
parents:
diff changeset
786
kono
parents:
diff changeset
787 and Mapping_Preserved
kono
parents:
diff changeset
788 (E_Left => Elements (Container),
kono
parents:
diff changeset
789 E_Right => Elements (Container)'Old,
kono
parents:
diff changeset
790 P_Left => Positions (Container),
kono
parents:
diff changeset
791 P_Right => Positions (Container)'Old)
kono
parents:
diff changeset
792 and P.Keys_Included_Except
kono
parents:
diff changeset
793 (Positions (Container)'Old,
kono
parents:
diff changeset
794 Positions (Container),
kono
parents:
diff changeset
795 Find (Container, Item)'Old);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
796 -- Searches for Item in the set (which involves calling both Hash and
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
797 -- Equivalent_Elements). If the search fails, then the operation raises
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
798 -- Constraint_Error. Otherwise it removes the node from the set and then
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
799 -- deallocates it. (This is the deletion analog of non-conditional
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
800 -- Insert. It is intended for use when you want to assert that the item is
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
801 -- already in the set.)
111
kono
parents:
diff changeset
802
kono
parents:
diff changeset
803 procedure Delete (Container : in out Set; Position : in out Cursor) with
kono
parents:
diff changeset
804 Global => null,
kono
parents:
diff changeset
805 Pre => Has_Element (Container, Position),
kono
parents:
diff changeset
806 Post =>
kono
parents:
diff changeset
807 Position = No_Element
kono
parents:
diff changeset
808 and Length (Container) = Length (Container)'Old - 1
kono
parents:
diff changeset
809
kono
parents:
diff changeset
810 -- The element at position Position is no longer in Container
kono
parents:
diff changeset
811
kono
parents:
diff changeset
812 and not Contains (Container, Element (Container, Position)'Old)
kono
parents:
diff changeset
813 and not P.Has_Key (Positions (Container), Position'Old)
kono
parents:
diff changeset
814
kono
parents:
diff changeset
815 -- Other elements are preserved
kono
parents:
diff changeset
816
kono
parents:
diff changeset
817 and Model (Container) <= Model (Container)'Old
kono
parents:
diff changeset
818 and M.Included_Except
kono
parents:
diff changeset
819 (Model (Container)'Old,
kono
parents:
diff changeset
820 Model (Container),
kono
parents:
diff changeset
821 Element (Container, Position)'Old)
kono
parents:
diff changeset
822
kono
parents:
diff changeset
823 -- Mapping from cursors to elements is preserved
kono
parents:
diff changeset
824
kono
parents:
diff changeset
825 and Mapping_Preserved
kono
parents:
diff changeset
826 (E_Left => Elements (Container),
kono
parents:
diff changeset
827 E_Right => Elements (Container)'Old,
kono
parents:
diff changeset
828 P_Left => Positions (Container),
kono
parents:
diff changeset
829 P_Right => Positions (Container)'Old)
kono
parents:
diff changeset
830 and P.Keys_Included_Except
kono
parents:
diff changeset
831 (Positions (Container)'Old,
kono
parents:
diff changeset
832 Positions (Container),
kono
parents:
diff changeset
833 Position'Old);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
834 -- Removes the node designated by Position from the set, and then
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
835 -- deallocates the node. The operation calls Hash to determine the bucket,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
836 -- and then compares Position to each node in the bucket until there's a
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
837 -- match (it does not call Equivalent_Elements).
111
kono
parents:
diff changeset
838
kono
parents:
diff changeset
839 procedure Union (Target : in out Set; Source : Set) with
kono
parents:
diff changeset
840 Global => null,
kono
parents:
diff changeset
841 Pre =>
kono
parents:
diff changeset
842 Length (Source) - Length (Target and Source) <=
kono
parents:
diff changeset
843 Target.Capacity - Length (Target),
kono
parents:
diff changeset
844 Post =>
kono
parents:
diff changeset
845 Length (Target) = Length (Target)'Old
kono
parents:
diff changeset
846 - M.Num_Overlaps (Model (Target)'Old, Model (Source))
kono
parents:
diff changeset
847 + Length (Source)
kono
parents:
diff changeset
848
kono
parents:
diff changeset
849 -- Elements already in Target are still in Target
kono
parents:
diff changeset
850
kono
parents:
diff changeset
851 and Model (Target)'Old <= Model (Target)
kono
parents:
diff changeset
852
kono
parents:
diff changeset
853 -- Elements of Source are included in Target
kono
parents:
diff changeset
854
kono
parents:
diff changeset
855 and Model (Source) <= Model (Target)
kono
parents:
diff changeset
856
kono
parents:
diff changeset
857 -- Elements of Target come from either Source or Target
kono
parents:
diff changeset
858
kono
parents:
diff changeset
859 and M.Included_In_Union
kono
parents:
diff changeset
860 (Model (Target), Model (Source), Model (Target)'Old)
kono
parents:
diff changeset
861
kono
parents:
diff changeset
862 -- Actual value of elements come from either Left or Right
kono
parents:
diff changeset
863
kono
parents:
diff changeset
864 and E_Elements_Included
kono
parents:
diff changeset
865 (Elements (Target),
kono
parents:
diff changeset
866 Model (Target)'Old,
kono
parents:
diff changeset
867 Elements (Target)'Old,
kono
parents:
diff changeset
868 Elements (Source))
kono
parents:
diff changeset
869
kono
parents:
diff changeset
870 and E_Elements_Included
kono
parents:
diff changeset
871 (Elements (Target)'Old, Model (Target)'Old, Elements (Target))
kono
parents:
diff changeset
872
kono
parents:
diff changeset
873 and E_Elements_Included
kono
parents:
diff changeset
874 (Elements (Source),
kono
parents:
diff changeset
875 Model (Target)'Old,
kono
parents:
diff changeset
876 Elements (Source),
kono
parents:
diff changeset
877 Elements (Target))
kono
parents:
diff changeset
878
kono
parents:
diff changeset
879 -- Mapping from cursors of Target to elements is preserved
kono
parents:
diff changeset
880
kono
parents:
diff changeset
881 and Mapping_Preserved
kono
parents:
diff changeset
882 (E_Left => Elements (Target)'Old,
kono
parents:
diff changeset
883 E_Right => Elements (Target),
kono
parents:
diff changeset
884 P_Left => Positions (Target)'Old,
kono
parents:
diff changeset
885 P_Right => Positions (Target));
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
886 -- Iterates over the Source set, and conditionally inserts each element
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
887 -- into Target.
111
kono
parents:
diff changeset
888
kono
parents:
diff changeset
889 function Union (Left, Right : Set) return Set with
kono
parents:
diff changeset
890 Global => null,
kono
parents:
diff changeset
891 Pre => Length (Left) <= Count_Type'Last - Length (Right),
kono
parents:
diff changeset
892 Post =>
kono
parents:
diff changeset
893 Length (Union'Result) = Length (Left)
kono
parents:
diff changeset
894 - M.Num_Overlaps (Model (Left), Model (Right))
kono
parents:
diff changeset
895 + Length (Right)
kono
parents:
diff changeset
896
kono
parents:
diff changeset
897 -- Elements of Left and Right are in the result of Union
kono
parents:
diff changeset
898
kono
parents:
diff changeset
899 and Model (Left) <= Model (Union'Result)
kono
parents:
diff changeset
900 and Model (Right) <= Model (Union'Result)
kono
parents:
diff changeset
901
kono
parents:
diff changeset
902 -- Elements of the result of union come from either Left or Right
kono
parents:
diff changeset
903
kono
parents:
diff changeset
904 and
kono
parents:
diff changeset
905 M.Included_In_Union
kono
parents:
diff changeset
906 (Model (Union'Result), Model (Left), Model (Right))
kono
parents:
diff changeset
907
kono
parents:
diff changeset
908 -- Actual value of elements come from either Left or Right
kono
parents:
diff changeset
909
kono
parents:
diff changeset
910 and E_Elements_Included
kono
parents:
diff changeset
911 (Elements (Union'Result),
kono
parents:
diff changeset
912 Model (Left),
kono
parents:
diff changeset
913 Elements (Left),
kono
parents:
diff changeset
914 Elements (Right))
kono
parents:
diff changeset
915
kono
parents:
diff changeset
916 and E_Elements_Included
kono
parents:
diff changeset
917 (Elements (Left), Model (Left), Elements (Union'Result))
kono
parents:
diff changeset
918
kono
parents:
diff changeset
919 and E_Elements_Included
kono
parents:
diff changeset
920 (Elements (Right),
kono
parents:
diff changeset
921 Model (Left),
kono
parents:
diff changeset
922 Elements (Right),
kono
parents:
diff changeset
923 Elements (Union'Result));
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
924 -- The operation first copies the Left set to the result, and then iterates
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
925 -- over the Right set to conditionally insert each element into the result.
111
kono
parents:
diff changeset
926
kono
parents:
diff changeset
927 function "or" (Left, Right : Set) return Set renames Union;
kono
parents:
diff changeset
928
kono
parents:
diff changeset
929 procedure Intersection (Target : in out Set; Source : Set) with
kono
parents:
diff changeset
930 Global => null,
kono
parents:
diff changeset
931 Post =>
kono
parents:
diff changeset
932 Length (Target) =
kono
parents:
diff changeset
933 M.Num_Overlaps (Model (Target)'Old, Model (Source))
kono
parents:
diff changeset
934
kono
parents:
diff changeset
935 -- Elements of Target were already in Target
kono
parents:
diff changeset
936
kono
parents:
diff changeset
937 and Model (Target) <= Model (Target)'Old
kono
parents:
diff changeset
938
kono
parents:
diff changeset
939 -- Elements of Target are in Source
kono
parents:
diff changeset
940
kono
parents:
diff changeset
941 and Model (Target) <= Model (Source)
kono
parents:
diff changeset
942
kono
parents:
diff changeset
943 -- Elements both in Source and Target are in the intersection
kono
parents:
diff changeset
944
kono
parents:
diff changeset
945 and M.Includes_Intersection
kono
parents:
diff changeset
946 (Model (Target), Model (Source), Model (Target)'Old)
kono
parents:
diff changeset
947
kono
parents:
diff changeset
948 -- Actual value of elements of Target is preserved
kono
parents:
diff changeset
949
kono
parents:
diff changeset
950 and E_Elements_Included (Elements (Target), Elements (Target)'Old)
kono
parents:
diff changeset
951 and E_Elements_Included
kono
parents:
diff changeset
952 (Elements (Target)'Old, Model (Source), Elements (Target))
kono
parents:
diff changeset
953
kono
parents:
diff changeset
954 -- Mapping from cursors of Target to elements is preserved
kono
parents:
diff changeset
955
kono
parents:
diff changeset
956 and Mapping_Preserved
kono
parents:
diff changeset
957 (E_Left => Elements (Target),
kono
parents:
diff changeset
958 E_Right => Elements (Target)'Old,
kono
parents:
diff changeset
959 P_Left => Positions (Target),
kono
parents:
diff changeset
960 P_Right => Positions (Target)'Old);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
961 -- Iterates over the Target set (calling First and Next), calling Find to
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
962 -- determine whether the element is in Source. If an equivalent element is
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
963 -- not found in Source, the element is deleted from Target.
111
kono
parents:
diff changeset
964
kono
parents:
diff changeset
965 function Intersection (Left, Right : Set) return Set with
kono
parents:
diff changeset
966 Global => null,
kono
parents:
diff changeset
967 Post =>
kono
parents:
diff changeset
968 Length (Intersection'Result) =
kono
parents:
diff changeset
969 M.Num_Overlaps (Model (Left), Model (Right))
kono
parents:
diff changeset
970
kono
parents:
diff changeset
971 -- Elements in the result of Intersection are in Left and Right
kono
parents:
diff changeset
972
kono
parents:
diff changeset
973 and Model (Intersection'Result) <= Model (Left)
kono
parents:
diff changeset
974 and Model (Intersection'Result) <= Model (Right)
kono
parents:
diff changeset
975
kono
parents:
diff changeset
976 -- Elements both in Left and Right are in the result of Intersection
kono
parents:
diff changeset
977
kono
parents:
diff changeset
978 and M.Includes_Intersection
kono
parents:
diff changeset
979 (Model (Intersection'Result), Model (Left), Model (Right))
kono
parents:
diff changeset
980
kono
parents:
diff changeset
981 -- Actual value of elements come from Left
kono
parents:
diff changeset
982
kono
parents:
diff changeset
983 and E_Elements_Included
kono
parents:
diff changeset
984 (Elements (Intersection'Result), Elements (Left))
kono
parents:
diff changeset
985
kono
parents:
diff changeset
986 and E_Elements_Included
kono
parents:
diff changeset
987 (Elements (Left), Model (Right),
kono
parents:
diff changeset
988 Elements (Intersection'Result));
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
989 -- Iterates over the Left set, calling Find to determine whether the
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
990 -- element is in Right. If an equivalent element is found, it is inserted
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
991 -- into the result set.
111
kono
parents:
diff changeset
992
kono
parents:
diff changeset
993 function "and" (Left, Right : Set) return Set renames Intersection;
kono
parents:
diff changeset
994
kono
parents:
diff changeset
995 procedure Difference (Target : in out Set; Source : Set) with
kono
parents:
diff changeset
996 Global => null,
kono
parents:
diff changeset
997 Post =>
kono
parents:
diff changeset
998 Length (Target) = Length (Target)'Old -
kono
parents:
diff changeset
999 M.Num_Overlaps (Model (Target)'Old, Model (Source))
kono
parents:
diff changeset
1000
kono
parents:
diff changeset
1001 -- Elements of Target were already in Target
kono
parents:
diff changeset
1002
kono
parents:
diff changeset
1003 and Model (Target) <= Model (Target)'Old
kono
parents:
diff changeset
1004
kono
parents:
diff changeset
1005 -- Elements of Target are not in Source
kono
parents:
diff changeset
1006
kono
parents:
diff changeset
1007 and M.No_Overlap (Model (Target), Model (Source))
kono
parents:
diff changeset
1008
kono
parents:
diff changeset
1009 -- Elements in Target but not in Source are in the difference
kono
parents:
diff changeset
1010
kono
parents:
diff changeset
1011 and M.Included_In_Union
kono
parents:
diff changeset
1012 (Model (Target)'Old, Model (Target), Model (Source))
kono
parents:
diff changeset
1013
kono
parents:
diff changeset
1014 -- Actual value of elements of Target is preserved
kono
parents:
diff changeset
1015
kono
parents:
diff changeset
1016 and E_Elements_Included (Elements (Target), Elements (Target)'Old)
kono
parents:
diff changeset
1017 and E_Elements_Included
kono
parents:
diff changeset
1018 (Elements (Target)'Old, Model (Target), Elements (Target))
kono
parents:
diff changeset
1019
kono
parents:
diff changeset
1020 -- Mapping from cursors of Target to elements is preserved
kono
parents:
diff changeset
1021
kono
parents:
diff changeset
1022 and Mapping_Preserved
kono
parents:
diff changeset
1023 (E_Left => Elements (Target),
kono
parents:
diff changeset
1024 E_Right => Elements (Target)'Old,
kono
parents:
diff changeset
1025 P_Left => Positions (Target),
kono
parents:
diff changeset
1026 P_Right => Positions (Target)'Old);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1027 -- Iterates over the Source (calling First and Next), calling Find to
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1028 -- determine whether the element is in Target. If an equivalent element is
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1029 -- found, it is deleted from Target.
111
kono
parents:
diff changeset
1030
kono
parents:
diff changeset
1031 function Difference (Left, Right : Set) return Set with
kono
parents:
diff changeset
1032 Global => null,
kono
parents:
diff changeset
1033 Post =>
kono
parents:
diff changeset
1034 Length (Difference'Result) = Length (Left) -
kono
parents:
diff changeset
1035 M.Num_Overlaps (Model (Left), Model (Right))
kono
parents:
diff changeset
1036
kono
parents:
diff changeset
1037 -- Elements of the result of Difference are in Left
kono
parents:
diff changeset
1038
kono
parents:
diff changeset
1039 and Model (Difference'Result) <= Model (Left)
kono
parents:
diff changeset
1040
kono
parents:
diff changeset
1041 -- Elements of the result of Difference are in Right
kono
parents:
diff changeset
1042
kono
parents:
diff changeset
1043 and M.No_Overlap (Model (Difference'Result), Model (Right))
kono
parents:
diff changeset
1044
kono
parents:
diff changeset
1045 -- Elements in Left but not in Right are in the difference
kono
parents:
diff changeset
1046
kono
parents:
diff changeset
1047 and M.Included_In_Union
kono
parents:
diff changeset
1048 (Model (Left), Model (Difference'Result), Model (Right))
kono
parents:
diff changeset
1049
kono
parents:
diff changeset
1050 -- Actual value of elements come from Left
kono
parents:
diff changeset
1051
kono
parents:
diff changeset
1052 and E_Elements_Included
kono
parents:
diff changeset
1053 (Elements (Difference'Result), Elements (Left))
kono
parents:
diff changeset
1054
kono
parents:
diff changeset
1055 and E_Elements_Included
kono
parents:
diff changeset
1056 (Elements (Left),
kono
parents:
diff changeset
1057 Model (Difference'Result),
kono
parents:
diff changeset
1058 Elements (Difference'Result));
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1059 -- Iterates over the Left set, calling Find to determine whether the
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1060 -- element is in the Right set. If an equivalent element is not found, the
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1061 -- element is inserted into the result set.
111
kono
parents:
diff changeset
1062
kono
parents:
diff changeset
1063 function "-" (Left, Right : Set) return Set renames Difference;
kono
parents:
diff changeset
1064
kono
parents:
diff changeset
1065 procedure Symmetric_Difference (Target : in out Set; Source : Set) with
kono
parents:
diff changeset
1066 Global => null,
kono
parents:
diff changeset
1067 Pre =>
kono
parents:
diff changeset
1068 Length (Source) - Length (Target and Source) <=
kono
parents:
diff changeset
1069 Target.Capacity - Length (Target) + Length (Target and Source),
kono
parents:
diff changeset
1070 Post =>
kono
parents:
diff changeset
1071 Length (Target) = Length (Target)'Old -
kono
parents:
diff changeset
1072 2 * M.Num_Overlaps (Model (Target)'Old, Model (Source)) +
kono
parents:
diff changeset
1073 Length (Source)
kono
parents:
diff changeset
1074
kono
parents:
diff changeset
1075 -- Elements of the difference were not both in Source and in Target
kono
parents:
diff changeset
1076
kono
parents:
diff changeset
1077 and M.Not_In_Both (Model (Target), Model (Target)'Old, Model (Source))
kono
parents:
diff changeset
1078
kono
parents:
diff changeset
1079 -- Elements in Target but not in Source are in the difference
kono
parents:
diff changeset
1080
kono
parents:
diff changeset
1081 and M.Included_In_Union
kono
parents:
diff changeset
1082 (Model (Target)'Old, Model (Target), Model (Source))
kono
parents:
diff changeset
1083
kono
parents:
diff changeset
1084 -- Elements in Source but not in Target are in the difference
kono
parents:
diff changeset
1085
kono
parents:
diff changeset
1086 and M.Included_In_Union
kono
parents:
diff changeset
1087 (Model (Source), Model (Target), Model (Target)'Old)
kono
parents:
diff changeset
1088
kono
parents:
diff changeset
1089 -- Actual value of elements come from either Left or Right
kono
parents:
diff changeset
1090
kono
parents:
diff changeset
1091 and E_Elements_Included
kono
parents:
diff changeset
1092 (Elements (Target),
kono
parents:
diff changeset
1093 Model (Target)'Old,
kono
parents:
diff changeset
1094 Elements (Target)'Old,
kono
parents:
diff changeset
1095 Elements (Source))
kono
parents:
diff changeset
1096
kono
parents:
diff changeset
1097 and E_Elements_Included
kono
parents:
diff changeset
1098 (Elements (Target)'Old, Model (Target), Elements (Target))
kono
parents:
diff changeset
1099
kono
parents:
diff changeset
1100 and E_Elements_Included
kono
parents:
diff changeset
1101 (Elements (Source), Model (Target), Elements (Target));
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1102 -- The operation iterates over the Source set, searching for the element
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1103 -- in Target (calling Hash and Equivalent_Elements). If an equivalent
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1104 -- element is found, it is removed from Target; otherwise it is inserted
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1105 -- into Target.
111
kono
parents:
diff changeset
1106
kono
parents:
diff changeset
1107 function Symmetric_Difference (Left, Right : Set) return Set with
kono
parents:
diff changeset
1108 Global => null,
kono
parents:
diff changeset
1109 Pre => Length (Left) <= Count_Type'Last - Length (Right),
kono
parents:
diff changeset
1110 Post =>
kono
parents:
diff changeset
1111 Length (Symmetric_Difference'Result) = Length (Left) -
kono
parents:
diff changeset
1112 2 * M.Num_Overlaps (Model (Left), Model (Right)) +
kono
parents:
diff changeset
1113 Length (Right)
kono
parents:
diff changeset
1114
kono
parents:
diff changeset
1115 -- Elements of the difference were not both in Left and Right
kono
parents:
diff changeset
1116
kono
parents:
diff changeset
1117 and M.Not_In_Both
kono
parents:
diff changeset
1118 (Model (Symmetric_Difference'Result),
kono
parents:
diff changeset
1119 Model (Left),
kono
parents:
diff changeset
1120 Model (Right))
kono
parents:
diff changeset
1121
kono
parents:
diff changeset
1122 -- Elements in Left but not in Right are in the difference
kono
parents:
diff changeset
1123
kono
parents:
diff changeset
1124 and M.Included_In_Union
kono
parents:
diff changeset
1125 (Model (Left),
kono
parents:
diff changeset
1126 Model (Symmetric_Difference'Result),
kono
parents:
diff changeset
1127 Model (Right))
kono
parents:
diff changeset
1128
kono
parents:
diff changeset
1129 -- Elements in Right but not in Left are in the difference
kono
parents:
diff changeset
1130
kono
parents:
diff changeset
1131 and M.Included_In_Union
kono
parents:
diff changeset
1132 (Model (Right),
kono
parents:
diff changeset
1133 Model (Symmetric_Difference'Result),
kono
parents:
diff changeset
1134 Model (Left))
kono
parents:
diff changeset
1135
kono
parents:
diff changeset
1136 -- Actual value of elements come from either Left or Right
kono
parents:
diff changeset
1137
kono
parents:
diff changeset
1138 and E_Elements_Included
kono
parents:
diff changeset
1139 (Elements (Symmetric_Difference'Result),
kono
parents:
diff changeset
1140 Model (Left),
kono
parents:
diff changeset
1141 Elements (Left),
kono
parents:
diff changeset
1142 Elements (Right))
kono
parents:
diff changeset
1143
kono
parents:
diff changeset
1144 and E_Elements_Included
kono
parents:
diff changeset
1145 (Elements (Left),
kono
parents:
diff changeset
1146 Model (Symmetric_Difference'Result),
kono
parents:
diff changeset
1147 Elements (Symmetric_Difference'Result))
kono
parents:
diff changeset
1148
kono
parents:
diff changeset
1149 and E_Elements_Included
kono
parents:
diff changeset
1150 (Elements (Right),
kono
parents:
diff changeset
1151 Model (Symmetric_Difference'Result),
kono
parents:
diff changeset
1152 Elements (Symmetric_Difference'Result));
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1153 -- The operation first iterates over the Left set. It calls Find to
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1154 -- determine whether the element is in the Right set. If no equivalent
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1155 -- element is found, the element from Left is inserted into the result. The
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1156 -- operation then iterates over the Right set, to determine whether the
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1157 -- element is in the Left set. If no equivalent element is found, the Right
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1158 -- element is inserted into the result.
111
kono
parents:
diff changeset
1159
kono
parents:
diff changeset
1160 function "xor" (Left, Right : Set) return Set
kono
parents:
diff changeset
1161 renames Symmetric_Difference;
kono
parents:
diff changeset
1162
kono
parents:
diff changeset
1163 function Overlap (Left, Right : Set) return Boolean with
kono
parents:
diff changeset
1164 Global => null,
kono
parents:
diff changeset
1165 Post =>
kono
parents:
diff changeset
1166 Overlap'Result = not (M.No_Overlap (Model (Left), Model (Right)));
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1167 -- Iterates over the Left set (calling First and Next), calling Find to
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1168 -- determine whether the element is in the Right set. If an equivalent
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1169 -- element is found, the operation immediately returns True. The operation
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1170 -- returns False if the iteration over Left terminates without finding any
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1171 -- equivalent element in Right.
111
kono
parents:
diff changeset
1172
kono
parents:
diff changeset
1173 function Is_Subset (Subset : Set; Of_Set : Set) return Boolean with
kono
parents:
diff changeset
1174 Global => null,
kono
parents:
diff changeset
1175 Post => Is_Subset'Result = (Model (Subset) <= Model (Of_Set));
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1176 -- Iterates over Subset (calling First and Next), calling Find to determine
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1177 -- whether the element is in Of_Set. If no equivalent element is found in
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1178 -- Of_Set, the operation immediately returns False. The operation returns
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1179 -- True if the iteration over Subset terminates without finding an element
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1180 -- not in Of_Set (that is, every element in Subset is equivalent to an
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1181 -- element in Of_Set).
111
kono
parents:
diff changeset
1182
kono
parents:
diff changeset
1183 function First (Container : Set) return Cursor with
kono
parents:
diff changeset
1184 Global => null,
kono
parents:
diff changeset
1185 Contract_Cases =>
kono
parents:
diff changeset
1186 (Length (Container) = 0 =>
kono
parents:
diff changeset
1187 First'Result = No_Element,
kono
parents:
diff changeset
1188
kono
parents:
diff changeset
1189 others =>
kono
parents:
diff changeset
1190 Has_Element (Container, First'Result)
kono
parents:
diff changeset
1191 and P.Get (Positions (Container), First'Result) = 1);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1192 -- Returns a cursor that designates the first non-empty bucket, by
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1193 -- searching from the beginning of the buckets array.
111
kono
parents:
diff changeset
1194
kono
parents:
diff changeset
1195 function Next (Container : Set; Position : Cursor) return Cursor with
kono
parents:
diff changeset
1196 Global => null,
kono
parents:
diff changeset
1197 Pre =>
kono
parents:
diff changeset
1198 Has_Element (Container, Position) or else Position = No_Element,
kono
parents:
diff changeset
1199 Contract_Cases =>
kono
parents:
diff changeset
1200 (Position = No_Element
kono
parents:
diff changeset
1201 or else P.Get (Positions (Container), Position) = Length (Container)
kono
parents:
diff changeset
1202 =>
kono
parents:
diff changeset
1203 Next'Result = No_Element,
kono
parents:
diff changeset
1204
kono
parents:
diff changeset
1205 others =>
kono
parents:
diff changeset
1206 Has_Element (Container, Next'Result)
kono
parents:
diff changeset
1207 and then P.Get (Positions (Container), Next'Result) =
kono
parents:
diff changeset
1208 P.Get (Positions (Container), Position) + 1);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1209 -- Returns a cursor that designates the node that follows the current one
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1210 -- designated by Position. If Position designates the last node in its
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1211 -- bucket, the operation calls Hash to compute the index of this bucket,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1212 -- and searches the buckets array for the first non-empty bucket, starting
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1213 -- from that index; otherwise, it simply follows the link to the next node
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1214 -- in the same bucket.
111
kono
parents:
diff changeset
1215
kono
parents:
diff changeset
1216 procedure Next (Container : Set; Position : in out Cursor) with
kono
parents:
diff changeset
1217 Global => null,
kono
parents:
diff changeset
1218 Pre =>
kono
parents:
diff changeset
1219 Has_Element (Container, Position) or else Position = No_Element,
kono
parents:
diff changeset
1220 Contract_Cases =>
kono
parents:
diff changeset
1221 (Position = No_Element
kono
parents:
diff changeset
1222 or else P.Get (Positions (Container), Position) = Length (Container)
kono
parents:
diff changeset
1223 =>
kono
parents:
diff changeset
1224 Position = No_Element,
kono
parents:
diff changeset
1225
kono
parents:
diff changeset
1226 others =>
kono
parents:
diff changeset
1227 Has_Element (Container, Position)
kono
parents:
diff changeset
1228 and then P.Get (Positions (Container), Position) =
kono
parents:
diff changeset
1229 P.Get (Positions (Container), Position'Old) + 1);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1230 -- Equivalent to Position := Next (Position)
111
kono
parents:
diff changeset
1231
kono
parents:
diff changeset
1232 function Find
kono
parents:
diff changeset
1233 (Container : Set;
kono
parents:
diff changeset
1234 Item : Element_Type) return Cursor
kono
parents:
diff changeset
1235 with
kono
parents:
diff changeset
1236 Global => null,
kono
parents:
diff changeset
1237 Contract_Cases =>
kono
parents:
diff changeset
1238
kono
parents:
diff changeset
1239 -- If Item is not contained in Container, Find returns No_Element
kono
parents:
diff changeset
1240
kono
parents:
diff changeset
1241 (not Contains (Model (Container), Item) =>
kono
parents:
diff changeset
1242 Find'Result = No_Element,
kono
parents:
diff changeset
1243
kono
parents:
diff changeset
1244 -- Otherwise, Find returns a valid cursor in Container
kono
parents:
diff changeset
1245
kono
parents:
diff changeset
1246 others =>
kono
parents:
diff changeset
1247 P.Has_Key (Positions (Container), Find'Result)
kono
parents:
diff changeset
1248 and P.Get (Positions (Container), Find'Result) =
kono
parents:
diff changeset
1249 Find (Elements (Container), Item)
kono
parents:
diff changeset
1250
kono
parents:
diff changeset
1251 -- The element designated by the result of Find is Item
kono
parents:
diff changeset
1252
kono
parents:
diff changeset
1253 and Equivalent_Elements
kono
parents:
diff changeset
1254 (Element (Container, Find'Result), Item));
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1255 -- Searches for Item in the set. Find calls Hash to determine the item's
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1256 -- bucket; if the bucket is not empty, it calls Equivalent_Elements to
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1257 -- compare Item to each element in the bucket. If the search succeeds, Find
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1258 -- returns a cursor designating the node containing the equivalent element;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1259 -- otherwise, it returns No_Element.
111
kono
parents:
diff changeset
1260
kono
parents:
diff changeset
1261 function Contains (Container : Set; Item : Element_Type) return Boolean with
kono
parents:
diff changeset
1262 Global => null,
kono
parents:
diff changeset
1263 Post => Contains'Result = Contains (Model (Container), Item);
kono
parents:
diff changeset
1264 pragma Annotate (GNATprove, Inline_For_Proof, Contains);
kono
parents:
diff changeset
1265
kono
parents:
diff changeset
1266 function Has_Element (Container : Set; Position : Cursor) return Boolean
kono
parents:
diff changeset
1267 with
kono
parents:
diff changeset
1268 Global => null,
kono
parents:
diff changeset
1269 Post =>
kono
parents:
diff changeset
1270 Has_Element'Result = P.Has_Key (Positions (Container), Position);
kono
parents:
diff changeset
1271 pragma Annotate (GNATprove, Inline_For_Proof, Has_Element);
kono
parents:
diff changeset
1272
kono
parents:
diff changeset
1273 function Default_Modulus (Capacity : Count_Type) return Hash_Type with
kono
parents:
diff changeset
1274 Global => null;
kono
parents:
diff changeset
1275
kono
parents:
diff changeset
1276 generic
kono
parents:
diff changeset
1277 type Key_Type (<>) is private;
kono
parents:
diff changeset
1278
kono
parents:
diff changeset
1279 with function Key (Element : Element_Type) return Key_Type;
kono
parents:
diff changeset
1280
kono
parents:
diff changeset
1281 with function Hash (Key : Key_Type) return Hash_Type;
kono
parents:
diff changeset
1282
kono
parents:
diff changeset
1283 with function Equivalent_Keys (Left, Right : Key_Type) return Boolean;
kono
parents:
diff changeset
1284
kono
parents:
diff changeset
1285 package Generic_Keys with SPARK_Mode is
kono
parents:
diff changeset
1286
kono
parents:
diff changeset
1287 package Formal_Model with Ghost is
kono
parents:
diff changeset
1288
kono
parents:
diff changeset
1289 function M_Included_Except
kono
parents:
diff changeset
1290 (Left : M.Set;
kono
parents:
diff changeset
1291 Right : M.Set;
kono
parents:
diff changeset
1292 Key : Key_Type) return Boolean
kono
parents:
diff changeset
1293 with
kono
parents:
diff changeset
1294 Global => null,
kono
parents:
diff changeset
1295 Post =>
kono
parents:
diff changeset
1296 M_Included_Except'Result =
kono
parents:
diff changeset
1297 (for all E of Left =>
kono
parents:
diff changeset
1298 Contains (Right, E)
kono
parents:
diff changeset
1299 or Equivalent_Keys (Generic_Keys.Key (E), Key));
kono
parents:
diff changeset
1300
kono
parents:
diff changeset
1301 end Formal_Model;
kono
parents:
diff changeset
1302 use Formal_Model;
kono
parents:
diff changeset
1303
kono
parents:
diff changeset
1304 function Key (Container : Set; Position : Cursor) return Key_Type with
kono
parents:
diff changeset
1305 Global => null,
kono
parents:
diff changeset
1306 Post => Key'Result = Key (Element (Container, Position));
kono
parents:
diff changeset
1307 pragma Annotate (GNATprove, Inline_For_Proof, Key);
kono
parents:
diff changeset
1308
kono
parents:
diff changeset
1309 function Element (Container : Set; Key : Key_Type) return Element_Type
kono
parents:
diff changeset
1310 with
kono
parents:
diff changeset
1311 Global => null,
kono
parents:
diff changeset
1312 Pre => Contains (Container, Key),
kono
parents:
diff changeset
1313 Post =>
kono
parents:
diff changeset
1314 Element'Result = Element (Container, Find (Container, Key));
kono
parents:
diff changeset
1315 pragma Annotate (GNATprove, Inline_For_Proof, Element);
kono
parents:
diff changeset
1316
kono
parents:
diff changeset
1317 procedure Replace
kono
parents:
diff changeset
1318 (Container : in out Set;
kono
parents:
diff changeset
1319 Key : Key_Type;
kono
parents:
diff changeset
1320 New_Item : Element_Type)
kono
parents:
diff changeset
1321 with
kono
parents:
diff changeset
1322 Global => null,
kono
parents:
diff changeset
1323 Pre => Contains (Container, Key),
kono
parents:
diff changeset
1324 Post =>
kono
parents:
diff changeset
1325 Length (Container) = Length (Container)'Old
kono
parents:
diff changeset
1326
kono
parents:
diff changeset
1327 -- Key now maps to New_Item
kono
parents:
diff changeset
1328
kono
parents:
diff changeset
1329 and Element (Container, Key) = New_Item
kono
parents:
diff changeset
1330
kono
parents:
diff changeset
1331 -- New_Item is contained in Container
kono
parents:
diff changeset
1332
kono
parents:
diff changeset
1333 and Contains (Model (Container), New_Item)
kono
parents:
diff changeset
1334
kono
parents:
diff changeset
1335 -- Other elements are preserved
kono
parents:
diff changeset
1336
kono
parents:
diff changeset
1337 and M_Included_Except
kono
parents:
diff changeset
1338 (Model (Container)'Old,
kono
parents:
diff changeset
1339 Model (Container),
kono
parents:
diff changeset
1340 Key)
kono
parents:
diff changeset
1341 and M.Included_Except
kono
parents:
diff changeset
1342 (Model (Container),
kono
parents:
diff changeset
1343 Model (Container)'Old,
kono
parents:
diff changeset
1344 New_Item)
kono
parents:
diff changeset
1345
kono
parents:
diff changeset
1346 -- Mapping from cursors to elements is preserved
kono
parents:
diff changeset
1347
kono
parents:
diff changeset
1348 and Mapping_Preserved_Except
kono
parents:
diff changeset
1349 (E_Left => Elements (Container)'Old,
kono
parents:
diff changeset
1350 E_Right => Elements (Container),
kono
parents:
diff changeset
1351 P_Left => Positions (Container)'Old,
kono
parents:
diff changeset
1352 P_Right => Positions (Container),
kono
parents:
diff changeset
1353 Position => Find (Container, Key))
kono
parents:
diff changeset
1354 and Positions (Container) = Positions (Container)'Old;
kono
parents:
diff changeset
1355
kono
parents:
diff changeset
1356 procedure Exclude (Container : in out Set; Key : Key_Type) with
kono
parents:
diff changeset
1357 Global => null,
kono
parents:
diff changeset
1358 Post => not Contains (Container, Key),
kono
parents:
diff changeset
1359 Contract_Cases =>
kono
parents:
diff changeset
1360
kono
parents:
diff changeset
1361 -- If Key is not in Container, nothing is changed
kono
parents:
diff changeset
1362
kono
parents:
diff changeset
1363 (not Contains (Container, Key) =>
kono
parents:
diff changeset
1364 Model (Container) = Model (Container)'Old
kono
parents:
diff changeset
1365 and Elements (Container) = Elements (Container)'Old
kono
parents:
diff changeset
1366 and Positions (Container) = Positions (Container)'Old,
kono
parents:
diff changeset
1367
kono
parents:
diff changeset
1368 -- Otherwise, Key is removed from Container
kono
parents:
diff changeset
1369
kono
parents:
diff changeset
1370 others =>
kono
parents:
diff changeset
1371 Length (Container) = Length (Container)'Old - 1
kono
parents:
diff changeset
1372
kono
parents:
diff changeset
1373 -- Other elements are preserved
kono
parents:
diff changeset
1374
kono
parents:
diff changeset
1375 and Model (Container) <= Model (Container)'Old
kono
parents:
diff changeset
1376 and M_Included_Except
kono
parents:
diff changeset
1377 (Model (Container)'Old,
kono
parents:
diff changeset
1378 Model (Container),
kono
parents:
diff changeset
1379 Key)
kono
parents:
diff changeset
1380
kono
parents:
diff changeset
1381 -- Mapping from cursors to elements is preserved
kono
parents:
diff changeset
1382
kono
parents:
diff changeset
1383 and Mapping_Preserved
kono
parents:
diff changeset
1384 (E_Left => Elements (Container),
kono
parents:
diff changeset
1385 E_Right => Elements (Container)'Old,
kono
parents:
diff changeset
1386 P_Left => Positions (Container),
kono
parents:
diff changeset
1387 P_Right => Positions (Container)'Old)
kono
parents:
diff changeset
1388 and P.Keys_Included_Except
kono
parents:
diff changeset
1389 (Positions (Container)'Old,
kono
parents:
diff changeset
1390 Positions (Container),
kono
parents:
diff changeset
1391 Find (Container, Key)'Old));
kono
parents:
diff changeset
1392
kono
parents:
diff changeset
1393 procedure Delete (Container : in out Set; Key : Key_Type) with
kono
parents:
diff changeset
1394 Global => null,
kono
parents:
diff changeset
1395 Pre => Contains (Container, Key),
kono
parents:
diff changeset
1396 Post =>
kono
parents:
diff changeset
1397 Length (Container) = Length (Container)'Old - 1
kono
parents:
diff changeset
1398
kono
parents:
diff changeset
1399 -- Key is no longer in Container
kono
parents:
diff changeset
1400
kono
parents:
diff changeset
1401 and not Contains (Container, Key)
kono
parents:
diff changeset
1402
kono
parents:
diff changeset
1403 -- Other elements are preserved
kono
parents:
diff changeset
1404
kono
parents:
diff changeset
1405 and Model (Container) <= Model (Container)'Old
kono
parents:
diff changeset
1406 and M_Included_Except
kono
parents:
diff changeset
1407 (Model (Container)'Old,
kono
parents:
diff changeset
1408 Model (Container),
kono
parents:
diff changeset
1409 Key)
kono
parents:
diff changeset
1410
kono
parents:
diff changeset
1411 -- Mapping from cursors to elements is preserved
kono
parents:
diff changeset
1412
kono
parents:
diff changeset
1413 and Mapping_Preserved
kono
parents:
diff changeset
1414 (E_Left => Elements (Container),
kono
parents:
diff changeset
1415 E_Right => Elements (Container)'Old,
kono
parents:
diff changeset
1416 P_Left => Positions (Container),
kono
parents:
diff changeset
1417 P_Right => Positions (Container)'Old)
kono
parents:
diff changeset
1418 and P.Keys_Included_Except
kono
parents:
diff changeset
1419 (Positions (Container)'Old,
kono
parents:
diff changeset
1420 Positions (Container),
kono
parents:
diff changeset
1421 Find (Container, Key)'Old);
kono
parents:
diff changeset
1422
kono
parents:
diff changeset
1423 function Find (Container : Set; Key : Key_Type) return Cursor with
kono
parents:
diff changeset
1424 Global => null,
kono
parents:
diff changeset
1425 Contract_Cases =>
kono
parents:
diff changeset
1426
kono
parents:
diff changeset
1427 -- If Key is not contained in Container, Find returns No_Element
kono
parents:
diff changeset
1428
kono
parents:
diff changeset
1429 ((for all E of Model (Container) =>
kono
parents:
diff changeset
1430 not Equivalent_Keys (Key, Generic_Keys.Key (E))) =>
kono
parents:
diff changeset
1431 Find'Result = No_Element,
kono
parents:
diff changeset
1432
kono
parents:
diff changeset
1433 -- Otherwise, Find returns a valid cursor in Container
kono
parents:
diff changeset
1434
kono
parents:
diff changeset
1435 others =>
kono
parents:
diff changeset
1436 P.Has_Key (Positions (Container), Find'Result)
kono
parents:
diff changeset
1437
kono
parents:
diff changeset
1438 -- The key designated by the result of Find is Key
kono
parents:
diff changeset
1439
kono
parents:
diff changeset
1440 and Equivalent_Keys
kono
parents:
diff changeset
1441 (Generic_Keys.Key (Container, Find'Result), Key));
kono
parents:
diff changeset
1442
kono
parents:
diff changeset
1443 function Contains (Container : Set; Key : Key_Type) return Boolean with
kono
parents:
diff changeset
1444 Global => null,
kono
parents:
diff changeset
1445 Post =>
kono
parents:
diff changeset
1446 Contains'Result =
kono
parents:
diff changeset
1447 (for some E of Model (Container) =>
kono
parents:
diff changeset
1448 Equivalent_Keys (Key, Generic_Keys.Key (E)));
kono
parents:
diff changeset
1449
kono
parents:
diff changeset
1450 end Generic_Keys;
kono
parents:
diff changeset
1451
kono
parents:
diff changeset
1452 private
kono
parents:
diff changeset
1453 pragma SPARK_Mode (Off);
kono
parents:
diff changeset
1454
kono
parents:
diff changeset
1455 pragma Inline (Next);
kono
parents:
diff changeset
1456
kono
parents:
diff changeset
1457 type Node_Type is
kono
parents:
diff changeset
1458 record
kono
parents:
diff changeset
1459 Element : Element_Type;
kono
parents:
diff changeset
1460 Next : Count_Type;
kono
parents:
diff changeset
1461 Has_Element : Boolean := False;
kono
parents:
diff changeset
1462 end record;
kono
parents:
diff changeset
1463
kono
parents:
diff changeset
1464 package HT_Types is new
kono
parents:
diff changeset
1465 Ada.Containers.Hash_Tables.Generic_Bounded_Hash_Table_Types (Node_Type);
kono
parents:
diff changeset
1466
kono
parents:
diff changeset
1467 type Set (Capacity : Count_Type; Modulus : Hash_Type) is
kono
parents:
diff changeset
1468 new HT_Types.Hash_Table_Type (Capacity, Modulus) with null record;
kono
parents:
diff changeset
1469
kono
parents:
diff changeset
1470 use HT_Types;
kono
parents:
diff changeset
1471
kono
parents:
diff changeset
1472 Empty_Set : constant Set := (Capacity => 0, Modulus => 0, others => <>);
kono
parents:
diff changeset
1473
kono
parents:
diff changeset
1474 end Ada.Containers.Formal_Hashed_Sets;