wl_lib_0.1.3_1c94dc7c/src/wl-graphs.ads

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
with Ada.Containers;

private with Ada.Containers.Doubly_Linked_Lists;
private with Ada.Containers.Vectors;

generic
   type Index_Type is range <>;
   type Vertex_Type is private;
   type Cost_Type is digits <>;

   Default_Cost  : Cost_Type := 1.0;

   with function Index_Of (Vertex : Vertex_Type) return Index_Type;
   with function "=" (Left, Right : Vertex_Type) return Boolean is <>;
package WL.Graphs is

   subtype Count_Type is Ada.Containers.Count_Type;

   subtype Extended_Index is Index_Type'Base
     range Index_Type'First - 1 ..
     Index_Type'Min (Index_Type'Base'Last - 1, Index_Type'Last) + 1;

   type Graph is tagged private;

   function Is_Empty
     (Container : Graph)
      return Boolean;

   function Vertex
     (Container : Graph;
      Index     : Index_Type)
      return Vertex_Type
     with Inline;

   function Contains
     (Container : Graph;
      Vertex    : Vertex_Type)
      return Boolean;

   function Last_Vertex_Index
     (Container : Graph)
      return Extended_Index;

   procedure Append
     (Container : in out Graph;
      Vertex    : Vertex_Type)
     with Pre => not Container.Contains (Vertex);

   function Edge_Count
     (Container : Graph;
      Vertex    : Index_Type)
      return Count_Type;

   function Connected
     (Container    : Graph;
      From, To     : Index_Type)
      return Boolean;

   function Edge_Cost
     (Container    : Graph;
      From, To     : Index_Type)
      return Cost_Type
     with Pre => Container.Connected (From, To);

   procedure Connect
     (Container : in out Graph'Class;
      From, To  : Index_Type;
      Cost      : Cost_Type := Default_Cost)
     with Pre => not Container.Connected (From, To);

   type Cursor is private;

   procedure Iterate
     (Container : Graph;
      Process   : not null access procedure (Position : Cursor));

   procedure Iterate_Edges
     (Container : Graph;
      From      : Index_Type;
      Process   : not null access procedure (To : Index_Type;
                                             Cost : Cost_Type));

   procedure Iterate_Edges
     (Container : Graph;
      From      : Vertex_Type;
      Process   : not null access
        procedure (To : Vertex_Type;
                   Cost : Cost_Type));

   function Edge
     (Container : Graph;
      From      : Vertex_Type;
      Index     : Count_Type)
      return Vertex_Type;

   function Breadth_First_Search
     (Container : Graph;
      Start     : Vertex_Type;
      Test      : not null access
        function (Vertex : Vertex_Type) return Boolean)
      return Vertex_Type;

   type Sub_Graph is private;

   procedure Create
     (Container : Graph'Class;
      Sub       : out Sub_Graph);

   procedure Append
     (Sub   : in out Sub_Graph;
      Index : Index_Type);

   function Contains
     (Sub : Sub_Graph;
      Index : Index_Type)
      return Boolean;

   procedure Depth_First_Search
     (Container : Graph;
      Start     : Index_Type;
      Max       : Cost_Type;
      Result    : out Sub_Graph);

   procedure Breadth_First_Search
     (Container : Graph;
      Start     : Index_Type;
      Max       : Cost_Type;
      Result    : out Sub_Graph);

   procedure Breadth_First_Search
     (Container : Graph;
      Start     : Index_Type;
      Max_Steps : Count_Type;
      Result    : out Sub_Graph);

   procedure Breadth_First_Search
     (Container : Graph;
      Start     : Index_Type;
      Test      : not null access
        function (Vertex : Vertex_Type) return Boolean;
      Result    : out Sub_Graph);

   procedure Connected_Sub_Graph
     (Container : Graph;
      Start     : Vertex_Type;
      Is_Member : not null access
        function (Vertex : Vertex_Type) return Boolean;
      Result    : out Sub_Graph);

   procedure Iterate
     (Sub     : Sub_Graph;
      Process : not null access procedure (Vertex : Vertex_Type));

   type Sub_Graph_Collection is private;

   function Contains
     (Collection : Sub_Graph_Collection;
      Index      : Index_Type)
      return Boolean;

   procedure Append
     (Collection : in out Sub_Graph_Collection;
      Sub        : Sub_Graph);

   function Sub_Graph_Count
     (Collection : Sub_Graph_Collection)
      return Natural;

   function Get_Sub_Graph
     (Collection : Sub_Graph_Collection;
      Index      : Positive)
      return Sub_Graph
     with Pre => Index <= Sub_Graph_Count (Collection);

   function Same_Sub_Graph
     (Collection : Sub_Graph_Collection;
      V1, V2     : Index_Type)
      return Boolean;

   procedure Get_Connected_Components
     (Container : Graph'Class;
      Result    : out Sub_Graph_Collection);

   procedure Insert
     (Collection : in out Sub_Graph_Collection;
      Sub        : Sub_Graph);

   type Path is private;

   function Cost (P : Path) return Cost_Type;
   function Vertex_Count (P : Path) return Extended_Index;
   function Next (Container : Graph;
                  P         : Path)
                  return Vertex_Type
     with Pre => Vertex_Count (P) > 1;

   type Array_Of_Vertices is array (Positive range <>) of Index_Type;

   function Path_Vertices
     (Container : Graph;
      P         : Path)
      return Array_Of_Vertices;

   function Shortest_Path
     (Container : Graph'Class;
      From, To  : Index_Type)
      return Path;

   function Shortest_Path
     (Container : Graph'Class;
      From, To  : Index_Type;
      Test_Vertex : not null access
        function (Vertex : Vertex_Type) return Boolean)
      return Path;

   function Shortest_Path
     (Container : Graph'Class;
      From, To  : Index_Type;
      Cost      : not null access
        function (From, To : Vertex_Type) return Cost_Type)
      return Path;

   function Shortest_Path
     (Container : Graph'Class;
      From, To  : Index_Type;
      Cost      : not null access
        function (From, To : Vertex_Type) return Cost_Type;
      Estimate  : not null access
        function (From, To : Vertex_Type) return Cost_Type)
      return Path;

   function Shortest_Path
     (Container      : Graph'Class;
      Start, Finish  : Index_Type;
      Passable       : not null access
        function (From, To : Vertex_Type) return Boolean;
      Cost           : not null access
        function (From, To : Vertex_Type) return Cost_Type;
      Estimate       : not null access
        function (From, To : Vertex_Type) return Cost_Type)
      return Path;

   procedure Breadth_First_Scan
     (Container : Graph;
      Start     : Index_Type;
      Process   : not null access
        procedure (Path_To : Path));

private

   type Edge_Type is
      record
         To   : Index_Type;
         Cost : Cost_Type;
      end record;

   package Edge_Lists is
     new Ada.Containers.Doubly_Linked_Lists (Edge_Type);

   type Vertex_Info is
      record
         Vertex : Vertex_Type;
         Index  : Index_Type;
         Edges  : Edge_Lists.List;
      end record;

   package Vertex_Info_Vectors is
     new Ada.Containers.Vectors (Index_Type, Vertex_Info);

   package Vertex_Vectors is
     new Ada.Containers.Vectors (Index_Type, Vertex_Type);

   type Graph is tagged
      record
         Vertices : Vertex_Info_Vectors.Vector;
         Vs       : Vertex_Vectors.Vector;
      end record;

   type Cursor is new Vertex_Info_Vectors.Cursor;

   package Index_Lists is
     new Ada.Containers.Doubly_Linked_Lists (Index_Type);

   package Index_Flag_Vectors is
     new Ada.Containers.Vectors (Index_Type, Boolean);

   type Sub_Graph is
      record
         Main_Graph   : access constant Graph'Class;
         Vertex_List  : Index_Lists.List;
         Vertex_Flags : Index_Flag_Vectors.Vector;
      end record;

   package Sub_Graph_Vectors is
     new Ada.Containers.Vectors (Positive, Sub_Graph);

   type Sub_Graph_Collection is
      record
         Vector : Sub_Graph_Vectors.Vector;
      end record;

   type Path is
      record
         Cost : Cost_Type := 0.0;
         List : Index_Lists.List;
      end record;

   function Index_Of
     (Container : Graph;
      Vertex    : Vertex_Type)
      return Extended_Index;

   function Edge_Count
     (Container : Graph;
      Vertex    : Index_Type)
      return Count_Type
   is (Container.Vertices.Element (Vertex).Edges.Length);

   function Is_Empty
     (Container : Graph)
      return Boolean
   is (Container.Vs.Is_Empty);

end WL.Graphs;