annotate gcc/ada/libgnat/a-cforse.ads @ 131:84e7813d76e9

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