forked from rescript-lang/rescript
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsig.ml
executable file
·375 lines (284 loc) · 12.3 KB
/
sig.ml
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
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
(**************************************************************************)
(* *)
(* Ocamlgraph: a generic graph library for OCaml *)
(* Copyright (C) 2004-2010 *)
(* Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles *)
(* *)
(* This software is free software; you can redistribute it and/or *)
(* modify it under the terms of the GNU Library General Public *)
(* License version 2.1, with the special exception on linking *)
(* described in file LICENSE. *)
(* *)
(* This software is distributed in the hope that it will be useful, *)
(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)
(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *)
(* *)
(**************************************************************************)
(** {b Signatures for graph implementations.} *)
(** {2 Signature for ordered and hashable types} *)
(** Signature with only an abstract type. *)
module type ANY_TYPE = sig type t end
(** Signature equivalent to [Set.OrderedType]. *)
module type ORDERED_TYPE = sig type t val compare : t -> t -> int end
(** Signature equivalent to [Set.OrderedType] with a default value. *)
module type ORDERED_TYPE_DFT = sig include ORDERED_TYPE val default : t end
(** Signature equivalent to [Hashtbl.HashedType]. *)
module type HASHABLE = sig
type t
val hash : t -> int
val equal : t -> t -> bool
end
(** Signature merging {!ORDERED_TYPE} and {!HASHABLE}. *)
module type COMPARABLE = sig
type t
val compare : t -> t -> int
val hash : t -> int
val equal : t -> t -> bool
end
(** {2 Signatures for graph implementations} *)
(** Signature for vertices. *)
module type VERTEX = sig
(** Vertices are {!COMPARABLE}. *)
type t
include COMPARABLE with type t := t
(** Vertices are labeled. *)
type label
val create : label -> t
val label : t -> label
end
(** Signature for edges. *)
module type EDGE = sig
(** Edges are {!ORDERED_TYPE}. *)
type t
val compare : t -> t -> int
(** Edges are directed. *)
type vertex
val src : t -> vertex
(** Edge origin. *)
val dst : t -> vertex
(** Edge destination. *)
(** Edges are labeled. *)
type label
val create : vertex -> label -> vertex -> t
(** [create v1 l v2] creates an edge from [v1] to [v2] with label [l] *)
val label : t -> label
(** Get the label of an edge. *)
end
(** Common signature for all graphs. *)
module type G = sig
(** {2 Graph structure} *)
(** Abstract type of graphs *)
type t
(** Vertices have type [V.t] and are labeled with type [V.label]
(note that an implementation may identify the vertex with its
label) *)
module V : VERTEX
type vertex = V.t
(** Edges have type [E.t] and are labeled with type [E.label].
[src] (resp. [dst]) returns the origin (resp. the destination) of a
given edge. *)
module E : EDGE with type vertex = vertex
type edge = E.t
(** Is this an implementation of directed graphs? *)
val is_directed : bool
(** {2 Size functions} *)
val is_empty : t -> bool
val nb_vertex : t -> int
val nb_edges : t -> int
(** Degree of a vertex *)
val out_degree : t -> vertex -> int
(** [out_degree g v] returns the out-degree of [v] in [g].
@raise Invalid_argument if [v] is not in [g]. *)
val in_degree : t -> vertex -> int
(** [in_degree g v] returns the in-degree of [v] in [g].
@raise Invalid_argument if [v] is not in [g]. *)
(** {2 Membership functions} *)
val mem_vertex : t -> vertex -> bool
val mem_edge : t -> vertex -> vertex -> bool
val mem_edge_e : t -> edge -> bool
val find_edge : t -> vertex -> vertex -> edge
(** [find_edge g v1 v2] returns the edge from [v1] to [v2] if it exists.
Unspecified behaviour if [g] has several edges from [v1] to [v2].
@raise Not_found if no such edge exists. *)
val find_all_edges : t -> vertex -> vertex -> edge list
(** [find_all_edges g v1 v2] returns all the edges from [v1] to [v2].
@since ocamlgraph 1.8 *)
(** {2 Successors and predecessors}
You should better use iterators on successors/predecessors (see
Section "Vertex iterators"). *)
val succ : t -> vertex -> vertex list
(** [succ g v] returns the successors of [v] in [g].
@raise Invalid_argument if [v] is not in [g]. *)
val pred : t -> vertex -> vertex list
(** [pred g v] returns the predecessors of [v] in [g].
@raise Invalid_argument if [v] is not in [g]. *)
(** Labeled edges going from/to a vertex *)
val succ_e : t -> vertex -> edge list
(** [succ_e g v] returns the edges going from [v] in [g].
@raise Invalid_argument if [v] is not in [g]. *)
val pred_e : t -> vertex -> edge list
(** [pred_e g v] returns the edges going to [v] in [g].
@raise Invalid_argument if [v] is not in [g]. *)
(** {2 Graph iterators} *)
val iter_vertex : (vertex -> unit) -> t -> unit
(** Iter on all vertices of a graph. *)
val fold_vertex : (vertex -> 'a -> 'a) -> t -> 'a -> 'a
(** Fold on all vertices of a graph. *)
val iter_edges : (vertex -> vertex -> unit) -> t -> unit
(** Iter on all edges of a graph. Edge label is ignored. *)
val fold_edges : (vertex -> vertex -> 'a -> 'a) -> t -> 'a -> 'a
(** Fold on all edges of a graph. Edge label is ignored. *)
val iter_edges_e : (edge -> unit) -> t -> unit
(** Iter on all edges of a graph. *)
val fold_edges_e : (edge -> 'a -> 'a) -> t -> 'a -> 'a
(** Fold on all edges of a graph. *)
val map_vertex : (vertex -> vertex) -> t -> t
(** Map on all vertices of a graph. *)
(** {2 Vertex iterators}
Each iterator [iterator f v g] iters [f] to the successors/predecessors
of [v] in the graph [g] and raises [Invalid_argument] if [v] is not in
[g]. It is the same for functions [fold_*] which use an additional
accumulator.
<b>Time complexity for ocamlgraph implementations:</b>
operations on successors are in O(1) amortized for imperative graphs and
in O(ln(|V|)) for persistent graphs while operations on predecessors are
in O(max(|V|,|E|)) for imperative graphs and in O(max(|V|,|E|)*ln|V|) for
persistent graphs. *)
(** iter/fold on all successors/predecessors of a vertex. *)
val iter_succ : (vertex -> unit) -> t -> vertex -> unit
val iter_pred : (vertex -> unit) -> t -> vertex -> unit
val fold_succ : (vertex -> 'a -> 'a) -> t -> vertex -> 'a -> 'a
val fold_pred : (vertex -> 'a -> 'a) -> t -> vertex -> 'a -> 'a
(** iter/fold on all edges going from/to a vertex. *)
val iter_succ_e : (edge -> unit) -> t -> vertex -> unit
val fold_succ_e : (edge -> 'a -> 'a) -> t -> vertex -> 'a -> 'a
val iter_pred_e : (edge -> unit) -> t -> vertex -> unit
val fold_pred_e : (edge -> 'a -> 'a) -> t -> vertex -> 'a -> 'a
end
(** Signature for persistent (i.e. immutable) graph. *)
module type P = sig
include G
(** A persistent graph is a graph. *)
val empty : t
(** The empty graph. *)
val add_vertex : t -> vertex -> t
(** [add_vertex g v] adds the vertex [v] to the graph [g].
Just return [g] if [v] is already in [g]. *)
val remove_vertex : t -> vertex -> t
(** [remove g v] removes the vertex [v] from the graph [g]
(and all the edges going from [v] in [g]).
Just return [g] if [v] is not in [g].
<b>Time complexity for ocamlgraph implementations:</b>
O(|V|*ln(|V|)) for unlabeled graphs and
O(|V|*max(ln(|V|),D)) for labeled graphs.
D is the maximal degree of the graph. *)
val add_edge : t -> vertex -> vertex -> t
(** [add_edge g v1 v2] adds an edge from the vertex [v1] to the vertex [v2]
in the graph [g].
Add also [v1] (resp. [v2]) in [g] if [v1] (resp. [v2]) is not in [g].
Just return [g] if this edge is already in [g]. *)
val add_edge_e : t -> edge -> t
(** [add_edge_e g e] adds the edge [e] in the graph [g].
Add also [E.src e] (resp. [E.dst e]) in [g] if [E.src e] (resp. [E.dst
e]) is not in [g].
Just return [g] if [e] is already in [g]. *)
val remove_edge : t -> vertex -> vertex -> t
(** [remove_edge g v1 v2] removes the edge going from [v1] to [v2] from the
graph [g]. If the graph is labelled, all the edges going from [v1] to
[v2] are removed from [g].
Just return [g] if this edge is not in [g].
@raise Invalid_argument if [v1] or [v2] are not in [g]. *)
val remove_edge_e : t -> edge -> t
(** [remove_edge_e g e] removes the edge [e] from the graph [g].
Just return [g] if [e] is not in [g].
@raise Invalid_argument if [E.src e] or [E.dst e] are not in [g]. *)
end
(** Signature for imperative (i.e. mutable) graphs. *)
module type I = sig
include G
(** An imperative graph is a graph. *)
val create : ?size:int -> unit -> t
(** [create ()] returns an empty graph. Optionally, a size can be
given, which should be on the order of the expected number of
vertices that will be in the graph (for hash tables-based
implementations). The graph grows as needed, so [size] is
just an initial guess. *)
val clear: t -> unit
(** Remove all vertices and edges from the given graph.
@since ocamlgraph 1.4 *)
val copy : t -> t
(** [copy g] returns a copy of [g]. Vertices and edges (and eventually
marks, see module [Mark]) are duplicated. *)
val add_vertex : t -> vertex -> unit
(** [add_vertex g v] adds the vertex [v] to the graph [g].
Do nothing if [v] is already in [g]. *)
val remove_vertex : t -> vertex -> unit
(** [remove g v] removes the vertex [v] from the graph [g]
(and all the edges going from [v] in [g]).
Do nothing if [v] is not in [g].
<b>Time complexity for ocamlgraph implementations:</b>
O(|V|*ln(D)) for unlabeled graphs and O(|V|*D) for
labeled graphs. D is the maximal degree of the graph. *)
val add_edge : t -> vertex -> vertex -> unit
(** [add_edge g v1 v2] adds an edge from the vertex [v1] to the vertex [v2]
in the graph [g].
Add also [v1] (resp. [v2]) in [g] if [v1] (resp. [v2]) is not in [g].
Do nothing if this edge is already in [g]. *)
val add_edge_e : t -> edge -> unit
(** [add_edge_e g e] adds the edge [e] in the graph [g].
Add also [E.src e] (resp. [E.dst e]) in [g] if [E.src e] (resp. [E.dst
e]) is not in [g].
Do nothing if [e] is already in [g]. *)
val remove_edge : t -> vertex -> vertex -> unit
(** [remove_edge g v1 v2] removes the edge going from [v1] to [v2] from the
graph [g]. If the graph is labelled, all the edges going from [v1] to
[v2] are removed from [g].
Do nothing if this edge is not in [g].
@raise Invalid_argument if [v1] or [v2] are not in [g]. *)
val remove_edge_e : t -> edge -> unit
(** [remove_edge_e g e] removes the edge [e] from the graph [g].
Do nothing if [e] is not in [g].
@raise Invalid_argument if [E.src e] or [E.dst e] are not in [g]. *)
end
(** Signature for edges' weights. *)
module type WEIGHT = sig
type edge
(** Type for graph edges. *)
type t
(** Type of edges' weights. *)
val weight : edge -> t
(** Get the weight of an edge. *)
val compare : t -> t -> int
(** Weights must be ordered. *)
val add : t -> t -> t
(** Addition of weights. *)
val zero : t
(** Neutral element for {!add}. *)
end
(** Signature for marks on vertices. *)
module type MARK = sig
type graph
(** Type of graphs. *)
type vertex
(** Type of graph vertices. *)
val clear : graph -> unit
(** [clear g] sets all the marks to 0 for all the vertices of [g]. *)
val get : vertex -> int
(** Mark value (in O(1)). *)
val set : vertex -> int -> unit
(** Set the mark of the given vertex. *)
end
(** Signature for imperative graphs with marks on vertices. *)
module type IM = sig
include I
(** An imperative graph with marks is an imperative graph. *)
(** Mark on vertices.
Marks can be used if you want to store some information on vertices:
it is more efficient to use marks than an external table. *)
module Mark : MARK with type graph = t and type vertex = vertex
end
(*
Local Variables:
compile-command: "make -C .."
End:
*)