annotate gcc/ada/libgnat/a-cofuse.ads @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents 84e7813d76e9
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 ------------------------------------------------------------------------------
kono
parents:
diff changeset
2 -- --
kono
parents:
diff changeset
3 -- GNAT LIBRARY COMPONENTS --
kono
parents:
diff changeset
4 -- --
kono
parents:
diff changeset
5 -- ADA.CONTAINERS.FUNCTIONAL_SETS --
kono
parents:
diff changeset
6 -- --
kono
parents:
diff changeset
7 -- S p e c --
kono
parents:
diff changeset
8 -- --
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
9 -- Copyright (C) 2016-2019, Free Software Foundation, Inc. --
111
kono
parents:
diff changeset
10 -- --
kono
parents:
diff changeset
11 -- This specification is derived from the Ada Reference Manual for use with --
kono
parents:
diff changeset
12 -- GNAT. The copyright notice above, and the license provisions that follow --
kono
parents:
diff changeset
13 -- apply solely to the contents of the part following the private keyword. --
kono
parents:
diff changeset
14 -- --
kono
parents:
diff changeset
15 -- GNAT is free software; you can redistribute it and/or modify it under --
kono
parents:
diff changeset
16 -- terms of the GNU General Public License as published by the Free Soft- --
kono
parents:
diff changeset
17 -- ware Foundation; either version 3, or (at your option) any later ver- --
kono
parents:
diff changeset
18 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
kono
parents:
diff changeset
19 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
kono
parents:
diff changeset
20 -- or FITNESS FOR A PARTICULAR PURPOSE. --
kono
parents:
diff changeset
21 -- --
kono
parents:
diff changeset
22 -- As a special exception under Section 7 of GPL version 3, you are granted --
kono
parents:
diff changeset
23 -- additional permissions described in the GCC Runtime Library Exception, --
kono
parents:
diff changeset
24 -- version 3.1, as published by the Free Software Foundation. --
kono
parents:
diff changeset
25 -- --
kono
parents:
diff changeset
26 -- You should have received a copy of the GNU General Public License and --
kono
parents:
diff changeset
27 -- a copy of the GCC Runtime Library Exception along with this program; --
kono
parents:
diff changeset
28 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
kono
parents:
diff changeset
29 -- <http://www.gnu.org/licenses/>. --
kono
parents:
diff changeset
30 ------------------------------------------------------------------------------
kono
parents:
diff changeset
31
kono
parents:
diff changeset
32 pragma Ada_2012;
kono
parents:
diff changeset
33 private with Ada.Containers.Functional_Base;
kono
parents:
diff changeset
34
kono
parents:
diff changeset
35 generic
kono
parents:
diff changeset
36 type Element_Type (<>) is private;
kono
parents:
diff changeset
37
kono
parents:
diff changeset
38 with function Equivalent_Elements
kono
parents:
diff changeset
39 (Left : Element_Type;
kono
parents:
diff changeset
40 Right : Element_Type) return Boolean is "=";
kono
parents:
diff changeset
41
kono
parents:
diff changeset
42 Enable_Handling_Of_Equivalence : Boolean := True;
kono
parents:
diff changeset
43 -- This constant should only be set to False when no particular handling
kono
parents:
diff changeset
44 -- of equivalence over elements is needed, that is, Equivalent_Elements
kono
parents:
diff changeset
45 -- defines an element uniquely.
kono
parents:
diff changeset
46
kono
parents:
diff changeset
47 package Ada.Containers.Functional_Sets with SPARK_Mode is
kono
parents:
diff changeset
48
kono
parents:
diff changeset
49 type Set is private with
kono
parents:
diff changeset
50 Default_Initial_Condition => Is_Empty (Set),
kono
parents:
diff changeset
51 Iterable => (First => Iter_First,
kono
parents:
diff changeset
52 Next => Iter_Next,
kono
parents:
diff changeset
53 Has_Element => Iter_Has_Element,
kono
parents:
diff changeset
54 Element => Iter_Element);
kono
parents:
diff changeset
55 -- Sets are empty when default initialized.
kono
parents:
diff changeset
56 -- "For in" quantification over sets should not be used.
kono
parents:
diff changeset
57 -- "For of" quantification over sets iterates over elements.
kono
parents:
diff changeset
58 -- Note that, for proof, "for of" quantification is understood modulo
kono
parents:
diff changeset
59 -- equivalence (the range of quantification comprises all the elements that
kono
parents:
diff changeset
60 -- are equivalent to any element of the set).
kono
parents:
diff changeset
61
kono
parents:
diff changeset
62 -----------------------
kono
parents:
diff changeset
63 -- Basic operations --
kono
parents:
diff changeset
64 -----------------------
kono
parents:
diff changeset
65
kono
parents:
diff changeset
66 -- Sets are axiomatized using Contains, which encodes whether an element is
kono
parents:
diff changeset
67 -- contained in a set. The length of a set is also added to protect Add
kono
parents:
diff changeset
68 -- against overflows but it is not actually modeled.
kono
parents:
diff changeset
69
kono
parents:
diff changeset
70 function Contains (Container : Set; Item : Element_Type) return Boolean with
kono
parents:
diff changeset
71 -- Return True if Item is contained in Container
kono
parents:
diff changeset
72
kono
parents:
diff changeset
73 Global => null,
kono
parents:
diff changeset
74 Post =>
kono
parents:
diff changeset
75 (if Enable_Handling_Of_Equivalence then
kono
parents:
diff changeset
76
kono
parents:
diff changeset
77 -- Contains returns the same result on all equivalent elements
kono
parents:
diff changeset
78
kono
parents:
diff changeset
79 (if (for some E of Container => Equivalent_Elements (E, Item)) then
kono
parents:
diff changeset
80 Contains'Result));
kono
parents:
diff changeset
81
kono
parents:
diff changeset
82 function Length (Container : Set) return Count_Type with
kono
parents:
diff changeset
83 Global => null;
kono
parents:
diff changeset
84 -- Return the number of elements in Container
kono
parents:
diff changeset
85
kono
parents:
diff changeset
86 ------------------------
kono
parents:
diff changeset
87 -- Property Functions --
kono
parents:
diff changeset
88 ------------------------
kono
parents:
diff changeset
89
kono
parents:
diff changeset
90 function "<=" (Left : Set; Right : Set) return Boolean with
kono
parents:
diff changeset
91 -- Set inclusion
kono
parents:
diff changeset
92
kono
parents:
diff changeset
93 Global => null,
kono
parents:
diff changeset
94 Post => "<="'Result = (for all Item of Left => Contains (Right, Item));
kono
parents:
diff changeset
95
kono
parents:
diff changeset
96 function "=" (Left : Set; Right : Set) return Boolean with
kono
parents:
diff changeset
97 -- Extensional equality over sets
kono
parents:
diff changeset
98
kono
parents:
diff changeset
99 Global => null,
kono
parents:
diff changeset
100 Post => "="'Result = (Left <= Right and Right <= Left);
kono
parents:
diff changeset
101
kono
parents:
diff changeset
102 pragma Warnings (Off, "unused variable ""Item""");
kono
parents:
diff changeset
103 function Is_Empty (Container : Set) return Boolean with
kono
parents:
diff changeset
104 -- A set is empty if it contains no element
kono
parents:
diff changeset
105
kono
parents:
diff changeset
106 Global => null,
kono
parents:
diff changeset
107 Post =>
kono
parents:
diff changeset
108 Is_Empty'Result = (for all Item of Container => False)
kono
parents:
diff changeset
109 and Is_Empty'Result = (Length (Container) = 0);
kono
parents:
diff changeset
110 pragma Warnings (On, "unused variable ""Item""");
kono
parents:
diff changeset
111
kono
parents:
diff changeset
112 function Included_Except
kono
parents:
diff changeset
113 (Left : Set;
kono
parents:
diff changeset
114 Right : Set;
kono
parents:
diff changeset
115 Item : Element_Type) return Boolean
kono
parents:
diff changeset
116 -- Return True if Left contains only elements of Right except possibly
kono
parents:
diff changeset
117 -- Item.
kono
parents:
diff changeset
118
kono
parents:
diff changeset
119 with
kono
parents:
diff changeset
120 Global => null,
kono
parents:
diff changeset
121 Post =>
kono
parents:
diff changeset
122 Included_Except'Result =
kono
parents:
diff changeset
123 (for all E of Left =>
kono
parents:
diff changeset
124 Contains (Right, E) or Equivalent_Elements (E, Item));
kono
parents:
diff changeset
125
kono
parents:
diff changeset
126 function Includes_Intersection
kono
parents:
diff changeset
127 (Container : Set;
kono
parents:
diff changeset
128 Left : Set;
kono
parents:
diff changeset
129 Right : Set) return Boolean
kono
parents:
diff changeset
130 with
kono
parents:
diff changeset
131 -- Return True if every element of the intersection of Left and Right is
kono
parents:
diff changeset
132 -- in Container.
kono
parents:
diff changeset
133
kono
parents:
diff changeset
134 Global => null,
kono
parents:
diff changeset
135 Post =>
kono
parents:
diff changeset
136 Includes_Intersection'Result =
kono
parents:
diff changeset
137 (for all Item of Left =>
kono
parents:
diff changeset
138 (if Contains (Right, Item) then Contains (Container, Item)));
kono
parents:
diff changeset
139
kono
parents:
diff changeset
140 function Included_In_Union
kono
parents:
diff changeset
141 (Container : Set;
kono
parents:
diff changeset
142 Left : Set;
kono
parents:
diff changeset
143 Right : Set) return Boolean
kono
parents:
diff changeset
144 with
kono
parents:
diff changeset
145 -- Return True if every element of Container is the union of Left and Right
kono
parents:
diff changeset
146
kono
parents:
diff changeset
147 Global => null,
kono
parents:
diff changeset
148 Post =>
kono
parents:
diff changeset
149 Included_In_Union'Result =
kono
parents:
diff changeset
150 (for all Item of Container =>
kono
parents:
diff changeset
151 Contains (Left, Item) or Contains (Right, Item));
kono
parents:
diff changeset
152
kono
parents:
diff changeset
153 function Is_Singleton
kono
parents:
diff changeset
154 (Container : Set;
kono
parents:
diff changeset
155 New_Item : Element_Type) return Boolean
kono
parents:
diff changeset
156 with
kono
parents:
diff changeset
157 -- Return True Container only contains New_Item
kono
parents:
diff changeset
158
kono
parents:
diff changeset
159 Global => null,
kono
parents:
diff changeset
160 Post =>
kono
parents:
diff changeset
161 Is_Singleton'Result =
kono
parents:
diff changeset
162 (for all Item of Container => Equivalent_Elements (Item, New_Item));
kono
parents:
diff changeset
163
kono
parents:
diff changeset
164 function Not_In_Both
kono
parents:
diff changeset
165 (Container : Set;
kono
parents:
diff changeset
166 Left : Set;
kono
parents:
diff changeset
167 Right : Set) return Boolean
kono
parents:
diff changeset
168 -- Return True if there are no elements in Container that are in Left and
kono
parents:
diff changeset
169 -- Right.
kono
parents:
diff changeset
170
kono
parents:
diff changeset
171 with
kono
parents:
diff changeset
172 Global => null,
kono
parents:
diff changeset
173 Post =>
kono
parents:
diff changeset
174 Not_In_Both'Result =
kono
parents:
diff changeset
175 (for all Item of Container =>
kono
parents:
diff changeset
176 not Contains (Left, Item) or not Contains (Right, Item));
kono
parents:
diff changeset
177
kono
parents:
diff changeset
178 function No_Overlap (Left : Set; Right : Set) return Boolean with
kono
parents:
diff changeset
179 -- Return True if there are no equivalent elements in Left and Right
kono
parents:
diff changeset
180
kono
parents:
diff changeset
181 Global => null,
kono
parents:
diff changeset
182 Post =>
kono
parents:
diff changeset
183 No_Overlap'Result =
kono
parents:
diff changeset
184 (for all Item of Left => not Contains (Right, Item));
kono
parents:
diff changeset
185
kono
parents:
diff changeset
186 function Num_Overlaps (Left : Set; Right : Set) return Count_Type with
kono
parents:
diff changeset
187 -- Number of elements that are both in Left and Right
kono
parents:
diff changeset
188
kono
parents:
diff changeset
189 Global => null,
kono
parents:
diff changeset
190 Post =>
kono
parents:
diff changeset
191 Num_Overlaps'Result = Length (Intersection (Left, Right))
kono
parents:
diff changeset
192 and (if Left <= Right then Num_Overlaps'Result = Length (Left)
kono
parents:
diff changeset
193 else Num_Overlaps'Result < Length (Left))
kono
parents:
diff changeset
194 and (if Right <= Left then Num_Overlaps'Result = Length (Right)
kono
parents:
diff changeset
195 else Num_Overlaps'Result < Length (Right))
kono
parents:
diff changeset
196 and (Num_Overlaps'Result = 0) = No_Overlap (Left, Right);
kono
parents:
diff changeset
197
kono
parents:
diff changeset
198 ----------------------------
kono
parents:
diff changeset
199 -- Construction Functions --
kono
parents:
diff changeset
200 ----------------------------
kono
parents:
diff changeset
201
kono
parents:
diff changeset
202 -- For better efficiency of both proofs and execution, avoid using
kono
parents:
diff changeset
203 -- construction functions in annotations and rather use property functions.
kono
parents:
diff changeset
204
kono
parents:
diff changeset
205 function Add (Container : Set; Item : Element_Type) return Set with
kono
parents:
diff changeset
206 -- Return a new set containing all the elements of Container plus E
kono
parents:
diff changeset
207
kono
parents:
diff changeset
208 Global => null,
kono
parents:
diff changeset
209 Pre =>
kono
parents:
diff changeset
210 not Contains (Container, Item)
kono
parents:
diff changeset
211 and Length (Container) < Count_Type'Last,
kono
parents:
diff changeset
212 Post =>
kono
parents:
diff changeset
213 Length (Add'Result) = Length (Container) + 1
kono
parents:
diff changeset
214 and Contains (Add'Result, Item)
kono
parents:
diff changeset
215 and Container <= Add'Result
kono
parents:
diff changeset
216 and Included_Except (Add'Result, Container, Item);
kono
parents:
diff changeset
217
kono
parents:
diff changeset
218 function Remove (Container : Set; Item : Element_Type) return Set with
kono
parents:
diff changeset
219 -- Return a new set containing all the elements of Container except E
kono
parents:
diff changeset
220
kono
parents:
diff changeset
221 Global => null,
kono
parents:
diff changeset
222 Pre => Contains (Container, Item),
kono
parents:
diff changeset
223 Post =>
kono
parents:
diff changeset
224 Length (Remove'Result) = Length (Container) - 1
kono
parents:
diff changeset
225 and not Contains (Remove'Result, Item)
kono
parents:
diff changeset
226 and Remove'Result <= Container
kono
parents:
diff changeset
227 and Included_Except (Container, Remove'Result, Item);
kono
parents:
diff changeset
228
kono
parents:
diff changeset
229 function Intersection (Left : Set; Right : Set) return Set with
kono
parents:
diff changeset
230 -- Returns the intersection of Left and Right
kono
parents:
diff changeset
231
kono
parents:
diff changeset
232 Global => null,
kono
parents:
diff changeset
233 Post =>
kono
parents:
diff changeset
234 Intersection'Result <= Left
kono
parents:
diff changeset
235 and Intersection'Result <= Right
kono
parents:
diff changeset
236 and Includes_Intersection (Intersection'Result, Left, Right);
kono
parents:
diff changeset
237
kono
parents:
diff changeset
238 function Union (Left : Set; Right : Set) return Set with
kono
parents:
diff changeset
239 -- Returns the union of Left and Right
kono
parents:
diff changeset
240
kono
parents:
diff changeset
241 Global => null,
kono
parents:
diff changeset
242 Pre =>
kono
parents:
diff changeset
243 Length (Left) - Num_Overlaps (Left, Right) <=
kono
parents:
diff changeset
244 Count_Type'Last - Length (Right),
kono
parents:
diff changeset
245 Post =>
kono
parents:
diff changeset
246 Length (Union'Result) =
kono
parents:
diff changeset
247 Length (Left) - Num_Overlaps (Left, Right) + Length (Right)
kono
parents:
diff changeset
248 and Left <= Union'Result
kono
parents:
diff changeset
249 and Right <= Union'Result
kono
parents:
diff changeset
250 and Included_In_Union (Union'Result, Left, Right);
kono
parents:
diff changeset
251
kono
parents:
diff changeset
252 ---------------------------
kono
parents:
diff changeset
253 -- Iteration Primitives --
kono
parents:
diff changeset
254 ---------------------------
kono
parents:
diff changeset
255
kono
parents:
diff changeset
256 type Private_Key is private;
kono
parents:
diff changeset
257
kono
parents:
diff changeset
258 function Iter_First (Container : Set) return Private_Key with
kono
parents:
diff changeset
259 Global => null;
kono
parents:
diff changeset
260
kono
parents:
diff changeset
261 function Iter_Has_Element
kono
parents:
diff changeset
262 (Container : Set;
kono
parents:
diff changeset
263 Key : Private_Key) return Boolean
kono
parents:
diff changeset
264 with
kono
parents:
diff changeset
265 Global => null;
kono
parents:
diff changeset
266
kono
parents:
diff changeset
267 function Iter_Next
kono
parents:
diff changeset
268 (Container : Set;
kono
parents:
diff changeset
269 Key : Private_Key) return Private_Key
kono
parents:
diff changeset
270 with
kono
parents:
diff changeset
271 Global => null,
kono
parents:
diff changeset
272 Pre => Iter_Has_Element (Container, Key);
kono
parents:
diff changeset
273
kono
parents:
diff changeset
274 function Iter_Element
kono
parents:
diff changeset
275 (Container : Set;
kono
parents:
diff changeset
276 Key : Private_Key) return Element_Type
kono
parents:
diff changeset
277 with
kono
parents:
diff changeset
278 Global => null,
kono
parents:
diff changeset
279 Pre => Iter_Has_Element (Container, Key);
kono
parents:
diff changeset
280 pragma Annotate (GNATprove, Iterable_For_Proof, "Contains", Contains);
kono
parents:
diff changeset
281
kono
parents:
diff changeset
282 private
kono
parents:
diff changeset
283
kono
parents:
diff changeset
284 pragma SPARK_Mode (Off);
kono
parents:
diff changeset
285
kono
parents:
diff changeset
286 subtype Positive_Count_Type is Count_Type range 1 .. Count_Type'Last;
kono
parents:
diff changeset
287
kono
parents:
diff changeset
288 function "="
kono
parents:
diff changeset
289 (Left : Element_Type;
kono
parents:
diff changeset
290 Right : Element_Type) return Boolean renames Equivalent_Elements;
kono
parents:
diff changeset
291
kono
parents:
diff changeset
292 package Containers is new Ada.Containers.Functional_Base
kono
parents:
diff changeset
293 (Element_Type => Element_Type,
kono
parents:
diff changeset
294 Index_Type => Positive_Count_Type);
kono
parents:
diff changeset
295
kono
parents:
diff changeset
296 type Set is record
kono
parents:
diff changeset
297 Content : Containers.Container;
kono
parents:
diff changeset
298 end record;
kono
parents:
diff changeset
299
kono
parents:
diff changeset
300 type Private_Key is new Count_Type;
kono
parents:
diff changeset
301
kono
parents:
diff changeset
302 function Iter_First (Container : Set) return Private_Key is (1);
kono
parents:
diff changeset
303
kono
parents:
diff changeset
304 function Iter_Has_Element
kono
parents:
diff changeset
305 (Container : Set;
kono
parents:
diff changeset
306 Key : Private_Key) return Boolean
kono
parents:
diff changeset
307 is
kono
parents:
diff changeset
308 (Count_Type (Key) in 1 .. Containers.Length (Container.Content));
kono
parents:
diff changeset
309
kono
parents:
diff changeset
310 function Iter_Next
kono
parents:
diff changeset
311 (Container : Set;
kono
parents:
diff changeset
312 Key : Private_Key) return Private_Key
kono
parents:
diff changeset
313 is
kono
parents:
diff changeset
314 (if Key = Private_Key'Last then 0 else Key + 1);
kono
parents:
diff changeset
315
kono
parents:
diff changeset
316 function Iter_Element
kono
parents:
diff changeset
317 (Container : Set;
kono
parents:
diff changeset
318 Key : Private_Key) return Element_Type
kono
parents:
diff changeset
319 is
kono
parents:
diff changeset
320 (Containers.Get (Container.Content, Count_Type (Key)));
kono
parents:
diff changeset
321
kono
parents:
diff changeset
322 end Ada.Containers.Functional_Sets;