stubs for LazyGraph functions;

added LazyGraph to containers.mllib
This commit is contained in:
Simon Cruanes 2013-03-19 00:32:37 +01:00
parent f3206ca019
commit a3c7b70e53
3 changed files with 287 additions and 12 deletions

View file

@ -1,14 +1,15 @@
Vector Cache
Deque Deque
Enum Enum
Graph
Cache
FlatHashtbl
FHashtbl FHashtbl
FQueue FQueue
FlatHashtbl
Graph
Hashset Hashset
Heap
LazyGraph
PHashtbl
Sequence Sequence
SplayTree SplayTree
PHashtbl
Heap
Univ Univ
Vector

View file

@ -25,3 +25,273 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
(** {1 Lazy graph data structure} *) (** {1 Lazy graph data structure} *)
module type S = sig
(** This module serves to represent directed graphs in a lazy fashion. Such
a graph is always accessed from a given initial node (so only connected
components can be represented by a single value of type ('v,'e) t). *)
(** {2 Type definitions} *)
type vertex
(** The concrete type of a vertex. Vertices are considered unique within
the graph. *)
type ('v, 'e) t = vertex -> ('v, 'e) node
(** Lazy graph structure. Vertices are annotated with values of type 'v,
and edges are of type 'e. A graph is a function that maps vertices
to a label and some edges to other vertices. *)
and ('v, 'e) node =
| Empty
| Node of vertex * 'v * ('e * vertex) Enum.t
(** A single node of the graph, with outgoing edges *)
(** {2 Basic constructors} *)
(** It is difficult to provide generic combinators to build graphs. The problem
is that if one wants to "update" a node, it's still very hard to update
how other nodes re-generate the current node at the same time. *)
val empty : ('v, 'e) t
(** Empty graph *)
val singleton : vertex -> 'v -> ('v, 'e) t
(** Trivial graph, composed of one node *)
val from_enum : vertices:(vertex * 'v) Enum.t ->
edges:(vertex * 'e * vertex) Enum.t ->
('v, 'e) t
(** Concrete (eager) representation of a Graph *)
val from_fun : (vertex -> ('v * ('e * vertex) list) option) -> ('v, 'e) t
(** Convenient semi-lazy implementation of graphs *)
(** {2 Traversals} *)
(** {3 Full interface to traversals} *)
module Full : sig
type ('v, 'e) traverse_event =
| EnterVertex of vertex * 'v * int * vertex list (* unique ID, trail *)
| ExitVertex of vertex (* trail *)
| MeetEdge of vertex * 'e * vertex * edge_type (* edge *)
and edge_type =
| EdgeForward (* toward non explored vertex *)
| EdgeBackward (* toward the current trail *)
| EdgeTransverse (* toward a totally explored part of the graph *)
val bfs_full : ?id:int -> ('v, 'e) t -> vertex -> ('v, 'e) traverse_event Enum.t
val dfs_full : ?id:int -> ('v, 'e) t -> vertex -> ('v, 'e) traverse_event Enum.t
(** Lazy traversal in depth first *)
end
(** The traversal functions assign a unique ID to every traversed node *)
val bfs : ?id:int -> ('v, 'e) t -> vertex -> (vertex * 'v * int) Enum.t
(** Lazy traversal in breadth first *)
val dfs : ?id:int -> ('v, 'e) t -> vertex -> (vertex * 'v * int) Enum.t
(** Lazy traversal in depth first *)
val enum : ('v, 'e) t -> vertex -> (vertex * 'v) Enum.t * (vertex * 'e * vertex) Enum.t
(** Convert to an enumeration. The traversal order is undefined. *)
val depth : (_, 'e) t -> vertex -> (int, 'e) t
(** Map vertices to their depth, ie their distance from the initial point *)
type 'e path = (vertex * 'e * vertex) list
val min_path : ?distance:(vertex -> 'e -> vertex -> int) ->
('v, 'e) t -> vertex -> vertex ->
int * 'e path
(** Minimal path from the given Graph from the first vertex to
the second. It returns both the distance and the path *)
(** {2 Lazy transformations} *)
val union : ?combine:('v -> 'v -> 'v) -> ('v, 'e) t -> ('v, 'e) t -> ('v, 'e) t
(** Lazy union of the two graphs. If they have common vertices,
[combine] is used to combine the labels. By default, the second
label is dropped and only the first is kept *)
val map : vertices:('v -> 'v2) -> edges:('e -> 'e2) ->
('v, 'e) t -> ('v2, 'e2) t
(** Map vertice and edge labels *)
val filter : ?vertices:(vertex -> 'v -> bool) ->
?edges:(vertex -> 'e -> vertex -> bool) ->
('v, 'e) t -> ('v, 'e) t
(** Filter out vertices and edges that do not satisfy the given
predicates. The default predicates always return true. *)
val limit_depth : max:int -> ('v, 'e) t -> ('v, 'e) t
(** Return the same graph, but with a bounded depth. Vertices whose
depth is too high will be replaced by Empty *)
module Infix : sig
val (++) : ('v, 'e) t -> ('v, 'e) t -> ('v, 'e) t
(** Union of graphs (alias for {! union}) *)
end
(** {2 Pretty printing in the DOT (graphviz) format *)
module Dot : sig
type graph
(** A DOT graph *)
val empty : string -> graph
(** Create an empty graph with the given name *)
type attribute = [
| `Color of string
| `Shape of string
| `Weight of int
| `Style of string
| `Label of string
| `Other of string * string
] (** Dot attribute *)
val add : print_edge:(vertex -> 'e -> vertex -> attribute list) ->
print_vertex:(vertex -> 'v -> attribute list) ->
graph ->
('v,'e) t -> vertex Enum.t ->
graph
(** Add the given vertices of the graph to the DOT graph *)
val pp : Format.formatter -> graph -> unit
(** Pretty print the graph in DOT, on the given formatter. *)
val to_string : graph -> string
(** Pretty print the graph in a string *)
end
end
(** {2 Module type for hashable types} *)
module type HASHABLE = sig
type t
val equal : t -> t -> bool
val hash : t -> int
end
(** {2 Implementation of HASHABLE with physical equality and hash} *)
module PhysicalHash(X : sig type t end) : HASHABLE with type t = X.t
= struct
type t = X.t
let equal a b = a == b
let hash a = Hashtbl.hash a
end
(** {2 Build a graph} *)
module Make(X : HASHABLE) : S with type vertex = X.t = struct
(** {2 Type definitions} *)
type vertex = X.t
(** The concrete type of a vertex. Vertices are considered unique within
the graph. *)
type ('v, 'e) t = vertex -> ('v, 'e) node
(** Lazy graph structure. Vertices are annotated with values of type 'v,
and edges are of type 'e. A graph is a function that maps vertices
to a label and some edges to other vertices. *)
and ('v, 'e) node =
| Empty
| Node of vertex * 'v * ('e * vertex) Enum.t
(** A single node of the graph, with outgoing edges *)
(** {2 Basic constructors} *)
let empty =
fun _ -> Empty
let singleton v label =
fun v' ->
if X.equal v v' then Node (v, label, Enum.empty) else Empty
let from_enum ~vertices ~edges = failwith "from_enum: not implemented"
let from_fun f =
fun v ->
match f v with
| None -> Empty
| Some (l, edges) -> Node (v, l, Enum.of_list edges)
(** {2 Traversals} *)
(** {3 Full interface to traversals} *)
module Full = struct
type ('v, 'e) traverse_event =
| EnterVertex of vertex * 'v * int * vertex list (* unique ID, trail *)
| ExitVertex of vertex (* trail *)
| MeetEdge of vertex * 'e * vertex * edge_type (* edge *)
and edge_type =
| EdgeForward (* toward non explored vertex *)
| EdgeBackward (* toward the current trail *)
| EdgeTransverse (* toward a totally explored part of the graph *)
let bfs_full ?(id=0) graph v = Enum.empty (* TODO *)
let dfs_full ?(id=0) graph v = Enum.empty (* TODO *)
end
let bfs ?id graph v = Enum.empty (* TODO *)
let dfs ?id graph v = Enum.empty (* TODO *)
let enum graph v = (Enum.empty, Enum.empty) (* TODO *)
let depth graph v = failwith "not implemented"
type 'e path = (vertex * 'e * vertex) list
(** Minimal path from the given Graph from the first vertex to
the second. It returns both the distance and the path *)
let min_path ?(distance=fun v1 e v2 -> 1) graph v1 v2 = failwith "not implemented"
(** {2 Lazy transformations} *)
let union ?(combine=fun x y -> x) g1 g2 =
fun v ->
match g1 v, g2 v with
| Empty, Empty -> Empty
| ((Node _) as n), Empty -> n
| Empty, ((Node _) as n) -> n
| Node (_, l1, e1), Node (_, l2, e2) ->
Node (v, combine l1 l2, Enum.append e1 e2)
let map ~vertices ~edges g = failwith "not implemented"
let filter ?(vertices=fun v l -> true) ?(edges=fun v1 e v2 -> true) g =
failwith "not implemented"
let limit_depth ~max g = failwith "not implemented"
module Infix = struct
let (++) g1 g2 = union ?combine:None g1 g2
end
module Dot = struct
type graph = Graph of string (* TODO *)
let empty name = Graph name
type attribute = [
| `Color of string
| `Shape of string
| `Weight of int
| `Style of string
| `Label of string
| `Other of string * string
] (** Dot attribute *)
let add ~print_edge ~print_vertex graph g vertices = graph (* TODO *)
let pp formatter graph = failwith "not implemented"
let to_string graph =
let b = Buffer.create 64 in
Format.bprintf b "%a@?" pp graph;
Buffer.contents b
end
end
(** {2 Build a graph based on physical equality} *)
module PhysicalMake(X : sig type t end) : S with type vertex = X.t
= Make(PhysicalHash(X))

View file

@ -49,7 +49,10 @@ module type S = sig
(** It is difficult to provide generic combinators to build graphs. The problem (** It is difficult to provide generic combinators to build graphs. The problem
is that if one wants to "update" a node, it's still very hard to update is that if one wants to "update" a node, it's still very hard to update
how other nodes re-generate the current node at the same time. *) how other nodes re-generate the current node at the same time.
The best way to do it is to build one function that maps the
underlying structure of the type vertex to a graph (for instance,
a concrete data structure, or an URL...). *)
val empty : ('v, 'e) t val empty : ('v, 'e) t
(** Empty graph *) (** Empty graph *)
@ -60,9 +63,9 @@ module type S = sig
val from_enum : vertices:(vertex * 'v) Enum.t -> val from_enum : vertices:(vertex * 'v) Enum.t ->
edges:(vertex * 'e * vertex) Enum.t -> edges:(vertex * 'e * vertex) Enum.t ->
('v, 'e) t ('v, 'e) t
(** Concrete (eager) representation of a Graph *) (** Concrete (eager) representation of a Graph (XXX not implemented)*)
val from_fun : (vertex -> 'v * ('e * vertex) list) -> vertex -> ('v, 'e) t val from_fun : (vertex -> ('v * ('e * vertex) list) option) -> ('v, 'e) t
(** Convenient semi-lazy implementation of graphs *) (** Convenient semi-lazy implementation of graphs *)
(** {2 Traversals} *) (** {2 Traversals} *)
@ -79,6 +82,7 @@ module type S = sig
| EdgeTransverse (* toward a totally explored part of the graph *) | EdgeTransverse (* toward a totally explored part of the graph *)
val bfs_full : ?id:int -> ('v, 'e) t -> vertex -> ('v, 'e) traverse_event Enum.t val bfs_full : ?id:int -> ('v, 'e) t -> vertex -> ('v, 'e) traverse_event Enum.t
(** Lazy traversal in breadth first *)
val dfs_full : ?id:int -> ('v, 'e) t -> vertex -> ('v, 'e) traverse_event Enum.t val dfs_full : ?id:int -> ('v, 'e) t -> vertex -> ('v, 'e) traverse_event Enum.t
(** Lazy traversal in depth first *) (** Lazy traversal in depth first *)
@ -92,10 +96,10 @@ module type S = sig
val dfs : ?id:int -> ('v, 'e) t -> vertex -> (vertex * 'v * int) Enum.t val dfs : ?id:int -> ('v, 'e) t -> vertex -> (vertex * 'v * int) Enum.t
(** Lazy traversal in depth first *) (** Lazy traversal in depth first *)
val enum : ('v, 'e) t -> (vertex * 'v) Enum.t * (vertex * 'e * vertex) Enum.t val enum : ('v, 'e) t -> vertex -> (vertex * 'v) Enum.t * (vertex * 'e * vertex) Enum.t
(** Convert to an enumeration. The traversal order is undefined. *) (** Convert to an enumeration. The traversal order is undefined. *)
val depth : (_, 'e) t -> (int, 'e) t val depth : (_, 'e) t -> vertex -> (int, 'e) t
(** Map vertices to their depth, ie their distance from the initial point *) (** Map vertices to their depth, ie their distance from the initial point *)
type 'e path = (vertex * 'e * vertex) list type 'e path = (vertex * 'e * vertex) list
@ -113,7 +117,7 @@ module type S = sig
[combine] is used to combine the labels. By default, the second [combine] is used to combine the labels. By default, the second
label is dropped and only the first is kept *) label is dropped and only the first is kept *)
val map : ?vertices:('v -> 'v2) -> ?edges:('e -> 'e2) -> val map : vertices:('v -> 'v2) -> edges:('e -> 'e2) ->
('v, 'e) t -> ('v2, 'e2) t ('v, 'e) t -> ('v2, 'e2) t
(** Map vertice and edge labels *) (** Map vertice and edge labels *)