ocamlgraph-2.0.0/ 0000755 0001750 0000144 00000000000 13735627615 012211 5 ustar rt users ocamlgraph-2.0.0/src/ 0000755 0001750 0000144 00000000000 13735627615 013000 5 ustar rt users ocamlgraph-2.0.0/src/dot.mli 0000644 0001750 0000144 00000003716 13735627615 014300 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(** Parser for DOT file format. *)
open Dot_ast
val parse_dot_ast : string -> Dot_ast.file
type clusters_hash = (string, attr list) Hashtbl.t
(** Provide a parser for DOT file format. *)
module Parse
(B : Builder.S)
(L : sig
val node : node_id -> attr list -> B.G.V.label
(** How to build the node label out of the set of attributes *)
val edge : attr list -> B.G.E.label
(** How to build the edge label out of the set of attributes *)
end) :
sig
(** Parses a dot file *)
val parse : string -> B.G.t
(** Parses a dot file and returns the graph, its bounding box and
a hash table from clusters to dot attributes *)
val parse_bounding_box_and_clusters :
string -> B.G.t * string * clusters_hash
end
ocamlgraph-2.0.0/src/md.mli 0000644 0001750 0000144 00000004410 13735627615 014102 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(** Minimum Degree algorithm
Based on the article:
The Minimum Degree Heuristic and the Minimal Triangulation Process
by A. Berry, Pinar Heggernes & Geneviève Simonet.
@author Matthieu Sozeau
@author Pierre-Loic Garoche *)
module P(G : Sig.P) : sig
type edgeset = (G.V.t * G.V.t) list
val md : G.t -> G.t * edgeset * G.V.t list
(** [md g] return a tuple [(g', e, o)] where [g'] is
a triangulated graph, [e] is the triangulation of [g] and
[o] is a perfect elimination order of [g'] *)
val triangulate : G.t -> G.t
(** [triangulate g] return the graph [g'] produced by applying
miminum degree to [g]. *)
end
module I(G : Sig.I) : sig
type edgeset = (G.V.t * G.V.t) list
val md : G.t -> G.t * edgeset * G.V.t list
(** [md g] return a tuple [(g', e, o)] where [g'] is
a triangulated graph, [e] is the triangulation of [g] and
[o] is a perfect elimination order of [g'] *)
val triangulate : G.t -> G.t
(** [triangulate g] return the graph [g'] produced by applying
miminum degree to [g]. *)
end
ocamlgraph-2.0.0/src/dGraphSubTree.ml 0000644 0001750 0000144 00000024205 13735627615 016034 0 ustar rt users (**************************************************************************)
(* *)
(* This file is part of OcamlGraph. *)
(* *)
(* Copyright (C) 2009-2010 *)
(* CEA (Commissariat � l'�nergie Atomique) *)
(* *)
(* you can redistribute it and/or modify it under the terms of the GNU *)
(* Lesser General Public License as published by the Free Software *)
(* Foundation, version 2.1, with a linking exception. *)
(* *)
(* It 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. See the *)
(* GNU Lesser General Public License for more details. *)
(* *)
(* See the file ../LICENSE for more details. *)
(* *)
(* Authors: *)
(* - Julien Signoles (Julien.Signoles@cea.fr) *)
(* - Jean-Denis Koeck (jdkoeck@gmail.com) *)
(* - Benoit Bataille (benoit.bataille@gmail.com) *)
(* *)
(**************************************************************************)
module type G = sig
type t
module V : sig
type t
type label
val label : t -> label
val hash : t -> int
val equal : t -> t -> bool
end
module E : sig
type t
end
val iter_succ : (V.t -> unit) -> t -> V.t -> unit
val iter_pred : (V.t -> unit) -> t -> V.t -> unit
val find_edge : t -> V.t -> V.t -> E.t
end
module type Tree = sig
type t
module V : sig
type t
type label
val create : label -> t
val label : t -> label
val hash: t -> int
val equal: t -> t -> bool
end
module E : Sig.EDGE with type vertex = V.t
val create : ?size:int -> unit -> t
val add_vertex : t -> V.t -> unit
val add_edge_e : t -> E.t -> unit
end
module type S = sig
module Tree: Tree with type E.label = unit
type t
val get_structure : t -> Tree.t
val get_root : t -> Tree.V.t
val get_tree_vertices : Tree.V.label -> t -> Tree.V.t list
val is_ghost_node : Tree.V.t -> t -> bool
val is_ghost_edge : Tree.E.t -> t -> bool
exception Ghost_node
val get_graph_vertex : Tree.V.t -> t -> Tree.V.label
end
module Build
(G : G)
(Tree : Tree with type V.label = G.V.t and type E.label = unit)
(GA: sig
type t
val iter_succ: (G.V.t -> unit) -> t -> G.V.t -> unit
val iter_pred: (G.V.t -> unit) -> t -> G.V.t -> unit
end) =
struct
module Tree = Tree
module H = Hashtbl.Make(G.V)
module HT = Hashtbl.Make(Tree.V)
module HE =
Hashtbl.Make
(struct
type t = Tree.E.t
let equal x y = Tree.E.compare x y = 0
let hash = Hashtbl.hash
end)
type t = {
structure: Tree.t; (* the tree itself *)
root : Tree.V.t; (* the root *)
(* nodes of the tree corresponding to the original nodes *)
assoc_vertex_table: Tree.V.t H.t;
ghost_vertices: unit HT.t;
ghost_edges: unit HE.t;
}
(* Getter *)
let get_structure t = t.structure;;
let get_root t = t.root;;
(** Give the list of vertices in the tree graph representing a vertex
from the old graph *)
let get_tree_vertices vertex tree =
try H.find_all tree.assoc_vertex_table vertex
with Not_found -> assert false;;
(** True if the vertex is not to be shown *)
let is_ghost_node v tree = HT.mem tree.ghost_vertices v;;
(** True if the edge is not to be shown *)
let is_ghost_edge e tree = HE.mem tree.ghost_edges e;;
exception Ghost_node;;
(** Give the old graph vertex represented by a vertex in the tree -
@raise Ghost_node if the vertex is a ghost vertex *)
let get_graph_vertex vertex tree =
if is_ghost_node vertex tree then raise Ghost_node
else Tree.V.label vertex;;
(* Explore the graph from a vertex and build a tree -
Will be used forward and backward *)
let build src_graph tree src_vertex tree_root backward_flag depth =
let complete_to_depth v missing =
let pred_vertex = ref v in
let next_vertex = ref v in
for _i = 1 to missing - 1 do
next_vertex := Tree.V.create (Tree.V.label v);
HT.add tree.ghost_vertices !next_vertex ();
let new_ghost_edge =
if backward_flag then Tree.E.create !next_vertex () !pred_vertex
else Tree.E.create !pred_vertex () !next_vertex
in Tree.add_edge_e tree.structure new_ghost_edge;
HE.add tree.ghost_edges new_ghost_edge ();
pred_vertex := !next_vertex;
done
in
let has_succ = ref false in
let vertex_visited = H.create 97 in
let queue = Queue.create () in
H.add vertex_visited src_vertex true;
(* Initialize queue *)
if depth <> 0 then
if backward_flag then
GA.iter_pred
(fun a -> Queue.add (a, tree_root, depth) queue)
src_graph
src_vertex
else
GA.iter_succ
(fun a -> Queue.add (a, tree_root, depth) queue)
src_graph
src_vertex;
(* Empty queue *)
let rec empty_queue () =
if not(Queue.is_empty queue) then begin
let vertex, origin_vertex, depth = Queue.take queue in
if depth > 0 then begin
let new_vertex = Tree.V.create vertex in
H.add tree.assoc_vertex_table vertex new_vertex;
if backward_flag then begin
let new_edge = Tree.E.create new_vertex () origin_vertex in
Tree.add_edge_e tree.structure new_edge
end else begin
let new_edge = Tree.E.create origin_vertex () new_vertex in
Tree.add_edge_e tree.structure new_edge
end;
if not(H.mem vertex_visited vertex) then begin
H.add vertex_visited vertex true;
let iter f =
f
(fun a ->
Queue.add (a, new_vertex, depth - 1) queue;
has_succ := true)
src_graph
vertex
in
if backward_flag then iter GA.iter_pred else iter GA.iter_succ;
if not !has_succ then complete_to_depth new_vertex depth;
has_succ := false;
end else if depth <> 1 then begin
if backward_flag then
GA.iter_pred (fun _ -> has_succ := true) src_graph vertex
else
GA.iter_succ (fun _ -> has_succ := true) src_graph vertex;
if !has_succ then begin
let ghost_vertex = Tree.V.create vertex in
HT.add tree.ghost_vertices ghost_vertex ();
let new_edge =
if backward_flag then Tree.E.create ghost_vertex () new_vertex
else Tree.E.create new_vertex () ghost_vertex
in Tree.add_edge_e tree.structure new_edge;
complete_to_depth ghost_vertex (depth-1)
end else
complete_to_depth new_vertex depth;
has_succ := false;
end
end;
empty_queue ()
end
in
empty_queue ()
(* [JS 2010/11/10] trying to simplify the algorithm. Not finish yet
let new_build graph tree root troot depth backward =
let first = ref true in
let q = Queue.create () in
(* invariant: [h] contains exactly the vertices which have been pushed *)
let must_add_ghost = ref true in
let add_tree_vertex v =
let tv = if !first then troot else Tree.V.create v in
first := false;
Tree.add_vertex tree.structure tv;
H.add tree.assoc_vertex_table v tv;
tv
in
let add_tree_edge tsrc dst =
let tdst = add_tree_vertex dst in
let tsrc, tdst = if backward then tdst, tsrc else tsrc, tdst in
let e = Tree.E.create tsrc () tdst in
Tree.add_edge_e tree.structure e;
tdst, e
in
let push n src dst =
if n < depth then Queue.add (dst, n + 1) q;
ignore (add_tree_edge src dst);
must_add_ghost := false
in
let loop () =
while not (Queue.is_empty q) do
let v, n = Queue.pop q in
let tv = add_tree_vertex v in
must_add_ghost := true;
(if backward then GA.iter_pred else GA.iter_succ) (push n tv) graph v;
if !must_add_ghost then
let tsrc = ref tv in
for i = n to depth do
let tdst, te = add_tree_edge !tsrc v in
HT.add tree.ghost_vertices tdst ();
HE.add tree.ghost_edges te ();
tsrc := tdst
done
done
in
Queue.add (root, 0) q;
loop ()
*)
(** Build a tree graph centered on a vertex and containing its
predecessors and successors *)
let make src_graph src_vertex depth_forward depth_backward =
let tree = {
structure = Tree.create ();
root = Tree.V.create src_vertex;
assoc_vertex_table = H.create 97;
ghost_vertices = HT.create 17;
ghost_edges = HE.create 17;
}
in
H.add tree.assoc_vertex_table src_vertex tree.root;
Tree.add_vertex tree.structure tree.root;
build src_graph tree src_vertex tree.root false depth_forward;
build src_graph tree src_vertex tree.root true depth_backward;
(* new_build src_graph tree src_vertex tree.root depth_forward false;
new_build src_graph tree src_vertex tree.root depth_backward true;*)
tree
end
module Make
(G : G)
(Tree : Tree with type V.label = G.V.t and type E.label = unit) =
Build(G)(Tree)(G)
module Make_from_dot_model
(Tree : Tree with type V.label = DGraphModel.DotG.V.t
and type E.label = unit) =
Build
(DGraphModel.DotG)
(Tree)
(struct
type t = DGraphModel.dotg_model
let iter_succ f g = g#iter_succ f
let iter_pred f g = g#iter_pred f
end)
ocamlgraph-2.0.0/src/dot_ast.mli 0000644 0001750 0000144 00000003745 13735627615 015151 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(* $Id:$ *)
(** AST for DOT file format. *)
type id =
| Ident of string
| Number of string
| String of string
| Html of string
type attr = (id * id option) list
type compass_pt = N | Ne | E | Se | S | Sw | W | Nw
type port =
| PortId of id * compass_pt option
| PortC of compass_pt
type node_id = id * port option
type subgraph =
| SubgraphId of id
| SubgraphDef of id option * stmt list
and node =
| NodeId of node_id
| NodeSub of subgraph
and stmt =
| Node_stmt of node_id * attr list
| Edge_stmt of node * node list * attr list
| Attr_graph of attr list
| Attr_node of attr list
| Attr_edge of attr list
| Equal of id * id
| Subgraph of subgraph
type file =
{ strict : bool;
digraph : bool;
id : id option;
stmts : stmt list }
ocamlgraph-2.0.0/src/imperative.mli 0000644 0001750 0000144 00000013161 13735627615 015652 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(** Imperative Graph Implementations. *)
open Sig
(** Signature of imperative graphs. *)
module type S = sig
(** Edges may be labeled or not :
- Unlabeled: there is no label on edges
- Labeled: you have to provide a label implementation as a functor
parameter.
Vertices may be concrete or abstract :
- Concrete: type of vertex labels and type of vertices are identified.
- Abstract: type of vertices is abstract (in particular it is not equal
to type of vertex labels
How to choose between concrete and abstract vertices for my graph
implementation ?
Usually, if you fall into one of the following cases, use abstract
vertices:
- you cannot provide efficient comparison/hash functions for vertices; or
- you wish to get two different vertices with the same label.
In other cases, it is certainly easier to use concrete vertices. *)
(** Imperative Unlabeled Graphs. *)
module Concrete (V: COMPARABLE) :
Sig.I with type V.t = V.t and type V.label = V.t and type E.t = V.t * V.t
and type E.label = unit
(** Abstract Imperative Unlabeled Graphs. *)
module Abstract(V: ANY_TYPE) :
Sig.IM with type V.label = V.t and type E.label = unit
(** Imperative Labeled Graphs. *)
module ConcreteLabeled (V: COMPARABLE)(E: ORDERED_TYPE_DFT) :
Sig.I with type V.t = V.t and type V.label = V.t
and type E.t = V.t * E.t * V.t and type E.label = E.t
(** Abstract Imperative Labeled Graphs. *)
module AbstractLabeled (V: ANY_TYPE)(E: ORDERED_TYPE_DFT) :
Sig.IM with type V.label = V.t and type E.label = E.t
end
(** Imperative Directed Graphs. *)
module Digraph : sig
include S
(** {2 Bidirectional graphs}
Bidirectional graphs use more memory space (at worse the double) that
standard concrete directional graphs. But accessing predecessors is in
O(1) amortized instead of O(max(|V|,|E|)) and removing a vertex is in
O(D*ln(D)) instead of O(|V|*ln(D)). D is the maximal degree of the
graph. *)
(** Imperative Unlabeled, bidirectional graph. *)
module ConcreteBidirectional (V: COMPARABLE) :
Sig.I with type V.t = V.t and type V.label = V.t and type E.t = V.t * V.t
and type E.label = unit
(** Imperative Labeled and bidirectional graph. *)
module ConcreteBidirectionalLabeled(V:COMPARABLE)(E:ORDERED_TYPE_DFT) :
Sig.I with type V.t = V.t and type V.label = V.t
and type E.t = V.t * E.t * V.t and type E.label = E.t
end
(** Imperative Undirected Graphs. *)
module Graph : S
(** Imperative graphs implemented as adjacency matrices. *)
module Matrix : sig
module type S = sig
(** Vertices are integers in [0..n-1].
A vertex label is the vertex itself.
Edges are unlabeled. *)
include Sig.I with type V.t = int and type V.label = int
and type E.t = int * int
(** Creation. graphs are not resizeable: size is given at creation time.
Thus [make] must be used instead of [create]. *)
val make : int -> t
(** Note: [add_vertex] and [remove_vertex] have no effect.
[clear] only removes edges, not vertices. *)
end
module Digraph : S
(** Imperative Directed Graphs implemented with adjacency matrices. *)
module Graph : S
(** Imperative Undirected Graphs implemented with adjacency matrices. *)
end
(****
(** Faster implementations for abstract (un)labeled (di)graphs
when vertices are _not shared_ between different graphs.
This means that, when using the following implementations, two different
graphs (created with two calls to [create]) must have disjoint sets of
vertices. *)
module UV : sig
(** directed graphs *)
module Digraph : sig
module Abstract(V: ANY_TYPE) :
Sig.IM with type V.label = V.t and type E.label = unit
module AbstractLabeled (V: ANY_TYPE)(E: ORDERED_TYPE_DFT) :
Sig.IM with type V.label = V.t and type E.label = E.t
end
(** undirected graphs *)
module Graph : sig
module Abstract(V: ANY_TYPE) :
Sig.IM with type V.label = V.t and type E.label = unit
module AbstractLabeled (V: ANY_TYPE)(E: ORDERED_TYPE_DFT) :
Sig.IM with type V.label = V.t and type E.label = E.t
end
end
****)
(*
Local Variables:
compile-command: "make -C .."
End:
*)
ocamlgraph-2.0.0/src/dGraphModel.ml 0000644 0001750 0000144 00000021461 13735627615 015524 0 ustar rt users (**************************************************************************)
(* *)
(* This file is part of OcamlGraph. *)
(* *)
(* Copyright (C) 2009-2010 *)
(* CEA (Commissariat � l'�nergie Atomique) *)
(* *)
(* you can redistribute it and/or modify it under the terms of the GNU *)
(* Lesser General Public License as published by the Free Software *)
(* Foundation, version 2.1, with a linking exception. *)
(* *)
(* It 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. See the *)
(* GNU Lesser General Public License for more details. *)
(* *)
(* See the file ../LICENSE for more details. *)
(* *)
(* Authors: *)
(* - Julien Signoles (Julien.Signoles@cea.fr) *)
(* - Jean-Denis Koeck (jdkoeck@gmail.com) *)
(* - Benoit Bataille (benoit.bataille@gmail.com) *)
(* *)
(**************************************************************************)
(* This graph model is for now immutable, no adding or removing nodes. *)
open XDot
exception DotError of string
(* ABSTRACT CLASS *)
class type ['vertex, 'edge, 'cluster] abstract_model = object
method iter_edges : ('vertex -> 'vertex -> unit) -> unit
method iter_edges_e : ('edge -> unit) -> unit
method iter_pred : ('vertex -> unit) -> 'vertex -> unit
method iter_pred_e : ('edge -> unit) -> 'vertex -> unit
method iter_succ : ('vertex -> unit) -> 'vertex -> unit
method iter_succ_e : ('edge -> unit) -> 'vertex -> unit
method iter_vertex : ('vertex -> unit) -> unit
method iter_clusters : ('cluster -> unit) -> unit
method iter_associated_vertex : ('vertex -> unit) -> 'vertex -> unit
(** Membership functions *)
method find_edge : 'vertex -> 'vertex -> 'edge
method mem_edge : 'vertex -> 'vertex -> bool
method mem_edge_e : 'edge -> bool
method mem_vertex : 'vertex -> bool
method src : 'edge -> 'vertex
method dst : 'edge -> 'vertex
(** Dot layout *)
method bounding_box : bounding_box
method get_edge_layout : 'edge -> edge_layout
method get_vertex_layout : 'vertex -> node_layout
method get_cluster_layout : 'cluster -> cluster_layout
end
(* BUILDING A MODEL WITH AN OCAML GRAPH *)
module Make(G : Graphviz.GraphWithDotAttrs)
= struct
exception Multiple_layouts of (G.E.t * edge_layout) list
type cluster = string
module X = XDot.Make(G)
class model layout g : [G.vertex, G.edge, cluster] abstract_model =
object (self)
(* Iterators *)
method iter_edges f = G.iter_edges f g
method iter_edges_e f = G.iter_edges_e f g
method iter_pred f v = G.iter_pred f g v
method iter_pred_e f v = G.iter_pred_e f g v
method iter_succ f = G.iter_succ f g
method iter_succ_e f = G.iter_succ_e f g
method iter_vertex f = G.iter_vertex f g
method iter_associated_vertex f v = f v
method iter_clusters f =
Hashtbl.iter (fun k _ -> f k) layout.X.cluster_layouts
(* Membership functions *)
method find_edge = try G.find_edge g with Not_found -> assert false
method mem_edge = G.mem_edge g
method mem_edge_e = G.mem_edge_e g
method mem_vertex = G.mem_vertex g
method src = G.E.src
method dst = G.E.dst
(* Layout *)
method bounding_box = layout.X.bbox
method get_vertex_layout v =
try X.HV.find layout.X.vertex_layouts v
with Not_found -> assert false
method get_edge_layout e =
try X.HE.find e layout.X.edge_layouts
with Not_found ->
(* if there are several edges from a vertex [v1] to a vertex [v2], they
can share the same layout. In that case, one these edges is
unfortunately not in the layout table because of key sharing. Try to
recover it when possible by creating a list of all possible layouts
for the given edge. If there is only one, easy win, otherwise return
them all in an exception and let the caller decide what to do *)
let layouts = ref [] in
self#iter_succ_e
(fun e' ->
if G.V.equal (self#dst e) (self#dst e') then
try
let layout = X.HE.find e' layout.X.edge_layouts in
if not (List.exists (fun (_, l) -> layout = l) !layouts) then
layouts := (e', layout) :: !layouts
with Not_found -> ())
(self#src e);
match !layouts with
| [] -> assert false
| [ _, x ] -> x
| _ :: _ :: _ -> raise (Multiple_layouts !layouts)
method get_cluster_layout c =
try Hashtbl.find layout.X.cluster_layouts c
with Not_found -> assert false
end
let from_graph ?(cmd="dot") ?(tmp_name = "dgraph") g =
(* Output dot file *)
let module DumpDot = Graphviz.Dot(G) in
let dot_file, out = Filename.open_temp_file tmp_name ".dot" in
DumpDot.output_graph out g;
close_out out;
(* Get layout from dot file *)
let layout =
try X.layout_of_dot ~cmd ~dot_file g
with X.DotError err -> raise (DotError err)
in
let model = new model layout g in
Sys.remove dot_file;
model
end
(* BUILDING A MODEL WITH A DOT FILE *)
(* Here we build a model from a graph where vertices and edges
are labeled with xdot layouts *)
module Vertex = struct
type t = XDot.node_layout
end
module Edge = struct
type t = XDot.edge_layout
let default = XDot.mk_edge_layout
~draw:[] ~ldraw:[] ~hdraw:[] ~tdraw:[] ~hldraw:[] ~tldraw:[]
let compare : t -> t -> int = Stdlib.compare
end
module DotG = Imperative.Digraph.AbstractLabeled(Vertex)(Edge)
module DotB = Builder.I(DotG)
type cluster = string
type dotg_model = (DotG.vertex, DotG.edge, cluster) abstract_model
module DotParser =
Dot.Parse
(DotB)
(struct
(* Read the attributes of a node *)
let node = XDot.read_node_layout
(* Read edge attributes *)
let edge = XDot.read_edge_layout
end)
module DotModel = struct
type cluster = string
class model g clusters_hash bounding_box
: [DotG.vertex, DotG.edge, cluster] abstract_model
=
object
(* Iterators *)
method iter_edges f = DotG.iter_edges f g
method iter_edges_e f = DotG.iter_edges_e f g
method iter_pred f v = DotG.iter_pred f g v
method iter_pred_e f v = DotG.iter_pred_e f g v
method iter_succ f = DotG.iter_succ f g
method iter_succ_e f = DotG.iter_succ_e f g
method iter_vertex f = DotG.iter_vertex f g
method iter_associated_vertex f v = f v
method iter_clusters f = Hashtbl.iter (fun k _ -> f k) clusters_hash
(* Membership functions *)
method find_edge = try DotG.find_edge g with Not_found -> assert false
method mem_edge = DotG.mem_edge g
method mem_edge_e = DotG.mem_edge_e g
method mem_vertex = DotG.mem_vertex g
method src = DotG.E.src
method dst = DotG.E.dst
(* Layout *)
method bounding_box = bounding_box
method get_vertex_layout = DotG.V.label
method get_edge_layout = DotG.E.label
method get_cluster_layout c =
let attrs =
try Hashtbl.find clusters_hash c with Not_found -> assert false
in
XDot.read_cluster_layout attrs
end
let model = new model
end
(* Runs graphviz, parses the graph and instantiates the model *)
let read_dot ?(cmd="dot") dot_file =
let basename = try Filename.chop_extension dot_file
with Invalid_argument _ -> dot_file in
let xdot_file = basename ^ ".xdot" in
let dot_cmd = Printf.sprintf "%s -Txdot %s > %s" cmd dot_file xdot_file in
(* Run graphviz *)
match Sys.command dot_cmd with
| 0 -> begin
let graph, bb, clusters_hash =
DotParser.parse_bounding_box_and_clusters xdot_file in
DotModel.model graph clusters_hash (XDot.read_bounding_box bb)
end
| _ -> raise (DotError "Error during dot execution")
(* Does not run graphviz.
Parses a graph from an xdot file and instantiates the model. *)
let read_xdot xdot_file =
let graph, bb, clusters_hash =
DotParser.parse_bounding_box_and_clusters xdot_file
in
DotModel.model graph clusters_hash (XDot.read_bounding_box bb)
ocamlgraph-2.0.0/src/sig.mli 0000644 0001750 0000144 00000030552 13735627615 014272 0 ustar rt users (**************************************************************************)
(* *)
(* 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.
Time complexity for ocamlgraph implementations:
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].
Time complexity for ocamlgraph implementations:
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].
Time complexity for ocamlgraph implementations:
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:
*)
ocamlgraph-2.0.0/src/classic.mli 0000644 0001750 0000144 00000004752 13735627615 015134 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(* $Id: classic.mli,v 1.12 2005-02-25 13:54:33 signoles Exp $ *)
(** Some classic graphs *)
module type S = sig
type graph
val divisors : int -> graph
(** [divisors n] builds the graph of divisors.
Vertices are integers from [2] to [n]. [i] is connected to [j] if
and only if [i] divides [j].
@raise Invalid_argument is [n < 2]. *)
val de_bruijn : int -> graph
(** [de_bruijn n] builds the de Bruijn graph of order [n].
Vertices are bit sequences of length [n] (encoded as their
interpretation as binary integers). The sequence [xw] is connected
to the sequence [wy] for any bits [x] and [y] and any bit sequence
[w] of length [n-1].
@raise Invalid_argument is [n < 1] or [n > Sys.word_size-1]. *)
val vertex_only : int -> graph
(** [vertex_only n] builds a graph with [n] vertices and no edge. *)
val full : ?self:bool -> int -> graph
(** [full n] builds a graph with [n] vertices and all possible edges.
The optional argument [self] indicates if loop edges should be added
(default value is [true]). *)
end
module P (G : Sig.P with type V.label = int) : S with type graph = G.t
(** Classic Persistent Graphs *)
module I (G : Sig.I with type V.label = int) : S with type graph = G.t
(** Classic Imperative Graphs *)
ocamlgraph-2.0.0/src/graphml.ml 0000644 0001750 0000144 00000007303 13735627615 014767 0 ustar rt users (******************************************************************************)
(* *)
(* Copyright (C) 2012 Pietro Abate *)
(* *)
(* This library is free software: you can redistribute it and/or modify *)
(* it under the terms of the GNU Lesser General Public License as *)
(* published by the Free Software Foundation, either version 3 of the *)
(* License, or (at your option) any later version. A special linking *)
(* exception to the GNU Lesser General Public License applies to this *)
(* library, see the COPYING file for more information. *)
(* *)
(******************************************************************************)
module type G = sig
type t
type vertex
module E : sig
type t
val src: t -> vertex
val dst : t -> vertex
end
val is_directed : bool
val iter_vertex : (vertex -> unit) -> t -> unit
val iter_edges_e : (E.t -> unit) -> t -> unit
end
module Print
(G: G)
(L : sig
val vertex_properties : (string * string * string option) list
val edge_properties : (string * string * string option) list
val map_vertex : G.vertex -> (string * string) list
val map_edge : G.E.t -> (string * string) list
val vertex_uid : G.vertex -> int
val edge_uid : G.E.t -> int
end)
= struct
let header =
" \
"
;;
let data_pp fmt (key,value) =
Format.fprintf fmt "%s " key value
let pp_type fmt t prop typ default =
Format.fprintf fmt "" prop t prop typ;
match default with
|None -> Format.fprintf fmt " \n"
|Some s -> begin
Format.fprintf fmt "\n %s \n" s;
Format.fprintf fmt "\n"
end
let print fmt graph =
Format.fprintf fmt "%s\n" header;
(* node attributed declaration *)
List.iter
(fun (prop,typ,default) -> pp_type fmt "node" prop typ default)
L.vertex_properties;
(* edge attributed declaration *)
List.iter
(fun (prop,typ,default) -> pp_type fmt "edge" prop typ default)
L.edge_properties ;
let directed = if G.is_directed then "edgedefault=\"directed\"" else "" in
Format.fprintf fmt "\n" directed;
(* vertex printer *)
G.iter_vertex
(fun vertex ->
let id = L.vertex_uid vertex in
let l = L.map_vertex vertex in
Format.fprintf fmt " \n" id;
List.iter (Format.fprintf fmt " %a\n" data_pp) l;
Format.fprintf fmt " \n")
graph ;
(* edge printer *)
G.iter_edges_e
(fun edge ->
let n1 = L.vertex_uid (G.E.src edge) in
let n2 = L.vertex_uid (G.E.dst edge) in
let eid = L.edge_uid edge in
let l = L.map_edge edge in
Format.fprintf fmt
" \n" eid n1 n2;
List.iter (Format.fprintf fmt " %a\n" data_pp) l;
Format.fprintf fmt " \n")
graph ;
Format.fprintf fmt " \n";
Format.fprintf fmt " \n"
end
(*
Local Variables:
compile-command: "make -C .."
End:
*)
ocamlgraph-2.0.0/src/dot_lexer.mll 0000644 0001750 0000144 00000006310 13735627615 015473 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(* $Id:$ *)
{
open Dot_ast
open Dot_parser
let string_buf = Buffer.create 1024
let keyword =
let h = Hashtbl.create 17 in
List.iter
(fun (s,k) -> Hashtbl.add h s k)
[
"strict", STRICT;
"graph", GRAPH;
"digraph", DIGRAPH;
"subgraph", SUBGRAPH;
"node", NODE;
"edge", EDGE;
];
fun s -> let s = String.lowercase_ascii s in Hashtbl.find h s
}
let alpha = ['a'-'z' 'A'-'Z' '_']
let digit = ['0'-'9']
let ident = alpha (alpha | digit)*
let number = '-'? ('.'['0'-'9']+ | ['0'-'9']+('.'['0'-'9']*)? )
let space = [' ' '\t' '\r' '\n']+
rule token = parse
| space
{ token lexbuf }
| ('#' | "//") [^ '\n']* '\n'
{ token lexbuf }
| "/*"
{ comment lexbuf; token lexbuf }
| ":"
{ COLON }
| ","
{ COMMA }
| ";"
{ SEMICOLON }
| "="
{ EQUAL }
| "{"
{ LBRA }
| "}"
{ RBRA }
| "["
{ LSQ }
| "]"
{ RSQ }
| "--" | "->"
{ EDGEOP }
| ident as s
{ try keyword s with Not_found -> ID (Ident s) }
| number as s
{ ID (Number s) }
| "\""
{ Buffer.clear string_buf;
let s = string lexbuf in
ID (String s) }
| "<"
{ Buffer.clear string_buf;
html lexbuf;
ID (Html (Buffer.contents string_buf)) }
| eof
{ EOF }
| _ as c
{ failwith ("Dot_lexer: invalid character " ^ String.make 1 c) }
and string = parse
| "\""
{ Buffer.contents string_buf }
| "\\" "\""
{ Buffer.add_char string_buf '"';
string lexbuf }
| _ as c
{ Buffer.add_char string_buf c;
string lexbuf }
| eof
{ failwith ("Dot_lexer: unterminated string literal") }
and html = parse
| ">"
{ () }
| "<"
{ Buffer.add_char string_buf '<'; html lexbuf;
Buffer.add_char string_buf '>'; html lexbuf }
| _ as c
{ Buffer.add_char string_buf c;
html lexbuf }
| eof
{ failwith ("Dot_lexer: unterminated html literal") }
and comment = parse
| "*/"
{ () }
| _
{ comment lexbuf }
| eof
{ failwith "Dot_lexer: unterminated comment" }
ocamlgraph-2.0.0/src/pack.ml 0000644 0001750 0000144 00000013146 13735627615 014255 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(* $Id: pack.ml,v 1.13 2006-05-12 14:07:16 filliatr Exp $ *)
module Generic(G : Sig.IM with type V.label = int and type E.label = int) =
struct
include G
exception Found of V.t
let find_vertex g i =
try
iter_vertex (fun v -> if V.label v = i then raise (Found v)) g;
raise Not_found
with Found v ->
v
module Builder = Builder.I(G)
module Dfs = Traverse.Dfs(G)
module Bfs = Traverse.Bfs(G)
module Marking = Traverse.Mark(G)
module Coloring = Coloring.Mark(G)
module Classic = Classic.I(G)
module Rand = Rand.I(G)
module Components = Components.Make(G)
module W = struct
type edge = G.E.t
type t = int
let weight e = G.E.label e
let zero = 0
let add = (+)
let sub = (-)
let compare : t -> t -> int = Stdlib.compare
end
include Path.Dijkstra(G)(W)
include Path.Johnson(G)(W)
module BF = Path.BellmanFord(G)(W)
let bellman_ford = BF.find_negative_cycle_from
module F = struct
type label = int
type t = int
let max_capacity x = x
let min_capacity _ = 0
let flow _ = 0
let add = (+)
let sub = (-)
let compare : t -> t -> int = Stdlib.compare
let zero = 0
end
module FF = Flow.Ford_Fulkerson(G)(F)
let ford_fulkerson g =
if not G.is_directed then
invalid_arg "ford_fulkerson: not a directed graph";
FF.maxflow g
module Goldberg = Flow.Goldberg_Tarjan(G)(F)
let goldberg_tarjan g =
if not G.is_directed then invalid_arg "goldberg: not a directed graph";
Goldberg.maxflow g
include Oper.Make(Builder)
module PathCheck = Path.Check(G)
module Topological = struct
include Topological.Make(G)
module S = Topological.Make_stable(G)
let fold_stable = S.fold
let iter_stable = S.iter
end
module Int = struct
type t = int
let compare : t -> t -> int = Stdlib.compare
end
include Kruskal.Make(G)(Int)
module Display = struct
include G
let vertex_name v = string_of_int (V.label v)
let graph_attributes _ = []
let default_vertex_attributes _ = []
let vertex_attributes _ = []
let default_edge_attributes _ = []
let edge_attributes e = [ `Label (string_of_int (E.label e) ) ]
let get_subgraph _ = None
end
module Dot_ = Graphviz.Dot(Display)
module Neato = Graphviz.Neato(Display)
let dot_output g f =
let oc = open_out f in
if is_directed then Dot_.output_graph oc g else Neato.output_graph oc g;
close_out oc
let display_with_gv g =
let tmp = Filename.temp_file "graph" ".dot" in
dot_output g tmp;
ignore (Sys.command ("dot -Tps " ^ tmp ^ " | gv -"));
Sys.remove tmp
module GmlParser =
Gml.Parse
(Builder)
(struct
let node l =
try match List.assoc "id" l with Gml.Int n -> n | _ -> -1
with Not_found -> -1
let edge _ =
0
end)
let parse_gml_file = GmlParser.parse
module DotParser =
Dot.Parse
(Builder)
(struct
let nodes = Hashtbl.create 97
let new_node = ref 0
let node (id,_) _ =
try
Hashtbl.find nodes id
with Not_found ->
incr new_node;
Hashtbl.add nodes id !new_node;
!new_node
let edge _ =
0
end)
let parse_dot_file = DotParser.parse
open Format
module GmlPrinter =
Gml.Print
(G)
(struct
let node n = ["label", Gml.Int n]
let edge n = ["label", Gml.Int n]
end)
let print_gml = GmlPrinter.print
let print_gml_file g f =
let c = open_out f in
let fmt = formatter_of_out_channel c in
fprintf fmt "%a@." GmlPrinter.print g;
close_out c
(*
module GraphmlPrinter =
Graphml.Print
(G)
(struct
let node n = ["label", Gml.Int n]
let edge n = ["label", Gml.Int n]
module Vhash = Hashtbl.Make(G.V)
let vertex_uid = uid (Vhash.create 17) Vhash.find Vhash.add
module Ehash = Hashtbl.Make(G.E)
let edge_uid = uid (Ehash.create 17) Ehash.find Ehash.add
end)
let print_gml = GmlPrinter.print
let print_gml_file g f =
let c = open_out f in
let fmt = formatter_of_out_channel c in
fprintf fmt "%a@." GmlPrinter.print g;
close_out c
*)
end
module I = struct
type t = int
let compare : t -> t -> int = Stdlib.compare
let default = 0
end
module Digraph = Generic(Imperative.Digraph.AbstractLabeled(I)(I))
module Graph = Generic(Imperative.Graph.AbstractLabeled(I)(I))
ocamlgraph-2.0.0/src/contraction.mli 0000644 0001750 0000144 00000004262 13735627615 016032 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(* Copyright (c) 2012 Technische Universitaet Muenchen
* Markus W. Weissmann
* All rights reserved. *)
(** Edge contraction for directed, edge-labeled graphs *)
(* This algorithm should be extensible to undirected, unlabeled graphs! *)
(** Minimal graph signature for edge contraction algorithm *)
module type G = sig
type t
module V : Sig.COMPARABLE
type vertex = V.t
module E : Sig.EDGE with type vertex = vertex
type edge = E.t
val empty : t
val add_edge_e : t -> edge -> t
val fold_edges_e : (edge -> 'a -> 'a) -> t -> 'a -> 'a
val fold_vertex : (vertex -> 'a -> 'a) -> t -> 'a -> 'a
end
module Make
(G : G) :
sig
val contract : (G.E.t -> bool) -> G.t -> G.t
(** [contract p g] will perform edge contraction on the graph [g].
The edges for which the property [p] holds/is true will get contracted:
The resulting graph will not have these edges; the start- and end-node
of these edges will get united. *)
end
ocamlgraph-2.0.0/src/dot.ml 0000644 0001750 0000144 00000015560 13735627615 014127 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(** Parser for DOT file format *)
open Dot_ast
let parse_dot_ast_from_chan c =
let lb = Lexing.from_channel c in
let dot =
try
Dot_parser.file Dot_lexer.token lb
with Parsing.Parse_error ->
let n = Lexing.lexeme_start lb in
failwith (Printf.sprintf "Dot.parse: parse error character %d" n)
in
close_in c;
dot
let parse_dot_ast f =
let c = open_in f in
parse_dot_ast_from_chan c
type clusters_hash = (string, attr list) Hashtbl.t
let get_string = function
| String s -> s
| Ident s -> s
| Number s -> s
| Html s -> s
module Parse
(B : Builder.S)
(L : sig
val node : node_id -> attr list -> B.G.V.label
(** how to build the node label out of the set of attributes *)
val edge : attr list -> B.G.E.label
(** how to build the edge label out of the set of attributes *)
end) =
struct
module Attr = struct
module M =
Map.Make
(struct
type t = id
let compare : t -> t -> int = Stdlib.compare
end)
let empty = M.empty
let add = List.fold_left (fun a (x,v) -> M.add x v a)
let addl = List.fold_left add
let list a = M.fold (fun x v l -> (x,v) :: l) a []
end
let create_graph_and_clusters dot =
(* pass 1*)
(* collect node attributes *)
let def_node_attr = ref Attr.empty in
let node_attr = Hashtbl.create 97 in
(* collect cluster attributes *)
let def_clust_attr = ref Attr.empty in
let clust_attr = Hashtbl.create 97 in
(* collect clusters nodes *)
let clust_nodes = Hashtbl.create 97 in
let add_node_attr id al =
let l = try Hashtbl.find node_attr id
with Not_found -> !def_node_attr in
Hashtbl.replace node_attr id (Attr.addl l al) in
let add_clust_attr id_opt al =
match id_opt with
| Some id ->
let s = get_string id in
let l = try Hashtbl.find clust_attr s
with Not_found -> !def_clust_attr in
Hashtbl.replace clust_attr s (Attr.addl l al)
| _ -> () in
let add_clust_node id_cluster id_node =
let id_nodes = try Hashtbl.find clust_nodes id_cluster
with Not_found -> [] in
Hashtbl.add clust_nodes id_cluster (id_node :: id_nodes) in
let rec collect_node_attr cluster_op stmts =
List.iter (
function
| Node_stmt (id, al) ->
add_node_attr id al;
begin match cluster_op with
| Some id_cluster -> add_clust_node id_cluster id
| _ -> ()
end
| Attr_node al -> def_node_attr := Attr.addl !def_node_attr al
| Edge_stmt (NodeId id, nl, _) ->
add_node_attr id [];
List.iter (function | NodeId id -> add_node_attr id []
| _ -> ()) nl
| Subgraph (SubgraphDef (id, stmts)) ->
collect_node_attr (Some id) stmts
| Attr_graph al ->
begin match cluster_op with
| Some id -> add_clust_attr id al
| None -> ()
end
| _ -> ()
) stmts
in
collect_node_attr None dot.stmts;
(* pass 2: build the graph and the clusters *)
let def_edge_attr = ref Attr.empty in
let nodes = Hashtbl.create 97 in
let node g id _ =
try
g, Hashtbl.find nodes id
with Not_found ->
let l = try Hashtbl.find node_attr id with Not_found -> Attr.empty in
let n = B.G.V.create (L.node id [Attr.list l]) in
Hashtbl.add nodes id n;
B.add_vertex g n, n
in
let rec add_stmts g stmts =
List.fold_left
(fun g s -> match s with
| Node_stmt (id, al) ->
let g,_ = node g id al in g
| Edge_stmt (NodeId id, nl, al) ->
let al = Attr.addl !def_edge_attr al in
let el = L.edge [Attr.list al] in
let g,vn = node g id [] in
fst (List.fold_left
(fun (g,pvn) m -> match m with
| NodeId idm ->
let g,vm = node g idm [] in
let e = B.G.E.create pvn el vm in
((B.add_edge_e g e),vm)
| NodeSub _ ->
(g,pvn))
(g,vn) nl)
| Attr_edge al ->
def_edge_attr := Attr.addl !def_edge_attr al; g
| Subgraph (SubgraphDef (_, stmts)) ->
add_stmts g stmts
| _ -> g
)
g stmts in
let graph = add_stmts (B.empty ()) dot.stmts in
let clusters_hash =
let h = Hashtbl.create 30 in
Hashtbl.iter (fun k a -> Hashtbl.add h k [Attr.list a]) clust_attr;
h in
graph, clusters_hash
let get_graph_bb stmts =
let graph_bb = ref None in
let read_attr = function
| (Ident "bb" , Some (String bb)) -> graph_bb := Some bb
| _ -> () in
let read_stmt = function
| Attr_graph attrs -> List.iter (List.iter read_attr) attrs
| _ -> () in
List.iter read_stmt stmts;
!graph_bb
let parse_dot_from_chan c =
let lb = Lexing.from_channel c in
let dot =
try
Dot_parser.file Dot_lexer.token lb
with Parsing.Parse_error ->
let n = Lexing.lexeme_start lb in
failwith (Printf.sprintf "Dot.parse: parse error character %d" n)
in
close_in c;
dot
let parse_dot f =
let c = open_in f in
parse_dot_from_chan c
let parse f =
fst (create_graph_and_clusters (parse_dot f))
let parse_bounding_box_and_clusters f =
let dot = parse_dot f in
let graph, clusters = create_graph_and_clusters dot in
match get_graph_bb dot.stmts with
| Some bounding_box ->
graph, bounding_box, clusters
| None ->
failwith "Cannot read bounding box in xdot file"
end
ocamlgraph-2.0.0/src/dGraphRandModel.ml 0000644 0001750 0000144 00000006047 13735627615 016334 0 ustar rt users (**************************************************************************)
(* *)
(* This file is part of OcamlGraph. *)
(* *)
(* Copyright (C) 2009-2010 *)
(* CEA (Commissariat � l'�nergie Atomique) *)
(* *)
(* you can redistribute it and/or modify it under the terms of the GNU *)
(* Lesser General Public License as published by the Free Software *)
(* Foundation, version 2.1, with a linking exception. *)
(* *)
(* It 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. See the *)
(* GNU Lesser General Public License for more details. *)
(* *)
(* See the file ../LICENSE for more details. *)
(* *)
(* Authors: *)
(* - Julien Signoles (Julien.Signoles@cea.fr) *)
(* - Jean-Denis Koeck (jdkoeck@gmail.com) *)
(* - Benoit Bataille (benoit.bataille@gmail.com) *)
(* *)
(**************************************************************************)
let element = function
| [] -> invalid_arg "empty list in element"
| l ->
Random.self_init ();
List.nth l (Random.int (List.length l))
let black = 0x000000
and white = 0xFFFFFF
and red = 0xFF0000
and green = 0x00FF00
and blue = 0x0000FF
and yellow = 0xFFFF00
and cyan = 0x00FFFF
and magenta = 0xFF00FF
module Vertex = struct
type t = int
end
module Edge = struct
type t = int
let compare : int -> int -> int = Stdlib.compare
let default = 0
end
module G = Imperative.Digraph.AbstractLabeled(Vertex)(Edge)
module R = Rand.I(G)
module GraphAttrs = struct
include G
let graph_attributes _ = []
let default_vertex_attributes _ = []
let vertex_name v = string_of_int (G.V.label v)
let vertex_attributes _ =
let shape = element [`Ellipse; `Box; `Circle; `Doublecircle; `Diamond] in
let color = element [black; white; red; green; blue; yellow; cyan; magenta] in
[`Shape shape; `Color color]
let default_edge_attributes _ = []
let edge_attributes _ = []
let get_subgraph _ = None
end
module Model = DGraphModel.Make(GraphAttrs)
let create () =
(* State *)
Random.self_init ();
let v = 100 in
let e = Random.int (v*2) in
let g = R.graph ~loops:true ~v ~e () in
Model.from_graph g
ocamlgraph-2.0.0/src/dGraphTreeLayout.mli 0000644 0001750 0000144 00000005146 13735627615 016734 0 ustar rt users (**************************************************************************)
(* *)
(* This file is part of OcamlGraph. *)
(* *)
(* Copyright (C) 2009-2010 *)
(* CEA (Commissariat � l'�nergie Atomique) *)
(* *)
(* you can redistribute it and/or modify it under the terms of the GNU *)
(* Lesser General Public License as published by the Free Software *)
(* Foundation, version 2.1, with a linking exception. *)
(* *)
(* It 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. See the *)
(* GNU Lesser General Public License for more details. *)
(* *)
(* See the file ../LICENSE for more details. *)
(* *)
(* Authors: *)
(* - Julien Signoles (Julien.Signoles@cea.fr) *)
(* - Jean-Denis Koeck (jdkoeck@gmail.com) *)
(* - Benoit Bataille (benoit.bataille@gmail.com) *)
(* *)
(**************************************************************************)
type cluster = string
module Make
(Tree: Graphviz.GraphWithDotAttrs)
(TreeManipulation: sig val is_ghost_node: Tree.V.t -> bool end):
sig
val from_tree:
fontMeasure:(
fontName:string -> fontSize:int -> string -> int * int
) -> Tree.t -> Tree.V.t -> XDot.Make(Tree).graph_layout
end
module MakeFromDotModel
(Tree : Sig.G with type V.label = DGraphModel.DotG.V.t
and type E.label = unit)
(TreeManipulation: sig val is_ghost_node: Tree.V.t -> bool end):
sig
module Tree: Graphviz.GraphWithDotAttrs with module V = Tree.V
and module E = Tree.E
and type t = Tree.t
val from_model:
Tree.t -> Tree.V.t -> DGraphModel.dotg_model -> XDot.Make(Tree).graph_layout
end
ocamlgraph-2.0.0/src/xDot.ml 0000644 0001750 0000144 00000030212 13735627615 014246 0 ustar rt users (**************************************************************************)
(* *)
(* This file is part of OcamlGraph. *)
(* *)
(* Copyright (C) 2009-2010 *)
(* CEA (Commissariat � l'�nergie Atomique) *)
(* *)
(* you can redistribute it and/or modify it under the terms of the GNU *)
(* Lesser General Public License as published by the Free Software *)
(* Foundation, version 2.1, with a linking exception. *)
(* *)
(* It 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. See the *)
(* GNU Lesser General Public License for more details. *)
(* *)
(* See the file ../LICENSE for more details. *)
(* *)
(* Authors: *)
(* - Julien Signoles (Julien.Signoles@cea.fr) *)
(* - Jean-Denis Koeck (jdkoeck@gmail.com) *)
(* - Benoit Bataille (benoit.bataille@gmail.com) *)
(* *)
(**************************************************************************)
(** Reading XDot files *)
open Dot_ast
open Printf
(* Layout types *)
(* This file is responsible for converting the coordinates from dot coordinates
to GnomeCanvas world coordinates.
The matrix transformation to apply is:
(1 0)
(0 -1)
Care must be taken to exchange max and min values on the y axis.
Outside this module all coordinates are assumed to be in canvas
world coordinates.
*)
type pos = float * float (* coordinates *)
type bounding_box = pos * pos (* bounding box *)
type node_layout = {
n_name : string;
n_pos : pos;
n_bbox : bounding_box;
n_draw : XDotDraw.operation list;
n_ldraw : XDotDraw.operation list;
}
type cluster_layout = {
c_pos : pos;
c_bbox : bounding_box;
c_draw : XDotDraw.operation list;
c_ldraw : XDotDraw.operation list;
}
type edge_layout = {
e_draw : XDotDraw.operation list;
e_ldraw : XDotDraw.operation list;
e_hdraw : XDotDraw.operation list;
e_tdraw : XDotDraw.operation list;
e_hldraw : XDotDraw.operation list;
e_tldraw : XDotDraw.operation list;
}
let mk_node_layout ~name ~pos ~bbox ~draw ~ldraw =
{ n_name = name;
n_pos = pos;
n_bbox = bbox;
n_draw = draw;
n_ldraw = ldraw }
let mk_cluster_layout ~pos ~bbox ~draw ~ldraw =
{ c_pos = pos;
c_bbox = bbox;
c_draw = draw;
c_ldraw = ldraw }
let mk_edge_layout ~draw ~ldraw ~hdraw ~tdraw ~hldraw ~tldraw =
{ e_draw = draw;
e_ldraw = ldraw;
e_hdraw = hdraw;
e_tdraw = tdraw;
e_hldraw = hldraw;
e_tldraw = tldraw;
}
exception ParseError of string
(* MISCELLANEOUS FUNCTIONS *)
let read_pos s = Scanf.sscanf s "%f,%f" (fun x y -> x, -.y)
let bounding_box (x, y) w h =
let lower_left = x -. w , y -. h in
let upper_right = x+.w,y+.h in
lower_left,upper_right
let get_dot_string = function
| Dot_ast.String s -> s
| Dot_ast.Ident s -> s
| Dot_ast.Number s -> s
| Dot_ast.Html s -> s
(* READING VERTEX LAYOUTS *)
(** Finds the attributes [pos], [width] and [height] of a node
in the attribute list *)
let read_common_layout mk_layout attr_list =
(* Iter on the attributes *)
(* shape, position, width, height, color, filled *)
let fold ((p,w,h, draw,ldraw) as attrs) = function
| (Dot_ast.Ident "pos"), Some (Dot_ast.String s) ->
(Some s), w, h, draw,ldraw
| (Dot_ast.Ident "width"), Some (Dot_ast.String s) ->
p, (Some s), h, draw,ldraw
| (Dot_ast.Ident "height"), Some (Dot_ast.String s) ->
p, w, (Some s), draw,ldraw
| (Dot_ast.Ident "_draw_"), Some (Dot_ast.String draw) ->
p,w,h, XDotDraw.parse draw, ldraw
| (Dot_ast.Ident "_ldraw_"), Some (Dot_ast.String ldraw) ->
p,w,h, draw, XDotDraw.parse ldraw
| _ -> attrs in
let fold_attr acc attr_list =
List.fold_left fold acc attr_list in
let attrs = List.fold_left fold_attr (None, None, None, [], [])
attr_list in
(* Check if we have position, width and height *)
match attrs with
| Some pos, Some w, Some h, draw,ldraw->
let pos = read_pos pos in
let coord = bounding_box pos
(float_of_string w) (-.(float_of_string h)) in
(* Return the node model *)
mk_layout ~pos ~bbox:coord ~draw ~ldraw
| _,_,_, draw, ldraw ->
let pos = (0.,0.) in
let bbox = (0.,0.),(0.,0.) in
mk_layout ~pos ~bbox ~draw ~ldraw
let read_node_layout (id,_) attrs =
let f = read_common_layout
(fun ~pos ~bbox ~draw ~ldraw -> mk_node_layout ~pos ~bbox ~draw ~ldraw)
attrs in
f ~name:(get_dot_string id)
let read_cluster_layout = read_common_layout mk_cluster_layout
(* READING EDGE LAYOUTS *)
(** Reads the spline control points of a curve in an xdot file
example : "c 5 -black B 4 65 296 65 288 65 279 65 270 "
*)
(* The edge drawing operations are in the following attributes :
_hdraw_ Head arrowhead
_tdraw_ Tail arrowhead
_hldraw_ Head label
_tldraw_ Tail label
*)
(** Gets the layout of an edge out of the dot ast *)
let read_edge_layout attr_list =
let draw = ref [] in
let ldraw = ref [] in
let hdraw = ref [] in
let tdraw = ref [] in
let hldraw = ref [] in
let tldraw = ref [] in
let fill_draw_ops = function
| (Dot_ast.Ident "_draw_"), Some (Dot_ast.String s) ->
draw := XDotDraw.parse s
| (Dot_ast.Ident "_ldraw_"), Some (Dot_ast.String s) ->
ldraw := XDotDraw.parse s
| (Dot_ast.Ident "_hdraw_"), Some (Dot_ast.String s) ->
hdraw := XDotDraw.parse s
| (Dot_ast.Ident "_tdraw_"), Some (Dot_ast.String s) ->
tdraw := XDotDraw.parse s
| (Dot_ast.Ident "_hldraw_"), Some (Dot_ast.String s) ->
hldraw := XDotDraw.parse s
| (Dot_ast.Ident "_tldraw_"), Some (Dot_ast.String s) ->
tldraw := XDotDraw.parse s
| _ -> () in
List.iter (List.iter fill_draw_ops) attr_list;
let draw, ldraw = !draw, !ldraw in
let hdraw, tdraw, hldraw, tldraw = !hdraw, !tdraw, !hldraw, !tldraw in
mk_edge_layout ~draw ~ldraw ~hdraw ~tdraw ~hldraw ~tldraw
(* Computes the bounding box *)
let read_bounding_box str =
let x1,y1,x2,y2 = Scanf.sscanf str "%f,%f,%f,%f" (fun a b c d -> a,b,c,d) in
(* Convert coordinates to the world canvas coordinates *)
let lower_left = (x1, -.y2) and upper_right = x2, -.y1 in
lower_left,upper_right
module Make(G : Graphviz.GraphWithDotAttrs) = struct
module HV = Hashtbl.Make(G.V)
(* cannot use an hashtable because no hash function for edges *)
module HE =
Map.Make
(struct
type t = G.E.t
let compare = G.E.compare
end)
module HT =
Hashtbl.Make
(Util.HTProduct
(Util.HTProduct(G.V)(G.V))
(struct type t = string let equal = (=) let hash = Hashtbl.hash end))
type graph_layout =
{ vertex_layouts : node_layout HV.t;
edge_layouts : edge_layout HE.t;
cluster_layouts : (string, cluster_layout) Hashtbl.t;
bbox : bounding_box }
exception Found of string
let get_edge_comment e =
let al = G.edge_attributes e in
try
List.iter (function `Comment c -> raise (Found c) | _ -> ()) al;
None
with Found c ->
Some c
let get_dot_comment (al : Dot_ast.attr list) =
try
List.iter
(List.iter
(function
| Ident "comment", Some c -> raise (Found (get_dot_string c))
| _ -> ()))
al;
""
with Found c ->
c
let strip_quotes = function
| "" -> ""
| s ->
let len = String.length s in
if s.[0] = '"' && s.[len -1] = '"' then String.sub s 1 (len - 2)
else s
(* Parses the graph attribute named id, and converts it with conv *)
let parse_graph_attr id conv stmts =
let read_attr = function
| Ident ident , Some (String attr) when ident = id ->
raise (Found attr)
| _ -> ()
in
let read_stmt = function
| Attr_graph attrs -> List.iter (List.iter read_attr) attrs
| _ -> ()
in
try
List.iter read_stmt stmts;
failwith ("Could not find the graph attribute named " ^ id)
with Found attr ->
conv attr
let parse_bounding_box = parse_graph_attr "bb" read_bounding_box
(*let parse_bgcolor = parse_graph_attr "bgcolor" XDotDraw.normalize_color*)
let parse_layouts g stmts =
let name_to_vertex = Hashtbl.create 97 in
let vertices_comment_to_edge = HT.create 97 in
let vertex_layouts = HV.create 97 in
let edge_layouts = ref HE.empty in
let cluster_layouts = Hashtbl.create 97 in
G.iter_vertex
(fun v ->
let name = strip_quotes (G.vertex_name v) in
Hashtbl.add name_to_vertex name v)
g;
G.iter_edges_e
(fun e ->
let comment = match get_edge_comment e with
| Some c -> strip_quotes c
| None -> ""
in
let vs = G.E.src e, G.E.dst e in
HT.add vertices_comment_to_edge (vs, comment) e)
g;
let find_vertex (id,_) =
let name = get_dot_string id in
try Hashtbl.find name_to_vertex name
with Not_found -> failwith ("Could not find vertex named " ^ name)
in
let find_edge v v' comment =
try HT.find vertices_comment_to_edge ((v, v'), comment)
with Not_found ->
(* Printf.printf "Did not find edge from %s to %s with comment %s\n"
(G.vertex_name v) (G.vertex_name v')
(match comment with Some c -> c | None -> "none");*)
raise Not_found
in
let rec collect_layouts cluster stmt =
try
match stmt with
| Node_stmt (node_id, al) ->
let v = find_vertex node_id in
HV.add vertex_layouts v (read_node_layout node_id al)
| Edge_stmt (NodeId id, [NodeId id'], al) ->
let v = find_vertex id in
let v' = find_vertex id' in
let comment = get_dot_comment al in
let e = find_edge v v' comment in
edge_layouts := HE.add e (read_edge_layout al) !edge_layouts
| Subgraph (SubgraphDef (Some id, stmts)) ->
let cluster = get_dot_string id in
List.iter (collect_layouts (Some cluster)) stmts
(* Anonymous subgraph *)
| Subgraph (SubgraphDef (_, stmts)) ->
List.iter (collect_layouts cluster) stmts
| Attr_graph al ->
(match cluster with
| Some c -> Hashtbl.add cluster_layouts c (read_cluster_layout al)
| None -> ())
| _ -> ()
with Not_found ->
()
in
List.iter (collect_layouts None) stmts;
vertex_layouts, edge_layouts, cluster_layouts
let parse g dot_ast =
let v_layouts, e_layouts, c_layouts = parse_layouts g dot_ast.stmts in
let bbox = parse_bounding_box dot_ast.stmts in
(* let bgcolor = parse_bgcolor dot_ast.stmts in*)
{ vertex_layouts = v_layouts;
edge_layouts = !e_layouts;
cluster_layouts = c_layouts;
bbox = bbox }
exception DotError of string
let layout_of_xdot ~xdot_file g =
let dot_ast = Dot.parse_dot_ast xdot_file in
parse g dot_ast
let layout_of_dot ?(cmd="dot") ~dot_file g =
let base_name =
try Filename.basename (Filename.chop_extension dot_file)
with Invalid_argument _ -> dot_file
in
let xdot_file = Filename.temp_file base_name ".xdot" in
(* Run graphviz to get xdot file *)
let dot_cmd = sprintf "%s -Txdot %s > %s" cmd dot_file xdot_file in
match Sys.command dot_cmd with
| 0 ->
let l = layout_of_xdot ~xdot_file g in
Sys.remove xdot_file;
l
| _ ->
Sys.remove xdot_file;
raise (DotError "Error during dot execution")
end
ocamlgraph-2.0.0/src/nonnegative.ml 0000644 0001750 0000144 00000061601 13735627615 015653 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(* This module is a contribution of Yuto Takei *)
module Imperative
(G: Sig.IM)
(W: Sig.WEIGHT with type edge = G.E.t) = struct
module S = Set.Make(G.V)
module M = Map.Make(G.V)
module V = G.V
module E = G.E
(* [G.t] represents graph itself. [unit M.t] maintains a list of
source vertices to keep track of distances for all vertices.
[(G.E.t option * W.t) M.t M.t] holds mappings for all vertices,
each of which contains its shortest-path tree ancestor (parent)
and a distances from source vertices. *)
type t = G.t * S.t ref * (G.E.t option * W.t) M.t M.t ref
type edge = G.edge
type vertex = G.vertex
let sov v = string_of_int (Obj.magic (V.label v))
let dump_cycle cycle =
let v0 = G.E.src (List.hd cycle) in
print_string ("(" ^ (sov v0) ^ ")");
let v1 = List.fold_left (fun v e ->
assert ((G.V.compare v (G.E.src e)) = 0);
let v = G.E.dst e in
print_string ("-(" ^ (sov v) ^ ")");
v) v0 cycle in
assert (G.V.equal v0 v1);
print_string "\n"
let dump_set = S.iter (fun x -> print_string ((sov x) ^ ", "))
let dump (src, dist) =
print_string "====================\nS: ";
dump_set !src;
print_string "\nMap:";
M.iter (fun k v ->
print_string ("\n " ^ (sov k) ^ ": ");
M.iter (fun k (origin, dist) ->
print_string (
"(" ^ (sov k) ^ ">>" ^
(match origin with
| None -> "---"
| Some e -> (sov (G.E.src e)) ^ ">"
^ (sov (G.E.dst e))) ^ ":" ^
(string_of_int (Obj.magic dist)) ^ ") ")) v) !dist;
print_string "\n"
(* If an edge is going to be added to the graph, which will cause
a negative cycle, raises [Negative_cycle] with edges that can
form such the cycle. *)
exception Negative_cycle of G.E.t list
let create ?size () =
let g = match size with
| Some size -> G.create ~size ()
| None -> G.create () in
(g, ref S.empty, ref M.empty)
let copy (g, src, dist) =
(G.copy g, ref (!src), ref (!dist))
let clear (g, src, dist) =
G.clear g;
src := S.empty;
dist := M.empty
let add_vertex (g, src, dist) v =
(* Before adding vertex to the graph, make sure that the vertex
is not in the graph. If already in the graph, just do
nothing and return as is. *)
if not (G.mem_vertex g v) then begin
(* Add a vertex to the original one *)
G.add_vertex g v;
(* The new vertex will immediately be added to the source list *)
src := S.add v !src;
(* The new edge should contain a distance mapping with only
from myself with distance zero. *)
dist := M.add v (M.add v (None, W.zero) M.empty) !dist;
dump (src, dist)
end
let rec propagate (g, src, dist) q start =
if Queue.is_empty q then (g, src, dist)
else begin
let (v1, v1src) = Queue.pop q in
let v1dist = M.find v1 dist in
let dist = G.fold_succ_e (fun e dist ->
let v2 = G.E.dst e in
let v2dist = if M.mem v2 dist then M.find v2 dist else M.empty in
(* Compare distances from given source vertices.
If relax happens, record it to the new list. *)
let (v2dist, nextSrc) = S.fold (fun x (v2dist, nextSrc) ->
let _, dev1 = M.find x v1dist in
let ndev2 = W.add dev1 (W.weight e) in
let improvement =
try
let _, dev2 = M.find x v2dist in
W.compare ndev2 dev2 < 0
with Not_found -> true in
if improvement then
let v2dist = M.add x (Some e, ndev2) v2dist in
let nextSrc = S.add x nextSrc in
(v2dist, nextSrc)
else
(v2dist, nextSrc)
) v1src (v2dist, S.empty) in
if S.is_empty nextSrc then
dist
else if G.V.equal start v2 then
(* Propagation reaches back to the starting node, which
immediately means presence of a negative cycle. *)
(* We should use one of 'src' to traverse to the start node *)
let dist = M.add v2 v2dist dist in
let cycle = S.fold (fun s x ->
let rec build_cycle x ret =
match M.find s (M.find x dist) with
| Some e, _ ->
let y = G.E.src e in
let cycle = e :: ret in
if G.V.equal start y then Some cycle
else build_cycle y cycle
| _ -> None in
match x with
| None -> build_cycle v2 []
| Some _ -> x) nextSrc None in
let cycle = match cycle with
| Some x -> x | None -> assert false in
dump_cycle cycle;
raise (Negative_cycle cycle)
else
begin
(* TODO: Some room for improvement.
If queue has (v2, s) already, technically we can merge
nextSrc into s, so that the number of propagation can be
reduced. *)
Queue.push (v2, nextSrc) q;
M.add v2 v2dist dist
end
) g v1 dist in
propagate (g, src, dist) q start
end
let m_cardinal m = M.fold (fun _ _ acc -> acc+1) m 0
let set_of_map m = M.fold (fun k _ acc -> S.add k acc) m S.empty
let add_edge_internal (g, src, dist) v1 v2 =
(* Distance mappings at v1 *)
let dv1 = M.find v1 dist in
(* To reduce the amount of codes, we just start propagation from
v1. Of course, this can be optimized by starting from v2. But
it may duplicate the same code in multiple places in the
file. In addition, such an optimization only cost for small
amount, which precisely is the operations to relax edges from
v1, other than which have been existed before this
[add_edge_e] call. *)
let q = Queue.create () in
(* We need to check whether v2 should be kept in the source list
or not. That is, if there maybe a cycle with v1, the
distance from v1 should be still maintained. Otherwise,
simply ignore the distance from v2 *)
if m_cardinal dv1 = 1 && M.mem v2 dv1 then (
(* Now we definitely introduced a loop (and possibly non-negative)!
Let me see if this would be negative or not... *)
Queue.add (v1, (S.add v2 S.empty)) q;
propagate (g, src, dist) q v1
) else (
(* Or even if we fall back to else-clause here, the edge addition
may have introduced a cycle. Anyway, we need to check if one is
newly created or not at [propagate] *)
let (src, dist, dv1) =
if not (S.mem v2 src) then
(* If v2 isn't one of the source vertices, just simply do
propagation. *)
(src, dist, dv1)
else
(* We can exclude v2 from the list of source because
one can reach v2 from some other vertex. *)
let src = S.remove v2 src in
(* Note that following line can be skipped only if the
user don't remove vertex. Otherwise, such operation
like [add_edge g v1 v2] > [remove_vertex g v2] >
[add_vertex g v2] can result in unexpected
behavior. *)
let dist = M.map (M.remove v2) dist in
(* We need to re-obtain the distance mappings at v1,
since it can be changed by the line above. *)
let dv1 = M.find v1 dist in
(src, dist, dv1) in
(* Now let's start propagation. *)
Queue.add (v1, set_of_map dv1) q;
propagate (g, src, dist) q v1)
let add_edge_e (g, src, dist) e =
(* Before adding edge to the graph, make sure that the edge is
not in the graph. If already in the graph, just do nothing
and return as is. *)
if not (G.mem_edge_e g e) then begin
(* Vertices involved *)
let v1 = G.E.src e in
let v2 = G.E.dst e in
List.iter (add_vertex (g, src, dist)) [v1 ; v2];
begin try
(* Because we can restore the graph by calling [G.remove_edge_e]
even in case of failure, we first add it by [G.add_edge_e]. *)
G.add_edge_e g e;
let (_, src', dist') = add_edge_internal (g, !src, !dist) v1 v2 in
src := src'; dist := dist'
with exp ->
(* In case of excecption, restore the graph by removing the
edge, and rethrow the exception. *)
G.remove_edge_e g e;
raise exp
end;
dump (src, dist)
end
let add_edge (g, src, dist) v1 v2 =
(* Same as [add_edge_e] *)
if not (G.mem_edge g v1 v2) then begin
List.iter (add_vertex (g, src, dist)) [v1 ; v2];
begin try
(* Because we cannot know the default value for edge length,
we first try to add one by [G.add_edge]. If there occurs an
exception, restore the graph by [G.remove_edge] since there
were no other connections between [v1] and [v2]. *)
G.add_edge g v1 v2;
let (_, src', dist') = add_edge_internal (g, !src, !dist) v1 v2 in
src := src'; dist := dist'
with exp ->
(* In case of excecption, restore the graph by removing the
edge, and rethrow the exception. *)
G.remove_edge g v1 v2;
raise exp
end;
dump (src, dist)
end
let remove_edge_internal (g, src) v2 =
(* Actually, we need to rebuild the distance table, rather than
traverse precedants to remove the edge. *)
let q = Queue.create () in
print_string ("dump: ");
dump_set src;
let dist = S.fold (fun x dist ->
print_string ("source: " ^ (sov x) ^ "\n");
Queue.add (x, (S.add x S.empty)) q;
M.add x (M.add x (None, W.zero) M.empty) dist) src M.empty in
let g, src, dist = propagate (g, src, dist) q (S.choose src) in
if M.mem v2 dist then
(g, src, dist)
else (
Queue.add (v2, (S.add v2 S.empty)) q;
let src = S.add v2 src in
let dist = M.add v2 (M.add v2 (None, W.zero) M.empty) dist in
propagate (g, src, dist) q v2)
let remove_edge_e (g, src, dist) e =
(* Same as [add_edge_e] *)
if G.mem_edge_e g e then begin
G.remove_edge_e g e;
(* Vertices involved *)
let v2 = G.E.dst e in
let (_, src', dist') = remove_edge_internal (g, !src) v2 in
src := src';
dist := dist';
dump (src, dist)
end
let remove_edge (g, src, dist) v1 v2 =
(* Same as [add_edge] *)
if G.mem_edge g v1 v2 then begin
G.remove_edge g v1 v2;
let (_, src', dist') = remove_edge_internal (g, !src) v2 in
src := src';
dist := dist';
dump (src, dist)
end
let remove_vertex (g, src, dist) v =
(* Same as [add_edge] *)
if G.mem_vertex g v then begin
(* [remove_vertex] first deletes all outgoing edges from [v] *)
G.iter_succ_e (fun e -> remove_edge_e (g, src, dist) e) g v;
(* Then after, deletes all incoming edges to [v] *)
G.iter_pred_e (fun e -> remove_edge_e (g, src, dist) e) g v;
(* Note that we are iterating on [g] that is being modified during
iteration. We can do such an above iteration since G is here
permanent. Do not try this for imperative graph. *)
(* Now we can feel free to delete [v]. *)
G.remove_vertex g v;
src := S.remove v !src;
dist := M.remove v (M.map (M.remove v) !dist);
dump (src, dist)
end
let map_vertex f (g, src, dist) =
let map_map update m =
M.fold (fun v m acc -> M.add (f v) (update m) acc) m M.empty
in
let (g, src, dist) = (G.map_vertex f g,
S.fold (fun v acc -> S.add (f v) acc) !src S.empty,
let update = function
| None, _ as v -> v
| Some e, w ->
Some (E.create (f (E.src e)) (E.label e) (f (E.dst e))), w
in
map_map (map_map update) !dist) in
(g, ref src, ref dist)
let fold_pred_e f (g, _, _) = G.fold_pred_e f g
let iter_pred_e f (g, _, _) = G.iter_pred_e f g
let fold_succ_e f (g, _, _) = G.fold_succ_e f g
let iter_succ_e f (g, _, _) = G.iter_succ_e f g
let fold_pred f (g, _, _) = G.fold_pred f g
let fold_succ f (g, _, _) = G.fold_succ f g
let iter_pred f (g, _, _) = G.iter_pred f g
let iter_succ f (g, _, _) = G.iter_succ f g
let fold_edges_e f (g, _, _) = G.fold_edges_e f g
let iter_edges_e f (g, _, _) = G.iter_edges_e f g
let fold_edges f (g, _, _) = G.fold_edges f g
let iter_edges f (g, _, _) = G.iter_edges f g
let fold_vertex f (g, _, _) = G.fold_vertex f g
let iter_vertex f (g, _, _) = G.iter_vertex f g
let pred_e (g, _, _) = G.pred_e g
let succ_e (g, _, _) = G.succ_e g
let pred (g, _, _) = G.pred g
let succ (g, _, _) = G.succ g
let find_all_edges (g, _, _) = G.find_all_edges g
let find_edge (g, _, _) = G.find_edge g
let mem_edge_e (g, _, _) = G.mem_edge_e g
let mem_edge (g, _, _) = G.mem_edge g
let mem_vertex (g, _, _) = G.mem_vertex g
let in_degree (g, _, _) = G.in_degree g
let out_degree (g, _, _) = G.out_degree g
let nb_edges (g, _, _) = G.nb_edges g
let nb_vertex (g, _, _) = G.nb_vertex g
let is_empty (g, _, _) = G.is_empty g
let is_directed = G.is_directed
module Mark = struct
type graph = t
type vertex = G.vertex
let clear g = let (g, _, _) = g in G.Mark.clear g
let get = G.Mark.get
let set = G.Mark.set
end
end
module Persistent
(G: Sig.P)
(W: Sig.WEIGHT with type edge = G.E.t) = struct
module S = Set.Make(G.V)
module M = Map.Make(G.V)
module E = G.E
module V = G.V
(* [G.t] represents graph itself. [unit M.t] maintains a list of
source vertices to keep track of distances for all vertices.
[(G.E.t option * W.t) M.t M.t] holds mappings for all vertices,
each of which contains its shortest-path tree ancestor (parent)
and a distances from source vertices. *)
type t = G.t * S.t * (G.E.t option * W.t) M.t M.t
type edge = G.edge
type vertex = G.vertex
(* If an edge is going to be added to the graph, which will cause
a negative cycle, raises [Negative_cycle] with edges that can
form such the cycle. *)
exception Negative_cycle of G.E.t list
let empty : t =
let g = G.empty in
let src = S.empty in
let dist = M.empty in
(g, src, dist)
let add_vertex (g, src, dist) v =
(* Before adding vertex to the graph, make sure that the vertex
is not in the graph. If already in the graph, just do
nothing and return as is. *)
if G.mem_vertex g v then
(g, src, dist)
else
(* Add a vertex to the original one *)
(G.add_vertex g v),
(* The new vertex will immediately be added to the source list *)
(S.add v src),
(* The new edge should contain a distance mapping with only
from myself with distance zero. *)
(M.add v (M.add v (None, W.zero) M.empty) dist)
let rec propagate (g, src, dist) q start =
if Queue.is_empty q then (g, src, dist)
else begin
let (v1, v1src) = Queue.pop q in
let v1dist = M.find v1 dist in
let dist = G.fold_succ_e (fun e dist ->
let v2 = G.E.dst e in
let v2dist = M.find v2 dist in
(* Compare distances from given source vertices.
If relax happens, record it to the new list. *)
let (v2dist, nextSrc) = S.fold (fun x (v2dist, nextSrc) ->
let _, dev1 = M.find x v1dist in
let ndev2 = W.add dev1 (W.weight e) in
let improvement =
try
let _, dev2 = M.find x v2dist in
W.compare ndev2 dev2 < 0
with Not_found -> true in
if improvement then
let v2dist = M.add x (Some e, ndev2) v2dist in
let nextSrc = S.add x nextSrc in
(v2dist, nextSrc)
else
(v2dist, nextSrc)
) v1src (v2dist, S.empty) in
if S.is_empty nextSrc then
dist
else if G.V.equal start v2 then
(* Propagation reaches back to the starting node, which
immediately means presence of a negative cycle. *)
(* We should use one of 'src' to traverse to the start node *)
let s = S.choose nextSrc in
let rec build_cycle x ret =
match M.find s (M.find x dist) with
| Some e, _ ->
let y = G.E.src e in
let cycle = e :: ret in
if G.V.equal start y then cycle
else build_cycle y cycle
| _ -> assert false in
raise (Negative_cycle (build_cycle v2 []))
else
begin
(* TODO: Some room for improvement.
If queue has (v2, s) already, technically we can merge
nextSrc into s, so that the number of propagation can be
reduced. *)
Queue.push (v2, nextSrc) q;
M.add v2 v2dist dist
end
) g v1 dist in
propagate (g, src, dist) q start
end
let m_cardinal m = M.fold (fun _ _ acc -> acc+1) m 0
let set_of_map m = M.fold (fun k _ acc -> S.add k acc) m S.empty
let add_edge_internal (g, src, dist) v1 v2 =
(* Distance mappings at v1 *)
let dv1 = M.find v1 dist in
(* To reduce the amount of codes, we just start propagation from
v1. Of course, this can be optimized by starting from v2. But
it may duplicate the same code in multiple places in the
file. In addition, such an optimization only cost for small
amount, which precisely is the operations to relax edges from
v1, other than which have been existed before this
[add_edge_e] call. *)
let q = Queue.create () in
(* We need to check whether v2 should be kept in the source list
or not. That is, if there maybe a cycle with v1, the
distance from v1 should be still maintained. Otherwise,
simply ignore the distance from v2 *)
if m_cardinal dv1 = 1 && M.mem v2 dv1 then (
(* Now we definitely introduced a loop (but possibly non-negative)!
Let me see if this would be negative or not... *)
Queue.add (v1, (S.add v2 S.empty)) q;
propagate (g, src, dist) q v1
) else (
(* Or even if we fall back to else-clause here, the edge addition
may have introduced a cycle. Anyway, we need to check if one is
newly created or not at [propagate] *)
let (src, dist, dv1) =
if not (S.mem v2 src) then
(* If v2 isn't one of the source vertices, just simply do
propagation. *)
(src, dist, dv1)
else
(* We can exclude v2 from the list of source because
one can reach v2 from some other vertex. *)
((S.remove v2 src),
(* Note that following line can be skipped only if the
user don't remove vertex. Otherwise, such operation
like [add_edge g v1 v2] > [remove_vertex g v2] >
[add_vertex g v2] can result in unexpected
behaviour. *)
(M.map (M.remove v2) dist),
(* We need to re-obtain the distance mappings at v1,
since it can be changed by the line above. *)
(M.find v1 dist)) in
(* Now let's start propagation. *)
Queue.add (v1, set_of_map dv1) q;
propagate (g, src, dist) q v1)
let add_edge_e (g, src, dist) e =
(* Before adding edge to the graph, make sure that the edge is
not in the graph. If already in the graph, just do nothing
and return as is. *)
if G.mem_edge_e g e then
(g, src, dist)
else begin
(* Vertices involved *)
let v1 = G.E.src e in
let v2 = G.E.dst e in
let (g, src, dist) = List.fold_left
add_vertex (g, src, dist) [v1 ; v2] in
let g = G.add_edge_e g e in
add_edge_internal (g, src, dist) v1 v2
end
let add_edge (g, src, dist) v1 v2 =
(* Same as [add_edge_e] *)
if G.mem_edge g v1 v2 then
(g, src, dist)
else begin
let (g, src, dist) = List.fold_left
add_vertex (g, src, dist) [v1 ; v2] in
let g = G.add_edge g v1 v2 in
add_edge_internal (g, src, dist) v1 v2
end
let remove_edge_internal (g, src) v2 =
(* Actually, we need to rebuild the distance table, rather than
traverse precedants to remove the edge. *)
let q = Queue.create () in
let dist = S.fold (fun x dist ->
Queue.add (x, (S.add x S.empty)) q;
M.add x (M.add x (None, W.zero) M.empty) dist) src M.empty in
let g, src, dist = propagate (g, src, dist) q (S.choose src) in
if M.mem v2 dist then
(g, src, dist)
else (
Queue.add (v2, (S.add v2 S.empty)) q;
let src = S.add v2 src in
let dist = M.add v2 (M.add v2 (None, W.zero) M.empty) dist in
propagate (g, src, dist) q v2)
let remove_edge_e (g, src, dist) e =
(* Same as [add_edge_e] *)
if not (G.mem_edge_e g e) then
(g, src, dist)
else begin
let g = G.remove_edge_e g e in
(* Vertices involved *)
let v2 = G.E.dst e in
remove_edge_internal (g, src) v2
end
let remove_edge (g, src, dist) v1 v2 =
(* Same as [add_edge] *)
if not (G.mem_edge g v1 v2) then
(g, src, dist)
else begin
let g = G.remove_edge g v1 v2 in
remove_edge_internal (g, src) v2
end
let remove_vertex t v =
(* [remove_vertex] first deletes all outgoing edges from [v] *)
let (g, _, _) = t in
let t = G.fold_succ_e (fun e t -> remove_edge_e t e) g v t in
(* Then after, deletes all incoming edges to [v] *)
let (g, _, _) = t in
let t = G.fold_pred_e (fun e t -> remove_edge_e t e) g v t in
(* Note that we are iterating on [g] that is being modified during
iteration. We can do such an above iteration since G is here
permanent. Do not try this for imperative graph. *)
let (g, src, dist) = t in
(* Now we can feel free to delete [v]. *)
(G.remove_vertex g v,
(S.remove v src),
(M.map (M.remove v) dist))
let map_vertex f (g, src, dist) =
let map_map update m =
M.fold (fun v m acc -> M.add (f v) (update m) acc) m M.empty
in
(G.map_vertex f g,
S.fold (fun v acc -> S.add (f v) acc) src S.empty,
let update = function
| None, _ as v -> v
| Some e, w ->
Some (E.create (f (E.src e)) (E.label e) (f (E.dst e))), w
in
map_map (map_map update) dist)
(* All below are wrappers *)
let fold_pred_e f (g, _, _) = G.fold_pred_e f g
let iter_pred_e f (g, _, _) = G.iter_pred_e f g
let fold_succ_e f (g, _, _) = G.fold_succ_e f g
let iter_succ_e f (g, _, _) = G.iter_succ_e f g
let fold_pred f (g, _, _) = G.fold_pred f g
let fold_succ f (g, _, _) = G.fold_succ f g
let iter_pred f (g, _, _) = G.iter_pred f g
let iter_succ f (g, _, _) = G.iter_succ f g
let fold_edges_e f (g, _, _) = G.fold_edges_e f g
let iter_edges_e f (g, _, _) = G.iter_edges_e f g
let fold_edges f (g, _, _) = G.fold_edges f g
let iter_edges f (g, _, _) = G.iter_edges f g
let fold_vertex f (g, _, _) = G.fold_vertex f g
let iter_vertex f (g, _, _) = G.iter_vertex f g
let pred_e (g, _, _) = G.pred_e g
let succ_e (g, _, _) = G.succ_e g
let pred (g, _, _) = G.pred g
let succ (g, _, _) = G.succ g
let find_all_edges (g, _, _) = G.find_all_edges g
let find_edge (g, _, _) = G.find_edge g
let mem_edge_e (g, _, _) = G.mem_edge_e g
let mem_edge (g, _, _) = G.mem_edge g
let mem_vertex (g, _, _) = G.mem_vertex g
let in_degree (g, _, _) = G.in_degree g
let out_degree (g, _, _) = G.out_degree g
let nb_edges (g, _, _) = G.nb_edges g
let nb_vertex (g, _, _) = G.nb_vertex g
let is_empty (g, _, _) = G.is_empty g
let is_directed = G.is_directed
end
ocamlgraph-2.0.0/src/merge.ml 0000644 0001750 0000144 00000021345 13735627615 014436 0 ustar rt users (**************************************************************************)
(* *)
(* Ocamlgraph: a generic graph library for OCaml *)
(* Copyright (C) 2004-2012 *)
(* 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. *)
(* *)
(**************************************************************************)
module type S = sig
type graph
type vertex
type edge
type edge_label
val merge_vertex: graph -> vertex list -> graph
val merge_edges_e:
?src:vertex -> ?dst:vertex -> graph -> edge list -> graph
val merge_edges_with_label:
?src:vertex -> ?dst:vertex -> ?label:edge_label -> graph -> edge_label
-> graph
val merge_isolabelled_edges: graph -> graph
val merge_ends: ?strict:bool -> ?specified_vertex:vertex -> graph -> graph
val merge_starts: ?strict:bool -> ?specified_vertex:vertex -> graph -> graph
val merge_scc:
?loop_killer:bool -> ?specified_vertex:(vertex list -> vertex) -> graph ->
graph
end
module B(B: Builder.S) = struct
type graph = B.G.t
type vertex = B.G.vertex
type edge = B.G.edge
type edge_label = B.G.E.label
let mem x ec = List.exists (fun y -> B.G.V.equal x y) ec
let identify x ec = match ec with
| [] -> false , x
| y :: ec -> if mem x ec then true, y else false, x
let identify_extremities g vl =
let f e accu =
let sx, x = identify (B.G.E.src e) vl in
let sy, y = identify (B.G.E.dst e) vl in
if sx || sy
then B.G.E.(create x (label e) y) :: accu
else accu
in
B.G.fold_edges_e f g []
(* – former buggy version – the case where v is neither the source nor the
destination of some arrow was not taken into account, so that vertices were
just removed
let merge_vertex g vl = match vl with
| [] -> g
| _ :: vl' ->
let to_be_added = identify_extremities g vl in
let g = List.fold_left B.remove_vertex g vl' in
List.fold_left B.add_edge_e g to_be_added
*)
let merge_vertex g vl = match vl with
| [] -> g
| v :: vl' ->
let to_be_added = identify_extremities g vl in
let g = List.fold_left B.remove_vertex g vl' in
if to_be_added = []
then B.add_vertex g v
else List.fold_left B.add_edge_e g to_be_added
let merge_edges_e ?src ?dst g el = match el with
| e :: el' ->
let el' = List.filter (B.G.mem_edge_e g) el' in
if el' <> []
then
(let el = e :: el' in
let extremities e = B.G.E.(src e, dst e) in
let sources , destinations = List.split (List.map extremities el) in
let remove accu e =
try B.remove_edge_e accu e
with Invalid_argument _ -> g in
let g = List.fold_left remove g el in
if List.exists (fun v -> mem v destinations) sources then
let v = match src with
| None ->
(match dst with
| None -> List.hd sources
| Some w -> w)
| Some v -> v in
let g = merge_vertex g (v :: sources @ destinations) in
B.add_edge_e g B.G.E.(create v (label e) v)
else
let v = match src with None -> List.hd sources | Some v -> v in
let w = match src with
| None -> List.hd destinations
| Some w -> w in
let g = merge_vertex g sources in
let g = merge_vertex g destinations in
B.add_edge_e g B.G.E.(create v (label e) w))
else g
| [] -> g
let merge_edges_with_label ?src ?dst ?label g l =
let update_label e = match label with
| None -> e
| Some l -> B.G.E.(create (src e) l (dst e))
in
let collect_edge e accu =
if B.G.E.label e = l
then (update_label e) :: accu
else accu
in
let edges_to_be_merged = B.G.fold_edges_e collect_edge g [] in
merge_edges_e ?src ?dst g edges_to_be_merged
(* To deduce a comparison function on labels from a comparison function on
edges *)
let compare_label g =
try
let default_vertex =
let a_vertex_of_g = ref None in
(try B.G.iter_vertex (fun v -> a_vertex_of_g := Some v ; raise Exit) g
with Exit -> ());
match !a_vertex_of_g with
| Some v -> v
| None -> raise Exit (*hence g is empty*) in
fun l1 l2 ->
let e1 = B.G.E.create default_vertex l1 default_vertex in
let e2 = B.G.E.create default_vertex l2 default_vertex in
B.G.E.compare e1 e2
with Exit -> (fun _ _ -> 0)
let merge_isolabelled_edges g =
let module S = Set.Make(B.G.V) in
let do_meet s1 s2 = S.exists (fun x -> S.mem x s2) s1 in
let module M =
(* TODO: using [compare] here is really suspicious ...
DONE – yet not so clean *)
Map.Make(struct type t = B.G.E.label let compare = compare_label g end)
in
let accumulating e accu =
let l = B.G.E.label e in
try
let s , d = M.find l accu in
let s , d = B.G.E.(S.add (src e) s , S.add (dst e) d) in
M.add l (s, d) accu
with Not_found ->
M.add l B.G.E.(S.singleton (src e), S.singleton (dst e)) accu
in
let to_be_identified = B.G.fold_edges_e accumulating g M.empty in
let gathering _ (s, d) accu =
let to_be_gathered, others = List.partition (do_meet s) accu in
let accu =
List.fold_left (fun accu x -> S.union accu x) s to_be_gathered
:: others
in
let to_be_gathered , others = List.partition (do_meet d) accu in
List.fold_left (fun accu x -> S.union accu x) d to_be_gathered :: others
in
let to_be_identified = M.fold gathering to_be_identified [] in
List.fold_left
(fun accu s -> merge_vertex accu (S.elements s))
g
to_be_identified
let merge_ends ?(strict=false) ?specified_vertex g =
let accumulator v accu =
if
let out_d = B.G.out_degree g v in
out_d = 0 ||
((not strict) && out_d = List.length (B.G.find_all_edges g v v))
then v :: accu
else accu
in
let ends = B.G.(fold_vertex accumulator g []) in
let to_be_merged =
match specified_vertex with
| Some v -> v :: ends
| None -> ends
in
merge_vertex g to_be_merged
let merge_starts ?(strict=false) ?specified_vertex g =
let accumulator v accu =
if
let in_d = B.G.in_degree g v in
in_d = 0 ||
((not strict) && in_d = List.length (B.G.find_all_edges g v v))
then v :: accu
else accu
in
let starts = B.G.(fold_vertex accumulator g []) in
let to_be_merged =
match specified_vertex with
| Some v -> v :: starts
| None -> starts
in
merge_vertex g to_be_merged
let merge_scc ?(loop_killer=false) ?specified_vertex g =
let module C = Components.Make(B.G) in
let components = C.scc_list g in
let alter accu to_be_identified =
let to_be_identified =
match specified_vertex with
| None -> to_be_identified
| Some f -> (f to_be_identified) :: to_be_identified in
let v = List.hd to_be_identified in
let accu = merge_vertex accu to_be_identified in
if loop_killer
then B.remove_edge accu v v
else accu in
List.fold_left alter g components
end
module P(G: Sig.P) = B(Builder.P(G))
module I(G: Sig.I) = struct
include B(Builder.I(G))
let merge_vertex g vl = ignore (merge_vertex g vl)
let merge_edges_e ?src ?dst g el = ignore (merge_edges_e ?src ?dst g el)
let merge_edges_with_label ?src ?dst ?label g l =
ignore (merge_edges_with_label ?src ?dst ?label g l)
let merge_isolabelled_edges g = ignore (merge_isolabelled_edges g)
let merge_ends ?strict ?specified_vertex g =
ignore (merge_ends ?strict ?specified_vertex g)
let merge_starts ?strict ?specified_vertex g =
ignore (merge_starts ?strict ?specified_vertex g)
let merge_scc ?loop_killer ?specified_vertex g =
ignore (merge_scc ?loop_killer ?specified_vertex g)
end
(*
Local Variables:
compile-command: "make -C .."
End:
*)
ocamlgraph-2.0.0/src/minsep.ml 0000644 0001750 0000144 00000011050 13735627615 014622 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
module type G = sig
type t
module V : Sig.COMPARABLE
val succ: t -> V.t -> V.t list
val iter_succ: (V.t -> unit) -> t -> V.t -> unit
val fold_succ: (V.t -> 'a -> 'a) -> t -> V.t -> 'a -> 'a
val iter_vertex: (V.t -> unit) -> t -> unit
val fold_vertex: (V.t -> 'a -> 'a) -> t -> 'a -> 'a
end
module type MINSEP = sig
module G : G
module Vertex_Set : Set.S with type elt = G.V.t
module VSetset : Set.S with type elt = Vertex_Set.t
val allminsep : G.t -> Vertex_Set.t list
val list_of_allminsep : G.t -> G.V.t list list
val set_of_allminsep : G.t -> VSetset.t
end
module Make
(G : sig
include G
val cc: t -> V.t list -> V.t list list
(** compute the set of connected components of G(V \ l) *)
end) =
struct
module N = Oper.Neighbourhood(G)
module Vertex_Set: Set.S with type t = N.Vertex_Set.t
and type elt = G.V.t = N.Vertex_Set
module VSetset = Set.Make(N.Vertex_Set)
(* Use [N.Vertex_Set] instead of [Vertex_Set] in order to avoid an error with
ocamldoc 4.02. However this change requires to add extra type annotations
to module [Vertex_Set] above in order to prevent compilation error with
OCaml <= 4.0 :-(. *)
let initialisation g =
let cc = G.cc g in
let neighbourhood = N.list_from_vertex g in
let neighbourhoods = N.set_from_vertices g in
G.fold_vertex
(fun v s ->
List.fold_left
(fun s l -> neighbourhoods l :: s)
s (cc (v :: neighbourhood v)))
g []
let generation g =
let neighbourhood = N.list_from_vertex g in
let neighbourhoods = N.set_from_vertices g in
let cc = G.cc g in
let rec gen_aux seen bigs = function
| [] -> bigs
| s :: tl ->
let l = Vertex_Set.elements s in
let seen = VSetset.add s seen in
let bigs, tl =
Vertex_Set.fold
(fun v _ ->
let add_neighbourhoods (bigs, tl) l =
let s = neighbourhoods l in
s :: bigs, if VSetset.mem s seen then tl else s :: tl
in
List.fold_left
add_neighbourhoods
(bigs, tl) (cc (l @ neighbourhood v)))
s (bigs, tl)
in
gen_aux seen bigs tl
in
fun bigs -> gen_aux VSetset.empty bigs bigs
let allminsep g = generation g (initialisation g)
let set_of_allminsep g =
List.fold_left
(fun bigs s -> VSetset.add s bigs) VSetset.empty (allminsep g)
let list_of_allminsep g = List.map Vertex_Set.elements (allminsep g)
end
module P(G : sig include G val remove_vertex : t -> V.t -> t end) = struct
module G = G
include Make(struct
include G
let cc =
let module CC = Components.Make(G) in
fun g l ->
let g = List.fold_left remove_vertex g l in
CC.scc_list g
end)
end
module I(G : sig
include G
module Mark : Sig.MARK with type graph = t and type vertex = V.t
end) =
struct
module G = G
include Make(struct
include G
let cc =
let module CC =
Components.Make
(struct
include G
let iter_vertex f =
iter_vertex (fun v -> if Mark.get v=0 then f v)
end)
in
fun g l ->
G.Mark.clear g;
List.iter (fun v -> G.Mark.set v 1) l;
CC.scc_list g
end)
end
ocamlgraph-2.0.0/src/graphml.mli 0000644 0001750 0000144 00000004666 13735627615 015151 0 ustar rt users (******************************************************************************)
(* *)
(* Copyright (C) 2012 Pietro Abate *)
(* *)
(* This library is free software: you can redistribute it and/or modify *)
(* it under the terms of the GNU Lesser General Public License as *)
(* published by the Free Software Foundation, either version 3 of the *)
(* License, or (at your option) any later version. A special linking *)
(* exception to the GNU Lesser General Public License applies to this *)
(* library, see the COPYING file for more information. *)
(* *)
(******************************************************************************)
(** Generic GraphMl Printer *)
(** Graph information required by Graphml *)
module type G = sig
type t
type vertex
module E : sig
type t
val src: t -> vertex
val dst : t -> vertex
end
val is_directed : bool
val iter_vertex : (vertex -> unit) -> t -> unit
val iter_edges_e : (E.t -> unit) -> t -> unit
end
(** Graphml Printer given a graph and required info *)
module Print
(G: G)
(L : sig
val vertex_properties : (string * string * string option) list
(** List of the type of the vertex proprierties.
The format is (id,type,default). *)
val edge_properties : (string * string * string option) list
(** List of the type of the edge proprierties. *)
val map_vertex : G.vertex -> (string * string) list
(** Associates to each vertex a key/value list where
the key is the id of a vertex attribute and the value is the value
associated to this vertex *)
val map_edge : G.E.t -> (string * string) list
(** Associates to each edge a key/value list *)
val vertex_uid : G.vertex -> int
(** @return a unique integer identifier for the vertex *)
val edge_uid : G.E.t -> int
(** @return a unique integer identifier for the edge *)
end) :
sig
val print : Format.formatter -> G.t -> unit
(** [print fmt graph] print the GraphMl representation of the given graph
on the given formatter *)
end
(*
Local Variables:
compile-command: "make -C .."
End:
*)
ocamlgraph-2.0.0/src/clique.ml 0000644 0001750 0000144 00000003651 13735627615 014621 0 ustar rt users (**************************************************************************)
(* *)
(* Ocamlgraph: a generic graph library for OCaml *)
(* Copyright (C) 2014-2015 *)
(* Giselle Reis *)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
module type G = sig
type t
module V : Sig.COMPARABLE
val succ : t -> V.t -> V.t list
val fold_vertex : (V.t -> 'a -> 'a) -> t -> 'a -> 'a
end
module Bron_Kerbosch(G : G) = struct
let rec bron_kerbosch cliquelst graph clique candidates used = match (candidates, used) with
| ([], []) -> clique :: cliquelst
| ([], _) -> cliquelst
| (c, u) ->
let (_, _, cliques) = List.fold_left ( fun (c, u, acc) v ->
(* Get the neighbors ignoring self-loops *)
let n = List.filter (fun nb -> not (G.V.equal nb v)) (G.succ graph v) in
let c' = List.filter (fun cv -> List.exists (fun v -> G.V.equal v cv) n) c in
let u' = List.filter (fun cv -> List.exists (fun v -> G.V.equal v cv) n) u in
let c_minus_v = List.filter (fun cv -> not (G.V.equal cv v)) c in
( c_minus_v, (v :: u), bron_kerbosch acc graph (v :: clique) c' u')
) (c, u, []) c in
cliques @ cliquelst
let maximalcliques g =
let vertices = G.fold_vertex (fun v acc -> v :: acc) g [] in
bron_kerbosch [] g [] vertices []
end
ocamlgraph-2.0.0/src/builder.ml 0000644 0001750 0000144 00000004505 13735627615 014764 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
module type S = sig
module G : Sig.G
val empty : unit -> G.t
val copy : G.t -> G.t
val add_vertex : G.t -> G.V.t -> G.t
val add_edge : G.t -> G.V.t -> G.V.t -> G.t
val add_edge_e : G.t -> G.E.t -> G.t
val remove_vertex : G.t -> G.V.t -> G.t
val remove_edge : G.t -> G.V.t -> G.V.t -> G.t
val remove_edge_e : G.t -> G.E.t -> G.t
end
module type INT = S with type G.V.label = int
module P(G : Sig.P) = struct
module G = G
let empty () = G.empty
let copy g = g
let add_vertex = G.add_vertex
let add_edge = G.add_edge
let add_edge_e = G.add_edge_e
let remove_vertex = G.remove_vertex
let remove_edge = G.remove_edge
let remove_edge_e = G.remove_edge_e
end
module I(G : Sig.I) = struct
module G = G
let empty () = G.create ~size:97 ()
let copy = G.copy
let add_vertex g v = G.add_vertex g v; g
let add_edge g v1 v2 = G.add_edge g v1 v2; g
let add_edge_e g e = G.add_edge_e g e; g
let remove_vertex g v = G.remove_vertex g v; g
let remove_edge g v1 v2 = G.remove_edge g v1 v2; g
let remove_edge_e g e = G.remove_edge_e g e; g
end
(*
Local Variables:
compile-command: "make -C .."
End:
*)
ocamlgraph-2.0.0/src/oper.ml 0000644 0001750 0000144 00000013573 13735627615 014310 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(* Basic operations over graphs *)
module type S = sig
type g
val transitive_closure : ?reflexive:bool -> g -> g
val add_transitive_closure : ?reflexive:bool -> g -> g
val transitive_reduction : ?reflexive:bool -> g -> g
val replace_by_transitive_reduction : ?reflexive:bool -> g -> g
val mirror : g -> g
val complement : g -> g
val intersect : g -> g -> g
val union : g -> g -> g
end
module Make(B : Builder.S) = struct
open B
(* Roy-Warshall's algorithm *)
type g = G.t
let add_transitive_closure ?(reflexive=false) g0 =
let phi v g =
let g = if reflexive then B.add_edge g v v else g in
G.fold_succ
(fun sv g -> G.fold_pred (fun pv g -> B.add_edge g pv sv) g v g)
g v g
in
G.fold_vertex phi g0 g0
let transitive_closure ?(reflexive=false) g0 =
add_transitive_closure ~reflexive (B.copy g0)
let mirror g =
if G.is_directed then begin
let g' =
G.fold_vertex
(fun v g' -> B.add_vertex g' v)
g (B.empty ())
in
G.fold_edges_e
(fun e g' ->
let v1 = G.E.src e in
let v2 = G.E.dst e in
B.add_edge_e g' (G.E.create v2 (G.E.label e) v1))
g g'
end else
g
let complement g =
G.fold_vertex
(fun v g' ->
G.fold_vertex
(fun w g' ->
if G.mem_edge g v w then g'
else B.add_edge g' v w)
g g')
g (B.empty ())
let intersect g1 g2 =
G.fold_vertex
(fun v g ->
try
let succ = G.succ_e g2 v in
G.fold_succ_e
(fun e g ->
if List.exists (fun e' -> G.E.compare e e' = 0) succ
then B.add_edge_e g e
else g)
g1 v (B.add_vertex g v)
with Invalid_argument _ ->
(* [v] not in [g2] *)
g)
g1 (B.empty ())
let union g1 g2 =
let add g1 g2 =
(* add the graph [g1] in [g2] *)
G.fold_vertex
(fun v g ->
G.fold_succ_e (fun e g -> B.add_edge_e g e) g1 v (B.add_vertex g v))
g1 g2
in
add g1 (B.copy g2)
let replace_by_transitive_reduction ?(reflexive=false) g0 =
(* first compute reachability in g0 using a DFS from each vertex *)
let module H = Hashtbl.Make(G.V) in
let module D = Traverse.Dfs(G) in
let reachable = H.create (G.nb_vertex g0) in
let path_from v =
let s = H.create 8 in
H.add reachable v s;
D.prefix_component (fun w -> H.add s w ()) g0 v in
G.iter_vertex path_from g0;
let path u v = H.mem (H.find reachable u) v in
(* then remove redundant edges *)
let phi v g =
let g = if reflexive then B.remove_edge g v v else g in
G.fold_succ
(fun sv g ->
G.fold_succ
(fun sv' g ->
if not (G.V.equal sv sv') && path sv sv'
then B.remove_edge g v sv' else g)
g v g)
g v g
in
G.fold_vertex phi g0 g0
let transitive_reduction ?(reflexive=false) g0 =
replace_by_transitive_reduction ~reflexive (B.copy g0)
end
module P(G : Sig.P) = Make(Builder.P(G))
module I(G : Sig.I) = Make(Builder.I(G))
module Choose(G : sig
type t
type vertex
type edge
val iter_vertex : (vertex -> unit) -> t -> unit
val iter_edges_e : (edge -> unit) -> t -> unit
end) =
struct
exception Found_Vertex of G.vertex
let choose_vertex g =
try
G.iter_vertex (fun v -> raise (Found_Vertex v)) g;
invalid_arg "choose_vertex"
with Found_Vertex v ->
v
exception Found_Edge of G.edge
let choose_edge g =
try
G.iter_edges_e (fun v -> raise (Found_Edge v)) g;
invalid_arg "choose_vertex"
with Found_Edge v ->
v
end
module Neighbourhood(G : sig
type t
module V : Sig.COMPARABLE
val fold_succ: (V.t -> 'a -> 'a) -> t -> V.t -> 'a -> 'a
val succ: t -> V.t -> V.t list
end) =
struct
module Vertex_Set = Set.Make(G.V)
let set_from_vertex g v =
G.fold_succ
(fun v' s -> if G.V.equal v v' then s else Vertex_Set.add v' s)
g v Vertex_Set.empty
let list_from_vertex g v =
let rec aux = function
| [] -> []
| v' :: l ->
if G.V.equal v v' then begin
assert (not (List.exists (G.V.equal v) l));
l
end else
v' :: aux l
in
aux (G.succ g v)
let set_from_vertices g l =
let fold_left f = List.fold_left f Vertex_Set.empty l in
let env_init = fold_left (fun s v -> Vertex_Set.add v s) in
let add x s =
if Vertex_Set.mem x env_init then s else Vertex_Set.add x s
in
fold_left (fun s v -> G.fold_succ add g v s)
let list_from_vertices g l = Vertex_Set.elements (set_from_vertices g l)
end
ocamlgraph-2.0.0/src/fixpoint.mli 0000644 0001750 0000144 00000012100 13735627615 015335 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(* Copyright (c) 2010 - 2012 Technische Universitaet Muenchen
* Markus W. Weissmann
* All rights reserved. *)
(** Fixpoint computation implemented using the work list algorithm.
This module makes writing data-flow analysis easy.
One of the simplest fixpoint analysis is that of reachability.
Given a directed graph module [G], its analysis can be implemented
as follows:
{[
module Reachability = Graph.Fixpoint.Make(G)
(struct
type vertex = G.E.vertex
type edge = G.E.t
type g = G.t
type data = bool
let direction = Graph.Fixpoint.Forward
let equal = (=)
let join = (||)
let analyze _ = (fun x -> x)
end)
]}
The types for [vertex], [edge] and [g] are those of the graph to be
analyzed. The [data] type is [bool]: It will tell if the
vertex is reachable from the start vertex. The [equal] operation
for [bool] is simply structural equality; the [join] operation is
logical or. The [analyze] function is very simple, too: If the
predecessor vertex is reachable, so is the successor vertex of the
edge.
To use the analysis, an instance of a graph [g] is required. For
this analysis a predicate [is_root_vertex : G.E.vertex -> bool] is
required to initialize the reachability of the root vertex to
[true] and of all other vertices to [false].
{[
let g = ...
let result = Reachability.analyze is_root_vertex g
]}
The [result] is a map of type [G.E.vertex -> bool] that can be
queried for every vertex to tell if the vertex is reachable from
the root vertex.
@author Markus W. Weissmann
@see "Introduction to Lattices and Order" B. A. Davey and H. A. Priestley, Cambridge University Press, 2002
@see "Fixed Point Theory" Andrzej Granas and James Dugundji, Springer, 2003
@see "Principles of Program Analysis" Flemming Nielson, Hanne Riis Nielson and Chris Hankin, Springer, 2005
@see "Ubersetzerbau 3: Analyse und Transformation" Reinhard Wilhelm and Helmut Seidl, Springer, 2010
*)
(** Minimal graph signature for work list algorithm *)
module type G = sig
type t
module V : Sig.COMPARABLE
module E : sig
type t
val dst : t -> V.t
val src : t -> V.t
end
val fold_vertex : (V.t -> 'a -> 'a) -> t -> 'a -> 'a
val succ_e : t -> V.t -> E.t list
val pred_e : t -> V.t -> E.t list
val succ : t -> V.t -> V.t list
val pred : t -> V.t -> V.t list
end
type direction = Forward | Backward
(** Type of an analysis *)
module type Analysis = sig
type data
(** information stored at each vertex *)
type edge
(** type of edges of the underlying graph *)
type vertex
(** type of vertices of the underlying graph *)
type g
(** type of the underlying graph *)
val direction : direction
(** the direction of the analysis *)
val join : data -> data -> data
(** operation how to join data when paths meet *)
val equal : data -> data -> bool
(** predicate to determine the fixpoint *)
val analyze : edge -> data -> data
(** the actual analysis of one edge; provided the edge and the incoming
data, it needs to compute the outgoing data *)
end
module Make
(G : G)
(A : Analysis with type g = G.t with type edge = G.E.t
with type vertex = G.V.t) :
sig
val analyze : (G.V.t -> A.data) -> A.g -> (G.V.t -> A.data)
(** [analyze f g] computes the fixpoint on the given graph using the
work list algorithm. Beware that a misconstructed Analysis will
not terminate! [f] is used to create the initial analysis
data. The function returned is a map to see what data was computed
for which node.
Beware of applying function [analyze] partially, to arguments
[f] and [g] only. The result is a function that is to be used to query
the result of the analysis. *)
end
ocamlgraph-2.0.0/src/weakTopological.mli 0000644 0001750 0000144 00000011223 13735627615 016626 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(* Copyright © 2015 Thibault Suzanne
* École Normale Supérieure, Département d'Informatique
* Paris Sciences et Lettres
*)
(* Original algorithm by François Bourdoncle. See :
* "Efficient chaotic iteration strategies with widenings",
* Formal Methods in Programming and their Applications,
* Springer Berlin Heidelberg, 1993.
*)
(** Weak topological ordering of the vertices of a graph, as described
by François Bourdoncle.
Weak topological ordering is an extension of topological ordering
for potentially cyclic graphs.
A hierarchical ordering of a set is a well-parenthesized
permutation of its elements with no consecutive [(]. The elements
between two parentheses are called a {e component}, and the first
elements of a component is called the {e head}. A weak topological
ordering of a graph is a hierarchical ordering of its vertices
such that for every edge [u -> v] of the graph, either [u] comes
(strictly) before [v], or [v] is the head of a component
containing [u].
One may notice that :
- For an acyclic graph, every topological ordering is also a weak
topological ordering.
- For any graph with the vertices [v1, ..., vN], the following
trivial weak topological ordering is valid : [(v1 (v2
(... (vN))...))].
Weak topological ordering are useful for fixpoint computation (see
{!ChaoticIteration}). This module aims at computing weak
topological orderings which improve the precision and the
convergence speed of these analyses.
@author Thibault Suzanne
@see "Efficient chaotic iteration strategies with widenings",
François Bourdoncle,
Formal Methods in Programming and their Applications,
Springer Berlin Heidelberg, 1993
*)
(** Minimal graph signature for the algorithm *)
module type G = sig
type t
module V : Sig.COMPARABLE
val iter_vertex : (V.t -> unit) -> t -> unit
val iter_succ : (V.t -> unit) -> t -> V.t -> unit
end
(** The type of the elements of a weak topological ordering over a set
of ['a].
- [Vertex v] represents a single vertex.
- [Component (head, cs)] is a component of the wto, that is
a sequence of elements between two parentheses. [head] is the head
of the component, that is the first element, which is guaranteed to
be a vertex by definition. [cs] is the rest of the component.
*)
type 'a element =
| Vertex of 'a
| Component of 'a * 'a t
and 'a t
(** The type of a sequence of outermost elements in a weak topological
ordering. This is also the type of a weak topological ordering
over a set of ['a].
*)
val fold_left : ('a -> 'b element -> 'a) -> 'a -> 'b t -> 'a
(** Folding over the elements of a weak topological ordering. They are
given to the accumulating function according to their order.
Note that as [element]s present in an ordering of type [t] can
contain values of type [t] itself due to the [Component] variant,
this function should be used by defining a recursive function [f],
which will call [fold_left] with [f] used to define the first
parameter.
*)
module Make : functor (G : G) -> sig
val recursive_scc : G.t -> G.V.t -> G.V.t t
(** [recursive_scc g root_g] computes a weak topological ordering of
the vertices of [g], with the general algorithm recursively
computing the strongly connected components of [g]. [root_g] is
taken as the root of the graph and must be a valid vertex of
[g].
*)
end
ocamlgraph-2.0.0/src/dGraphRandModel.mli 0000644 0001750 0000144 00000004073 13735627615 016502 0 ustar rt users (**************************************************************************)
(* *)
(* This file is part of OcamlGraph. *)
(* *)
(* Copyright (C) 2009-2010 *)
(* CEA (Commissariat � l'�nergie Atomique) *)
(* *)
(* you can redistribute it and/or modify it under the terms of the GNU *)
(* Lesser General Public License as published by the Free Software *)
(* Foundation, version 2.1, with a linking exception. *)
(* *)
(* It 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. See the *)
(* GNU Lesser General Public License for more details. *)
(* *)
(* See the file ../LICENSE for more details. *)
(* *)
(* Authors: *)
(* - Julien Signoles (Julien.Signoles@cea.fr) *)
(* - Jean-Denis Koeck (jdkoeck@gmail.com) *)
(* - Benoit Bataille (benoit.bataille@gmail.com) *)
(* *)
(**************************************************************************)
module G: Sig.G
module GraphAttrs:
Graphviz.GraphWithDotAttrs with type t = G.t
and type V.t = G.V.t
and type E.t = G.E.t
val create: unit -> DGraphModel.Make(GraphAttrs).model
ocamlgraph-2.0.0/src/mcs_m.mli 0000644 0001750 0000144 00000004573 13735627615 014612 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(* $Id: mcs_m.mli,v 1.2 2004-10-19 15:21:44 signoles Exp $ *)
(** Maximal Cardinality Search (MCS-M) algorithm
Based on the article:
Maximal Cardinality Search for Computing Minimal Triangulations of Graphs.
by A. Berry, Jean R. S. Blair, Pinar Heggernes & Barry W. Peyton.
@author Matthieu Sozeau
@author Pierre-Loic Garoche *)
module MaximalCardinalitySearch : sig
module P(G : Sig.P) : sig
type edgelist = (G.V.t * G.V.t) list
(** [mcsm g] returns a tuple [(o, e)] where [o] is a perfect elimination
order of [g'] where [g'] is the triangulation [e] applied to [g]. *)
val mcsm : G.t -> (int * G.V.t) list * edgelist
(** [triangulate g] computes a triangulation of [g]
using the MCS-M algorithm *)
val triangulate : G.t -> G.t
end
module I(Gr : Sig.I) : sig
type edgelist = (Gr.V.t * Gr.V.t) list
(** [mcsm g] return a tuple [(o, e)] where o is a perfect elimination order
of [g'] where [g'] is the triangulation [e] applied to [g]. *)
val mcsm : Gr.t -> (int * Gr.V.t) list * edgelist
(** [triangulate g] triangulates [g] using the MCS-M algorithm *)
val triangulate : Gr.t -> unit
end
end
ocamlgraph-2.0.0/src/traverse.ml 0000644 0001750 0000144 00000024571 13735627615 015176 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(* Graph traversal *)
module type G = sig
val is_directed : bool
type t
module V : Sig.COMPARABLE
val iter_vertex : (V.t -> unit) -> t -> unit
val fold_vertex : (V.t -> 'a -> 'a) -> t -> 'a -> 'a
val iter_succ : (V.t -> unit) -> t -> V.t -> unit
val fold_succ : (V.t -> 'a -> 'a) -> t -> V.t -> 'a -> 'a
end
(* depth-first search *)
module Dfs(G : G) = struct
module H = Hashtbl.Make(G.V)
let fold f i g =
let h = H.create 97 in
let s = Stack.create () in
let push v =
if not (H.mem h v) then begin H.add h v (); Stack.push v s end
in
let rec loop acc =
if not (Stack.is_empty s) then
let v = Stack.pop s in
let ns = f v acc in
G.iter_succ push g v;
loop ns
else
acc
in
G.fold_vertex (fun v s -> push v; loop s) g i
let iter ?(pre=fun _ -> ()) ?(post=fun _ -> ()) g =
let h = H.create 97 in
let rec visit v =
if not (H.mem h v) then begin
H.add h v ();
pre v;
G.iter_succ visit g v;
post v
end
in
G.iter_vertex visit g
let postfix post g = iter ~post g
let fold_component f i g v0 =
let h = H.create 97 in
let s = Stack.create () in
(* invariant: [h] contains exactly the vertices which have been pushed *)
let push v =
if not (H.mem h v) then begin H.add h v (); Stack.push v s end
in
push v0;
let rec loop acc =
if not (Stack.is_empty s) then
let v = Stack.pop s in
let ns = f v acc in
G.iter_succ push g v;
loop ns
else
acc
in
loop i
let iter_component ?(pre=fun _ -> ()) ?(post=fun _ -> ()) g v =
let h = H.create 97 in
let rec visit v =
H.add h v ();
pre v;
G.iter_succ (fun w -> if not (H.mem h w) then visit w) g v;
post v
in
visit v
let postfix_component post g = iter_component ~post g
module Tail = struct
let has_cycle g =
let h = H.create 97 in
let stack = Stack.create () in
let loop () =
while not (Stack.is_empty stack) do
let v = Stack.top stack in
if H.mem h v then begin
(* we are now done with node v *)
(* assert (H.find h v = true); *)
H.replace h v false;
ignore (Stack.pop stack)
end else begin
(* we start DFS from node v *)
H.add h v true;
G.iter_succ
(fun w ->
try if H.find h w then raise Exit
with Not_found -> Stack.push w stack)
g v;
end
done
in
try
G.iter_vertex
(fun v ->
if not (H.mem h v) then begin Stack.push v stack; loop () end)
g;
false
with Exit ->
true
let has_cycle_undirected g =
let h = H.create 97 in
let father = H.create 97 in
let is_father u v = (* u is the father of v in the DFS descent *)
try G.V.equal (H.find father v) u with Not_found -> false
in
let stack = Stack.create () in
let loop () =
while not (Stack.is_empty stack) do
let v = Stack.top stack in
if H.mem h v then begin
(* we are now done with node v *)
(* assert (H.find h v = true); *)
H.remove father v;
H.replace h v false;
ignore (Stack.pop stack)
end else begin
(* we start DFS from node v *)
H.add h v true;
G.iter_succ
(fun w ->
try if H.find h w && not (is_father w v) then raise Exit
with Not_found -> H.add father w v; Stack.push w stack)
g v;
end
done
in
try
G.iter_vertex
(fun v ->
if not (H.mem h v) then begin Stack.push v stack; loop () end)
g;
false
with Exit ->
true
let has_cycle g =
if G.is_directed then has_cycle g else has_cycle_undirected g
let iter f g =
let h = H.create 97 in
let stack = Stack.create () in
let loop () =
while not (Stack.is_empty stack) do
let v = Stack.pop stack in
if not (H.mem h v) then begin
H.add h v ();
f v;
G.iter_succ
(fun w -> if not (H.mem h w) then Stack.push w stack) g v
end
done
in
G.iter_vertex
(fun v ->
if not (H.mem h v) then begin Stack.push v stack; loop () end)
g
let iter_component f g v0 =
let h = H.create 97 in
let stack = Stack.create () in
Stack.push v0 stack;
while not (Stack.is_empty stack) do
let v = Stack.pop stack in
if not (H.mem h v) then begin
H.add h v ();
f v;
G.iter_succ (fun w -> if not (H.mem h w) then Stack.push w stack) g v
end
done
end
let prefix = Tail.iter
let has_cycle = Tail.has_cycle
let prefix_component = Tail.iter_component
(* step-by-step iterator *)
module S = Set.Make(G.V)
type iterator = S.t * G.V.t list * G.t
(** (h, st, g) where h is the set of marked vertices and st the stack
invariant: the first element of st is not in h i.e. to be visited *)
let start g =
let st = G.fold_vertex (fun v st -> v :: st) g [] in
S.empty, st, g
let get (_,st,_) = match st with
| [] -> raise Exit
| v :: _ -> v
let step (s,st,g) = match st with
| [] ->
raise Exit
| v :: st ->
let s' = S.add v s in
let st' = G.fold_succ (fun w st -> w :: st) g v st in
let rec clean = function
| w :: st when S.mem w s' -> clean st
| st -> st
in
(s', clean st', g)
end
(* breadth-first search *)
module Bfs(G : G) = struct
module H = Hashtbl.Make(G.V)
let fold f i (g : G.t) =
let h = H.create 97 in
let q = Queue.create () in
(* invariant: [h] contains exactly the vertices which have been pushed *)
let push v =
if not (H.mem h v) then begin H.add h v (); Queue.add v q end
in
let rec loop s =
if not (Queue.is_empty q) then
let v = Queue.pop q in
let ns = f v s in (* Sticking to OCamlGraph's fold conv *)
G.iter_succ push g v;
loop ns
else
s
in
G.fold_vertex (fun v s -> push v; loop s) g i
let iter f = fold (fun v () -> f v) ()
let fold_component f i g v0 =
let h = H.create 97 in
let q = Queue.create () in
(* invariant: [h] contains exactly the vertices which have been pushed *)
let push v =
if not (H.mem h v) then begin H.add h v (); Queue.add v q end
in
push v0;
let rec loop s =
if not (Queue.is_empty q) then
let v = Queue.pop q in
let ns = f v s in
G.iter_succ push g v;
loop ns
else
s
in
loop i
let iter_component f = fold_component (fun v () -> f v) ()
(* step-by-step iterator *)
(* simple, yet O(1)-amortized, persistent queues *)
module Q = struct
type 'a t = 'a list * 'a list
exception Empty
let empty = [], []
let is_empty = function [], [] -> true | _ -> false
let push x (i,o) = (x :: i, o)
let pop = function
| i, y :: o -> y, (i,o)
| [], [] -> raise Empty
| i, [] -> match List.rev i with
| x :: o -> x, ([], o)
| [] -> assert false
let peek q = fst (pop q)
end
module S = Set.Make(G.V)
(* state is [(s,q,g)] : [s] contains elements never been pushed in [q] *)
type iterator = S.t * G.V.t Q.t * G.t
let start g =
let s = G.fold_vertex S.add g S.empty in
s, Q.empty, g
let get (s,q,_) =
if Q.is_empty q then
if S.is_empty s then raise Exit else S.choose s
else
Q.peek q
let step (s,q,g) =
let push v (s,q as acc) =
if S.mem v s then
S.remove v s, Q.push v q
else
acc
in
let v,s',q' =
if Q.is_empty q then begin
if S.is_empty s then raise Exit;
let v = S.choose s in
v, S.remove v s, q
end else
let v,q' = Q.pop q in
v, s, q'
in
let s'',q'' = G.fold_succ push g v (s',q') in
(s'',q'',g)
end
(* Graph traversal with marking. *)
module type GM = sig
type t
module V : sig type t end
val iter_vertex : (V.t -> unit) -> t -> unit
val iter_succ : (V.t -> unit) -> t -> V.t -> unit
module Mark : sig
val clear : t -> unit
val get : V.t -> int
val set : V.t -> int -> unit
end
end
module Mark(G : GM) = struct
let dfs g =
G.Mark.clear g;
let n = ref 0 in
let rec visit v =
if G.Mark.get v = 0 then begin
incr n;
G.Mark.set v !n;
G.iter_succ visit g v
end
in
G.iter_vertex visit g
(* invariant: [h v = 0] means not visited at all; [h v = 1] means
already visited in the current component; [h v = 2] means
already visited in another tree *)
let has_cycle g =
G.Mark.clear g;
let rec visit v =
G.Mark.set v 1;
G.iter_succ
(fun w ->
let m = G.Mark.get w in
if m = 1 then raise Exit;
if m = 0 then visit w)
g v;
G.Mark.set v 2
in
try G.iter_vertex (fun v -> if G.Mark.get v = 0 then visit v) g; false
with Exit -> true
end
ocamlgraph-2.0.0/src/topological.ml 0000644 0001750 0000144 00000012023 13735627615 015644 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
module type G = sig
type t
module V : Sig.COMPARABLE
val iter_vertex : (V.t -> unit) -> t -> unit
val iter_succ : (V.t -> unit) -> t -> V.t -> unit
end
module Make(G: G) = struct
module Scc = Components.Make(G)
let fold f g acc =
(* build the graph of strongly-connected components *)
let n, scc = Scc.scc g in
let vertices = Array.make n [] in
let edges = Array.make n [] in
let degree = Array.make n 0 in (* in-degree *)
let add_vertex x =
let ix = scc x in
vertices.(ix) <- x :: vertices.(ix);
let add_edge y =
let iy = scc y in
if ix <> iy then begin
edges.(ix) <- iy :: edges.(ix);
degree.(iy) <- degree.(iy) + 1
end
in
G.iter_succ add_edge g x
in
G.iter_vertex add_vertex g;
(* standard topological sort on a DAG *)
let todo = Queue.create () in
let rec walk acc =
if Queue.is_empty todo then
acc
else
let i = Queue.pop todo in
let acc = List.fold_right f vertices.(i) acc in
List.iter
(fun j ->
let d = degree.(j) in
assert (d > 0); (* no back edge *)
if d = 1 then Queue.push j todo else degree.(j) <- d-1)
edges.(i);
walk acc
in
for i = 0 to n-1 do if degree.(i) = 0 then Queue.push i todo done;
walk acc
let iter f g = fold (fun v () -> f v) g ()
end
module Make_stable(G: sig include G val in_degree : t -> V.t -> int end) =
struct
module H = Hashtbl.Make(G.V)
module C = Path.Check(G)
let choose ~old (v, n: G.V.t * int) =
let l, min = old in
if n = min then v :: l, n
else if n < min then [ v ], n
else old
module Q = struct
module S = Set.Make(G.V)
let create () = ref S.empty
let push v s = s := S.add v !s
let pop s =
let r = S.min_elt !s in
s := S.remove r !s;
r
let is_empty s = S.is_empty !s
let choose ~old new_ =
let l, n = choose ~old new_ in
List.sort G.V.compare l, n
end
(* in case of multiple cycles, choose one vertex in a cycle which
does not depend of any other. *)
let find_top_cycle checker vl =
(* choose [v] if each other vertex [v'] is in the same cycle
(a path from v to v') or is in a separate component
(no path from v' to v).
So, if there is a path from v' to without any path from v to v',
discard v. *)
let on_top_cycle v =
List.for_all
(fun v' ->
G.V.equal v v' ||
C.check_path checker v v' || not (C.check_path checker v' v))
vl
in
List.filter on_top_cycle vl
let fold f g acc =
let checker = C.create g in
let degree = H.create 97 in
let todo = Q.create () in
let push x =
H.remove degree x;
Q.push x todo
in
let rec walk acc =
if Q.is_empty todo then
(* let's find any node of minimal degree *)
let min, _ =
H.fold (fun v d old -> Q.choose ~old (v, d)) degree ([], max_int)
in
match min with
| [] -> acc
| _ ->
let vl = find_top_cycle checker min in
List.iter push vl;
(* let v = choose_independent_vertex checker min in push v; *)
walk acc
else
let v = Q.pop todo in
let acc = f v acc in
G.iter_succ
(fun x->
try
let d = H.find degree x in
if d = 1 then push x else H.replace degree x (d-1)
with Not_found ->
(* [x] already visited *)
())
g v;
walk acc
in
G.iter_vertex
(fun v ->
let d = G.in_degree g v in
if d = 0 then Q.push v todo
else H.add degree v d)
g;
walk acc
let iter f g = fold (fun v () -> f v) g ()
end
(*
Local Variables:
compile-command: "make -C .."
End:
*)
ocamlgraph-2.0.0/src/delaunay.ml 0000644 0001750 0000144 00000027722 13735627615 015146 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(* $Id: delaunay.ml,v 1.12 2005-11-02 13:43:35 filliatr Exp $ *)
(** Code follows Don Knuth's algorithm
from ``Axioms and hulls'' (LNCS 606, Springer-Verlag, 1992), pp. 73-77.
Some code and comments are taken from the Stanford Graph Base,
file [gb_plane].
*)
module type CCC = sig
type point
val ccw : point -> point -> point -> bool
val in_circle : point -> point -> point -> point -> bool
end
module type Triangulation = sig
module S : CCC
type triangulation
val triangulate : S.point array -> triangulation
val iter : (S.point -> S.point -> unit) -> triangulation -> unit
val fold : (S.point -> S.point -> 'a -> 'a) -> triangulation -> 'a -> 'a
val iter_triangles :
(S.point -> S.point -> S.point -> unit) -> triangulation -> unit
end
module Make (S : CCC) = struct
module S = S
type point = Point of int | Infinity
(* Each edge of the current triangulation is represented by two arcs
pointing in opposite directions; the two arcs are called mates. Each
arc conceptually has a triangle on its left and a mate on its right. *)
type arc = {
mutable vert : point;
(* v, if this arc goes from u to v *)
mutable next : arc;
(* the arc from v that shares a triangle with this one *)
mutable inst : node ref;
(* instruction to change when the triangle is modified *)
mate : int
}
and node =
| Branch of int * int * node ref * node ref
| Terminal of arc
type triangulation = {
points : S.point array;
arcs : arc array;
last_used_arc : int
}
let rec dummy_arc =
{ vert = Infinity; next = dummy_arc;
inst = ref (Terminal dummy_arc); mate = -1 }
let make_arc n i =
{ vert = Infinity; next = dummy_arc;
inst = ref (Terminal dummy_arc); mate = 6 * n - 7 - i }
let finite = function Point p -> p | Infinity -> assert false
(* [flip] will be used in both steps T4 and T5 *)
let flip c d e t'' p n n' =
let e' = e.next in
let c' = c.next in
let c'' = c'.next in
e.next <- c;
c.next <- c'';
c''.next <- e;
c''.inst <- n; c.inst <- n; e.inst <- n;
c.vert <- Point p;
d.next <- e';
e'.next <- c';
c'.next <- d;
c'.inst <- n'; e'.inst <- n'; d.inst <- n';
d.vert <- Point t''
let triangulate points =
let ccw p q r = S.ccw points.(p) points.(q) points.(r) in
let in_circle p q r s =
S.in_circle points.(p) points.(q) points.(r) points.(s)
in
let n = Array.length points in
if n < 2 then invalid_arg "triangulate";
let arcs = Array.init (6 * n - 6) (make_arc n) in
let mate i = 6 * n - 7 - i in
(*i DEBUG
let rec dump d l =
eprintf "%s" (String.make (2*d) ' ');
match !l with
| Terminal a ->
eprintf "T %d\n" (mate a.mate)
| Branch (u, v, l, r) ->
eprintf "N %d %d\n" u v;
dump (d+1) l;
dump (d+1) r
in
i*)
(* initialization:
create a trivial triangulation for the first 2 vertices *)
let u = 0 in
let v = 1 in
let a1 = arcs.(0) in
let a2 = arcs.(1) in
let a3 = arcs.(2) in
let b1 = arcs.(mate 0) in
let b2 = arcs.(mate 1) in
let b3 = arcs.(mate 2) in
let l1 = ref (Terminal a2) in
let l2 = ref (Terminal b3) in
a1.vert <- Point v; a1.next <- a2; a1.inst <- l1;
a2.vert <- Infinity; a2.next <- a3; a2.inst <- l1;
a3.vert <- Point u; a3.next <- a1; a3.inst <- l1;
b1.vert <- Point u; b1.next <- b3; b1.inst <- l2;
b2.vert <- Point v; b2.next <- b1; b2.inst <- l2;
b3.vert <- Infinity; b3.next <- b2; b3.inst <- l2;
let l0 = ref (Branch (u, v, l1, l2)) in
let j = ref 2 in (* last used arc *)
(* then for each new vertex [p] *)
for p = 2 to n - 1 do
(* Step T1 *)
let rec step_T1 l p = match !l with
| Terminal al ->
l, al
| Branch (pl, ql, al, bl) ->
step_T1 (if ccw pl ql p then al else bl) p
in
let l, al = step_T1 l0 p in
(* Step T2 *)
let a = al in
let b = a.next in
let c = b.next in
let q = a.vert in
let r = b.vert in
let s = c.vert in
j := !j + 3;
let aj = arcs.(!j) in
let aj_1 = arcs.(!j - 1) in
let aj_2 = arcs.(!j - 2) in
let bj = arcs.(aj.mate) in
let bj_1 = arcs.(aj_1.mate) in
let bj_2 = arcs.(aj_2.mate) in
let l' = ref (Terminal a) in
let l'' = ref (Terminal aj) in
let l''' = ref (Terminal c) in
aj.vert <- q; aj.next <- b; aj.inst <- l'';
aj_1.vert <- r; aj_1.next <- c; aj_1.inst <- l''';
aj_2.vert <- s; aj_2.next <- a; aj_2.inst <- l';
bj.vert <- Point p; bj.next <- aj_2; bj.inst <- l';
bj_1.vert <- Point p; bj_1.next <- aj; bj_1.inst <- l'';
bj_2.vert <- Point p; bj_2.next <- aj_1; bj_2.inst <- l''';
a.next <- bj; a.inst <- l';
b.next <- bj_1; b.inst <- l'';
c.next <- bj_2; c.inst <- l''';
let r = finite r in
let s = finite s in
(* steps T3 or T4 depending on [q] *)
let r = match q with
| Point q -> (* Step T3 *)
let n = ref (Branch (q, p, l', l'')) in
let n' = ref (Branch (s, p, l''', l')) in
l := Branch (r, p, n, n');
r
| Infinity -> (* Step T4 *)
let n = ref (Branch (s, p, l''', l')) in
l := Branch (r, p, l'', n);
let rec loop m a d s t =
if t <> r && ccw p s t then begin
let n = ref (Terminal d) in
match !m with
| Branch (mu, mv, ml, is_l') ->
assert (is_l' == l');
m := Branch (mu, mv, ml, d.inst);
d.inst := Branch (t, p, n, l');
let m = d.inst in
flip a arcs.(a.mate) d t p n l';
let a = arcs.(a.mate).next in
let d = arcs.(a.mate).next in
let s = t in
let t = finite d.vert in
l' := Terminal a;
loop m a d s t
| Terminal _ ->
assert false
end else begin
(* at exit of while loop *)
let n = ref (Terminal d.next) in
d.inst := Branch (s, p, n, l');
d.inst <- n; d.next.inst <- n; d.next.next.inst <- n;
s
end
in
let d = arcs.(a.mate).next in
loop n a d s (finite d.vert)
in
(* Step T5 *)
let rec loop c =
let d = arcs.(c.mate) in
let e = d.next in
let t = finite d.vert in
let t' = finite c.vert in
let t'' = e.vert in
if t'' <> Infinity && in_circle (finite t'') t' t p then begin
let t'' = finite t'' in
let n = ref (Terminal e) in
let n' = ref (Terminal d) in
c.inst := Branch (t'', p, n, n');
d.inst := Branch (t'', p, n, n');
flip c d e t'' p n n';
loop e
end else if t' <> r then
loop arcs.(c.next.mate).next
else
() (* break *)
in
loop c
done;
{ points = points; arcs = arcs; last_used_arc = !j }
let iter f t =
let points = t.points in
let n = Array.length t.arcs in
for i = 0 to t.last_used_arc do
match t.arcs.(i).vert, t.arcs.(n - 1 - i).vert with
| Point u, Point v -> f points.(u) points.(v)
| _ -> ()
done
let iter_triangles f t =
let n = Array.length t.arcs in
let seen_arc = Array.make n false in
let mate i = n - 1 - i in
let index a = mate a.mate in
for i = 0 to n-1 do
if not seen_arc.(i) then begin
let a1 = t.arcs.(i) in
let a2 = a1.next in
let a3 = a2.next in
seen_arc.(i) <- true;
seen_arc.(index a2) <- true;
seen_arc.(index a3) <- true;
match a1.vert, a2.vert, a3.vert with
| Point i1, Point i2, Point i3 ->
f t.points.(i1) t.points.(i2) t.points.(i3)
| _ ->
()
end
done
let fold f t a =
let points = t.points in
let n = Array.length t.arcs in
let rec loop i a =
if i <= t.last_used_arc then
match t.arcs.(i).vert, t.arcs.(n - 1 - i).vert with
| Point u, Point v -> loop (succ i) (f points.(u) points.(v) a)
| _ -> loop (succ i) a
else
a
in
loop 0 a
end
(** Points with floating point coordinates *)
module FloatPoints = struct
type point = float * float
let ( + ) = ( +. )
let ( - ) = ( -. )
let ( * ) = ( *. )
let det = function
| [| [| a00; a01 |];
[| a10; a11 |] |] ->
a00 * a11 - a01 * a10
| [| [| a00; a01; a02 |];
[| a10; a11; a12 |];
[| a20; a21; a22 |] |] ->
a00*a11*a22 - a00*a12*a21 - a10*a01*a22 +
a10*a02*a21 + a20*a01*a12 - a20*a02*a11
| [| [| a00; a01; a02; a03 |];
[| a10; a11; a12; a13 |];
[| a20; a21; a22; a23 |];
[| a30; a31; a32; a33 |] |] ->
a00*a11*a22*a33 - a00*a11*a23*a32 - a00*a21*a12*a33 +
a00*a21*a13*a32 + a00*a31*a12*a23 - a00*a31*a13*a22 -
a10*a01*a22*a33 + a10*a01*a23*a32 + a10*a21*a02*a33 -
a10*a21*a03*a32 - a10*a31*a02*a23 + a10*a31*a03*a22 +
a20*a01*a12*a33 - a20*a01*a13*a32 - a20*a11*a02*a33 +
a20*a11*a03*a32 + a20*a31*a02*a13 - a20*a31*a03*a12 -
a30*a01*a12*a23 + a30*a01*a13*a22 + a30*a11*a02*a23 -
a30*a11*a03*a22 - a30*a21*a02*a13 + a30*a21*a03*a12
| _ -> assert false
let ccw (xu,yu) (xv,yv) (xw,yw) =
det [| [| xu; yu; 1.0 |];
[| xv; yv; 1.0 |];
[| xw; yw; 1.0 |] |] > 0.0
(*i DEBUG
let ccw (xu,yu) (xv,yv) (xw,yw) =
eprintf "ccw((%.0f,%.0f),(%.0f,%.0f),(%.0f,%.0f)) -> "
xu yu xv yv xw yw;
let r = ccw (xu,yu) (xv,yv) (xw,yw) in
eprintf "%b\n" r; flush stderr;
r
i*)
let in_circle (xt,yt) (xu,yu) (xv,yv) (xw,yw) =
det [| [| xt; yt; (xt * xt + yt * yt); 1.0 |];
[| xu; yu; (xu * xu + yu * yu); 1.0 |];
[| xv; yv; (xv * xv + yv * yv); 1.0 |];
[| xw; yw; (xw * xw + yw * yw); 1.0 |]; |] > 0.0
(*i DEBUG
let in_circle (xt,yt) (xu,yu) (xv,yv) (xw,yw) =
eprintf "in_circle((%.0f,%.0f),(%.0f,%.0f),(%.0f,%.0f),(%.0f,%.0f)) -> "
xt yt xu yu xv yv xw yw;
let r = in_circle (xt,yt) (xu,yu) (xv,yv) (xw,yw) in
eprintf "%b\n" r; flush stderr;
r
i*)
end
module Float = Make(FloatPoints)
(** Points with integer coordinates.
We approximate using module [FloatPoints] but this could be made exact
following Knuth's code in Axioms and Hulls *)
module IntPoints = struct
type point = int * int
let ccw (xu,yu) (xv,yv) (xw,yw) =
FloatPoints.ccw
(float xu, float yu) (float xv, float yv) (float xw, float yw)
let in_circle (xt,yt) (xu,yu) (xv,yv) (xw,yw) =
FloatPoints.in_circle
(float xt, float yt)
(float xu, float yu) (float xv, float yv) (float xw, float yw)
end
module Int = Make(IntPoints)
ocamlgraph-2.0.0/src/classic.ml 0000644 0001750 0000144 00000006244 13735627615 014761 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(* $Id: classic.ml,v 1.9 2004-02-02 08:11:14 filliatr Exp $ *)
module type S = sig
type graph
val divisors : int -> graph
val de_bruijn : int -> graph
val vertex_only : int -> graph
val full : ?self:bool -> int -> graph
end
module Generic(B : Builder.INT) = struct
type graph = B.G.t
let divisors n =
if n < 2 then invalid_arg "divisors";
let v = Array.init (n + 1) (fun i -> B.G.V.create i) in
let rec loop g i =
let sqrt_i = truncate (sqrt (float i)) in
let rec loop_i g d =
if d > sqrt_i then
g
else if i mod d == 0 then
loop_i (B.add_edge (B.add_edge g v.(i / d) v.(i)) v.(d) v.(i)) (d+1)
else
loop_i g (succ d)
in
if i > n then g else loop (loop_i (B.add_vertex g v.(i)) 2) (i+1)
in
loop (B.empty ()) 2
let fold_for i0 i1 f =
let rec loop i v = if i > i1 then v else loop (i + 1) (f v i) in
loop i0
let de_bruijn n =
if n < 1 || n > Sys.word_size - 1 then invalid_arg "de_bruijn";
let v = Array.init (1 lsl n) (fun i -> B.G.V.create i) in
let all_1 = 1 lsl n - 1 in (* 11...1 *)
let g = fold_for 0 all_1 (fun g i -> B.add_vertex g v.(i)) (B.empty ()) in
let rec loop g i =
if i > all_1 then
g
else
let si = (i lsl 1) land all_1 in
let g = B.add_edge g v.(i) v.(si) in
let g = B.add_edge g v.(i) v.(si lor 1) in
loop g (i + 1)
in
loop g 0
let vertex_only n =
fold_for 1 n (fun g i -> B.add_vertex g (B.G.V.create i)) (B.empty ())
let full ?(self=true) n =
let v = Array.init (n + 1) (fun i -> B.G.V.create i) in
fold_for 1 n
(fun g i ->
fold_for 1 n
(fun g j -> if self || i <> j then B.add_edge g v.(i) v.(j) else g)
g)
(fold_for 1 n (fun g i -> B.add_vertex g v.(i)) (B.empty ()))
end
module P (G : Sig.P with type V.label = int) = Generic(Builder.P(G))
module I (G : Sig.I with type V.label = int) = Generic(Builder.I(G))
ocamlgraph-2.0.0/src/chaoticIteration.mli 0000644 0001750 0000144 00000014705 13735627615 017003 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(* Copyright © 2015 Thibault Suzanne
* École Normale Supérieure, Département d'Informatique
* Paris Sciences et Lettres
*)
(** Fixpoint computation with widenings using weak topological
orderings as defined by François Bourdoncle and implemented
in {!WeakTopological}.
{!Fixpoint} is another (simpler) fixpoint computation module, with
general references.
The general idea of fixpoint computation is to iteratively compute
the result of the analysis a vertex from the results of its
predecessors, until stabilisation is achieved on every vertex. The
way to determine, at each step, the next vertex to analyse is
called a {e chaotic iteration strategy}. A good strategy can make
the analysis much faster. To enforce the termination of the
analyse and speed it up when it terminates in too many steps, one
can also use a {e widening}, to ensure that there is no infinite
(nor too big) sequence of intermediary results for a given
vertex. However, it usually results in a loss of precision, which
is why choosing a good widening set (the set of points on which
the widening will be performed) is mandatory.
This module computes a fixpoint over a graph using weak
topological ordering, which can be used to get both the iteration
strategy and the widening set. The module {!WeakTopological} aims
to compute weak topological orderings which are known to be
excellent decompositions w.r.t these two critical points.
@author Thibault Suzanne
@see "Efficient chaotic iteration strategies with widenings",
François Bourdoncle,
Formal Methods in Programming and their Applications,
Springer Berlin Heidelberg, 1993
*)
(** How to determine which vertices are to be considered as widening
points.
- [FromWto] indicates to use as widening points the heads of the
weak topological ordering given as a parameter of the analysis
function. This will always be a safe choice, and in most cases
it will also be a good one with respect to the precision of the
analysis.
- [Predicate f] indicates to use [f] as the characteristic
function of the widening set. [Predicate (fun _ -> false)] can
be used if a widening is not needed. This variant can be used
when there is a special knowledge of the graph to achieve
a better precision of the analysis. For instance, if the graph
happens to be the flow graph of a program, the predicate should
be true for control structures heads. In any case, a condition
for a safe widening predicate is that every cycle of the graph
should go through at least one widening point. Otherwise, the
analysis may not terminate. Note that even with a safe
predicate, ensuring the termination does still require a correct
widening definition.
*)
type 'a widening_set =
| FromWto
| Predicate of ('a -> bool)
(** Minimal graph signature for the algorithm.
Sub-signature of [Traverse.G]. *)
module type G = sig
type t
module V : Sig.COMPARABLE
module E : sig
type t
val src : t -> V.t
end
val fold_pred_e : (E.t -> 'a -> 'a) -> t -> V.t -> 'a -> 'a
end
(** Parameters of the analysis. *)
module type Data = sig
type t
(** Information stored at each vertex. *)
type edge
(** Edge of the graph. *)
val join : t -> t -> t
(** Operation to join data when several paths meet. *)
val equal : t -> t -> bool
(** Equality test for data. *)
val analyze : edge -> t -> t
(** How to analyze one edge: given an edge and the data stored at
its origin, it must compute the resulting data to be stored at
its destination. *)
val widening : t -> t -> t
(** The widening operator. [fun _ x -> x] is correct and is
equivalent to not doing widening. Note that to enforce
termination, the following property should hold: for all
sequence [x_0, x_1, ...] of data, the sequence defined by [y_0 =
x_0; y_{i+1} = widening y_i x_i] stabilizes in finite time. *)
end
module Make
(G : G)
(D : Data with type edge = G.E.t) :
sig
module M : Map.S with type key = G.V.t and type 'a t = 'a Map.Make(G.V).t
(** Map used to store the result of the analysis *)
val recurse :
G.t ->
G.V.t WeakTopological.t ->
(G.V.t -> D.t) ->
G.V.t widening_set ->
int ->
D.t M.t
(** [recurse g wto init widening_set widening_delay] computes the
fixpoint of the analysis of a graph. This function uses the
recursive iteration strategy: it recursively stabilizes the
subcomponents of every component every time the component is
stabilized (cf. Bourdoncle's paper).
@param g The graph to analyse.
@param wto A weak topological ordering of the vertices of [g].
@param widening_set On which points to do the widening.
@param widening_delay How many computations steps will be done
before using widening to speed up the stabilisation. This
counter is reset when entering each component, and is shared
between all outermost vertices of this component. A negative
value means [0].
@param init How to compute the initial analysis data.
@return A map from vertices of [g] to their analysis result.
*)
end
ocamlgraph-2.0.0/src/builder.mli 0000644 0001750 0000144 00000004304 13735627615 015132 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(** Graph builders in order to persistent/imperative graphs sharing a same
signature. *)
(** {2 Common interface for graph builders}.
Note: the following functions always return graphs but this is meaningless
for imperative implementations (the graph is modified in-place).
This is just to provide a common interface. *)
module type S = sig
module G : Sig.G
val empty : unit -> G.t
val copy : G.t -> G.t
val add_vertex : G.t -> G.V.t -> G.t
val add_edge : G.t -> G.V.t -> G.V.t -> G.t
val add_edge_e : G.t -> G.E.t -> G.t
val remove_vertex : G.t -> G.V.t -> G.t
val remove_edge : G.t -> G.V.t -> G.V.t -> G.t
val remove_edge_e : G.t -> G.E.t -> G.t
end
module type INT = S with type G.V.label = int
(** {1 Builders for the various graph implementations} *)
module P(G : Sig.P) : S with module G = G
(** Persistent Graphs Builders. *)
module I(G : Sig.I) : S with module G = G
(** Imperative Graphs Builders. *)
(*
Local Variables:
compile-command: "make -C .."
End:
*)
ocamlgraph-2.0.0/src/topological.mli 0000644 0001750 0000144 00000007022 13735627615 016020 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(** Topological order.
This functor provides functions which allow iterating over a graph in
topological order. Cycles in graphs are allowed. Specification is the
following:
if vertex [x] is visited before vertex [y]
then either there is a path from [x] to [y],
or there is no path from [y] to [x].
In the particular case of a DAG, this simplifies to:
if there is an edge from [x] to [y], then [x] is visited before [y]. *)
(** Minimal graph signature to provide.
Sub-signature of {!Sig.G}. *)
module type G = sig
type t
module V : Sig.COMPARABLE
val iter_vertex : (V.t -> unit) -> t -> unit
val iter_succ : (V.t -> unit) -> t -> V.t -> unit
end
(** Functor providing topological iterators over a graph. *)
module Make(G: G) : sig
val fold : (G.V.t -> 'a -> 'a) -> G.t -> 'a -> 'a
(** [fold action g seed] allows iterating over the graph [g]
in topological order. [action node accu] is called repeatedly,
where [node] is the node being visited, and [accu] is the result of
the [action]'s previous invocation, if any, and [seed] otherwise.
If [g] contains cycles, the order is unspecified inside the cycles and
every node in the cycles will be presented exactly once.
Not tail-recursive. Complexity: O(V+E) *)
val iter : (G.V.t -> unit) -> G.t -> unit
(** [iter action] calls [action node] repeatedly. Nodes are (again)
presented to [action] in topological order.
The order is the same as for [fold]. *)
end
(** Provide the same features than {!Make}, except that the resulting
topological ordering is stable according to vertices comparison: if two
vertices [v1] and [v2] are topologically equal, [v1] is presented first to
the iterator if and only if [G.V.compare v1 v2 <= 0]. In particular, the
resulting order is not dependent on the provided hash function. This
property is not guaranteed by the functor {!Make}. The counterpart is a less
efficient implementation: worst time complexity is O(E*V*ln(V)) instead of
O(E*V) (with E = number of edges and V = number of vertices. *)
module Make_stable(G: sig include G val in_degree : t -> V.t -> int end): sig
val fold : (G.V.t -> 'a -> 'a) -> G.t -> 'a -> 'a
val iter : (G.V.t -> unit) -> G.t -> unit
end
(*
Local Variables:
compile-command: "make -C .."
End:
*)
ocamlgraph-2.0.0/src/strat.ml 0000644 0001750 0000144 00000014065 13735627615 014475 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(* Signature for graphs *)
module type G = sig
type t
module V : Sig.ORDERED_TYPE
type vertex = V.t
val mem_vertex : t -> vertex -> bool
val succ : t -> vertex -> vertex list
val fold_vertex : (vertex -> 'a -> 'a) -> t -> 'a -> 'a
val fold_succ : (vertex -> 'a -> 'a) -> t -> vertex -> 'a -> 'a
end
(* Signature for graph add-ons: an initial vertex, final vertices
and membership of vertices to either true or false,
i.e. first or second player *)
module type PLAYER = sig
type t
type vertex
val get_initial : t -> vertex
val is_final : t -> vertex -> bool
val turn : t -> vertex -> bool
end
(* Signature for strategies : for a given state, the strategy tells
which state to go to *)
module type STRAT = sig
type t
type vertex
val empty : t
val add : t -> vertex -> vertex -> t
val next : t -> vertex -> vertex
(* Raises Invalid_argument if vertex's image is not defined *)
end
(* Implements strategy algorithms on graphs *)
module Algo (G : G) (P : PLAYER with type vertex = G.vertex)
(S : STRAT with type vertex = G.vertex) :
sig
(* coherent_player g p returns true iff
the completion p is coherent w.r.t.
the graph g *)
val coherent_player : G.t -> P.t -> bool
(* coherent_strat g s returns true iff
the strategy s is coherent w.r.t.
the graph g *)
val coherent_strat : G.t -> S.t -> bool
(* game g p a b returns true iff a wins in g
given the completion p (i.e. the game
goes through a final state). *)
val game : G.t -> P.t -> S.t -> S.t -> bool
(* strategy g p s returns true iff s wins in g
given the completion p, whatever strategy
plays the other player. *)
val strategy : G.t -> P.t -> S.t -> bool
(* strategyA g p returns true iff there
exists a winning stragegy for the true
player. In this case, the winning
strategy is provided. *)
val strategyA : G.t -> P.t -> (bool * S.t)
end = struct
module SetV = Set.Make (G.V)
let rec eq l1 l2 = match l1, l2 with
[], [] -> true
| e1 :: l1', e2 :: l2' ->
(G.V.compare e1 e2 = 0) && (eq l1' l2')
| _ -> false
let rec eq_mem i l1 l2 = match l1, l2 with
[], [] -> (true, false)
| e1 :: l1', e2 :: l2' ->
if G.V.compare e1 e2 = 0 then
if G.V.compare e1 i = 0 then (eq l1' l2', true)
else eq_mem i l1' l2'
else (false, false)
| _ -> (false, false)
let puit g v = match G.succ g v with
[] -> true
| _ -> false
let get_finals g p =
let f a l =
if P.is_final p a then a :: l
else l
in G.fold_vertex f g []
let coherent_player g p =
G.mem_vertex g (P.get_initial p)
let coherent_strat g s =
let f v b =
try
let v' = S.next s v in
b && (G.mem_vertex g v')
with Invalid_argument _ -> true
in
G.fold_vertex f g true
let game _ p a b =
let rec game_aux l pi =
let continue x =
try
game_aux (SetV.add pi l) (S.next x pi)
with Invalid_argument _ -> false
in
(P.is_final p pi) ||
(if SetV.mem pi l then false
else
if P.turn p pi then continue a
else continue b)
in
game_aux SetV.empty (P.get_initial p)
let attract1 g p s l =
let f v l1 =
if not (List.mem v l1) then
if P.turn p v then
try
if List.mem (S.next s v) l1 then v :: l1
else l1
with Invalid_argument _ -> l1
else
if puit g v then l1
else
if G.fold_succ (fun v' b -> b && (List.mem v' l1)) g v true
then v :: l1
else l1
else l1
in
G.fold_vertex f g l
let strategy g p s =
let rec strategy_aux l1 l2 =
let (b1, b2) = eq_mem (P.get_initial p) l1 l2 in
if b1 then b2
else strategy_aux (attract1 g p s l1) l1
in
let finaux = get_finals g p in
strategy_aux (attract1 g p s finaux) finaux
let attract g p (l, l') =
let f v (l1, l1') =
if not (List.mem v l1) then
if P.turn p v then
let f' v' l2 =
(match l2 with
[] ->
if List.mem v' l1 then [v']
else []
| _ -> l2) in
(match G.fold_succ f' g v [] with
[] -> (l1, l1')
| v' :: _ -> (v :: l1, S.add l1' v v' ))
else
if puit g v then (l1, l1')
else
if G.fold_succ (fun v' b -> b && (List.mem v' l1)) g v true
then (v :: l1, l1')
else (l1, l1')
else (l1, l1')
in
G.fold_vertex f g (l, l')
let strategyA g p =
let rec strategyA_aux l1 l2 f =
let (b1, b2) = eq_mem (P.get_initial p) l1 l2 in
if b1 then (b2, f)
else
let (new_l1, new_f) = attract g p (l1, f) in
strategyA_aux new_l1 l1 new_f
in
let finaux = get_finals g p in
let (l, r) = attract g p (finaux, S.empty) in
strategyA_aux l finaux r;;
end
ocamlgraph-2.0.0/src/chaoticIteration.ml 0000644 0001750 0000144 00000010766 13735627615 016635 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(* Copyright © 2015 Thibault Suzanne
* École Normale Supérieure, Département d'Informatique
* Paris Sciences et Lettres
*)
(* Original algorithm by François Bourdoncle. See :
* "Efficient chaotic iteration strategies with widenings",
* Formal Methods in Programming and their Applications,
* Springer Berlin Heidelberg, 1993.
*)
let ( |> ) x f = f x
type 'a widening_set =
| FromWto
| Predicate of ('a -> bool)
module type G = sig
type t
module V : Sig.COMPARABLE
module E : sig
type t
val src : t -> V.t
end
val fold_pred_e : (E.t -> 'a -> 'a) -> t -> V.t -> 'a -> 'a
end
module type Data = sig
type t
type edge
val join : t -> t -> t
val equal : t -> t -> bool
val analyze : edge -> t -> t
val widening : t -> t -> t
end
module Make
(G : G)
(D : Data with type edge = G.E.t)
=
struct
module M = Map.Make (G.V)
let recurse g wto init widening_set widening_delay =
(* The following two functions are predicates used to know whether
to compute a widening when analysing a vertex which is not
(resp. is) the head of a WTO component. They will be called
only if the specified number of steps before widening has been
done. *)
let do_nonhead_widen v = match widening_set with
| FromWto -> false
| Predicate f -> f v
in
let do_head_widen v = match widening_set with
| FromWto -> true
| Predicate f -> f v
in
let find vertex data =
try M.find vertex data
with Not_found -> init vertex
in
let analyze_vertex widening_steps do_widen v data =
(* Computes the result of the analysis for one vertex *)
let result = G.fold_pred_e
(fun edge acc ->
let src = G.E.src edge in
let data_src = find src data in
let data_dst = D.analyze edge data_src in
D.join data_dst acc)
g v (init v) in
if widening_steps <= 0 && do_widen v
then D.widening (find v data) result
else result
in
let rec analyze_elements widening_steps comp data =
(* Computes the result of one iteration of the analysis of the
elements of a component. *)
WeakTopological.fold_left (analyze_element widening_steps) data comp
and stabilize can_stop widening_steps head comps data =
(* Iterates the analysis of a component until
stabilisation. [can_stop] is [false] if no iteration has been
made so far, since at least one is needed before ending with
stabilisation. *)
let old_data_head =
find head data in
let new_data_head =
analyze_vertex widening_steps do_head_widen head data in
if can_stop && D.equal old_data_head new_data_head
then data
else
data
|> M.add head new_data_head
|> analyze_elements widening_steps comps
|> stabilize true (widening_steps - 1) head comps
and analyze_element widening_steps data = function
(* Computes the result of the analysis of one element *)
| WeakTopological.Vertex v ->
M.add v (analyze_vertex widening_steps do_nonhead_widen v data) data
| WeakTopological.Component (head, comps) ->
stabilize false widening_delay head comps data
in
analyze_elements widening_delay wto M.empty
end
ocamlgraph-2.0.0/src/pack.mli 0000644 0001750 0000144 00000003277 13735627615 014432 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(* $Id: pack.mli,v 1.1 2004-02-04 11:52:02 filliatr Exp $ *)
(** {b Immediate access to the library}: provides implementation of imperative
graphs labeled with integer as well as algorithms on such graphs.
So if you bother functors, you can use this module. *)
(** Directed imperative graphs with edges and vertices labeled with integer. *)
module Digraph : Sig_pack.S
(** Undirected imperative graphs with edges and vertices labeled with
integer. *)
module Graph : Sig_pack.S
ocamlgraph-2.0.0/src/lib/ 0000755 0001750 0000144 00000000000 13735627615 013546 5 ustar rt users ocamlgraph-2.0.0/src/lib/heap.ml 0000644 0001750 0000144 00000007025 13735627615 015021 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
module type Ordered = sig
type t
val compare : t -> t -> int
end
exception EmptyHeap
module Imperative(X : Ordered) = struct
(* The heap is encoded in the array [data], where elements are stored
from [0] to [size - 1]. From an element stored at [i], the left
(resp. right) subtree, if any, is rooted at [2*i+1] (resp. [2*i+2]). *)
type t = { mutable size : int; mutable data : X.t array }
(* When [create n] is called, we cannot allocate the array, since there is
no known value of type [X.t]; we'll wait for the first addition to
do it, and we remember this situation with a negative size. *)
let create n =
if n <= 0 then invalid_arg "create";
{ size = -n; data = [||] }
let is_empty h = h.size <= 0
(* [resize] doubles the size of [data] *)
let resize h =
let n = h.size in
assert (n > 0);
let n' = 2 * n in
let d = h.data in
let d' = Array.make n' d.(0) in
Array.blit d 0 d' 0 n;
h.data <- d'
let add h x =
(* first addition: we allocate the array *)
if h.size < 0 then begin
h.data <- Array.make (- h.size) x; h.size <- 0
end;
let n = h.size in
(* resizing if needed *)
if n == Array.length h.data then resize h;
let d = h.data in
(* moving [x] up in the heap *)
let rec moveup i =
let fi = (i - 1) / 2 in
if i > 0 && X.compare d.(fi) x < 0 then begin
d.(i) <- d.(fi);
moveup fi
end else
d.(i) <- x
in
moveup n;
h.size <- n + 1
let maximum h =
if h.size <= 0 then raise EmptyHeap;
h.data.(0)
let remove h =
if h.size <= 0 then raise EmptyHeap;
let n = h.size - 1 in
h.size <- n;
let d = h.data in
let x = d.(n) in
(* moving [x] down in the heap *)
let rec movedown i =
let j = 2 * i + 1 in
if j < n then
let j =
let j' = j + 1 in
if j' < n && X.compare d.(j') d.(j) > 0 then j' else j
in
if X.compare d.(j) x > 0 then begin
d.(i) <- d.(j);
movedown j
end else
d.(i) <- x
else
d.(i) <- x
in
movedown 0
let pop_maximum h = let m = maximum h in remove h; m
let iter f h =
let d = h.data in
for i = 0 to h.size - 1 do f d.(i) done
let fold f h x0 =
let n = h.size in
let d = h.data in
let rec foldrec x i =
if i >= n then x else foldrec (f d.(i) x) (succ i)
in
foldrec x0 0
end
ocamlgraph-2.0.0/src/lib/unionfind.ml 0000644 0001750 0000144 00000006062 13735627615 016075 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(* $Id$ *)
module type HashedOrderedType = sig
type t
val equal : t -> t -> bool
val hash : t -> int
val compare : t -> t -> int
end
module type S = sig
type elt
type t
val init : elt list -> t
val find : elt -> t -> elt
val union : elt -> elt -> t -> unit
end
module Make(X:HashedOrderedType) = struct
type elt = X.t
module H = Hashtbl.Make(X)
type cell = {
mutable c : int;
data : elt;
mutable father : cell
}
type t = cell H.t (* a forest *)
let init l =
let h = H.create 997 in
List.iter
(fun x ->
let rec cell = { c = 0; data = x; father = cell } in
H.add h x cell)
l;
h
let rec find_aux cell =
if cell.father == cell then
cell
else
let r = find_aux cell.father in
cell.father <- r;
r
let find x h = (find_aux (H.find h x)).data
let union x y h =
let rx = find_aux (H.find h x) in
let ry = find_aux (H.find h y) in
if rx != ry then begin
if rx.c > ry.c then
ry.father <- rx
else if rx.c < ry.c then
rx.father <- ry
else begin
rx.c <- rx.c + 1;
ry.father <- rx
end
end
end
(*** test ***)
(***
module M = Make (struct
type t = int let
hash = Hashtbl.hash
let compare = compare
let equal = (=)
end)
open Printf
let saisir s =
printf "%s = " s; flush stdout;
let x = read_int () in
x
let h = M.init [0;1;2;3;4;5;6;7;8;9]
let () = if not !Sys.interactive then
while true do
printf "1) find\n2) union\n";
match read_int () with
1 -> begin
let x = saisir "x" in
printf "%d\n" (M.find x h)
end
| 2 -> begin
let x, y = saisir "x", saisir "y" in
M.union x y h
end
| _ -> ()
done
***)
ocamlgraph-2.0.0/src/lib/bitv.ml 0000644 0001750 0000144 00000044470 13735627615 015055 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(*i $Id: bitv.ml,v 1.18 2008/04/01 09:59:03 filliatr Exp $ i*)
(*s Bit vectors. The interface and part of the code are borrowed from the
[Array] module of the ocaml standard library (but things are simplified
here since we can always initialize a bit vector). This module also
provides bitwise operations. *)
(*s We represent a bit vector by a vector of integers (field [bits]),
and we keep the information of the size of the bit vector since it
can not be found out with the size of the array (field [length]). *)
type t = {
length : int;
bits : int array }
let length v = v.length
(*s Each element of the array is an integer containing [bpi] bits, where
[bpi] is determined according to the machine word size. Since we do not
use the sign bit, [bpi] is 30 on a 32-bits machine and 62 on a 64-bits
machines. We maintain the following invariant:
{\em The unused bits of the last integer are always
zeros.} This is ensured by [create] and maintained in other functions
using [normalize]. [bit_j], [bit_not_j], [low_mask] and [up_mask]
are arrays used to extract and mask bits in a single integer. *)
let bpi = Sys.word_size - 2
let max_length = Sys.max_array_length * bpi
let bit_j = Array.init bpi (fun j -> 1 lsl j)
let bit_not_j = Array.init bpi (fun j -> max_int - bit_j.(j))
let low_mask = Array.make (succ bpi) 0
let _ =
for i = 1 to bpi do low_mask.(i) <- low_mask.(i-1) lor bit_j.(pred i) done
let keep_lowest_bits a j = a land low_mask.(j)
let high_mask = Array.init (succ bpi) (fun j -> low_mask.(j) lsl (bpi-j))
let keep_highest_bits a j = a land high_mask.(j)
(*s Creating and normalizing a bit vector is easy: it is just a matter of
taking care of the invariant. Copy is immediate. *)
let create n b =
let initv = if b then max_int else 0 in
let r = n mod bpi in
if r = 0 then
{ length = n; bits = Array.make (n / bpi) initv }
else begin
let s = n / bpi in
let b = Array.make (succ s) initv in
b.(s) <- b.(s) land low_mask.(r);
{ length = n; bits = b }
end
let normalize v =
let r = v.length mod bpi in
if r > 0 then
let b = v.bits in
let s = Array.length b in
b.(s-1) <- b.(s-1) land low_mask.(r)
let copy v = { length = v.length; bits = Array.copy v.bits }
(*s Access and assignment. The [n]th bit of a bit vector is the [j]th
bit of the [i]th integer, where [i = n / bpi] and [j = n mod
bpi]. Both [i] and [j] and computed by the function [pos].
Accessing a bit is testing whether the result of the corresponding
mask operation is non-zero, and assigning it is done with a
bitwiwe operation: an {\em or} with [bit_j] to set it, and an {\em
and} with [bit_not_j] to unset it. *)
let pos n =
let i = n / bpi and j = n mod bpi in
if j < 0 then (i - 1, j + bpi) else (i,j)
let unsafe_get v n =
let (i,j) = pos n in
((Array.unsafe_get v.bits i) land (Array.unsafe_get bit_j j)) > 0
let unsafe_set v n b =
let (i,j) = pos n in
if b then
Array.unsafe_set v.bits i
((Array.unsafe_get v.bits i) lor (Array.unsafe_get bit_j j))
else
Array.unsafe_set v.bits i
((Array.unsafe_get v.bits i) land (Array.unsafe_get bit_not_j j))
(*s The corresponding safe operations test the validiy of the access. *)
let get v n =
if n < 0 || n >= v.length then invalid_arg "Bitv.get";
let (i,j) = pos n in
((Array.unsafe_get v.bits i) land (Array.unsafe_get bit_j j)) > 0
let set v n b =
if n < 0 || n >= v.length then invalid_arg "Bitv.set";
let (i,j) = pos n in
if b then
Array.unsafe_set v.bits i
((Array.unsafe_get v.bits i) lor (Array.unsafe_get bit_j j))
else
Array.unsafe_set v.bits i
((Array.unsafe_get v.bits i) land (Array.unsafe_get bit_not_j j))
(*s [init] is implemented naively using [unsafe_set]. *)
let init n f =
let v = create n false in
for i = 0 to pred n do
unsafe_set v i (f i)
done;
v
(*s Handling bits by packets is the key for efficiency of functions
[append], [concat], [sub] and [blit].
We start by a very general function [blit_bits a i m v n] which blits
the bits [i] to [i+m-1] of a native integer [a]
onto the bit vector [v] at index [n]. It assumes that [i..i+m-1] and
[n..n+m-1] are respectively valid subparts of [a] and [v].
It is optimized when the bits fit the lowest boundary of an integer
(case [j == 0]). *)
let blit_bits a i m v n =
let (i',j) = pos n in
if j == 0 then
Array.unsafe_set v i'
((keep_lowest_bits (a lsr i) m) lor
(keep_highest_bits (Array.unsafe_get v i') (bpi - m)))
else
let d = m + j - bpi in
if d > 0 then begin
Array.unsafe_set v i'
(((keep_lowest_bits (a lsr i) (bpi - j)) lsl j) lor
(keep_lowest_bits (Array.unsafe_get v i') j));
Array.unsafe_set v (succ i')
((keep_lowest_bits (a lsr (i + bpi - j)) d) lor
(keep_highest_bits (Array.unsafe_get v (succ i')) (bpi - d)))
end else
Array.unsafe_set v i'
(((keep_lowest_bits (a lsr i) m) lsl j) lor
((Array.unsafe_get v i') land (low_mask.(j) lor high_mask.(-d))))
(*s [blit_int] implements [blit_bits] in the particular case when
[i=0] and [m=bpi] i.e. when we blit all the bits of [a]. *)
let blit_int a v n =
let (i,j) = pos n in
if j == 0 then
Array.unsafe_set v i a
else begin
Array.unsafe_set v i
( (keep_lowest_bits (Array.unsafe_get v i) j) lor
((keep_lowest_bits a (bpi - j)) lsl j));
Array.unsafe_set v (succ i)
((keep_highest_bits (Array.unsafe_get v (succ i)) (bpi - j)) lor
(a lsr (bpi - j)))
end
(*s When blitting a subpart of a bit vector into another bit vector, there
are two possible cases: (1) all the bits are contained in a single integer
of the first bit vector, and a single call to [blit_bits] is the
only thing to do, or (2) the source bits overlap on several integers of
the source array, and then we do a loop of [blit_int], with two calls
to [blit_bits] for the two bounds. *)
let unsafe_blit v1 ofs1 v2 ofs2 len =
if len > 0 then
let (bi,bj) = pos ofs1 in
let (ei,ej) = pos (ofs1 + len - 1) in
if bi == ei then
blit_bits (Array.unsafe_get v1 bi) bj len v2 ofs2
else begin
blit_bits (Array.unsafe_get v1 bi) bj (bpi - bj) v2 ofs2;
let n = ref (ofs2 + bpi - bj) in
for i = succ bi to pred ei do
blit_int (Array.unsafe_get v1 i) v2 !n;
n := !n + bpi
done;
blit_bits (Array.unsafe_get v1 ei) 0 (succ ej) v2 !n
end
let blit v1 ofs1 v2 ofs2 len =
if len < 0 || ofs1 < 0 || ofs1 + len > v1.length
|| ofs2 < 0 || ofs2 + len > v2.length
then invalid_arg "Bitv.blit";
unsafe_blit v1.bits ofs1 v2.bits ofs2 len
(*s Extracting the subvector [ofs..ofs+len-1] of [v] is just creating a
new vector of length [len] and blitting the subvector of [v] inside. *)
let sub v ofs len =
if ofs < 0 || len < 0 || ofs + len > v.length then invalid_arg "Bitv.sub";
let r = create len false in
unsafe_blit v.bits ofs r.bits 0 len;
r
(*s The concatenation of two bit vectors [v1] and [v2] is obtained by
creating a vector for the result and blitting inside the two vectors.
[v1] is copied directly. *)
let append v1 v2 =
let l1 = v1.length
and l2 = v2.length in
let r = create (l1 + l2) false in
let b1 = v1.bits in
let b2 = v2.bits in
let b = r.bits in
for i = 0 to Array.length b1 - 1 do
Array.unsafe_set b i (Array.unsafe_get b1 i)
done;
unsafe_blit b2 0 b l1 l2;
r
(*s The concatenation of a list of bit vectors is obtained by iterating
[unsafe_blit]. *)
let concat vl =
let size = List.fold_left (fun sz v -> sz + v.length) 0 vl in
let res = create size false in
let b = res.bits in
let pos = ref 0 in
List.iter
(fun v ->
let n = v.length in
unsafe_blit v.bits 0 b !pos n;
pos := !pos + n)
vl;
res
(*s Filling is a particular case of blitting with a source made of all
ones or all zeros. Thus we instanciate [unsafe_blit], with 0 and
[max_int]. *)
let blit_zeros v ofs len =
if len > 0 then
let (bi,bj) = pos ofs in
let (ei,ej) = pos (ofs + len - 1) in
if bi == ei then
blit_bits 0 bj len v ofs
else begin
blit_bits 0 bj (bpi - bj) v ofs;
let n = ref (ofs + bpi - bj) in
for _i = succ bi to pred ei do
blit_int 0 v !n;
n := !n + bpi
done;
blit_bits 0 0 (succ ej) v !n
end
let blit_ones v ofs len =
if len > 0 then
let (bi,bj) = pos ofs in
let (ei,ej) = pos (ofs + len - 1) in
if bi == ei then
blit_bits max_int bj len v ofs
else begin
blit_bits max_int bj (bpi - bj) v ofs;
let n = ref (ofs + bpi - bj) in
for _i = succ bi to pred ei do
blit_int max_int v !n;
n := !n + bpi
done;
blit_bits max_int 0 (succ ej) v !n
end
let fill v ofs len b =
if ofs < 0 || len < 0 || ofs + len > v.length then invalid_arg "Bitv.fill";
if b then blit_ones v.bits ofs len else blit_zeros v.bits ofs len
(*s All the iterators are implemented as for traditional arrays, using
[unsafe_get]. For [iter] and [map], we do not precompute [(f
true)] and [(f false)] since [f] is likely to have
side-effects. *)
let iter f v =
for i = 0 to v.length - 1 do f (unsafe_get v i) done
let map f v =
let l = v.length in
let r = create l false in
for i = 0 to l - 1 do
unsafe_set r i (f (unsafe_get v i))
done;
r
let iteri f v =
for i = 0 to v.length - 1 do f i (unsafe_get v i) done
let mapi f v =
let l = v.length in
let r = create l false in
for i = 0 to l - 1 do
unsafe_set r i (f i (unsafe_get v i))
done;
r
let fold_left f x v =
let r = ref x in
for i = 0 to v.length - 1 do
r := f !r (unsafe_get v i)
done;
!r
let fold_right f v x =
let r = ref x in
for i = v.length - 1 downto 0 do
r := f (unsafe_get v i) !r
done;
!r
let foldi_left f x v =
let r = ref x in
for i = 0 to v.length - 1 do
r := f !r i (unsafe_get v i)
done;
!r
let foldi_right f v x =
let r = ref x in
for i = v.length - 1 downto 0 do
r := f i (unsafe_get v i) !r
done;
!r
(*s Bitwise operations. It is straigthforward, since bitwise operations
can be realized by the corresponding bitwise operations over integers.
However, one has to take care of normalizing the result of [bwnot]
which introduces ones in highest significant positions. *)
let bw_and v1 v2 =
let l = v1.length in
if l <> v2.length then invalid_arg "Bitv.bw_and";
let b1 = v1.bits
and b2 = v2.bits in
let n = Array.length b1 in
let a = Array.make n 0 in
for i = 0 to n - 1 do
a.(i) <- b1.(i) land b2.(i)
done;
{ length = l; bits = a }
let bw_or v1 v2 =
let l = v1.length in
if l <> v2.length then invalid_arg "Bitv.bw_or";
let b1 = v1.bits
and b2 = v2.bits in
let n = Array.length b1 in
let a = Array.make n 0 in
for i = 0 to n - 1 do
a.(i) <- b1.(i) lor b2.(i)
done;
{ length = l; bits = a }
let bw_xor v1 v2 =
let l = v1.length in
if l <> v2.length then invalid_arg "Bitv.bw_xor";
let b1 = v1.bits
and b2 = v2.bits in
let n = Array.length b1 in
let a = Array.make n 0 in
for i = 0 to n - 1 do
a.(i) <- b1.(i) lxor b2.(i)
done;
{ length = l; bits = a }
let bw_not v =
let b = v.bits in
let n = Array.length b in
let a = Array.make n 0 in
for i = 0 to n - 1 do
a.(i) <- max_int land (lnot b.(i))
done;
let r = { length = v.length; bits = a } in
normalize r;
r
(*s Shift operations. It is easy to reuse [unsafe_blit], although it is
probably slightly less efficient than a ad-hoc piece of code. *)
let rec shiftl v d =
if d == 0 then
copy v
else if d < 0 then
shiftr v (-d)
else begin
let n = v.length in
let r = create n false in
if d < n then unsafe_blit v.bits 0 r.bits d (n - d);
r
end
and shiftr v d =
if d == 0 then
copy v
else if d < 0 then
shiftl v (-d)
else begin
let n = v.length in
let r = create n false in
if d < n then unsafe_blit v.bits d r.bits 0 (n - d);
r
end
(*s Testing for all zeros and all ones. *)
let all_zeros v =
let b = v.bits in
let n = Array.length b in
let rec test i =
(i == n) || ((Array.unsafe_get b i == 0) && test (succ i))
in
test 0
let all_ones v =
let b = v.bits in
let n = Array.length b in
let rec test i =
if i == n - 1 then
let m = v.length mod bpi in
(Array.unsafe_get b i) == (if m == 0 then max_int else low_mask.(m))
else
((Array.unsafe_get b i) == max_int) && test (succ i)
in
test 0
(*s Conversions to and from strings. *)
let to_string v =
let n = v.length in
let s = Buffer.create n in
for i = 0 to n - 1 do
Buffer.add_char s (if unsafe_get v i then '1' else '0')
done;
Buffer.contents s
let print fmt v = Format.pp_print_string fmt (to_string v)
let of_string s =
let n = String.length s in
let v = create n false in
for i = 0 to n - 1 do
let c = String.unsafe_get s i in
if c = '1' then
unsafe_set v i true
else
if c <> '0' then invalid_arg "Bitv.of_string"
done;
v
(*s Iteration on all bit vectors of length [n] using a Gray code. *)
let first_set v n =
let rec lookup i =
if i = n then raise Not_found ;
if unsafe_get v i then i else lookup (i + 1)
in
lookup 0
let gray_iter f n =
let bv = create n false in
let rec iter () =
f bv;
unsafe_set bv 0 (not (unsafe_get bv 0));
f bv;
let pos = succ (first_set bv n) in
if pos < n then begin
unsafe_set bv pos (not (unsafe_get bv pos));
iter ()
end
in
if n > 0 then iter ()
(*s Coercions to/from lists of integers *)
let of_list l =
let n = List.fold_left max 0 l in
let b = create (succ n) false in
let add_element i =
(* negative numbers are invalid *)
if i < 0 then invalid_arg "Bitv.of_list";
unsafe_set b i true
in
List.iter add_element l;
b
let of_list_with_length l len =
let b = create len false in
let add_element i =
if i < 0 || i >= len then invalid_arg "Bitv.of_list_with_length";
unsafe_set b i true
in
List.iter add_element l;
b
let to_list b =
let n = length b in
let rec make i acc =
if i < 0 then acc
else make (pred i) (if unsafe_get b i then i :: acc else acc)
in
make (pred n) []
(*s To/from integers. *)
(* [int] *)
let of_int_us i =
{ length = bpi; bits = [| i land max_int |] }
let to_int_us v =
if v.length < bpi then invalid_arg "Bitv.to_int_us";
v.bits.(0)
let of_int_s i =
{ length = succ bpi; bits = [| i land max_int; (i lsr bpi) land 1 |] }
let to_int_s v =
if v.length < succ bpi then invalid_arg "Bitv.to_int_s";
v.bits.(0) lor (v.bits.(1) lsl bpi)
(* [Int32] *)
let of_int32_us i = match Sys.word_size with
| 32 -> { length = 31;
bits = [| (Int32.to_int i) land max_int;
let hi = Int32.shift_right_logical i 30 in
(Int32.to_int hi) land 1 |] }
| 64 -> { length = 31; bits = [| (Int32.to_int i) land 0x7fffffff |] }
| _ -> assert false
let to_int32_us v =
if v.length < 31 then invalid_arg "Bitv.to_int32_us";
match Sys.word_size with
| 32 ->
Int32.logor (Int32.of_int v.bits.(0))
(Int32.shift_left (Int32.of_int (v.bits.(1) land 1)) 30)
| 64 ->
Int32.of_int (v.bits.(0) land 0x7fffffff)
| _ -> assert false
(* this is 0xffffffff (ocaml >= 3.08 checks for literal overflow) *)
let ffffffff = (0xffff lsl 16) lor 0xffff
let of_int32_s i = match Sys.word_size with
| 32 -> { length = 32;
bits = [| (Int32.to_int i) land max_int;
let hi = Int32.shift_right_logical i 30 in
(Int32.to_int hi) land 3 |] }
| 64 -> { length = 32; bits = [| (Int32.to_int i) land ffffffff |] }
| _ -> assert false
let to_int32_s v =
if v.length < 32 then invalid_arg "Bitv.to_int32_s";
match Sys.word_size with
| 32 ->
Int32.logor (Int32.of_int v.bits.(0))
(Int32.shift_left (Int32.of_int (v.bits.(1) land 3)) 30)
| 64 ->
Int32.of_int (v.bits.(0) land ffffffff)
| _ -> assert false
(* [Int64] *)
let of_int64_us i = match Sys.word_size with
| 32 -> { length = 63;
bits = [| (Int64.to_int i) land max_int;
(let mi = Int64.shift_right_logical i 30 in
(Int64.to_int mi) land max_int);
let hi = Int64.shift_right_logical i 60 in
(Int64.to_int hi) land 1 |] }
| 64 -> { length = 63;
bits = [| (Int64.to_int i) land max_int;
let hi = Int64.shift_right_logical i 62 in
(Int64.to_int hi) land 1 |] }
| _ -> assert false
let to_int64_us _ = failwith "todo"
let of_int64_s _ = failwith "todo"
let to_int64_s _ = failwith "todo"
(* [Nativeint] *)
let select_of f32 f64 = match Sys.word_size with
| 32 -> (fun i -> f32 (Nativeint.to_int32 i))
| 64 -> (fun i -> f64 (Int64.of_nativeint i))
| _ -> assert false
let of_nativeint_s = select_of of_int32_s of_int64_s
let of_nativeint_us = select_of of_int32_us of_int64_us
let select_to f32 f64 = match Sys.word_size with
| 32 -> (fun i -> Nativeint.of_int32 (f32 i))
| 64 -> (fun i -> Int64.to_nativeint (f64 i))
| _ -> assert false
let to_nativeint_s = select_to to_int32_s to_int64_s
let to_nativeint_us = select_to to_int32_us to_int64_us
ocamlgraph-2.0.0/src/lib/persistentQueue.ml 0000644 0001750 0000144 00000003552 13735627615 017312 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(** Purely applicative queues implemented in a standard way
using a pair of lists (Hood & Melville 1981) *)
type 'a t = 'a list * 'a list
(** a queue is a pair (prefix, xiffus), with elements popped from prefix
and inserted into xiffus
invariant: prefix=[] -> xiffus=[] *)
let empty = [], []
let is_empty (prefix, _) =
prefix = []
let add queue elt = match queue with
| [], [] -> [elt], []
| prefix, xiffus -> prefix, elt :: xiffus
let head = function
| head :: _, _-> head
| [], _ -> raise Not_found
let tail = function
| [_], xiffus -> List.rev xiffus, []
| _ :: prefix, xiffus -> prefix, xiffus
| [], _ -> raise Not_found
ocamlgraph-2.0.0/src/lib/persistentQueue.mli 0000644 0001750 0000144 00000002565 13735627615 017466 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(** Purely applicative queues *)
type 'a t
val empty : 'a t
val is_empty : 'a t -> bool
val add : 'a t -> 'a -> 'a t
val head : 'a t -> 'a
val tail : 'a t -> 'a t
ocamlgraph-2.0.0/src/lib/unionfind.mli 0000644 0001750 0000144 00000003454 13735627615 016250 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(* Unionfind structure over hash-ordered types.
This module implements a unionfind data structure, given a total ordering
function and a hash function over the elements.
*)
module type HashedOrderedType = sig
(* The type of the elements*)
type t
val equal : t -> t -> bool
val hash : t -> int
val compare : t -> t -> int
end
(* Input signature of the functor Unionfind.Make *)
module type S = sig
type elt
type t
val init : elt list -> t
val find : elt -> t -> elt
val union : elt -> elt -> t -> unit
end
module Make (X : HashedOrderedType) : S with type elt = X.t
ocamlgraph-2.0.0/src/lib/heap.mli 0000644 0001750 0000144 00000004666 13735627615 015202 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(** Priority queues *)
module type Ordered = sig
type t
val compare : t -> t -> int
end
exception EmptyHeap
module Imperative(X: Ordered) : sig
(* Type of imperative heaps.
(In the following [n] refers to the number of elements in the heap) *)
type t
(* [create c] creates a new heap, with initial capacity of [c] *)
val create : int -> t
(* [is_empty h] checks the emptiness of [h] *)
val is_empty : t -> bool
(* [add x h] adds a new element [x] in heap [h]; size of [h] is doubled
when maximum capacity is reached; complexity $O(log(n))$ *)
val add : t -> X.t -> unit
(* [maximum h] returns the maximum element of [h]; raises [EmptyHeap]
when [h] is empty; complexity $O(1)$ *)
val maximum : t -> X.t
(* [remove h] removes the maximum element of [h]; raises [EmptyHeap]
when [h] is empty; complexity $O(log(n))$ *)
val remove : t -> unit
(* [pop_maximum h] removes the maximum element of [h] and returns it;
raises [EmptyHeap] when [h] is empty; complexity $O(log(n))$ *)
val pop_maximum : t -> X.t
(* usual iterators and combinators; elements are presented in
arbitrary order *)
val iter : (X.t -> unit) -> t -> unit
val fold : (X.t -> 'a -> 'a) -> t -> 'a -> 'a
end
ocamlgraph-2.0.0/src/lib/bitv.mli 0000644 0001750 0000144 00000017301 13735627615 015217 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(*s {\bf Module Bitv}.
This module implements bit vectors, as an abstract datatype [t].
Since bit vectors are particular cases of arrays, this module provides
the same operations as the module [Array] (Sections~\ref{barray}
up to \ref{earray}). It also provides bitwise operations
(Section~\ref{bitwise}). In the following, [false] stands for the bit 0
and [true] for the bit 1. *)
type t
(*s {\bf Creation, access and assignment.} \label{barray}
[(Bitv.create n b)] creates a new bit vector of length [n],
initialized with [b].
[(Bitv.init n f)] returns a fresh vector of length [n],
with bit number [i] initialized to the result of [(f i)].
[(Bitv.set v n b)] sets the [n]th bit of [v] to the value [b].
[(Bitv.get v n)] returns the [n]th bit of [v].
[Bitv.length] returns the length (number of elements) of the given
vector. *)
val create : int -> bool -> t
val init : int -> (int -> bool) -> t
val set : t -> int -> bool -> unit
val get : t -> int -> bool
val length : t -> int
(*s [max_length] is the maximum length of a bit vector (System dependent). *)
val max_length : int
(*s {\bf Copies and concatenations.}
[(Bitv.copy v)] returns a copy of [v],
that is, a fresh vector containing the same elements as
[v]. [(Bitv.append v1 v2)] returns a fresh vector containing the
concatenation of the vectors [v1] and [v2]. [Bitv.concat] is
similar to [Bitv.append], but catenates a list of vectors. *)
val copy : t -> t
val append : t -> t -> t
val concat : t list -> t
(*s {\bf Sub-vectors and filling.}
[(Bitv.sub v start len)] returns a fresh
vector of length [len], containing the bits number [start] to
[start + len - 1] of vector [v]. Raise [Invalid_argument
"Bitv.sub"] if [start] and [len] do not designate a valid
subvector of [v]; that is, if [start < 0], or [len < 0], or [start
+ len > Bitv.length a].
[(Bitv.fill v ofs len b)] modifies the vector [v] in place,
storing [b] in elements number [ofs] to [ofs + len - 1]. Raise
[Invalid_argument "Bitv.fill"] if [ofs] and [len] do not designate
a valid subvector of [v].
[(Bitv.blit v1 o1 v2 o2 len)] copies [len] elements from vector
[v1], starting at element number [o1], to vector [v2], starting at
element number [o2]. It {\em does not work} correctly if [v1] and [v2] are
the same vector with the source and destination chunks overlapping.
Raise [Invalid_argument "Bitv.blit"] if [o1] and [len] do not
designate a valid subvector of [v1], or if [o2] and [len] do not
designate a valid subvector of [v2]. *)
val sub : t -> int -> int -> t
val fill : t -> int -> int -> bool -> unit
val blit : t -> int -> t -> int -> int -> unit
(*s {\bf Iterators.} \label{earray}
[(Bitv.iter f v)] applies function [f] in turn to all
the elements of [v]. Given a function [f], [(Bitv.map f v)] applies
[f] to all
the elements of [v], and builds a vector with the results returned
by [f]. [Bitv.iteri] and [Bitv.mapi] are similar to [Bitv.iter]
and [Bitv.map] respectively, but the function is applied to the
index of the element as first argument, and the element itself as
second argument.
[(Bitv.fold_left f x v)] computes [f (... (f (f x (get v 0)) (get
v 1)) ...) (get v (n-1))], where [n] is the length of the vector
[v].
[(Bitv.fold_right f a x)] computes [f (get v 0) (f (get v 1)
( ... (f (get v (n-1)) x) ...))], where [n] is the length of the
vector [v]. *)
val iter : (bool -> unit) -> t -> unit
val map : (bool -> bool) -> t -> t
val iteri : (int -> bool -> unit) -> t -> unit
val mapi : (int -> bool -> bool) -> t -> t
val fold_left : ('a -> bool -> 'a) -> 'a -> t -> 'a
val fold_right : (bool -> 'a -> 'a) -> t -> 'a -> 'a
val foldi_left : ('a -> int -> bool -> 'a) -> 'a -> t -> 'a
val foldi_right : (int -> bool -> 'a -> 'a) -> t -> 'a -> 'a
(*s [gray_iter f n] iterates function [f] on all bit vectors
of length [n], once each, using a Gray code. The order in which
bit vectors are processed is unspecified. *)
val gray_iter : (t -> unit) -> int -> unit
(*s {\bf Bitwise operations.} \label{bitwise} [bwand], [bwor] and
[bwxor] implement logical and, or and exclusive or. They return
fresh vectors and raise [Invalid_argument "Bitv.xxx"] if the two
vectors do not have the same length (where \texttt{xxx} is the
name of the function). [bwnot] implements the logical negation.
It returns a fresh vector.
[shiftl] and [shiftr] implement shifts. They return fresh vectors.
[shiftl] moves bits from least to most significant, and [shiftr]
from most to least significant (think [lsl] and [lsr]).
[all_zeros] and [all_ones] respectively test for a vector only
containing zeros and only containing ones. *)
val bw_and : t -> t -> t
val bw_or : t -> t -> t
val bw_xor : t -> t -> t
val bw_not : t -> t
val shiftl : t -> int -> t
val shiftr : t -> int -> t
val all_zeros : t -> bool
val all_ones : t -> bool
(*s {\bf Conversions to and from strings.}
Least significant bit comes first. *)
val to_string : t -> string
val of_string : string -> t
val print : Format.formatter -> t -> unit
(*s {\bf Conversions to and from lists of integers.}
The list gives the indices of bits which are set (ie [true]). *)
val to_list : t -> int list
val of_list : int list -> t
val of_list_with_length : int list -> int -> t
(*s Interpretation of bit vectors as integers. Least significant bit
comes first (ie is at index 0 in the bit vector).
[to_xxx] functions truncate when the bit vector is too wide,
and raise [Invalid_argument] when it is too short.
Suffix [_s] indicates that sign bit is kept,
and [_us] that it is discarded. *)
(* type [int] (length 31/63 with sign, 30/62 without) *)
val of_int_s : int -> t
val to_int_s : t -> int
val of_int_us : int -> t
val to_int_us : t -> int
(* type [Int32.t] (length 32 with sign, 31 without) *)
val of_int32_s : Int32.t -> t
val to_int32_s : t -> Int32.t
val of_int32_us : Int32.t -> t
val to_int32_us : t -> Int32.t
(* type [Int64.t] (length 64 with sign, 63 without) *)
val of_int64_s : Int64.t -> t
val to_int64_s : t -> Int64.t
val of_int64_us : Int64.t -> t
val to_int64_us : t -> Int64.t
(* type [Nativeint.t] (length 32/64 with sign, 31/63 without) *)
val of_nativeint_s : Nativeint.t -> t
val to_nativeint_s : t -> Nativeint.t
val of_nativeint_us : Nativeint.t -> t
val to_nativeint_us : t -> Nativeint.t
(*s Only if you know what you are doing... *)
val unsafe_set : t -> int -> bool -> unit
val unsafe_get : t -> int -> bool
ocamlgraph-2.0.0/src/dGraphTreeModel.ml 0000644 0001750 0000144 00000017515 13735627615 016351 0 ustar rt users (**************************************************************************)
(* *)
(* This file is part of OcamlGraph. *)
(* *)
(* Copyright (C) 2009-2010 *)
(* CEA (Commissariat � l'�nergie Atomique) *)
(* *)
(* you can redistribute it and/or modify it under the terms of the GNU *)
(* Lesser General Public License as published by the Free Software *)
(* Foundation, version 2.1, with a linking exception. *)
(* *)
(* It 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. See the *)
(* GNU Lesser General Public License for more details. *)
(* *)
(* See the file ../LICENSE for more details. *)
(* *)
(* Authors: *)
(* - Julien Signoles (Julien.Signoles@cea.fr) *)
(* - Jean-Denis Koeck (jdkoeck@gmail.com) *)
(* - Benoit Bataille (benoit.bataille@gmail.com) *)
(* *)
(**************************************************************************)
module type S = sig
module Tree: Graphviz.GraphWithDotAttrs
module TreeManipulation : sig
type t
val get_structure : t -> Tree.t
val get_tree_vertices : Tree.V.label -> t -> Tree.V.t list
val get_graph_vertex : Tree.V.t -> t -> Tree.V.label
val is_ghost_node : Tree.V.t -> t -> bool
val is_ghost_edge : Tree.E.t -> t -> bool
end
type cluster = string
type graph_layout
class tree_model :
graph_layout ->
TreeManipulation.t ->
[Tree.V.t, Tree.E.t, cluster] DGraphModel.abstract_model
val tree : unit -> TreeManipulation.t
end
module Build
(G: Sig.G)
(T: Graphviz.GraphWithDotAttrs with type V.label = G.V.t)
(TM: DGraphSubTree.S with type Tree.t = T.t
and type Tree.V.t = T.V.t
and type Tree.E.t = T.E.t) =
struct
module TreeManipulation = TM
type cluster = string
module X = XDot.Make(T)
type graph_layout = X.graph_layout
class tree_model layout tree
: [ T.V.t, T.E.t, cluster ] DGraphModel.abstract_model
=
let tree_structure = TM.get_structure tree in
object
(* Iterators *)
method iter_edges f =
T.iter_edges
(fun v1 v2 ->
if not (TM.is_ghost_node v1 tree && TM.is_ghost_node v2 tree) then
f v1 v2)
tree_structure
method iter_edges_e f =
T.iter_edges_e
(fun e -> if not (TM.is_ghost_edge e tree) then f e)
tree_structure
method iter_pred f v =
T.iter_pred
(fun v -> if not (TM.is_ghost_node v tree) then f v)
tree_structure v
method iter_pred_e f v =
T.iter_pred_e
(fun e -> if not (TM.is_ghost_edge e tree) then f e)
tree_structure v
method iter_succ f =
T.iter_succ
(fun v -> if not (TM.is_ghost_node v tree) then f v)
tree_structure
method iter_succ_e f =
T.iter_succ_e
(fun e -> if not (TM.is_ghost_edge e tree) then f e)
tree_structure
method iter_vertex f =
T.iter_vertex
(fun v -> if not (TM.is_ghost_node v tree) then f v)
tree_structure
method iter_associated_vertex f v =
let origin_vertex = TM.get_graph_vertex v tree in
List.iter
(fun v -> if not (TM.is_ghost_node v tree) then f v)
(TM.get_tree_vertices origin_vertex tree)
method iter_clusters f =
Hashtbl.iter (fun k _ -> f k) layout.X.cluster_layouts
(* Membership functions *)
method find_edge =
try T.find_edge tree_structure
with Not_found -> assert false
method mem_edge = T.mem_edge tree_structure
method mem_edge_e = T.mem_edge_e tree_structure
method mem_vertex = T.mem_vertex tree_structure
method src = T.E.src
method dst = T.E.dst
(* Layout *)
method bounding_box = layout.X.bbox
method get_vertex_layout v =
try X.HV.find layout.X.vertex_layouts v
with Not_found -> assert false
method get_edge_layout e =
try X.HE.find e layout.X.edge_layouts
with Not_found -> assert false
method get_cluster_layout c =
try Hashtbl.find layout.X.cluster_layouts c
with Not_found -> assert false
end
end
module SubTreeMake(G: Graphviz.GraphWithDotAttrs) = struct
module T = Imperative.Digraph.Abstract(G.V)
module TM = DGraphSubTree.Make(G)(T)
let tree_ref : TM.t option ref = ref None
let tree () = match !tree_ref with None -> assert false | Some t -> t
let graph_ref: G.t option ref = ref None
let graph () = match !graph_ref with None -> assert false | Some g -> g
module Tree = struct
include T
let graph_attributes _ = G.graph_attributes (graph ())
let default_vertex_attributes _ = G.default_vertex_attributes (graph ())
let default_edge_attributes _ = G.default_edge_attributes (graph ())
let cpt = ref 0
let name_table = Hashtbl.create 97
let vertex_name v =
try Hashtbl.find name_table v
with Not_found ->
incr cpt;
Hashtbl.add name_table v (string_of_int !cpt);
string_of_int !cpt
let vertex_attributes v =
let t = tree () in
if TM.is_ghost_node v t then [ `Style `Invis ]
else G.vertex_attributes (TM.get_graph_vertex v t)
let edge_attributes e =
let t = tree () in
if TM.is_ghost_node (T.E.src e) t || TM.is_ghost_node (T.E.dst e) t then
[ `Style `Dashed; `Dir `None ]
else
G.edge_attributes
(G.find_edge
(graph ())
(TM.get_graph_vertex (T.E.src e) t)
(TM.get_graph_vertex (T.E.dst e) t))
let get_subgraph v =
let t = tree () in
if TM.is_ghost_node v t then None
else G.get_subgraph (TM.get_graph_vertex v t)
end
include Build(G)(Tree)(TM)
module TreeLayout =
DGraphTreeLayout.Make
(Tree)
(struct let is_ghost_node v = TM.is_ghost_node v (tree ()) end)
let from_graph
?(depth_forward=2)
?(depth_backward=2)
~fontMeasure
g
v
=
(* Generate subtree *)
let t = TM.make g v depth_forward depth_backward in
tree_ref := Some t;
graph_ref := Some g;
let layout =
TreeLayout.from_tree ~fontMeasure (TM.get_structure t) (TM.get_root t)
in
new tree_model layout t
end
module SubTreeDotModelMake = struct
module T = Imperative.Digraph.Abstract(DGraphModel.DotG.V)
module TM = DGraphSubTree.Make_from_dot_model(T)
let tree_ref : TM.t option ref = ref None
let tree () = match !tree_ref with None -> assert false | Some t -> t
module TreeLayout =
DGraphTreeLayout.MakeFromDotModel
(T)
(struct let is_ghost_node v = TM.is_ghost_node v (tree ()) end)
include TreeLayout
include Build(DGraphModel.DotG)(Tree)(TM)
let from_model ?(depth_forward=2) ?(depth_backward=2) model v =
let t = TM.make model v depth_forward depth_backward in
tree_ref := Some t;
let tree_structure = TM.get_structure t in
let layout = from_model tree_structure (TM.get_root t) model in
new tree_model layout t
end
ocamlgraph-2.0.0/src/dGraphModel.mli 0000644 0001750 0000144 00000007754 13735627615 015706 0 ustar rt users (**************************************************************************)
(* *)
(* This file is part of OcamlGraph. *)
(* *)
(* Copyright (C) 2009-2010 *)
(* CEA (Commissariat � l'�nergie Atomique) *)
(* *)
(* you can redistribute it and/or modify it under the terms of the GNU *)
(* Lesser General Public License as published by the Free Software *)
(* Foundation, version 2.1, with a linking exception. *)
(* *)
(* It 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. See the *)
(* GNU Lesser General Public License for more details. *)
(* *)
(* See the file ../LICENSE for more details. *)
(* *)
(* Authors: *)
(* - Julien Signoles (Julien.Signoles@cea.fr) *)
(* - Jean-Denis Koeck (jdkoeck@gmail.com) *)
(* - Benoit Bataille (benoit.bataille@gmail.com) *)
(* *)
(**************************************************************************)
(** Abstract graph model *)
open XDot
exception DotError of string
(** Immutable graph model.
Layout accessors, iterators and
membership functions. *)
class type ['vertex, 'edge, 'cluster] abstract_model = object
method iter_edges : ('vertex -> 'vertex -> unit) -> unit
method iter_edges_e : ('edge -> unit) -> unit
method iter_pred : ('vertex -> unit) -> 'vertex -> unit
method iter_pred_e : ('edge -> unit) -> 'vertex -> unit
method iter_succ : ('vertex -> unit) -> 'vertex -> unit
method iter_succ_e : ('edge -> unit) -> 'vertex -> unit
method iter_vertex : ('vertex -> unit) -> unit
method iter_clusters : ('cluster -> unit) -> unit
method iter_associated_vertex : ('vertex -> unit) -> 'vertex -> unit
(** Membership functions *)
method find_edge : 'vertex -> 'vertex -> 'edge
method mem_edge : 'vertex -> 'vertex -> bool
method mem_edge_e : 'edge -> bool
method mem_vertex : 'vertex -> bool
method src : 'edge -> 'vertex
method dst : 'edge -> 'vertex
(** Dot layout *)
method bounding_box : bounding_box
method get_edge_layout : 'edge -> edge_layout
(** @raise Multiple_layouts when there are several possible layouts for the
given edge *)
method get_vertex_layout : 'vertex -> node_layout
method get_cluster_layout : 'cluster -> cluster_layout
end
(** This functor creates a model from a graph *)
module Make(G : Graphviz.GraphWithDotAttrs) : sig
type cluster = string
exception Multiple_layouts of (G.E.t * edge_layout) list
class model:
XDot.Make(G).graph_layout -> G.t -> [G.V.t, G.E.t, cluster] abstract_model
val from_graph : ?cmd:string -> ?tmp_name:string -> G.t -> model
(** Creates a model using graphviz.
[tmp_name] is the name of the temporary dot files.
@raise DotError if issue occurs with the generated dot file *)
end
module DotG : Sig.G
with type V.label = XDot.node_layout and type E.label = XDot.edge_layout
type cluster = string
type dotg_model = (DotG.vertex, DotG.edge, cluster) abstract_model
(** Creates a model from a dot file. *)
val read_dot : ?cmd:string -> string -> dotg_model
(** Creates a model from an xdot file (the layout is not recomputed)*)
val read_xdot : string -> dotg_model
ocamlgraph-2.0.0/src/delaunay.mli 0000644 0001750 0000144 00000006547 13735627615 015321 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(* $Id: delaunay.mli,v 1.8 2004-02-20 14:37:40 signoles Exp $ *)
(** Delaunay triangulation. *)
(** Delaunay triangulation is available for any CCC system in the sense
of Knuth's ``Axioms and Hulls'' *)
module type CCC = sig
type point
val ccw : point -> point -> point -> bool
(** The counterclockwise relation [ccw p q r] states that the
circle through points [(p,q,r)] is traversed counterclockwise
when we encounter the points in cyclic order [p,q,r,p,...] **)
val in_circle : point -> point -> point -> point -> bool
(** The relation [in_circle p q r s] states that [s] lies
inside the circle [(p,q,r)] if [ccw p q r] is true, or outside that
circle if [ccw p q r] is false. *)
end
(** The result of triangulation is an abstract value of type [triangulation].
Then one can iterate over all edges of the triangulation. *)
module type Triangulation = sig
module S : CCC
type triangulation
val triangulate : S.point array -> triangulation
(** [triangulate a] computes the Delaunay triangulation of a set of
points, given as an array [a]. If [N] is the number of points
(that is [Array.length a]), then the running time is $O(N \log N)$
on the average and $O(N^2)$ on the worst-case. The space used is
always $O(N)$. *)
val iter : (S.point -> S.point -> unit) -> triangulation -> unit
(** [iter f t] iterates over all edges of the triangulation [t].
[f u v] is called once for each undirected edge [(u,v)]. *)
val fold : (S.point -> S.point -> 'a -> 'a) -> triangulation -> 'a -> 'a
val iter_triangles :
(S.point -> S.point -> S.point -> unit) -> triangulation -> unit
end
(** Generic Delaunay triangulation *)
module Make(S : CCC) : Triangulation with module S = S
(** Points with integer coordinates *)
module IntPoints : CCC with type point = int * int
(** Delaunay triangulation with integer coordinates *)
module Int : Triangulation with module S = IntPoints
(** Points with floating point coordinates *)
module FloatPoints : CCC with type point = float * float
(** Delaunay triangulation with floating point coordinates *)
module Float : Triangulation with module S = FloatPoints
ocamlgraph-2.0.0/src/rand.ml 0000644 0001750 0000144 00000020102 13735627615 014251 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(* $Id: rand.ml,v 1.18 2005-03-31 13:32:51 filliatr Exp $ *)
module type S = sig
type graph
type vertex
type edge_label
val graph : ?loops:bool -> v:int -> e:int -> unit -> graph
val labeled :
(vertex -> vertex -> edge_label) ->
?loops:bool -> v:int -> e:int -> unit -> graph
(* DEBUG *)
val random_few_edges : loops:bool -> v:int -> e:int -> graph
val random_many_edges : loops:bool -> v:int -> e:int -> graph
val gnp : ?loops:bool -> v:int -> prob:float -> unit -> graph
val gnp_labeled :
(vertex -> vertex -> edge_label) ->
?loops:bool -> v:int -> prob:float -> unit -> graph
end
module Make(B : Builder.INT) = struct
open B
type graph = G.t
type vertex = G.V.t
type edge_label = G.E.label
open Int64
let max_edges ~loops ~v ~e =
if v <= 0 || e < 0 then invalid_arg "random";
let v64 = of_int v in
let max_e = mul v64 (pred v64) in
let max_e = if G.is_directed then max_e else div max_e (of_int 2) in
let max_e = if loops then add max_e v64 else max_e in
if of_int e > max_e then invalid_arg "random: too many edges";
max_e
let fold_for i0 i1 f =
let rec loop i v = if i > i1 then v else loop (i + 1) (f v i) in
loop i0
(* naive implementation: we randomly chose edges up to [e] different edges *)
let random_few_edges add_edge ~loops ~v ~e =
let _ = max_edges ~loops ~v ~e in
let a = Array.init v G.V.create in
let g = Array.fold_left add_vertex (empty ()) a in
let rec random_edge g =
let i = Random.int v in
let j = Random.int v in
if (i = j && not loops) || G.mem_edge g a.(i) a.(j) then
random_edge g
else
add_edge g a.(i) a.(j)
in
fold_for 1 e (fun g _ -> random_edge g) g
(* other implementation in O(v * v); faster when [e] is large *)
let random_many_edges add_edge ~loops ~v ~e =
let v64 = of_int v in
let max_e = max_edges ~loops ~v ~e in
let a = Array.init v G.V.create in
let g = Array.fold_left add_vertex (empty ()) a in
let rec add_edges i j max nb g =
assert
(max >= 0L &&
max_e =
add max (add (mul (of_int i) v64)
(of_int
(j -
(match G.is_directed, loops with
| true, true -> 0
| true, false -> if j > i then i + 1 else i
| false, true -> i * (i - 1) / 2 + if j > i then i else j
| false, false -> i*(i+1)/2 + if j > i then i+1 else j)))));
if nb = 0 then
g
else
let add_edges =
let i, j = if j = v - 1 then i + 1, 0 else i, j + 1 in
add_edges i j
in
if (i = j && not loops) || (not G.is_directed && i > j) then
add_edges max nb g
else
let add_edges = add_edges (pred max) in
if Random.int64 max < of_int nb then
add_edges (nb - 1) (add_edge g a.(i) a.(j))
else
add_edges nb g
in
add_edges 0 0 max_e e g
let random ~loops ~v ~e =
let r = float e /. (float v *. float v) in
(if r < 0.4 then random_few_edges else random_many_edges) ~loops ~v ~e
let graph ?(loops=false) ~v ~e () = random B.add_edge ~loops ~v ~e
let labeled f ?(loops=false) ~v ~e () =
random
(fun g v1 v2 -> B.add_edge_e g (G.E.create v1 (f v1 v2) v2))
~loops ~v ~e
(* DEBUG *)
let random_few_edges = random_few_edges B.add_edge
let random_many_edges = random_many_edges B.add_edge
(** G(n,p) graphs
See https://en.wikipedia.org/wiki/Random_graph *)
let gnp_generic add_edge ?(loops=false) ~v ~prob () =
if not (0.0 <= prob && prob <= 1.0) then invalid_arg "gnp";
let vertices = Array.init v (fun i -> B.G.V.create i) in
let g = Array.fold_left B.add_vertex (B.empty ()) vertices in
let g = ref g in
for i = 0 to v-1 do
for j = 0 to (if G.is_directed then v-1 else i) do
if (loops || j <> i) && (prob = 1.0 || Random.float 1.0 < prob) then
g := add_edge !g vertices.(i) vertices.(j)
done
done;
!g
let gnp ?(loops=false) ~v ~prob () =
gnp_generic B.add_edge ~loops ~v ~prob ()
let gnp_labeled f ?(loops=false) ~v ~prob () =
gnp_generic (fun g v1 v2 -> B.add_edge_e g (G.E.create v1 (f v1 v2) v2))
~loops ~v ~prob ()
end
module P (G : Sig.P with type V.label = int) = Make(Builder.P(G))
module I (G : Sig.I with type V.label = int) = Make(Builder.I(G))
(** Random planar graphs *)
module Planar = struct
module type S = sig
type graph
val graph :
?loops:bool -> xrange:int*int -> yrange:int*int ->
prob:float -> int -> graph
end
module Make
(B : Builder.S with type G.V.label = int * int and type G.E.label = int) =
struct
type graph = B.G.t
open B.G
module Point = struct
type point = V.t
let ccw v1 v2 v3 =
Delaunay.IntPoints.ccw (V.label v1) (V.label v2) (V.label v3)
let in_circle v1 v2 v3 v4 =
Delaunay.IntPoints.in_circle
(V.label v1) (V.label v2) (V.label v3) (V.label v4)
let distance v1 v2 =
let x1,y1 = V.label v1 in
let x2,y2 = V.label v2 in
let sqr x = let x = float x in x *. x in
truncate (sqrt (sqr (x1 - x2) +. sqr (y1 - y2)))
end
module Triangulation = Delaunay.Make(Point)
let graph ?(loops=false) ~xrange:(xmin,xmax) ~yrange:(ymin,ymax) ~prob v =
if not (0.0 <= prob && prob <= 1.0) then invalid_arg "Planar.graph";
if v < 2 then invalid_arg "Planar.graph";
(* [v] random points and their Delaunay triangulation *)
let random_point () =
xmin + Random.int (1 + xmax - xmin),
ymin + Random.int (1 + ymax - ymin)
in
let vertices = Array.init v (fun _ -> V.create (random_point ())) in
let t = Triangulation.triangulate vertices in
(* a graph with [v] vertices and random loops if any *)
let g = Array.fold_left B.add_vertex (B.empty ()) vertices in
let g =
if loops then
Array.fold_left
(fun g v ->
if Random.float 1.0 < prob then
g
else
let e = E.create v 0 v in B.add_edge_e g e)
g vertices
else
g
in
(* we keep some edges from the triangulation according to [prob] *)
let add_edge v1 v2 g =
if Random.float 1.0 < prob then
g
else
let e = E.create v1 (Point.distance v1 v2) v2 in B.add_edge_e g e
in
Triangulation.fold
(fun v1 v2 g ->
let g = add_edge v1 v2 g in
if is_directed then add_edge v2 v1 g else g)
t g
end
module P (G : Sig.P with type V.label = int * int and type E.label = int) =
Make(Builder.P(G))
module I (G : Sig.I with type V.label = int * int and type E.label = int) =
Make(Builder.I(G))
end
(*
Local Variables:
compile-command: "make -C .. src/rand.cmo"
End:
*)
ocamlgraph-2.0.0/src/mincut.ml 0000644 0001750 0000144 00000007031 13735627615 014632 0 ustar rt users (**************************************************************************)
(* *)
(* Ocamlgraph: a generic graph library for OCaml *)
(* Copyright (C) 2013-2014 *)
(* David Monniaux, Gabriel Radanne *)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
module type G = sig
type t
module V : Sig.VERTEX
val succ : t -> V.t -> V.t list
end
module Make (G : G) = struct
module H = Hashtbl.Make (G.V)
let find_default htbl x =
try H.find htbl x
with Not_found -> false
let min_cutset gr first_node =
let n_labels = H.create 97 in
let l_labels = H.create 97 in
let already_processed = H.create 97 in
let is_already_processed x = find_default already_processed x in
let on_the_stack = H.create 97 in
let is_on_the_stack x = find_default on_the_stack x in
let cut_set = ref [] in
let counter = ref 1 in
let rec step2 top rest_of_stack =
assert (not (is_already_processed top));
assert (not (is_on_the_stack top));
H.add on_the_stack top true;
H.add n_labels top !counter;
counter := !counter + 1;
H.add l_labels top 0;
H.add already_processed top true;
step3 (G.succ gr top) top rest_of_stack
and step3 successors top rest_of_stack = match successors with
| successor :: other_successors ->
if not (is_already_processed successor)
(* step 4 *)
then step2 successor ((top,successors)::rest_of_stack)
(* step 5 *)
else begin
let x =
if is_on_the_stack successor
then H.find n_labels successor
else H.find l_labels successor
in
H.add l_labels top
(max (H.find l_labels top) x) ;
step3 other_successors top rest_of_stack
end
| [] -> begin
(* step 7 *)
if H.find l_labels top = H.find n_labels top
then begin
cut_set := top::!cut_set ;
H.add l_labels top 0 ;
end ;
(* check added between algorithms C and D *)
if H.find l_labels top > H.find n_labels top
then raise (Invalid_argument "Graph.Mincut: graph not reducible")
(* step 8 *)
else match rest_of_stack with
| [] -> !cut_set (* SUCCESS *)
| (new_top, new_successors)::new_tail -> begin
H.add on_the_stack top false;
H.add l_labels new_top
(max (H.find l_labels top) (H.find l_labels new_top)) ;
step3 new_successors new_top new_tail
end
end in
(* step 2 *)
step2 first_node []
end
ocamlgraph-2.0.0/src/path.mli 0000644 0001750 0000144 00000012751 13735627615 014445 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(* $Id: path.mli,v 1.9 2005-07-18 07:10:35 filliatr Exp $ *)
(** Paths *)
(** Minimal graph signature for Dijkstra's algorithm.
Sub-signature of {!Sig.G}. *)
module type G = sig
type t
module V : Sig.COMPARABLE
module E : sig
type t
type label
val label : t -> label
val src : t -> V.t
val dst : t -> V.t
val create : V.t -> label -> V.t -> t
end
val iter_vertex : (V.t -> unit) -> t -> unit
val fold_vertex : (V.t -> 'a -> 'a) -> t -> 'a -> 'a
val iter_succ : (V.t -> unit) -> t -> V.t -> unit
val iter_succ_e : (E.t -> unit) -> t -> V.t -> unit
val fold_edges_e : (E.t -> 'a -> 'a) -> t -> 'a -> 'a
val nb_vertex : t -> int
end
module Dijkstra
(G: G)
(W: Sig.WEIGHT with type edge = G.E.t) :
sig
val shortest_path : G.t -> G.V.t -> G.V.t -> G.E.t list * W.t
(** [shortest_path g v1 v2] computes the shortest path from vertex [v1]
to vertex [v2] in graph [g]. The path is returned as the list of
followed edges, together with the total length of the path.
raise [Not_found] if the path from [v1] to [v2] does not exist.
Complexity: at most O((V+E)log(V)) *)
end
(* The following module is a contribution of Yuto Takei (University of Tokyo) *)
module BellmanFord
(G: G)
(W: Sig.WEIGHT with type edge = G.E.t) :
sig
module H : Hashtbl.S
with type key = G.V.t
and type 'a t = 'a Hashtbl.Make(G.V).t
exception NegativeCycle of G.E.t list
val all_shortest_paths : G.t -> G.V.t -> W.t H.t
(** [shortest_path g vs] computes the distances of shortest paths
from vertex [vs] to all other vertices in graph [g]. They are
returned as a hash table mapping each vertex reachable from
[vs] to its distance from [vs]. If [g] contains a
negative-length cycle reachable from [vs], raises
[NegativeCycle l] where [l] is such a cycle.
Complexity: at most O(VE) *)
val find_negative_cycle_from: G.t -> G.V.t -> G.E.t list
(** [find_negative_cycle_from g vs] looks for a negative-length
cycle in graph [g] that is reachable from vertex [vs] and
returns it as a list of edges. If no such a cycle exists,
raises [Not_found].
Complexity: at most O(VE). *)
val find_negative_cycle: G.t -> G.E.t list
(** [find_negative_cycle g] looks for a negative-length cycle in
graph [g] and returns it. If the graph [g] is free from such a
cycle, raises [Not_found].
Complexity: O(V^2E) *)
end
(** Weight signature for Johnson's algorithm. *)
module type WJ = sig
include Sig.WEIGHT
val sub : t -> t -> t
(** Subtraction of weights. *)
end
module Johnson
(G: G)
(W: WJ with type edge = G.E.t) :
sig
module HVV : Hashtbl.S with type key = (G.V.t * G.V.t)
val all_pairs_shortest_paths : G.t -> W.t HVV.t
(** [all_pairs_shortest_paths g] computes the distance of shortest
path between all pairs of vertices in [g]. They are returned as
a hash table mapping each pair of vertices to their
distance. If [g] contains a negative-cycle, raises
[NegativeCycle l] where [l] is such a cycle.
Complexity: at most O(VElog(V)) *)
end
(** Check for a path. *)
module Check
(G : sig
type t
module V : Sig.COMPARABLE
val iter_succ : (V.t -> unit) -> t -> V.t -> unit
end) :
sig
type path_checker
(** the abstract data type of a path checker; this is a mutable data
structure *)
val create : G.t -> path_checker
(** [create g] builds a new path checker for the graph [g];
if the graph is mutable, it must not be mutated while this path
checker is in use (through the function [check_path] below). *)
val check_path : path_checker -> G.V.t -> G.V.t -> bool
(** [check_path pc v1 v2] checks whether there is a path from [v1] to
[v2] in the graph associated to the path checker [pc].
Complexity: The path checker contains a cache of all results computed
so far. This cache is implemented with a hash table so access in this
cache is usually O(1). When the result is not in the cache, Dijkstra's
algorithm is run to check for the path, and all intermediate results
are cached.
Note: if checks are to be done for almost all pairs of vertices, it
may be more efficient to compute the transitive closure of the graph
(see module [Oper]).
*)
end
ocamlgraph-2.0.0/src/gml.mll 0000644 0001750 0000144 00000012365 13735627615 014274 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(* $Id: gml.mll,v 1.3 2005-07-06 13:20:31 conchon Exp $ *)
{
open Lexing
type value =
| Int of int
| Float of float
| String of string
| List of value_list
and value_list = (string * value) list
}
let space = [' ' '\t' '\r' '\n']+
let ident = ['a'-'z' 'A'-'Z'] ['a'-'z' 'A'-'Z' '0'-'9']*
let digit = ['0'-'9']
let sign = '-' | '+'
let integer = sign? digit+
let mantissa = 'E' sign? digit+
let real = sign? digit* '.' digit* mantissa?
let in_string = [^ '"']*
rule file = parse
| space
{ file lexbuf }
| (ident as key) space
{ let v = value lexbuf in
(key, v) :: file lexbuf }
| eof
{ [] }
| _ as c
{ failwith ("Gml: invalid character " ^ String.make 1 c) }
and value_list = parse
| space
{ value_list lexbuf }
| (ident as key) space
{ let v = value lexbuf in
(key, v) :: value_list lexbuf }
| ']'
{ [] }
| _ as c
{ failwith ("Gml: invalid character " ^ String.make 1 c) }
and value = parse
| integer as i
{ Int (int_of_string i) }
| real as r
{ Float (float_of_string r) }
| '"' (in_string as s) '"'
{ String s }
| '['
{ let l = value_list lexbuf in List l }
| _ as c
{ failwith ("Gml: invalid character " ^ String.make 1 c) }
{
let parse f =
let c = open_in f in
let lb = from_channel c in
let v = file lb in
close_in c;
v
module Parse
(B : Builder.S)
(L : sig val node : value_list -> B.G.V.label
val edge : value_list -> B.G.E.label end) =
struct
let create_graph l =
let nodes = Hashtbl.create 97 in
let g = B.empty () in
(* 1st pass: create the nodes *)
let g =
List.fold_left
(fun g v -> match v with
| "node", List l ->
let n = B.G.V.create (L.node l) in
begin
try
let id = List.assoc "id" l in Hashtbl.add nodes id n
with Not_found ->
()
end;
B.add_vertex g n
| _ ->
g)
g l
in
(* 2nd pass: add the edges *)
List.fold_left
(fun g v -> match v with
| "edge", List l ->
begin try
let source = List.assoc "source" l in
let target = List.assoc "target" l in
let nsource = Hashtbl.find nodes source in
let ntarget = Hashtbl.find nodes target in
let e = B.G.E.create nsource (L.edge l) ntarget in
B.add_edge_e g e
with Not_found ->
g
end
| _ ->
g)
g l
let parse f =
match parse f with
| ["graph", List l] -> create_graph l
| _ -> invalid_arg "Gml.Parse.parse: not a graph file"
end
module type G = sig
module V : sig
type t
val hash : t -> int
val equal : t -> t -> bool
type label
val label : t -> label
end
module E : sig
type t
type label
val src : t -> V.t
val dst : t -> V.t
val label : t -> label
end
type t
val iter_vertex : (V.t -> unit) -> t -> unit
val iter_edges_e : (E.t -> unit) -> t -> unit
end
module Print
(G : G)
(L : sig
val node : G.V.label -> value_list
val edge : G.E.label -> value_list
end) =
struct
open Format
module H = Hashtbl.Make(G.V)
let print fmt g =
let nodes = H.create 97 in
let cpt = ref 0 in
let id n =
try H.find nodes n
with Not_found -> incr cpt; let id = !cpt in H.add nodes n id; id
in
fprintf fmt "@[graph [@\n";
let rec value fmt = function
| Int n -> fprintf fmt "%d" n
| Float f -> fprintf fmt "%f" f
| String s -> fprintf fmt "\"%s\"" s
| List l -> fprintf fmt "[@\n @[%a@]@\n]" value_list l
and value_list fmt = function
| [] -> ()
| [s,v] -> fprintf fmt "%s %a" s value v
| (s,v) :: l -> fprintf fmt "%s %a@\n" s value v; value_list fmt l
in
G.iter_vertex
(fun v ->
fprintf fmt " @[node [@\n id %d@\n @[%a@]@\n]@]@\n"
(id v) value_list (L.node (G.V.label v)))
g;
G.iter_edges_e
(fun e ->
fprintf fmt
" @[edge [@\n source %d@\n target %d@\n @[%a@]@\n]@]@\n"
(id (G.E.src e)) (id (G.E.dst e))
value_list (L.edge (G.E.label e)))
g;
fprintf fmt "]@\n"
end
}
ocamlgraph-2.0.0/src/blocks.ml 0000644 0001750 0000144 00000065676 13735627615 014633 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(** Common implementation to persistent and imperative graphs. *)
open Sig
open Util
let first_value_for_cpt_vertex = 0
let cpt_vertex = ref first_value_for_cpt_vertex
(* global counter for abstract vertex *)
(* [max_cpt t1 t2] returns the maximum of [t1] and [t2] wrt the total ordering
induced by tags creation. This ordering is defined as follow:
forall tags t1 t2,
t1 <= t2 iff
t1 is before t2 in the finite sequence
[0; 1; ..; max_int; min_int; min_int-1; -1] *)
let max_cpt c1 c2 = max (c1 + min_int) (c2 + min_int) - min_int
(* This function must be called after the unserialisation of any abstract
vertex if you want to create new vertices. *)
let after_unserialization serialized_cpt_vertex =
cpt_vertex := max_cpt serialized_cpt_vertex !cpt_vertex
(* ************************************************************************* *)
(** {2 Association table builder} *)
(* ************************************************************************* *)
(** Common signature to an imperative/persistent association table *)
module type HM = sig
type 'a return
type 'a t
type key
val create : ?size:int -> unit -> 'a t
val create_from : 'a t -> 'a t
val empty : 'a return
val clear: 'a t -> unit
val is_empty : 'a t -> bool
val add : key -> 'a -> 'a t -> 'a t
val remove : key -> 'a t -> 'a t
val mem : key -> 'a t -> bool
val find : key -> 'a t -> 'a
val find_and_raise : key -> 'a t -> string -> 'a
(** [find_and_raise k t s] is equivalent to [find k t] but
raises [Invalid_argument s] when [find k t] raises [Not_found] *)
val iter : (key -> 'a -> unit) -> 'a t -> unit
val map : (key -> 'a -> key * 'a) -> 'a t -> 'a t
val fold : (key -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b
val copy : 'a t -> 'a t
end
module type TBL_BUILDER = functor(X: COMPARABLE) -> HM with type key = X.t
(** [HM] implementation using hashtbl. *)
module Make_Hashtbl(X: COMPARABLE) = struct
include Hashtbl.Make(X)
type 'a return = unit
let empty = ()
(* never call and not visible for the user thank's to signature
constraints *)
let create_from h = create (length h)
let create ?(size=97) () = create size
let is_empty h = (length h = 0)
let find_and_raise k h s = try find h k with Not_found -> invalid_arg s
let map f h =
let h' = create_from h in
iter (fun k v -> let k, v = f k v in add h' k v) h;
h'
let add k v h = replace h k v; h
let remove k h = remove h k; h
let mem k h = mem h k
let find k h = find h k
end
(** [HM] implementation using map *)
module Make_Map(X: COMPARABLE) = struct
include Map.Make(X)
type 'a return = 'a t
let create ?size:_ () = assert false
(* never call and not visible for the user thank's to
signature constraints *)
let create_from _ = empty
let copy m = m
let map f m = fold (fun k v m -> let k, v = f k v in add k v m) m empty
let find_and_raise k h s = try find k h with Not_found -> invalid_arg s
let clear _ = assert false
(* never call and not visible for the user thank's to
signature constraints *)
end
(* ************************************************************************* *)
(** {2 Blocks builder} *)
(* ************************************************************************* *)
(** Common implementation to all (directed) graph implementations. *)
module Minimal(S: Set.S)(HM: HM) = struct
type vertex = HM.key
let is_directed = true
let empty = HM.empty
let create = HM.create
let is_empty = HM.is_empty
let copy = HM.copy
let clear = HM.clear
let nb_vertex g = HM.fold (fun _ _ -> succ) g 0
let nb_edges g = HM.fold (fun _ s n -> n + S.cardinal s) g 0
let out_degree g v =
S.cardinal
(try HM.find v g with Not_found -> invalid_arg "[ocamlgraph] out_degree")
let mem_vertex g v = HM.mem v g
let unsafe_add_vertex g v = HM.add v S.empty g
let unsafe_add_edge g v1 v2 = HM.add v1 (S.add v2 (HM.find v1 g)) g
let add_vertex g v = if HM.mem v g then g else unsafe_add_vertex g v
let iter_vertex f = HM.iter (fun v _ -> f v)
let fold_vertex f = HM.fold (fun v _ -> f v)
end
(** All the predecessor operations from the iterators on the edges *)
module Pred
(S: sig
module PV: COMPARABLE
module PE: EDGE with type vertex = PV.t
type t
val mem_vertex : PV.t -> t -> bool
val iter_edges : (PV.t -> PV.t -> unit) -> t -> unit
val fold_edges : (PV.t -> PV.t -> 'a -> 'a) -> t -> 'a -> 'a
val iter_edges_e : (PE.t -> unit) -> t -> unit
val fold_edges_e : (PE.t -> 'a -> 'a) -> t -> 'a -> 'a
end) =
struct
open S
let iter_pred f g v =
if not (mem_vertex v g) then invalid_arg "[ocamlgraph] iter_pred";
iter_edges (fun v1 v2 -> if PV.equal v v2 then f v1) g
let fold_pred f g v =
if not (mem_vertex v g) then invalid_arg "[ocamlgraph] fold_pred";
fold_edges (fun v1 v2 a -> if PV.equal v v2 then f v1 a else a) g
let pred g v = fold_pred (fun v l -> v :: l) g v []
let in_degree g v =
if not (mem_vertex v g) then invalid_arg "[ocamlgraph] in_degree";
fold_pred (fun _ n -> n + 1) g v 0
let iter_pred_e f g v =
if not (mem_vertex v g) then invalid_arg "[ocamlgraph] iter_pred_e";
iter_edges_e (fun e -> if PV.equal v (PE.dst e) then f e) g
let fold_pred_e f g v =
if not (mem_vertex v g) then invalid_arg "[ocamlgraph] fold_pred_e";
fold_edges_e (fun e a -> if PV.equal v (PE.dst e) then f e a else a) g
let pred_e g v = fold_pred_e (fun v l -> v :: l) g v []
end
(** Common implementation to all the unlabeled (directed) graphs. *)
module Unlabeled(V: COMPARABLE)(HM: HM with type key = V.t) = struct
module S = Set.Make(V)
module E = struct
type vertex = V.t
include OTProduct(V)(V)
let src = fst
let dst = snd
type label = unit
let label _ = ()
let create v1 () v2 = v1, v2
end
type edge = E.t
let mem_edge g v1 v2 =
try S.mem v2 (HM.find v1 g)
with Not_found -> false
let mem_edge_e g (v1, v2) = mem_edge g v1 v2
let find_edge g v1 v2 = if mem_edge g v1 v2 then v1, v2 else raise Not_found
let find_all_edges g v1 v2 = try [ find_edge g v1 v2 ] with Not_found -> []
let unsafe_remove_edge g v1 v2 = HM.add v1 (S.remove v2 (HM.find v1 g)) g
let unsafe_remove_edge_e g (v1, v2) = unsafe_remove_edge g v1 v2
let remove_edge g v1 v2 =
if not (HM.mem v2 g) then invalid_arg "[ocamlgraph] remove_edge";
HM.add
v1 (S.remove v2 (HM.find_and_raise v1 g "[ocamlgraph] remove_edge")) g
let remove_edge_e g (v1, v2) = remove_edge g v1 v2
let iter_succ f g v =
S.iter f (HM.find_and_raise v g "[ocamlgraph] iter_succ")
let fold_succ f g v =
S.fold f (HM.find_and_raise v g "[ocamlgraph] fold_succ")
let iter_succ_e f g v = iter_succ (fun v2 -> f (v, v2)) g v
let fold_succ_e f g v = fold_succ (fun v2 -> f (v, v2)) g v
let succ g v = S.elements (HM.find_and_raise v g "[ocamlgraph] succ")
let succ_e g v = fold_succ_e (fun e l -> e :: l) g v []
let map_vertex f =
HM.map (fun v s -> f v, S.fold (fun v s -> S.add (f v) s) s S.empty)
module I = struct
type t = S.t HM.t
module PV = V
module PE = E
let iter_edges f = HM.iter (fun v -> S.iter (f v))
let fold_edges f = HM.fold (fun v -> S.fold (f v))
let iter_edges_e f = iter_edges (fun v1 v2 -> f (v1, v2))
let fold_edges_e f = fold_edges (fun v1 v2 a -> f (v1, v2) a)
end
include I
include Pred(struct include I let mem_vertex = HM.mem end)
end
(** Common implementation to all the labeled (directed) graphs. *)
module Labeled(V: COMPARABLE)(E: ORDERED_TYPE)(HM: HM with type key = V.t) =
struct
module VE = OTProduct(V)(E)
module S = Set.Make(VE)
module E = struct
type vertex = V.t
type label = E.t
type t = vertex * label * vertex
let src (v, _, _) = v
let dst (_, _, v) = v
let label (_, l, _) = l
let create v1 l v2 = v1, l, v2
module C = OTProduct(V)(VE)
let compare (x1, x2, x3) (y1, y2, y3) =
C.compare (x1, (x3, x2)) (y1, (y3, y2))
end
type edge = E.t
let mem_edge g v1 v2 =
try S.exists (fun (v2', _) -> V.equal v2 v2') (HM.find v1 g)
with Not_found -> false
let mem_edge_e g (v1, l, v2) =
try
let ve = v2, l in
S.exists (fun ve' -> VE.compare ve ve' = 0) (HM.find v1 g)
with Not_found ->
false
exception Found of edge
let find_edge g v1 v2 =
try
S.iter
(fun (v2', l) -> if V.equal v2 v2' then raise (Found (v1, l, v2')))
(HM.find v1 g);
raise Not_found
with Found e ->
e
let find_all_edges g v1 v2 =
try
S.fold
(fun (v2', l) acc ->
if V.equal v2 v2' then (v1, l, v2') :: acc else acc)
(HM.find v1 g)
[]
with Not_found ->
[]
let unsafe_remove_edge g v1 v2 =
HM.add
v1
(S.filter (fun (v2', _) -> not (V.equal v2 v2')) (HM.find v1 g))
g
let unsafe_remove_edge_e g (v1, l, v2) =
HM.add v1 (S.remove (v2, l) (HM.find v1 g)) g
let remove_edge g v1 v2 =
if not (HM.mem v2 g) then invalid_arg "[ocamlgraph] remove_edge";
HM.add
v1
(S.filter
(fun (v2', _) -> not (V.equal v2 v2'))
(HM.find_and_raise v1 g "[ocamlgraph] remove_edge"))
g
let remove_edge_e g (v1, l, v2) =
if not (HM.mem v2 g) then invalid_arg "[ocamlgraph] remove_edge_e";
HM.add
v1
(S.remove (v2, l) (HM.find_and_raise v1 g "[ocamlgraph] remove_edge_e"))
g
let iter_succ f g v =
S.iter (fun (w, _) -> f w) (HM.find_and_raise v g "[ocamlgraph] iter_succ")
let fold_succ f g v =
S.fold (fun (w, _) -> f w) (HM.find_and_raise v g "[ocamlgraph] fold_succ")
let iter_succ_e f g v =
S.iter
(fun (w, l) -> f (v, l, w))
(HM.find_and_raise v g "[ocamlgraph] iter_succ_e")
let fold_succ_e f g v =
S.fold
(fun (w, l) -> f (v, l, w))
(HM.find_and_raise v g "[ocamlgraph] fold_succ_e")
let succ g v = fold_succ (fun w l -> w :: l) g v []
let succ_e g v = fold_succ_e (fun e l -> e :: l) g v []
let map_vertex f =
HM.map
(fun v s -> f v, S.fold (fun (v, l) s -> S.add (f v, l) s) s S.empty)
module I = struct
type t = S.t HM.t
module PV = V
module PE = E
let iter_edges f = HM.iter (fun v -> S.iter (fun (w, _) -> f v w))
let fold_edges f = HM.fold (fun v -> S.fold (fun (w, _) -> f v w))
let iter_edges_e f =
HM.iter (fun v -> S.iter (fun (w, l) -> f (v, l, w)))
let fold_edges_e f =
HM.fold (fun v -> S.fold (fun (w, l) -> f (v, l, w)))
end
include I
include Pred(struct include I let mem_vertex = HM.mem end)
end
(** The vertex module and the vertex table for the concrete graphs. *)
module ConcreteVertex(F : TBL_BUILDER)(V: COMPARABLE) = struct
module V = struct
include V
type label = t
let label v = v
let create v = v
end
module HM = F(V)
end
module Make_Abstract
(G: sig
module HM: HM
module S: Set.S
include G with type t = S.t HM.t and type V.t = HM.key
val remove_edge: t -> vertex -> vertex -> t
val remove_edge_e: t -> edge -> t
(* val unsafe_add_vertex: t -> vertex -> t *) (* Was unused *)
val unsafe_add_edge: t -> vertex -> S.elt -> t
val unsafe_remove_edge: t -> vertex -> vertex -> t
val unsafe_remove_edge_e: t -> edge -> t
val create: ?size:int -> unit -> t
val clear: t -> unit
end) =
struct
module I = struct
type t = { edges : G.t; mutable size : int }
(* BE CAREFUL: [size] is only mutable in the imperative version. As
there is no extensible records in current ocaml version, and for
genericity purpose, [size] is mutable in both imperative and
persistent implementations.
Do not modify size in the persistent implementation! *)
type vertex = G.vertex
type edge = G.edge
module PV = G.V
module PE = G.E
let iter_edges f g = G.iter_edges f g.edges
let fold_edges f g = G.fold_edges f g.edges
let iter_edges_e f g = G.iter_edges_e f g.edges
let fold_edges_e f g = G.fold_edges_e f g.edges
let mem_vertex v g = G.mem_vertex g.edges v
let create ?size () = { edges = G.create ?size (); size = 0 }
let clear g = G.clear g.edges; g.size <- 0
end
include I
include Pred(I)
(* optimisations *)
let is_empty g = g.size = 0
let nb_vertex g = g.size
(* redefinitions *)
module V = G.V
module E = G.E
module HM = G.HM
module S = G.S
let unsafe_add_edge = G.unsafe_add_edge
let unsafe_remove_edge = G.unsafe_remove_edge
let unsafe_remove_edge_e = G.unsafe_remove_edge_e
let is_directed = G.is_directed
let remove_edge g = G.remove_edge g.edges
let remove_edge_e g = G.remove_edge_e g.edges
let out_degree g = G.out_degree g.edges
let in_degree g = G.in_degree g.edges
let nb_edges g = G.nb_edges g.edges
let succ g = G.succ g.edges
let mem_vertex g = G.mem_vertex g.edges
let mem_edge g = G.mem_edge g.edges
let mem_edge_e g = G.mem_edge_e g.edges
let find_edge g = G.find_edge g.edges
let find_all_edges g = G.find_all_edges g.edges
let iter_vertex f g = G.iter_vertex f g.edges
let fold_vertex f g = G.fold_vertex f g.edges
let iter_succ f g = G.iter_succ f g.edges
let fold_succ f g = G.fold_succ f g.edges
let succ_e g = G.succ_e g.edges
let iter_succ_e f g = G.iter_succ_e f g.edges
let fold_succ_e f g = G.fold_succ_e f g.edges
let map_vertex f g = { g with edges = G.map_vertex f g.edges }
(* reimplementation *)
let copy g =
let h = HM.create () in
let vertex v =
try
HM.find v h
with Not_found ->
let v' = V.create (V.label v) in
let h' = HM.add v v' h in
assert (h == h');
v'
in
map_vertex vertex g
end
(** Support for explicitly maintaining edge set of
predecessors. Crucial for algorithms that do a lot of backwards
traversal. *)
module BidirectionalMinimal(S:Set.S)(HM:HM) = struct
type vertex = HM.key
let is_directed = true
let empty = HM.empty
let create = HM.create
let clear = HM.clear
let is_empty = HM.is_empty
let copy = HM.copy
let nb_vertex g = HM.fold (fun _ _ -> succ) g 0
let nb_edges g = HM.fold (fun _ (_,s) n -> n + S.cardinal s) g 0
let out_degree g v =
S.cardinal
(snd (try HM.find v g
with Not_found -> invalid_arg "[ocamlgraph] out_degree"))
let mem_vertex g v = HM.mem v g
let unsafe_add_vertex g v = HM.add v (S.empty, S.empty) g
let add_vertex g v = if HM.mem v g then g else unsafe_add_vertex g v
let iter_vertex f = HM.iter (fun v _ -> f v)
let fold_vertex f = HM.fold (fun v _ -> f v)
end
module BidirectionalUnlabeled(V:COMPARABLE)(HM:HM with type key = V.t) = struct
module S = Set.Make(V)
module E = struct
type vertex = V.t
include OTProduct(V)(V)
let src = fst
let dst = snd
type label = unit
let label _ = ()
let create v1 () v2 = v1, v2
end
type edge = E.t
let mem_edge g v1 v2 =
try S.mem v2 (snd (HM.find v1 g))
with Not_found -> false
let mem_edge_e g (v1,v2) = mem_edge g v1 v2
let find_edge g v1 v2 = if mem_edge g v1 v2 then v1, v2 else raise Not_found
let find_all_edges g v1 v2 = try [ find_edge g v1 v2 ] with Not_found -> []
let unsafe_remove_edge g v1 v2 =
let in_set, out_set = HM.find v1 g in
let g = HM.add v1 (in_set, S.remove v2 out_set) g in
let in_set, out_set = HM.find v2 g in
HM.add v2 (S.remove v1 in_set, out_set) g
let unsafe_remove_edge_e g (v1,v2) = unsafe_remove_edge g v1 v2
let remove_edge g v1 v2 =
if not (HM.mem v2 g && HM.mem v1 g) then
invalid_arg "[ocamlgraph] remove_edge";
unsafe_remove_edge g v1 v2
let remove_edge_e g (v1, v2) = remove_edge g v1 v2
let iter_succ f g v =
S.iter f (snd (HM.find_and_raise v g "[ocamlgraph] iter_succ"))
let fold_succ f g v =
S.fold f (snd (HM.find_and_raise v g "[ocamlgraph] fold_succ"))
let iter_succ_e f g v = iter_succ (fun v2 -> f (v, v2)) g v
let fold_succ_e f g v = fold_succ (fun v2 -> f (v, v2)) g v
let succ g v = S.elements (snd (HM.find_and_raise v g "[ocamlgraph] succ"))
let succ_e g v = fold_succ_e (fun e l -> e :: l) g v []
let map_vertex f =
HM.map
(fun v (s1,s2) ->
f v,
(S.fold (fun v s -> S.add (f v) s) s1 S.empty,
S.fold (fun v s -> S.add (f v) s) s2 S.empty))
module I = struct
(* we keep sets for both incoming and outgoing edges *)
type t = (S.t (* incoming *) * S.t (* outgoing *)) HM.t
module PV = V
module PE = E
let iter_edges f = HM.iter (fun v (_, outset) -> S.iter (f v) outset)
let fold_edges f = HM.fold (fun v (_, outset) -> S.fold (f v) outset)
let iter_edges_e f = iter_edges (fun v1 v2 -> f (v1, v2))
let fold_edges_e f = fold_edges (fun v1 v2 a -> f (v1, v2) a)
end
include I
let iter_pred f g v =
S.iter f (fst (HM.find_and_raise v g "[ocamlgraph] iter_pred"))
let fold_pred f g v =
S.fold f (fst (HM.find_and_raise v g "[ocamlgraph] fold_pred"))
let pred g v = S.elements (fst (HM.find_and_raise v g "[ocamlgraph] pred"))
let in_degree g v =
S.cardinal
(fst (try HM.find v g
with Not_found -> invalid_arg "[ocamlgraph] in_degree"))
let iter_pred_e f g v = iter_pred (fun v2 -> f (v2, v)) g v
let fold_pred_e f g v = fold_pred (fun v2 -> f (v2, v)) g v
let pred_e g v = fold_pred_e (fun e l -> e :: l) g v []
end
module BidirectionalLabeled
(V:COMPARABLE)(E:ORDERED_TYPE)(HM:HM with type key = V.t) =
struct
module VE = OTProduct(V)(E)
module S = Set.Make(VE)
module E = struct
type vertex = V.t
type label = E.t
type t = vertex * label * vertex
let src (v, _, _) = v
let dst (_, _, v) = v
let label (_, l, _) = l
let create v1 l v2 = v1, l, v2
module C = OTProduct(V)(VE)
let compare (x1, x2, x3) (y1, y2, y3) =
C.compare (x1, (x3, x2)) (y1, (y3, y2))
end
type edge = E.t
let mem_edge g v1 v2 =
try S.exists (fun (v2', _) -> V.equal v2 v2') (snd (HM.find v1 g))
with Not_found -> false
let mem_edge_e g (v1, l, v2) =
try
let ve = v2, l in
S.exists (fun ve' -> VE.compare ve ve' = 0) (snd (HM.find v1 g))
with Not_found ->
false
exception Found of edge
let find_edge g v1 v2 =
try
S.iter
(fun (v2', l) -> if V.equal v2 v2' then raise (Found (v1, l, v2')))
(snd (HM.find v1 g));
raise Not_found
with Found e ->
e
let find_all_edges g v1 v2 =
try
S.fold
(fun (v2', l) acc ->
if V.equal v2 v2' then (v1, l, v2') :: acc else acc)
(snd (HM.find v1 g))
[]
with Not_found ->
[]
let unsafe_remove_edge g v1 v2 =
let in_set, out_set = HM.find v1 g in
let del v set = S.filter (fun (v', _) -> not (V.equal v v')) set in
let g = HM.add v1 (in_set, del v2 out_set) g in
let in_set, out_set = HM.find v2 g in
HM.add v2 (del v1 in_set, out_set) g
let unsafe_remove_edge_e g (v1, l, v2) =
let in_set, out_set = HM.find v1 g in
let g = HM.add v1 (in_set, S.remove (v2, l) out_set) g in
let in_set, out_set = HM.find v2 g in
HM.add v2 (S.remove (v1, l) in_set, out_set) g
let remove_edge g v1 v2 =
(* if not (HM.mem v2 g) then invalid_arg "[ocamlgraph] remove_edge";*)
let in_set, out_set = HM.find_and_raise v1 g "[ocamlgraph] remove_edge" in
let del v set = S.filter (fun (v', _) -> not (V.equal v v')) set in
let g = HM.add v1 (in_set, del v2 out_set) g in
let in_set, out_set = HM.find_and_raise v2 g "[ocamlgraph] remove_edge" in
HM.add v2 (del v1 in_set, out_set) g
let remove_edge_e g (v1, l, v2) =
(* if not (HM.mem v2 g) then invalid_arg "[ocamlgraph] remove_edge_e";*)
let in_set, out_set = HM.find_and_raise v1 g "[ocamlgraph] remove_edge_e" in
let g = HM.add v1 (in_set, S.remove (v2, l) out_set) g in
let in_set, out_set = HM.find_and_raise v2 g "[ocamlgraph] remove_edge_e" in
HM.add v2 (S.remove (v1, l) in_set, out_set) g
let iter_succ f g v =
S.iter
(fun (w, _) -> f w)
(snd (HM.find_and_raise v g "[ocamlgraph] iter_succ"))
let fold_succ f g v =
S.fold
(fun (w, _) -> f w)
(snd (HM.find_and_raise v g "[ocamlgraph] fold_succ"))
let iter_succ_e f g v =
S.iter
(fun (w, l) -> f (v, l, w))
(snd (HM.find_and_raise v g "[ocamlgraph] iter_succ_e"))
let fold_succ_e f g v =
S.fold
(fun (w, l) -> f (v, l, w))
(snd (HM.find_and_raise v g "[ocamlgraph] fold_succ_e"))
let succ g v = fold_succ (fun w l -> w :: l) g v []
let succ_e g v = fold_succ_e (fun e l -> e :: l) g v []
let map_vertex f =
HM.map
(fun v (s1,s2) ->
f v,
(S.fold (fun (v, l) s -> S.add (f v, l) s) s1 S.empty,
S.fold (fun (v, l) s -> S.add (f v, l) s) s2 S.empty))
module I = struct
type t = (S.t * S.t) HM.t
module PV = V
module PE = E
let iter_edges f = HM.iter (fun v (_,outset) ->
S.iter (fun (w, _) -> f v w) outset)
let fold_edges f = HM.fold (fun v (_,outset) ->
S.fold (fun (w, _) -> f v w) outset)
let iter_edges_e f = HM.iter (fun v (_,outset) ->
S.iter (fun (w, l) -> f (v, l, w)) outset)
let fold_edges_e f = HM.fold (fun v (_,outset) ->
S.fold (fun (w, l) -> f (v, l, w)) outset)
end
include I
let iter_pred f g v =
S.iter
(fun (w, _) -> f w)
(fst (HM.find_and_raise v g "[ocamlgraph] iter_pred"))
let fold_pred f g v =
S.fold
(fun (w, _) -> f w)
(fst (HM.find_and_raise v g "[ocamlgraph] fold_pred"))
let in_degree g v =
S.cardinal
(fst (try HM.find v g
with Not_found -> invalid_arg "[ocamlgraph] in_degree"))
let iter_pred_e f g v =
S.iter
(fun (w, l) -> f (w, l, v))
(fst (HM.find_and_raise v g "[ocamlgraph] iter_pred_e"))
let fold_pred_e f g v =
S.fold
(fun (w, l) -> f (w, l, v))
(fst (HM.find_and_raise v g "[ocamlgraph] fold_pred_e"))
let pred g v = fold_pred (fun w l -> w :: l) g v []
let pred_e g v = fold_pred_e (fun e l -> e :: l) g v []
end
(** Build persistent (resp. imperative) graphs from a persistent (resp.
imperative) association table *)
module Make(F : TBL_BUILDER) = struct
module Digraph = struct
module Concrete(V: COMPARABLE) = struct
include ConcreteVertex(F)(V)
include Unlabeled(V)(HM)
include Minimal(S)(HM)
let add_edge g v1 v2 =
if mem_edge g v1 v2 then g
else
let g = add_vertex g v1 in
let g = add_vertex g v2 in
unsafe_add_edge g v1 v2
let add_edge_e g (v1, v2) = add_edge g v1 v2
end
module ConcreteBidirectional(V: COMPARABLE) = struct
include ConcreteVertex(F)(V)
include BidirectionalUnlabeled(V)(HM)
include BidirectionalMinimal(S)(HM)
let unsafe_add_edge g v1 v2 =
let find v g = try HM.find v g with Not_found -> S.empty, S.empty in
let in_set, out_set = find v1 g in
let g = HM.add v1 (in_set,S.add v2 out_set) g in
let in_set, out_set = find v2 g in
HM.add v2 (S.add v1 in_set,out_set) g
let add_edge g v1 v2 =
if mem_edge g v1 v2 then g
else unsafe_add_edge g v1 v2
let add_edge_e g (v1, v2) = add_edge g v1 v2
end
module ConcreteLabeled(V: COMPARABLE)(Edge: ORDERED_TYPE_DFT) = struct
include ConcreteVertex(F)(V)
include Labeled(V)(Edge)(HM)
include Minimal(S)(HM)
let add_edge_e g (v1, l, v2 as e) =
if mem_edge_e g e then g
else
let g = add_vertex g v1 in
let g = add_vertex g v2 in
unsafe_add_edge g v1 (v2, l)
let add_edge g v1 v2 = add_edge_e g (v1, Edge.default, v2)
end
module ConcreteBidirectionalLabeled
(V: COMPARABLE)(Edge: ORDERED_TYPE_DFT) =
struct
include ConcreteVertex(F)(V)
include BidirectionalLabeled(V)(Edge)(HM)
include BidirectionalMinimal(S)(HM)
let unsafe_add_edge_e g (v1, l, v2) =
let find v g = try HM.find v g with Not_found -> S.empty, S.empty in
let in_set, out_set = find v1 g in
let g = HM.add v1 (in_set,S.add (v2,l) out_set) g in
let in_set, out_set = find v2 g in
HM.add v2 (S.add (v1,l) in_set,out_set) g
let add_edge_e g e = if mem_edge_e g e then g else unsafe_add_edge_e g e
let add_edge g v1 v2 = add_edge_e g (v1, Edge.default, v2)
end
module Abstract(V: VERTEX) = struct
module G = struct
module V = V
module HM = F(V)
include Unlabeled(V)(HM)
include Minimal(S)(HM)
end
include Make_Abstract(G)
end
module AbstractLabeled(V: VERTEX)(E: ORDERED_TYPE_DFT) = struct
module G = struct
module V = V
module HM = F(V)
include Labeled(V)(E)(HM)
include Minimal(S)(HM)
end
include Make_Abstract(G)
end
end
end
(** Implementation of undirected graphs from implementation of directed
graphs. *)
module Graph
(G: sig
include Sig.G
val create: ?size:int -> unit -> t
val clear: t -> unit
val copy: t -> t
type return
val add_vertex: t -> vertex -> return
val remove_vertex: t -> vertex -> return
end) =
struct
include G
let is_directed = false
(* Redefine iterators and [nb_edges]. *)
let iter_edges f =
iter_edges (fun v1 v2 -> if V.compare v1 v2 >= 0 then f v1 v2)
let fold_edges f =
fold_edges
(fun v1 v2 acc -> if V.compare v1 v2 >= 0 then f v1 v2 acc else acc)
let iter_edges_e f =
iter_edges_e (fun e -> if V.compare (E.src e) (E.dst e) >= 0 then f e)
let fold_edges_e f =
fold_edges_e
(fun e acc ->
if V.compare (E.src e) (E.dst e) >= 0 then f e acc else acc)
let nb_edges g = fold_edges_e (fun _ -> (+) 1) g 0
(* Redefine operations on predecessors:
predecessors are successors in an undirected graph. *)
let pred = succ
let in_degree = out_degree
let iter_pred = iter_succ
let fold_pred = fold_succ
let pred_e = succ_e
let iter_pred_e = iter_succ_e
let fold_pred_e = fold_succ_e
end
(*
Local Variables:
compile-command: "make -C .."
End:
*)
ocamlgraph-2.0.0/src/fixpoint.ml 0000644 0001750 0000144 00000014140 13735627615 015172 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(* Copyright (c) 2010 - 2012 Technische Universitaet Muenchen
* Markus W. Weissmann
* All rights reserved. *)
(* maximum fixpoint point calculation with the work list algorithm;
to implement a concrete analysis, implement a module that satisfies
the Rules signature. Such a module in the Analysis functor gives a
complete analysis/optimization module that works on a CFG.
*)
type direction = Forward | Backward
module type Analysis = sig
type data
type edge
type vertex
type g
val direction : direction
val join : data -> data -> data
val equal : data -> data -> bool
val analyze : edge -> data -> data
end
(** Minimal graph signature for work list algorithm *)
module type G = sig
type t
module V : Sig.COMPARABLE
module E : sig
type t
val dst : t -> V.t
val src : t -> V.t
end
val fold_vertex : (V.t -> 'a -> 'a) -> t -> 'a -> 'a
val succ_e : t -> V.t -> E.t list
val pred_e : t -> V.t -> E.t list
val succ : t -> V.t -> V.t list
val pred : t -> V.t -> V.t list
end
module Make
(G : G)
(A : Analysis with type g = G.t with type edge = G.E.t
with type vertex = G.V.t) =
struct
module M = Map.Make(G.V)
module N = Set.Make(G.V)
let analyze initial g =
let (nodes, data) =
G.fold_vertex
(fun vertex (n, m) ->
(N.add vertex n, M.add vertex (initial vertex) m))
g (N.empty, M.empty)
in
(* generate an associative map to quickly find the incoming
* (outgoing) edges of a node during the anaysis store a pair of
* a partially applied analysis function and the corresponding
* 'partner' node *)
let nodemap : ((A.data -> A.data) * G.V.t) list M.t =
let add = match A.direction with
| Forward ->
(fun n ->
let preds = G.pred_e g n in
List.map
(fun edge -> (A.analyze edge, G.E.src edge))
preds)
| Backward ->
(fun n ->
let succs = G.succ_e g n in
List.map
(fun edge -> (A.analyze edge, G.E.dst edge))
succs)
in
G.fold_vertex (fun vertex m -> M.add vertex (add vertex) m) g M.empty
in
let rec worklist (data : A.data M.t) (wl : N.t) =
(* 'meet' an arbitrary number of data-sets *)
let meet initial xs = List.fold_left A.join initial xs
in
(* analyze one node, creating a new data-set and node-worklist
as necessary *)
let analyze_node analysis n d wl =
match analysis d n with
| None -> (d, wl)
| Some d' -> (d', N.add n wl)
in
(* get some node from the node-set -- this will eventually trigger
an exception *)
match (try Some (N.choose wl) with Not_found -> None) with
| None -> data
| Some n ->
(* remove the chosen node from the set *)
let wl = N.remove n wl in
let (f, ns) = match A.direction with
(* analyze all INCOMING edges of all SUCCESSOR nodes of the
node to be processed *)
| Forward ->
(* process one node: analyze all it's incoming edges
and merge the resulting data;
if the result is different to the previously stored data
for this node, return a new tuple, else None *)
let new_node_data (data : A.data M.t) node =
let edges = M.find node nodemap in
let analysis =
List.map
(fun (f, src) -> f (M.find src data)) edges
in
let node_data = M.find node data in
let node_data' = meet (initial node) analysis in
if A.equal node_data node_data' then None
else Some (M.add node node_data' data)
in
(new_node_data, G.succ g n)
(* analyze all OUTGOING edges of all PREDECESSOR nodes
of the node to be processed *)
| Backward ->
let new_node_data (data : A.data M.t) node =
let edges = M.find node nodemap in
let analysis =
List.map
(fun (f, dst) -> f (M.find dst data)) edges
in
let node_data = M.find node data in
let node_data' = meet (initial node) analysis in
if A.equal node_data node_data' then None
else Some (M.add node node_data' data)
in
(new_node_data, G.pred g n)
in
(* analyze all successor nodes by analyzing all of their
predecessor edges *)
let (data, wl) =
List.fold_left (fun (d, wl) n -> analyze_node f n d wl)
(data, wl) ns
in
(* do a recursive call: the recursion will eventually end with a
* Not_found exception when no nodes are left in the work list *)
worklist data wl
in
let data = worklist data nodes in
(fun n -> M.find n data)
end
ocamlgraph-2.0.0/src/leaderlist.ml 0000644 0001750 0000144 00000007007 13735627615 015466 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(* Copyright (c) 2010 - 2011 Technische Universitaet Muenchen
* Markus W. Weissmann
* Florian Pichlmeier
* All rights reserved. *)
(* Minimal graph signature for leader list algorithm *)
module type G = sig
type t
module V : Sig.COMPARABLE
val fold_vertex : (V.t -> 'a -> 'a) -> t -> 'a -> 'a
val succ : t -> V.t -> V.t list
val pred : t -> V.t -> V.t list
end
module Make
(G : G) =
struct
module S = Set.Make(G.V)
let leader_lists g root =
(* partition all vertices into two Sets *)
let partition_vertices f g =
G.fold_vertex
(fun n (s1, s2) ->
if f n then (S.add n s1, s2) else (s1, S.add n s2))
g (S.empty, S.empty)
in
(* predicate to determine if a node is a leader *)
let is_leader n =
if G.V.equal n root then true (* the root node is always a leader *)
else
match G.pred g n with
| [] ->
true
(* this would be dead code --
it has no predecessor so make it a leader anyway *)
| x::[] -> begin match G.succ g x with
| [] ->
assert false (* -> inconsistency in the graph implementation *)
| _::[] ->
false (* this is a straight, continuous control flow *)
| _ ->
true (* predecessor has multiple successors *)
end
| _ -> true (* more than one predecessor *)
in
let (leader, entourage) = partition_vertices is_leader g in
(* build a basic block *)
let basic_block x =
let rec basic_block x bb =
match G.succ g x with
| [] -> x::bb (* no successors -- end of basic block *)
| y::_ -> begin match S.mem y entourage with
| true ->
(* successor is not a leader, continue collecting *)
basic_block y (x::bb)
| false ->
x :: bb (* successor is a leader -- end of basic block *)
end
in
(* blocks a are built in reverse order for performance reasons --
correct that *)
List.rev (basic_block x [])
in
let basic_block_list = S.fold (fun x ss -> (basic_block x)::ss) leader [] in
List.rev basic_block_list
(* this will bring the head of the lists in ascending order --
as given by Set.S *)
end
ocamlgraph-2.0.0/src/dGraphTreeLayout.ml 0000644 0001750 0000144 00000076562 13735627615 016575 0 ustar rt users (**************************************************************************)
(* *)
(* This file is part of OcamlGraph. *)
(* *)
(* Copyright (C) 2009-2010 *)
(* CEA (Commissariat � l'�nergie Atomique) *)
(* *)
(* you can redistribute it and/or modify it under the terms of the GNU *)
(* Lesser General Public License as published by the Free Software *)
(* Foundation, version 2.1, with a linking exception. *)
(* *)
(* It 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. See the *)
(* GNU Lesser General Public License for more details. *)
(* *)
(* See the file ../LICENSE for more details. *)
(* *)
(* Authors: *)
(* - Julien Signoles (Julien.Signoles@cea.fr) *)
(* - Jean-Denis Koeck (jdkoeck@gmail.com) *)
(* - Benoit Bataille (benoit.bataille@gmail.com) *)
(* *)
(**************************************************************************)
let set_if_none field value = match field with
| None -> Some value
| Some a -> Some a
let the = function None -> assert false | Some a -> a
type cluster = string
module Build
(G: Graphviz.GraphWithDotAttrs)
(TreeManipulation: sig val is_ghost_node: G.V.t -> bool end) =
struct
module Layout = struct
include XDot.Make(G)
open XDot
type t = graph_layout =
{ vertex_layouts : node_layout HV.t;
edge_layouts : edge_layout HE.t;
cluster_layouts : (string, cluster_layout) Hashtbl.t;
bbox : bounding_box }
end
open Layout
type geometry_info = {
dimensions : (float * float) HV.t;
position : (float * float) HV.t;
mutable x_offset : float;
mutable y_offset : int;
}
let get_position v geometry_info =
try HV.find geometry_info.position v
with Not_found -> assert false
let get_dimensions v geometry_info =
try HV.find geometry_info.dimensions v
with Not_found -> assert false
let set_offset geometry_info =
geometry_info.y_offset <- 150;
geometry_info.x_offset <-
HV.fold (fun _ (w, _) maxw -> max w maxw)
geometry_info.dimensions 0.
(* Calculate node positions for a tree *)
let fill_tree_positions tree root iter_fun fold_fun table geometry_info =
let vertex_x_space = 10. in
let stack = Stack.create () in
let fill_stack tree root =
let stack_queue = Queue.create () in
let rec flush_queue queue =
if not(Queue.is_empty queue) then begin
let elem, depth = Queue.take queue in
iter_fun (fun v -> Queue.add (v, depth + 1) queue) tree elem;
Stack.push (elem,depth) stack;
flush_queue queue
end
in
Queue.add (root, 0) stack_queue;
flush_queue stack_queue;
in
fill_stack tree root;
let offset = ref geometry_info.x_offset in
let max_depth = snd (Stack.top stack) in
let rec flush_stack stack =
if not (Stack.is_empty stack) then begin
let elem, depth = Stack.pop stack in
if depth = max_depth then begin
HV.add table elem (!offset, depth);
offset := !offset +. geometry_info.x_offset +. vertex_x_space;
end else begin
let sum, cpt =
fold_fun
(fun v (sum, cpt) ->
let (x, _) =
try HV.find table v with Not_found -> assert false
in
sum +. x, cpt +. 1.)
tree
elem
(0., 0.)
in
assert (cpt <> 0.);
HV.add table elem (sum /. cpt, depth)
end;
flush_stack stack
end
in
flush_stack stack
(* Bind two tree position tables together *)
let bind_tree_tables forward_table backward_table root geometry_info =
(* Using dimension is required in order to be put at the middle of the
canvas.*)
let max_fwd, max_dim_fwd =
HV.fold
(fun v (_, y) (max_y, max_dimy as acc) ->
if TreeManipulation.is_ghost_node v then acc
else (*max y max_y*)
if y < max_y then acc
else
let _, dimy = get_dimensions v geometry_info in
(*[BM] why 1.5? *)
let dimy = dimy *. 1.5 in
y, if y = max_y then max max_dimy dimy else dimy)
forward_table
(0, 0.)
in
HV.iter
(fun v (x, y) ->(*[BM]: why 0.5 and 1.5 ??? *)
HV.add
geometry_info.position
v
(x, ((float (max_fwd + y)) -. 0.5) *. float geometry_info.y_offset
-. 1.5 *. max_dim_fwd))
backward_table;
HV.iter
(fun v (x, y) ->(*[BM]: why 0.5 and 1.5 ??? *)
HV.add
geometry_info.position
v
(x, ((float (max_fwd - y)) -. 0.5) *. float geometry_info.y_offset
-. 1.5 *. max_dim_fwd))
forward_table;
HV.remove geometry_info.position root
(* DRAW OPERATIONS *)
(* Convert an int in hexadecimal representing a color in rgb format to a
string prefixed by # *)
let string_color i = Printf.sprintf "#%06X" i
let string_color32 i = Printf.sprintf "#%08lX" i
(** @return an array of positions to draw an edge from positions and
dimensions of vertices *)
let edge_to_posarray src dst geometry_info =
let xsrc, ysrc = get_position src geometry_info in
let _, hsrc = get_dimensions src geometry_info in
let xdst, ydst = get_position dst geometry_info in
let _, hdst = get_dimensions dst geometry_info in
let ystart = ysrc -. hsrc/.2. and yend = ydst +. hdst/. 2. in
(* Bezier intermediate points. *)
let xdec = (xdst -. xsrc)/.4.0 in
let ydec = (ydst -. ysrc)/.4.0 in
(* Format.printf "%f %f %f@." ystart yend ydec;*)
[| xsrc, ystart;
xsrc +. xdec, ystart +. ydec;
xdst -. xdec, yend -. ydec;
xdst, yend |]
(** @return an array to draw an arrow from start and end positions of the
edge *)
let edge_to_arrow (x1, y1) (x2, y2) =
let warrow = 4. in (* Half-width of the arrow *)
let harrow = 10. in (* Height of the arrow *)
let dx = x2 -. x1 in
let dy = y1 -. y2 in
let d = sqrt (dx *. dx +. dy *. dy) in
let xp1 = -. (harrow *. dx +. warrow *. dy) /. d +. x2 in
let yp1 = (harrow *. dy -. warrow *. dx) /. d +. y2 in
let xp2 = (warrow *. dy -. harrow *. dx) /. d +. x2 in
let yp2 = (warrow *. dx +. harrow *. dy) /. d +. y2 in
[ XDotDraw.Filled_polygon [| x2, y2; xp1, yp1; xp2, yp2 |] ]
end
(* FROM GRAPH *)
module Make
(Tree: Graphviz.GraphWithDotAttrs)
(TreeManipulation: sig val is_ghost_node: Tree.V.t -> bool end) =
struct
include Build(Tree)(TreeManipulation)
open Layout
(* PARSE VERTICES ATTRIBUTES *)
type vattributes = {
(* See graphviz.mli for the meaning of each options *)
mutable color : int32 option;
mutable fontcolor : int option;
mutable fontname : string option;
mutable fontsize : int option;
mutable height : float option;
mutable label : string option;
mutable html_label : string option;
mutable orientation : float option;
mutable peripheries : int option;
mutable regular : bool option;
mutable shape : [ `Ellipse | `Box | `Circle | `Doublecircle | `Diamond
| `Oval | `Egg | `Triangle | `Invtriangle
| `Trapezium | `Invtrapezium
| `House | `Invhouse
| `Oval | `Egg | `Triangle | `Invtriangle
| `Trapezium | `Invtrapezium
| `House | `Invhouse
| `Parallelogram | `Doubleoctagon | `Tripleoctagon
| `Mdiamond | `Mcircle | `Msquare
| `Star | `Underline
| `Note | `Tab | `Folder
| `Box3d | `Component | `Promoter
| `Cds
| `Terminator | `Utr | `Primersite
| `Restrictionsite
| `Fivepoverhang | `Threepoverhang | `Noverhang
| `Assembly | `Signature | `Insulator | `Ribosite | `Rnastab
| `Proteasesite | `Proteinstab | `Rpromoter | `Rarrow
| `Larrow | `Lpromoter
| `Plaintext | `Record | `Polygon of int * float ] option;
mutable style : [ `Rounded | `Filled | `Solid | `Dashed | `Dotted | `Bold
| `Invis ] list;
mutable width : float option;
mutable fillcolor : int32 option;
}
let set_vattribute vattrs : Graphviz.DotAttributes.vertex -> _ = function
| `Color c ->
vattrs.color <-
set_if_none vattrs.color (Graphviz.color_to_color_with_transparency c)
| `ColorWithTransparency c -> vattrs.color <- set_if_none vattrs.color c
| `Fontcolor c -> vattrs.fontcolor <- set_if_none vattrs.fontcolor c
| `Fontname n -> vattrs.fontname <- set_if_none vattrs.fontname n
| `Fontsize s -> vattrs.fontsize <- set_if_none vattrs.fontsize s
| `Height h -> vattrs.height <- set_if_none vattrs.height h
| `Label label -> vattrs.label <- set_if_none vattrs.label label
| `HtmlLabel l -> vattrs.html_label <- set_if_none vattrs.html_label l
| `Orientation o -> vattrs.orientation <- set_if_none vattrs.orientation o
| `Peripheries p -> vattrs.peripheries <- set_if_none vattrs.peripheries p
| `Regular r -> vattrs.regular <- set_if_none vattrs.regular r
| `Shape shape -> vattrs.shape <- set_if_none vattrs.shape shape
| `Style s -> vattrs.style <- s :: vattrs.style
| `Width w -> vattrs.width <- set_if_none vattrs.width w
| `Fillcolor c ->
vattrs.fillcolor <- set_if_none vattrs.fillcolor
(Graphviz.color_to_color_with_transparency c)
| `FillcolorWithTransparency c ->
vattrs.fillcolor <- set_if_none vattrs.fillcolor c
| `Comment _ | `Distortion _ | `Fixedsize _ | `Layer _ | `Penwidth _
| `Url _ | `Z _ ->
() (* TODO *)
let attributes_list_to_vattributes vattrs =
List.iter (set_vattribute vattrs)
let fill_vattributes tree vattributes =
let vertex_to_vattrs v =
let vattrs = {
color = None;
fontcolor = None;
fontname = None;
fontsize = None;
height = None;
label = None;
html_label = None;
orientation = None;
peripheries = None;
regular = None;
shape = None;
style = [];
width = None;
fillcolor = None
} in
let dgraph_layout_default =
[ `Color 0xFFFFFF; `Fontcolor 0x000000; `Fontname "Sans";
`Fontsize 12; `Height 0.; `Label (Tree.vertex_name v);
`Orientation 0.; `Peripheries 1; `Regular false; `Shape `Ellipse;
`Width 0.; `Fillcolor 0xFFFFFF ]
in
attributes_list_to_vattributes vattrs
(Tree.vertex_attributes v
@ Tree.default_vertex_attributes tree
@ dgraph_layout_default);
vattrs
in
Tree.iter_vertex (fun v -> HV.add vattributes v (vertex_to_vattrs v)) tree
(* PLACE VERTICES *)
(* Calculate dimension of a string in pixel *)
let calc_dimensions
~fontMeasure
font
ptsize
s
=
let width_margin = 20. in
let height_margin = 0. in
let width, height = fontMeasure ~fontName:font ~fontSize:ptsize s in
float width +. width_margin, float height +. height_margin
let fill_dimensions ~fontMeasure tree vattributes geometry_info =
let add_vertex_dimensions v =
let vattrs = try HV.find vattributes v with Not_found -> assert false in
let minwidth, minheight = the vattrs.width, the vattrs.height in
let truewidth, trueheight =
calc_dimensions
~fontMeasure
(the vattrs.fontname)
(the vattrs.fontsize)
(the vattrs.label)
in
let width = max minwidth truewidth in
let height = max minheight trueheight in
HV.replace geometry_info.dimensions v (width, height)
in
Tree.iter_vertex add_vertex_dimensions tree
let fill_position tree root geometry_info =
let forward_table = HV.create 97 in
let backward_table = HV.create 97 in
fill_tree_positions tree root Tree.iter_succ Tree.fold_succ forward_table
geometry_info;
fill_tree_positions tree root Tree.iter_pred Tree.fold_pred backward_table
geometry_info;
bind_tree_tables forward_table backward_table root geometry_info
(* BUILD LAYOUT - ADD DRAW OPERATIONS *)
let style_to_style_attr = function
| `Filled -> XDotDraw.Filled
| `Solid -> XDotDraw.Solid
| `Dashed -> XDotDraw.Dashed
| `Dotted -> XDotDraw.Dotted
| `Bold -> XDotDraw.Bold
| `Invis -> XDotDraw.Invisible
| `Rounded -> XDotDraw.Rounded
(* FOR VERTEX *)
let shape_to_operations v vattrs geometry_info shape =
let width, height =
let a, b = get_dimensions v geometry_info in
a /. 2., b
in
let position = get_position v geometry_info in
let filled = List.mem `Filled vattrs.style in
match shape with
| `Ellipse ->
if filled then [ XDotDraw.Filled_ellipse (position,width,height) ]
else [ XDotDraw.Unfilled_ellipse (position,width,height) ]
| `Circle ->
let diameter = max width height in
if filled then [ XDotDraw.Filled_ellipse (position,diameter,diameter) ]
else [ XDotDraw.Unfilled_ellipse (position,diameter,diameter) ]
| `Doublecircle ->
let diameter = max width height in
let big_diameter = diameter +. 5. in
(XDotDraw.Unfilled_ellipse (position,big_diameter,big_diameter)) ::
[ if filled then XDotDraw.Filled_ellipse (position,diameter,diameter)
else XDotDraw.Unfilled_ellipse (position,diameter,diameter) ]
| `Box ->
let x, y = position in
let x1 = x -. width and x2 = x +. width in
let y1 = y -. height and y2 = y +. height in
let pos_array = [|(x1,y1);(x1,y2);(x2,y2);(x2,y1)|] in
if filled then [ XDotDraw.Filled_polygon pos_array ]
else [ XDotDraw.Unfilled_polygon pos_array ]
| `Record ->
let x, y = position in
let x1 = x -. width and x2 = x +. width in
let y1 = y -. height and y2 = y +. height in
let pos_array = [|(x1,y1);(x1,y2);(x2,y2);(x2,y1)|] in
if filled then [ XDotDraw.Filled_polygon pos_array ]
else [ XDotDraw.Unfilled_polygon pos_array ]
| `Diamond ->
let x, y = position in
let x1 = x -. width and x2 = x +. width in
let y1 = y -. height and y2 = y +. height in
let pos_array = [|(x,y1);(x1,y);(x,y2);(x2,y)|] in
if filled then [ XDotDraw.Filled_polygon pos_array ]
else [ XDotDraw.Unfilled_polygon pos_array ]
|_ -> [ XDotDraw.Unfilled_ellipse ((0.,0.),0.,0.) ]
let vattrs_to_draw_operations v vattributes geometry_info =
let vattrs = try HV.find vattributes v with Not_found -> assert false in
let width, _height = get_dimensions v geometry_info in
(* Vertex shape drawing *)
XDotDraw.Pen_color (string_color32 (the vattrs.color)) ::
XDotDraw.Style (List.map (style_to_style_attr) vattrs.style) ::
(if List.mem `Filled vattrs.style then
XDotDraw.Fill_color (string_color32 (the vattrs.fillcolor)) ::
shape_to_operations v vattrs geometry_info (the vattrs.shape)
else
shape_to_operations v vattrs geometry_info (the vattrs.shape))
,
(* Vertex label drawing *)
[ XDotDraw.Pen_color (string_color (the vattrs.fontcolor));
XDotDraw.Font
(float (the vattrs.fontsize),
the vattrs.fontname);
let x, y = get_position v geometry_info in
let _, h = get_dimensions v geometry_info in
(* [JS 2010/10/08] "/. 4." is quite strange but gives better results *)
XDotDraw.Text
((x, y +. h /. 4.),
XDotDraw.Center,
width,
the vattrs.label) ]
let vertex_to_node_layout v vattributes geometry_info =
let draw, ldraw = vattrs_to_draw_operations v vattributes geometry_info in
let width, height = get_dimensions v geometry_info in
let abs, ord = get_position v geometry_info in
{
XDot.n_name = Tree.vertex_name v;
XDot.n_pos = (abs,ord);
XDot.n_bbox = XDot.bounding_box (abs, ord) width height;
XDot.n_draw = draw;
XDot.n_ldraw = ldraw
}
(* FOR CLUSTER *)
open Graphviz.DotAttributes
(* FOR EDGE *)
type eattributes = {
(* See graphviz.mli for the meaning of each field *)
mutable color : int32 option;
mutable decorate : bool option;
mutable dir : [ `Forward | `Back | `Both | `None ] option;
mutable fontcolor : int option;
mutable fontname : string option;
mutable fontsize : int option;
mutable label : string option;
mutable html_label : string option;
mutable labelfontcolor : int option;
mutable labelfontname : string option;
mutable labelfontsize : int option;
mutable style : [ `Solid | `Dashed | `Dotted | `Bold | `Invis ] list
}
let rec attributes_list_to_eattributes (eattrs:eattributes)
: edge list -> _
= function
|[] -> ()
| `Color c :: q ->
eattrs.color <-
set_if_none eattrs.color (Graphviz.color_to_color_with_transparency c);
attributes_list_to_eattributes eattrs q
| `ColorWithTransparency c :: q ->
eattrs.color <- set_if_none eattrs.color c;
attributes_list_to_eattributes eattrs q
| `Decorate d :: q ->
eattrs.decorate <- set_if_none eattrs.decorate d;
attributes_list_to_eattributes eattrs q
| `Dir d :: q ->
eattrs.dir <- set_if_none eattrs.dir d;
attributes_list_to_eattributes eattrs q
| `Fontcolor c :: q ->
eattrs.fontcolor <- set_if_none eattrs.fontcolor c;
attributes_list_to_eattributes eattrs q
| `Fontname n :: q ->
eattrs.fontname <- set_if_none eattrs.fontname n;
attributes_list_to_eattributes eattrs q
| `Fontsize s :: q ->
eattrs.fontsize <- set_if_none eattrs.fontsize s;
attributes_list_to_eattributes eattrs q
| `Label l :: q ->
eattrs.label <- set_if_none eattrs.label l;
attributes_list_to_eattributes eattrs q
| `HtmlLabel l :: q ->
eattrs.html_label <- set_if_none eattrs.html_label l;
attributes_list_to_eattributes eattrs q
| `Labelfontcolor c :: q ->
eattrs.fontcolor <- set_if_none eattrs.fontcolor c;
attributes_list_to_eattributes eattrs q
| `Labelfontname n :: q ->
eattrs.labelfontname <- set_if_none eattrs.labelfontname n;
attributes_list_to_eattributes eattrs q
| `Labelfontsize s :: q ->
eattrs.labelfontsize <- set_if_none eattrs.labelfontsize s;
attributes_list_to_eattributes eattrs q
| `Style s :: q ->
eattrs.style <- s :: eattrs.style;
attributes_list_to_eattributes eattrs q
| (`Arrowhead _ | `Arrowsize _ | `Arrowtail _ | `Comment _ | `Constraint _
| `Headlabel _ | `Headport _ | `Headurl _ | `Labelangle _
|`Labeldistance _ | `Labelfloat _ | `Layer _ | `Minlen _ | `Penwidth _
| `Samehead _ | `Sametail _ | `Taillabel _ | `Tailport _ | `Tailurl _
| `Weight _ ) :: q ->
attributes_list_to_eattributes eattrs q
let eattrs_to_operation tree e geometry_info =
let eattrs = {
color = None;
decorate = None;
dir = None;
fontcolor = None;
fontname = None;
fontsize = None;
label = None;
html_label = None;
labelfontcolor = None;
labelfontname = None;
labelfontsize = None;
style = [] }
in
let dgraph_layout_default =
[ `Color 0xFF0000; `Decorate false; `Dir `Forward; `Fontcolor 0x00000;
`Fontname "Sans"; `Fontsize 12; `Label ""; `Labelfontcolor 0x000000;
`Labelfontname "Sans"; `Labelfontsize 12; `Style `Solid ]
in
attributes_list_to_eattributes eattrs
(Tree.default_edge_attributes tree
@ Tree.edge_attributes e
@ dgraph_layout_default);
let posarray =
edge_to_posarray (Tree.E.src e) (Tree.E.dst e) geometry_info
in
let xsrc, ysrc = posarray.(0) in
let xend, yend = posarray.(3) in
(
(* Shapes and curves *)
[ XDotDraw.Pen_color (string_color32 (the eattrs.color));
XDotDraw.Fill_color (string_color32 (the eattrs.color));
XDotDraw.Style (List.map (style_to_style_attr) eattrs.style);
XDotDraw.Filled_bspline posarray ]
,
(* Label drawing *)
[ XDotDraw.Pen_color (string_color (the eattrs.fontcolor));
XDotDraw.Fill_color (string_color (the eattrs.fontcolor));
XDotDraw.Font (float_of_int (the eattrs.fontsize),
(the eattrs.fontname));
(let pos = ((xsrc +. xend) /. 2. +. 5., (ysrc +. yend) /. 2.) in
XDotDraw.Text (pos,XDotDraw.Center,40.,the eattrs.label)) ]
,
(* Head arrowhead drawing *)
(if eattrs.dir = Some `None then
[]
else
XDotDraw.Pen_color (string_color32 (the eattrs.color)) ::
XDotDraw.Fill_color (string_color32 (the eattrs.color)) ::
XDotDraw.Style (List.map (style_to_style_attr) eattrs.style) ::
(edge_to_arrow posarray.(2) posarray.(3)))
,
(* Tail arrowhead drawing *)
[]
,
(* Head label drawing *)
[]
,
(* Tail label drawing *)
[]
)
let edge_to_edge_layout tree e geometry_info =
let (draw,ldraw,hdraw,tdraw,hldraw,tldraw) =
eattrs_to_operation tree e geometry_info
in
{
XDot.e_draw = draw;
XDot.e_ldraw = ldraw;
XDot.e_hdraw = hdraw;
XDot.e_tdraw = tdraw;
XDot.e_hldraw = hldraw;
XDot.e_tldraw = tldraw
}
(* Graph *)
let from_tree ~fontMeasure tree root =
let vattributes = HV.create 97 in
fill_vattributes tree vattributes;
let geometry_info =
{ dimensions = HV.create 97;
position = HV.create 97;
x_offset = 0.;
y_offset = 0 }
in
fill_dimensions ~fontMeasure tree vattributes geometry_info;
set_offset geometry_info;
fill_position tree root geometry_info;
let vertex_layouts = HV.create 97 in
Tree.iter_vertex
(fun v ->
let n_layout = vertex_to_node_layout v vattributes geometry_info in
HV.add vertex_layouts v n_layout)
tree;
let edge_layouts = ref HE.empty in
Tree.iter_edges_e
(fun e ->
let e_layout = edge_to_edge_layout tree e geometry_info in
edge_layouts := HE.add e e_layout !edge_layouts)
tree;
let cluster_layouts = Hashtbl.create 7
(* [JS 2010/09/09] does not work *)
(* build_cluster_layouts tree geometry_info*)
in
{ vertex_layouts = vertex_layouts;
edge_layouts = !edge_layouts;
cluster_layouts = cluster_layouts;
bbox =
let ((_,_), (_,_) as bb) =
HV.fold
(fun v (x, y) ((minx, miny),(maxx, maxy) as acc) ->
if TreeManipulation.is_ghost_node v then acc
else (min x minx, min y miny), (max x maxx, max y maxy))
geometry_info.position
((max_float, max_float), (0., 0.))
in
(* Format.printf "BB=%f %f %f %f@." x1 y1 x2 y2;*)
bb }
end
module MakeFromDotModel
(Tree: Sig.G with type V.label = DGraphModel.DotG.V.t
and type E.label = unit)
(TreeManipulation: sig val is_ghost_node: Tree.V.t -> bool end) =
struct
module Tree = struct
include Tree
let graph_attributes _ = []
let default_vertex_attributes _ = []
let default_edge_attributes _ = []
let vertex_name _ = ""
let vertex_attributes _ = []
let edge_attributes _ = []
let get_subgraph _ = None
end
include Build(Tree)(TreeManipulation)
open Layout
(* POSITIONS *)
let fill_dimensions model tree geometry_info =
let corners pos_array =
let p0 = pos_array.(0) in
Array.fold_left
(fun ((minx, miny), (maxx, maxy)) (x, y) ->
(min minx x, min miny y), (max maxx x, max maxy y))
(p0, p0)
pos_array
in
(* The width and height of the bounding box of the first shape
corresponding to a node.*)
let rec get_size = function
| [] -> 0., 0.
| XDotDraw.Unfilled_ellipse (_,w,h) :: _
| XDotDraw.Filled_ellipse (_,w,h) :: _ ->
2. *. w, 2. *. h
| XDotDraw.Unfilled_polygon pos_array :: _
| XDotDraw.Filled_polygon pos_array :: _ ->
let (minx, miny), (maxx, maxy) = corners pos_array in
maxx -. minx, maxy -. miny
| (XDotDraw.Style _ |XDotDraw.Font _|XDotDraw.Pen_color _
|XDotDraw.Fill_color _|XDotDraw.Filled_bspline _ |XDotDraw.Bspline _
| XDotDraw.Polyline _|XDotDraw.Text _)
:: tl -> get_size tl
in
Tree.iter_vertex
(fun v ->
let layout = model#get_vertex_layout (Tree.V.label v) in
let dim = get_size layout.XDot.n_draw in
HV.add geometry_info.dimensions v dim)
tree
let fill_position tree root geometry_info =
let forward_table = HV.create 97 in
let backward_table = HV.create 97 in
fill_tree_positions tree root Tree.iter_succ Tree.fold_succ forward_table
geometry_info;
(*HV.iter (fun k (off,depth) -> Format.printf "off:%f depth:%d@." off depth)
forward_table;*)
fill_tree_positions tree root Tree.iter_pred Tree.fold_pred backward_table
geometry_info;
(* HV.iter (fun k (off,depth) ->
Format.printf "BACKoff:%f depth:%d@." off depth)
backward_table;
Format.printf "DONE@.";*)
bind_tree_tables forward_table backward_table root geometry_info
(* VERTICES *)
let parse_n_draw_operations operations (abs, ord as pos) =
let polygon pts =
let length = float (Array.length pts) in
let oldabssum, oldordsum =
Array.fold_left
(fun (xsum, ysum) (x, y) -> xsum +. x, ysum +. y) (0.,0.) pts
in
let oldabs, oldord = oldabssum /. length, oldordsum /. length in
Array.map (fun (x, y) -> x -. oldabs +. abs, y -. oldord +. ord) pts
in
let do_one = function
| XDotDraw.Unfilled_ellipse (_, w, h) ->
XDotDraw.Unfilled_ellipse (pos, w, h)
| XDotDraw.Filled_ellipse (_, w, h) -> XDotDraw.Filled_ellipse (pos, w, h)
| XDotDraw.Filled_polygon pts -> XDotDraw.Filled_polygon (polygon pts)
| XDotDraw.Unfilled_polygon pts -> XDotDraw.Unfilled_polygon (polygon pts)
| op -> op
in
List.map do_one operations
let parse_n_ldraw_operations
(initial_node_pos_x,initial_node_pos_y)
(node_pos_x,node_pos_y)
operations
=
List.map
(function
| XDotDraw.Text ((pos_x,pos_y), align, w, s) ->
let translate_x,translate_y =
node_pos_x-.initial_node_pos_x,node_pos_y-.initial_node_pos_y
in
let (_,_ as pos) = (* same affine move as the attached node has had*)
pos_x+.translate_x,
pos_y+.translate_y
in
XDotDraw.Text (pos, align, w, s)
| op -> op)
operations
let parse_vertex_layout _tree v orig_layout geometry_info =
let width, height = get_dimensions v geometry_info in
let (_,_ as pos) = get_position v geometry_info in
{ XDot.n_name = orig_layout.XDot.n_name;
n_pos = pos;
n_bbox = XDot.bounding_box pos width height;
n_draw = parse_n_draw_operations orig_layout.XDot.n_draw pos;
n_ldraw = parse_n_ldraw_operations
orig_layout.XDot.n_pos
pos
orig_layout.XDot.n_ldraw}
(* EDGES *)
let rec parse_e_draw_operations operations src dst geometry_info =
match operations with
| [] -> []
| XDotDraw.Bspline _ :: tl ->
let pos_array = edge_to_posarray src dst geometry_info in
XDotDraw.Bspline pos_array ::
(edge_to_arrow pos_array.(2) pos_array.(3)) @
(parse_e_draw_operations tl src dst geometry_info)
| XDotDraw.Filled_bspline _ :: tl ->
let pos_array = edge_to_posarray src dst geometry_info in
XDotDraw.Filled_bspline pos_array ::
(edge_to_arrow pos_array.(2) pos_array.(3)) @
(parse_e_draw_operations tl src dst geometry_info)
| XDotDraw.Pen_color c :: tl ->
XDotDraw.Pen_color c :: XDotDraw.Fill_color c ::
(parse_e_draw_operations tl src dst geometry_info)
| op :: tl -> op :: (parse_e_draw_operations tl src dst geometry_info)
let rec parse_e_ldraw_operations operations src dst geometry_info =
match operations with
| [] -> []
| XDotDraw.Text (_, align, w, s) :: tl ->
let (xsrc,ysrc) = get_position src geometry_info in
let (xdst,ydst) = get_position dst geometry_info in
let pos = ((xsrc +. xdst) /. 2., (ysrc +. ydst) /. 2.) in
XDotDraw.Text (pos, align, w, s) ::
(parse_e_ldraw_operations tl src dst geometry_info)
| op :: tl -> op :: (parse_e_ldraw_operations tl src dst geometry_info)
let parse_edge_layout _tree e layout geometry_info =
let src = Tree.E.src e and dst = Tree.E.dst e in
{
XDot.e_draw =
parse_e_draw_operations layout.XDot.e_draw src dst geometry_info;
e_ldraw =
parse_e_ldraw_operations layout.XDot.e_ldraw src dst geometry_info;
e_hdraw = [];
e_tdraw = [];
e_hldraw = [];
e_tldraw = []
}
(* CLUSTERS *)
let from_model tree root model =
let geometry_info =
{ dimensions = HV.create 97;
position = HV.create 97;
x_offset = 0.;
y_offset = 0 }
in
fill_dimensions model tree geometry_info;
set_offset geometry_info;
fill_position tree root geometry_info;
let vertex_layouts = HV.create 97 in
Tree.iter_vertex
(fun v ->
let old_layout = model#get_vertex_layout (Tree.V.label v) in
let v_layout = parse_vertex_layout tree v old_layout geometry_info in
HV.add vertex_layouts v v_layout)
tree;
let edge_layouts = ref HE.empty in
Tree.iter_edges_e
(fun e ->
let src = Tree.V.label (Tree.E.src e) in
let dst = Tree.V.label (Tree.E.dst e) in
let old_layout =
try model#get_edge_layout (model#find_edge src dst)
with Not_found ->
{ XDot.e_draw = [];
e_ldraw = [];
e_hdraw = [];
e_tdraw = [];
e_hldraw = [];
e_tldraw = [] }
in
let e_layout = parse_edge_layout tree e old_layout geometry_info in
edge_layouts := HE.add e e_layout !edge_layouts)
tree;
let cluster_layouts = Hashtbl.create 7 in
let root_pos = get_position root geometry_info in
{ vertex_layouts = vertex_layouts;
edge_layouts = !edge_layouts;
cluster_layouts = cluster_layouts;
bbox =
let ((_,_), (_,_) as bb) =
HV.fold
(fun v (x, y) ((minx, miny),(maxx, maxy) as acc) ->
if TreeManipulation.is_ghost_node v then acc
else
let width,height= get_dimensions v geometry_info in
(min (x-.width) minx, min (y-.height) miny),
(max (x+.width) maxx, max (y+.height) maxy))
geometry_info.position
(root_pos, root_pos)
in
(* Format.printf "BB=%f %f %f %f@." x1 y1 x2 y2;*)
bb }
end
ocamlgraph-2.0.0/src/minsep.mli 0000644 0001750 0000144 00000005607 13735627615 015006 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(**
Minimal separators of a graph
Based on the article:
Generating all the minimal separators of a graph.
by A. Berry, J.-P. Bordat and O.Cogis
http://www.isima.fr/berry/generating.html
A set [S] of vertices is a minimal separator if it exists 2 distinct
connected components [C] and [D] in [G \ S] such that each vertex of [S] has
a successor in [C] and [D]. *)
(** Minimal signature for computing the minimal separators *)
module type G = sig
type t
module V : Sig.COMPARABLE
val succ: t -> V.t -> V.t list
val iter_succ: (V.t -> unit) -> t -> V.t -> unit
val fold_succ: (V.t -> 'a -> 'a) -> t -> V.t -> 'a -> 'a
val iter_vertex: (V.t -> unit) -> t -> unit
val fold_vertex: (V.t -> 'a -> 'a) -> t -> 'a -> 'a
end
module type MINSEP = sig
module G : G
(** Implementation of a graph *)
module Vertex_Set : Set.S with type elt = G.V.t
(** Implementation of a set of vertex *)
module VSetset : Set.S with type elt = Vertex_Set.t
(** Implementation of a set of [Vertex_Set] *)
val allminsep : G.t -> Vertex_Set.t list
(** [allminsep g] computes the list of all minimal separators of g. *)
val list_of_allminsep : G.t -> G.V.t list list
(** Less efficient that [allminsep] *)
val set_of_allminsep : G.t -> VSetset.t
(** Less efficient that [allminsep] *)
end
(** Implementation for a persistent graph *)
module P(G : sig include G val remove_vertex : t -> V.t -> t end) :
MINSEP with module G = G
(** Implementation for an imperative graph.
Less efficient that the implementation for a persistent graph *)
module I(G : sig
include G
module Mark : Sig.MARK with type graph = t and type vertex = V.t
end) :
MINSEP with module G = G
ocamlgraph-2.0.0/src/weakTopological.ml 0000644 0001750 0000144 00000006737 13735627615 016473 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(* Copyright © 2015 Thibault Suzanne
* École Normale Supérieure, Département d'Informatique
* Paris Sciences et Lettres
*)
(* Original algorithm by François Bourdoncle. See :
* "Efficient chaotic iteration strategies with widenings",
* Formal Methods in Programming and their Applications,
* Springer Berlin Heidelberg, 1993.
*)
module type G = sig
type t
module V : Sig.COMPARABLE
val iter_vertex : (V.t -> unit) -> t -> unit
val iter_succ : (V.t -> unit) -> t -> V.t -> unit
end
type 'a element =
| Vertex of 'a
| Component of 'a * 'a t
and 'a t = 'a element list
let fold_left = List.fold_left
module Make (G : G) = struct
module HT = Hashtbl.Make(G.V)
let recursive_scc g root_g =
(* Straight OCaml implementation of the Section 4.3,
fig. 4 algorithm in Bourdoncle's paper *)
let stack = Stack.create () in
let dfn = HT.create 1024 in
let num = ref 0 in
let partition = ref [] in
G.iter_vertex (fun v -> HT.add dfn v 0) g;
let rec visit vertex partition =
let head = ref 0 in
let loop = ref false in
Stack.push vertex stack;
incr num;
HT.replace dfn vertex !num;
head := !num;
G.iter_succ
(fun succ ->
let dfn_succ = HT.find dfn succ in
let min =
if dfn_succ = 0
then visit succ partition
else dfn_succ in
if min <= !head then begin
head := min;
loop := true
end)
g vertex;
if !head = HT.find dfn vertex
then begin
HT.replace dfn vertex max_int;
let element = ref (Stack.pop stack) in
if !loop then begin
while G.V.compare !element vertex <> 0 do
HT.replace dfn !element 0;
element := Stack.pop stack;
done;
partition := component vertex :: !partition;
end
else partition := Vertex vertex :: !partition
end;
!head
and component vertex =
let partition = ref [] in
G.iter_succ
(fun succ ->
if HT.find dfn succ = 0
then ignore (visit succ partition : int))
g vertex;
Component (vertex, !partition)
in
let (_ : int) = visit root_g partition in
!partition
end
ocamlgraph-2.0.0/src/xDot.mli 0000644 0001750 0000144 00000012517 13735627615 014427 0 ustar rt users (**************************************************************************)
(* *)
(* This file is part of OcamlGraph. *)
(* *)
(* Copyright (C) 2009-2010 *)
(* CEA (Commissariat � l'�nergie Atomique) *)
(* *)
(* you can redistribute it and/or modify it under the terms of the GNU *)
(* Lesser General Public License as published by the Free Software *)
(* Foundation, version 2.1, with a linking exception. *)
(* *)
(* It 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. See the *)
(* GNU Lesser General Public License for more details. *)
(* *)
(* See the file ../LICENSE for more details. *)
(* *)
(* Authors: *)
(* - Julien Signoles (Julien.Signoles@cea.fr) *)
(* - Jean-Denis Koeck (jdkoeck@gmail.com) *)
(* - Benoit Bataille (benoit.bataille@gmail.com) *)
(* *)
(**************************************************************************)
(** Reads layout information from xdot ASTs *)
(** Simple layout types *)
(** 2D coordinates *)
type pos = float * float
(** upper-left and bottom-right corners *)
type bounding_box = pos * pos
(**
Layout informations are parsed from xdot files
(dot files with graphviz layout).
Each node or edge layout thus contains several lists of
drawing operations.
See http://www.graphviz.org/doc/info/output.html#d:xdot
to understand the details of the layout informations.
*)
(** Each node has at least a position and a bounding box. *)
type node_layout = {
n_name : string; (** Dot label *)
n_pos : pos; (** Center position *)
n_bbox : bounding_box; (** Bounding box *)
n_draw : XDotDraw.operation list; (** Shape drawing *)
n_ldraw : XDotDraw.operation list; (** Label drawing *)
}
type cluster_layout = {
c_pos : pos;
c_bbox : bounding_box;
c_draw : XDotDraw.operation list;
c_ldraw : XDotDraw.operation list;
}
type edge_layout = {
e_draw : XDotDraw.operation list; (** Shapes and curves *)
e_ldraw : XDotDraw.operation list; (** Label drawing *)
e_hdraw : XDotDraw.operation list; (** Head arrowhead drawing *)
e_tdraw : XDotDraw.operation list; (** Tail arrowhead drawing *)
e_hldraw : XDotDraw.operation list; (** Head label drawing *)
e_tldraw : XDotDraw.operation list; (** Tail label drawing *)
}
(** Creates a node layout *)
val mk_node_layout :
name:string ->
pos:pos ->
bbox:bounding_box ->
draw:XDotDraw.operation list ->
ldraw:XDotDraw.operation list ->
node_layout
(** Creates a cluster layout *)
val mk_cluster_layout :
pos:pos ->
bbox:bounding_box ->
draw:XDotDraw.operation list ->
ldraw:XDotDraw.operation list ->
cluster_layout
(** Creates an edge layout *)
val mk_edge_layout :
draw:XDotDraw.operation list ->
ldraw:XDotDraw.operation list ->
hdraw:XDotDraw.operation list ->
tdraw:XDotDraw.operation list ->
hldraw:XDotDraw.operation list ->
tldraw:XDotDraw.operation list ->
edge_layout
(** Parsing and reading XDot *)
exception ParseError of string
(** Instantiates a module which creates graph layouts from xdot files *)
module Make(G : Graphviz.GraphWithDotAttrs) : sig
module HV: Hashtbl.S with type key = G.V.t
module HE: Map.S with type key = G.E.t
(** Main layout type *)
type graph_layout =
{ vertex_layouts : node_layout HV.t;
edge_layouts : edge_layout HE.t;
cluster_layouts : (string, cluster_layout) Hashtbl.t;
bbox : bounding_box }
exception DotError of string
(** Extracts a layout of an xdot file *)
val layout_of_xdot: xdot_file:string -> G.t -> graph_layout
(** Using the dot file and graphviz,
create an xdot and extracts its layout. *)
val layout_of_dot: ?cmd:string -> dot_file:string -> G.t -> graph_layout
end
(** Converts and reads various layout informations *)
(** [bounding_box pos w h] converts a bounding box of center [pos],
width [w] and height [h] from a Dot file to a pair of corners
(lower left and upper right) in the world coordinate system.
@param pos position of the center of the node
@param w width of the node
@param h height of the node
*)
val bounding_box : (float * float) -> float -> float -> bounding_box
val read_bounding_box : string -> bounding_box
(** Reads xdot layouts from the dot ast *)
val read_node_layout : Dot_ast.node_id -> Dot_ast.attr list -> node_layout
val read_edge_layout : Dot_ast.attr list -> edge_layout
val read_cluster_layout : Dot_ast.attr list -> cluster_layout
ocamlgraph-2.0.0/src/kruskal.ml 0000644 0001750 0000144 00000004701 13735627615 015010 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(* $Id: kruskal.ml,v 1.5 2005-06-30 10:48:55 filliatr Exp $ *)
module type UNIONFIND = sig
type elt
type t
val init : elt list -> t
val find : elt -> t -> elt
val union : elt -> elt -> t -> unit
end
module type G = sig
type t
module V : Sig.COMPARABLE
module E : sig
type t
type label
val label : t -> label
val dst : t -> V.t
val src : t -> V.t
end
val fold_vertex : (V.t -> 'a -> 'a) -> t -> 'a -> 'a
val iter_edges_e : (E.t -> unit) -> t -> unit
end
module Generic
(G: G)
(W : Sig.ORDERED_TYPE with type t = G.E.label)
(UF: UNIONFIND with type elt = G.V.t) =
struct
let spanningtree g =
let vertices = G.fold_vertex (fun v a -> v :: a) g [] in
let uf = UF.init vertices in
let edges =
let l = ref [] in
G.iter_edges_e (fun e -> l := e :: !l) g;
List.sort (fun e e'-> W.compare (G.E.label e) (G.E.label e')) !l
in
let s = ref [] in
let cover e =
let u, v = G.E.src e, G.E.dst e in
if G.V.compare (UF.find u uf) (UF.find v uf) <> 0 then begin
UF.union u v uf;
s := e :: !s
end
in
List.iter cover edges;
!s
end
module Make(G: G)(W : Sig.ORDERED_TYPE with type t=G.E.label) =
Generic(G)(W)(Unionfind.Make(G.V))
ocamlgraph-2.0.0/src/util.mli 0000644 0001750 0000144 00000004013 13735627615 014456 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(** Some useful operations. *)
open Sig
(** Cartesian product of two ordered types. *)
module OTProduct(X: ORDERED_TYPE)(Y: ORDERED_TYPE) :
ORDERED_TYPE with type t = X.t * Y.t
(** Cartesian product of two hashable types. *)
module HTProduct(X: HASHABLE)(Y: HASHABLE) :
HASHABLE with type t = X.t * Y.t
(** Cartesian product of two comparable types. *)
module CMPProduct(X: COMPARABLE)(Y: COMPARABLE) :
COMPARABLE with type t = X.t * Y.t
(** Create a vertex type with some data attached to it *)
module DataV(L : sig type t end)(V : Sig.COMPARABLE) : sig
type data = L.t
and label = V.t
and t = data ref * V.t
val compare : t -> t -> int
val hash : t -> int
val equal : t -> t -> bool
val create : data -> V.t -> t
val label : t -> V.t
val data : t -> data
val set_data : t -> data -> unit
end
ocamlgraph-2.0.0/src/xDotDraw.ml 0000644 0001750 0000144 00000027043 13735627615 015074 0 ustar rt users (**************************************************************************)
(* *)
(* This file is part of OcamlGraph. *)
(* *)
(* Copyright (C) 2009-2010 *)
(* CEA (Commissariat � l'�nergie Atomique) *)
(* *)
(* you can redistribute it and/or modify it under the terms of the GNU *)
(* Lesser General Public License as published by the Free Software *)
(* Foundation, version 2.1, with a linking exception. *)
(* *)
(* It 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. See the *)
(* GNU Lesser General Public License for more details. *)
(* *)
(* See the file ../LICENSE for more details. *)
(* *)
(* Authors: *)
(* - Julien Signoles (Julien.Signoles@cea.fr) *)
(* - Jean-Denis Koeck (jdkoeck@gmail.com) *)
(* - Benoit Bataille (benoit.bataille@gmail.com) *)
(* *)
(**************************************************************************)
(* This module parses _draw_ attributes in XDot *)
type pos = float * float
type width = float
type height = float
type size = int
type align = Left | Center | Right
type style_attr =
| Filled | Invisible | Diagonals | Rounded | Dashed | Dotted
| Solid | Bold | StyleString of string
(* Drawing operations *)
type operation =
| Filled_ellipse of pos * width * height
| Unfilled_ellipse of pos * width * height
| Filled_polygon of pos array
| Unfilled_polygon of pos array
| Polyline of pos array
| Bspline of pos array
| Filled_bspline of pos array
| Text of pos * align * width * string
| Fill_color of string
| Pen_color of string
| Font of float * string
| Style of style_attr list
(* Drawing state *)
type draw_state = {
mutable fill_color : string;
mutable pen_color : string;
mutable font : float * string;
mutable style : style_attr list
}
let default_draw_state () =
{ fill_color = "#FFFFFF";
pen_color = "#000000";
font = 0., "";
style = [] }
let set_fill_color st c = st.fill_color <- c
let set_pen_color st c = st.pen_color <- c
let set_font st c = st.font <- c
let set_style st s = st.style <- s
(* STRING OPERATIONS *)
let suffix s i =
try String.sub s i (String.length s - i) with Invalid_argument _ -> ""
(** Splits a string with a separator
returns a list of strings *)
let split c s =
let rec split_from n =
try let p = String.index_from s n c
in (String.sub s n (p-n)) :: (split_from (p+1))
with Not_found -> [ suffix s n ]
in if s="" then [] else split_from 0 ;;
let string_scale_size
~(fontMeasure:
fontName: string -> fontSize:int ->
string -> (int * int)
)
font size s =
let width, height = fontMeasure ~fontName:font ~fontSize:(int_of_float size) s in
let width = float width in
let linear_width = size *. (float (String.length s)) in
size*.width/.linear_width,
float height
(* HSV TO RGB CONVERSION *)
(* If color string in hsv format, convert to hex *)
let normalize_color s =
try
let h,s,v = Scanf.sscanf s "%f %f %f"(fun a b c -> (a,b,c)) in
let h' = 360. *. h /. 60. in
let hi = truncate h' mod 6 in
let f = h' -. floor h' in
let p = v *. (1. -. s) in
let q = v *. (1. -. f*.s) in
let t = v *. (1. -. (1. -. f) *. s) in
let r,g,b = match hi with
| 0 -> v,t,p
| 1 -> q,v,p
| 2 -> p,v,t
| 3 -> p,q,v
| 4 -> t,p,v
| 5 -> v,p,q
| _ -> 1.,1.,1. in
let to_hex x = Printf.sprintf "%02X" (truncate (x *. 255.)) in
"#" ^ to_hex r ^ to_hex g ^ to_hex b
with Scanf.Scan_failure _ -> s
(* PARSE STATE *)
type state = {
mutable operations : operation list;
mutable cur : int;
str : string;
}
exception ParseError of string
exception NoOperationId
let mk_state s = { operations = []; cur = 0; str = s }
let char state = state.str.[state.cur]
let incr state = state.cur <- state.cur + 1
(* No more characters *)
let over state = state.cur >= String.length state.str
let add_operation i state =
state.operations <- i :: state.operations
(* GET TOKENS *)
let get_n n st =
let s = String.sub st.str st.cur n in
st.cur <- st.cur + n;
s
let is_space = function
| ' ' | '\t' | '\n' -> true
| _ -> false
let is_token = function
| "E" | "e" | "P" | "p" | "L" | "B" | "b" | "T" | "C" | "c" | "F"
| "S" -> true
| _ -> false
let skip_spaces state =
let rec loop () =
if not (over state) then
if is_space (char state) then begin
incr state;
loop ()
end
in loop ()
(* Gets a word *)
let get_word state =
skip_spaces state;
let start = state.cur in
let rec get' () =
if over state then
if start = String.length state.str then
None
else
Some (String.sub state.str start (state.cur - start))
else
if not (is_space (char state)) then begin
incr state;
get' ()
end else
Some (String.sub state.str start (state.cur - start)) in
get' ()
(* Gets a rendering or attribute operation *)
let get_op_id state =
let tok = get_word state in
match tok with
| None ->
raise NoOperationId
| Some tok' ->
if is_token tok' then
tok'
else
raise NoOperationId
let get_int state =
match get_word state with
| Some w -> begin
(*let w' = filter_int w in*)
try int_of_string w
with Failure _ -> raise (ParseError "Cannot parse int")
end
| None -> raise (ParseError "Cannot parse int")
let get_float state =
match get_word state with
| Some w -> begin
try float_of_string w
with Failure _ -> raise (ParseError "Cannot parse float")
end
| None -> raise (ParseError "Cannot parse float")
let get_pos state =
try
let x0 = get_float state in
let y0 = get_float state in
(x0, y0)
with ParseError _ -> raise (ParseError "Cannot parse point in position")
(* PARSING *)
let get_anchor state =
let i = get_int state in
match i with
| -1 -> Left
| 0 -> Center
| 1 -> Right
| _ -> raise (ParseError "Cannot parse anchor")
let parse_bytes st =
skip_spaces st;
let n = get_int st in
skip_spaces st;
if char st <> '-' then
raise (ParseError "Cannot parse bytes")
else begin
incr st;
get_n n st
end
let parse_ellipse constr state =
(* pos width height *)
let pos = get_pos state in
let w = get_float state in
let h = get_float state in
constr (pos, w, h)
let invert_y_pos (x,y) = (x,-.y)
let parse_filled_ellipse =
parse_ellipse (fun (p,w,h) -> Filled_ellipse (invert_y_pos p,w,h))
let parse_unfilled_ellipse =
parse_ellipse (fun (p,w,h) -> Unfilled_ellipse (invert_y_pos p,w,h))
let parse_points state =
let n = get_int state in
Array.init n (fun _ -> invert_y_pos (get_pos state))
let parse_filled_polygon state =
Filled_polygon (parse_points state)
let parse_unfilled_polygon state =
Unfilled_polygon (parse_points state)
let parse_polyline state =
Polyline (parse_points state)
let parse_bspline state =
Bspline (parse_points state)
let parse_filled_bspline state =
Filled_bspline (parse_points state)
let parse_text state =
let pos = invert_y_pos (get_pos state) in
let anchor = get_anchor state in
let width = get_float state in
let str = parse_bytes state in
Text (pos, anchor, width, str)
let parse_fill_color state =
Fill_color (normalize_color (parse_bytes state))
let parse_pen_color state =
Pen_color (normalize_color (parse_bytes state))
let parse_font state =
let size = get_float state in
let font = parse_bytes state in
Font (size, font)
let parse_style state =
let read = function
| "filled" -> Filled
| "invisible" -> Invisible
| "diagonals" -> Diagonals
| "rounded" -> Rounded
| "dashed" -> Dashed
| "dotted" -> Dotted
| "solid" -> Solid
| "bold" -> Bold
| s -> StyleString s in
let str = parse_bytes state in
Style (List.map read (split ',' str))
let parse_operation state =
let operation () = match get_op_id state with
| "E" -> parse_filled_ellipse state
| "e" -> parse_unfilled_ellipse state
| "P" -> parse_filled_polygon state
| "p" -> parse_unfilled_polygon state
| "L" -> parse_polyline state
| "B" -> parse_bspline state
| "b" -> parse_filled_bspline state
| "T" -> parse_text state
| "C" -> parse_fill_color state
| "c" -> parse_pen_color state
| "F" -> parse_font state
| "S" -> parse_style state
| _ -> raise (ParseError "Cannot parse operation") in
try add_operation (operation ()) state
with NoOperationId -> ()
let parse_with_state state =
let rec loop () =
parse_operation state;
if over state then
state.operations
else loop () in
try List.rev (loop ())
with NoOperationId -> List.rev state.operations
(* Long drawing operation strings sometimes contain useless backslashes
We get rid of them to avoid problems with the parser *)
let remove_backslashes s =
let buf = Buffer.create 30 in
let rec loop i =
if i = String.length s then ()
else
if s.[i] = '\\' && i < String.length s - 1 && s.[i+1] = '\n' then
loop (i+2)
else begin
Buffer.add_char buf s.[i];
loop (i+1)
end in
loop 0;
Buffer.contents buf
let parse s =
parse_with_state (mk_state (remove_backslashes s))
let draw_with (f : draw_state -> operation -> unit) operations =
let st = default_draw_state () in
let draw_op = function
(* The 4 following instructions modify the drawing state *)
| Fill_color c as op ->
set_fill_color st c;
f st op
| Pen_color c as op ->
set_pen_color st c;
f st op
| Font (sty,font) as op ->
set_font st (sty,font);
f st op
| Style stys as op ->
set_style st stys;
f st op
(* No state effects on the other operations *)
| op -> f st op
in List.iter draw_op operations
(* let d1 = parse "c 5 -white C 5 -white P 4 0 0 0 409 228 409 228 0 " *)
(* let d2 = parse "S 6 -filled c 9 -lightgrey C 9 -lightgrey P 4 8 72 8 365 101 365 101 72 " *)
(* let d3 = parse "S 6 -filled c 5 -white C 5 -white E 65 314 27 18 " *)
(* let d4 = parse "F 14.000000 11 -Times-Roman c 5 -black T 39 109 0 35 4 -LR_0 " *)
(* let d5 = parse "S 6 -filled c 5 -white C 5 -white E 64 98 27 18 " *)
(* let d6 = parse "S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 69 270 65 260 62 270 " *)
(* let d7 = parse "S 6 -filled c 7 -salmon2 C 7 -salmon2 P 9 865 1177 877 1193 841 1200 760 1192 695 1178 700 1167 756 1161 810 1160 841 1165 " *)
(* let d8 = parse "F 14.000000 17 -Helvetica-Outline c 5 -black T 529 1005 0 65 9 -Mini Unix " *)
(* let d9 = parse "S 6 -filled c 11 -greenyellow C 11 -greenyellow P 10 1254 819 1263 834 1247 843 1197 841 1137 830 1110 817 1131 808 1177 805 121\ *)
(* 6 804 1238 809 " *)
(* let d10 = parse "S 6 -filled c 11 -greenyellow C 11 -greenyellow P 10 255 282 264 297 248 306 198 304 138 293 111 280 132 271 178 268 217 267 239\\\n 272 " *)
ocamlgraph-2.0.0/src/gml.mli 0000644 0001750 0000144 00000005274 13735627615 014272 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(* $Id: gml.mli,v 1.3 2005-07-06 13:20:31 conchon Exp $ *)
(** Parser and pretty-printer for GML file format. *)
type value =
| Int of int
| Float of float
| String of string
| List of value_list
and value_list = (string * value) list
(** {2 Parser} *)
(** Provide a parser for GML file format. *)
module Parse
(B : Builder.S)
(L : sig
val node : value_list -> B.G.V.label
(** How to build the node label out of the set of GML attributes.
For example {v node [ id 12 label "foo" ] v} will call this
function with [["id", Int 12; "label", String "foo"]] *)
val edge : value_list -> B.G.E.label
(** How to build the edge label out of the set of GML attributes *)
end) :
sig
val parse : string -> B.G.t
end
(** {2 Pretty-printer} *)
(** Signature for graph required by {!Print}.
Sub-signature of {!Sig.G}. *)
module type G = sig
module V : sig
type t
val hash : t -> int
val equal : t -> t -> bool
type label
val label : t -> label
end
module E : sig
type t
type label
val src : t -> V.t
val dst : t -> V.t
val label : t -> label
end
type t
val iter_vertex : (V.t -> unit) -> t -> unit
val iter_edges_e : (E.t -> unit) -> t -> unit
end
(** Provide a pretty-printer for GML file format. *)
module Print
(G: G)
(L: sig
val node : G.V.label -> value_list
val edge : G.E.label -> value_list
end) :
sig
val print : Format.formatter -> G.t -> unit
end
ocamlgraph-2.0.0/src/persistent.mli 0000644 0001750 0000144 00000007524 13735627615 015713 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(** Persistent Graph Implementations. *)
open Sig
(** Signature of persistent graphs. *)
module type S = sig
(** Edges may be labeled or not :
- Unlabeled: there is no label on edges
- Labeled: you have to provide a label implementation as a functor
parameter.
Vertices may be concrete or abstract :
- Concrete: type of vertex labels and type of vertices are identified.
- Abstract: type of vertices is abstract (in particular it is not equal
to type of vertex labels
How to choose between concrete and abstract vertices for my graph
implementation ?
Usually, if you fall into one of the following cases, use abstract
vertices:
- you cannot provide efficient comparison/hash functions for vertices; or
- you wish to get two different vertices with the same label.
In other cases, it is certainly easier to use concrete vertices. *)
(** Persistent Unlabeled Graphs. *)
module Concrete (V: COMPARABLE) :
Sig.P with type V.t = V.t and type V.label = V.t and type E.t = V.t * V.t
and type E.label = unit
(** Abstract Persistent Unlabeled Graphs. *)
module Abstract(V: ANY_TYPE) : Sig.P with type V.label = V.t
and type E.label = unit
(** Persistent Labeled Graphs. *)
module ConcreteLabeled (V: COMPARABLE)(E: ORDERED_TYPE_DFT) :
Sig.P with type V.t = V.t and type V.label = V.t
and type E.t = V.t * E.t * V.t and type E.label = E.t
(** Abstract Persistent Labeled Graphs. *)
module AbstractLabeled (V: ANY_TYPE)(E: ORDERED_TYPE_DFT) :
Sig.P with type V.label = V.t and type E.label = E.t
end
(** Persistent Directed Graphs. *)
module Digraph : sig
include S
(** {2 Bidirectional graphs}
Bidirectional graphs use more memory space (at worse the double) that
standard concrete directional graphs. But accessing predecessors and
removing a vertex are faster. *)
(** Imperative Unlabeled, bidirectional graph. *)
module ConcreteBidirectional (V: COMPARABLE) :
Sig.P with type V.t = V.t and type V.label = V.t and type E.t = V.t * V.t
and type E.label = unit
(** Imperative Labeled and bidirectional graph. *)
module ConcreteBidirectionalLabeled(V:COMPARABLE)(E:ORDERED_TYPE_DFT) :
Sig.P with type V.t = V.t and type V.label = V.t
and type E.t = V.t * E.t * V.t and type E.label = E.t
end
(** Persistent Undirected Graphs. *)
module Graph : S
(*
Local Variables:
compile-command: "make -C .."
End:
*)
ocamlgraph-2.0.0/src/coloring.ml 0000644 0001750 0000144 00000011741 13735627615 015152 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
module type GM = sig
val is_directed : bool
type t
val nb_vertex : t -> int
module V : Sig.COMPARABLE
val out_degree : t -> V.t -> int
val iter_vertex : (V.t -> unit) -> t -> unit
val fold_vertex : (V.t -> 'a -> 'a) -> t -> 'a -> 'a
val iter_succ : (V.t -> unit) -> t -> V.t -> unit
val fold_succ : (V.t -> 'a -> 'a) -> t -> V.t -> 'a -> 'a
module Mark : sig
val get : V.t -> int
val set : V.t -> int -> unit
end
end
exception NoColoring
(** Graph coloring with marking.
Only applies to imperative graphs with marks. *)
module Mark(G : GM) = struct
module Bfs = Traverse.Bfs(G)
let coloring g k =
if G.is_directed then invalid_arg "coloring: directed graph";
(* first step: we eliminate vertices with less than [k] successors *)
let stack = Stack.create () in
let nb_to_color = ref (G.nb_vertex g) in
let count = ref 1 in
while !count > 0 do
count := 0;
let erase v = incr count; G.Mark.set v (k+1); Stack.push v stack in
G.iter_vertex
(fun v -> if G.Mark.get v = 0 && G.out_degree g v < k then erase v)
g;
(*Format.printf "eliminating %d nodes@." !count;*)
nb_to_color := !nb_to_color - !count
done;
(* second step: we k-color the remaining of the graph *)
(* [try_color v i] tries to assign color [i] to vertex [v] *)
let try_color v i =
G.Mark.set v i;
G.iter_succ (fun w -> if G.Mark.get w = i then raise NoColoring) g v
in
let uncolor v = G.Mark.set v 0 in
if !nb_to_color > 0 then begin
let rec iterate iter =
let v = Bfs.get iter in
let m = G.Mark.get v in
if m > 0 then
iterate (Bfs.step iter)
else begin
for i = 1 to k do
try try_color v i; iterate (Bfs.step iter)
with NoColoring -> ()
done;
uncolor v;
raise NoColoring
end
in
try iterate (Bfs.start g) with Exit -> ()
end;
(* third step: we color the eliminated vertices, in reverse order *)
Stack.iter
(fun v ->
try
for i = 1 to k do
try try_color v i; raise Exit with NoColoring -> ()
done;
raise NoColoring (* it may still fail on a self edge v->v *)
with Exit -> ())
stack
let two_color g =
if G.is_directed then invalid_arg "coloring: directed graph";
(* first, set all colors to 0 *)
let erase v = G.Mark.set v 0 in
G.iter_vertex erase g;
(* then, use dfs to color the nodes *)
let rec dfs c v = match G.Mark.get v with
| 1 | 2 as cv -> if cv <> c then raise NoColoring (* check for cycles *)
| _ -> G.Mark.set v c; G.iter_succ (dfs (1-c)) g v in
let start v = match G.Mark.get v with 1 | 2 -> () | _ -> dfs 1 v in
G.iter_vertex start g
end
(** Graph coloring for graphs without marks: we use an external hash table *)
module type G = sig
val is_directed : bool
type t
val nb_vertex : t -> int
module V : Sig.COMPARABLE
val out_degree : t -> V.t -> int
val iter_vertex : (V.t -> unit) -> t -> unit
val fold_vertex : (V.t -> 'a -> 'a) -> t -> 'a -> 'a
val iter_succ : (V.t -> unit) -> t -> V.t -> unit
val fold_succ : (V.t -> 'a -> 'a) -> t -> V.t -> 'a -> 'a
end
module Make(G: G) = struct
module H = Hashtbl.Make(G.V)
let add_marks () =
let h = H.create 97 in
h, (module struct
include G
module Mark = struct
let get v = try H.find h v with Not_found -> 0
let set v n = H.replace h v n end end :
GM with type t = G.t and type V.t = G.V.t)
let coloring g k =
let h, (module GM) = add_marks () in
let module M = Mark(GM) in
M.coloring g k;
h
let two_color g =
let h, (module GM) = add_marks () in
let module M = Mark(GM) in
M.two_color g;
h
end
ocamlgraph-2.0.0/src/gmap.mli 0000644 0001750 0000144 00000005726 13735627615 014441 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(** Graph mapping. Map a graph to another one. *)
(** {2 Mapping of vertices} *)
(** Signature for the source graph. *)
module type V_SRC = sig
type t
module V : Sig.HASHABLE
val fold_vertex : (V.t -> 'a -> 'a) -> t -> 'a -> 'a
end
(** Signature for the destination graph. *)
module type V_DST = sig
type t
type vertex
val empty : unit -> t
val add_vertex : t -> vertex -> t
end
(** Provide a mapping function from a mapping of vertices. *)
module Vertex(G_Src : V_SRC)(G_Dst : V_DST) : sig
val map : (G_Src.V.t -> G_Dst.vertex) -> G_Src.t -> G_Dst.t
(** [map f g] applies [f] to each vertex of [g] and so builds a new graph
based on [g] *)
val filter_map : (G_Src.V.t -> G_Dst.vertex option) -> G_Src.t -> G_Dst.t
(** [filter_map f g] applies [f] to each vertex of [g] and so
builds a new graph based on [g]; if [None] is returned by [f]
the vertex is omitted in the new graph. *)
end
(** {2 Mapping of edges} *)
(** Signature for the source graph. *)
module type E_SRC = sig
type t
module E : Sig.ORDERED_TYPE
val fold_edges_e : (E.t -> 'a -> 'a) -> t -> 'a -> 'a
end
(** Signature for the destination graph. *)
module type E_DST = sig
type t
type edge
val empty : unit -> t
val add_edge_e : t -> edge -> t
end
(** Provide a mapping function from a mapping of edges. *)
module Edge(G_Src: E_SRC)(G_Dst: E_DST) : sig
val map : (G_Src.E.t -> G_Dst.edge) -> G_Src.t -> G_Dst.t
(** [map f g] applies [f] to each edge of [g] and so builds a new graph
based on [g] *)
val filter_map : (G_Src.E.t -> G_Dst.edge option) -> G_Src.t -> G_Dst.t
(** [filter_map f g] applies [f] to each edge of [g] and so builds
a new graph based on [g]; if [None] is returned by [f] the
edge is omitted in the new graph. *)
end
ocamlgraph-2.0.0/src/leaderlist.mli 0000644 0001750 0000144 00000004067 13735627615 015642 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(* Copyright (c) 2010 - 2011 Technische Universitaet Muenchen
* Markus W. Weissmann
* Florian Pichlmeier
* All rights reserved. *)
(** The leader list algorithm; it generates a list of basic blocks from
a directed graph. A basic block is a forward path of nodes that requires
neither branching from nor into.
*)
(** Minimal graph signature for leader list algorithm *)
module type G = sig
type t
module V : Sig.COMPARABLE
val fold_vertex : (V.t -> 'a -> 'a) -> t -> 'a -> 'a
val succ : t -> V.t -> V.t list
val pred : t -> V.t -> V.t list
end
module Make
(G : G) :
sig
val leader_lists : G.t -> G.V.t -> G.V.t list list
(** [leader_lists graph root] computes the leader lists or basic blocks
of the given graph. The node [root] is always a leader of a basic block. *)
end
ocamlgraph-2.0.0/src/persistent.ml 0000644 0001750 0000144 00000023663 13735627615 015544 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
open Sig
open Blocks
module type S = sig
(** Persistent Unlabeled Graphs *)
module Concrete (V: COMPARABLE) :
Sig.P with type V.t = V.t and type V.label = V.t and type E.t = V.t * V.t
and type E.label = unit
(** Abstract Persistent Unlabeled Graphs *)
module Abstract(V: sig type t end) : Sig.P with type V.label = V.t
and type E.label = unit
(** Persistent Labeled Graphs *)
module ConcreteLabeled (V: COMPARABLE)(E: ORDERED_TYPE_DFT) :
Sig.P with type V.t = V.t and type V.label = V.t
and type E.t = V.t * E.t * V.t and type E.label = E.t
(** Abstract Persistent Labeled Graphs *)
module AbstractLabeled (V: sig type t end)(E: ORDERED_TYPE_DFT) :
Sig.P with type V.label = V.t and type E.label = E.t
end
module P = Make(Make_Map)
type 'a abstract_vertex = { tag : int; label : 'a }
(* Vertex for the abstract persistent graphs. *)
module AbstractVertex(V: sig type t end) = struct
type label = V.t
type t = label abstract_vertex
let compare x y = Stdlib.compare x.tag y.tag
let hash x = x.tag
let equal x y = x.tag = y.tag
let label x = x.label
let create l =
if !cpt_vertex = first_value_for_cpt_vertex - 1 then
invalid_arg "Too much vertices";
incr cpt_vertex;
{ tag = !cpt_vertex; label = l }
end
module Digraph = struct
module Concrete(V:COMPARABLE) = struct
include P.Digraph.Concrete(V)
let remove_vertex g v =
if HM.mem v g then
let g = HM.remove v g in
HM.fold (fun k s -> HM.add k (S.remove v s)) g empty
else
g
end
module ConcreteLabeled(V:COMPARABLE)(E:ORDERED_TYPE_DFT) = struct
include P.Digraph.ConcreteLabeled(V)(E)
let remove_vertex g v =
if HM.mem v g then
let g = HM.remove v g in
let remove v = S.filter (fun (v2, _) -> not (V.equal v v2)) in
HM.fold (fun k s -> HM.add k (remove v s)) g empty
else
g
end
module ConcreteBidirectional(V: COMPARABLE) = struct
include P.Digraph.ConcreteBidirectional(V)
let remove_vertex g v =
if HM.mem v g then
let remove v = S.filter (fun v' -> not (V.equal v v')) in
let g =
fold_pred
(fun v' acc ->
let in_set, out_set = HM.find v' acc in
HM.add v' (in_set, remove v out_set) acc)
g v g
in
let g =
fold_succ
(fun v' acc ->
let in_set, out_set = HM.find v' acc in
HM.add v' (remove v in_set, out_set) acc)
g v g
in
HM.remove v g
else
g
end
module ConcreteBidirectionalLabeled(V:COMPARABLE)(E:ORDERED_TYPE_DFT) = struct
include P.Digraph.ConcreteBidirectionalLabeled(V)(E)
let remove_vertex (g:t) (v:vertex) =
if HM.mem v g then
let remove v = S.filter (fun (v', _) -> not (V.equal v v')) in
let g =
fold_pred
(fun v' acc ->
let in_set, out_set = HM.find v' acc in
HM.add v' (in_set, remove v out_set) acc)
g v g
in
let g =
fold_succ
(fun v' acc ->
let in_set, out_set = HM.find v' acc in
HM.add v' (remove v in_set, out_set) acc)
g v g
in
HM.remove v g
else
g
end
module Abstract(V: sig type t end) = struct
include P.Digraph.Abstract(AbstractVertex(V))
let empty = { edges = G.empty; size = 0 }
let add_vertex g v =
if mem_vertex g v then
g
else
{ edges = G.unsafe_add_vertex g.edges v;
size = Stdlib.succ g.size }
let add_edge g v1 v2 =
let g = add_vertex g v1 in
let g = add_vertex g v2 in
{ g with edges = G.unsafe_add_edge g.edges v1 v2 }
let add_edge_e g (v1, v2) = add_edge g v1 v2
let remove_vertex g v =
if HM.mem v g.edges then
let e = HM.remove v g.edges in
let e = HM.fold (fun k s g -> HM.add k (S.remove v s) g) e HM.empty in
{ edges = e; size = Stdlib.pred g.size }
else
g
let remove_edge g v1 v2 = { g with edges = remove_edge g v1 v2 }
let remove_edge_e g e = { g with edges = remove_edge_e g e }
end
module AbstractLabeled(V: sig type t end)(Edge: ORDERED_TYPE_DFT) = struct
include P.Digraph.AbstractLabeled(AbstractVertex(V))(Edge)
let empty = { edges = G.empty; size = 0 }
let add_vertex g v =
if mem_vertex g v then
g
else
{ edges = G.unsafe_add_vertex g.edges v;
size = Stdlib.succ g.size }
let add_edge_e g (v1, l, v2) =
let g = add_vertex g v1 in
let g = add_vertex g v2 in
{ g with edges = G.unsafe_add_edge g.edges v1 (v2, l) }
let add_edge g v1 v2 = add_edge_e g (v1, Edge.default, v2)
let remove_vertex g v =
if HM.mem v g.edges then
let remove v s =
S.fold
(fun (v2, _ as e) s -> if not (V.equal v v2) then S.add e s else s)
s S.empty
in
let edges = HM.remove v g.edges in
{ edges =
HM.fold (fun k s g -> HM.add k (remove v s) g) edges HM.empty;
size = Stdlib.pred g.size }
else
g
let remove_edge g v1 v2 = { g with edges = remove_edge g v1 v2 }
let remove_edge_e g e = { g with edges = remove_edge_e g e }
end
end
module Graph = struct
module Concrete(V: COMPARABLE) = struct
module G = struct include Digraph.Concrete(V) type return = t end
include Blocks.Graph(G)
(* Export some definitions of [G] *)
let empty = G.empty
(* Redefine the [add_edge] and [remove_edge] operations *)
let add_edge g v1 v2 =
let g = G.add_edge g v1 v2 in
assert (G.HM.mem v1 g && G.HM.mem v2 g);
G.unsafe_add_edge g v2 v1
let add_edge_e g (v1, v2) = add_edge g v1 v2
let remove_edge g v1 v2 =
let g = G.remove_edge g v1 v2 in
assert (G.HM.mem v1 g && G.HM.mem v2 g);
G.unsafe_remove_edge g v2 v1
let remove_edge_e g (v1, v2) = remove_edge g v1 v2
end
module ConcreteLabeled(V: COMPARABLE)(Edge: ORDERED_TYPE_DFT) = struct
module G = struct
include Digraph.ConcreteLabeled(V)(Edge)
type return = t
end
include Blocks.Graph(G)
(* Export some definitions of [G] *)
let empty = G.empty
(* Redefine the [add_edge] and [remove_edge] operations *)
let add_edge_e g (v1, l, v2 as e) =
let g = G.add_edge_e g e in
assert (G.HM.mem v1 g && G.HM.mem v2 g);
G.unsafe_add_edge g v2 (v1, l)
let add_edge g v1 v2 = add_edge_e g (v1, Edge.default, v2)
let remove_edge g v1 v2 =
let g = G.remove_edge g v1 v2 in
assert (G.HM.mem v1 g && G.HM.mem v2 g);
G.unsafe_remove_edge g v2 v1
let remove_edge_e g (v1, l, v2 as e) =
let g = G.remove_edge_e g e in
assert (G.HM.mem v1 g && G.HM.mem v2 g);
G.unsafe_remove_edge_e g (v2, l, v1)
end
module Abstract(V: sig type t end) = struct
module G = struct include Digraph.Abstract(V) type return = t end
include Blocks.Graph(G)
(* Export some definitions of [G] *)
let empty = G.empty
(* Redefine the [add_edge] and [remove_edge] operations *)
let add_edge g v1 v2 =
let g = G.add_edge g v1 v2 in
assert (G.HM.mem v1 g.G.edges && G.HM.mem v2 g.G.edges);
{ g with G.edges = G.unsafe_add_edge g.G.edges v2 v1 }
let add_edge_e g (v1, v2) = add_edge g v1 v2
let remove_edge g v1 v2 =
let g = G.remove_edge g v1 v2 in
assert (G.HM.mem v1 g.G.edges && G.HM.mem v2 g.G.edges);
{ g with G.edges = G.unsafe_remove_edge g.G.edges v2 v1 }
let remove_edge_e g (v1, v2) = remove_edge g v1 v2
end
module AbstractLabeled (V: sig type t end)(Edge: ORDERED_TYPE_DFT) = struct
module G = struct
include Digraph.AbstractLabeled(V)(Edge)
type return = t
end
include Blocks.Graph(G)
(* Export some definitions of [G] *)
let empty = G.empty
(* Redefine the [add_edge] and [remove_edge] operations *)
let add_edge_e g (v1, l, v2 as e) =
let g = G.add_edge_e g e in
assert (G.HM.mem v1 g.G.edges && G.HM.mem v2 g.G.edges);
{ g with G.edges = G.unsafe_add_edge g.G.edges v2 (v1, l) }
let add_edge g v1 v2 = add_edge_e g (v1, Edge.default, v2)
let remove_edge g v1 v2 =
let g = G.remove_edge g v1 v2 in
assert (G.HM.mem v1 g.G.edges && G.HM.mem v2 g.G.edges);
{ g with G.edges = G.unsafe_remove_edge g.G.edges v2 v1 }
let remove_edge_e g (v1, l, v2 as e) =
let g = G.remove_edge_e g e in
assert (G.HM.mem v1 g.G.edges && G.HM.mem v2 g.G.edges);
{ g with G.edges = G.unsafe_remove_edge_e g.G.edges (v2, l, v1) }
end
end
(*
Local Variables:
compile-command: "make -C .."
End:
*)
ocamlgraph-2.0.0/src/mcs_m.ml 0000644 0001750 0000144 00000014063 13735627615 014434 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(* $Id: mcs_m.mli,v 1.2 2004-10-19 15:21:44 signoles Exp $ *)
module MaximalCardinalitySearch = struct
module WeightedV(V : Sig.COMPARABLE) = struct
include Util.DataV(struct type t = int end)(V)
let weight = data
let set_weight = set_data
end
module P(Gr : Sig.P) = struct
type edgelist = (Gr.V.t * Gr.V.t) list
module NewV = WeightedV(Gr.V)
module G = Persistent.Graph.Concrete(NewV)
module EdgeSet = Set.Make(G.E)
module VerticesSet = Set.Make(NewV)
module Choose = Oper.Choose(G)
module H = Hashtbl.Make(NewV)
let check_path g u v =
let h = H.create 97 in
let maxw = NewV.weight u in
let rec aux x : bool =
if H.mem h x then
false
else
if G.V.equal x v then true
else
if NewV.weight x < maxw || G.V.equal x u then
begin
H.add h x ();
G.fold_succ
(fun x found ->
if not found then aux x
else found)
g x false
end
else (H.add h x (); false)
in aux u
module Copy = Gmap.Vertex(Gr)(struct include G include Builder.P(G) end)
let fold f d =
let rec aux = function
(true, a) -> aux (f a)
| (false, a) -> a
in aux d
let mcsm g =
let g' = Copy.map (NewV.create 0) g in
let (_, _, ord, triang) =
fold
(fun ((i, g', a, f) as x)->
if i = 0 then (false, x)
else
let v =
G.fold_vertex
(fun x max ->
if NewV.weight x > NewV.weight max then x else max)
g' (ref 0, snd (Choose.choose_vertex g'))
in
let s =
G.fold_vertex
(fun x s ->
if G.V.equal x v then s
else
if check_path g' x v then
VerticesSet.add x s
else s)
g' VerticesSet.empty
in
let f' =
VerticesSet.fold
(fun x f ->
NewV.set_weight x (succ (NewV.weight x));
if not (G.mem_edge g' x v) then
EdgeSet.add (x,v) f
else f)
s f
in
let g' = G.remove_vertex g' v in
let a' = (i, NewV.label v) :: a in
(true, (i - 1, g', a', f')))
(true, (Gr.nb_vertex g, g', [], EdgeSet.empty))
in
(List.rev ord,
EdgeSet.fold
(fun (x, y) e -> (NewV.label x, NewV.label y) :: e)
triang [])
let triangulate g =
let (_, triang) = mcsm g in
List.fold_left (fun g (x, y) -> Gr.add_edge g x y) g triang
end
module I(Gr : Sig.I) = struct
type edgelist = (Gr.V.t * Gr.V.t) list
module NewV = WeightedV(Gr.V)
module G = Imperative.Graph.Concrete(NewV)
module EdgeSet = Set.Make(G.E)
module VerticesSet = Set.Make(NewV)
module Choose = Oper.Choose(G)
module H = Hashtbl.Make(NewV)
let check_path g u v =
let h = H.create 97 in
let maxw = NewV.weight u in
let rec aux x : bool =
if H.mem h x then
false
else
if G.V.equal x v then true
else
if NewV.weight x < maxw || G.V.equal x u then begin
H.add h x ();
G.fold_succ
(fun x found ->
if not found then aux x
else found)
g x false
end else (H.add h x (); false)
in aux u
module Copy = Gmap.Vertex(Gr)(struct include G include Builder.I(G) end)
let mcsm g =
let f = ref EdgeSet.empty
and a = ref []
and g' = Copy.map (NewV.create 0) g in
for i = Gr.nb_vertex g downto 1 do
let v =
G.fold_vertex
(fun x max ->
if NewV.weight x > NewV.weight max then x else max)
g' (ref 0, snd (Choose.choose_vertex g'))
in
let s =
G.fold_vertex
(fun x s ->
if G.V.equal x v then s
else
if check_path g' x v then
VerticesSet.add x s
else s)
g' VerticesSet.empty
in
let f' =
VerticesSet.fold
(fun x f ->
NewV.set_weight x (succ (NewV.weight x));
if not (G.mem_edge g' x v) then
EdgeSet.add (x,v) f
else f)
s !f
in
f := f';
G.remove_vertex g' v;
a := (i, NewV.label v) :: !a;
done;
(List.rev !a,
EdgeSet.fold
(fun (x, y) e -> (NewV.label x, NewV.label y) :: e)
!f [])
let triangulate g =
let (_, triang) = mcsm g in
List.iter (fun (x, y) -> Gr.add_edge g x y) triang
end
end
ocamlgraph-2.0.0/src/prim.ml 0000644 0001750 0000144 00000005751 13735627615 014311 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
module type G = sig
type t
module V : Sig.COMPARABLE
module E : sig
type t
type label
val label : t -> label
val dst : t -> V.t
val src : t -> V.t
val compare : t -> t -> int
end
val iter_vertex : (V.t -> unit) -> t -> unit
val iter_edges_e : (E.t -> unit) -> t -> unit
val iter_succ_e : (E.t -> unit) -> t -> V.t -> unit
end
module Make
(G: G)
(W: Sig.WEIGHT with type edge = G.E.t) =
struct
open G.E
module H = Hashtbl.Make(G.V)
module Elt = struct
type t = W.t * G.V.t
(* weights are compared first, and minimal weights come first in the
queue *)
let compare (w1,v1) (w2,v2) =
let cw = W.compare w2 w1 in
if cw != 0 then cw else G.V.compare v1 v2
end
module Q = Heap.Imperative(Elt)
let spanningtree_from g r =
let visited = H.create 97 in
let key = H.create 97 in
let q = Q.create 17 in
Q.add q (W.zero, r);
while not (Q.is_empty q) do
let (_,u) = Q.pop_maximum q in
if not (H.mem visited u) then begin
H.add visited u ();
G.iter_succ_e (fun e ->
let v = dst e in
if not (H.mem visited v) then begin
let wuv = W.weight e in
let improvement =
try W.compare wuv (fst (H.find key v)) < 0 with Not_found -> true
in
if improvement then begin
H.replace key v (wuv, e);
Q.add q (wuv, v)
end;
end) g u
end
done;
H.fold (fun _ (_, e) acc -> e :: acc) key []
let spanningtree g =
let r = ref None in
try
G.iter_vertex (fun v -> r := Some v; raise Exit) g;
invalid_arg "spanningtree"
with Exit ->
match !r with
| None -> assert false
| Some r -> spanningtree_from g r
end
ocamlgraph-2.0.0/src/traverse.mli 0000644 0001750 0000144 00000012636 13735627615 015346 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(** Graph traversal. *)
(** {2 Dfs and Bfs} *)
(** Minimal graph signature for {!Dfs} and {!Bfs}.
Sub-signature of {!Sig.G}. *)
module type G = sig
val is_directed : bool
type t
module V : Sig.COMPARABLE
val iter_vertex : (V.t -> unit) -> t -> unit
(** It is enough to iter over all the roots (vertices without predecessor) of
the graph, even if iterating over the other vertices is correct. *)
val fold_vertex : (V.t -> 'a -> 'a) -> t -> 'a -> 'a
(** It is enough to fold over all the roots (vertices without predecessor) of
the graph, even if folding over the other vertices is correct. *)
val iter_succ : (V.t -> unit) -> t -> V.t -> unit
val fold_succ : (V.t -> 'a -> 'a) -> t -> V.t -> 'a -> 'a
end
(** Depth-first search *)
module Dfs(G : G) : sig
(** {2 Classical big-step iterators} *)
val iter : ?pre:(G.V.t -> unit) ->
?post:(G.V.t -> unit) -> G.t -> unit
(** [iter pre post g] visits all nodes of [g] in depth-first search,
applying [pre] to each visited node before its successors,
and [post] after them. Each node is visited exactly once.
Not tail-recursive. *)
val prefix : (G.V.t -> unit) -> G.t -> unit
(** applies only a prefix function; note that this function is more
efficient than [iter] and is tail-recursive. *)
val postfix : (G.V.t -> unit) -> G.t -> unit
(** applies only a postfix function. Not tail-recursive. *)
(** Same thing, but for a single connected component
(only [prefix_component] is tail-recursive) *)
val iter_component : ?pre:(G.V.t -> unit) ->
?post:(G.V.t -> unit) -> G.t -> G.V.t -> unit
val prefix_component : (G.V.t -> unit) -> G.t -> G.V.t -> unit
val postfix_component : (G.V.t -> unit) -> G.t -> G.V.t -> unit
(** {2 Classical folds} *)
val fold : (G.V.t -> 'a -> 'a) -> 'a -> G.t -> 'a
(** The function is applied each time a node is reached for the first time,
before idoterating over its successors. Tail-recursive. *)
val fold_component : (G.V.t -> 'a -> 'a) -> 'a -> G.t -> G.V.t -> 'a
(** Idem, but limited to a single root vertex. *)
(** {2 Step-by-step iterator}
This is a variant of the iterators above where you can move on
step by step. The abstract type [iterator] represents the current
state of the iteration. The [step] function returns the next state.
In each state, function [get] returns the currently visited vertex.
On the final state both [get] and [step] raises exception [Exit].
Note: the iterator type is persistent (i.e. is not modified by the
[step] function) and thus can be used in backtracking algorithms. *)
type iterator
val start : G.t -> iterator
val step : iterator -> iterator
val get : iterator -> G.V.t
(** {2 Cycle detection} *)
val has_cycle : G.t -> bool
(** [has_cycle g] checks for a cycle in [g]. Linear in time and space. *)
end
(** Breadth-first search *)
module Bfs(G : G) : sig
(** {2 Classical big-step iterators} *)
val iter : (G.V.t -> unit) -> G.t -> unit
val iter_component : (G.V.t -> unit) -> G.t -> G.V.t -> unit
(** {2 Classical folds} *)
val fold : (G.V.t -> 'a -> 'a) -> 'a -> G.t -> 'a
val fold_component : (G.V.t -> 'a -> 'a) -> 'a -> G.t -> G.V.t -> 'a
(** {2 Step-by-step iterator}
See module [Dfs] *)
type iterator
val start : G.t -> iterator
val step : iterator -> iterator
val get : iterator -> G.V.t
end
(** {2 Traversal with marking}
Provide a more efficient version of depth-first algorithm when graph
vertices are marked. *)
(** Minimal graph signature for graph traversal with marking.
Sub-signature of {!Sig.IM}. *)
module type GM = sig
type t
module V : sig type t end
val iter_vertex : (V.t -> unit) -> t -> unit
val iter_succ : (V.t -> unit) -> t -> V.t -> unit
module Mark : sig
val clear : t -> unit
val get : V.t -> int
val set : V.t -> int -> unit
end
end
(** Graph traversal with marking.
Only applies to imperative graphs with marks. *)
module Mark(G : GM) : sig
val dfs : G.t -> unit
(** [dfs g] traverses [g] in depth-first search, marking all nodes. *)
val has_cycle : G.t -> bool
(** [has_cycle g] checks for a cycle in [g]. Modifies the marks.
Linear time, constant space. *)
end
ocamlgraph-2.0.0/src/flow.mli 0000644 0001750 0000144 00000007303 13735627615 014455 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(** Algorithms on flows
The following flow algorithms only apply to networks, that are
directed graphs together with a source (a 0 in-degree vertex) and a
terminal (a 0 out-degree vertex). *)
(** {1 Maximum flow algorithms} *)
(** Signature for edges' flow. *)
module type FLOW = sig
type t
(** Type of edges. *)
type label
(** Type of labels on edges. *)
(** Maximum and minimum capacities for a label on an edge. *)
val max_capacity : label -> t
(** Current flow for a label on an edge. *)
val flow : label -> t
(** [+] and [-] on flows. *)
val add : t -> t -> t
val sub : t -> t -> t
(** Neutral element for [add] and [sub]. *)
val zero : t
(** A total ordering over flows. *)
val compare : t -> t -> int
end
(** {2 Goldberg-Tarjan maximal flow algorithm} *)
(** Minimal graph signature for Goldberg-Tarjan.
Sub-signature of {!Sig.G}. *)
module type G_GOLDBERG_TARJAN = sig
type t
module V : Sig.COMPARABLE
module E : Sig.EDGE with type vertex = V.t
val nb_vertex : t -> int
val nb_edges : t -> int
val fold_edges_e : (E.t -> 'a -> 'a) -> t -> 'a -> 'a
val fold_succ_e : (E.t -> 'a -> 'a) -> t -> V.t -> 'a -> 'a
val fold_pred_e : (E.t -> 'a -> 'a) -> t -> V.t -> 'a -> 'a
end
module Goldberg_Tarjan
(G: G_GOLDBERG_TARJAN)
(F: FLOW with type label = G.E.label) :
sig
val maxflow : G.t -> G.V.t -> G.V.t -> (G.E.t -> F.t) * F.t
(** [maxflow g v1 v2] searchs the maximal flow from source [v1] to
terminal [v2] using Goldberg-Tarjan algorithm (with gap detection
heuristic).
It returns the flow on each edge and the growth of the flow. *)
end
(** {2 Ford-Fulkerson maximal flow algorithm} *)
(** Minimal digraph signature for Ford-Fulkerson.
Sub-signature of {!Sig.G}. *)
module type G_FORD_FULKERSON = sig
type t
module V : Sig.HASHABLE
module E : sig
type t
type label
val src : t -> V.t
val dst : t -> V.t
val label : t -> label
end
val iter_succ_e : (E.t -> unit) -> t -> V.t -> unit
val iter_pred_e : (E.t -> unit) -> t -> V.t -> unit
end
module type FLOWMIN = sig
include FLOW
val min_capacity : label -> t
end
module Ford_Fulkerson
(G: G_FORD_FULKERSON)
(F: FLOWMIN with type label = G.E.label) :
sig
val maxflow : G.t -> G.V.t -> G.V.t -> (G.E.t -> F.t) * F.t
(** [maxflow g v1 v2] searchs the maximal flow from source [v1]
to terminal [v2] using the Ford-Fulkerson algorithm. It
returns the new flows on each edges and the growth of the
flow. *)
end
ocamlgraph-2.0.0/src/sig_pack.mli 0000644 0001750 0000144 00000035342 13735627615 015272 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(* $Id: sig_pack.mli,v 1.23 2005-07-18 07:10:35 filliatr Exp $ *)
(** Immediate access to the library: contain a signature gathering an
imperative graph signature and all algorithms.
Vertices and edges are labeled with integers. *)
(** Signature gathering an imperative graph signature and all algorithms.
Vertices and edges are labeled with integers. *)
module type S = sig
(** {2 Graph structure} *)
(** abstract type of graphs *)
type t
(** Vertices *)
module V : sig
(** Vertices are [COMPARABLE] *)
type t
val compare : t -> t -> int
val hash : t -> int
val equal : t -> t -> bool
(** vertices are labeled with integers *)
type label = int
val create : label -> t
val label : t -> label
end
type vertex = V.t
(** Edges *)
module E : sig
(** Edges are [ORDERED]. *)
type t
val compare : t -> t -> int
(** Edges are directed. *)
val src : t -> V.t
val dst : t -> V.t
(** Edges are labeled with integers. *)
type label = int
val create : V.t -> label -> V.t -> t
(** [create v1 l v2] creates an edge from [v1] to [v2] with label [l] *)
val label : t -> label
type vertex = V.t
end
type edge = E.t
(** is this an implementation of directed graphs? *)
val is_directed : bool
(** {2 Graph constructors and destructors} *)
val create : ?size:int -> unit -> t
(** Return 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 -> V.t -> unit
(** [add_vertex g v] adds the vertex [v] from the graph [g].
Do nothing if [v] is already in [g]. *)
val remove_vertex : t -> V.t -> 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]. *)
val add_edge : t -> V.t -> V.t -> 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 -> E.t -> 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 -> V.t -> V.t -> unit
(** [remove_edge g v1 v2] removes the edge going from [v1] to [v2] from the
graph [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 -> E.t -> 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]. *)
(** Vertices contains integers marks, which can be set or used by some
algorithms (see for instance module [Marking] below) *)
module Mark : sig
type graph = t
type vertex = V.t
val clear : t -> unit
(** [clear g] sets all marks to 0 from all the vertives of [g]. *)
val get : V.t -> int
val set : V.t -> int -> unit
end
(** {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 -> V.t -> 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 -> V.t -> 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 -> V.t -> bool
val mem_edge : t -> V.t -> V.t -> bool
val mem_edge_e : t -> E.t -> bool
val find_edge : t -> V.t -> V.t -> E.t
val find_all_edges : t -> V.t -> V.t -> E.t list
(** {2 Successors and predecessors of a vertex} *)
val succ : t -> V.t -> V.t list
(** [succ g v] returns the successors of [v] in [g].
@raise Invalid_argument if [v] is not in [g]. *)
val pred : t -> V.t -> V.t 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 -> V.t -> E.t 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 -> V.t -> E.t 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} *)
(** iter/fold on all vertices/edges of a graph *)
val iter_vertex : (V.t -> unit) -> t -> unit
val iter_edges : (V.t -> V.t -> unit) -> t -> unit
val fold_vertex : (V.t -> 'a -> 'a) -> t -> 'a -> 'a
val fold_edges : (V.t -> V.t -> 'a -> 'a) -> t -> 'a -> 'a
(** map iterator on vertex *)
val map_vertex : (V.t -> V.t) -> t -> t
(** iter/fold on all labeled edges of a graph *)
val iter_edges_e : (E.t -> unit) -> t -> unit
val fold_edges_e : (E.t -> 'a -> 'a) -> t -> 'a -> 'a
(** {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]. *)
(** iter/fold on all successors/predecessors of a vertex. *)
val iter_succ : (V.t -> unit) -> t -> V.t -> unit
val iter_pred : (V.t -> unit) -> t -> V.t -> unit
val fold_succ : (V.t -> 'a -> 'a) -> t -> V.t -> 'a -> 'a
val fold_pred : (V.t -> 'a -> 'a) -> t -> V.t -> 'a -> 'a
(** iter/fold on all edges going from/to a vertex. *)
val iter_succ_e : (E.t -> unit) -> t -> V.t -> unit
val fold_succ_e : (E.t -> 'a -> 'a) -> t -> V.t -> 'a -> 'a
val iter_pred_e : (E.t -> unit) -> t -> V.t -> unit
val fold_pred_e : (E.t -> 'a -> 'a) -> t -> V.t -> 'a -> 'a
(** {2 Basic operations} *)
val find_vertex : t -> int -> V.t
(** [vertex g i] returns a vertex of label [i] in [g]. The behaviour is
unspecified if [g] has several vertices with label [i].
Note: this function is inefficient (linear in the number of vertices);
you should better keep the vertices as long as you create them. *)
val transitive_closure : ?reflexive:bool -> t -> t
(** [transitive_closure ?reflexive g] returns the transitive closure
of [g] (as a new graph). Loops (i.e. edges from a vertex to itself)
are added only if [reflexive] is [true] (default is [false]). *)
val add_transitive_closure : ?reflexive:bool -> t -> t
(** [add_transitive_closure ?reflexive g] replaces [g] by its
transitive closure. Meaningless for persistent implementations
(then acts as [transitive_closure]). *)
val transitive_reduction : ?reflexive:bool -> t -> t
(** [transitive_reduction ?reflexive g] returns the transitive reduction
of [g] (as a new graph). Loops (i.e. edges from a vertex to itself)
are removed only if [reflexive] is [true] (default is [false]). *)
val replace_by_transitive_reduction : ?reflexive:bool -> t -> t
(** [replace_by_transitive_reduction ?reflexive g] replaces [g] by its
transitive reduction. Meaningless for persistent implementations
(then acts as [transitive_reduction]). *)
val mirror : t -> t
(** [mirror g] returns a new graph which is the mirror image of [g]:
each edge from [u] to [v] has been replaced by an edge from [v] to [u].
For undirected graphs, it simply returns a copy of [g]. *)
val complement : t -> t
(** [complement g] builds a new graph which is the complement of [g]:
each edge present in [g] is not present in the resulting graph and
vice-versa. Edges of the returned graph are unlabeled. *)
val intersect : t -> t -> t
(** [intersect g1 g2] returns a new graph which is the intersection of [g1]
and [g2]: each vertex and edge present in [g1] *and* [g2] is present
in the resulting graph. *)
val union : t -> t -> t
(** [union g1 g2] returns a new graph which is the union of [g1] and [g2]:
each vertex and edge present in [g1] *or* [g2] is present in the
resulting graph. *)
(** {2 Traversal} *)
(** Depth-first search *)
module Dfs : sig
val iter : ?pre:(V.t -> unit) ->
?post:(V.t -> unit) -> t -> unit
(** [iter pre post g] visits all nodes of [g] in depth-first search,
applying [pre] to each visited node before its successors,
and [post] after them. Each node is visited exactly once. *)
val prefix : (V.t -> unit) -> t -> unit
(** applies only a prefix function *)
val postfix : (V.t -> unit) -> t -> unit
(** applies only a postfix function *)
val fold : (V.t -> 'a -> 'a) -> 'a -> t -> 'a
(** Same thing, but for a single connected component *)
val iter_component :
?pre:(V.t -> unit) ->
?post:(V.t -> unit) -> t -> V.t -> unit
val prefix_component : (V.t -> unit) -> t -> V.t -> unit
val postfix_component : (V.t -> unit) -> t -> V.t -> unit
val fold_component : (V.t -> 'a -> 'a) -> 'a -> t -> V.t -> 'a
val has_cycle : t -> bool
end
(** Breadth-first search *)
module Bfs : sig
val iter : (V.t -> unit) -> t -> unit
val iter_component : (V.t -> unit) -> t -> V.t -> unit
end
(** Graph traversal with marking *)
module Marking : sig
val dfs : t -> unit
val has_cycle : t -> bool
end
(** Coloring *)
module Coloring : sig
val coloring: t -> int -> unit
(** [coloring g k] colors the nodes of graph [g] using [k] colors,
assigning the marks integer values between 1 and [k]. *)
val two_color: t -> unit
(** [two_color g] attemps to color [g] with colors 1 and 2. *)
end
(** {2 Graph generators} *)
(** Classic graphs *)
module Classic : sig
val divisors : int -> t
(** [divisors n] builds the graph of divisors.
Vertices are integers from [2] to [n]. [i] is connected to [j] if
and only if [i] divides [j].
@raise Invalid_argument is [n < 2]. *)
val de_bruijn : int -> t
(** [de_bruijn n] builds the de Bruijn graph of order [n].
Vertices are bit sequences of length [n] (encoded as their
interpretation as binary integers). The sequence [xw] is connected
to the sequence [wy] for any bits [x] and [y] and any bit sequence
[w] of length [n-1].
@raise Invalid_argument is [n < 1] or [n > Sys.word_size-1]. *)
val vertex_only : int -> t
(** [vertex_only n] builds a graph with [n] vertices and no edge. *)
val full : ?self:bool -> int -> t
(** [full n] builds a graph with [n] vertices and all possible edges.
The optional argument [self] indicates if loop edges should be added
(default value is [true]). *)
end
(** Random graphs *)
module Rand : sig
val graph : ?loops:bool -> v:int -> e:int -> unit -> t
(** [random v e] generates a random with [v] vertices and [e] edges. *)
val labeled :
(V.t -> V.t -> E.label) ->
?loops:bool -> v:int -> e:int -> unit -> t
(** [random_labeled f] is similar to [random] except that edges are
labeled using function [f] *)
val gnp : ?loops:bool -> v:int -> prob:float -> unit -> t
(** [gnp v prob] generates a random graph with [v] vertices and
where each edge is selected with probality [prob] (G(n,p) model) *)
val gnp_labeled :
(V.t -> V.t -> E.label) ->
?loops:bool -> v:int -> prob:float -> unit -> t
(** [gnp_labeled add_edge v prob] is similar to [gnp] except that
edges are labeled using function [f] *)
end
(** Strongly connected components *)
module Components : sig
val scc : t -> int * (V.t -> int)
(** strongly connected components *)
val scc_array : t -> V.t list array
val scc_list : t -> V.t list list
end
(** {2 Classical algorithms} *)
val shortest_path : t -> V.t -> V.t -> E.t list * int
(** Dijkstra's shortest path algorithm. Weights are the labels. *)
val ford_fulkerson : t -> V.t -> V.t -> (E.t -> int) * int
(** Ford Fulkerson maximum flow algorithm *)
val goldberg_tarjan : t -> V.t -> V.t -> (E.t -> int) * int
(** Goldberg-Tarjan maximum flow algorithm *)
val bellman_ford : t -> V.t -> E.t list
(** [bellman_ford g v] finds a negative cycle from [v], and returns it,
or raises [Not_found] if there is no such cycle *)
(** Path checking *)
module PathCheck : sig
type path_checker
val create : t -> path_checker
val check_path : path_checker -> V.t -> V.t -> bool
end
(** Topological order *)
module Topological : sig
val fold : (V.t -> 'a -> 'a) -> t -> 'a -> 'a
val iter : (V.t -> unit) -> t -> unit
val fold_stable : (V.t -> 'a -> 'a) -> t -> 'a -> 'a
val iter_stable : (V.t -> unit) -> t -> unit
end
val spanningtree : t -> E.t list
(** Kruskal algorithm *)
(** {2 Input / Output} *)
val dot_output : t -> string -> unit
(** DOT output in a file *)
val display_with_gv : t -> unit
(** Displays the given graph using the external tools "dot" and "gv"
and returns when gv's window is closed *)
val parse_gml_file : string -> t
val parse_dot_file : string -> t
val print_gml : Format.formatter -> t -> unit
val print_gml_file : t -> string -> unit
(* val print_graphml : Format.formatter -> t -> unit *)
end
ocamlgraph-2.0.0/src/clique.mli 0000644 0001750 0000144 00000003014 13735627615 014763 0 ustar rt users (**************************************************************************)
(* *)
(* Ocamlgraph: a generic graph library for OCaml *)
(* Copyright (C) 2014-2015 *)
(* Giselle Reis *)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(** Graph cliques *)
(** {1 Clique algorithms} *)
(** {2 Bron-Kerbosch Algorithm}
This algorithm will find and return all maximal cliques in an undirected graph. *)
(** Minimal graph signature for Bron-Kerbosch.
Sub-signature of {!Sig.G}. *)
module type G = sig
type t
module V : Sig.COMPARABLE
val succ : t -> V.t -> V.t list
val fold_vertex : (V.t -> 'a -> 'a) -> t -> 'a -> 'a
end
module Bron_Kerbosch(G : G) : sig
val maximalcliques : G.t -> G.V.t list list
(** [maximalcliques g] computes all the maximal cliques of [g] using the
Bron-Kerbosch algorithm. It returns the sets of vertices belonging to the
same maximal clique. *)
end
ocamlgraph-2.0.0/src/graph.ml 0000644 0001750 0000144 00000002364 13735627615 014440 0 ustar rt users module Sig = Sig
module Sig_pack = Sig_pack
module Dot_ast = Dot_ast
module Util = Util
module Blocks = Blocks
module Persistent = Persistent
module Imperative = Imperative
module Delaunay = Delaunay
module Builder = Builder
module Classic = Classic
module Rand = Rand
module Oper = Oper
module Components = Components
module Path = Path
module Nonnegative = Nonnegative
module Traverse = Traverse
module Coloring = Coloring
module Topological = Topological
module Kruskal = Kruskal
module Flow = Flow
module Prim = Prim
module Dominator = Dominator
module Graphviz = Graphviz
module Gml = Gml
module Dot = Dot
module Pack = Pack
module Gmap = Gmap
module Minsep = Minsep
module Cliquetree = Cliquetree
module Mcs_m = Mcs_m
module Md = Md
module Strat = Strat
module Fixpoint = Fixpoint
module Leaderlist = Leaderlist
module Contraction = Contraction
module Graphml = Graphml
module Merge = Merge
module Mincut = Mincut
module Clique = Clique
module WeakTopological = WeakTopological
module ChaoticIteration = ChaoticIteration
module XDotDraw = XDotDraw
module XDot = XDot
module DGraphModel = DGraphModel
module DGraphTreeLayout = DGraphTreeLayout
module DGraphSubTree = DGraphSubTree
module DGraphTreeModel = DGraphTreeModel
module DGraphRandModel = DGraphRandModel
ocamlgraph-2.0.0/src/dune 0000644 0001750 0000144 00000000324 13735627615 013655 0 ustar rt users (include_subdirs unqualified)
(library
(name graph)
(public_name ocamlgraph)
(libraries stdlib-shims)
(modules_without_implementation dot_ast sig sig_pack))
(ocamlyacc dot_parser)
(ocamllex gml dot_lexer)
ocamlgraph-2.0.0/src/components.mli 0000644 0001750 0000144 00000006304 13735627615 015673 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(** Strongly connected components. *)
(** Minimal graph signature required by {!Make}.
Sub-signature of {!Sig.G}. *)
module type G = sig
type t
module V : Sig.COMPARABLE
val iter_vertex : (V.t -> unit) -> t -> unit
val iter_succ : (V.t -> unit) -> t -> V.t -> unit
end
(** Functor providing functions to compute strongly connected components of a
graph. *)
module Make (G: G) : sig
val scc : G.t -> int * (G.V.t -> int)
(** [scc g] computes the strongly connected components of [g].
The result is a pair [(n,f)] where [n] is the number of
components. Components are numbered from [0] to [n-1], and
[f] is a function mapping each vertex to its component
number. In particular, [f u = f v] if and only if [u] and
[v] are in the same component. Another property of the
numbering is that components are numbered in a topological
order: if there is an arc from [u] to [v], then [f u >= f u]
Not tail-recursive.
Complexity: O(V+E)
The function returned has complexity O(1) *)
val scc_array : G.t -> G.V.t list array
(** [scc_array g] computes the strongly connected components of [g].
Components are stored in the resulting array, indexed with a
numbering with the same properties as for [scc] above. *)
val scc_list : G.t -> G.V.t list list
(** [scc_list g] computes the strongly connected components of [g].
The result is a partition of the set of the vertices of [g].
The [n]-th components is [(scc_array g).(n-1)]. *)
end
(** Connected components (for undirected graphs).
The implementation uses union-find. Time complexity is (quasi) O(V+E).
Space complexity is O(V). *)
module type U = sig
type t
module V : Sig.COMPARABLE
val iter_vertex : (V.t -> unit) -> t -> unit
val iter_edges : (V.t -> V.t -> unit) -> t -> unit
end
module Undirected(G: U) : sig
val components: G.t -> int * (G.V.t -> int)
val components_array: G.t -> G.V.t list array
val components_list: G.t -> G.V.t list list
end
ocamlgraph-2.0.0/src/dominator.mli 0000644 0001750 0000144 00000014070 13735627615 015501 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(*
Copyright © 2009 Carnegie-Mellon University, David Brumley, and Ivan Jager.
From the BAP library; see http://bap.ece.cmu.edu
Modified by OCamlGraph's authors.
*)
(** Dominators
All of the functions in this module assume that the graph is not modified
between calling one of these functions and using the returned functions.
Such mutation results in undefined behavior.
@author Ivan Jager
*)
exception Unreachable
module type G = sig
type t
module V : Sig.COMPARABLE
val pred : t -> V.t -> V.t list
val succ : t -> V.t -> V.t list
val fold_vertex : (V.t -> 'a -> 'a) -> t -> 'a -> 'a
val iter_vertex : (V.t -> unit) -> t -> unit
val iter_succ : (V.t -> unit) -> t -> V.t -> unit
val nb_vertex : t -> int
end
module type S = sig
type t (** type of graphs *)
type vertex (** type of vertices *)
module S: Set.S with type elt = vertex
(** function from [n] to [n]'s immediate dominator *)
type idom = vertex -> vertex
(** [idoms x y] is true when [x] is [y]'s immediate dominator *)
type idoms = vertex -> vertex -> bool
(** function from [x] to a list of nodes immediately dominated by [x] *)
type dom_tree = vertex -> vertex list
(** function from node to a list of nodes that dominate it. *)
type dominators = vertex -> vertex list
(** [dom x y] returns true iff [x] dominates [y] *)
type dom = vertex -> vertex -> bool
(** [sdom x y] returns true iff [x] strictly dominates [y]. *)
type sdom = vertex -> vertex -> bool
(** function from [x] to a list of nodes not dominated by [x], but with
predecessors which are dominated by [x] *)
type dom_frontier = vertex -> vertex list
(** Computes the dominator tree, using the Lengauer-Tarjan algorithm.
[compute_idom cfg s0] returns a function [idom : V.t -> V.t] s.t.
[idom x] returns the immediate dominator of [x]. *)
val compute_idom: t -> vertex -> vertex -> vertex
(** Given a function from a node to it's dominators, returns a function
[dom : V.t -> V.t -> bool] s.t. [dom x y] returns true when
[x] dominates [y]. *)
val dominators_to_dom: ('a -> S.t) -> vertex -> 'a -> bool
(** Given a function from a node to it's dominators, returns a function
[sdom : V.t -> V.t -> bool] s.t. [sdom x y] returns true when
[x] strictly dominates [y]. *)
val dominators_to_sdom: (vertex -> S.t) -> vertex -> vertex -> bool
val dom_to_sdom: (vertex -> vertex -> bool) -> vertex -> vertex -> bool
(** Given a a function from a node to it's dominators, returns a function
from a node to it's strict dominators. *)
val dominators_to_sdominators: (vertex -> S.t) -> vertex -> S.t
(** Given a function from a node to it's dominators, returns a function
[idoms : vertex -> vertex -> bool] s.t. [idoms x y] returns true when
[x] is the immediate dominator of [y]. *)
val dominators_to_idoms : (vertex -> S.t) -> vertex -> vertex -> bool
(** Computes a dominator tree (function from x to a list of nodes immediately
dominated by x) for the given CFG and dominator function.
Note: The dominator tree is also called [IDom] by Muchnick.
Note: If you are computing a post-dominator tree, then the
optional argument pred should be G.succ. *)
val dominators_to_dom_tree:
t ->
?pred:(t -> vertex -> vertex list) -> (vertex -> S.t) -> vertex -> S.t
(** Computes a dominator tree (function from x to a list of nodes immediately
dominated by x) for the given CFG and idom function. *)
val idom_to_dom_tree: t -> (vertex -> vertex) -> vertex -> vertex list
val idom_to_idoms: idom -> vertex -> vertex -> bool
(** Computes the dominance frontier.
As specified in section 19.1 of Modern Compiler Implementation in ML
by Andrew Appel. *)
val compute_dom_frontier: t -> dom_tree -> idom -> vertex -> vertex list
val idom_to_dominators: ('a -> 'a) -> 'a -> 'a list
val idom_to_dom: (vertex -> vertex) -> vertex -> vertex -> bool
end
module Make(G : G) : S with type t = G.t and type vertex = G.V.t
module type I = sig
include G
val empty: unit -> t
val add_edge: t -> V.t -> V.t -> t
end
module Make_graph(G:I): sig
include S with type t = G.t and type vertex = G.V.t
type dom_graph = unit -> t
type dom_functions = {
idom: idom;
idoms: idoms;
dom_tree: dom_tree;
dominators: dominators;
dom: dom;
sdom: sdom;
dom_frontier: dom_frontier;
dom_graph: dom_graph
}
val compute_dom_graph : G.t -> dom_tree -> G.t
(** Computes all dominance functions.
This function computes some things eagerly and some lazily, so don't
worry about it doing extra work to compute functions you don't need,
but also don't call it if you aren't going to use anything it returns.
@return a record containing all dominance functions for the given graph
and entry node.
*)
val compute_all : G.t -> vertex -> dom_functions
end
ocamlgraph-2.0.0/src/merge.mli 0000644 0001750 0000144 00000016210 13735627615 014602 0 ustar rt users (**************************************************************************)
(* *)
(* Ocamlgraph: a generic graph library for OCaml *)
(* Copyright (C) 2004-2012 *)
(* 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. *)
(* *)
(**************************************************************************)
(** Provides functions to extend any module satisfying one of the signatures
Sig.P, Sig.I and Builder.S .*)
module type S = sig
type graph
type vertex
type edge
type edge_label
val merge_vertex: graph -> vertex list -> graph
(** If no element of [vl] belongs to [g] then [merge_vertex g (v::vl)] is the
graph [g]. Otherwise the collection of vertices of [merge_vertex g
(v::vl)] is the collection of vertices of [g] from which all the elements
of [vl] were removed and to which [v] was added. Any edge of [merge_vertex
g (v::vl)] is an edge of [g] whose source (destination) was changed to [v]
if it belongs to [vl]. The function [merge_vertex] always returns a graph
with a smaller collection of vertices and a smaller collection of edges
(in the weak sense). However the labels appearing in [merge_vertex g
v::vl] are exactly the ones appearing in [g].*)
val merge_edges_e: ?src:vertex -> ?dst:vertex -> graph -> edge list -> graph
(** If no element of [el] belongs to [g] then [merge_edges_e g (e::el)] is the
graph [g]. Otherwise the collection of vertices of [merge_edges_e g
(e::el)] is precisely the collection of vertices of [g] from which the
sources and the destinations of all the elements of [el] were removed and
to which the vertices [v] and [w] were added. If [dst] was provided then
[v] is [src] otherwise it is the source of [e]. If [dst] was provided then
[w] is [y] otherwise it is the destination of [e]. The collection of edges
of [merge_edges_e g e::el] is precisely the collection of edges of [g]
from which all the elements of [el] were removed and to which an edge from
[v] to [w] sharing the label of [e] was added; the edges of [g] being
understood up to the fact their source and destination were updated. Note
[v=w] if and only if the source of some element of [el] matches the
destination of some element of [el] (possibly the same).*)
val merge_edges_with_label:
?src:vertex -> ?dst:vertex -> ?label:edge_label -> graph -> edge_label
-> graph
(** The graph [merge_edges_with_label ?src ?tgt ?label g l] is the graph
[merge_edges_e ?src ?dst g el] with [el] being the list of all edges of
[g] carrying the label [l]. If the optional value [label] is provided then
the edge to which all the elements of [el] are identified carries the
label [label]. Otherwise it carries the label [l]. In particular
[merge_edges_with_label ?src ?tgt ?label g l] is the graph [g] if and only
if there is at most one edge of [g] carrying the label [l].*)
val merge_isolabelled_edges: graph -> graph
(** The graph [merge_isolabelled_edges g] is obtained from [g] by
identifying two vertices when they are the sources (destinations) of two
edges sharing the same label. Therefore two distinct edges of the
returned graph cannot carry the same label. In particular if all the
edges share the same label then the returned graph is either empty (if
[g] is so) or a single vertex (if [g] has no edge and at least one
vertex) or a single vertex and a single edge (if [g] has both a vertex
and an edge). A label is carried by some edge of
[merge_isolabelled_edges g] if and only if it is carried by some edge of
[g].*)
val merge_ends: ?strict:bool -> ?specified_vertex:vertex -> graph -> graph
(** A vertex [v] of [g] is called an end if every edge of [g] arriving to [v]
also starts from [v]. It is called a strict end if no edge of [g] arrives
to it. The graph [merge_ends g] is the graph [merge_vertex vl] where [vl]
is the list of (strict) ends of [g]. The vertex substituted to the ends
can be specified.*)
val merge_starts: ?strict:bool -> ?specified_vertex:vertex -> graph -> graph
(** A vertex [v] of [g] is called a start if every edge of [g] starting from
[v] also arrives to [v]. It is called a strict start if no edge of [g]
starts from it. The graph [merge_starts g] is the graph [merge_vertex vl]
where [vl] is the list of (strict) starts of [g]. The vertex substituted
to the starts can be specified.*)
val merge_scc:
?loop_killer:bool -> ?specified_vertex:(vertex list -> vertex) -> graph ->
graph
(** The vertex of every strongly connected component are identified. If the
option [loop_killer] is set to [true] then all the edges between identified
vertices are removed. The option [specified_vertex] allows to choose the
vertex that replaces the elements of a strongly connected component.*)
end
(** Extension for the module [X].*)
module B(X: Builder.S) : S with type graph = X.G.t
and type vertex := X.G.vertex
and type edge := X.G.edge
and type edge_label = X.G.E.label
(**Extension for the module [G].*)
module P(G: Sig.P): S with type graph = G.t
and type vertex := G.vertex
and type edge := G.edge
and type edge_label = G.E.label
(**Extension for the module [G].*)
module I(G: Sig.I): sig
(** Same specification than module type {!S} but modify the graph inplace
instead of returning a new graph. *)
type graph = G.t
type vertex = G.vertex
type edge = G.edge
type edge_label = G.E.label
val merge_vertex: graph -> vertex list -> unit
val merge_edges_e: ?src:vertex -> ?dst:vertex -> graph -> edge list -> unit
val merge_edges_with_label:
?src:vertex -> ?dst:vertex -> ?label:edge_label -> graph -> edge_label
-> unit
val merge_isolabelled_edges: graph -> unit
val merge_ends: ?strict:bool -> ?specified_vertex:vertex -> graph -> unit
val merge_starts: ?strict:bool -> ?specified_vertex:vertex -> graph -> unit
val merge_scc:
?loop_killer:bool -> ?specified_vertex:(vertex list -> vertex) -> graph ->
unit
end
(*
Local Variables:
compile-command: "make -C .."
End:
*)
(*OCaml >= 3.12*)
ocamlgraph-2.0.0/src/oper.mli 0000644 0001750 0000144 00000012206 13735627615 014451 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(** Basic operations over graphs *)
(** {2 Basic operations over graphs} *)
module type S = sig
type g
val transitive_closure : ?reflexive:bool -> g -> g
(** [transitive_closure ?reflexive g] returns the transitive closure
of [g] (as a new graph). Loops (i.e. edges from a vertex to itself)
are added only if [reflexive] is [true] (default is [false]). *)
val add_transitive_closure : ?reflexive:bool -> g -> g
(** [add_transitive_closure ?reflexive g] replaces [g] by its
transitive closure. Meaningless for persistent implementations
(then acts as [transitive_closure]). *)
val transitive_reduction : ?reflexive:bool -> g -> g
(** [transitive_reduction ?reflexive g] returns the transitive reduction
of [g] (as a new graph). Loops (i.e. edges from a vertex to itself)
are removed only if [reflexive] is [true] (default is [false]). *)
val replace_by_transitive_reduction : ?reflexive:bool -> g -> g
(** [replace_by_transitive_reduction ?reflexive g] replaces [g] by its
transitive reduction. Meaningless for persistent implementations
(then acts as [transitive_reduction]). *)
val mirror : g -> g
(** [mirror g] returns a new graph which is the mirror image of [g]:
each edge from [u] to [v] has been replaced by an edge from [v] to [u].
For undirected graphs, it simply returns [g].
Note: Vertices are shared between [g] and [mirror g]; you may need to
make a copy of [g] before using [mirror] *)
val complement : g -> g
(** [complement g] returns a new graph which is the complement of [g]:
each edge present in [g] is not present in the resulting graph and
vice-versa. Edges of the returned graph are unlabeled. *)
val intersect : g -> g -> g
(** [intersect g1 g2] returns a new graph which is the intersection of [g1]
and [g2]: each vertex and edge present in [g1] *and* [g2] is present
in the resulting graph. *)
val union : g -> g -> g
(** [union g1 g2] returns a new graph which is the union of [g1] and [g2]:
each vertex and edge present in [g1] *or* [g2] is present in the
resulting graph. *)
end
module Make(B : Builder.S) : S with type g = B.G.t
(** Basic operations over graphs *)
module P(G : Sig.P) : S with type g = G.t
(** Basic operations over persistent graphs *)
module I(G : Sig.I) : S with type g = G.t
(** Basic operations over imperative graphs *)
(** {2 Choose} *)
(** Choose an element in a graph *)
module Choose(G : sig
type t
type vertex
type edge
val iter_vertex : (vertex -> unit) -> t -> unit
val iter_edges_e : (edge -> unit) -> t -> unit
end) :
sig
val choose_vertex : G.t -> G.vertex
(** [choose_vertex g] returns a vertex from the graph.
@raise Invalid_argument if the graph is empty. *)
val choose_edge : G.t -> G.edge
(** [choose_edge g] returns an edge from the graph.
@raise Invalid_argument if the graph has no edge. *)
end
(** {2 Neighbourhood} *)
(** Neighbourhood of vertex / vertices *)
module Neighbourhood(G : sig
type t
module V : Sig.COMPARABLE
val fold_succ: (V.t -> 'a -> 'a) -> t -> V.t -> 'a -> 'a
val succ: t -> V.t -> V.t list
end) :
sig
module Vertex_Set : Set.S with type elt = G.V.t
(** The neighbourhood of a vertex [v] is
\{ v' | (succ g v) and (v <> v') \} *)
val list_from_vertex : G.t -> G.V.t -> G.V.t list
(** Neighbourhood of a vertex as a list. *)
val set_from_vertex : G.t -> G.V.t -> Vertex_Set.t
(** Neighbourhood of a vertex as a set.
Less efficient that [list_from_vertex]. *)
(** The neighbourhood of a set [S] of vertices is [U \ S] where
[U] is the union of neighbourhoods of each vertex of [S]. *)
val list_from_vertices : G.t -> G.V.t list -> G.V.t list
(** Neighbourhood of a list of vertices as a list. *)
val set_from_vertices : G.t -> G.V.t list -> Vertex_Set.t
(** Neighbourhood of a list of vertices as a set.
More efficient that [list_from_vertices]. *)
end
ocamlgraph-2.0.0/src/contraction.ml 0000644 0001750 0000144 00000006047 13735627615 015664 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(* Copyright (c) 2012 Technische Universitaet Muenchen
* Markus W. Weissmann
* All rights reserved. *)
(* Edge contraction for directed, edge-labeled graphs *)
module type G = sig
type t
module V : Sig.COMPARABLE
type vertex = V.t
module E : Sig.EDGE with type vertex = vertex
type edge = E.t
val empty : t
val add_edge_e : t -> edge -> t
val fold_edges_e : (edge -> 'a -> 'a) -> t -> 'a -> 'a
val fold_vertex : (vertex -> 'a -> 'a) -> t -> 'a -> 'a
end
module Make
(G : G) =
struct
module M = Map.Make(G.V)
module S = Set.Make(G.V)
let contract prop g =
(* if the edge is to be removed (property = true):
* make a union of the two union-sets of start and end node;
* put this set in the map for all nodes in this set *)
let f edge m =
if prop edge then
let s_src, s_dst = M.find (G.E.src edge) m, M.find (G.E.dst edge) m in
let s = S.union s_src s_dst in
S.fold (fun vertex m -> M.add vertex s m) s m
else
m
in
(* if the edge is to be kept, add it to the new graph, exchanging
* the start and end node with the minimum element from the set of
* to-be-unified nodes; 'minimum is an arbitrary choice: any
* deterministic choice will do *)
let add m edge g =
if prop edge then
g
else
let lookup n = S.min_elt (M.find n m) in
G.add_edge_e g
(G.E.create (lookup (G.E.src edge)) (G.E.label edge)
(lookup (G.E.dst edge)))
in
(* initialize map with singleton-sets for every node (of itself) *)
let m =
G.fold_vertex (fun vertex m -> M.add vertex (S.singleton vertex) m)
g M.empty
in
(* find all closures *)
let m = G.fold_edges_e f g m in
(* rewrite the node numbers to close the gaps *)
G.fold_edges_e (add m) g G.empty
end
ocamlgraph-2.0.0/src/graphviz.ml 0000644 0001750 0000144 00000105401 13735627615 015165 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(** Interface with {i GraphViz}
This module provides a basic interface with dot and neato,
two programs of the GraphViz toolbox.
These tools are available at the following URLs:
http://www.graphviz.org/
http://www.research.att.com/sw/tools/graphviz/ *)
open Format
(***************************************************************************)
(** {2 Common stuff} *)
(** Because the neato and dot engines present a lot of common points -
in particular in the graph description language, large parts of
the code is shared. First, the [!CommonAttributes] module defines
attributes of graphs, nodes and edges that are understood by the
two engines. Second, given a module (of type [!ENGINE])
describing an engine the [!MakeEngine] functor provides suitable
interface function for it. *)
(*-------------------------------------------------------------------------*)
(** {3 Common attributes} *)
type color = int
type color_with_transparency = int32
let color_to_color_with_transparency color =
Int32.add (Int32.shift_left (Int32.of_int color) 8) 0xFFl
let fprint_color ppf color =
fprintf ppf "\"#%06X\"" color
let fprint_color_with_transparency ppf color =
fprintf ppf "\"#%08lX\"" color
let fprint_string ppf s = fprintf ppf "\"%s\"" s
(* let s' = String.escaped s in
if s' = s && s <> ""
then fprintf ppf "%s" s
else fprintf ppf "\"%s\"" s'*)
let fprint_string_user ppf s =
(* let s = String.escaped s in*)
fprintf ppf "\"%s\"" s
let fprint_htmlstring_user ppf s = fprintf ppf "<%s>" s
let fprint_square_not_empty printer ppf = function
| [] -> ()
| l -> fprintf ppf " [%a]" printer l
type arrow_style =
[ `None | `Normal | `Onormal | `Inv | `Dot | `Odot | `Invdot | `Invodot ]
let fprint_arrow_style ppf = function
`None -> fprintf ppf "none"
| `Normal -> fprintf ppf "normal"
| `Onormal -> fprintf ppf "onormal"
| `Inv -> fprintf ppf "inv"
| `Dot -> fprintf ppf "dot"
| `Odot -> fprintf ppf "odot"
| `Invdot -> fprintf ppf "invdot"
| `Invodot -> fprintf ppf "invodot"
let fprint_dir ppf = function
`TopToBottom -> fprintf ppf "TB"
| `BottomToTop -> fprintf ppf "BT"
| `LeftToRight -> fprintf ppf "LR"
| `RightToLeft -> fprintf ppf "RL"
type symbseq =
| COMMA
| SEMI
let fprint_symbseq ppf = function
| COMMA -> pp_print_string ppf ","
| SEMI -> pp_print_string ppf ";"
(** The [ATTRIBUTES] module type defines the interface for the engines. *)
module type ATTRIBUTES = sig
type graph (** Attributes of graphs. *)
type vertex (** Attributes of vertices. *)
type edge (** Attributes of edges. *)
(** Attributes of (optional) boxes around vertices. *)
type subgraph = {
sg_name : string; (** Box name. *)
sg_attributes : vertex list; (** Box attributes. *)
sg_parent : string option; (** Nested subgraphs. *)
}
end
(** The [CommonAttributes] module defines attributes for graphs, nodes and
edges that are available in the two engines, dot and neato. *)
module CommonAttributes = struct
(** Attributes of graphs. *)
type graph =
[ `Center of bool
(** Centers the drawing on the page. Default value is [false]. *)
| `Fontcolor of color
(** Sets the font color. Default value is [black]. *)
| `Fontname of string
(** Sets the font family name. Default value is ["Times-Roman"]. *)
| `Fontsize of int
(** Sets the type size (in points). Default value is [14]. *)
| `Label of string
(** Caption for graph drawing. *)
| `HtmlLabel of string
| `Orientation of [ `Portrait | `Landscape ]
(** Sets the page orientation. Default value is [`Portrait]. *)
| `Page of float * float
(** Sets the PostScript pagination unit, e.g [8.5, 11.0]. *)
| `Pagedir of [ `TopToBottom | `LeftToRight ]
(** Traversal order of pages. Default value is [`TopToBottom]. *)
| `Size of float * float
(** Sets the bounding box of drawing (in inches). *)
| `OrderingOut
(** Constrains order of out-edges in a subgraph according to
their file sequence *)
]
(** Attributes of nodes. *)
type vertex =
[ `Color of color
(** Sets the color of the border of the node. Default value is [black]
*)
| `ColorWithTransparency of color_with_transparency
(** Sets the color of the border of the vertex with a transparency
component. Default value is fully opaque [black] *)
| `Fontcolor of color
(** Sets the label font color. Default value is [black]. *)
| `Fontname of string
(** Sets the label font family name. Default value is
["Times-Roman"]. *)
| `Fontsize of int
(** Sets the label type size (in points). Default value is [14]. *)
| `Height of float
(** Sets the minimum height. Default value is [0.5]. *)
| `Label of string
(** Sets the label printed in the node. The string may include escaped
newlines [\n], [\l], or [\r] for center, left, and right justified
lines.
Record labels may contain recursive box lists delimited by { | }.
*)
| `HtmlLabel of string
| `Orientation of float
(** Node rotation angle, in degrees. Default value is [0.0]. *)
| `Penwidth of float
(** Width of the pen (in points) used to draw the border of the node.
Default value is [1.0]. *)
| `Peripheries of int
(** Sets the number of periphery lines drawn around the polygon. *)
| `Regular of bool
(** If [true], then the polygon is made regular, i.e. symmetric about
the x and y axis, otherwise the polygon takes on the aspect
ratio of the label. Default value is [false]. *)
| `Shape of
[`Ellipse | `Box | `Circle | `Doublecircle | `Diamond
| `Oval | `Egg | `Triangle | `Invtriangle
| `Trapezium | `Invtrapezium
| `House | `Invhouse
| `Parallelogram | `Doubleoctagon | `Tripleoctagon
| `Mdiamond | `Mcircle | `Msquare
| `Star | `Underline
| `Note | `Tab | `Folder
| `Box3d | `Component | `Promoter
| `Cds
| `Terminator | `Utr | `Primersite
| `Restrictionsite
| `Fivepoverhang | `Threepoverhang | `Noverhang
| `Assembly | `Signature | `Insulator | `Ribosite | `Rnastab
| `Proteasesite | `Proteinstab | `Rpromoter | `Rarrow
| `Larrow | `Lpromoter
| `Plaintext | `Record | `Polygon of int * float]
(** Sets the shape of the node. Default value is [`Ellipse].
[`Polygon (i, f)] draws a polygon with [n] sides and a skewing
of [f]. *)
| `Style of
[ `Rounded | `Filled | `Solid | `Dashed | `Dotted | `Bold | `Invis ]
(** Sets the layout style of the node. Several styles may be combined
simultaneously. *)
| `Width of float
(** Sets the minimum width. Default value is [0.75]. *)
]
(** Attributes of edges. *)
type edge =
[ `Color of color
(** Sets the edge stroke color. Default value is [black]. *)
| `ColorWithTransparency of color_with_transparency
(** Sets the color of the border of the vertex with a transparency
component. Default value is fully opaque [black] *)
| `Decorate of bool
(** If [true], draws a line connecting labels with their edges. *)
| `Dir of [ `Forward | `Back | `Both | `None ]
(** Sets arrow direction. Default value is [`Forward]. *)
| `Fontcolor of color
(** Sets the label font color. Default value is [black]. *)
| `Fontname of string
(** Sets the label font family name. Default value is
["Times-Roman"]. *)
| `Fontsize of int
(** Sets the label type size (in points). Default value is [14]. *)
| `Label of string
(** Sets the label to be attached to the edge. The string may include
escaped newlines [\n], [\l], or [\r] for centered, left, or right
justified lines. *)
| `HtmlLabel of string
| `Labelfontcolor of color
(** Sets the font color for head and tail labels. Default value is
[black]. *)
| `Labelfontname of string
(** Sets the font family name for head and tail labels. Default
value is ["Times-Roman"]. *)
| `Labelfontsize of int
(** Sets the font size for head and tail labels (in points).
Default value is [14]. *)
| `Penwidth of float
(** Width of the pen (in points) used to draw the edge. Default value
is [1.0]. *)
| `Style of [ `Solid | `Dashed | `Dotted | `Bold | `Invis ]
(** Sets the layout style of the edge. Several styles may be combined
simultaneously. *)
]
(** Pretty-print. *)
let fprint_orientation ppf = function
`Portrait -> fprintf ppf "portrait"
| `Landscape -> fprintf ppf "landscape"
let fprint_graph ppf = function
`Center b -> fprintf ppf "center=%i" (if b then 1 else 0)
| `Fontcolor a -> fprintf ppf "fontcolor=%a" fprint_color a
| `Fontname s -> fprintf ppf "fontname=%a" fprint_string s
| `Fontsize i -> fprintf ppf "fontsize=%i" i
| `Label s -> fprintf ppf "label=%a" fprint_string_user s
| `HtmlLabel s -> fprintf ppf "label=%a" fprint_htmlstring_user s
| `Orientation a -> fprintf ppf "orientation=%a" fprint_orientation a
| `Page (x, y) -> fprintf ppf "page=\"%f,%f\"" x y
| `Pagedir a -> fprintf ppf "pagedir=%a" fprint_dir a
| `Size (x, y) -> fprintf ppf "size=\"%f,%f\"" x y
| `OrderingOut -> fprintf ppf "ordering=out"
let fprint_shape ppf = function
| `Ellipse -> fprintf ppf "ellipse"
| `Box -> fprintf ppf "box"
| `Circle -> fprintf ppf "circle"
| `Doublecircle -> fprintf ppf "doublecircle"
| `Diamond -> fprintf ppf "diamond"
| `Plaintext -> fprintf ppf "plaintext"
| `Record -> fprintf ppf "record"
| `Egg -> fprintf ppf "egg"
| `House -> fprintf ppf "house"
| `Invhouse -> fprintf ppf "invhouse"
| `Trapezium -> fprintf ppf "trapezium"
| `Invtrapezium -> fprintf ppf "invtrapezium"
| `Triangle -> fprintf ppf "triangle"
| `Invtriangle -> fprintf ppf "invtriangle"
| `Oval -> fprintf ppf "oval"
| `Assembly -> fprintf ppf "assembly"
| `Box3d -> fprintf ppf "box3d"
| `Cds -> fprintf ppf "cds"
| `Component -> fprintf ppf "component"
| `Doubleoctagon -> fprintf ppf "doubleoctagon"
| `Fivepoverhang -> fprintf ppf "fivepoverhang"
| `Folder -> fprintf ppf "folder"
| `Insulator -> fprintf ppf "insulator"
| `Larrow -> fprintf ppf "larrow"
| `Lpromoter -> fprintf ppf "lpromoter"
| `Mcircle -> fprintf ppf "mcircle"
| `Mdiamond -> fprintf ppf "mdiamond"
| `Msquare -> fprintf ppf " msquare"
| `Note -> fprintf ppf "note"
| `Noverhang -> fprintf ppf "noverhang"
| `Parallelogram -> fprintf ppf "parallelogram"
| `Primersite -> fprintf ppf "primersite"
| `Promoter -> fprintf ppf "promoter"
| `Proteasesite -> fprintf ppf "proteasesite"
| `Proteinstab -> fprintf ppf "proteinstab"
| `Rarrow -> fprintf ppf "rarrow"
| `Restrictionsite -> fprintf ppf "restrictionsite"
| `Ribosite -> fprintf ppf "ribosite"
| `Rnastab -> fprintf ppf "rnastab"
| `Rpromoter -> fprintf ppf "rpromoter"
| `Signature -> fprintf ppf "signature"
| `Star -> fprintf ppf "star"
| `Tab -> fprintf ppf "tab"
| `Terminator -> fprintf ppf "terminator"
| `Threepoverhang -> fprintf ppf "threepoverhang"
| `Tripleoctagon -> fprintf ppf "tripleoctagon"
| `Underline -> fprintf ppf "underline"
| `Utr -> fprintf ppf "utr"
| `Polygon (i, f) -> fprintf ppf "polygon, sides=%i, skew=%f" i f
let rec fprint_string_list ppf = function
| [] -> ()
| [hd] -> fprintf ppf "%s" hd
| hd :: tl -> fprintf ppf "%s,%a" hd fprint_string_list tl
let node_style_str = function
| `Rounded -> "rounded"
| `Filled -> "filled"
| `Solid -> "solid"
| `Dashed -> "dashed"
| `Dotted -> "dotted"
| `Bold -> "bold"
| `Invis -> "invis"
let fprint_style_list sep ppf a =
fprintf ppf "style=\"%a\"%a@ "
fprint_string_list (List.map node_style_str a)
fprint_symbseq sep
let fprint_vertex ppf = function
| `Color a -> fprintf ppf "color=%a" fprint_color a
| `ColorWithTransparency a ->
fprintf ppf "color=%a" fprint_color_with_transparency a
| `Fontcolor a -> fprintf ppf "fontcolor=%a" fprint_color a
| `Fontname s -> fprintf ppf "fontname=%a" fprint_string s
| `Fontsize i -> fprintf ppf "fontsize=%i" i
| `Height f -> fprintf ppf "height=%f" f
| `Label s -> fprintf ppf "label=%a" fprint_string_user s
| `HtmlLabel s -> fprintf ppf "label=%a" fprint_htmlstring_user s
| `Orientation f -> fprintf ppf "orientation=%f" f
| `Penwidth f -> fprintf ppf "penwidth=%f" f
| `Peripheries i -> fprintf ppf "peripheries=%i" i
| `Regular b -> fprintf ppf "regular=%b" b
| `Shape a -> fprintf ppf "shape=%a" fprint_shape a
| `Style _ -> assert false
| `Width f -> fprintf ppf "width=%f" f
let fprint_arrow_direction ppf = function
`Forward -> fprintf ppf "forward"
| `Back -> fprintf ppf "back"
| `Both -> fprintf ppf "both"
| `None -> fprintf ppf "none"
let fprint_edge ppf = function
| `Color a -> fprintf ppf "color=%a" fprint_color a
| `ColorWithTransparency a ->
fprintf ppf "color=%a" fprint_color_with_transparency a
| `Decorate b -> fprintf ppf "decorate=%b" b
| `Dir a -> fprintf ppf "dir=%a" fprint_arrow_direction a
| `Fontcolor a -> fprintf ppf "fontcolor=%a" fprint_color a
| `Fontname s -> fprintf ppf "fontname=%a" fprint_string s
| `Fontsize i -> fprintf ppf "fontsize=%i" i
| `Label s -> fprintf ppf "label=%a" fprint_string_user s
| `HtmlLabel s -> fprintf ppf "label=%a" fprint_htmlstring_user s
| `Labelfontcolor a -> fprintf ppf "labelfontcolor=%a" fprint_color a
| `Labelfontname s -> fprintf ppf "labelfontname=\"%s\"" s
(* (String.escaped s) *)
| `Labelfontsize i -> fprintf ppf "labelfontsize=%i" i
| `Penwidth f -> fprintf ppf "penwidth=%f" f
| `Style _ -> assert false
let rec filter_style al sl l = match l with
| [] -> al, sl
| `Style s :: l -> filter_style al (s :: sl) l
| a :: l -> filter_style (a :: al) sl l
(** [fprint_graph_attribute printer ppf list] pretty prints a list of
attributes on the formatter [ppf], using the printer [printer] for
each attribute. The list appears between brackets and attributes
are speparated by ",". If the list is empty, nothing is printed. *)
let fprint_attributes fprint_style_list fprint_attribute sep ppf list =
if list <> [] then begin
let list, styles = filter_style [] [] list in
let rec fprint_attributes_rec ppf = function
| [] -> ()
| hd :: tl ->
fprintf ppf "%a%a@ "
fprint_attribute hd
fprint_symbseq sep;
fprint_attributes_rec ppf tl
in
fprintf ppf "@[%a" fprint_attributes_rec list;
if styles <> [] then begin
fprint_style_list sep ppf styles
end;
fprintf ppf "@]"
end
end
(*-------------------------------------------------------------------------*)
(** {3 The [MakeEngine] functor} *)
(** An engine is described by a module of the following signature. *)
module type ENGINE = sig
module Attributes : sig
include ATTRIBUTES
val fprint_graph:formatter -> graph -> unit
val fprint_vertex_list: symbseq -> formatter -> vertex list -> unit
val fprint_edge_list: symbseq -> formatter -> edge list -> unit
end
(** The litteral name of the engine. *)
val name: string
(** The keyword for graphs ("digraph" for dot, "graph" for neato) *)
val opening: string
(** The litteral for edge arrows ("->" for dot, "--" for neato) *)
val edge_arrow: string
end
module type GRAPH = sig
end
module MakeEngine
(EN: ENGINE)
(X : sig
type t
module V : sig type t end
module E : sig type t val src : t -> V.t val dst : t -> V.t end
val iter_vertex : (V.t -> unit) -> t -> unit
val iter_edges_e : (E.t -> unit) -> t -> unit
val graph_attributes: t -> EN.Attributes.graph list
val default_vertex_attributes: t -> EN.Attributes.vertex list
val vertex_name : V.t -> string
val vertex_attributes: V.t -> EN.Attributes.vertex list
val default_edge_attributes: t -> EN.Attributes.edge list
val edge_attributes: E.t -> EN.Attributes.edge list
val get_subgraph : V.t -> EN.Attributes.subgraph option
end) =
struct
let command = ref EN.name
let set_command cmd =
command := cmd
exception Error of string
let handle_error f arg =
try
f arg
with
Error msg ->
Printf.eprintf "%s: %s failure\n %s\n"
Sys.argv.(0) EN.name msg;
flush stderr;
exit 2
(** [fprint_graph_attributes ppf list] pretty prints a list of
graph attributes on the formatter [ppf]. Attributes are separated
by a ";". *)
let fprint_graph_attributes ppf list =
List.iter (function att ->
fprintf ppf "%a;@ " EN.Attributes.fprint_graph att
) list
(** [fprint_graph ppf graph] pretty prints the graph [graph] in
the CGL language on the formatter [ppf]. *)
let fprint_graph ppf graph =
let module SG = Map.Make(String) in
let subgraphs = ref SG.empty in
(* Printing nodes. *)
let print_nodes ppf =
let default_node_attributes = X.default_vertex_attributes graph in
if default_node_attributes <> [] then
fprintf ppf "node%a;@ "
(fprint_square_not_empty (EN.Attributes.fprint_vertex_list COMMA))
default_node_attributes;
X.iter_vertex
(function node ->
begin match X.get_subgraph node with
| None -> ()
| Some sg ->
let (sg, nodes) =
if SG.mem sg.EN.Attributes.sg_name !subgraphs then
SG.find sg.EN.Attributes.sg_name !subgraphs
else
(sg, [])
in
subgraphs := SG.add sg.EN.Attributes.sg_name (sg, node :: nodes) !subgraphs
end;
fprintf ppf "%s%a;@ "
(X.vertex_name node)
(fprint_square_not_empty (EN.Attributes.fprint_vertex_list COMMA))
(X.vertex_attributes node)
)
graph
in
(* Printing subgraphs *)
let rec print_nested_subgraphs ppf = function
| [] ->
() (* no more work to do, so terminate *)
| name :: worklist ->
let sg, nodes = SG.find name !subgraphs in
let children = SG.filter (fun _ (sg, _) -> sg.EN.Attributes.sg_parent = Some name) !subgraphs in
fprintf ppf "@[subgraph cluster_%s { %a%t@ %t };@]@\n"
name
(EN.Attributes.fprint_vertex_list SEMI)
sg.EN.Attributes.sg_attributes
(fun ppf ->
(List.iter (fun n -> fprintf ppf "%s;" (X.vertex_name n)) nodes)
)
(fun ppf ->
print_nested_subgraphs ppf (List.map fst (SG.bindings children))
);
print_nested_subgraphs ppf worklist
in
let print_subgraphs ppf =
let root_worklist = SG.filter (fun _ (sg, _) -> sg.EN.Attributes.sg_parent = None) !subgraphs in
print_nested_subgraphs ppf (List.map fst (SG.bindings root_worklist))
in
(* Printing edges *)
let print_edges ppf =
let default_edge_attributes = X.default_edge_attributes graph in
if default_edge_attributes <> [] then
fprintf ppf "edge%a;@ "
(fprint_square_not_empty (EN.Attributes.fprint_edge_list COMMA))
default_edge_attributes;
X.iter_edges_e (function edge ->
fprintf ppf "%s %s %s%a;@ "
(X.vertex_name (X.E.src edge))
EN.edge_arrow
(X.vertex_name (X.E.dst edge))
(fprint_square_not_empty (EN.Attributes.fprint_edge_list COMMA))
(X.edge_attributes edge)
) graph
in
fprintf ppf "@[%s G {@ @[ %a"
EN.opening
fprint_graph_attributes (X.graph_attributes graph);
fprintf ppf "%t@ " print_nodes;
fprintf ppf "%t@ " print_subgraphs;
fprintf ppf "%t@ " print_edges;
fprintf ppf "@]}@]"
(** [output_graph oc graph] pretty prints the graph [graph] in the dot
language on the channel [oc]. *)
let output_graph oc graph =
let ppf = formatter_of_out_channel oc in
fprint_graph ppf graph;
pp_print_flush ppf ()
end
(***************************************************************************)
(** {2 Interface with the dot engine} *)
(** The [DotAttributes] module defines attributes for graphs, nodes and edges
that are available in the dot engine. *)
module DotAttributes = struct
(** Attributes of graphs. They include all common graph attributes and
several specific ones. All attributes described in the "dot User's
Manual, February 4, 2002" are handled, excepted: clusterank, color,
compound, labeljust, labelloc, ordering, rank, remincross, rotate,
searchsize and style.
*)
type graph =
[ CommonAttributes.graph
| `Bgcolor of color
(** Sets the background color and the inital fill color. *)
| `BgcolorWithTransparency of color_with_transparency
(** Sets the background color and the inital fill color with
a transparency component. *)
| `Comment of string
(** Comment string. *)
| `Concentrate of bool
(** If [true], enables edge concentrators. Default value is [false]. *)
| `Fontpath of string
(** List of directories for fonts. *)
| `Layers of string list
(** List of layers. *)
| `Margin of float
(** Sets the page margin (included in the page size). Default value is
[0.5]. *)
| `Mclimit of float
(** Scale factor for mincross iterations. Default value is [1.0]. *)
| `Nodesep of float
(** Sets the minimum separation between nodes, in inches. Default
value is [0.25]. *)
| `Nslimit of int
(** If set of [f], bounds network simplex iterations by [f *
] when ranking nodes. *)
| `Nslimit1 of int
(** If set of [f], bounds network simplex iterations by [f *
] when setting x-coordinates. *)
| `Ranksep of float
(** Sets the minimum separation between ranks. *)
| `Quantum of float
(** If not [0.0], node label dimensions will be rounded to integral
multiples of it. Default value is [0.0]. *)
| `Rankdir of [ `TopToBottom | `BottomToTop | `LeftToRight | `RightToLeft ]
(** Direction of rank ordering. Default value is [`TopToBottom]. *)
| `Ratio of [ `Float of float | `Fill | `Compress| `Auto ]
(** Sets the aspect ratio. *)
| `Samplepoints of int
(** Number of points used to represent ellipses and circles on output.
Default value is [8]. *)
| `Url of string
(** URL associated with graph (format-dependent). *)
]
(** Attributes of nodes. They include all common node attributes and
several specific ones. All attributes described in the "dot User's
Manual, February 4, 2002" are handled, excepted: bottomlabel, group,
shapefile and toplabel.
*)
type vertex =
[ CommonAttributes.vertex
| `Comment of string
(** Comment string. *)
| `Distortion of float
(* TEMPORARY *)
| `Fillcolor of color
(** Sets the fill color (used when `Style filled). Default value
is [lightgrey]. *)
| `FillcolorWithTransparency of color_with_transparency
(** Sets the fill color (used when `Style filled) with a transparency
component. Default value is fully opaque [lightgrey]. *)
| `Fixedsize of bool
(** If [true], forces the given dimensions to be the actual ones.
Default value is [false]. *)
| `Layer of string
(** Overlay. *)
| `Url of string
(** The default url for image map files; in PostScript files,
the base URL for all relative URLs, as recognized by Acrobat
Distiller 3.0 and up. *)
| `Z of float
(** z coordinate for VRML output. *)
]
(** Attributes of edges. They include all common edge attributes and
several specific ones. All attributes described in the "dot User's
Manual, February 4, 2002" are handled, excepted: lhead and ltail.
*)
type edge =
[ CommonAttributes.edge
| `Arrowhead of arrow_style
(** Sets the style of the head arrow. Default value is [`Normal]. *)
| `Arrowsize of float
(** Sets the scaling factor of arrowheads. Default value is [1.0]. *)
| `Arrowtail of arrow_style
(** Sets the style of the tail arrow. Default value is [`Normal]. *)
| `Comment of string
(** Comment string. *)
| `Constraint of bool
(** If [false], causes an edge to be ignored for rank assignment.
Default value is [true]. *)
| `Headlabel of string
(** Sets the label attached to the head arrow. *)
| `Headport of [ `N | `NE | `E | `SE | `S | `SW | `W | `NW ]
(* TEMPORARY *)
| `Headurl of string
(** Url attached to head label if output format is ismap. *)
| `Labelangle of float
(** Angle in degrees which head or tail label is rotated off edge.
Default value is [-25.0]. *)
| `Labeldistance of float
(** Scaling factor for distance of head or tail label from node.
Default value is [1.0]. *)
| `Labelfloat of bool
(** If [true], lessen constraints on edge label placement.
Default value is [false]. *)
| `Layer of string
(** Overlay. *)
| `Minlen of int
(** Minimum rank distance between head an tail. Default value is [1]. *)
| `Samehead of string
(** Tag for head node; edge heads with the same tag are merged onto the
same port. *)
| `Sametail of string
(** Tag for tail node; edge tails with the same tag are merged onto the
same port. *)
| `Taillabel of string
(** Sets the label attached to the tail arrow. *)
| `Tailport of [ `N | `NE | `E | `SE | `S | `SW | `W | `NW ]
(* TEMPORARY *)
| `Tailurl of string
(** Url attached to tail label if output format is ismap. *)
| `Weight of int
(** Sets the integer cost of stretching the edge. Default value is
[1]. *)
]
type subgraph = {
sg_name : string;
sg_attributes : vertex list;
sg_parent : string option;
}
(** {4 Pretty-print of attributes} *)
let rec fprint_string_list ppf = function
[] -> ()
| [hd] -> fprintf ppf "%s" hd
| hd :: tl -> fprintf ppf "%s,%a" hd fprint_string_list tl
let fprint_ratio ppf = function
`Float f -> fprintf ppf "%f" f
| `Fill -> fprintf ppf "fill"
| `Compress -> fprintf ppf "compress"
| `Auto -> fprintf ppf "auto"
let fprint_graph ppf = function
#CommonAttributes.graph as att -> CommonAttributes.fprint_graph ppf att
| `Bgcolor a -> fprintf ppf "bgcolor=%a" fprint_color a
| `BgcolorWithTransparency a ->
fprintf ppf "bgcolor=%a" fprint_color_with_transparency a
| `Comment s -> fprintf ppf "comment=%a" fprint_string s
| `Concentrate b -> fprintf ppf "concentrate=%b" b
| `Fontpath s -> fprintf ppf "fontpath=%a" fprint_string s
| `Layers s -> fprintf ppf "layers=%a" fprint_string_list s
| `Margin f -> fprintf ppf "margin=%f" f
| `Mclimit f -> fprintf ppf "mclimit=%f" f
| `Nodesep f -> fprintf ppf "nodesep=%f" f
| `Nslimit i -> fprintf ppf "nslimit=%i" i
| `Nslimit1 i -> fprintf ppf "nslimit1=%i" i
| `Ranksep f -> fprintf ppf "ranksep=%f" f
| `Quantum f -> fprintf ppf "quantum=%f" f
| `Rankdir a -> fprintf ppf "rankdir=%a" fprint_dir a
| `Ratio a -> fprintf ppf "ratio=%a" fprint_ratio a
| `Samplepoints i -> fprintf ppf "samplepoints=%i" i
| `Url s -> fprintf ppf "URL=\"%s\"" s (*(String.escaped s)*)
let fprint_vertex ppf = function
#CommonAttributes.vertex as att ->
CommonAttributes.fprint_vertex ppf att
| `Comment s -> fprintf ppf "comment=%a" fprint_string s
| `Distortion f -> fprintf ppf "distortion=%f" f
| `Fillcolor a -> fprintf ppf "fillcolor=%a" fprint_color a
| `FillcolorWithTransparency a ->
fprintf ppf "fillcolor=%a" fprint_color_with_transparency a
| `Fixedsize b -> fprintf ppf "fixedsize=%b" b
| `Layer s -> fprintf ppf "layer=%a" fprint_string s
| `Url s -> fprintf ppf "URL=\"%s\"" s (*(String.escaped s)*)
| `Z f -> fprintf ppf "z=%f" f
let fprint_port ppf = function
`N -> fprintf ppf "n"
| `NE -> fprintf ppf "ne"
| `E -> fprintf ppf "e"
| `SE -> fprintf ppf "se"
| `S -> fprintf ppf "s"
| `SW -> fprintf ppf "sw"
| `W -> fprintf ppf "w"
| `NW -> fprintf ppf "nw"
let fprint_edge ppf = function
#CommonAttributes.edge as att -> CommonAttributes.fprint_edge ppf att
| `Arrowhead a -> fprintf ppf "arrowhead=%a" fprint_arrow_style a
| `Arrowsize f -> fprintf ppf "arrowsize=%f" f
| `Arrowtail a -> fprintf ppf "arrowtail=%a" fprint_arrow_style a
| `Comment s -> fprintf ppf "comment=%a" fprint_string s
| `Constraint b -> fprintf ppf "constraint=%b" b
| `Headlabel s -> fprintf ppf "headlabel=%a" fprint_string s
| `Headport a -> fprintf ppf "headport=%a" fprint_port a
| `Headurl s -> fprintf ppf "headURL=%a" fprint_string s
| `Labelangle f -> fprintf ppf "labelangle=%f" f
| `Labeldistance f -> fprintf ppf "labeldistance=%f" f
| `Labelfloat b -> fprintf ppf "labelfloat=%b" b
| `Layer s -> fprintf ppf "layer=%a" fprint_string s
| `Minlen i -> fprintf ppf "minlen=%i" i
| `Samehead s -> fprintf ppf "samehead=%a" fprint_string s
| `Sametail s -> fprintf ppf "sametail=%a" fprint_string s
| `Taillabel s -> fprintf ppf "taillabel=%a" fprint_string s
| `Tailport a -> fprintf ppf "tailport=%a" fprint_port a
| `Tailurl s -> fprintf ppf "tailURL=%a" fprint_string s
| `Weight i -> fprintf ppf "weight=%i" i
let fprint_vertex_list =
CommonAttributes.fprint_attributes
CommonAttributes.fprint_style_list fprint_vertex
let fprint_edge_list =
CommonAttributes.fprint_attributes
CommonAttributes.fprint_style_list fprint_edge
end
(** Graph modules with dot attributes *)
module type GraphWithDotAttrs = sig
include Sig.G
(** Graph, vertex and edge attributes. *)
val graph_attributes: t -> DotAttributes.graph list
(** Vertex attributes *)
val default_vertex_attributes: t -> DotAttributes.vertex list
val vertex_name : V.t -> string
val vertex_attributes: V.t -> DotAttributes.vertex list
(** Edge attributes *)
val default_edge_attributes: t -> DotAttributes.edge list
val edge_attributes: E.t -> DotAttributes.edge list
val get_subgraph : V.t -> DotAttributes.subgraph option
(** The box (if exists) which the vertex belongs to. Boxes with same
names are not distinguished and so they should have the same
attributes. *)
end
module Dot =
MakeEngine (struct
module Attributes = DotAttributes
let name = "dot"
let opening = "digraph"
let edge_arrow = "->"
end)
(***************************************************************************)
(** {2 Interface with the neato engine} *)
(** The [NeatoAttributes] module defines attributes for graphs, nodes and edges
that are available in the neato engine. *)
module NeatoAttributes = struct
(** Attributes of graphs. They include all common graph attributes and
several specific ones. All attributes described in the "Neato User's
manual, April 10, 2002" are handled. *)
type graph =
[ CommonAttributes.graph
| `Margin of float * float
(** Sets the page margin (included in the page size). Default value is
[0.5, 0.5]. *)
| `Start of int
(** Seed for random number generator. *)
| `Overlap of bool
(** Default value is [true]. *)
| `Spline of bool
(** [true] makes edge splines if nodes don't overlap.
Default value is [false]. *)
| `Sep of float
(** Edge spline separation factor from nodes. Default value
is [0.0]. *)
]
(** Attributes of nodes. They include all common node attributes and
several specific ones. All attributes described in the "Neato User's
manual, April 10, 2002" are handled. *)
type vertex =
[ CommonAttributes.vertex
| `Pos of float * float
(** Initial coordinates of the node. *)
]
(** Attributes of edges. They include all common edge attributes and
several specific ones. All attributes described in the "Neato User's
manual, April 10, 2002" are handled. *)
type edge =
[ CommonAttributes.edge
| `Id of string
(** Optional value to distinguish multiple edges. *)
| `Len of float
(** Preferred length of edge. Default value is [1.0]. *)
| `Weight of float
(** Strength of edge spring. Default value is [1.0]. *)
]
type subgraph = {
sg_name : string;
sg_attributes : vertex list;
sg_parent : string option;
}
(** {4 Pretty-print of attributes} *)
let fprint_graph ppf = function
#CommonAttributes.graph as att -> CommonAttributes.fprint_graph ppf att
| `Margin (f1, f2) -> fprintf ppf "margin=\"%f,%f\"" f1 f2
| `Start i -> fprintf ppf "start=%i" i
| `Overlap b -> fprintf ppf "overlap=%b" b
| `Spline b -> fprintf ppf "spline=%b" b
| `Sep f -> fprintf ppf "sep=%f" f
let fprint_vertex ppf = function
#CommonAttributes.vertex as att ->
CommonAttributes.fprint_vertex ppf att
| `Pos (f1, f2) -> fprintf ppf "pos=\"%f,%f\"" f1 f2
let fprint_edge ppf = function
#CommonAttributes.edge as att -> CommonAttributes.fprint_edge ppf att
| `Id s -> fprintf ppf "id=%a" fprint_string s
| `Len f -> fprintf ppf "len=%f" f
| `Weight f -> fprintf ppf "weight=%f" f
let fprint_vertex_list =
CommonAttributes.fprint_attributes
CommonAttributes.fprint_style_list fprint_vertex
let fprint_edge_list =
CommonAttributes.fprint_attributes
CommonAttributes.fprint_style_list fprint_edge
end
module Neato =
MakeEngine (struct
module Attributes = NeatoAttributes
let name = "neato"
let opening = "graph"
let edge_arrow = "--"
end)
ocamlgraph-2.0.0/src/graphviz.mli 0000644 0001750 0000144 00000052353 13735627615 015345 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(** Interface with {i GraphViz}
This module provides a basic interface with dot and neato,
two programs of the GraphViz toolbox.
These tools are available at the following URLs:
- {v http://www.graphviz.org v}
- {v http://www.research.att.com/sw/tools/graphviz v} *)
open Format
(***************************************************************************)
(** {2 Common stuff} *)
(** Because the neato and dot engines present a lot of common points -
in particular in the graph description language, large parts of
the code is shared. The [CommonAttributes] module defines
attributes of graphs, vertices and edges that are understood by the
two engines. Then module [DotAttributes] and [NeatoAttributes]
define attributes specific to dot and neato respectively. *)
(*-------------------------------------------------------------------------*)
(** {3 Common types and signatures} *)
type color = int
type color_with_transparency = int32
(** The two least significant bytes encode the transparency information;
the six most signification are the standard RGB color *)
val color_to_color_with_transparency: color -> color_with_transparency
type arrow_style =
[ `None | `Normal | `Onormal | `Inv | `Dot | `Odot | `Invdot | `Invodot ]
(** The [ATTRIBUTES] module type defines the interface for the engines. *)
module type ATTRIBUTES = sig
type graph (** Attributes of graphs. *)
type vertex (** Attributes of vertices. *)
type edge (** Attributes of edges. *)
(** Attributes of (optional) boxes around vertices. *)
type subgraph = {
sg_name : string; (** Box name. *)
sg_attributes : vertex list; (** Box attributes. *)
sg_parent : string option; (** Nested subgraphs. *)
}
end
(*-------------------------------------------------------------------------*)
(** {3 Common attributes} *)
(** The [CommonAttributes] module defines attributes for graphs, vertices and
edges that are available in the two engines, dot and neato. *)
module CommonAttributes : sig
(** Attributes of graphs. *)
type graph =
[ `Center of bool
(** Centers the drawing on the page. Default value is [false]. *)
| `Fontcolor of color
(** Sets the font color. Default value is [black]. *)
| `Fontname of string
(** Sets the font family name. Default value is ["Times-Roman"]. *)
| `Fontsize of int
(** Sets the type size (in points). Default value is [14]. *)
| `Label of string
(** Caption for graph drawing. *)
| `HtmlLabel of string
(** Caption for graph drawing. In HTML strings, angle brackets must occur in
matched pairs, and newlines and other formatting whitespace characters
are allowed. In addition, the content must be legal XML, so that the
special XML escape sequences for ", &, <, and > may be necessary in
order to embed these characters in attribute values or raw text." *)
| `Orientation of [ `Portrait | `Landscape ]
(** Sets the page orientation. Default value is [`Portrait]. *)
| `Page of float * float
(** Sets the PostScript pagination unit, e.g [8.5, 11.0]. *)
| `Pagedir of [ `TopToBottom | `LeftToRight ]
(** Traversal order of pages. Default value is [`TopToBottom]. *)
| `Size of float * float
(** Sets the bounding box of drawing (in inches). *)
| `OrderingOut
(** Constrains order of out-edges in a subgraph according to
their file sequence *)
]
(** Attributes of vertices. *)
type vertex =
[ `Color of color
(** Sets the color of the border of the vertex.
Default value is [black] *)
| `ColorWithTransparency of color_with_transparency
(** Sets the color of the border of the vertex with a transparency
component. Default value is fully opaque [black] *)
| `Fontcolor of color
(** Sets the label font color. Default value is [black]. *)
| `Fontname of string
(** Sets the label font family name. Default value is
["Times-Roman"]. *)
| `Fontsize of int
(** Sets the label type size (in points). Default value is [14].
*)
| `Height of float
(** Sets the minimum height. Default value is [0.5]. *)
| `Label of string
(** Sets the label printed in the vertex.
The string may include escaped
newlines [\n], [\l], or [\r] for center, left, and right justified
lines.
Record labels may contain recursive box lists delimited by { | }.
*)
| `HtmlLabel of string
(** Like label, in html style. In HTML strings, angle brackets must occur in
matched pairs, and newlines and other formatting whitespace characters
are allowed. In addition, the content must be legal XML, so that the
special XML escape sequences for ", &, <, and > may be necessary in
order to embed these characters in attribute values or raw text." *)
| `Orientation of float
(** Vertex rotation angle, in degrees. Default value is [0.0]. *)
| `Penwidth of float
(** Width of the pen (in points) used to draw the border of the node.
Default value is [1.0]. *)
| `Peripheries of int
(** Sets the number of periphery lines drawn around the polygon. *)
| `Regular of bool
(** If [true], then the polygon is made regular, i.e. symmetric about
the x and y axis, otherwise the polygon takes on the aspect
ratio of the label. Default value is [false]. *)
| `Shape of
[`Ellipse | `Box | `Circle | `Doublecircle | `Diamond
| `Plaintext | `Record
(* Addition through http://www.graphviz.org/doc/info/shapes.html *)
| `Oval | `Egg | `Triangle | `Invtriangle
| `Trapezium | `Invtrapezium
| `House | `Invhouse
| `Parallelogram | `Doubleoctagon | `Tripleoctagon
| `Mdiamond | `Mcircle | `Msquare
| `Star | `Underline
| `Note | `Tab | `Folder
| `Box3d | `Component | `Promoter
| `Cds
| `Terminator | `Utr | `Primersite
| `Restrictionsite
| `Fivepoverhang | `Threepoverhang | `Noverhang
| `Assembly | `Signature | `Insulator | `Ribosite | `Rnastab
| `Proteasesite | `Proteinstab | `Rpromoter | `Rarrow
| `Larrow | `Lpromoter
(* Addition ends here *)
| `Polygon of int * float]
(** Sets the shape of the vertex. Default value is [`Ellipse].
[`Polygon (i, f)] draws a polygon with [n] sides and a skewing
of [f]. *)
| `Style of
[ `Rounded | `Filled | `Solid | `Dashed | `Dotted | `Bold | `Invis ]
(** Sets the layout style of the vertex.
Several styles may be combined simultaneously. *)
| `Width of float
(** Sets the minimum width. Default value is [0.75]. *)
]
(** Attributes of edges. *)
type edge =
[ `Color of color
(** Sets the edge stroke color. Default value is [black]. *)
| `ColorWithTransparency of color_with_transparency
(** Sets the edge stroke color with a transparency
component. Default value is fully opaque [black] *)
| `Decorate of bool
(** If [true], draws a line connecting labels with their edges. *)
| `Dir of [ `Forward | `Back | `Both | `None ]
(** Sets arrow direction. Default value is [`Forward]. *)
| `Fontcolor of color
(** Sets the label font color. Default value is [black]. *)
| `Fontname of string
(** Sets the label font family name. Default value is
["Times-Roman"]. *)
| `Fontsize of int
(** Sets the label type size (in points). Default value is [14]. *)
| `Label of string
(** Sets the label to be attached to the edge. The string may include
escaped newlines [\n], [\l], or [\r] for centered, left, or right
justified lines. *)
| `HtmlLabel of string
(** Like label, in html style. In HTML strings, angle brackets must occur in
matched pairs, and newlines and other formatting whitespace characters
are allowed. In addition, the content must be legal XML, so that the
special XML escape sequences for ", &, <, and > may be necessary in
order to embed these characters in attribute values or raw text." *)
| `Labelfontcolor of color
(** Sets the font color for head and tail labels. Default value is
[black]. *)
| `Labelfontname of string
(** Sets the font family name for head and tail labels. Default
value is ["Times-Roman"]. *)
| `Labelfontsize of int
(** Sets the font size for head and tail labels (in points).
Default value is [14]. *)
| `Penwidth of float
(** Width of the pen (in points) used to draw the edge. Default value
is [1.0]. *)
| `Style of [ `Solid | `Dashed | `Dotted | `Bold | `Invis ]
(** Sets the layout style of the edge. Several styles may be combined
simultaneously. *)
]
end
(***************************************************************************)
(** {2 Interface with the dot engine} *)
(** [DotAttributes] extends [CommonAttributes] and implements [ATTRIBUTES]. *)
module DotAttributes : sig
(** Attributes of graphs. They include all common graph attributes and
several specific ones. All attributes described in the "dot User's
Manual, February 4, 2002" are handled, excepted: clusterank, color,
compound, labeljust, labelloc, ordering, rank, remincross, rotate,
searchsize and style. *)
type graph =
[ CommonAttributes.graph
| `Bgcolor of color
(** Sets the background color and the inital fill color. *)
| `BgcolorWithTransparency of color_with_transparency
(** Sets the background color and the inital fill color with
a transparency component. *)
| `Comment of string
(** Comment string. *)
| `Concentrate of bool
(** If [true], enables edge concentrators. Default value is [false]. *)
| `Fontpath of string
(** List of directories for fonts. *)
| `Layers of string list
(** List of layers. *)
| `Margin of float
(** Sets the page margin (included in the page size). Default value is
[0.5]. *)
| `Mclimit of float
(** Scale factor for mincross iterations. Default value is [1.0]. *)
| `Nodesep of float
(** Sets the minimum separation between nodes, in inches. Default
value is [0.25]. *)
| `Nslimit of int
(** If set of [f], bounds network simplex iterations by [f *
] when ranking nodes. *)
| `Nslimit1 of int
(** If set of [f], bounds network simplex iterations by [f *
] when setting x-coordinates. *)
| `Ranksep of float
(** Sets the minimum separation between ranks. *)
| `Quantum of float
(** If not [0.0], node label dimensions will be rounded to integral
multiples of it. Default value is [0.0]. *)
| `Rankdir of [ `TopToBottom | `BottomToTop | `LeftToRight | `RightToLeft ]
(** Direction of rank ordering. Default value is [`TopToBottom]. *)
| `Ratio of [ `Float of float | `Fill | `Compress| `Auto ]
(** Sets the aspect ratio. *)
| `Samplepoints of int
(** Number of points used to represent ellipses and circles on output.
Default value is [8]. *)
| `Url of string
(** URL associated with graph (format-dependent). *)
]
(** Attributes of nodes. They include all common node attributes and
several specific ones. All attributes described in the "dot User's
Manual, February 4, 2002" are handled, excepted: bottomlabel, group,
shapefile and toplabel. *)
type vertex =
[ CommonAttributes.vertex
| `Comment of string
(** Comment string. *)
| `Distortion of float
(* TEMPORARY *)
| `Fillcolor of color
(** Sets the fill color (used when `Style filled). Default value
is [lightgrey]. *)
| `FillcolorWithTransparency of color_with_transparency
(** Sets the fill color (used when `Style filled) with a transparency
component. Default value is fully opaque [lightgrey]. *)
| `Fixedsize of bool
(** If [true], forces the given dimensions to be the actual ones.
Default value is [false]. *)
| `Layer of string
(** Overlay. *)
| `Url of string
(** The default url for image map files; in PostScript files,
the base URL for all relative URLs, as recognized by Acrobat
Distiller 3.0 and up. *)
| `Z of float
(** z coordinate for VRML output. *)
]
(** Attributes of edges. They include all common edge attributes and
several specific ones. All attributes described in the "dot User's
Manual, February 4, 2002" are handled, excepted: lhead and ltail. *)
type edge =
[ CommonAttributes.edge
| `Arrowhead of arrow_style
(** Sets the style of the head arrow. Default value is [`Normal]. *)
| `Arrowsize of float
(** Sets the scaling factor of arrowheads. Default value is [1.0]. *)
| `Arrowtail of arrow_style
(** Sets the style of the tail arrow. Default value is [`Normal]. *)
| `Comment of string
(** Comment string. *)
| `Constraint of bool
(** If [false], causes an edge to be ignored for rank assignment.
Default value is [true]. *)
| `Headlabel of string
(** Sets the label attached to the head arrow. *)
| `Headport of [ `N | `NE | `E | `SE | `S | `SW | `W | `NW ]
(* TEMPORARY *)
| `Headurl of string
(** Url attached to head label if output format is ismap. *)
| `Labelangle of float
(** Angle in degrees which head or tail label is rotated off edge.
Default value is [-25.0]. *)
| `Labeldistance of float
(** Scaling factor for distance of head or tail label from node.
Default value is [1.0]. *)
| `Labelfloat of bool
(** If [true], lessen constraints on edge label placement.
Default value is [false]. *)
| `Layer of string
(** Overlay. *)
| `Minlen of int
(** Minimum rank distance between head an tail.
Default value is [1]. *)
| `Samehead of string
(** Tag for head node; edge heads with the same tag are merged onto the
same port. *)
| `Sametail of string
(** Tag for tail node; edge tails with the same tag are merged onto the
same port. *)
| `Taillabel of string
(** Sets the label attached to the tail arrow. *)
| `Tailport of [ `N | `NE | `E | `SE | `S | `SW | `W | `NW ]
(* TEMPORARY *)
| `Tailurl of string
(** Url attached to tail label if output format is ismap. *)
| `Weight of int
(** Sets the integer cost of stretching the edge. Default value is
[1]. *)
]
(** Subgraphs have a name and some vertices. *)
type subgraph = {
sg_name : string;
sg_attributes : vertex list;
sg_parent : string option;
}
end
(** Graph module with dot attributes *)
module type GraphWithDotAttrs = sig
include Sig.G
val graph_attributes: t -> DotAttributes.graph list
(** Vertex attributes *)
val default_vertex_attributes: t -> DotAttributes.vertex list
val vertex_name : V.t -> string
val vertex_attributes: V.t -> DotAttributes.vertex list
(** Edge attributes *)
val default_edge_attributes: t -> DotAttributes.edge list
val edge_attributes: E.t -> DotAttributes.edge list
val get_subgraph : V.t -> DotAttributes.subgraph option
(** The box (if exists) which the vertex belongs to. Boxes with same
names are not distinguished and so they should have the same
attributes. *)
end
module Dot
(X : sig
(** Graph implementation. Sub-signature of {!Sig.G} *)
type t
module V : sig type t end
module E : sig type t val src : t -> V.t val dst : t -> V.t end
val iter_vertex : (V.t -> unit) -> t -> unit
val iter_edges_e : (E.t -> unit) -> t -> unit
(** Graph, vertex and edge attributes. *)
val graph_attributes: t -> DotAttributes.graph list
val default_vertex_attributes: t -> DotAttributes.vertex list
val vertex_name : V.t -> string
val vertex_attributes: V.t -> DotAttributes.vertex list
val get_subgraph : V.t -> DotAttributes.subgraph option
(** The box (if exists) which the vertex belongs to. Boxes with same
names are not distinguished and so they should have the same
attributes. *)
val default_edge_attributes: t -> DotAttributes.edge list
val edge_attributes: E.t -> DotAttributes.edge list
end) :
sig
val fprint_graph: formatter -> X.t -> unit
(** [fprint_graph ppf graph] pretty prints the graph [graph] in
the CGL language on the formatter [ppf]. *)
val output_graph: out_channel -> X.t -> unit
(** [output_graph oc graph] pretty prints the graph [graph] in the dot
language on the channel [oc]. *)
end
(***************************************************************************)
(** {2 The neato engine} *)
module NeatoAttributes : sig
(** Attributes of graphs. They include all common graph attributes and
several specific ones. All attributes described in the "Neato User's
manual, April 10, 2002" are handled. *)
type graph =
[ CommonAttributes.graph
| `Margin of float * float
(** Sets the page margin (included in the page size). Default value is
[0.5, 0.5]. *)
| `Start of int
(** Seed for random number generator. *)
| `Overlap of bool
(** Default value is [true]. *)
| `Spline of bool
(** [true] makes edge splines if nodes don't overlap.
Default value is [false]. *)
| `Sep of float
(** Edge spline separation factor from nodes. Default value
is [0.0]. *)
]
(** Attributes of nodes. They include all common node attributes and
several specific ones. All attributes described in the "Neato User's
manual, April 10, 2002" are handled. *)
type vertex =
[ CommonAttributes.vertex
| `Pos of float * float
(** Initial coordinates of the vertex. *)
]
(** Attributes of edges. They include all common edge attributes and
several specific ones. All attributes described in the "Neato User's
manual, April 10, 2002" are handled. *)
type edge =
[ CommonAttributes.edge
| `Id of string
(** Optional value to distinguish multiple edges. *)
| `Len of float
(** Preferred length of edge. Default value is [1.0]. *)
| `Weight of float
(** Strength of edge spring. Default value is [1.0]. *)
]
(** Subgraphs have a name and some vertices. *)
type subgraph = {
sg_name : string;
sg_attributes : vertex list;
sg_parent : string option;
}
end
module Neato
(X : sig
(** Graph implementation. Sub-signature of {!Sig.G}. *)
type t
module V : sig type t end
module E : sig type t val src : t -> V.t val dst : t -> V.t end
val iter_vertex : (V.t -> unit) -> t -> unit
val iter_edges_e : (E.t -> unit) -> t -> unit
(** Graph, vertex and edge attributes. *)
val graph_attributes: t -> NeatoAttributes.graph list
val default_vertex_attributes: t -> NeatoAttributes.vertex list
val vertex_name : V.t -> string
val vertex_attributes: V.t -> NeatoAttributes.vertex list
val get_subgraph : V.t -> NeatoAttributes.subgraph option
(** The box (if exists) which the vertex belongs to. Boxes with same
names are not distinguished and so they should have the same
attributes. *)
val default_edge_attributes: t -> NeatoAttributes.edge list
val edge_attributes: E.t -> NeatoAttributes.edge list
end) :
sig
val set_command: string -> unit
(** Several functions provided by this module run the external program
{i neato}. By default, this command is supposed to be in the default
path and is invoked by {i neato}. The function
[set_command] allows to set an alternative path at run time. *)
exception Error of string
val handle_error: ('a -> 'b) -> 'a -> 'b
val fprint_graph: formatter -> X.t -> unit
(** [fprint_graph ppf graph] pretty prints the graph [graph] in
the CGL language on the formatter [ppf]. *)
val output_graph: out_channel -> X.t -> unit
(** [output_graph oc graph] pretty prints the graph [graph] in the dot
language on the channel [oc]. *)
end
(*
Local Variables:
compile-command: "make -C .."
End:
*)
ocamlgraph-2.0.0/src/imperative.ml 0000644 0001750 0000144 00000047210 13735627615 015503 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
open Sig
open Blocks
module type S = sig
(** Imperative Unlabeled Graphs *)
module Concrete (V: COMPARABLE) :
Sig.I with type V.t = V.t and type V.label = V.t and type E.t = V.t * V.t
and type E.label = unit
(** Abstract Imperative Unlabeled Graphs *)
module Abstract(V: sig type t end) :
Sig.IM with type V.label = V.t and type E.label = unit
and type E.label = unit
(** Imperative Labeled Graphs *)
module ConcreteLabeled (V: COMPARABLE)(E: ORDERED_TYPE_DFT) :
Sig.I with type V.t = V.t and type V.label = V.t
and type E.t = V.t * E.t * V.t and type E.label = E.t
(** Abstract Imperative Labeled Graphs *)
module AbstractLabeled (V: sig type t end)(E: ORDERED_TYPE_DFT) :
Sig.IM with type V.label = V.t and type E.label = E.t
end
module I = Make(Make_Hashtbl)
type 'a abstract_vertex = { tag : int; label : 'a; mutable mark : int }
(* Implement module type [MARK]. *)
module Make_Mark
(X: sig
type graph
type label
val iter_vertex : (label abstract_vertex -> unit) -> graph -> unit
end) =
struct
type vertex = X.label abstract_vertex
type graph = X.graph
let get v = v.mark
let set v m = v.mark <- m
let clear g = X.iter_vertex (fun v -> set v 0) g
end
(* Vertex for abstract imperative graphs:
comparing to vertex for abstract **persistent** graphs, marks are added. *)
module AbstractVertex(V: sig type t end) = struct
type label = V.t
type t = label abstract_vertex
let compare x y = Stdlib.compare x.tag y.tag
let hash x = x.tag
let equal x y = x.tag = y.tag
let label x = x.label
let create l =
if !cpt_vertex = first_value_for_cpt_vertex - 1 then
invalid_arg "Too much vertices";
incr cpt_vertex;
{ tag = !cpt_vertex; label = l; mark = 0 }
end
module Digraph = struct
module Concrete(V: COMPARABLE) = struct
include I.Digraph.Concrete(V)
let add_vertex g v = ignore (add_vertex g v)
let add_edge g v1 v2 = ignore (add_edge g v1 v2)
let remove_edge g v1 v2 = ignore (remove_edge g v1 v2)
let remove_edge_e g e = ignore (remove_edge_e g e)
let add_edge_e g e = ignore (add_edge_e g e)
let remove_vertex g v =
if HM.mem v g then begin
ignore (HM.remove v g);
HM.iter (fun k s -> ignore (HM.add k (S.remove v s) g)) g
end
end
module ConcreteLabeled(V: COMPARABLE)(E: ORDERED_TYPE_DFT) = struct
include I.Digraph.ConcreteLabeled(V)(E)
let add_vertex g v = ignore (add_vertex g v)
let remove_edge g v1 v2 = ignore (remove_edge g v1 v2)
let remove_edge_e g e = ignore (remove_edge_e g e)
let add_edge_e g e = ignore (add_edge_e g e)
let add_edge g v1 v2 = ignore (add_edge g v1 v2)
let remove_vertex g v =
if HM.mem v g then begin
ignore (HM.remove v g);
let remove v = S.filter (fun (v2, _) -> not (V.equal v v2)) in
HM.iter (fun k s -> ignore (HM.add k (remove v s) g)) g
end
end
module ConcreteBidirectional(V: COMPARABLE) = struct
include I.Digraph.ConcreteBidirectional(V)
let add_vertex g v = ignore (add_vertex g v)
let add_edge g v1 v2 = ignore (add_edge g v1 v2)
let add_edge_e g (v1, v2) = add_edge g v1 v2
let remove_edge g v1 v2 = ignore (remove_edge g v1 v2)
let remove_edge_e g e = ignore (remove_edge_e g e)
let remove_vertex g v =
if HM.mem v g then begin
iter_pred_e (fun e -> remove_edge_e g e) g v;
iter_succ_e (fun e -> remove_edge_e g e) g v;
ignore (HM.remove v g)
end
end
module ConcreteBidirectionalLabeled(V:COMPARABLE)(E:ORDERED_TYPE_DFT) = struct
include I.Digraph.ConcreteBidirectionalLabeled(V)(E)
let add_vertex g v = ignore (add_vertex g v)
let add_edge g v1 v2 = ignore (add_edge g v1 v2)
let add_edge_e g (v1, l, v2) = ignore (add_edge_e g (v1, l, v2))
let remove_edge g v1 v2 = ignore (remove_edge g v1 v2)
let remove_edge_e g e = ignore (remove_edge_e g e)
let remove_vertex g v =
if HM.mem v g then begin
iter_pred_e (fun e -> remove_edge_e g e) g v;
iter_succ_e (fun e -> remove_edge_e g e) g v;
ignore (HM.remove v g)
end
end
module Abstract(V: sig type t end) = struct
include I.Digraph.Abstract(AbstractVertex(V))
let add_vertex g v =
if not (HM.mem v g.edges) then begin
g.size <- Stdlib.succ g.size;
ignore (G.unsafe_add_vertex g.edges v)
end
let add_edge g v1 v2 =
add_vertex g v1;
add_vertex g v2;
ignore (unsafe_add_edge g.edges v1 v2)
let add_edge_e g (v1, v2) = add_edge g v1 v2
let remove_vertex g v =
if HM.mem v g.edges then
let e = g.edges in
ignore (HM.remove v e);
HM.iter (fun k s -> ignore (HM.add k (S.remove v s) e)) e;
g.size <- Stdlib.pred g.size
module Mark =
Make_Mark
(struct
type graph = t
type label = V.label
let iter_vertex = iter_vertex
end)
let remove_edge g v1 v2 = ignore (remove_edge g v1 v2)
let remove_edge_e g e = ignore (remove_edge_e g e)
end
module AbstractLabeled(V: sig type t end)(Edge: ORDERED_TYPE_DFT) = struct
include I.Digraph.AbstractLabeled(AbstractVertex(V))(Edge)
let add_vertex g v =
if not (HM.mem v g.edges) then begin
g.size <- Stdlib.succ g.size;
ignore (G.unsafe_add_vertex g.edges v)
end
let add_edge_e g (v1, l, v2) =
add_vertex g v1;
add_vertex g v2;
ignore (unsafe_add_edge g.edges v1 (v2, l))
let add_edge g v1 v2 = add_edge_e g (v1, Edge.default, v2)
let remove_vertex g v =
if HM.mem v g.edges then
let remove s =
S.fold
(fun (v2, _ as e) s -> if not (V.equal v v2) then S.add e s else s)
s S.empty
in
let e = g.edges in
ignore (HM.remove v e);
HM.iter (fun k s -> ignore (HM.add k (remove s) e)) e;
g.size <- Stdlib.pred g.size
module Mark =
Make_Mark
(struct
type graph = t
type label = V.label
let iter_vertex = iter_vertex
end)
let remove_edge g v1 v2 = ignore (remove_edge g v1 v2)
let remove_edge_e g e = ignore (remove_edge_e g e)
end
end
module Graph = struct
module Concrete(V: COMPARABLE) = struct
module G = struct include Digraph.Concrete(V) type return = unit end
include Blocks.Graph(G)
(* Redefine the [add_edge] and [remove_edge] operations *)
let add_edge g v1 v2 =
if not (mem_edge g v1 v2) then begin
G.add_edge g v1 v2;
assert (G.HM.mem v1 g && G.HM.mem v2 g);
ignore (G.unsafe_add_edge g v2 v1)
end
let add_edge_e g (v1, v2) = add_edge g v1 v2
let remove_edge g v1 v2 =
G.remove_edge g v1 v2;
assert (G.HM.mem v1 g && G.HM.mem v2 g);
ignore (G.unsafe_remove_edge g v2 v1)
let remove_edge_e g (v1, v2) = remove_edge g v1 v2
end
module ConcreteLabeled (V: COMPARABLE)(Edge: ORDERED_TYPE_DFT) = struct
module G = struct
include Digraph.ConcreteLabeled(V)(Edge)
type return = unit
end
include Blocks.Graph(G)
(* Redefine the [add_edge] and [remove_edge] operations *)
let add_edge_e g (v1, l, v2 as e) =
if not (mem_edge_e g e) then begin
G.add_edge_e g e;
assert (G.HM.mem v1 g && G.HM.mem v2 g);
ignore (G.unsafe_add_edge g v2 (v1, l))
end
let add_edge g v1 v2 = add_edge_e g (v1, Edge.default, v2)
let remove_edge g v1 v2 =
G.remove_edge g v1 v2;
assert (G.HM.mem v1 g && G.HM.mem v2 g);
ignore (G.unsafe_remove_edge g v2 v1)
let remove_edge_e g (v1, l, v2 as e) =
G.remove_edge_e g e;
assert (G.HM.mem v1 g && G.HM.mem v2 g);
ignore (G.unsafe_remove_edge_e g (v2, l, v1))
end
module Abstract(V: sig type t end) = struct
module G = struct include Digraph.Abstract(V) type return = unit end
include Blocks.Graph(G)
(* Export some definitions of [G] *)
module Mark = G.Mark
(* Redefine the [add_edge] and [remove_edge] operations *)
let add_edge g v1 v2 =
G.add_edge g v1 v2;
assert (G.HM.mem v1 g.G.edges && G.HM.mem v2 g.G.edges);
ignore (G.unsafe_add_edge g.G.edges v2 v1)
let add_edge_e g (v1, v2) = add_edge g v1 v2
let remove_edge g v1 v2 =
G.remove_edge g v1 v2;
assert (G.HM.mem v1 g.G.edges && G.HM.mem v2 g.G.edges);
ignore (G.unsafe_remove_edge g.G.edges v2 v1)
let remove_edge_e g (v1, v2) = remove_edge g v1 v2
end
module AbstractLabeled (V: sig type t end)(Edge: ORDERED_TYPE_DFT) = struct
module G = struct
include Digraph.AbstractLabeled(V)(Edge)
type return = unit
end
include Blocks.Graph(G)
(* Export some definitions of [G] *)
module Mark = G.Mark
(* Redefine the [add_edge] and [remove_edge] operations *)
let add_edge_e g (v1, l, v2 as e) =
G.add_edge_e g e;
assert (G.HM.mem v1 g.G.edges && G.HM.mem v2 g.G.edges);
ignore (G.unsafe_add_edge g.G.edges v2 (v1, l))
let add_edge g v1 v2 = add_edge_e g (v1, Edge.default, v2)
let remove_edge g v1 v2 =
G.remove_edge g v1 v2;
assert (G.HM.mem v1 g.G.edges && G.HM.mem v2 g.G.edges);
ignore (G.unsafe_remove_edge g.G.edges v2 v1)
let remove_edge_e g (v1, l, v2 as e) =
ignore (G.remove_edge_e g e);
assert (G.HM.mem v1 g.G.edges && G.HM.mem v2 g.G.edges);
ignore (G.unsafe_remove_edge_e g.G.edges (v2, l, v1))
end
end
module Matrix = struct
module type S = sig
include Sig.I with type V.t = int and type V.label = int
and type E.t = int * int
val make : int -> t
end
module Digraph = struct
module V = struct
type t = int
type label = int
let compare : t -> t -> int = Stdlib.compare
let hash = Hashtbl.hash
let equal = (==)
let create i = i
let label i = i
end
module E = struct
type t = V.t * V.t
type vertex = V.t
let compare : t -> t -> int = Stdlib.compare
type label = unit
let create v1 _ v2 = (v1, v2)
let src = fst
let dst = snd
let label _ = ()
end
type t = Bitv.t array
type vertex = V.t
type edge = E.t
let create ?size:_ () =
failwith
"[ocamlgraph] do not use Matrix.create; please use Matrix.make instead"
let make n =
if n < 0 then invalid_arg "[ocamlgraph] Matrix.make";
Array.init n (fun _ -> Bitv.create n false)
let is_directed = true
let nb_vertex = Array.length
let is_empty g = nb_vertex g = 0
let nb_edges =
Array.fold_left (Bitv.fold_left (fun n b -> if b then n+1 else n)) 0
let mem_vertex g v = 0 <= v && v < nb_vertex g
let mem_edge g i j = Bitv.get g.(i) j
let mem_edge_e g (i,j) = Bitv.get g.(i) j
let find_edge g i j = if mem_edge g i j then i, j else raise Not_found
let find_all_edges g i j = try [ find_edge g i j ] with Not_found -> []
(* constructors *)
let add_edge g i j = Bitv.set g.(i) j true
let add_edge_e g (i,j) = Bitv.set g.(i) j true
let remove_edge g i j = Bitv.set g.(i) j false
let remove_edge_e g (i,j) = Bitv.set g.(i) j false
let unsafe_add_edge g i j =
Bitv.unsafe_set (Array.unsafe_get g i) j true
let unsafe_remove_edge g i j =
Bitv.unsafe_set (Array.unsafe_get g i) j false
let remove_vertex _ _ = ()
let add_vertex _ _ = ()
let clear g =
Array.iter (fun b -> Bitv.iteri (fun j _ -> Bitv.set b j false) b) g
let copy g = Array.init (nb_vertex g) (fun i -> Bitv.copy g.(i))
(* iter/fold on all vertices/edges of a graph *)
let iter_vertex f g =
for i = 0 to nb_vertex g - 1 do f i done
let iter_edges f g =
for i = 0 to nb_vertex g - 1 do
Bitv.iteri (fun j b -> if b then f i j) g.(i)
done
let fold_vertex f g a =
let n = nb_vertex g in
let rec fold i a = if i = n then a else fold (i+1) (f i a) in fold 0 a
let fold_edges f g a =
fold_vertex
(fun i a ->
Bitv.foldi_right (fun j b a -> if b then f i j a else a) g.(i) a)
g a
(* successors and predecessors of a vertex *)
let succ g i =
Bitv.foldi_left (fun l j b -> if b then j::l else l) [] g.(i)
let pred g i =
fold_vertex
(fun j a -> if Bitv.unsafe_get g.(j) i then j :: a else a)
g []
(* iter/fold on all successor/predecessor of a vertex. *)
let iter_succ f g i =
let si = g.(i) in
for j = 0 to nb_vertex g - 1 do if Bitv.unsafe_get si j then f j done
(* optimization w.r.t.
[Bitv.iteri (fun j b -> if b then f j) g.(i)]
*)
let iter_pred f g i =
for j = 0 to nb_vertex g - 1 do if Bitv.unsafe_get g.(j) i then f j done
let fold_succ f g i a =
Bitv.foldi_right (fun j b a -> if b then f j a else a) g.(i) a
let fold_pred f g i a =
fold_vertex
(fun j a -> if Bitv.unsafe_get g.(j) i then f j a else a)
g a
(* degree *)
let out_degree g i = fold_succ (fun _ n -> n + 1) g i 0
let in_degree g i = fold_pred (fun _ n -> n + 1) g i 0
(* map iterator on vertex *)
let map_vertex f g =
let n = nb_vertex g in
let g' = make n in
iter_edges
(fun i j ->
let fi = f i in
let fj = f j in
if fi < 0 || fi >= n || fj < 0 || fj >= n then
invalid_arg "[ocamlgraph] map_vertex";
Bitv.unsafe_set g'.(fi) fj true)
g;
g'
(* labeled edges going from/to a vertex *)
(* successors and predecessors of a vertex *)
let succ_e g i =
Bitv.foldi_left (fun l j b -> if b then (i,j)::l else l) [] g.(i)
let pred_e g i =
fold_vertex
(fun j a -> if Bitv.unsafe_get g.(j) i then (j,i) :: a else a)
g []
(* iter/fold on all labeled edges of a graph *)
let iter_edges_e f g =
for i = 0 to nb_vertex g - 1 do
Bitv.iteri (fun j b -> if b then f (i,j)) g.(i)
done
let fold_edges_e f g a =
fold_vertex
(fun i a ->
Bitv.foldi_right (fun j b a -> if b then f (i,j) a else a) g.(i) a)
g a
(* iter/fold on all edges going from/to a vertex *)
let iter_succ_e f g i =
let si = g.(i) in
for j = 0 to nb_vertex g - 1 do if Bitv.unsafe_get si j then f (i,j) done
let iter_pred_e f g i =
for j = 0 to nb_vertex g - 1 do
if Bitv.unsafe_get g.(j) i then f (j,i)
done
let fold_succ_e f g i a =
Bitv.foldi_right (fun j b a -> if b then f (i,j) a else a) g.(i) a
let fold_pred_e f g i a =
fold_vertex
(fun j a -> if Bitv.unsafe_get g.(j) i then f (j,i) a else a)
g a
end
module Graph = struct
module G = struct include Digraph type return = unit end
include Blocks.Graph(G)
(* Export some definitions of [G] *)
let make = G.make
(* Redefine the [add_edge] and [remove_edge] operations *)
let add_edge g v1 v2 =
G.add_edge g v1 v2;
ignore (G.unsafe_add_edge g v2 v1)
let add_edge_e g (v1, v2) = add_edge g v1 v2
let remove_edge g v1 v2 =
G.remove_edge g v1 v2;
ignore (G.unsafe_remove_edge g v2 v1)
let remove_edge_e g (v1, v2) = remove_edge g v1 v2
end
end
(* Faster implementations when vertices are not shared between graphs. *)
(****
module UV = struct
let cpt_vertex = ref min_int
type ('label, 'succ) vertex = {
tag : int;
label : 'label;
mutable mark : int;
mutable succ : 'succ;
}
module Digraph = struct
module Abstract(L: ANY_TYPE) :
Sig.IM with type V.label = L.t and type E.label = unit
=
struct
module rec V :
VERTEX with type label = L.t and type t = (L.t, S.t) vertex =
struct
type label = L.t
type t = (L.t, S.t) vertex
let compare x y = compare x.tag y.tag
let hash x = Hashtbl.hash x.tag
let equal x y = x.tag = y.tag
let label x = x.label
let create l =
assert (!cpt_vertex < max_int);
incr cpt_vertex;
{ tag = !cpt_vertex; label = l; mark = 0; succ = S.empty }
end
and S : Set.S with type elt = V.t = Set.Make(V)
type vertex = V.t
module E = struct
type t = V.t * V.t
type vertex = V.t
let compare = Stdlib.compare
type label = unit
let create v1 _ v2 = (v1, v2)
let src = fst
let dst = snd
let label _ = ()
end
type edge = E.t
type t = {
mutable vertices : S.t;
}
let create ?size () = { vertices = S.empty }
let is_directed = true
let is_empty g = S.is_empty g.vertices
let nb_vertex g = S.cardinal g.vertices
let out_degree _ v = S.cardinal v.succ
let clear g = g.vertices <- S.empty
let add_vertex g v = g.vertices <- S.add v g.vertices
let mem_vertex g v = S.mem v g.vertices
let iter_vertex f g = S.iter f g.vertices
let fold_vertex f g = S.fold f g.vertices
let succ _ v = S.elements v.succ
let succ_e _ v = List.map (fun w -> (v, w)) (S.elements v.succ)
let iter_succ f _ v = S.iter f v.succ
let iter_succ_e f _ v = S.iter (fun w -> f (v, w)) v.succ
let fold_succ f _ v acc = S.fold f v.succ acc
let fold_succ_e f _ v acc = S.fold (fun w acc -> f (v, w) acc) v.succ acc
let add_edge _ v1 v2 = v1.succ <- S.add v2 v1.succ
let add_edge_e g (v1, v2) = add_edge g v1 v2
let mem_edge _ v1 v2 = S.mem v2 v1.succ
let mem_edge_e g (v1, v2) = mem_edge g v1 v2
let remove_edge _ v1 v2 = v1.succ <- S.remove v2 v1.succ
let remove_edge_e g (v1, v2) = remove_edge g v1 v2
let nb_edges g = fold_vertex (fun v n -> n + S.cardinal v.succ) g 0
let find_edge g i j = if mem_edge g i j then i, j else raise Not_found
let find_all_edges g i j = try [ find_edge g i j ] with Not_found -> []
module Mark = struct
type graph = t
type vertex = V.t
let clear g = S.iter (fun v -> v.mark <- 0) g.vertices
let get v = v.mark
let set v m = v.mark <- m
end
end
module AbstractLabeled (V: ANY_TYPE)(E: ORDERED_TYPE_DFT) :
Sig.IM with type V.label = V.t and type E.label = E.t
=
AbstractLabeled
(V)(struct type t = unit let compare _ _ = 0 let default = () end)
end
(**
module Graph = struct
module Abstract(V: ANY_TYPE) :
Sig.IM with type V.label = V.t and type E.label = unit
module AbstractLabeled (V: ANY_TYPE)(E: ORDERED_TYPE_DFT) :
Sig.IM with type V.label = V.t and type E.label = E.t
end
**)
end
****)
(*
Local Variables:
compile-command: "make -C .."
End:
*)
ocamlgraph-2.0.0/src/xDotDraw.mli 0000644 0001750 0000144 00000007561 13735627615 015250 0 ustar rt users (**************************************************************************)
(* *)
(* This file is part of OcamlGraph. *)
(* *)
(* Copyright (C) 2009-2010 *)
(* CEA (Commissariat � l'�nergie Atomique) *)
(* *)
(* you can redistribute it and/or modify it under the terms of the GNU *)
(* Lesser General Public License as published by the Free Software *)
(* Foundation, version 2.1, with a linking exception. *)
(* *)
(* It 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. See the *)
(* GNU Lesser General Public License for more details. *)
(* *)
(* See the file ../LICENSE for more details. *)
(* *)
(* Authors: *)
(* - Julien Signoles (Julien.Signoles@cea.fr) *)
(* - Jean-Denis Koeck (jdkoeck@gmail.com) *)
(* - Benoit Bataille (benoit.bataille@gmail.com) *)
(* *)
(**************************************************************************)
(** Parses xdot drawing operations *)
(** See {{:http://www.graphviz.org/doc/info/output.html#d:xdot}dot documentation} to understand the drawing operations *)
(** {2 Types } *)
(** Dot layout coordinates *)
type pos = float * float
(** Dimensions *)
type width = float
type height = float
type size = int
(** Text alignment *)
type align = Left | Center | Right
(** Style attributes *)
type style_attr =
| Filled
| Invisible
| Diagonals
| Rounded
| Dashed
| Dotted
| Solid
| Bold
| StyleString of string
(** Drawing operations *)
type operation =
| Filled_ellipse of pos * width * height
| Unfilled_ellipse of pos * width * height
| Filled_polygon of pos array
| Unfilled_polygon of pos array
| Polyline of pos array
| Bspline of pos array
| Filled_bspline of pos array
| Text of pos * align * width * string
| Fill_color of string
| Pen_color of string
| Font of float * string
| Style of style_attr list
val string_scale_size:
fontMeasure:(
fontName: string -> fontSize:int ->
string -> (int * int)
) -> string -> float -> string -> width*height
(** [string_scale_size ~fontMeasure font font_size text].
Interpolates the font metrics we have to use to draw the given [text]
with the given font but preserving the bounding box of the [text] even
with a proportional font.
For a fixed width font the result is [font_size*font_size]. *)
(** {2 Parsing and drawing state } *)
(** Parses an xdot drawing attribute *)
val parse : string -> operation list
(** Some drawing operations modify the following drawing state
(pen_color, font and style).
*)
type draw_state = private {
mutable fill_color : string;
mutable pen_color : string;
mutable font : float * string;
mutable style : style_attr list;
}
(** Iterates on the drawing operations
and updates the implicit drawing state *)
val draw_with : (draw_state -> operation -> unit) -> operation list -> unit
(** {3 Miscellaneous} *)
(** Reads the color string and converts to rgb if in an another format *)
val normalize_color : string -> string
ocamlgraph-2.0.0/src/nonnegative.mli 0000644 0001750 0000144 00000004346 13735627615 016027 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(* This module is a contribution of Yuto Takei *)
(** Weighted graphs without negative-cycles. *)
(** This graph maintains the invariant that it is free of such cycles that
the total length of edges involving is negative. With introduction of
those negative-cycles causes an inability to compute the shortest paths
from arbitrary vertex. By using the graph modules defined here,
introduction of such a cycle is automatically prevented. *)
module Imperative
(G: Sig.IM)
(W: Sig.WEIGHT with type edge = G.E.t) : sig
include Sig.IM with module V = G.V and module E = G.E
exception Negative_cycle of G.E.t list
end
(** Persistent graphs with negative-cycle prevention *)
module Persistent
(G: Sig.P)
(W: Sig.WEIGHT with type edge = G.E.t) : sig
include Sig.P with module V = G.V and module E = G.E
exception Negative_cycle of G.E.t list
(** Exception [NegativeCycle] is raised whenever a negative cycle
is introduced for the first time (either with [add_edge]
or [add_edge_e]) *)
end
ocamlgraph-2.0.0/src/dGraphSubTree.mli 0000644 0001750 0000144 00000006517 13735627615 016213 0 ustar rt users (**************************************************************************)
(* *)
(* This file is part of OcamlGraph. *)
(* *)
(* Copyright (C) 2009-2010 *)
(* CEA (Commissariat � l'�nergie Atomique) *)
(* *)
(* you can redistribute it and/or modify it under the terms of the GNU *)
(* Lesser General Public License as published by the Free Software *)
(* Foundation, version 2.1, with a linking exception. *)
(* *)
(* It 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. See the *)
(* GNU Lesser General Public License for more details. *)
(* *)
(* See the file ../LICENSE for more details. *)
(* *)
(* Authors: *)
(* - Julien Signoles (Julien.Signoles@cea.fr) *)
(* - Jean-Denis Koeck (jdkoeck@gmail.com) *)
(* - Benoit Bataille (benoit.bataille@gmail.com) *)
(* *)
(**************************************************************************)
module type G = sig
type t
module V : sig
type t
type label
val label : t -> label
val hash : t -> int
val equal : t -> t -> bool
end
module E : sig
type t
end
val iter_succ : (V.t -> unit) -> t -> V.t -> unit
val iter_pred : (V.t -> unit) -> t -> V.t -> unit
val find_edge : t -> V.t -> V.t -> E.t
end
module type Tree = sig
type t
module V : sig
type t
type label
val create : label -> t
val label : t -> label
val hash : t -> int
val equal : t -> t -> bool
end
module E : Sig.EDGE with type vertex = V.t
val create : ?size:int -> unit -> t
val add_vertex : t -> V.t -> unit
val add_edge_e : t -> E.t -> unit
end
module type S = sig
module Tree: Tree with type E.label = unit
type t
val get_structure : t -> Tree.t
val get_root : t -> Tree.V.t
val get_tree_vertices : Tree.V.label -> t -> Tree.V.t list
val is_ghost_node : Tree.V.t -> t -> bool
val is_ghost_edge : Tree.E.t -> t -> bool
exception Ghost_node
val get_graph_vertex : Tree.V.t -> t -> Tree.V.label
end
module Make
(G : G)
(Tree : Tree with type V.label = G.V.t and type E.label = unit) :
sig
include S with module Tree = Tree
val make : G.t -> G.V.t -> int -> int -> t
end
module Make_from_dot_model
(Tree : Tree with type V.label = DGraphModel.DotG.V.t
and type E.label = unit) :
sig
include S with module Tree = Tree
val make:
(Tree.V.label, DGraphModel.DotG.E.t, string) DGraphModel.abstract_model ->
Tree.V.label -> int -> int -> t
end
ocamlgraph-2.0.0/src/flow.ml 0000644 0001750 0000144 00000054060 13735627615 014306 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
module type FLOW = sig
type t
type label
val max_capacity : label -> t
val flow : label -> t
val add : t -> t -> t
val sub : t -> t -> t
val zero : t
val compare : t -> t -> int
end
module type G_GOLDBERG_TARJAN = sig
type t
module V : Sig.COMPARABLE
module E : Sig.EDGE with type vertex = V.t
val nb_vertex : t -> int
val nb_edges : t -> int
val fold_edges_e : (E.t -> 'a -> 'a) -> t -> 'a -> 'a
val fold_succ_e : (E.t -> 'a -> 'a) -> t -> V.t -> 'a -> 'a
val fold_pred_e : (E.t -> 'a -> 'a) -> t -> V.t -> 'a -> 'a
end
module Goldberg_Tarjan
(G: G_GOLDBERG_TARJAN)
(F: FLOW with type label = G.E.label) =
struct
(* This code is a contribution of Guyslain Naves
Design notes:
This is an implementation of the classical Goldberg-Tarjan push-relabel
algorithm to compute maximum flow in directed graphs with upper capacities
on arcs. Several common optimizations are implemented to make it
more efficient than the pseudocode found in most textbooks on algorithms.
About the push-relabel algorithm.
--------------------------------------
Instead of keeping a valid flow and improving it by iteration (similar to
Ford-Fulkerson algorithm and its variants), the push-relabel always keep
a preflow and try make it becoe a flow. A preflow is a function on arcs that
violates the flow condition:
"flow that enters = flow that leaves (in every non-terminal vertex)"
and replaces it by:
" flow that enters >= flow that leaves (in every non-source vertex)"
That means that any vertex may have *excessive* flow entering it.
The algorithm proceed by making flow going down. Here down is defined
by a *potential*, an integer attached to every vertex. The excess at some
vertex can be routed to a successor in the residual graph with lower
potential. This is a *push* operation on the corresponding arc.
Pushing along all arcs leaving a vertex is a *discharge* of this vertex.
If a vertex is excessive, but no successor has lower potential, then we
increase the potential to make it slightly higher than at least one
of its successor. This is a *relabel* operation of that vertex.
The source (potential = n) and sink (potential = 0) may never be relabel.
The algorithm consists in doing push and relabel steps,
until no more are possible. Then the preflow is a maximum flow.
Optimizations.
--------------
- The simplest (and less efficient) way to optimize this algorithm is
to play with the order on which push and relabel operations are performed.
Here, the strategy used is the following:
1) sort excessive vertices by decreasing potential
2) for each vertex in that order:
a) discharge it
b) if still in excess, relabel it
(see [augmenting_step] and [discharge])
This is a basic strategy that could be improved.
- Textbook algorithms starts with non-source vertices with potential 0.
This forces the algorithm to perform a lot of relabel operations to get
to a more realistic and usable potential function. Here we use as initial
potential the distance from a vertex to the sink (even for the source).
(see [initialize_potential])
- The most important optimization: empirically one can check that the
push-relabel algorithm converges very quickly toward a preflow that maximizes
the flow sent to the sink. But then it takes very long to send back the
excessive flow to the source. Here we detect every few iterations if the
preflow is maximal. This is done by a bfs in the reversal of the residual
graph, by determining whether the source is reachable.
(see [is_maximum_preflow]).
Once the preflow is maximum (first pahse), we compute a maximum preflow from
sink to source in the reversed graph, with maximum capacities given by the
values of the maximum preflow just computed (second phase). This will
compute a reversed maximum preflow that must be actually a flow.
(see [compute_maximum_flow], and the use of [forward_context]
and [backward_context] for each of the two phases)
Implementation.
---------------
The most important thing is to understand that we are interested only
in the residual graph, and not by the original graph. Original arcs
may appears in one or two directions in the residual graph. This is
why we manipulate almost only [residual_arc] and no [arc = G.E.t].
It also implies that the incident arcs of a vertex are not those in
the original graph. Because we will work with both the residual graph
and its reversal, and that it depends on the current flow values, we
define two functions [incidence_residual] and [incidence_reversal].
Notice that their roles interchanged during the second phase.
[Forward] and [Backward] only refers to the orientation compared to the
orientation in the graph. Hence, in a reversed graph, backward residual arcs
are [Forward], and forward residual arcs are [Backward].
We define a type [context] containing the current state of computation.
We hide the data structures in [context] by providing [set] and [get]
functions. It makes the code more readable, and easier to modify if one
would like to change the data structures.
Structure of the code:
The first part of the code contains mostly helpers, up to the bfs algorithm.
With the bfs comes the function to compute the initial potential and
check the maximality of a preflow.
Then we define the push, relabel, discharge operations, and the functions
computing maximal preflows.
Finally we define how to initialize a context, and the max flow algorithm.
We choose to require by a functor the implementations for the main data
structures used by the algorithm. VMap and EMap could be replaced by
arrays for better efficiency, or using vertex and edge labels.
They are used to record potentials, excesses and flows.
VSet is used to track vertices that are still in excess. Because
we sort those vertices, using search trees would not be a problem,
but an array of size [G.nb_vertex] could degrade the performance.
The default is a hash table densely filled, hence [sort_by_potential]
is the asymptotical bottleneck.
Parameter:
- [param_freq_check_preflow]: used to parametrized how often one should check
whether the current preflow is maximum.
*)
type vertex = G.V.t
type arc = G.E.t
type flow = F.t
let (|>) x f = f x
open G
module Q = PersistentQueue
module VH = Hashtbl.Make(G.V)
module EM = Map.Make(G.E)
module VMap = struct
type 'a t = 'a VH.t
let create = VH.create
let add tbl key value = VH.add tbl key value
let remove tbl key = VH.remove tbl key
let find tbl key =
try Some (VH.find tbl key)
with Not_found -> None
end
module VSet = struct
type t = unit VH.t
let create () = VH.create 16
let add tbl v =
if not (VH.mem tbl v) then VH.add tbl v ()
let elements tbl = VH.fold (fun v () list -> v::list) tbl []
end
module EMap = struct
type 'a t = 'a EM.t ref
let create _ = ref EM.empty
let add map edge value =
map := EM.add edge value !map
let find map edge =
try Some (EM.find edge !map)
with Not_found -> None
end
let min_flow a b = if F.compare a b < 0 then a else b
let (+-) = F.add
let (--) = F.sub
let is_positive a = F.compare a F.zero > 0
let max_capacity e = F.max_capacity (E.label e)
type residual_arc =
| Forward of arc
| Backward of arc
(* context for computations *)
type context =
{
nb_vertices : int;
source : vertex;
sink : vertex;
reversed : bool;
incident : context -> vertex -> residual_arc list;
reverse_incident : context -> vertex -> residual_arc list;
max_capacity : arc -> F.t;
excess : flow VMap.t;
potential : int VMap.t;
mutable excessives : VSet.t;
flow : flow EMap.t
}
let get_excess ctxt vertex =
match VMap.find ctxt.excess vertex with
| Some value -> value
| None -> F.zero
let get_potential ctxt vertex =
match VMap.find ctxt.potential vertex with
| Some value -> value
| None -> 2 * ctxt.nb_vertices (* sink is not reachable from vertex *)
let set_excess ctxt vertex value =
VMap.remove ctxt.excess vertex;
VMap.add ctxt.excess vertex value
let set_potential ctxt vertex pi =
VMap.remove ctxt.potential vertex;
VMap.add ctxt.potential vertex pi
let mark_excessive ctxt vertex =
VSet.add ctxt.excessives vertex
let extract_excessives ctxt =
let in_excess = VSet.elements ctxt.excessives in
ctxt.excessives <- VSet.create ();
in_excess
let get_flow context arc =
match EMap.find context.flow arc with
| Some value -> value
| None -> F.zero
let set_flow context arc value =
EMap.add context.flow arc value
let get_capacity context = function
| Backward arc
| Forward arc -> context.max_capacity arc
(* residual graph helpers *)
let origin : residual_arc -> vertex = function
| Forward arc -> E.src arc
| Backward arc -> E.dst arc
let destination : residual_arc -> vertex = function
| Forward arc -> E.dst arc
| Backward arc -> E.src arc
let forward arc = Forward arc
let backward arc = Backward arc
let residual_capacity : context -> residual_arc -> flow =
fun context residual_arc -> match context.reversed, residual_arc with
| true, Forward arc
| false, Backward arc -> get_flow context arc
| _, Backward arc
| _, Forward arc -> F.sub (context.max_capacity arc) (get_flow context arc)
let is_forward context arc =
is_positive (context.max_capacity arc -- get_flow context arc)
let is_backward context arc =
is_positive (get_flow context arc)
let augment : context -> residual_arc -> F.t -> unit =
fun context residual_arc delta -> match context.reversed, residual_arc with
| true, Backward arc
| false, Forward arc ->
get_flow context arc +- delta |> set_flow context arc
| _, Backward arc
| _, Forward arc ->
get_flow context arc -- delta |> set_flow context arc
let cons e l = e::l
(* incidence function in the residual graph
and in the reversal of the residual of the reversed graph *)
let incidence_residual graph context vertex =
begin
fold_succ_e cons graph vertex []
|> List.filter (is_forward context)
|> List.map forward
end @ begin
fold_pred_e cons graph vertex []
|> List.filter (is_backward context)
|> List.map backward
end
(* incidence function in the reversal of the residual graph
and in the residual of the reversed graph *)
let incidence_reversal graph context vertex =
begin
fold_succ_e cons graph vertex []
|> List.filter (is_backward context)
|> List.map forward
end @ begin
fold_pred_e cons graph vertex []
|> List.filter (is_forward context)
|> List.map backward
end
(* Breadth-first search algorithm, with application of
* a function on each arc of the BFS tree. *)
let generic_bfs :
int ->
(vertex -> residual_arc list) ->
(residual_arc -> unit) ->
vertex -> unit
=
fun nb_vertices incidence iter_fun source ->
let reached = VMap.create nb_vertices in
let frontier = ref Q.empty in
let add_arc arc =
let dest = destination arc in
if VMap.find reached dest = None then
( VMap.add reached dest ();
iter_fun arc;
frontier := Q.add !frontier dest
)
in
let explore vertex = List.iter add_arc (incidence vertex) in
VMap.add reached source ();
explore source;
while not (Q.is_empty !frontier) do
explore (Q.head !frontier);
frontier := Q.tail !frontier
done
(* labels the vertices by their distance to the sink.
This is used to initial the potential of vertices,
and drastically improve the performance of the algorithm. *)
let initialize_potential context sink =
let update arc =
get_potential context (origin arc) + 1
|> set_potential context (destination arc)
in
set_potential context sink 0;
generic_bfs
context.nb_vertices
(context.reverse_incident context)
update
sink
(* checks whether a preflow is maximum.
Happens if no excessive vertex is reverse-reachable from the sink.
*)
exception Break
let is_maximum_preflow context =
let check_arc arc =
if F.compare (get_excess context (destination arc)) F.zero <> 0 then
raise Break
in
try
generic_bfs
context.nb_vertices
(context.reverse_incident context)
check_arc
context.sink;
true
with Break -> false
(* Push-relabel operations *)
(* push excessive flow along an residual arc *)
let push context arc =
let (u,v) = (origin arc, destination arc) in
let exc_u = get_excess context u in
if is_positive exc_u then
begin
let delta = min_flow exc_u (residual_capacity context arc) in
exc_u -- delta |> set_excess context u;
get_excess context v +- delta |> set_excess context v;
augment context arc delta;
mark_excessive context v
end
(* Augment potential of a vertex to get a lower-potential successor *)
let relabel context vertex =
context.incident context vertex
|> List.map (fun arc -> get_potential context (destination arc))
|> List.fold_left min (get_potential context vertex)
|> fun pi -> set_potential context vertex (pi+1)
(* push can be done only on arc with difference of potential = -1 *)
let is_admissible context arc =
let (u,v) = (origin arc, destination arc) in
get_potential context v - get_potential context u = -1
(* push as much flow from a vertex as allowed. *)
let discharge context vertex =
context.incident context vertex
|> List.filter (is_admissible context)
|> List.iter (push context)
|> fun () ->
if is_positive (get_excess context vertex) then
begin
relabel context vertex;
mark_excessive context vertex
end
(* Optimization: push vertices ordered by their potential.
(better strategies may be possible). *)
let compare_potential context u v =
get_potential context v - get_potential context u
let sort_by_potential context = List.sort (compare_potential context)
let is_dischargeable context v =
v <> context.source
&& v <> context.sink
&& is_positive (get_excess context v)
let augmenting_step context currently_in_excess =
context.excessives <- VSet.create ();
currently_in_excess
|> List.filter (is_dischargeable context)
|> sort_by_potential context
|> List.iter (discharge context)
let param_freq_check_preflow = ref 1000
let compute_max_preflow context =
let nb_steps = ref 0 in
let in_excess = ref (extract_excessives context) in
let check_freq = context.nb_vertices / !param_freq_check_preflow + 1 in
let is_maximum () =
( !in_excess = [] )
|| ( !nb_steps mod check_freq = 0 && is_maximum_preflow context )
in
while not (is_maximum ()) do
augmenting_step context !in_excess;
in_excess := extract_excessives context;
incr nb_steps
done
(* Maximally push each arc leaving the source,
set the potential of any vertex at distance to sink (optimization). *)
let init_context context =
let out_source = context.incident context context.source in
initialize_potential context context.sink;
set_potential context context.source context.nb_vertices;
out_source
|> List.map (get_capacity context)
|> List.fold_left F.add F.zero
|> set_excess context context.source;
out_source
|> List.iter (push context);
context
let new_context graph ~source ~sink ~reversed ~max_capacity ~flow =
let nb_vertices = G.nb_vertex graph in
init_context
{ nb_vertices; source; sink; reversed; max_capacity; flow;
incident =
if reversed then incidence_reversal graph
else incidence_residual graph;
reverse_incident =
if reversed then incidence_residual graph
else incidence_reversal graph;
excess = VMap.create nb_vertices;
potential = VMap.create nb_vertices;
excessives = VSet.create ();
}
let maxflow graph source sink =
let init_flow () =
let flow = EMap.create (G.nb_edges graph) in
G.fold_edges_e (fun e () -> EMap.add flow e F.zero) graph ();
flow
in
let forward_context =
new_context graph ~source ~sink
~reversed:false
~max_capacity
~flow:(init_flow ())
in
compute_max_preflow forward_context;
let backward_context =
new_context graph
~source:sink
~sink:source
~reversed:true
~max_capacity:(get_flow forward_context)
~flow:(init_flow ())
in
compute_max_preflow backward_context;
let max_flow_value =
fold_succ_e cons graph source []
|> List.map (get_flow backward_context)
|> List.fold_left F.add F.zero
in
let f e =
match EMap.find backward_context.flow e with
| Some x -> x | None -> F.zero in
f, max_flow_value
end
(*****************************************************************************)
module type G_FORD_FULKERSON = sig
type t
module V : Sig.HASHABLE
module E : sig
type t
type label
val src : t -> V.t
val dst : t -> V.t
val label : t -> label
end
val iter_succ_e : (E.t -> unit) -> t -> V.t -> unit
val iter_pred_e : (E.t -> unit) -> t -> V.t -> unit
end
module type FLOWMIN = sig
include FLOW
val min_capacity : label -> t
end
module Ford_Fulkerson
(G: G_FORD_FULKERSON)
(F: FLOWMIN with type label = G.E.label) =
struct
(* redefinition of F *)
module F = struct
include F
type u =
| Flow of F.t
| Infinity
let min x y = match x, y with
| Flow _, Infinity -> x
| Flow fx, Flow fy when F.compare fx fy < 0 -> x
| (Infinity, _) | (Flow _, Flow _) -> y
end
module Mark = struct
module H = Hashtbl.Make(G.V)
type mark = Plus | Minus
let marked = H.create 97
let unvisited = Queue.create ()
let clear () = H.clear marked
let mem = H.mem marked
let set s e tag =
assert (not (mem s));
H.add marked s (e, tag);
Queue.add s unvisited
let get s : G.E.t * mark =
let e, tag = H.find marked s in
(match e with None -> assert false | Some e -> e), tag
let next () = Queue.pop unvisited
end
module Result = struct
module H =
Hashtbl.Make
(struct
open G
type t = E.t
module U = Util.HTProduct(V)(V)
let equal e1 e2 = U.equal (E.src e1, E.dst e1) (E.src e2, E.dst e2)
let hash e = U.hash (E.src e, E.dst e)
end)
let create () = H.create 97
let find = H.find
let flow r e =
try
find r e
with Not_found ->
let f = F.flow (G.E.label e) in
H.add r e f;
f
let change op r e f =
try
H.replace r e (op (find r e) f);
with Not_found ->
assert false
let grow = change F.add
let reduce = change F.sub
end
let is_full r e =
F.compare (F.max_capacity (G.E.label e)) (Result.flow r e) = 0
let is_empty r e =
F.compare (F.min_capacity (G.E.label e)) (Result.flow r e) = 0
let set_flow r s t a =
let rec loop t =
if not (G.V.equal s t) then
let e, tag = Mark.get t in
match tag with
| Mark.Plus -> Result.grow r e a; loop (G.E.src e)
| Mark.Minus -> Result.reduce r e a; loop (G.E.dst e)
in
loop t
let grow_flow r s t a =
let rec loop u b =
if G.V.equal s u then begin
match b with
| F.Infinity -> (* source = destination *)
assert (G.V.equal s t);
a
| F.Flow f ->
set_flow r s t f;
F.add a f
end else
let e, tag = Mark.get u in
let l = G.E.label e in
match tag with
| Mark.Plus ->
loop
(G.E.src e)
(F.min b (F.Flow (F.sub (F.max_capacity l) (Result.flow r e))))
| Mark.Minus ->
loop
(G.E.dst e)
(F.min b (F.Flow (F.sub (Result.flow r e) (F.min_capacity l))))
in
loop t F.Infinity
let maxflow g s t =
let r = Result.create () in
let succ s =
G.iter_succ_e
(fun e ->
assert (G.V.equal s (G.E.src e));
let t = G.E.dst e in
if not (Mark.mem t || is_full r e) then
Mark.set t (Some e) Mark.Plus)
g s
in
let pred s =
G.iter_pred_e
(fun e ->
assert (G.V.equal s (G.E.dst e));
let t = G.E.src e in
if not (Mark.mem t || is_empty r e) then
Mark.set t (Some e) Mark.Minus)
g s
in
let internal_loop a =
try
while true do let s = Mark.next () in succ s; pred s done;
assert false
with Queue.Empty ->
if Mark.mem t then grow_flow r s t a else a
in
let rec external_loop a =
Mark.clear ();
Mark.set s None Mark.Plus;
let a' = internal_loop a in
if F.compare a a' = 0 then a else external_loop a'
in
let a = external_loop F.zero in
(fun e -> try Result.find r e with Not_found -> F.flow (G.E.label e)), a
end
ocamlgraph-2.0.0/src/dGraphTreeModel.mli 0000644 0001750 0000144 00000006032 13735627615 016512 0 ustar rt users (**************************************************************************)
(* *)
(* This file is part of OcamlGraph. *)
(* *)
(* Copyright (C) 2009-2010 *)
(* CEA (Commissariat � l'�nergie Atomique) *)
(* *)
(* you can redistribute it and/or modify it under the terms of the GNU *)
(* Lesser General Public License as published by the Free Software *)
(* Foundation, version 2.1, with a linking exception. *)
(* *)
(* It 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. See the *)
(* GNU Lesser General Public License for more details. *)
(* *)
(* See the file ../LICENSE for more details. *)
(* *)
(* Authors: *)
(* - Julien Signoles (Julien.Signoles@cea.fr) *)
(* - Jean-Denis Koeck (jdkoeck@gmail.com) *)
(* - Benoit Bataille (benoit.bataille@gmail.com) *)
(* *)
(**************************************************************************)
module type S = sig
module Tree: Graphviz.GraphWithDotAttrs
module TreeManipulation : sig
type t
val get_structure : t -> Tree.t
val get_tree_vertices : Tree.V.label -> t -> Tree.V.t list
val get_graph_vertex : Tree.V.t -> t -> Tree.V.label
val is_ghost_node : Tree.V.t -> t -> bool
val is_ghost_edge : Tree.E.t -> t -> bool
end
type cluster = string
type graph_layout
class tree_model :
graph_layout ->
TreeManipulation.t ->
[ Tree.V.t, Tree.E.t, cluster ] DGraphModel.abstract_model
val tree : unit -> TreeManipulation.t
end
(** This functor creates a model centered on a vertex from a graph *)
module SubTreeMake(G : Graphviz.GraphWithDotAttrs) : sig
include S with type Tree.V.label = G.V.t
val from_graph :
?depth_forward:int -> ?depth_backward:int ->
fontMeasure:(
fontName:string -> fontSize:int -> string -> int * int
) -> G.t -> G.V.t -> tree_model
end
(** Creates a model centered on a vertex from a dot model *)
module SubTreeDotModelMake : sig
include S with type Tree.V.label = DGraphModel.DotG.V.t
val from_model :
?depth_forward:int -> ?depth_backward:int
-> DGraphModel.dotg_model
-> DGraphModel.DotG.V.t
-> tree_model
end
ocamlgraph-2.0.0/src/util.ml 0000644 0001750 0000144 00000004141 13735627615 014307 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
open Sig
module OTProduct(X: ORDERED_TYPE)(Y: ORDERED_TYPE) = struct
type t = X.t * Y.t
let compare (x1, y1) (x2, y2) =
let cv = X.compare x1 x2 in
if cv != 0 then cv else Y.compare y1 y2
end
module HTProduct(X: HASHABLE)(Y: HASHABLE) = struct
type t = X.t * Y.t
let equal (x1, y1) (x2, y2) = X.equal x1 x2 && Y.equal y1 y2
let hash (x, y) = Hashtbl.hash (X.hash x, Y.hash y)
end
module CMPProduct(X: COMPARABLE)(Y: COMPARABLE) = struct
include HTProduct(X)(Y)
include (OTProduct(X)(Y): sig val compare : t -> t -> int end)
end
module DataV(L : sig type t end)(V : Sig.COMPARABLE) = struct
type data = L.t
type label = V.t
type t = data ref * V.t
let compare (_, x) (_, x') = V.compare x x'
let hash (_, x) = V.hash x
let equal (_, x) (_, x') = V.equal x x'
let create y lbl = (ref y, lbl)
let label (_, z) = z
let data (y, _) = !y
let set_data (y, _) = (:=) y
end
ocamlgraph-2.0.0/src/coloring.mli 0000644 0001750 0000144 00000007762 13735627615 015333 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(** [k]-coloring of undirected graphs.
A [k]-coloring of a graph [g] is a mapping [c] from nodes to [\{1,...,k\}]
such that [c(u) <> c(v)] for any edge [u-v] in [g]. *)
exception NoColoring
(** {2 Graph coloring for graphs with integer marks} *)
(** Minimal graph signature for {!Mark}.
Sub-signature of {!Sig.IM}. *)
module type GM = sig
val is_directed : bool
type t
val nb_vertex : t -> int
module V : Sig.COMPARABLE
val out_degree : t -> V.t -> int
val iter_vertex : (V.t -> unit) -> t -> unit
val fold_vertex : (V.t -> 'a -> 'a) -> t -> 'a -> 'a
val iter_succ : (V.t -> unit) -> t -> V.t -> unit
val fold_succ : (V.t -> 'a -> 'a) -> t -> V.t -> 'a -> 'a
module Mark : sig
val get : V.t -> int
val set : V.t -> int -> unit
end
end
(** Provide a function for [k]-coloring a graph with integer marks.
The provided function is more efficient that the one provided by functor
{!Make} above. *)
module Mark(G : GM) : sig
val coloring : G.t -> int -> unit
(** [coloring g k] colors the nodes of graph [g] using [k] colors,
assigning the marks integer values between 1 and [k].
The graph marks may be partially set before starting; the meaning of
initial values is as follows:
- 0: a node to be colored
- any value between 1 and [k]: a color already assigned
- any value greater than [k]: a node to be ignored
@raise NoColoring if [g] cannot be [k]-colored.
Worst-case time complexity is exponential. Space complexity is O(V). *)
val two_color: G.t -> unit
(** [two_color g] attemps to color [g] with colors 1 and 2.
@raise NoColoring if this is not possible (i.e., if the graph
is not bipartite). Runs in O(V+E). *)
end
(** {2 Graph coloring for graphs without marks} *)
(** Minimal graph signature for {!Make}.
Sub-signature of {!Sig.G}. *)
module type G = sig
val is_directed : bool
type t
val nb_vertex : t -> int
module V : Sig.COMPARABLE
val out_degree : t -> V.t -> int
val iter_vertex : (V.t -> unit) -> t -> unit
val fold_vertex : (V.t -> 'a -> 'a) -> t -> 'a -> 'a
val iter_succ : (V.t -> unit) -> t -> V.t -> unit
val fold_succ : (V.t -> 'a -> 'a) -> t -> V.t -> 'a -> 'a
end
(** Provide a function for [k]-coloring a graph. *)
module Make(G: G) : sig
module H : Hashtbl.S
with type key = G.V.t
and type 'a t = 'a Hashtbl.Make(G.V).t
(** Hash tables used to store the coloring *)
val coloring : G.t -> int -> int H.t
(** [coloring g k] colors the graph [g] with [k] colors and returns the
coloring as a hash table mapping nodes to their colors.
Colors are integers from 1 to [k].
@raise NoColoring if [g] cannot be [k]-colored.
Worst-case time complexity is exponential. Space complexity is O(V). *)
val two_color : G.t -> int H.t
end
ocamlgraph-2.0.0/src/cliquetree.ml 0000644 0001750 0000144 00000017772 13735627615 015512 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
module CliqueTree(Gr : Sig.G) = struct
(* Vertex signature *)
module rec CliqueV :
sig
type t
val compare : t -> t -> int
val hash : t -> int
val equal : t -> t -> bool
val label : t -> t
val create : Gr.V.t -> t
val vertex : t -> Gr.V.t
val number : t -> int
val set_number : t -> int -> unit
val clique : t -> int
val set_clique : t -> int -> unit
val mark : t -> int
val incr_mark : t -> unit
val m : t -> CVS.t
val set_m : t -> CVS.t -> unit
val last : t -> t
val set_last : t -> t -> unit
end =
struct
type t = {
mutable mark: int;
orig: Gr.V.t;
mutable m: CVS.t;
mutable last: t option;
mutable number: int;
mutable clique: int;
}
let compare x y = Gr.V.compare x.orig y.orig
let hash x = Gr.V.hash x.orig
let equal x y = Gr.V.equal x.orig y.orig
let label x = x
let create o = {
mark = 0;
orig = o;
m = CVS.empty;
last = None;
number = 0;
clique = -1;
}
let vertex x = x.orig
let clique x = x.clique
let set_clique x v = x.clique <- v
let number x = x.number
let set_number x v = x.number <- v
let mark x = x.mark
let incr_mark x =
(*Printf.printf "Increasing mark of %s to %i\n%!"
(Gr.v_to_string x.orig) (succ x.mark);*)
x.mark <- succ x.mark
let m x = x.m
let set_m x v = x.m <- v
let last x =
match x.last with
Some v -> v
| None -> failwith "last not set"
let set_last x v = x.last <- Some v
end
(* Clique tree vertex set *)
and CVS : Set.S with type elt = CliqueV.t = Set.Make(CliqueV)
(* The final clique tree vertex type:
- set of original vertexes ordered by mark.
- clique number.
*)
module CliqueTreeV =
Util.DataV
(struct type t = CliqueV.t list * CVS.t end)
(struct
type t = int
let compare : t -> t -> int = Stdlib.compare
let hash (x:t) = Hashtbl.hash x
let equal (x:int) (y:int) = x = y
end)
module CliqueTreeE = struct
type t = int * CVS.t
let compare (x, _ : t) (y, _ : t) = Stdlib.compare x y
let default = (0, CVS.empty)
let create n s = (n, s)
let vertices = snd
let width g tri (_, x) =
let vertices = List.map CliqueV.vertex (CVS.elements x) in
let w =
List.fold_left
(fun w v ->
List.fold_left
(fun w v' ->
if v <> v' then
if not (Gr.mem_edge g v v') && Gr.mem_edge tri v v'
then succ w
else w
else w)
w vertices)
0 vertices
in
assert(w mod 2 = 0);
w / 2
end
(* The returned tree *)
module CliqueTree =
Persistent.Digraph.ConcreteLabeled(CliqueTreeV)(CliqueTreeE)
(* Intermediate graph *)
module G = Persistent.Graph.Concrete(CliqueV)
(* Creates the intermediate graph from the original *)
module Copy = Gmap.Vertex(Gr)(struct include G include Builder.P(G) end)
open CliqueV
let mcs_clique g =
(* initializations *)
let n = Gr.nb_vertex g in
let g' = Copy.map CliqueV.create g in
let unnumbered = ref (G.fold_vertex CVS.add g' CVS.empty) in
let pmark = ref (-1) in
let order = ref [] in
let cliques = Array.make n ([], CVS.empty) in
let ties = ref [] in
let j = ref 0 in
(* loop, taking each unnumbered vertex in turn *)
for i = n downto 1 do
(* Find greatest unnumbered vertex
if CVS.is_empty !unnumbered then
Printf.printf "No more unnumbered vertices\n%!"
else
Printf.printf "%i unnumbered vertices remaining\n%!"
(CVS.cardinal !unnumbered);
*)
let x, mark =
let choosed = CVS.choose !unnumbered in
CVS.fold
(fun x ((_maxx, maxv) as max) ->
let v = mark x in
if v > maxv then (x, v) else max)
!unnumbered (choosed, mark choosed)
in
(* peo construction *)
order := x :: !order;
(* now numbered *)
unnumbered := CVS.remove x !unnumbered;
if mark <= !pmark then begin
(* Create a new clique (lemma 8) *)
incr j;
(* m x is the neighborhoud of x in the previous clique *)
cliques.(!j) <- ([x], CVS.add x (m x));
(* Use reverse map of cliques to find what clique
we're connected to. m x is the width of the ties *)
let clast = clique (last x) in
ties := (clast, m x, !j) :: !ties;
end else begin
let l, c = cliques.(!j) in
cliques.(!j) <- (x::l, CVS.add x c);
end;
G.iter_succ
(fun y ->
if number y == 0 then begin
incr_mark y;
set_m y (CVS.add x (m y));
end;
set_last y x)
g' x;
pmark := mark;
set_number x i;
set_clique x !j;
done;
let cliques =
Array.mapi
(fun i (l, c) -> CliqueTreeV.create (List.rev l, c) i)
(Array.sub cliques 0 (succ !j))
in
let tree =
Array.fold_left CliqueTree.add_vertex CliqueTree.empty cliques
in
let tree, _ =
List.fold_left
(fun (g, n) (i, verts, j) ->
let label = CliqueTreeE.create n verts in
let edge = CliqueTree.E.create cliques.(i) label cliques.(j) in
(CliqueTree.add_edge_e g edge, succ n))
(tree, 1) !ties
in
List.map CliqueV.vertex !order, tree, cliques.(0)
let sons g x = CliqueTree.fold_succ (fun x y -> x :: y) g x []
exception NotClique
let test_simpliciality_first' l sons =
List.for_all
(fun son ->
match !son with
| [] -> false
| xi :: _ ->
let other = m xi in
CVS.subset other l)
sons
let test_simpliciality_next vertices _sons =
match vertices with
| x :: tl ->
begin
try
ignore(
List.fold_left
(fun vm v' ->
let vm' = CliqueV.m v' in
if CVS.equal vm' vm then
CVS.add v' vm'
else raise NotClique)
(CVS.add x (m x)) tl);
true
with NotClique -> false
end
| _ -> true
let is_chordal g =
let _order, tree, root = mcs_clique g in
let rec aux c =
let csons = sons tree c in
let s = List.map CliqueTreeV.data csons in
let l = CliqueTreeV.data c in
let sons () = List.map (fun (x,_) -> ref x) s in
let first = test_simpliciality_first' (snd l) (sons ()) in
let next = test_simpliciality_next (fst l) (sons ()) in
first && next && (List.for_all aux csons)
in
aux root
let maxwidth g tri tree =
CliqueTree.fold_edges_e
(fun e res ->
let w = CliqueTreeE.width g tri (CliqueTree.E.label e) in
max res w)
tree 0
end
ocamlgraph-2.0.0/src/strat.mli 0000644 0001750 0000144 00000007200 13735627615 014637 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(** Strategies
Implementation of a winning strategy of a graph: the graph
represents a two players game, each vertex belongs to either player
(whose turn it is to play) and describes a configuration of the
game. The algorithm computes the winning strategy of a player, if any;
i.e. the moves to play (which vertex to go to) so that for all
possible moves of the other player, the game goes through a final
state.
@author Nicolas Ayache *)
(** Signature for graphs *)
module type G = sig
type t
module V : Sig.ORDERED_TYPE
type vertex = V.t
val mem_vertex : t -> vertex -> bool
val succ : t -> vertex -> vertex list
val fold_vertex : (vertex -> 'a -> 'a) -> t -> 'a -> 'a
val fold_succ : (vertex -> 'a -> 'a) -> t -> vertex -> 'a -> 'a
end
(** Signature for graph add-ons: an initial vertex, final vertices
and membership of vertices to either true or false,
i.e. first or second player *)
module type PLAYER = sig
type t
type vertex
val get_initial : t -> vertex
val is_final : t -> vertex -> bool
val turn : t -> vertex -> bool
end
(** Signature for strategies: for a given state, the strategy tells
which state to go to *)
module type STRAT = sig
type t
type vertex
val empty : t
val add : t -> vertex -> vertex -> t
val next : t -> vertex -> vertex
(** @raise Invalid_argument if vertex's image is not defined *)
end
(** Implements strategy algorithms on graphs *)
module Algo
(G : G)
(P : PLAYER with type vertex = G.vertex)
(S : STRAT with type vertex = G.vertex) :
sig
(** [coherent_player g p] returns [true] iff
the completion [p] is coherent w.r.t.
the graph g *)
val coherent_player : G.t -> P.t -> bool
(** [coherent_strat g s] returns [true] iff
the strategy [s] is coherent w.r.t.
the graph [g] *)
val coherent_strat : G.t -> S.t -> bool
(** [game g p a b] returns [true] iff [a] wins in [g]
given the completion [p] (i.e. the game
goes through a final state). *)
val game : G.t -> P.t -> S.t -> S.t -> bool
(** [strategy g p s] returns [true] iff [s] wins in [g]
given the completion [p], whatever strategy
plays the other player. *)
val strategy : G.t -> P.t -> S.t -> bool
(** [strategyA g p] returns [true] iff there
exists [a] winning stragegy for the true
player. In this case, the winning
strategy is provided. *)
val strategyA : G.t -> P.t -> (bool * S.t)
end
ocamlgraph-2.0.0/src/components.ml 0000644 0001750 0000144 00000010332 13735627615 015516 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
module type G = sig
type t
module V : Sig.COMPARABLE
val iter_vertex : (V.t -> unit) -> t -> unit
val iter_succ : (V.t -> unit) -> t -> V.t -> unit
end
module Make(G: G) = struct
module H = Hashtbl.Make(G.V)
(* iterative code using a stack (variable [cont] below) *)
type action =
| Finish of G.V.t * int
| Visit of G.V.t * G.V.t
| Test of G.V.t * G.V.t
let scc g =
let root = H.create 997 in
let hashcomp = H.create 997 in
let stack = ref [] in
let numdfs = ref 0 in
let numcomp = ref 0 in
let rec pop x = function
| ((y: int), w) :: l when y > x ->
H.add hashcomp w !numcomp;
pop x l
| l -> l
in
let cont = ref [] in
let visit v =
if not (H.mem root v) then begin
let n = incr numdfs; !numdfs in
H.add root v n;
cont := Finish (v, n) :: !cont;
G.iter_succ
(fun w ->
cont := Visit (v, w) :: Test (v, w) :: !cont)
g v;
end
in
let rec finish () = match !cont with
| [] -> ()
| action :: tail ->
cont := tail;
begin match action with
| Finish (v, n) ->
if H.find root v = n then begin
H.add hashcomp v !numcomp;
let s = pop n !stack in
stack:= s;
incr numcomp
end else
stack := (n, v) :: !stack;
| Visit (_, w) -> visit w
| Test (v, w) ->
if not (H.mem hashcomp w) then
H.replace root v (min (H.find root v) (H.find root w))
end;
finish ()
in
let visit_and_finish v =
visit v;
finish ()
in
G.iter_vertex visit_and_finish g;
!numcomp, (fun v -> H.find hashcomp v)
let scc_array g =
let n,f = scc g in
let t = Array.make n [] in
G.iter_vertex (fun v -> let i = f v in t.(i) <- v :: t.(i)) g;
t
let scc_list g =
let a = scc_array g in
Array.fold_right (fun l acc -> l :: acc) a []
end
(** Connected components (for undirected graphs) *)
module type U = sig
type t
module V : Sig.COMPARABLE
val iter_vertex : (V.t -> unit) -> t -> unit
val iter_edges : (V.t -> V.t -> unit) -> t -> unit
end
module Undirected(G: U) = struct
module UF = Unionfind.Make(G.V)
module H = Hashtbl.Make(G.V)
let components g =
let vertices = ref [] in
G.iter_vertex (fun v -> vertices := v :: !vertices) g;
let uf = UF.init !vertices in
let visit u v = UF.union u v uf in
G.iter_edges visit g;
let count = ref 0 in
let comp = H.create 5003 in
let visit v =
let v = UF.find v uf in
if not (H.mem comp v) then begin H.add comp v !count; incr count end in
G.iter_vertex visit g;
!count, (fun v -> H.find comp (UF.find v uf))
let components_array g =
let n,f = components g in
let t = Array.make n [] in
G.iter_vertex (fun v -> let i = f v in t.(i) <- v :: t.(i)) g;
t
let components_list g =
let a = components_array g in
Array.fold_right (fun l acc -> l :: acc) a []
end
ocamlgraph-2.0.0/src/md.ml 0000644 0001750 0000144 00000010544 13735627615 013736 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
module P(G : Sig.P) = struct
module CT = Cliquetree.CliqueTree(G)
type edgeset = (G.V.t * G.V.t) list
let md g =
let gref = ref g in
let gtri = ref g in
let n = G.nb_vertex g in
let tri = ref [] in
let ord = ref [] in
let i = ref 0 in
while not (CT.is_chordal !gtri) && !i < n do
let v =
let x =
G.fold_vertex
(fun v' x ->
let deg' = G.out_degree !gref v' in
match x with
Some (_,deg) when deg' > deg -> x
| _ -> Some (v', deg'))
!gref None
in match x with
Some (v,_) -> v
| None -> failwith "Expecting some vertex"
in
let ng = G.succ !gref v in
let g', tri' =
List.fold_left
(fun (g, tri) v ->
let tri' =
List.fold_left
(fun tri v' ->
if v <> v' && not (G.mem_edge g v v') then
(v, v') :: tri
else tri)
tri ng
in
let g' =
List.fold_left
(fun g v' ->
if v <> v' then
G.add_edge g v v'
else g)
g ng
in
(g', tri'))
(!gref, []) ng
in
ord := v :: !ord;
gtri := List.fold_left
(fun g (x,y) -> G.add_edge g x y)
!gtri tri';
gref := G.remove_vertex g' v;
tri := tri' @ !tri;
incr i;
done;
(!gtri, !tri, !ord)
let triangulate g =
let gtri, _, _ = md g in
gtri
end
module I(G : Sig.I) = struct
module CT = Cliquetree.CliqueTree(G)
type edgeset = (G.V.t * G.V.t) list
module Copy = Gmap.Vertex(G)(struct include G include Builder.I(G) end)
let md g =
let gtri = Copy.map (fun x -> x) g in
let gcur = Copy.map (fun x -> x) g in
let n = G.nb_vertex g in
let tri = ref [] in
let ord = ref [] in
let i = ref 0 in
while not (CT.is_chordal gtri) && !i < n do
let v =
let x =
G.fold_vertex
(fun v' x ->
let deg' = G.out_degree gcur v' in
match x with
Some (_,deg) when deg' > deg -> x
| _ -> Some (v', deg'))
gcur None
in match x with
Some (v,_) -> v
| None -> failwith "Expecting some vertex"
in
let ng = G.succ gcur v in
let tri' =
List.fold_left
(fun tri v ->
List.fold_left
(fun tri v' ->
let tri' =
if v <> v' && not (G.mem_edge g v v') then
(v, v') :: tri
else
tri
in
List.iter (fun v' -> if v <> v' then G.add_edge gcur v v') ng;
tri')
tri ng)
[] ng
in
ord := v :: !ord;
List.iter
(fun (x,y) -> G.add_edge gtri x y)
tri';
G.remove_vertex gcur v;
tri := tri' @ !tri;
incr i;
done;
(gtri, !tri, !ord)
let triangulate g =
let gtri, _, _ = md g in
gtri
end
ocamlgraph-2.0.0/src/gmap.ml 0000644 0001750 0000144 00000005773 13735627615 014272 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(** {2 Mapping of vertices} *)
module type V_SRC = sig
type t
module V : Sig.HASHABLE
val fold_vertex : (V.t -> 'a -> 'a) -> t -> 'a -> 'a
end
module type V_DST = sig
type t
type vertex
val empty : unit -> t
val add_vertex : t -> vertex -> t
end
module Vertex(G_Src : V_SRC)(G_Dst : V_DST ) = struct
module H = Hashtbl.Make(G_Src.V)
let vertices = H.create 97
let convert_vertex f x =
try
H.find vertices x
with Not_found ->
let x' = f x in
H.add vertices x x';
x'
let map f g =
H.clear vertices;
G_Src.fold_vertex
(fun x g -> G_Dst.add_vertex g (convert_vertex f x))
g (G_Dst.empty ())
let filter_map f g =
G_Src.fold_vertex
(fun x g -> match f x with
| Some e -> G_Dst.add_vertex g e
| None -> g
) g (G_Dst.empty ())
end
(** {2 Mapping of edges} *)
module type E_SRC = sig
type t
module E : Sig.ORDERED_TYPE
val fold_edges_e : (E.t -> 'a -> 'a) -> t -> 'a -> 'a
end
module type E_DST = sig
type t
type edge
val empty : unit -> t
val add_edge_e : t -> edge -> t
end
module Edge(G_Src: E_SRC)(G_Dst: E_DST) = struct
module M = Map.Make(G_Src.E)
let edges = ref M.empty
let convert_edge f x =
try
M.find x !edges
with Not_found ->
let x' = f x in
edges := M.add x x' !edges;
x'
let map f g =
edges := M.empty;
G_Src.fold_edges_e
(fun x g -> G_Dst.add_edge_e g (convert_edge f x))
g (G_Dst.empty ())
let filter_map f g =
G_Src.fold_edges_e
(fun x g -> match f x with
| Some e -> G_Dst.add_edge_e g e
| None -> g
) g (G_Dst.empty ())
end
(*
Vertex
(struct include G_Src module V = E let fold_vertex = fold_edges_e end)
(struct include G_Dst type vertex = edge let add_vertex = add_edge_e end)
*)
ocamlgraph-2.0.0/src/cliquetree.mli 0000644 0001750 0000144 00000006147 13735627615 015655 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(** Construction of the clique tree of a graph and recognition
of chordal graphs.
Based on the article:
Chordal graphs and their clique graph
by P. Galinier, M. Habib and C. Paul.
@author Matthieu Sozeau *)
module CliqueTree(G : Sig.G) : sig
(** Original graph vertex *)
module CliqueV :
sig
type t
val compare : t -> t -> int
val hash : t -> int
val equal : t -> t -> bool
val label : t -> t
val create : G.V.t -> t
val vertex : t -> G.V.t
end
(** Set of original vertices *)
module CVS : Set.S with type elt = CliqueV.t
(** Clique tree vertex type *)
module CliqueTreeV : sig
(** Trace of the algorithm as a list of markers Clique vertices *)
type data = CliqueV.t list * CVS.t
type label
type t
val compare : t -> t -> int
val hash : t -> int
val equal : t -> t -> bool
val create : data -> label -> t
val label : t -> label
val data : t -> data
end
module CliqueTreeE : sig
type t = int * CVS.t
val compare : t -> t -> int
val default : t
val create : int -> CVS.t -> t
(** Vertices in the clique tree edge
(intersection of the two clique extremities). *)
val vertices : t -> CVS.t
end
(** The clique tree graph type *)
module CliqueTree : Sig.G with type V.t = CliqueTreeV.t
and type E.label = CliqueTreeE.t
(** [mcs_clique g] return an perfect elimination order of [g]
(if it is chordal), the clique tree of [g] and its root. *)
val mcs_clique : G.t -> G.V.t list * CliqueTree.t * CliqueTree.V.t
(** [is_chordal g] uses the clique tree construction to test if a graph is
chordal or not. *)
val is_chordal : G.t -> bool
(** [maxwidth g tri tree] returns the maxwidth characteristic of the
triangulation [tri] of graph [g] given the clique tree [tree] of [tri]. *)
val maxwidth : G.t -> G.t -> CliqueTree.t -> int
end
ocamlgraph-2.0.0/src/prim.mli 0000644 0001750 0000144 00000003566 13735627615 014464 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
module type G = sig
type t
module V : Sig.COMPARABLE
module E : sig
type t
type label
val label : t -> label
val dst : t -> V.t
val src : t -> V.t
val compare : t -> t -> int
end
val iter_vertex : (V.t -> unit) -> t -> unit
val iter_edges_e : (E.t -> unit) -> t -> unit
val iter_succ_e : (E.t -> unit) -> t -> V.t -> unit
end
(** Functor providing an implementation of Prim's minimum-spanning-tree
algorithm.
Parameter [W] ensures that label on edges are comparable. *)
module Make(G: G)(W: Sig.WEIGHT with type edge = G.E.t) : sig
val spanningtree : G.t -> G.E.t list
val spanningtree_from : G.t -> G.V.t -> G.E.t list
end
ocamlgraph-2.0.0/src/mincut.mli 0000644 0001750 0000144 00000003523 13735627615 015005 0 ustar rt users (**************************************************************************)
(* *)
(* Ocamlgraph: a generic graph library for OCaml *)
(* Copyright (C) 2013-2014 *)
(* David Monniaux, Gabriel Radanne *)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(** Minimal cutset of a graph
Compute a minimal vertex cutset of a reducible oriented graph.
The set [S] of vertices is a cutset of [G] if [G \ S] doesn't
contain any cycle.
Based on the article: A linear time algorithm for finding minimum
cutsets in reducible graphs by A. Shamir (1979).
*)
(** Minimal signature for computing the minimal separators *)
module type G = sig
type t
module V : Sig.VERTEX
val succ : t -> V.t -> V.t list
end
module Make (G : G) : sig
(** Find a minimal cutset.
@raise Invalid_argument if the graph is not reducible.
*)
val min_cutset : G.t -> G.V.t -> G.V.t list
end
ocamlgraph-2.0.0/src/path.ml 0000644 0001750 0000144 00000024261 13735627615 014273 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(* $Id: path.ml,v 1.6 2005-07-18 07:10:35 filliatr Exp $ *)
module type G = sig
type t
module V : Sig.COMPARABLE
module E : sig
type t
type label
val label : t -> label
val src : t -> V.t
val dst : t -> V.t
val create : V.t -> label -> V.t -> t
end
val iter_vertex : (V.t -> unit) -> t -> unit
val fold_vertex : (V.t -> 'a -> 'a) -> t -> 'a -> 'a
val iter_succ : (V.t -> unit) -> t -> V.t -> unit
val iter_succ_e : (E.t -> unit) -> t -> V.t -> unit
val fold_edges_e : (E.t -> 'a -> 'a) -> t -> 'a -> 'a
val nb_vertex : t -> int
end
(** Weight signature for Johnson's algorithm. *)
module type WJ = sig
include Sig.WEIGHT
val sub : t -> t -> t
(** Subtraction of weights. *)
end
module Dijkstra
(G: G)
(W: Sig.WEIGHT with type edge = G.E.t) =
struct
open G.E
module H = Hashtbl.Make(G.V)
module Elt = struct
type t = W.t * G.V.t * G.E.t list
(* weights are compared first, and minimal weights come first in the
queue *)
let compare (w1,v1,_) (w2,v2,_) =
let cw = W.compare w2 w1 in
if cw != 0 then cw else G.V.compare v1 v2
end
module PQ = Heap.Imperative(Elt)
let shortest_path g v1 v2 =
let visited = H.create 97 in
let dist = H.create 97 in
let q = PQ.create 17 in
let rec loop () =
if PQ.is_empty q then raise Not_found;
let (w,v,p) = PQ.pop_maximum q in
if G.V.compare v v2 = 0 then
List.rev p, w
else begin
if not (H.mem visited v) then begin
H.add visited v ();
G.iter_succ_e
(fun e ->
let ev = dst e in
if not (H.mem visited ev) then begin
let dev = W.add w (W.weight e) in
let improvement =
try W.compare dev (H.find dist ev) < 0 with Not_found -> true
in
if improvement then begin
H.replace dist ev dev;
PQ.add q (dev, ev, e :: p)
end
end)
g v
end;
loop ()
end
in
PQ.add q (W.zero, v1, []);
H.add dist v1 W.zero;
loop ()
end
(* The following module is a contribution of Yuto Takei (University of Tokyo) *)
module BellmanFord
(G: G)
(W: Sig.WEIGHT with type edge = G.E.t) =
struct
open G.E
module H = Hashtbl.Make(G.V)
exception NegativeCycle of G.E.t list
let all_shortest_paths g vs =
let dist = H.create 97 in
H.add dist vs W.zero;
let admissible = H.create 97 in
let build_cycle_from x0 =
let rec traverse_parent x ret =
let e = H.find admissible x in
let s = src e in
if G.V.equal s x0 then e :: ret else traverse_parent s (e :: ret)
in
traverse_parent x0 []
in
let find_cycle x0 =
let visited = H.create 97 in
let rec visit x =
if H.mem visited x then
build_cycle_from x
else begin
H.add visited x ();
let e = H.find admissible x in
visit (src e)
end
in
visit x0
in
let rec relax i =
let update = G.fold_edges_e
(fun e x ->
let ev1 = src e in
let ev2 = dst e in
try begin
let dev1 = H.find dist ev1 in
let dev2 = W.add dev1 (W.weight e) in
let improvement =
try W.compare dev2 (H.find dist ev2) < 0
with Not_found -> true
in
if improvement then begin
H.replace dist ev2 dev2;
H.replace admissible ev2 e;
Some ev2
end else x
end with Not_found -> x) g None in
match update with
| Some x ->
if i == G.nb_vertex g then raise (NegativeCycle (find_cycle x))
else relax (i + 1)
| None -> dist
in
relax 0
let find_negative_cycle_from g vs =
try let _ = all_shortest_paths g vs in raise Not_found
with NegativeCycle l -> l
module Comp = Components.Make(G)
(* This is rather inefficient implementation. Indeed, for each
strongly connected component, we run a full Bellman-Ford
algorithm using one of its vertex as source, taking all edges
into consideration. Instead, we could limit ourselves to the
edges of the component. *)
let find_negative_cycle g =
let rec iter = function
| [] ->
raise Not_found
| (x :: _) :: cl ->
begin try find_negative_cycle_from g x with Not_found -> iter cl end
| [] :: _ ->
assert false (* a component is not empty *)
in
iter (Comp.scc_list g)
end
module Johnson
(G: G)
(W: WJ with type edge = G.E.t) =
struct
module HVV = Hashtbl.Make(Util.HTProduct(G.V)(G.V))
module G' = struct
type t = G.t
module V = struct
type t = New | Old of G.V.t
let compare v u = match v, u with
| New, New -> 0
| New, Old _ -> -1
| Old _, New -> 1
| Old v, Old u -> G.V.compare v u
let hash v = match v with
| Old v -> G.V.hash v
| New -> 42
let equal v u = match v, u with
| New, New -> true
| New, Old _ | Old _, New -> false
| Old v, Old u -> G.V.equal v u
end
module E = struct
type label = G.E.label
type t = NewE of V.t | OldE of G.E.t
let src e = match e with
| NewE _ -> V.New
| OldE e -> V.Old (G.E.src e)
let dst e = match e with
| NewE v -> v
| OldE e -> V.Old (G.E.dst e)
let label e = match e with
| NewE _ -> assert false
| OldE e -> G.E.label e
let create v l u = match v, u with
| V.New, V.Old u -> NewE (V.Old u)
| V.Old v, V.Old u -> OldE (G.E.create v l u)
| _, _ -> assert false
end
let iter_vertex f g = f V.New; G.iter_vertex (fun v -> f (V.Old v)) g
let fold_vertex f g acc =
let acc' = f V.New acc in
G.fold_vertex (fun v a -> f (V.Old v) a) g acc'
let iter_succ f g v = match v with
| V.New -> G.iter_vertex (fun u -> f (V.Old u)) g
| V.Old v -> G.iter_succ (fun u -> f (V.Old u)) g v
let iter_succ_e f g v = match v with
| V.New ->
G.iter_vertex (fun u -> f (E.NewE (V.Old u))) g
| V.Old v -> G.iter_succ_e (fun e -> f (E.OldE e)) g v
let fold_edges_e f g acc =
let acc' =
G.fold_vertex (fun x _ -> f (E.NewE (V.Old x)) acc) g acc
in
G.fold_edges_e (fun edg ->
let v1 = G.E.src edg in
let v2 = G.E.dst edg in
let l = G.E.label edg in
f (E.create (V.Old v1) l (V.Old v2))) g acc'
let nb_vertex g = G.nb_vertex g + 1
end
module W' = struct
open G'.E
type edge = G'.E.t
type t = W.t
let zero = W.zero
let weight e = match e with
| NewE _ -> zero
| OldE e -> W.weight e
let compare = W.compare
let add = W.add
end
module BF = BellmanFord(G')(W')
let all_pairs_shortest_paths g =
let pairs_dist = HVV.create 97 in
let bf_res = BF.all_shortest_paths g G'.V.New in
let module W'' = struct
type edge = W.edge
type t = W.t
let add = W.add
let sub = W.sub
let weight e =
let v1 = G.E.src e in
let v2 = G.E.dst e in
add (W.weight e)
(W.sub (BF.H.find bf_res (G'.V.Old v1))
(BF.H.find bf_res (G'.V.Old v2)))
let compare = W.compare
let zero = W.zero
end
in
let module D = Dijkstra(G)(W'') in
G.iter_vertex
(fun v ->
G.iter_vertex
(fun u ->
try
let (_, d) = D.shortest_path g v u in
HVV.add pairs_dist (v, u)
(W''.add d
(W''.sub (BF.H.find bf_res (G'.V.Old u))
(BF.H.find bf_res (G'.V.Old v))
))
with Not_found -> () ) g) g;
pairs_dist
end
module Check
(G :
sig
type t
module V : Sig.COMPARABLE
val iter_succ : (V.t -> unit) -> t -> V.t -> unit
end) =
struct
module HV = Hashtbl.Make(G.V)
module HVV = Hashtbl.Make(Util.HTProduct(G.V)(G.V))
(* the cache contains the path tests already computed *)
type path_checker = { cache : bool HVV.t; graph : G.t }
let create g = { cache = HVV.create 97; graph = g }
let check_path pc v1 v2 =
try
HVV.find pc.cache (v1, v2)
with Not_found ->
(* the path is not in cache; we check it with a BFS *)
let visited = HV.create 97 in
let q = Queue.create () in
let rec loop () =
if Queue.is_empty q then begin
HVV.add pc.cache (v1, v2) false;
false
end else begin
let v = Queue.pop q in
HVV.add pc.cache (v1, v) true;
if G.V.compare v v2 = 0 then
true
else begin
if not (HV.mem visited v) then begin
HV.add visited v ();
G.iter_succ (fun v' -> Queue.add v' q) pc.graph v
end;
loop ()
end
end
in
Queue.add v1 q;
loop ()
end
ocamlgraph-2.0.0/src/dominator.ml 0000644 0001750 0000144 00000033041 13735627615 015327 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(*
Copyright © 2009 Carnegie-Mellon University, David Brumley, and Ivan Jager.
From the BAP library; see http://bap.ece.cmu.edu
Modified by OCamlGraph's authors.
*)
(* stuff to read:
http://www.hipersoft.rice.edu/grads/publications/dom14.pdf
Modern Compiler Implementation in ML, by Appel
Introduction to Algorithms, Cormen et al
*)
exception Unreachable
module type G = sig
type t
module V : Sig.COMPARABLE
val pred : t -> V.t -> V.t list
val succ : t -> V.t -> V.t list
val fold_vertex : (V.t -> 'a -> 'a) -> t -> 'a -> 'a
val iter_vertex : (V.t -> unit) -> t -> unit
val iter_succ : (V.t -> unit) -> t -> V.t -> unit
val nb_vertex : t -> int
end
module type I = sig
include G
val empty: unit -> t
val add_edge: t -> V.t -> V.t -> t
end
module type S = sig
type t
type vertex
module S : Set.S with type elt = vertex
type idom = vertex -> vertex
type idoms = vertex -> vertex -> bool
type dom_tree = vertex -> vertex list
type dominators = vertex -> vertex list
type dom = vertex -> vertex -> bool
type sdom = vertex -> vertex -> bool
type dom_frontier = vertex -> vertex list
val compute_idom: t -> vertex -> vertex -> vertex
val dominators_to_dom: ('a -> S.t) -> vertex -> 'a -> bool
val dominators_to_sdom: (vertex -> S.t) -> vertex -> vertex -> bool
val dom_to_sdom: (vertex -> vertex -> bool) -> vertex -> vertex -> bool
val dominators_to_sdominators: (vertex -> S.t) -> vertex -> S.t
val dominators_to_idoms: (vertex -> S.t) -> vertex -> vertex -> bool
val dominators_to_dom_tree:
t ->
?pred:(t -> vertex -> vertex list) -> (vertex -> S.t) -> vertex -> S.t
val idom_to_dom_tree: t -> (vertex -> vertex) -> vertex -> vertex list
val idom_to_idoms: idom -> vertex -> vertex -> bool
val compute_dom_frontier: t -> dom_tree -> idom -> vertex -> vertex list
val idom_to_dominators: ('a -> 'a) -> 'a -> 'a list
val idom_to_dom: (vertex -> vertex) -> vertex -> vertex -> bool
end
module Make(G : G) = struct
type t = G.t
type vertex = G.V.t
module H = Hashtbl.Make(G.V)
module S = Set.Make(G.V)
(** function from [n] to [n]'s immediate dominator *)
type idom = vertex -> vertex
(** [idoms x y] is true when [x] is [y]'s immediate dominator *)
type idoms = vertex -> vertex -> bool
(** function from [x] to a list of nodes immediately dominated by [x] *)
type dom_tree = vertex -> vertex list
(** function from node to a list of nodes that dominate it. *)
type dominators = vertex -> vertex list
(** [dom x y] returns true iff [x] dominates [y] *)
type dom = vertex -> vertex -> bool
(** [sdom x y] returns true iff [x] strictly dominates [y]. *)
type sdom = vertex -> vertex -> bool
(** function from [x] to a list of nodes not dominated by [x], but with
predecessors which are dominated by [x] *)
type dom_frontier = vertex -> vertex list
let set_of_list x = List.fold_left (fun set v -> S.add v set) S.empty x
(** Computes the dominator tree, using the Lengauer-Tarjan algorithm.
[compute_idom cfg s0] returns a function [idom : V.t -> V.t] s.t.
[idom x] returns the immediate dominator of [x]
*)
let compute_idom cfg s0 =
(* based on the Tiger book, section 19.2.
This uses path compression, but doesn't yet do balanced path
compression, so the runtime is O(N log(N)) rather than
O(N inverseackerman(N))
*)
let size = G.nb_vertex cfg in
let bucket = H.create size (* node n -> *)
and dfnum_h = H.create size (* node -> DFS number *)
and parent = H.create size (* node -> parent in DFS tree*)
and semi_h = H.create size (* node -> semidominator *)
and ancestor = H.create size (* node -> *)
and best = H.create size (* node -> *)
and samedom = H.create size (* node -> node with same idom *)
and idom = H.create size (* node n -> idom n *)
and vertex = Array.make size s0 (* DFS number -> node *)
and nn = ref 0 in
let dfnum x = try H.find dfnum_h x with Not_found -> raise Unreachable
and semi = H.find semi_h in
let dfs n0 =
let stack = Stack.create () in
let loop () =
while not (Stack.is_empty stack) do
let n,p = Stack.pop stack in
if not (H.mem dfnum_h n) then begin
let enn = !nn in
H.add dfnum_h n enn;
vertex.(enn) <- n;
begin match p with
| Some p -> H.add parent n p
| None -> () end;
nn := enn + 1;
G.iter_succ
(fun m ->
if not (H.mem dfnum_h m) then Stack.push (m, Some n) stack)
cfg n
end
done
in
Stack.push (n0,None) stack;
loop ()
in
let rec ancestor_with_lowest_semi v =
try
let a = H.find ancestor v in
let b = ancestor_with_lowest_semi a in
let () = H.replace ancestor v (H.find ancestor a) in
let best_v = H.find best v in
if dfnum(semi b) < dfnum(semi best_v)
then (H.replace best v b; b)
else best_v
with Not_found -> H.find best v
in
let link p n =
H.replace ancestor n p;
H.replace best n n;
in
let semidominator n =
let s = H.find parent n in
List.fold_left
(fun s v ->
try (* FIXME: do we want to allow unreachable nodes? *)
let s' =
if dfnum v <= dfnum n
then v
else semi(ancestor_with_lowest_semi v)
in
if dfnum s' < dfnum s then s' else s
with Unreachable -> (* maybe switch to Not_found later *)
s (* v is unreachable from s0 *)
)
s
(G.pred cfg n)
in
let () = dfs s0 in
let lastn = !nn - 1 in
while decr nn; !nn > 0 do (* skip over the root node *)
let i = !nn in
let n = vertex.(i) in
let p = H.find parent n in
let s = semidominator n in
H.add semi_h n s;
H.add bucket s n;
link p n;
(* now that the path from p to v is in the forest,
calculate the dominator of v based on the first clause of the
Dominator Theorem, otherwise defer until y's dominator is known *)
List.iter
(fun v ->
let y = ancestor_with_lowest_semi v in
if G.V.equal (semi y) (semi v)
then H.add idom v p
else H.add samedom v y;
H.remove bucket p (*could use H.remove_all if we used extlib*)
)
(H.find_all bucket p)
done;
(* now all the defered calculations can be done *)
for i = 1 to lastn do
let n = vertex.(i) in
try
H.add idom n (H.find idom (H.find samedom n))
with Not_found -> ()
done;
H.find idom
(** Given a function from a node to it's dominators, returns a function
[dom : V.t -> V.t -> bool] s.t. [dom x y] returns true when
[x] dominates [y]
*)
let dominators_to_dom dominators x y =
S.mem x (dominators y)
(** Given a function from a node to it's dominators, returns a function
[sdom : V.t -> V.t -> bool] s.t. [sdom x y] returns true when
[x] strictly dominates [y] *)
let dominators_to_sdom dominators x y =
not(G.V.equal x y) && dominators_to_dom dominators x y
let dom_to_sdom dom x y =
not(G.V.equal x y) && dom x y
(** Given a a function from a node to it's dominators, returns a function
from a node to it's strict dominators. *)
let dominators_to_sdominators dominators x =
S.remove x (dominators x)
(** Given a function from a node to it's dominators, returns a function
[idoms : G.V.t -> G.V.t -> bool] s.t. [idoms x y] returns true when
[x] is the immediate dominator of [y].
*)
let dominators_to_idoms dominators =
let sdom = dominators_to_sdom dominators in
(fun x y ->
sdom x y
&& let sdoms = dominators_to_sdominators dominators y in
S.for_all (fun w -> G.V.equal x w || not(sdom x w)) sdoms
)
(** Computes a dominator tree (function from x to a list of nodes immediately
dominated by x) for the given CFG and dominator function.
Note: The dominator tree is also called [IDom] by Muchnick.
Note: If you are computing a post-dominator tree, then the
optional argument pred should be G.succ.
*)
let dominators_to_dom_tree cfg ?(pred=G.pred) dominators =
let idoms = dominators_to_idoms dominators in
let tree = H.create 97 in
let () =
G.iter_vertex
(fun y ->
match pred cfg y with
[x] -> (
(* a node that is not reachable from start has no
idom *)
if S.is_empty (dominators x) then () else
H.add tree x y
)
| _ -> (
S.iter
(fun x -> if idoms x y then H.add tree x y)
(dominators y)
)
)
cfg
in
(* FIXME: maybe faster to convert eagerly *)
fun x -> set_of_list(H.find_all tree x)
(** Computes a dominator tree (function from x to a list of nodes immediately
dominated by x) for the given CFG and idom function. *)
let idom_to_dom_tree cfg idom =
let tree = H.create (G.nb_vertex cfg) in
let () =
G.iter_vertex
(fun v ->
try H.add tree (idom v) v
with Not_found -> () (* s0 doesn't have an idom *)
)
cfg
in
H.find_all tree
let idom_to_idoms (idom:idom) x y =
try G.V.equal x (idom y)
with Not_found -> false (* s0 doesn't have an idom *)
(** Computes the dominance frontier.
As specified in section 19.1 of Modern Compiler Implementation in ML
by Andrew Appel.
*)
let compute_dom_frontier cfg (dom_tree: dom_tree) (idom: idom) =
let children = dom_tree in
let idoms = idom_to_idoms idom in
let df_cache = H.create 57 in
let df_local n =
(* the successors of n that are not strictly dominated by n *)
List.filter (fun y -> not (idoms n y)) (G.succ cfg n)
in
(* written in CPS to prevent stack overflow *)
let rec df n k =
match try Some (H.find df_cache n) with Not_found -> None with
| Some r -> k r
| None ->
let s = df_local n in
add_df_ups s n (fun res -> H.add df_cache n res; k res) (children n)
and add_df_ups s n k = function
| [] -> k s
| c :: chl ->
df c (fun dfc ->
add_df_ups
(List.fold_left
(* the appel errata uses sdom, but Muchnick uses idoms, which
should be a bit faster and is the same *)
(fun s w -> if idoms n w then s else w :: s) s dfc)
n k chl)
in
fun n -> df n (fun x -> x)
let idom_to_dominators idom x =
let rec d y list =
try
let i = idom y in
d i (i::list)
with Not_found ->
list
in
d x []
let rec idom_to_dom idom x y =
try
let d = idom y in
G.V.equal x d || idom_to_dom idom x d
with Not_found ->
false
end
module Make_graph(G: I) = struct
include Make(G)
type dom_graph = unit -> t
type dom_functions = {
idom : idom;
idoms: idoms;
dom_tree: dom_tree;
dominators: dominators;
dom: dom;
sdom: sdom;
dom_frontier: dom_frontier;
dom_graph : dom_graph;
}
let compute_dom_graph cfg dom_tree =
G.fold_vertex (fun p g ->
try
List.fold_left (fun g u -> (G.add_edge g p u)) g (dom_tree p)
with Not_found -> g
) cfg (G.empty ())
(** Computes all dominance functions.
This function computes some things eagerly and some lazily, so don't
worry about it doing extra work to compute functions you don't need,
but also don't call it if you aren't going to use anything it returns.
@return a record containing all dominance functions for the given graph
and entry node.
*)
let compute_all cfg s0 =
let idom = compute_idom cfg s0 in
let idoms = idom_to_idoms idom in
let dom_tree = lazy(idom_to_dom_tree cfg idom) in
let dominators = idom_to_dominators idom in
let dom = idom_to_dom idom in
let sdom = dom_to_sdom dom in
let dom_frontier =
lazy(compute_dom_frontier cfg (Lazy.force dom_tree) idom)
in
{
idom=idom;
idoms=idoms;
dom_tree=(fun x -> Lazy.force dom_tree x);
dominators=dominators;
dom=dom;
sdom=sdom;
dom_frontier=(fun x -> Lazy.force dom_frontier x);
dom_graph=(fun () -> compute_dom_graph cfg (Lazy.force dom_tree));
}
end
ocamlgraph-2.0.0/src/kruskal.mli 0000644 0001750 0000144 00000005043 13735627615 015161 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(* $Id: kruskal.mli,v 1.5 2005-06-30 10:48:55 filliatr Exp $ *)
(** Kruskal's minimum-spanning-tree algorithm. *)
(** Minimal graph signature for Kruskal.
Sub-signature of {!Sig.G}. *)
module type G = sig
type t
module V : Sig.COMPARABLE
module E : sig
type t
type label
val label : t -> label
val dst : t -> V.t
val src : t -> V.t
end
val fold_vertex : (V.t -> 'a -> 'a) -> t -> 'a -> 'a
val iter_edges_e : (E.t -> unit) -> t -> unit
end
(** Functor providing an implementation of Kruskal's minimum-spanning-tree
algorithm.
Parameter [W] ensures that label on edges are comparable. *)
module Make(G: G)(W: Sig.ORDERED_TYPE with type t = G.E.label) : sig
val spanningtree : G.t -> G.E.t list
end
(** {2 Generic version where union-find implementation is provided} *)
(** Signature of union-find. *)
module type UNIONFIND = sig
type elt
type t
val init : elt list -> t
val find : elt -> t -> elt
val union : elt -> elt -> t -> unit
end
(** Functor providing an implementation of Kruskal's minimum-spanning-tree
algorithm using a user-defined union-find algorithm.
Parameter [W] ensures that label on edges are comparable. *)
module Generic
(G: G)
(W: Sig.ORDERED_TYPE with type t = G.E.label)
(UF: UNIONFIND with type elt = G.V.t) :
sig
val spanningtree : G.t -> G.E.t list
end
ocamlgraph-2.0.0/src/dot_parser.mly 0000644 0001750 0000144 00000007326 13735627615 015675 0 ustar rt users /**************************************************************************/
/* */
/* 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. */
/* */
/**************************************************************************/
/* $Id:$ */
/* DOT parser, following http://www.graphviz.org/doc/info/lang.html */
%{
open Dot_ast
let compass_pt = function
| Ident "n" -> N
| Ident "ne" -> Ne
| Ident "e" -> E
| Ident "se" -> Se
| Ident "s" -> S
| Ident "sw" -> Sw
| Ident "w" -> W
| Ident "nw" -> Nw
| _ -> invalid_arg "compass_pt"
%}
%token ID
%token COLON COMMA EQUAL SEMICOLON EDGEOP
%token STRICT GRAPH DIGRAPH LBRA RBRA LSQ RSQ NODE EDGE SUBGRAPH EOF
%nonassoc ID
%nonassoc LBRA
%type file
%start file
%%
file:
| strict_opt graph_or_digraph id_opt LBRA stmt_list RBRA EOF
{ { strict = $1; digraph = $2; id = $3; stmts = $5 } }
;
strict_opt:
| /* epsilon */ { false }
| STRICT { true }
;
graph_or_digraph:
| GRAPH { false }
| DIGRAPH { true }
;
stmt_list:
| /* epsilon */ { [] }
| list1_stmt { $1 }
;
list1_stmt:
| stmt semicolon_opt { [$1] }
| stmt semicolon_opt list1_stmt { $1 :: $3 }
;
semicolon_opt:
| /* epsilon */ { () }
| SEMICOLON { () }
;
stmt:
| node_stmt { $1 }
| edge_stmt { $1 }
| attr_stmt { $1 }
| ID EQUAL ID { Equal ($1, $3) }
| subgraph { Subgraph $1 }
;
node_stmt:
| node_id attr_list_opt { Node_stmt ($1, $2) }
;
edge_stmt:
| node edge_rhs attr_list_opt { Edge_stmt ($1, $2, $3) }
;
attr_stmt:
| GRAPH attr_list { Attr_graph $2 }
| NODE attr_list { Attr_node $2 }
| EDGE attr_list { Attr_edge $2 }
;
edge_rhs:
| EDGEOP node edge_rhs_opt { $2 :: $3 }
;
edge_rhs_opt:
| /* epsilon */ { [] }
| EDGEOP node edge_rhs_opt { $2 :: $3 }
;
node:
| node_id { NodeId $1 }
| subgraph { NodeSub $1 }
;
node_id:
| ID port_opt { $1, $2 }
;
port_opt:
| /* epsilon */ { None }
| port { Some $1 }
;
port:
| COLON ID { try PortC (compass_pt $2)
with Invalid_argument _ -> PortId ($2, None) }
| COLON ID COLON ID
{ let cp =
try compass_pt $4 with Invalid_argument _ -> raise Parse_error
in
PortId ($2, Some cp) }
;
attr_list_opt:
| /* epsilon */ { [] }
| attr_list { $1 }
;
attr_list:
| LSQ a_list RSQ { [$2] }
| LSQ a_list RSQ attr_list { $2 :: $4 }
;
id_opt:
| /* epsilon */ { None }
| ID { Some $1 }
;
a_list:
| equality comma_opt { [$1] }
| equality comma_opt a_list { $1 :: $3 }
;
equality:
| ID { $1, None }
| ID EQUAL ID { $1, Some $3 }
;
comma_opt:
| /* epsilon */ { () }
| COMMA { () }
;
subgraph:
| SUBGRAPH ID { SubgraphId $2 }
| SUBGRAPH ID LBRA stmt_list RBRA { SubgraphDef (Some $2, $4) }
| SUBGRAPH LBRA stmt_list RBRA { SubgraphDef (None, $3) }
| LBRA stmt_list RBRA { SubgraphDef (None, $2) }
;
ocamlgraph-2.0.0/src/rand.mli 0000644 0001750 0000144 00000011260 13735627615 014427 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(* $Id: rand.mli,v 1.12 2005-03-31 13:32:51 filliatr Exp $ *)
(** Random graph generation. *)
(** {2 Random graphs} *)
module type S = sig
type graph
type vertex
type edge_label
val graph : ?loops:bool -> v:int -> e:int -> unit -> graph
(** [graph v e] generates a random graph with exactly [v] vertices
and [e] edges. Vertices are labeled with [0] ... [v-1].
The boolean [loops] indicates whether loops are allowed;
default value is no loop ([false]).
@raise Invalid_argument if [e] exceeds the maximal number of edges. *)
val labeled :
(vertex -> vertex -> edge_label) ->
?loops:bool -> v:int -> e:int -> unit -> graph
(** [labeled f] is similar to [graph] except that edges are labeled
using function [f].
@raise Invalid_argument if there are too many edges. *)
(** The two functions above actually make a choice between two
different implementations according to the ratio e/(v*v).
When this ratio is small, [random_few_edges] is selected;
otherwise [random_many_edges] is selected. *)
val random_few_edges : loops:bool -> v:int -> e:int -> graph
val random_many_edges : loops:bool -> v:int -> e:int -> graph
val gnp : ?loops:bool -> v:int -> prob:float -> unit -> graph
(** random graph using the G(n,p) model.
[gnp v prob] generates a random graph with exactly [v] vertices
and where each edge is selected with probability [prob] *)
val gnp_labeled :
(vertex -> vertex -> edge_label) ->
?loops:bool -> v:int -> prob:float -> unit -> graph
(** [gnp_labeled add_edge v e] is similar to [gnp] except that edges
are labeled using function [f]. *)
end
module Make(B: Builder.INT) :
S with type graph = B.G.t
and type vertex = B.G.V.t
and type edge_label = B.G.E.label
(** Random graphs *)
module P (G : Sig.P with type V.label = int) :
S with type graph = G.t
and type vertex = G.V.t
and type edge_label = G.E.label
(** Random persistent graphs *)
module I (G : Sig.I with type V.label = int) :
S with type graph = G.t
and type vertex = G.V.t
and type edge_label = G.E.label
(** Random imperative graphs *)
(** {2 Random planar graphs} *)
module Planar : sig
module type S = sig
type graph
val graph :
?loops:bool -> xrange:int*int -> yrange:int*int ->
prob:float -> int -> graph
(** [graph xrange yrange prob v]
generates a random planar graph with exactly [v] vertices.
Vertices are labeled with integer coordinates, randomly distributed
according to [xrange] and [yrange].
Edges are built as follows: the full Delaunay triangulation is
constructed and then each edge is discarded with probabiblity [prob]
(which should lie in [0..1]). In particular [prob = 0.0] gives the
full triangulation.
Edges are labeled with the (rounded) Euclidean distance between
the two vertices.
The boolean [loops] indicates whether loops are allowed;
default value is no loop ([false]). *)
end
module Make
(B : Builder.S with type G.V.label = int * int and type G.E.label = int) :
S with type graph = B.G.t
(** Random planar graphs *)
module P (G : Sig.P with type V.label = int * int and type E.label = int) :
S with type graph = G.t
(** Random persistent planar graphs *)
module I (G : Sig.I with type V.label = int * int and type E.label = int) :
S with type graph = G.t
(** Random imperative planar graphs *)
end
ocamlgraph-2.0.0/TODO.md 0000644 0001750 0000144 00000001224 13735627615 013277 0 ustar rt users
- has_cycle: return the cycle as a list of vertices
- Better graph viewer and editor
- Improve the website
- It should be possible to specify the first vertex to visit in traversal
algorithm (suggestion of Fabrice Derepas)
- Implementations for graph with unlabeled vertices
(exactly like graph with unlabeled edges)
- Provide more bidirectional graph implementation:
only Imperative.Digraph.ConcreteBidirectional exists at this day.
- Provide generic marks (instead of only integer marks)
## DGraph
### mode Tree
- texte trop bas
- texte multi-ligne
- gros zoom déviant
- mauvaise borne polygone & rectangle
Un bon exemple est 'examples/fancy.dot'
ocamlgraph-2.0.0/CHANGES.md 0000644 0001750 0000144 00000041203 13735627615 013603 0 ustar rt users
# 2.0.0 (October 2, 2020)
- port to dune and opam 2.0
- :exclamation: opam package now split into two packages: ocamlgraph and ocamlgraph_gtk
- [WeakTopological] fixed incorrect use of generic hash tables
(#99, Tomáš DacÃk)
- [Oper] fixed transitive_reduction (#91)
- fix incorrect uses of polymorphic equality (Steffen Smolka, Boris Yakobowski)
- [Coloring] fixed generation of OCamlDoc documentation
(contributed by Earnestly)
- :exclamation: [Coloring] functions now fail if the graph is directed
- :exclamation: [Coloring] now uses a single, global exception [NoColoring]
- [Coloring] new function two_color to 2-color a graph (or fail)
- :exclamation: [Fixpoint] Take initial labeling of nodes into account (Johannes Kloos)
# 1.8.8, October 17, 2017
- fixed installation (Virgile Prevosto, Jacques-Pascal Deplaix)
- safe-string compatible (Jacques-Pascal Deplaix)
- :exclamation: fixed method get_edge_layout of class abstract_model of DGraphModel.Make. The
bug could have occured when there are several edges between two vertices.
- [Traverse/Pack] added Dfs.fold and Dfs.fold_component (tail-recursive)
(contributed by Guillaume Chelfi)
- :exclamation: fixed implementation of Golberg-Tarjan maximal flow algorithm
(contributed by Guyslain Naves) No more function min_capacity in
the input interface. Renaming as follows: Flow.Goldberg ->
Flow.Goldberg_Tarjan and Pack.goldberg -> Pack.goldberg_tarjan
- new functors [WeakTopological] and [ChaoticIteration] to compute
fixpoints with widening, following Bourdoncle's algorithms (contributed
by Thibault Suzanne)
# 1.8.7, April 12, 2016
- fixed examples/demo.ml so that it also compiles with an installed OCamlGraph
- [Components] fixed stack overflow with [scc] (patch by Albin Coquereau)
- [Dominator] fixed stack overflow (patch by Albin Coquereau)
- new functor [Path.Johnson] to compute all pairs of shortest paths
using Johnson's algorithm (contributed by Mário Pereira)
- fixed configuration on Windows (patch by Martin R. Neuhäußer)
- new functor [Components.Undirected] to compute connected components
- Graphviz: fixed printing of attribute BgcolorWithTransparency
- :exclamation: Prim, Nonnegative: function weight now has the more general type "edge -> t"
(to be consistent with Path)
- new module type Sig.WEIGHT (used in Path, Prim, and Nonnegative)
- Fixpoint: do not catch Not_found raised by a user-provided function.
- Adding folds to BFS.
# 1.8.6, January 23, 2015
- :exclamation: Dominator: new functor [Make_graph] with may use graph building operations,
while the old functor [Make] now only requires a read-only graph.
Function [compute_all] and [compute_dom_graph] are now only defined in the
new [Make_graph] functor.
- Graphviz: support for additional polygonal-shapes
- New module Clique (contributed by Giselle Reis)
- Avoid ocamldoc error with OCaml 4.02
- :exclamation: Path: function weight now has the more general type "edge -> t"
(contributed by Steffen Smolka)
update your code by turning "weight l" into "weight (G.E.label e)"
- installation: "make install-findlib" now uses DESTDIR when defined
- Traverse: documentation is clarified: providing iterators over the roots of
the graph is enough.
- Imperative concreate (di)graph: fix bug of functions add_edge* of
imperative concrete (di)graphs which appears when the added edge
[e] was already in the graph [g] and one of the vertices of [e] is
equal to another vertex of [g] (when using the user-defined
equality [G.V.equal]), but not physically equal to it. This bug
only occurs with OCaml version >= 4.0.
- functions in modules Components, Dominator, Flow, Topological and
Traverse now create smaller auxiliary hash tables
- Graphviz: add the attribute `HtmlLabel to specify html strings.
# 1.8.5, March 4, 2014
- Graphviz: reverted to the old API where edges and vertices are
given a single style attribute; but such attributes are collected
and output in the DOT file into a list (thus allowing multiple
style attributes)
- fixed issue in ./configure with ocamlfind on Win32.
- fixed compilation when laglgnomecanvas is missing (bug introduced in 1.8.4).
- fixed more issues with 'make -j'.
# version 1.8.4, February 4, 2014
- fixed [Graphml] printer (contributed by Johannes Schauer)
- Components: the components of [scc_list] are provided in the same order than
the ones of [scc_array].
- fix compilation with 'make -j'
- Graphviz: handle attribute penwidth on edges and vertices
- also install graph.o and graph.cmxs
- fixed installation with ocamlfind (thanks to Virgile Prevosto)
- new functions [gnp] and [gnp_labeled] in module [Rand] to generate random
graphs using the G(n,p) model (contributed by Thomas Aubry)
- Prim's algorithm (in module [Prim]; not exported in [Pack])
(contributed by Thomas Aubry)
- Graphviz: support for nested subgraphs. (Backward-incompatible change:
add 'sg_parent = None' to obtain subgraphs whose parents are the main graph)
- Graphviz: edges and vertices can now receive multiple styles.
(Backward-incompatible change: constructors `Style now require a
list as argument)
- Graphviz: new vertex style 'rounded'
- Merge: fixed bug with vertices with no incoming nor outcoming edge.
- fixed compilation issue with OCaml 3.12.1
# 1.8.3, April 17, 2013
- new module Merge implementing several different merges of vertices and
edges into a graph (contributed by Emmanuel Haucourt)
- fixed DOT parser (contributed by Alex Reece)
- Topological: fixed bug in presence of disjoint cycles; new implementation
- new module [Graphml] to export graphs into the graphml format
(contributed by Pietro Abate)
- Builder.S now contains functions remove_*.
- modified Fixpoint module so that it also works with unlabeled
graphs, break backward compatibility yet (contributed by Markus W. Weissmann)
- support of lablgtk2 installed with findlib (contributed by B. Monate)
- new module [Dominator] to compute dominators
(contributed by David Brumley and Ivan Jager)
# 1.8.2, May 12, 2012
- new module [Path.BellmanFord] implementing Bellman-Ford algorithm
(contributed by Yuto Takei)
- new module Contraction implementing edge contraction
(contributed by Markus W. Weissmann)
- Gmap: new function [filter_map] (contributed by Markus W. Weissmann)
- Topological: fix bug when a cycle depends on another cycle. That breaks
compatibility: the input graph must implement Sig.COMPARABLE instead of
Sig.HASHABLE
- new module Topological.Make_stable to iterate over a graph in a **stable**
topological order. Stable means that the provided ordering only depends on
the graph topology and on the user's vertices ordering.
- new module Leaderlist to compute the leader list algorithm (see the Dragon)
(contributed by Markus W. Weissmann )
# 1.8.1, October 17, 2011
- module Gmap now has a signature for edges (E_SRC) compatible with
Sig, so that it is easier to apply functor Gmap.Edge
(contributed by Markus W. Weissmann )
- new module Fixpoint to compute fixpoints using the work-list
algorithm, e.g. for data flow analysis
(contributed by Markus W. Weissmann )
# 1.8, October 4, 2011
- removed ocamlyacc shift/reduce conflict in dot_parser.mly
(patch contributed by Till Varoquaux)
- Dgraph: Correct height and width-related problems with text
- DGraph: many bug fixes. Patch by Benjamin Monate
- Sig.G: new function [find_all_edges] for each graph implementation
- Oper: fixed bug with function [intersect]: now use G.E.compare instead of (=)
- fixed "make install-findlib"
# 1.7, February 23, 2011
- Makefile: fixed bug when installing ocamlgraph with ocamlfind
- DGraph: fixed bug with colors on some windows manager
- Configure: fixed issue with automatic detection of extension under
Windows/Mingw
# 1.6, December 13, 2010
- DGraph: new viewer mode (called `tree') which focus on a subset part of the
graph centered on a given node
- Graphviz: fixed bug with attribute `Constraint (was `Constraints) (patch by
Boris Yakobowski)
- DGraph: fixed font size issue when zooming
- DGraph: now interpret text anchors and espaced sequences correctly
- DGraph: offer possibility to disable the default callbacks on nodes
- 'make -j' works again
- new implementation Persistent.Digraph.ConcreteBidirectionalLabeled
- new implementation Persistent.Digraph.ConcreteBidirectional
- Makefile: bug fixed when ocamlc (resp. ocamlopt) and ocamlc.opt
(resp. ocamlopt.opt) are unconsistent
# 1.5, April 29, 2010
- Makefile: bug fixed when installing ocamlgraph with ocamlfind
(patch by Virgile Prevosto)
- DGraph: new method set_zoom_padding in DgraphView.view
- Traverse.Dfs.has_cycle: can now be used on undirected graphs as well,
and is now tail recursive
- DGraph: handle dotted ellipse
# 1.4, March 24, 2010
- new function [clear] for imperative graphs
- new implementation Imperative.Digraph.ConcreteBidirectionalLabeled
(contribution of Jaap Boender)
- Dgraph displays graphs faster
- DGraph: several bugs fixed
- DGraph: several API changes
(may break compatibility with existing development)
# 1.3, October 2, 2009
- Oper.mirror: undirected graphs are not copied anymore
- Oper.mirror: fixed bug (isolated vertices were lost)
- Graphviz: new signature GraphWithDotAttrs
- Improvements of Dgraph
- Configure: better test for detecting lablgtk
- OcamlGraph is now installed by default in `ocamlc -where`/ocamlgraph
- Viewgraph is now packed in a single module Viewgraph (break compatibility
with previous version)
- Dgraph is now packed in a single module Dgraph (break compatibility with
previous version)
- Makefile: fixed bug when the installation directory of binaries does not
exist
- Makefile: fixed bug of ocamldep under Windows
# 1.2, August 31, 2009
- experimental: new GTK-based graph viewer called Dgraph
(viewGraph is now deprecated)
- added Delaunay.iter_triangles (not of use in Ocamlgraph, actually)
# 1.1, June 23, 2009
- added constraint "type E.label = unit" to unlabeled graph data structure
- viewGraph: new module viewGraph_utils; fixed compilation (gtkInit
was missing; patch by Mehdi Dogguy)
- configure: fixed bug under Cygwin (patch by Julien Bernet)
- configure: look for lablgnomecanvas.cmxa when compiling in native code
- Makefile: fixed make install-findlib when lablgtk and/or
lablgnomecanvas not installed (patch by Peter Hawkins)
# 1.0, October 14, 2008
- license: LGPL updated to version 2.1
- ocamlgraph now requires ocaml 3.10 or higher
- experimental: GTK-based graph viewer based on dot
(contribution of Anne Pacalet)
- Makefile:
- fixed bug when lablgnomecanvas is not installed
- fixed bug when ocamlfind is installed
- patch to the build system for a DESTDIR (patch by Igor Galic)
- "make -j" compliant
- new function Blocks.after_unserialization in order to be able to safely
serialize abstract vertices (see the FAQ)
- Dot:
- fixed bug in the parsing of attributes
- fixed bug in the parsing of subgraphs (patch by Anne Pacalet)
- Oper: fixed bug in intersect
- Path: improved efficiency of Dijkstra
- Topological:
- fixed bug in Make.{iter,fold}
- folding is now tail-recursive (patch by Michael Furr)
# 0.99c, April 3rd, 2008
- replicated a bug fix of Bitv (could not affect Matrix, though)
- fixed DFS traversal in Traverse.Dfs.{prefix,prefix_component,iterator}
# 0.99b, December 18th, 2007
- fixed link bug with ocaml 3.09
(see http://caml.inria.fr/mantis/view.php?id=4124)
# 0.99a, November 21st, 2007
- fixed bug in Makefile when lablgtk2 is not installed
- Sig.I.create and Sig_pack.create are now of type ?size:int -> unit -> t
(instead of unit -> t) to indicate an initial guess on the graph size
# 0.99, June 27th, 2007
- experimental: GTK-based graph editor based on hyperbolic geometry;
to build it and test it, cd to editor/ and type make
- [Components.Make] functor: function [scc] as a new profile and a
more precise specification. New function [scc_array].
- fixed configure to set ocaml's standard library using "ocamlc -where"
- new module Dot to parse files in Graphviz's DOT format
- slight change in the license (no more clause 6 of the LGPL; see LICENSE)
- new module Strat implementing simple game strategies
- Graphviz: little refactoring and improved documentation
# 0.98, Sep 27th, 2006
- rename Sig.IA to Sig.IM
- add subgraph support in Graphviz
(breaks ascendent compatibility if you use Graphviz: by default add
let get_subgraph _ = None
in the argument of Graphviz.Dot and Graphviz.Neato)
# 0.97, July 20th, 2006
- fixed compilation under Windows/Cygwin (contributed by Denis Berthod)
- fixed bug with escaped string in Graphviz
# 0.96, May 2nd, 2006
- new demo program: sudoku.ml (solving the Sudoku using graph coloring)
- new module Coloring for (rather brute force) graph coloring
- new implementation Imperative.Digraph.ConcreteBidirectional
that maintains the set of ingoing edges for each node, thus improving the
efficiency of functions such as iter_pred, pred, in_degree, etc.
(contributed by Ted Kremenek)
# 0.95, November 2nd, 2005
- compatibility with ocaml 3.09
- new module Path.Check to check for paths
# 0.94, July 6th, 2005
- new module Gml to parse and print graphs in GML file format
(see http://www.infosun.fmi.uni-passau.de/Graphlet/GML)
corresponding functions parse_gml_file and print_gml_file in Pack
- added display_with_gv in Pack
- improved implementation of Unionfind (patch by Marc Lasson)
# 0.93, March 31st, 2005
- fixed bug in Rand (integer overflow causing Invalid_argument "random");
improved code in Rand
- bug fixed in the META file
- add find_edge in Sig.G (and so in all graph implementations)
# 0.92, January 18th, 2005
- fixed escaped labels in Graphviz output (patch by Boris Yakobowski)
- new Graphviz option OrderingOut (patch by Boris Yakobowski)
- fixed sharing bugs in Oper (patch by Boris Yakobowski)
- fixed bug in nb_edges for undirected graphs
- improvement of iterators of undirected concrete graphs
# 0.91, December 16th, 2004
- more precise specifications of remove_edge and shortest_path.
- bug fixed in mem_edge_e of labelled graphs
- generation of random graphs improved
- add Rand.Make and Rand.Planar.Make (generic functors)
- add signatures Persistent.S and Imperative.S
# 0.90, November 30th, 2004
- graph.cma graph.cmxa
- version.ml and META files are now writable
- add interfaces Sig.VERTEX and Sig.EDGE
- "sig.ml" and "sig_pack.ml" removed; ocamlgraph now requires ocaml 3.08.0
- improvement of Minsep
- add Components.scc_list
- Oper.Neighbourhood replaces Neighborhood
- Gmap replaces Copy
- add types Sig_pack.vertex and Sig_pack.edge
- fixed bug in Ford-Fulkerson: G.V.equal instead of = in two asserts
# 0.81, July 13th, 2004
- compatibility with ocaml 3.08
- Oper.Choose.choose_edge: choose an edge in a graph
- add types Sig.G.edge and Sig.G.vertex resp. equal to Sig.G.V.t and Sig.G.E.t
- fixed typos in invalid_arg arguments (in Bitv)
# 0.80, June 28th, 2004
- major contribution by Matthieu Sozeau and Pierre-Loïc Garoche.
New modules are:
- Md: Minimum Degree algorithm
- Cliquetree: the clique tree of a graph
- Mcs_m: Maximal Cardinality Search (MCS-M) algorithm
- Minsep: Minimal separators of a graph
- Neighborhood: compute the neighborhood of a vertex/some vertices
- Oper.Difference: subgraphs induced by the elimination of some vertices
- Oper.Choose: choose a vertex in a graph
- Copy: graphs copying
- Util.DataV: create a vertex type with data attached to it
- out_degree: raises Invalid_argument if v not in g (instead of Not_found)
- Pack.Graph: golberg/ford_fulkerson fail ("not a directed graph")
# 0.70, Feb 27th, 2004
- Makefile.in: dependences ("make -j" works)
- union and intersection (see Oper.S.union and Oper.S.intersection)
- Golberg/Ford_fulkerson algorithms in a single module Flow
- step-by-step iterators in Traverse.{Dfs,Bfs}
- Ford_fulkerson: maxflow now returns a flow function over edges
# 0.60, Feb 18th, 2004
- fixed bug in Ford-Fulkerson
- random planar graphs (see Rand.Planar)
- Delaunay triangulation (see Delaunay)
- implementations with adjacency matrices (see Imperative.Matrix)
- operations on predecessors for undirected graphs optimized
- Traverse.Dfs.{prefix,prefix_component} optimized (now tail recursive)
# 0.50, Feb 4th, 2004
- first release
ocamlgraph-2.0.0/dgraph/ 0000755 0001750 0000144 00000000000 13735627615 013456 5 ustar rt users ocamlgraph-2.0.0/dgraph/dGraphContainer.mli 0000644 0001750 0000144 00000012432 13735627615 017233 0 ustar rt users (**************************************************************************)
(* *)
(* This file is part of OcamlGraph. *)
(* *)
(* Copyright (C) 2009-2010 *)
(* CEA (Commissariat à l'Énergie Atomique) *)
(* *)
(* you can redistribute it and/or modify it under the terms of the GNU *)
(* Lesser General Public License as published by the Free Software *)
(* Foundation, version 2.1, with a linking exception. *)
(* *)
(* It 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. See the *)
(* GNU Lesser General Public License for more details. *)
(* *)
(* See the file ../LICENSE for more details. *)
(* *)
(* Authors: *)
(* - Julien Signoles (Julien.Signoles@cea.fr) *)
(* - Jean-Denis Koeck (jdkoeck@gmail.com) *)
(* - Benoit Bataille (benoit.bataille@gmail.com) *)
(* *)
(**************************************************************************)
open Graph
type cluster = string
type status = Global | Tree | Both
class type
['vertex, 'edge, 'cluster, 'tree_vertex, 'tree_edge, 'tree_cluster]
view_container_type =
object
method global_view :
('vertex, 'edge, 'cluster) DGraphView.view option
method tree_view:
('tree_vertex, 'tree_edge, 'tree_cluster) DGraphView.view option
method tree_root: 'vertex option
method depth_backward : int
method depth_forward : int
method status : status
method set_depth_backward : int -> unit
method set_depth_forward : int -> unit
method set_tree_root: 'vertex -> unit
method switch : status -> unit
method adapt_zoom: unit -> unit
end
module type S = sig
type graph
type vertex
type edge
module Tree: Sig.G with type V.label = vertex
module GView: DGraphView.S with type vertex = vertex
and type edge = edge
and type cluster = cluster
module TView: DGraphView.S with type vertex = Tree.V.t
and type edge = Tree.E.t
and type cluster = cluster
type global_view = (vertex, edge, cluster) DGraphView.view
type tree_view = (Tree.V.t, Tree.E.t, cluster) DGraphView.view
class view_container :
?packing:(GObj.widget -> unit)
-> ?status:status
-> ?default_callbacks:bool (* register default node callbacks (centering
and highlighting). True by default *)
-> mk_global_view: (unit -> global_view)
-> mk_tree_view:
(depth_backward:int -> depth_forward:int -> Gtk.widget Gtk.obj -> vertex
-> tree_view)
-> vertex option
-> [ vertex, edge, cluster, Tree.V.t, Tree.E.t, cluster]
view_container_type
end
module Make(G: Graphviz.GraphWithDotAttrs) : sig
include S with type graph = G.t and type vertex = G.V.t and type edge = G.E.t
val from_graph :
?packing:(GObj.widget -> unit)
-> ?status:status
-> ?default_callbacks:bool
->
?mk_global_view:
((G.V.t, G.E.t, cluster) DGraphModel.abstract_model -> global_view)
->
?mk_tree_view:
((Tree.V.t, Tree.E.t, cluster) DGraphModel.abstract_model -> tree_view)
-> ?root:G.vertex
-> G.t
-> view_container
val from_graph_with_commands :
?packing:(GObj.widget -> unit)
-> ?status:status
-> ?default_callbacks:bool
->
?mk_global_view:
((G.V.t, G.E.t, cluster) DGraphModel.abstract_model -> global_view)
->
?mk_tree_view:
((Tree.V.t, Tree.E.t, cluster) DGraphModel.abstract_model -> tree_view)
-> ?root:G.vertex
-> G.t
-> GPack.table * view_container
end
module Dot : sig
open DGraphModel
include S with type graph = DotG.t
and type vertex = DotG.V.t
and type edge = DotG.E.t
val from_dot :
?packing:(GObj.widget -> unit)
-> ?status:status
-> ?default_callbacks:bool
-> ?mk_global_view:
((DotG.V.t, DotG.E.t, cluster) abstract_model -> global_view)
-> ?mk_tree_view:
((Tree.V.t, Tree.E.t, cluster) abstract_model -> tree_view)
-> string (* dot filename *)
-> view_container
val from_dot_with_commands :
?packing:(GObj.widget -> unit)
-> ?status:status
-> ?default_callbacks:bool
-> ?mk_global_view:
((DotG.V.t, DotG.E.t, cluster) abstract_model -> global_view)
-> ?mk_tree_view:
((Tree.V.t, Tree.E.t, cluster) abstract_model -> tree_view)
-> string (* dot filename *)
-> GPack.table * view_container
end
ocamlgraph-2.0.0/dgraph/dGraphMake.ml 0000644 0001750 0000144 00000003571 13735627615 016021 0 ustar rt users (**************************************************************************)
(* *)
(* This file is part of OcamlGraph. *)
(* *)
(* Copyright (C) 2009-2010 *)
(* CEA (Commissariat à l'Énergie Atomique) *)
(* *)
(* you can redistribute it and/or modify it under the terms of the GNU *)
(* Lesser General Public License as published by the Free Software *)
(* Foundation, version 2.1, with a linking exception. *)
(* *)
(* It 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. See the *)
(* GNU Lesser General Public License for more details. *)
(* *)
(* See the file ../LICENSE for more details. *)
(* *)
(* Authors: *)
(* - Julien Signoles (Julien.Signoles@cea.fr) *)
(* - Jean-Denis Koeck (jdkoeck@gmail.com) *)
(* - Benoit Bataille (benoit.bataille@gmail.com) *)
(* *)
(**************************************************************************)
open Graph
open XDot
open Printf
exception DotError of string
ocamlgraph-2.0.0/dgraph/dGraphView.ml 0000644 0001750 0000144 00000026471 13735627615 016062 0 ustar rt users (**************************************************************************)
(* *)
(* This file is part of OcamlGraph. *)
(* *)
(* Copyright (C) 2009-2010 *)
(* CEA (Commissariat à l'Énergie Atomique) *)
(* *)
(* you can redistribute it and/or modify it under the terms of the GNU *)
(* Lesser General Public License as published by the Free Software *)
(* Foundation, version 2.1, with a linking exception. *)
(* *)
(* It 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. See the *)
(* GNU Lesser General Public License for more details. *)
(* *)
(* See the file ../LICENSE for more details. *)
(* *)
(* Authors: *)
(* - Julien Signoles (Julien.Signoles@cea.fr) *)
(* - Jean-Denis Koeck (jdkoeck@gmail.com) *)
(* - Benoit Bataille (benoit.bataille@gmail.com) *)
(* *)
(**************************************************************************)
open DGraphViewItem
let ($) f x = f x
class type ['vertex, 'edge, 'cluster] view = object
inherit GnoCanvas.canvas
method model : ('vertex, 'edge, 'cluster) DGraphModel.abstract_model
method get_node : 'vertex -> 'vertex view_item
method get_edge : 'edge -> 'edge view_item
method get_cluster : 'cluster -> 'cluster view_item
method iter_nodes: ('vertex view_item -> unit) -> unit
method iter_edges: ('vertex view_item -> 'vertex view_item -> unit) -> unit
method iter_edges_e: ('edge view_item -> unit) -> unit
method iter_clusters: ('cluster view_item -> unit) -> unit
method iter_succ: ('vertex view_item -> unit) -> 'vertex view_item -> unit
method iter_pred: ('vertex view_item -> unit) -> 'vertex view_item -> unit
method iter_succ_e: ('edge view_item -> unit) -> 'vertex view_item -> unit
method iter_pred_e: ('edge view_item -> unit) -> 'vertex view_item -> unit
method iter_associated_vertex:
('vertex view_item -> unit) -> 'vertex view_item -> unit
method mem_edge: 'vertex view_item -> 'vertex view_item -> bool
method find_edge: 'vertex view_item -> 'vertex view_item -> 'edge view_item
method src: 'edge view_item -> 'vertex view_item
method dst: 'edge view_item -> 'vertex view_item
method zoom_factor : float
method zoom_to : float -> unit
method zoom_in : unit -> unit
method zoom_out : unit -> unit
method adapt_zoom : unit -> unit
method center_node: 'vertex view_item -> unit
method set_zoom_padding: float -> unit
method connect_highlighting_event: unit -> unit
method highlight: ?color: int32 * int32 -> 'vertex view_item -> unit
method dehighlight: 'vertex view_item -> unit
end
module type S = sig
type vertex
type edge
type cluster
val view:
?aa:bool (** Anti-aliasing *) ->
?delay_node:(vertex -> bool) ->
?delay_edge:(edge -> bool) ->
?delay_cluster:(cluster -> bool) ->
?border_width:int ->
?width:int ->
?height:int ->
?packing:(GObj.widget -> unit) ->
?show:bool ->
(vertex, edge, cluster) DGraphModel.abstract_model ->
(vertex, edge, cluster) view
(** View as a Gnome Canvas.
Support zooming and scrolling. *)
end
(* ************************************************************************* *)
(** View from a model *)
(* ************************************************************************* *)
module Make(V: Sig.HASHABLE)(E: Sig.HASHABLE)(C: Sig.HASHABLE) = struct
type vertex = V.t
type edge = E.t
type cluster = C.t
module HV = Hashtbl.Make(V)
module HE = Hashtbl.Make(E)
module HC = Hashtbl.Make(C)
(* Widget derived from Gnome Canvas.
Supports zooming and scrolling *)
class view
?delay_node ?delay_edge ?delay_cluster
obj
(model : (V.t, E.t, C.t) DGraphModel.abstract_model)
=
let delay f v = match f with None -> false | Some f -> f v in
let (x1, y1), (x2, y2) = model#bounding_box in
object(self)
inherit GnoCanvas.canvas obj
method model = model
(* Hash tables from the model to the view items*)
val node_hash : V.t view_item HV.t = HV.create 17
val edge_hash : E.t view_item HE.t = HE.create 17
val cluster_hash : C.t view_item HC.t = HC.create 7
(* Canvas items creation *)
method private add_vertex vertex =
try
let layout = model#get_vertex_layout vertex in
let item =
view_node
~delay:(delay delay_node vertex)
~view:(self :> common_view) ~vertex ~layout ()
in
HV.add node_hash vertex item
with Not_found ->
assert false
method private add_edge edge =
try
let layout = model#get_edge_layout edge in
let item =
view_edge
~delay:(delay delay_edge edge)
~view:(self:>common_view) ~edge ~layout ()
in
HE.add edge_hash edge item
with Not_found ->
assert false
method private add_cluster cluster =
let layout = model#get_cluster_layout cluster in
let item =
view_cluster
~delay:(delay delay_cluster cluster)
~view:(self :> common_view) ~cluster ~layout ()
in
HC.add cluster_hash cluster item
(* From model to view items *)
method get_node n =
try HV.find node_hash n with Not_found -> assert false
method get_edge e =
try HE.find edge_hash e with Not_found -> assert false
method get_cluster c =
try HC.find cluster_hash c with Not_found -> assert false
(* Iterate on nodes and edges *)
method iter_nodes f = HV.iter (fun _ v -> f v) node_hash
method iter_edges_e f = HE.iter (fun _ e -> f e) edge_hash
method iter_clusters f = HC.iter (fun _ c -> f c) cluster_hash
method iter_edges f =
model#iter_edges (fun v1 v2 -> f (self#get_node v1) (self#get_node v2))
(* Iterate on successors of a node *)
method iter_succ f (node: 'v view_item) =
let f' v = f (self#get_node v) in
model#iter_succ f' node#item
(* Iterate on predecessors of a node *)
method iter_pred f (node: 'v view_item) =
let f' v = f (self#get_node v) in
model#iter_pred f' node#item
method iter_succ_e f (node: 'v view_item) =
let f' e = f (self#get_edge e) in
model#iter_succ_e f' node#item
method iter_pred_e f (node: 'v view_item) =
let f' e = f (self#get_edge e) in
model#iter_pred_e f' node#item
(* Iterate on associated nodes *)
method iter_associated_vertex f (node: 'v view_item) =
let f' v = f (self#get_node v) in
model#iter_associated_vertex f' node#item
(* Membership functions *)
method mem_edge (n1:'v view_item) (n2:'v view_item) =
model#mem_edge n1#item n2#item
method find_edge (n1:'v view_item) (n2:'v view_item) =
self#get_edge (model#find_edge n1#item n2#item)
method src (e: 'e view_item) = self#get_node (model#src e#item)
method dst (e: 'e view_item) = self#get_node (model#dst e#item)
(* Zoom factor *)
val mutable zoom_f = 1.
method zoom_factor = zoom_f
val mutable zoom_padding = 0.1
method set_zoom_padding n = zoom_padding <- n
method private set_zoom_f x = if x > 1e-10 then zoom_f <- x
(* Zoom to a particular factor *)
method zoom_to x =
self#set_zoom_f x;
self#set_pixels_per_unit zoom_f;
self#iter_clusters (fun c -> c#zoom_text zoom_f);
self#iter_nodes (fun n -> n#zoom_text zoom_f);
self#iter_edges_e (fun e -> e#zoom_text zoom_f)
method zoom_in () = self#zoom_to (zoom_f +. zoom_padding *. zoom_f)
method zoom_out () = self#zoom_to (zoom_f -. zoom_padding *. zoom_f)
method center_node (node:V.t view_item) =
node#center ()
(* self#zoom_in ();*)
method adapt_zoom () =
let width = self#hadjustment#page_size in
let height = self#vadjustment#page_size in
let w_zoom = width /. abs_float (x1-.x2) in
let h_zoom = height /. abs_float (y1-.y2) in
self#zoom_to (min 1. (min w_zoom h_zoom))
(* EVENTS *)
(* Zoom with the keys *)
method private zoom_keys_ev ev =
match GdkEvent.Key.keyval ev with
| k when k = GdkKeysyms._KP_Subtract -> self#zoom_out (); true
| k when k = GdkKeysyms._KP_Add -> self#zoom_in (); true
| _ -> false
(* Zoom with the mouse *)
method private zoom_mouse_ev ev =
match GdkEvent.Scroll.direction ev with
| `UP -> self#zoom_in (); true
| `DOWN -> self#zoom_out (); true
| _ -> false
method highlight ?color node =
let h e = e#highlight ?color () in
h node;
self#iter_associated_vertex (fun v ->
h v;
self#iter_succ_e h v;
self#iter_pred_e h v)
node
method dehighlight node =
let h e = e#dehighlight () in
h node;
self#iter_associated_vertex (fun v ->
h v;
self#iter_succ_e h v;
self#iter_pred_e h v)
node
method connect_highlighting_event () =
let connect node =
let callback = function
| `MOTION_NOTIFY _ -> self#highlight node; false
| `LEAVE_NOTIFY _ -> self#dehighlight node; false
| _ -> false
in
node#connect_event ~callback
in
self#iter_nodes connect
initializer
(* Create and add items from the model vertices, edges and clusters *)
model#iter_clusters self#add_cluster;
model#iter_vertex self#add_vertex;
model#iter_edges_e self#add_edge;
(* Scroll region management *)
ignore $ self#set_center_scroll_region true;
ignore $ self#set_scroll_region ~x1 ~y1 ~x2 ~y2 ;
(* Attach zoom events *)
ignore $ self#event#connect#key_press ~callback:self#zoom_keys_ev;
ignore $ self#event#connect#scroll ~callback:self#zoom_mouse_ev;
end
let view
?(aa=false) ?delay_node ?delay_edge ?delay_cluster
?border_width ?width ?height ?packing ?show
(model:(vertex, edge, cluster) DGraphModel.abstract_model) =
let canvas =
GnoCanvas.canvas ~aa ?border_width ?width ?height ?show ?packing ()
in
(* Grab focus to process keyboard input *)
ignore $ canvas#event#connect#enter_notify
~callback:(fun _ -> canvas#misc#grab_focus () ; false);
let view =
new view ?delay_node ?delay_edge ?delay_cluster
(Gobject.unsafe_cast canvas#as_widget)
model
in
view
end
ocamlgraph-2.0.0/dgraph/dGraphViewItem.ml 0000644 0001750 0000144 00000037313 13735627615 016676 0 ustar rt users (**************************************************************************)
(* *)
(* This file is part of OcamlGraph. *)
(* *)
(* Copyright (C) 2009-2010 *)
(* CEA (Commissariat � l'�nergie Atomique) *)
(* *)
(* you can redistribute it and/or modify it under the terms of the GNU *)
(* Lesser General Public License as published by the Free Software *)
(* Foundation, version 2.1, with a linking exception. *)
(* *)
(* It 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. See the *)
(* GNU Lesser General Public License for more details. *)
(* *)
(* See the file ../LICENSE for more details. *)
(* *)
(* Authors: *)
(* - Julien Signoles (Julien.Signoles@cea.fr) *)
(* - Jean-Denis Koeck (jdkoeck@gmail.com) *)
(* - Benoit Bataille (benoit.bataille@gmail.com) *)
(* *)
(**************************************************************************)
open XDot
open XDotDraw
let red_color = 0xFF0000FFl
let blue_color = 0x0000FFFFl
let green_color = 0x00FF00FFl
let black_color = 0x000000FFl
let white_color = 0xFFFFFFFFl
exception Cannot_convert_color of string
let rgba_to_int32 col =
(* Graphivz sometimes insert named colors by itself, we need to catch
those. The list might be incomplete though; if it is, we might need to
translate http://www.w3.org/TR/SVG/types.html#ColorKeywords *)
match col with
| "black" -> black_color
| "white" -> white_color
| "red" -> red_color
| "green" -> green_color
| "blue" -> blue_color
| _ ->
try
match String.length col with
| 7 -> Graph.Graphviz.color_to_color_with_transparency
(int_of_string ("0x" ^ String.sub col 1 6))
| 9 -> Int32.of_string ("0x" ^ String.sub col 1 8)
| _ -> failwith ""
with Failure _ ->
(* Can fail either in the failed match above, or in int*of_string *)
raise (Cannot_convert_color (col^" but int32 expected"))
let convert_fill_color col = `FILL_COLOR_RGBA (rgba_to_int32 col)
let convert_outline_color col = `OUTLINE_COLOR_RGBA (rgba_to_int32 col)
let ($) f x = f x
(* Derived text class. *)
class graph_text txt_obj ~size_points ~(props:GnomeCanvas.text_p list) =
let props = `SIZE_POINTS size_points :: props in
object (self)
inherit GnoCanvas.text txt_obj as text
val original_size = size_points
val mutable props = props
method! set p =
props <- p;
text#set p
method highlight ?(color=red_color,green_color) () =
let primary, secondary = color in
let color = ref primary in
let rec hi_props = function
| [] -> []
| `SIZE_POINTS p :: l ->
let p = if p >= 12. then p else max 6. (p *. 1.5) in
`SIZE_POINTS p :: hi_props l
| `WEIGHT d :: l ->
`WEIGHT (max 600 (int_of_float (float d *. 1.5))) :: hi_props l
| `FILL_COLOR_RGBA c :: l ->
if c = primary then color := secondary;
hi_props l
| p :: l -> p :: hi_props l
in
(* as inserted in head, `WEIGHT 600 will not apply if there is already a
specified weight *)
text#set (`FILL_COLOR_RGBA !color :: `WEIGHT 600 :: hi_props props)
method dehighlight () =
(* as inserted in head, properties will not apply if they are already
specified *)
text#set (`WEIGHT 400 :: `FILL_COLOR_RGBA black_color :: props)
method resize (zoom_factor:float) =
let rec change = function
| [] -> []
| `SIZE_POINTS _ :: l ->
`SIZE_POINTS (zoom_factor*.original_size) :: change l
| `FONT _ :: l -> change l
| p :: l -> p :: change l
in
self#set (change props)
initializer
text#set props
end
(* Constructor copied and adapted from gnoCanvas.ml *)
let graph_text ?x ?y ?text ?font ?anchor ~size_points ?(props=[]) p =
let add_prop props f x =
match x with None -> props | Some x -> f x :: props
in
let props = add_prop props (fun x -> `ANCHOR x) anchor in
let props = add_prop props (fun x -> `FONT x) font in
let props = add_prop props (fun x -> `TEXT x) text in
let props = add_prop props (fun x -> `Y x) y in
let props = add_prop props (fun x -> `X x) x in
let i = GnomeCanvas.Item.new_item p#as_group GnomeCanvas.Types.text in
new graph_text i ~size_points ~props
(** FROM DOT LAYOUT TO VIEW ITEMS *)
(* Shape properties.
Used when initializing items *)
let pen_color draw_st = convert_outline_color draw_st.XDotDraw.pen_color
let fill_color draw_st = convert_fill_color draw_st.XDotDraw.fill_color
(* Flattens an array of pair of coordinates into an array of coordinates *)
let flatten_points pts =
let convert i =
let x, y = pts.(i / 2) in
if i mod 2 = 0 then x else y
in
Array.init (2 * Array.length pts) convert
(* SHAPE CONSTRUCTORS *)
(* Ellipse, polygon and bpath canvas items do not share the same type
in lablgtk2
They are kept in separate type constructors along with their
initial properties. *)
type shape_t =
| SEllipse of GnoCanvas.ellipse
| SPolygon of GnoCanvas.polygon
| SBSpline of GnoCanvas.bpath
let shape_item = function
| SEllipse e -> e#as_item
| SPolygon p -> p#as_item
| SBSpline b -> b#as_item
(* Shape properties (used by canvas items ellipse, polygon and bpath) *)
type shape_p =
[ `FILL_COLOR_RGBA of int32
| `OUTLINE_COLOR_RGBA of int32
| `WIDTH_UNITS of float
| `DASH of float * float array ]
(* Property list completion *)
(* In the initial property list of a shape, we need all the properties to hold
a value, so that we can refer to them when unsetting property changes *)
let complete_props props =
let rec what_props (fill, width, outline, dash as acc) = function
| [] -> acc
| `FILL_COLOR_RGBA _ :: l -> what_props (true, width, outline, dash) l
| `WIDTH_UNITS _ :: l -> what_props (fill, true, outline, dash) l
| `OUTLINE_COLOR_RGBA _ :: l -> what_props (fill, width, true, dash) l
| `DASH _ :: l -> what_props (fill, width, outline, true) l
in
let fill, width, outline, dash =
what_props (false, false, false, false) props
in
let props = if fill then props else `FILL_COLOR_RGBA black_color :: props in
let props = if width then props else `WIDTH_UNITS 1. :: props in
let props =
if outline then props else `OUTLINE_COLOR_RGBA black_color :: props
in
if dash then props else `DASH (0., [| |]) :: props
(* Shape class (either a rect, an ellipse, a polygon or a path).
Uses a properties queue to undo changes *)
class shape ~fill shape init_props = object (self)
inherit GnoCanvas.base_item (shape_item shape)
method private set_props props = match shape with
| SPolygon p -> p#set (props :> GnomeCanvas.polygon_p list)
| SEllipse e -> e#set (props :> GnomeCanvas.re_p list)
| SBSpline b -> b#set (props :> GnomeCanvas.bpath_p list)
(* Properties queue *)
val mutable props = []
method set p =
props <- p;
self#set_props p
method highlight ?(color=red_color,green_color) () =
let primary, secondary = color in
let color = ref primary in
let rec hi_props = function
| [] -> []
| `WIDTH_UNITS u :: l -> `WIDTH_UNITS (max 3. (u *. 3.)) :: hi_props l
| `FILL_COLOR_RGBA c :: l when fill ->
if c = primary then color := secondary;
hi_props l
| `OUTLINE_COLOR_RGBA c :: l ->
if c = primary then color := secondary;
hi_props l
| p :: l -> p :: hi_props l
in
(* as inserted in head, `WIDTH_UNITS 3. will not apply if there is already
a specified weight *)
let props = hi_props props in
let props = if fill then `FILL_COLOR_RGBA !color :: props else props in
self#set_props (`OUTLINE_COLOR_RGBA !color :: `WIDTH_UNITS 3. :: props)
method dehighlight () =
(* as inserted in head, `WIDTH_UNITS 1. will not apply if there is already
a specified weight *)
let props = if fill then `FILL_COLOR_RGBA black_color :: props else props in
self#set_props (`WIDTH_UNITS 1. :: `OUTLINE_COLOR_RGBA black_color :: props)
initializer self#set (complete_props init_props)
end
let get_props draw_st =
let base_props = [ pen_color draw_st; fill_color draw_st ] in
let fold_sty_attr props = function
| Dashed -> `DASH (0., [|10.|]) :: props
| Dotted -> `DASH (0., [|2.; 10.|]) :: props
| _ -> props
in
List.fold_left fold_sty_attr base_props draw_st.style
let ellipse ~fill draw_st group pos w h =
let((x1,y1), (x2,y2)) = XDot.bounding_box pos w h in
let props = get_props draw_st in
let ellip = GnoCanvas.ellipse group ~x1 ~y1 ~x2 ~y2 ~props in
new shape ~fill (SEllipse ellip) props
let polygon ~fill draw_st group pts =
let props = get_props draw_st in
let points = flatten_points pts in
let poly = GnoCanvas.polygon group ~points ~props in
new shape ~fill (SPolygon poly) props
let pathdef pts =
if List.length pts mod 3 = 1 then
(* Starting point *)
let pathdef = GnomeCanvas.PathDef.new_path () in
let (x0,y0) = List.hd pts in
GnomeCanvas.PathDef.moveto pathdef x0 y0;
(* Rest of the spline *)
let rec curveto = function
| (x1,y1) :: (x2,y2) :: (x3,y3) :: t ->
GnomeCanvas.PathDef.curveto pathdef x1 y1 x2 y2 x3 y3;
curveto t
| _ -> ()
in
curveto (List.tl pts);
pathdef
else
(* failwith "Cannot build pathdef" *)
assert false
let bspline ~fill draw_st group pts =
let path =
pathdef (Array.fold_right (fun p acc -> p :: acc) pts [])
in
let props = get_props draw_st in
let bpath = GnoCanvas.bpath group ~bpath:path ~props in
new shape ~fill (SBSpline bpath) props
let text draw_st group (x,y) _align anchor label =
let size_points, font = draw_st.XDotDraw.font in
let props = [ convert_fill_color draw_st.XDotDraw.pen_color ] in
let anchor =
if anchor = -. 1. then `WEST else if anchor = 1.0 then `EAST else `CENTER
in
let size_points,height = XDotDraw.string_scale_size
~fontMeasure:(PangoMeasure.withContext ~context:(Gdk.Screen.get_pango_context ()))
font size_points label
in
(* y-height/4 because the base line of the text is 1/4th from the bottom *)
graph_text
group
~x ~y:(y-.height/.4.) ~text:label ~props ~anchor
~font ~size_points
class type common_view = object
inherit GnoCanvas.canvas
method zoom_factor : float
method adapt_zoom : unit -> unit
end
(* ITEMS *)
class type textshape = object
method highlight: ?color:int32 * int32 -> unit -> unit
method dehighlight: unit -> unit
method hide: unit -> unit
method show: unit -> unit
method lower_to_bottom: unit -> unit
method connect:
< event : callback:(GnoCanvas.item_event -> bool) -> GtkSignal.id;
after : GnoCanvas.item_signals;
destroy : callback:(unit -> unit) -> GtkSignal.id; >
end
(* DGraph item
Node and edge derive from this class
Contains shapes and texts
Can be : highlighted and/or selected
~pos : center of the container
~ops_list : list of list of operations
~hl_vip : highlight properties, set when method highlight is called *)
class [ 'a ] view_item ~fill ~delay ~(view: common_view) ~pos ~ops_list
~(item:'a) =
object (self)
inherit GnoCanvas.group view#root#as_group
val mutable hilighted = false
val mutable texts = []
val mutable shapes = []
val mutable computed = not delay
val mutable cached_events = []
method item = item
method private cache : 'a. ('a -> unit) -> 'a -> unit =
fun f x ->
if computed then f x
else cached_events <- (fun () -> f x) :: cached_events
method zoom_text (zf:float) =
self#cache (fun zf -> List.iter (fun t -> t#resize zf) texts) zf
method private iter f =
List.iter (fun t -> f (t :> textshape)) texts;
List.iter f (shapes :> textshape list)
method highlight ?color () =
self#cache
(fun () ->
if not hilighted then begin
hilighted <- true;
self#iter (fun s -> s#highlight ?color ());
List.iter (fun t -> t#raise_to_top ()) texts;
end)
()
method dehighlight () =
self#cache
(fun () ->
if hilighted then begin
hilighted <- false;
self#iter (fun s -> s#dehighlight ());
end)
()
method! hide () = self#cache (fun () -> self#iter (fun s -> s#hide ())) ()
method! show () = self#cache (fun () -> self#iter (fun s -> s#show ())) ()
method connect_event ~callback =
self#cache
(fun () -> self#iter (fun s -> ignore (s#connect#event ~callback)))
()
method center () =
self#cache(fun () ->
let x, y = pos in
let w = view#hadjustment#page_size /. view#zoom_factor in
let h = view#vadjustment#page_size /. view#zoom_factor in
let sx = x -. (w /. 2.) in
let sy = y -. (h /. 2.) in
let sx, sy = view#w2c ~wx:sx ~wy:sy in
ignore $ view#scroll_to ~x:sx ~y:sy)
()
method! lower_to_bottom () =
self#cache (fun () -> self#iter (fun s -> s#lower_to_bottom ())) ()
(* Reads a list of list of operations
Updates the shapes and texts lists *)
method private read_operations () =
let read_op draw_st = function
(* Create shapes *)
| XDotDraw.Filled_ellipse (pos, w, h)
| XDotDraw.Unfilled_ellipse (pos, w, h) ->
shapes <- ellipse ~fill draw_st self pos w h :: shapes
| XDotDraw.Filled_polygon pts | XDotDraw.Unfilled_polygon pts ->
shapes <- polygon ~fill draw_st self pts :: shapes
| XDotDraw.Bspline pts | XDotDraw.Filled_bspline pts ->
shapes <- bspline ~fill draw_st self pts :: shapes
| XDotDraw.Text (pos, align, anchor, label) ->
texts <- text draw_st self pos align anchor label :: texts
| _ -> ()
in
List.iter (draw_with read_op) ops_list;
List.iter (fun t -> t#raise_to_top ()) texts;
List.fold_right (* preserve order *) (fun f () -> f ()) cached_events ()
method compute () =
if not computed then begin
computed <- true;
self#read_operations ()
end
initializer
if delay then
let prio = Glib.int_of_priority `LOW in
ignore (Glib.Idle.add ~prio (fun () -> self#compute (); false))
else
self#read_operations ()
end
let view_node ~delay ~view ~vertex ~layout () =
let pos = layout.n_pos in
let ops_list = [ layout.n_ldraw; layout.n_draw ] in
new view_item ~fill:false ~delay ~view ~pos ~ops_list ~item:vertex
let view_edge ~delay ~view ~edge ~layout () =
let pos = 0., 0. in
let ops_list =
[ layout.e_draw; layout.e_ldraw;
layout.e_tldraw; layout.e_hldraw;
layout.e_tdraw; layout.e_hdraw ]
in
new view_item ~fill:true ~delay ~view ~pos ~ops_list ~item:edge
let view_cluster ~delay ~view ~cluster ~layout () =
let pos = layout.c_pos in
let ops_list = [ layout.c_ldraw; layout.c_draw ] in
let view =
new view_item ~fill:false ~delay ~pos ~ops_list ~view ~item:cluster
in
view#lower_to_bottom ();
view
ocamlgraph-2.0.0/dgraph/dGraphViewer.ml 0000644 0001750 0000144 00000012463 13735627615 016405 0 ustar rt users (**************************************************************************)
(* *)
(* This file is part of OcamlGraph. *)
(* *)
(* Copyright (C) 2009-2010 *)
(* CEA (Commissariat � l'�nergie Atomique) *)
(* *)
(* you can redistribute it and/or modify it under the terms of the GNU *)
(* Lesser General Public License as published by the Free Software *)
(* Foundation, version 2.1, with a linking exception. *)
(* *)
(* It 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. See the *)
(* GNU Lesser General Public License for more details. *)
(* *)
(* See the file ../LICENSE for more details. *)
(* *)
(* Authors: *)
(* - Julien Signoles (Julien.Signoles@cea.fr) *)
(* - Jean-Denis Koeck (jdkoeck@gmail.com) *)
(* - Benoit Bataille (benoit.bataille@gmail.com) *)
(* *)
(**************************************************************************)
open Graph_gtk
open Printf
let ($) f x = f x
let get_some = function Some t -> t | None -> assert false
let debug = false
module Content = DGraphContainer.Dot
type state = {
mutable file: string option;
mutable window: GWindow.window;
mutable content: (GPack.table * Content.view_container) option
}
let init_state () =
let window =
GWindow.window
~width:1280 ~height:1024
~title:"Graph Widget"
~allow_shrink:true ~allow_grow:true ()
in
let status = GMisc.label ~markup:"" () in
status#set_use_markup true;
let file = ref None in
for i=1 to Array.length Sys.argv - 1 do
file := Some Sys.argv.(i)
done;
{ file = !file;
window = window;
content = None }
(* Top menu *)
let menu_desc = "\
\
\
\
\
\
\
"
let update_state state ~packing =
(match state.content with None -> () | Some (t, _) -> t#destroy ());
try
let _, view as content = match state.file with
| Some file ->
if debug then printf "Building Model...\n";
state.file <- Some file;
Content.from_dot_with_commands ~packing file
| None ->
raise Not_found
in
state.content <- Some content;
state.window#show ();
view#adapt_zoom ()
with Not_found ->
if debug then printf "No model\n"
let all_files () =
let f = GFile.filter ~name:"All" () in
f#add_pattern "*" ;
f
let open_file state ~packing () =
let dialog =
GWindow.file_chooser_dialog
~action:`OPEN
~title:"Open File"
~parent:state.window ()
in
dialog#add_button_stock `CANCEL `CANCEL ;
dialog#add_select_button_stock `OPEN `OPEN ;
dialog#add_filter (all_files ()) ;
match dialog#run () with
| `OPEN ->
state.file <- dialog#filename;
dialog#destroy ();
update_state state ~packing
| `DELETE_EVENT | `CANCEL -> dialog#destroy ()
let create_menu state ~packing =
let ui_m = GAction.ui_manager () in
let actions = GAction.action_group ~name:"Actions" () in
GAction.add_actions actions [
GAction.add_action "FileMenu" ~label:"File" ;
GAction.add_action "Open" ~label:"Open" ~accel:"o" ~stock:`OPEN
~callback:(fun _ -> open_file state ~packing ());
GAction.add_action
"Zoom fit" ~label:"Zoom fit" ~accel:"t" ~stock:`ZOOM_FIT
~callback:(fun _ -> match state.content with
|None -> ()
|Some (_,v) -> v#adapt_zoom ());
GAction.add_action "Quit" ~label:"Quit" ~accel:"q" ~stock:`QUIT
~callback:(fun _ -> GMain.Main.quit ());
];
ui_m#insert_action_group actions 0 ;
ignore $ ui_m#add_ui_from_string menu_desc;
ui_m
(* Main loop *)
let main () =
(* GUI *)
let state = init_state () in
let vbox =
GPack.vbox ~border_width:4 ~spacing:4 ~packing:state.window#add ()
in
let packing = vbox#pack ~expand:true ~fill:true in
(* Menu *)
let ui_m = create_menu state ~packing in
state.window#add_accel_group ui_m#get_accel_group ;
vbox#pack ~expand:false (ui_m#get_widget "/MenuBar");
ignore $ state.window#connect#destroy ~callback:GMain.Main.quit;
if debug then printf "GUI built, time: %f\n" (Sys.time ());
update_state state ~packing;
state.window#show ();
GMain.Main.main ()
(* [JS 2009/09/21] Printexc.print prevents to use ocaml < 3.11 *)
let _ = (*Printexc.print*) main ()
ocamlgraph-2.0.0/dgraph/dGraphContainer.ml 0000644 0001750 0000144 00000035465 13735627615 017075 0 ustar rt users (**************************************************************************)
(* *)
(* This file is part of OcamlGraph. *)
(* *)
(* Copyright (C) 2009-2010 *)
(* CEA (Commissariat � l'�nergie Atomique) *)
(* *)
(* you can redistribute it and/or modify it under the terms of the GNU *)
(* Lesser General Public License as published by the Free Software *)
(* Foundation, version 2.1, with a linking exception. *)
(* *)
(* It 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. See the *)
(* GNU Lesser General Public License for more details. *)
(* *)
(* See the file ../LICENSE for more details. *)
(* *)
(* Authors: *)
(* - Julien Signoles (Julien.Signoles@cea.fr) *)
(* - Jean-Denis Koeck (jdkoeck@gmail.com) *)
(* - Benoit Bataille (benoit.bataille@gmail.com) *)
(* *)
(**************************************************************************)
open Graph
let ($) f x = f x
type cluster = string
type status = Global | Tree | Both
(* ABSTRACT CLASS *)
class type
['vertex, 'edge, 'cluster, 'tree_vertex, 'tree_edge, 'tree_cluster]
view_container_type =
object
method global_view :
('vertex, 'edge, 'cluster) DGraphView.view option
method tree_view:
('tree_vertex, 'tree_edge, 'tree_cluster) DGraphView.view option
method tree_root: 'vertex option
method depth_backward : int
method depth_forward : int
method status : status
method set_depth_backward : int -> unit
method set_depth_forward : int -> unit
method set_tree_root: 'vertex -> unit
method switch : status -> unit
method adapt_zoom: unit -> unit
end
module type S = sig
type graph
type vertex
type edge
module Tree: Sig.G with type V.label = vertex
module GView: DGraphView.S with type vertex = vertex
and type edge = edge
and type cluster = cluster
module TView: DGraphView.S with type vertex = Tree.V.t
and type edge = Tree.E.t
and type cluster = cluster
type global_view = (vertex, edge, cluster) DGraphView.view
type tree_view = (Tree.V.t, Tree.E.t, cluster) DGraphView.view
class view_container :
?packing:(GObj.widget -> unit)
-> ?status:status
-> ?default_callbacks:bool
-> mk_global_view: (unit -> global_view)
-> mk_tree_view:
(depth_backward:int -> depth_forward:int -> Gtk.widget Gtk.obj -> vertex
-> tree_view)
-> vertex option
-> [ vertex, edge, cluster, Tree.V.t, Tree.E.t, cluster]
view_container_type
end
(* CONTAINER *)
let with_commands ?packing mk_view model =
let main_table = GPack.table ~columns:2 ~rows:2 ?packing () in
let view =
let packing w = main_table#attach ~left:0 ~right:2 ~top:1 ~expand:`BOTH w in
mk_view ~packing model
in
(* Buttons box *)
let buttons_box =
GPack.button_box
`HORIZONTAL
~border_width:3
~child_height:10
~child_width:85
~spacing:10
~layout:`START
~packing:(main_table#attach ~top:0 ~left:0 ~expand:`X) ()
in
let view_label = GMisc.label ~markup:"View " () in
buttons_box#pack ~expand:false view_label#coerce;
let add_button label mode =
let b = GButton.button ~label ~packing:buttons_box#pack () in
ignore (b#connect#clicked ~callback:(fun _ -> view#switch mode))
in
add_button "Global" Global;
add_button "Tree" Tree;
add_button "Both" Both;
(* Depth of exploration controls *)
let depth_hbox =
GPack.hbox ~packing:(main_table#attach ~expand:`X ~top:0 ~left:1) ()
in
let depth_forward_adj = GData.adjustment ~lower:0. ~page_size:0. () in
let depth_backward_adj = GData.adjustment ~lower:0. ~page_size:0. () in
let change_depth_forward adj content () =
content#set_depth_forward (int_of_float adj#value);
in
let change_depth_backward adj content () =
content#set_depth_backward (int_of_float adj#value)
in
ignore $ depth_forward_adj#connect#value_changed
~callback:(change_depth_forward depth_forward_adj view);
ignore $ depth_backward_adj#connect#value_changed
~callback:(change_depth_backward depth_backward_adj view);
let depth_label = GMisc.label ~markup:"Depth " () in
let depth_forward_label = GMisc.label ~text:" forward: " () in
let depth_backward_label = GMisc.label ~text:" backward: " () in
let depth_forward_spin =
GEdit.spin_button ~value:2. ~adjustment:depth_forward_adj ()
in
let depth_backward_spin =
GEdit.spin_button ~value:2. ~adjustment:depth_backward_adj ()
in
depth_hbox#pack ~from:`END depth_backward_spin#coerce;
depth_hbox#pack ~from:`END depth_backward_label#coerce;
depth_hbox#pack ~from:`END depth_forward_spin#coerce;
depth_hbox#pack ~from:`END depth_forward_label#coerce;
depth_hbox#pack ~from:`END depth_label#coerce;
main_table, view
(* FROM GRAPH *)
module HString = struct
type t = string
let equal = (=)
let hash = Hashtbl.hash
end
module Build
(G: Sig.G)
(T: DGraphTreeModel.S with type Tree.V.label = G.V.t) =
struct
type graph = G.t
type vertex = G.V.t
type edge = G.E.t
module Tree = T.Tree
module HE(E: sig type t val compare: t -> t -> int end) = struct
type t = E.t
let equal x y = E.compare x y = 0
let hash = Hashtbl.hash
end
module GView = DGraphView.Make(G.V)(HE(G.E))(HString)
module TView = DGraphView.Make(Tree.V)(HE(Tree.E))(HString)
type global_view = (G.V.t, G.E.t, string) DGraphView.view
type tree_view = (Tree.V.t, Tree.E.t, string) DGraphView.view
class view_container
?packing
?(status=Global)
?(default_callbacks=true)
~mk_global_view
~mk_tree_view
default_tree_root
=
(* widgets *)
let paned_box = GPack.paned `VERTICAL ?packing () in
let global_frame = GBin.frame ~label:"Global View" () in
let tree_frame = GBin.frame ~label:"Tree View" () in
(* Callback functions *)
let connect_tree_callback view node =
let item = node#item in
let callback ev =
let apply f = match view#global_view with
| None -> false
| Some gview ->
let tree = T.tree () in
let vlist = T.TreeManipulation.get_graph_vertex item tree in
f (gview:global_view) (gview#get_node vlist);
false
in
match ev with
| `BUTTON_PRESS _ ->
(* clicking on a node of the tree view *)
view#set_tree_root (T.Tree.V.label item);
apply (fun v -> v#dehighlight)
| `MOTION_NOTIFY _ -> apply (fun v n -> v#highlight n)
| `LEAVE_NOTIFY _ -> apply (fun v -> v#dehighlight)
| _ -> false
in
node#connect_event ~callback
in
let connect_global_callback view node =
let item = node#item in
let callback ev =
let apply f = match view#tree_view with
| None -> false
| Some tview ->
let tree = T.tree () in
let vlist = T.TreeManipulation.get_tree_vertices item tree in
List.iter (fun v -> f (tview:tree_view) (tview#get_node v)) vlist;
false
in
match ev with
| `BUTTON_PRESS _ -> (* clicking on a node of the global view *)
(* Update the root of the tree view *)
view#set_tree_root node#item;
(* Center the global view on the selected node *)
begin match view#global_view with
| None -> ()
| Some w -> w#center_node node
end;
false
| `MOTION_NOTIFY _ -> apply (fun v n -> v#highlight n)
| `LEAVE_NOTIFY _ -> apply (fun v -> v#dehighlight)
|_ -> false
in
node#connect_event ~callback
in
object (self)
val mutable global_view: global_view option = None
val mutable tree_view: tree_view option = None
val mutable tree_change = false (* must recompute the tree? *)
val mutable tree_root = default_tree_root
val mutable status = status
val mutable depth_forward = 2
val mutable depth_backward = 2
(* Getters *)
method status = status
method global_view = global_view
method tree_view = tree_view
method tree_root = tree_root
method depth_forward = depth_forward
method depth_backward = depth_backward
(* Setters *)
method set_depth_forward i =
depth_forward <- i;
tree_change <- true;
self#update ()
method set_depth_backward i =
depth_backward <- i;
tree_change <- true;
self#update ()
method set_tree_root v =
tree_root <- Some v;
tree_change <- true;
self#update ()
method switch s =
status <- s;
self#update ()
(* Compute the views *)
method private memo_tree_view () =
if tree_change then begin
(match tree_view with
| None -> ()
| Some view ->
match view#misc#parent with
| Some parent -> tree_frame#remove parent
| None -> ()
);
match tree_root with
| None -> assert false
| Some r ->
let view =
mk_tree_view ~depth_backward ~depth_forward paned_box#as_widget r
in
tree_view <- Some view;
if default_callbacks then begin
view#connect_highlighting_event();
view#iter_nodes (connect_tree_callback self);
end;
let scroll =
GBin.scrolled_window
~hpolicy:`AUTOMATIC
~vpolicy:`AUTOMATIC
~packing:tree_frame#add
()
in
scroll#add view#coerce
end
method private memo_global_view () = match global_view with
| None ->
let view = mk_global_view () in
global_view <- Some view;
if default_callbacks then begin
view#connect_highlighting_event ();
view#iter_nodes (connect_global_callback self);
end;
let scroll =
GBin.scrolled_window
~hpolicy:`AUTOMATIC
~vpolicy:`AUTOMATIC
~packing:global_frame#add
()
in
scroll#add view#coerce
| Some _ ->
()
method adapt_zoom () =
let az = function
| None -> ()
| Some w -> w#adapt_zoom ()
in
az tree_view;
az global_view
method private add_global_view () =
self#memo_global_view ();
paned_box#pack1 global_frame#coerce
method private add_tree_view () =
self#memo_tree_view ();
paned_box#pack2 tree_frame#coerce
method private update () =
List.iter paned_box#remove paned_box#all_children;
(match status, tree_root with
| Global, _ | _, None -> self#add_global_view ()
| Tree, Some _ -> self#add_tree_view ()
| Both, Some _ -> self#add_global_view (); self#add_tree_view ())
initializer
self#update ()
end
end
module Make(G: Graphviz.GraphWithDotAttrs) = struct
module FullTreeModel = DGraphTreeModel.SubTreeMake(G)
include Build(G)(FullTreeModel)
module GlobalModel = DGraphModel.Make(G)
let from_graph
?packing
?status
?(default_callbacks=true)
?(mk_global_view = fun model -> GView.view ~aa:true model)
?(mk_tree_view = fun model -> TView.view ~aa:true model)
?root
g =
let status = match status with
| None ->
if G.nb_vertex g < 500 && G.nb_edges g < 2500 then Global else Tree
| Some s -> s
in
new view_container
?packing
~default_callbacks
~status
~mk_global_view:(fun () -> mk_global_view (GlobalModel.from_graph g))
~mk_tree_view:(fun ~depth_backward ~depth_forward w v ->
let context = GtkBase.Widget.create_pango_context w in
let fontMeasure = PangoMeasure.withContext ~context in
let model =
FullTreeModel.from_graph ~depth_forward ~depth_backward ~fontMeasure g v
in
mk_tree_view model)
root
let from_graph_with_commands ?packing ?status ?(default_callbacks=true) ?mk_global_view ?mk_tree_view ?root g =
with_commands
?packing
(fun ~packing g ->
from_graph
~packing ?status ~default_callbacks ?mk_global_view ?mk_tree_view
?root g)
g
end
(* FROM DOT *)
module Dot = struct
include Build(DGraphModel.DotG)(DGraphTreeModel.SubTreeDotModelMake)
exception Found of DGraphModel.DotG.V.t
let from_dot
?packing
?status
?(default_callbacks=true)
?(mk_global_view = fun model -> GView.view ~aa:true model)
?(mk_tree_view = fun model -> TView.view ~aa:true model)
dot_file =
let gmodel =
if Filename.check_suffix dot_file "xdot" then
DGraphModel.read_xdot dot_file
else
DGraphModel.read_dot dot_file
in
let one_vertex =
try
gmodel#iter_vertex (fun v -> raise (Found v));
None
with Found v ->
Some v
in
let status = match status with
| None ->
let nb f =
let cpt = ref 0 in
f gmodel (fun _ -> incr cpt);
!cpt
in
if nb (fun g -> g#iter_vertex) < 500
&& nb (fun g -> g#iter_edges_e) < 2500
then Global
else Tree
| Some s -> s
in
new view_container
?packing
~status
~default_callbacks
~mk_global_view:(fun () -> mk_global_view gmodel)
~mk_tree_view:(fun ~depth_backward ~depth_forward _ v ->
mk_tree_view
(DGraphTreeModel.SubTreeDotModelMake.from_model
~depth_forward
~depth_backward
gmodel
v))
one_vertex
let from_dot_with_commands ?packing ?status ?(default_callbacks=true) ?mk_global_view ?mk_tree_view dot_file =
with_commands
?packing
(fun ~packing d ->
from_dot
~packing ?status ~default_callbacks ?mk_global_view ?mk_tree_view d)
dot_file
end
ocamlgraph-2.0.0/dgraph/headers/ 0000755 0001750 0000144 00000000000 13735627615 015071 5 ustar rt users ocamlgraph-2.0.0/dgraph/headers/CEA_LGPL 0000644 0001750 0000144 00000001303 13735627615 016217 0 ustar rt users
This file is part of OcamlGraph.
Copyright (C) 2009-2010
CEA (Commissariat à l'Énergie Atomique)
you can redistribute it and/or modify it under the terms of the GNU
Lesser General Public License as published by the Free Software
Foundation, version 2.1, with a linking exception.
It 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. See the
GNU Lesser General Public License for more details.
See the file ../LICENSE for more details.
Authors:
- Julien Signoles (Julien.Signoles@cea.fr)
- Jean-Denis Koeck (jdkoeck@gmail.com)
- Benoit Bataille (benoit.bataille@gmail.com)
ocamlgraph-2.0.0/dgraph/headers/headache_config.txt 0000644 0001750 0000144 00000001424 13735627615 020702 0 ustar rt users # Objective Caml source
| ".*\\.mly" -> frame open:"/*" line:"*" close:"*/"
| ".*\\.ml[il4]?.*" -> frame open:"(*" line:"*" close:"*)"
# C source
| ".*\\.c" -> frame open:"/*" line:"*" close:"*/"
| ".*\\.ast" -> frame open:"//" line:" " close:" "
| ".*\\.cc" -> frame open:"/*" line:"*" close:"*/"
# Asm source
| ".*\\.S" -> frame open:"/*" line:"*" close:"*/"
# Configure
| "config\\.h\\.in" -> frame open:"/*" line:"*" close:"*/"
| "configure\\.in" -> frame open:"#" line:"#" close:"#"
# Makefile
| "Makefile" -> frame open:"#" line:"#" close:"#"
# Sh
| ".*\\.sh" -> frame open:"#" line:"#" close:"#"
# Misc
| "make_release" -> frame open:"#" line:"#" close:"#"
| "FAQ" -> frame open:"#" line:"#" close:"#"
| ".*\\.el" -> frame open: ";" line: ";" close:";"
ocamlgraph-2.0.0/dgraph/headers/headers.sh 0000755 0001750 0000144 00000000130 13735627615 017035 0 ustar rt users #! /bin/sh
headache -c headers/headache_config.txt -h headers/CEA_LGPL *.ml* *Makefile*
ocamlgraph-2.0.0/dgraph/dGraphViewItem.mli 0000644 0001750 0000144 00000012214 13735627615 017040 0 ustar rt users (**************************************************************************)
(* *)
(* This file is part of OcamlGraph. *)
(* *)
(* Copyright (C) 2009-2010 *)
(* CEA (Commissariat à l'Énergie Atomique) *)
(* *)
(* you can redistribute it and/or modify it under the terms of the GNU *)
(* Lesser General Public License as published by the Free Software *)
(* Foundation, version 2.1, with a linking exception. *)
(* *)
(* It 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. See the *)
(* GNU Lesser General Public License for more details. *)
(* *)
(* See the file ../LICENSE for more details. *)
(* *)
(* Authors: *)
(* - Julien Signoles (Julien.Signoles@cea.fr) *)
(* - Jean-Denis Koeck (jdkoeck@gmail.com) *)
(* - Benoit Bataille (benoit.bataille@gmail.com) *)
(* *)
(**************************************************************************)
(** View items for the different elements of a graph. *)
(* ********************************************************************** *)
(** {2 Shape} *)
(* ********************************************************************** *)
(** Shape properties *)
type shape_p = [ `FILL_COLOR_RGBA of int32
| `OUTLINE_COLOR_RGBA of int32
| `WIDTH_UNITS of float
| `DASH of float * float array ]
class type textshape = object
method highlight: ?color:int32 * int32 -> unit -> unit
(** Change the color of the text. May be cancelled by [dehighlight].
If [color] is [primary,secondary], then
[primary] is used except if the current color is [primary]. In this
case, [secondary] is used. *)
method dehighlight: unit -> unit
(** Cancel [highlight]. *)
method hide: unit -> unit
method show: unit -> unit
method lower_to_bottom: unit -> unit
method connect:
< event : callback:(GnoCanvas.item_event -> bool) -> GtkSignal.id;
after : GnoCanvas.item_signals;
destroy : callback:(unit -> unit) -> GtkSignal.id; >
end
class type shape = object
inherit GnoCanvas.base_item
inherit textshape
val obj : GnomeCanvas.item Gtk.obj
method set: shape_p list -> unit
end
(* ********************************************************************** *)
(** {2 Text} *)
(* ********************************************************************** *)
(** Derived text class. *)
class graph_text :
GnomeCanvas.text Gtk.obj ->
size_points:float ->
props:GnomeCanvas.text_p list ->
object
inherit GnoCanvas.text
inherit textshape
method resize: float -> unit
end
(* ********************************************************************** *)
(** {2 View items} *)
(* ********************************************************************** *)
class type common_view = object
inherit GnoCanvas.canvas
method zoom_factor : float
method adapt_zoom : unit -> unit
end
(** ViewItem class.
Group of shapes and texts *)
class ['a ] view_item :
fill:bool ->
delay:bool (** May the item be displayed non instantaneously? *) ->
view:common_view ->
pos:float * float ->
ops_list:XDotDraw.operation list list ->
item:'a ->
object
inherit GnoCanvas.group
method item: 'a
method zoom_text: float -> unit
method highlight: ?color: int32 * int32 -> unit -> unit
(** Change the color of the item. May be cancelled by [dehighlight].
If [color] is [primary,secondary], then
[primary] is used except if the current color is [primary]. In this
case, [secondary] is used. *)
method dehighlight: unit -> unit
(** Cancel [highlight]. *)
method show : unit -> unit
method hide : unit -> unit
method center : unit -> unit
method connect_event: callback:(GnoCanvas.item_event -> bool) -> unit
method compute: unit -> unit (** apply all delayed operations *)
method lower_to_bottom: unit -> unit
end
exception Cannot_convert_color of string
val view_node:
delay:bool ->
view:common_view ->
vertex:'vertex ->
layout:XDot.node_layout ->
unit ->
'vertex view_item
val view_edge:
delay:bool ->
view:common_view ->
edge:'edge ->
layout:XDot.edge_layout ->
unit ->
'edge view_item
val view_cluster:
delay:bool ->
view:common_view ->
cluster:'cluster ->
layout:XDot.cluster_layout ->
unit ->
'cluster view_item
ocamlgraph-2.0.0/dgraph/doc/ 0000755 0001750 0000144 00000000000 13735627615 014223 5 ustar rt users ocamlgraph-2.0.0/dgraph/doc/style.css 0000755 0001750 0000144 00000004331 13735627615 016101 0 ustar rt users a:visited {color : #416DFF; text-decoration : none; }
a:link {color : #416DFF; text-decoration : none;}
a:hover {color : Red; text-decoration : none; background-color: #5FFF88}
a:active {color : Red; text-decoration : underline; }
.keyword { font-weight : bold ; color : Red }
.keywordsign { color : #C04600 }
.superscript { font-size : 4 }
.subscript { font-size : 4 }
.comment { color : Green }
.constructor { color : Blue }
.type { color : #5C6585 }
.string { color : Maroon }
.warning { color : Red ; font-weight : bold }
.info { margin-left : 3em; margin-right : 3em }
.param_info { margin-top: 4px; margin-left : 3em; margin-right : 3em }
.code { color : #465F91 ; }
h1 { font-size : 20pt ; text-align: center; }
h2 { font-size : 20pt ; border: 1px solid #000000; margin-top: 5px; margin-bottom: 2px;text-align: center; background-color: #90BDFF ;padding: 2px; }
h3 { font-size : 20pt ; border: 1px solid #000000; margin-top: 5px; margin-bottom: 2px;text-align: center; background-color: #90DDFF ;padding: 2px; }
h4 { font-size : 20pt ; border: 1px solid #000000; margin-top: 5px; margin-bottom: 2px;text-align: center; background-color: #90EDFF ;padding: 2px; }
h5 { font-size : 20pt ; border: 1px solid #000000; margin-top: 5px; margin-bottom: 2px;text-align: center; background-color: #90FDFF ;padding: 2px; }
h6 { font-size : 20pt ; border: 1px solid #000000; margin-top: 5px; margin-bottom: 2px;text-align: center; background-color: #C0FFFF ; padding: 2px; }
div.h7 { font-size : 20pt ; border: 1px solid #000000; margin-top: 5px; margin-bottom: 2px;text-align: center; background-color: #E0FFFF ; padding: 2px; }
div.h8 { font-size : 20pt ; border: 1px solid #000000; margin-top: 5px; margin-bottom: 2px;text-align: center; background-color: #F0FFFF ; padding: 2px; }
div.h9 { font-size : 20pt ; border: 1px solid #000000; margin-top: 5px; margin-bottom: 2px;text-align: center; background-color: #FFFFFF ; padding: 2px; }
.typetable { border-style : hidden }
.indextable { border-style : hidden }
.paramstable { border-style : hidden ; padding: 5pt 5pt}
body { background-color : White }
tr { background-color : White }
td.typefieldcomment { background-color : #FFFFFF ; font-size: smaller ;}
pre { margin-bottom: 4px }
div.sig_block {margin-left: 2em} ocamlgraph-2.0.0/dgraph/dune 0000644 0001750 0000144 00000000446 13735627615 014340 0 ustar rt users (library
(name graph_gtk)
(public_name ocamlgraph_gtk)
(modules :standard \ dGraphViewer)
(libraries ocamlgraph stdlib-shims lablgtk2.gnomecanvas lablgtk2)
(flags -open Graph))
(executable
(name dGraphViewer)
(modules dGraphViewer)
(libraries graph_gtk lablgtk2.gnomecanvas lablgtk2))
ocamlgraph-2.0.0/dgraph/dGraphView.mli 0000644 0001750 0000144 00000012633 13735627615 016226 0 ustar rt users (**************************************************************************)
(* *)
(* This file is part of OcamlGraph. *)
(* *)
(* Copyright (C) 2009-2010 *)
(* CEA (Commissariat à l'Énergie Atomique) *)
(* *)
(* you can redistribute it and/or modify it under the terms of the GNU *)
(* Lesser General Public License as published by the Free Software *)
(* Foundation, version 2.1, with a linking exception. *)
(* *)
(* It 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. See the *)
(* GNU Lesser General Public License for more details. *)
(* *)
(* See the file ../LICENSE for more details. *)
(* *)
(* Authors: *)
(* - Julien Signoles (Julien.Signoles@cea.fr) *)
(* - Jean-Denis Koeck (jdkoeck@gmail.com) *)
(* - Benoit Bataille (benoit.bataille@gmail.com) *)
(* *)
(**************************************************************************)
(** View classes.
Each optional function [delay_node], [delay_edge] and [delay_cluster] of
this module may be used to indicate whether an element must be displayed
instantaneously (if the function returns [false]) or may be delayed for
latter display (if the function returns [true]). By default, each function
always returns [false]. It may be set for returning [true] from time to
time, improving efficiency. *)
open DGraphViewItem
(** Graph widget derived from [GnoCanvas.canvas].
Support zooming and scrolling. *)
class type ['vertex, 'edge, 'cluster] view = object
inherit GnoCanvas.canvas
method model : ('vertex, 'edge, 'cluster) DGraphModel.abstract_model
(** {2 Getters} *)
method get_node : 'vertex -> 'vertex view_item
method get_edge : 'edge -> 'edge view_item
method get_cluster : 'cluster -> 'cluster view_item
(** {2 Iterators} *)
method iter_nodes: ('vertex view_item -> unit) -> unit
method iter_edges: ('vertex view_item -> 'vertex view_item -> unit) -> unit
method iter_edges_e: ('edge view_item -> unit) -> unit
method iter_clusters: ('cluster view_item -> unit) -> unit
method iter_succ: ('vertex view_item -> unit) -> 'vertex view_item -> unit
method iter_pred: ('vertex view_item -> unit) -> 'vertex view_item -> unit
method iter_succ_e: ('edge view_item -> unit) -> 'vertex view_item -> unit
method iter_pred_e: ('edge view_item -> unit) -> 'vertex view_item -> unit
(* Benoit Bataille's method: is it really useful? *)
method iter_associated_vertex:
('vertex view_item -> unit) -> 'vertex view_item -> unit
(** {2 Membership functions} *)
method mem_edge: 'vertex view_item -> 'vertex view_item -> bool
method find_edge: 'vertex view_item -> 'vertex view_item -> 'edge view_item
method src: 'edge view_item -> 'vertex view_item
method dst: 'edge view_item -> 'vertex view_item
(** {2 Zooming} *)
method zoom_factor : float
(** The current zoom factor.*)
method zoom_to : float -> unit
(** Set an absolute zoom factor.*)
method zoom_in : unit -> unit
(** Increase [zoom_factor] by [zoom_factor*zoom_padding].*)
method zoom_out : unit -> unit
(** Decrease [zoom_factor] by [zoom_factor*zoom_padding].*)
method adapt_zoom : unit -> unit
(** Zoom in order to view the whole graph (bird eye view). *)
method set_zoom_padding: float -> unit
(** Set the zoom padding used by [zoom_in] and [zoom_out].
It defaults to 0.1. *)
method center_node: 'vertex view_item -> unit
(** Center canvas on a node. *)
(** {2 Highlighting} *)
method connect_highlighting_event: unit -> unit
method highlight: ?color: int32 * int32 -> 'vertex view_item -> unit
(** Change the color of the given vertex item.
May be cancelled by [dehighlight].
If [color] is [primary,secondary], then
[primary] is used except if the current color is [primary]. In this
case, [secondary] is used. *)
method dehighlight: 'vertex view_item -> unit
(** Cancel [highlight]. *)
end
module type S = sig
type vertex
type edge
type cluster
val view:
?aa:bool (** Anti-aliasing *) ->
?delay_node:(vertex -> bool) ->
?delay_edge:(edge -> bool) ->
?delay_cluster:(cluster -> bool) ->
?border_width:int ->
?width:int ->
?height:int ->
?packing:(GObj.widget -> unit) ->
?show:bool ->
(vertex, edge, cluster) DGraphModel.abstract_model ->
(vertex, edge, cluster) view
(** View as a Gnome Canvas.
Support zooming and scrolling. *)
end
module Make(V: Sig.HASHABLE)(E: Sig.HASHABLE)(C: Sig.HASHABLE) :
S with type vertex = V.t and type edge = E.t and type cluster = C.t
ocamlgraph-2.0.0/dgraph/pangoMeasure.ml 0000644 0001750 0000144 00000000567 13735627615 016446 0 ustar rt users let withContext ~context ~fontName ~fontSize text =
let font_description = Pango.Font.from_string fontName in
Pango.Font.modify font_description
~size:(fontSize * Pango.scale)
();
Pango.Context.set_font_description context font_description;
let layout = Pango.Layout.create context in
Pango.Layout.set_text layout text;
Pango.Layout.get_pixel_size layout
ocamlgraph-2.0.0/dgraph/pangoMeasure.mli 0000644 0001750 0000144 00000000141 13735627615 016603 0 ustar rt users val withContext : context:Pango.context -> fontName:string -> fontSize:int -> string -> int * int ocamlgraph-2.0.0/dgraph/examples/ 0000755 0001750 0000144 00000000000 13735627615 015274 5 ustar rt users ocamlgraph-2.0.0/dgraph/examples/siblings.dot 0000755 0001750 0000144 00000073643 13735627615 017636 0 ustar rt users /*
This is a graphviz-produced layout of the "family tree" of a fraternity and sorority.
Each member in the graph was assigned a "big brother" from one organization and a "big sister" from the other. Blue icons represent Brothers from the fraternity, Pink represents Sisters from the sorority (Purple members are in both organizations - like honoraries.)
Charter members (who can have no parent nodes) are outlined.
...
dot -Tgif -Goverlap=false -o siblings.gif siblings.dot
We're experimenting with different ways of coloring and graphing, but found this the easiest for now. When we have more people in, we might look at different shades depending on generation number -- earlier people would get lighter colors, more recent members darker. Thumbnail images would be an interesting alteration as well.
from Japheth Cleaver
*/
digraph sdsu {
size="36,36";
node [color=grey, style=filled];
node [fontname="Verdana", size="30,30"];
graph [ fontname = "Arial",
fontsize = 36,
style = "bold",
label = "\nKappa Kappa Psi/Tau Beta Sigma\nSan Diego State University\nEta Mu and Zeta Xi Family Tree\n\nto date: November 30th, 2008\n",
ssize = "30,60" ];
"Lori Brede" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=10"];
"Michael Griffith" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=24"];
"Amie Holston" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=30"];
"Michael Griffith" -> "Lori Brede"
"Amie Holston" -> "Lori Brede"
"Casey Carter" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=11"];
"Laura De'Armond" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=14"];
"Laura De'Armond" -> "Casey Carter"
"Japheth Cleaver" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=12"];
"Chuk Gawlik" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=22"];
"Stacy Snyder" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=309"];
"Chuk Gawlik" -> "Japheth Cleaver"
"Stacy Snyder" -> "Japheth Cleaver"
"Jillian Clifton" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=13"];
"David Guthrie" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=25"];
"David Guthrie" -> "Jillian Clifton"
"Japheth Cleaver" -> "Jillian Clifton"
"Tony Sacco" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=55"];
"Heather Smith" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=59"];
"Tony Sacco" -> "Laura De'Armond"
"Heather Smith" -> "Laura De'Armond"
"Kevin Decker" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=15"];
"Alex Hansen" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=26"];
"Wanda Livelsberger" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=53"];
"Alex Hansen" -> "Kevin Decker"
"Wanda Livelsberger" -> "Kevin Decker"
"Patrick Doerr" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=16"];
"Deanna Jagow" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=23"];
"Alex Hansen" -> "Patrick Doerr"
"Deanna Jagow" -> "Patrick Doerr"
"Lori Asaro" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=178"];
"Mark Pearson" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=169"];
"Lori Ball" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=167"];
"Mark Pearson" -> "Lori Asaro"
"Lori Ball" -> "Lori Asaro"
"Ryan Farris" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=18"];
"Rob Reiner" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=51"];
"Cindy Teel" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=62"];
"Rob Reiner" -> "Ryan Farris"
"Cindy Teel" -> "Ryan Farris"
"Ginger Palmer" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=180"];
"Mark Newton-John" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=46"];
"Mark Newton-John" -> "Ginger Palmer"
"Matthew FitzGerald" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=19"];
"Mervin Maniago" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=41"];
"Mervin Maniago" -> "Matthew FitzGerald"
"Amie Holston" -> "Matthew FitzGerald"
"Tani Miller" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=195"];
"Mark Pearson" -> "Tani Miller"
"Vienna McMurtry" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=196"];
"Robert Walwick" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=153"];
"Robert Walwick" -> "Vienna McMurtry"
"Ginger Palmer" -> "Vienna McMurtry"
"Chuck Foster" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=20"];
"Karen Saye" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=56"];
"Kevin Decker" -> "Chuck Foster"
"Karen Saye" -> "Chuck Foster"
"Gary Frampton" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=201"];
"Ginger Palmer" -> "Gary Frampton"
"Pat Norris" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=207"];
"Sean Tipps" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=204"];
"Teresa Long" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=194"];
"Sean Tipps" -> "Pat Norris"
"Teresa Long" -> "Pat Norris"
"Marc Martin-ez" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=208"];
"Mark Pearson" -> "Marc Martin-ez"
"Tani Miller" -> "Marc Martin-ez"
"Kristen Villone" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=209"];
"Kelly Erickson" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=199"];
"Anna Pedroza" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=197"];
"Kelly Erickson" -> "Kristen Villone"
"Anna Pedroza" -> "Kristen Villone"
"Geoff Frank" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=21"];
"Chris Livelsberger" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=40"];
"Amy Price" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=57"];
"Chris Livelsberger" -> "Geoff Frank"
"Amy Price" -> "Geoff Frank"
"Tracy Murray" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=210"];
"John FitzGibbon" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=92"];
"Judy Dulcich" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=177"];
"John FitzGibbon" -> "Tracy Murray"
"Judy Dulcich" -> "Tracy Murray"
"Ian McIntosh" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=215"];
"Barbara Tollison" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=172"];
"Robert Walwick" -> "Ian McIntosh"
"Barbara Tollison" -> "Ian McIntosh"
"Jayson Smith" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=58"];
"Jayson Smith" -> "Chuk Gawlik"
"Heather Smith" -> "Chuk Gawlik"
"Kelly McKinney" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=222"];
"Mark Nadeau" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=183"];
"Mark Nadeau" -> "Kelly McKinney"
"Judy Dulcich" -> "Kelly McKinney"
"Chris Livelsberger" -> "Deanna Jagow"
"Amy Price" -> "Deanna Jagow"
"Renee Thompson" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=231"];
"J. Angeles" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=3"];
"Kelley Smith" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=223"];
"J. Angeles" -> "Renee Thompson"
"Kelley Smith" -> "Renee Thompson"
"Steven Smith" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=233"];
"John FitzGibbon" -> "Steven Smith"
"Charlene Andrews" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=234"];
"Diane Reoch" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=227"];
"Diane Reoch" -> "Charlene Andrews"
"Tonya Alexander" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=238"];
"Gail Vasquez" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=225"];
"Gail Vasquez" -> "Tonya Alexander"
"Spencer Caldwell" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=239"];
"Becky Bernal" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=218"];
"Becky Bernal" -> "Spencer Caldwell"
"Chuk Gawlik" -> "Michael Griffith"
"Wanda Livelsberger" -> "Michael Griffith"
"Russell Grant" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=242"];
"Steven Smith" -> "Russell Grant"
"Tiffany Worthington" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=66"];
"Chuck Foster" -> "David Guthrie"
"Tiffany Worthington" -> "David Guthrie"
"Jerry Maya" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=250"];
"John FitzGibbon" -> "Jerry Maya"
"Melissa Schwartz" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=252"];
"Russell Grant" -> "Melissa Schwartz"
"Delphy Shaulis" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=255"];
"Renee Thompson" -> "Delphy Shaulis"
"Martin Naiman" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=45"];
"Janean Angeles" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=86"];
"Martin Naiman" -> "Alex Hansen"
"Janean Angeles" -> "Alex Hansen"
"Leslie Harlow" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=265"];
"Dennis McColl" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=251"];
"Denise Luna" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=236"];
"Dennis McColl" -> "Leslie Harlow"
"Denise Luna" -> "Leslie Harlow"
"Jonathan Yudman" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=267"];
"April Ortiz-cloninger" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=258"];
"April Ortiz-cloninger" -> "Jonathan Yudman"
"Michael Elgo" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=268"];
"Carol Kropp" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=254"];
"Spencer Caldwell" -> "Michael Elgo"
"Carol Kropp" -> "Michael Elgo"
"Denmark Vea" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=269"];
"Marc Martin-ez" -> "Denmark Vea"
"Kelley Smith" -> "Denmark Vea"
"Kathleen Hansen" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=27"];
"Martin Naiman" -> "Kathleen Hansen"
"Heather Smith" -> "Kathleen Hansen"
"Laura Stegner" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=274"];
"April Ortiz-cloninger" -> "Laura Stegner"
"Kathy Jones" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=28"];
"J. Angeles" -> "Kathy Jones"
"Eric Gates" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=282"];
"Erick Sugimura" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=280"];
"Erick Sugimura" -> "Eric Gates"
"Laura Stegner" -> "Eric Gates"
"Jennifer Stoewe" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=288"];
"Eric Gates" -> "Jennifer Stoewe"
"Karen Helbling" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=29"];
"Regan Ashker" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=5"];
"Kevin Decker" -> "Karen Helbling"
"Regan Ashker" -> "Karen Helbling"
"Scott Wood" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=295"];
"Eric Gates" -> "Scott Wood"
"Greg Flood" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=200"];
"Greg Flood" -> "J. Angeles"
"Ginger Palmer" -> "J. Angeles"
"Lynn Reeves" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=48"];
"Chuk Gawlik" -> "Amie Holston"
"Lynn Reeves" -> "Amie Holston"
"Susan Colwell" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=302"];
"Michael Elgo" -> "Susan Colwell"
"Christopher Jouan" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=306"];
"Kevin Owens" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=245"];
"Kevin Owens" -> "Christopher Jouan"
"Kristianna Reynante" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=308"];
"Michael Elgo" -> "Kristianna Reynante"
"Janean Angeles" -> "Kristianna Reynante"
"Amy Berner" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=300"];
"Amy Berner" -> "Stacy Snyder"
"Deanna Johnson" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=31"];
"Alex Hansen" -> "Deanna Johnson"
"Laura De'Armond" -> "Deanna Johnson"
"Johnny Richardson" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=310"];
"Russell Grant" -> "Johnny Richardson"
"Nathan Fellhauer" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=313"];
"James Rowland" [color=thistle, URL="http://sdsu.kkytbs.net/members/profile.html?who=52"];
"James Rowland" -> "Nathan Fellhauer"
"Kristianna Reynante" -> "Nathan Fellhauer"
"Brian Raneses" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=314"];
"Sean McHenry" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=42"];
"Sean McHenry" -> "Brian Raneses"
"Penny Lewis" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=315"];
"Martin Naiman" -> "Penny Lewis"
"Becky Graham" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=316"];
"Kristen Elgo" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=7"];
"Kristen Elgo" -> "Becky Graham"
"Steven Gross" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=318"];
"Rob Reiner" -> "Steven Gross"
"Stacy Snyder" -> "Steven Gross"
"Sedona Reynolds" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=32"];
"Mark Newton-John" -> "Sedona Reynolds"
"Cindy Teel" -> "Sedona Reynolds"
"Klair Mayerchak" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=320"];
"Nathan Fellhauer" -> "Klair Mayerchak"
"Becky Graham" -> "Klair Mayerchak"
"Shari VerBerkmoes" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=321"];
"Sean McHenry" -> "Shari VerBerkmoes"
"Janean Angeles" -> "Shari VerBerkmoes"
"Anson Summers" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=326"];
"James Rowland" -> "Anson Summers"
"Dusty Jolliff" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=33"];
"Rob Reiner" -> "Dusty Jolliff"
"Stacy Snyder" -> "Dusty Jolliff"
"Jennifer Garman" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=331"];
"James Rowland" -> "Jennifer Garman"
"Kelly Greenhill" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=333"];
"Rob Reiner" -> "Kelly Greenhill"
"Kristen Elgo" -> "Kelly Greenhill"
"Lucinda Farless" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=334"];
"J. Angeles" -> "Lucinda Farless"
"Susan Colwell" -> "Lucinda Farless"
"Alfredo Cardenas" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=335"];
"Chuk Gawlik" -> "Alfredo Cardenas"
"Kathleen Hansen" -> "Alfredo Cardenas"
"Jennifer Jouan" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=34"];
"Andrea Owens" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=276"];
"Andrea Owens" -> "Jennifer Jouan"
"Tamara Scrivner" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=345"];
"Joseph Butler" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=69"];
"Sarah Maltese" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=83"];
"Joseph Butler" -> "Tamara Scrivner"
"Sarah Maltese" -> "Tamara Scrivner"
"Bradley Stouse" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=346"];
"Ryan Underwood" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=74"];
"Ryan Underwood" -> "Bradley Stouse"
"Cindy Teel" -> "Bradley Stouse"
"Casondra Brimmage" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=347"];
"Kristopher Lininger" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=85"];
"Ilana Melcher" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=73"];
"Kristopher Lininger" -> "Casondra Brimmage"
"Ilana Melcher" -> "Casondra Brimmage"
"Cassiopeia Guthrie" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=348"];
"Jeremy Frazier" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=79"];
"Christine Mount" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=76"];
"Jeremy Frazier" -> "Cassiopeia Guthrie"
"Christine Mount" -> "Cassiopeia Guthrie"
"Kathleen Moran" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=349"];
"Matthew FitzGerald" -> "Kathleen Moran"
"Lori Brede" -> "Kathleen Moran"
"Tiffany Kalland" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=35"];
"Tony Sacco" -> "Tiffany Kalland"
"Karen Helbling" -> "Tiffany Kalland"
"Kristen Anderson" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=350"];
"Jennie Bogart" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=78"];
"David Guthrie" -> "Kristen Anderson"
"Jennie Bogart" -> "Kristen Anderson"
"Laura Simonette" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=351"];
"Jon Weisel" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=89"];
"Jon Weisel" -> "Laura Simonette"
"Japheth Cleaver" -> "Laura Simonette"
"Nathan Williams" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=352"];
"David Guthrie" -> "Nathan Williams"
"Karen Helbling" -> "Nathan Williams"
"Rebecca Hippert" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=353"];
"Ryan Underwood" -> "Rebecca Hippert"
"Tiffany Kalland" -> "Rebecca Hippert"
"Samuel Wallace" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=354"];
"Joseph Butler" -> "Samuel Wallace"
"Deanna Jagow" -> "Samuel Wallace"
"Scott Gardner" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=355"];
"Jeremy Frazier" -> "Scott Gardner"
"Christine Mount" -> "Scott Gardner"
"Alberto Ayon" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=356"];
"Bradley Stouse" -> "Alberto Ayon"
"Jennie Bogart" -> "Alberto Ayon"
"Susannah Clayton" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=357"];
"Nathan Williams" -> "Susannah Clayton"
"Karen Helbling" -> "Susannah Clayton"
"Lisa Gochnauer" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=358"];
"Scott Gardner" -> "Lisa Gochnauer"
"Casondra Brimmage" -> "Lisa Gochnauer"
"Jamie Jackson" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=359"];
"Samuel Wallace" -> "Jamie Jackson"
"Tamara Scrivner" -> "Jamie Jackson"
"Christina Kelly" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=36"];
"Matthew FitzGerald" -> "Christina Kelly"
"Lori Brede" -> "Christina Kelly"
"Gara Thornton" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=360"];
"Mark Newton-John" -> "Gara Thornton"
"Laura Simonette" -> "Gara Thornton"
"Robert Winebarger" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=361"];
"Robin Ellison" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=90"];
"Scott Gardner" -> "Robert Winebarger"
"Robin Ellison" -> "Robert Winebarger"
"Jeremy Kirchner" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=37"];
"Rob Reiner" -> "Jeremy Kirchner"
"Sandy Konar" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=38"];
"Jennifer Brandon" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=9"];
"Jennifer Brandon" -> "Sandy Konar"
"Dan Kuhlman" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=39"];
"Rob Reiner" -> "Dan Kuhlman"
"Dusty Jolliff" -> "Dan Kuhlman"
"Lindsay Arehart" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=4"];
"Martin Naiman" -> "Lindsay Arehart"
"Jennifer Brandon" -> "Lindsay Arehart"
"J. Angeles" -> "Mervin Maniago"
"Kathy Jones" -> "Mervin Maniago"
"Jarrod Monroe" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=43"];
"Jamie Fratacci" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=44"];
"Mark Newton-John" -> "Jarrod Monroe"
"Jamie Fratacci" -> "Jarrod Monroe"
"Chuk Gawlik" -> "Jamie Fratacci"
"Tiffany Worthington" -> "Jamie Fratacci"
"Russell Grant" -> "Martin Naiman"
"Tonya Alexander" -> "Martin Naiman"
"Edward Givens" [color=lightblue, outline=bold, style=bold, URL="http://sdsu.kkytbs.net/members/profile.html?who=106"];
"Edward Givens" -> "Mark Newton-John"
"Veronica Nickel" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=47"];
"Regan Ashker" -> "Veronica Nickel"
"Wanda Livelsberger" -> "Lynn Reeves"
"Bryan Ransom" [color=thistle, URL="http://sdsu.kkytbs.net/members/profile.html?who=49"];
"Jayson Smith" -> "Bryan Ransom"
"Tony Sacco" -> "Regan Ashker"
"Dusty Jolliff" -> "Regan Ashker"
"Jennifer Stout" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=50"];
"Matthew FitzGerald" -> "Jennifer Stout"
"Deanna Jagow" -> "Jennifer Stout"
"Sean McHenry" -> "James Rowland"
"James Rowland" -> "Wanda Livelsberger"
"Janean Angeles" -> "Wanda Livelsberger"
"Melissa Roy" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=54"];
"Mervin Maniago" -> "Melissa Roy"
"Christina Kelly" -> "Melissa Roy"
"Dennis McColl" -> "Tony Sacco"
"April Ortiz-cloninger" -> "Tony Sacco"
"Tony Sacco" -> "Karen Saye"
"Tony Sacco" -> "Amy Price"
"Kathleen Hansen" -> "Amy Price"
"James Rowland" -> "Jayson Smith"
"Brian Raneses" -> "Heather Smith"
"Kristen Elgo" -> "Heather Smith"
"Josh Atwood" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=6"];
"David Guthrie" -> "Josh Atwood"
"Lori Brede" -> "Josh Atwood"
"Katie Browne" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=60"];
"Patrick Doerr" -> "Katie Browne"
"Jamie Fratacci" -> "Katie Browne"
"Kristin Tang" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=61"];
"James Rowland" -> "Kristin Tang"
"Heather Smith" -> "Kristin Tang"
"Mervin Maniago" -> "Cindy Teel"
"Veronica Nickel" -> "Cindy Teel"
"Mike Tulumello" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=63"];
"Matthew FitzGerald" -> "Mike Tulumello"
"Katie Browne" -> "Mike Tulumello"
"Veronica Villanueva" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=64"];
"Ryan Farris" -> "Veronica Villanueva"
"Sedona Reynolds" -> "Veronica Villanueva"
"Mervin Maniago" -> "Tiffany Worthington"
"Jennifer Jouan" -> "Tiffany Worthington"
"Scott Wright" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=67"];
"James Rowland" -> "Scott Wright"
"Kristen Elgo" -> "Scott Wright"
"Jeremy Browne" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=68"];
"Matthew FitzGerald" -> "Jeremy Browne"
"Japheth Cleaver" -> "Jeremy Browne"
"James Fogelman" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=688"];
"Alberto Ayon" -> "James Fogelman"
"Susannah Clayton" -> "James Fogelman"
"Sandra Chase" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=689"];
"David Guthrie" -> "Sandra Chase"
"Japheth Cleaver" -> "Sandra Chase"
"Patrick Doerr" -> "Joseph Butler"
"Deanna Jagow" -> "Joseph Butler"
"Laura Fisher" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=690"];
"Nathan Williams" -> "Laura Fisher"
"Casondra Brimmage" -> "Laura Fisher"
"Katie Kozma" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=691"];
"Scott Wright" -> "Katie Kozma"
"Robin Ellison" -> "Katie Kozma"
"Rachel Perkins" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=692"];
"Joseph Butler" -> "Rachel Perkins"
"Cassiopeia Guthrie" -> "Rachel Perkins"
"Sarah Titilah" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=693"];
"Robert Winebarger" -> "Sarah Titilah"
"Karen Helbling" -> "Sarah Titilah"
"Ashley Rehart" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=694"];
"Laura Fisher" -> "Ashley Rehart"
"Cara Yancey" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=695"];
"Katie Kozma" -> "Cara Yancey"
"Ashley Presley" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=698"];
"Cara Yancey" -> "Ashley Presley"
"Leila Wilhelm" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=699"];
"Robin Ellison" -> "Leila Wilhelm"
"Sean McHenry" -> "Kristen Elgo"
"Stacy Snyder" -> "Kristen Elgo"
"Greg Moody" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=70"];
"Ryan Farris" -> "Greg Moody"
"Jennifer Stout" -> "Greg Moody"
"Lisa Fleck" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=700"];
"Rachel Perkins" -> "Lisa Fleck"
"Christine Coyne" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=701"];
"Rachel Perkins" -> "Christine Coyne"
"Jennifer Cooley" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=702"];
"Laura Fisher" -> "Jennifer Cooley"
"Elizabeth Larios" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=703"];
"Ashley Rehart" -> "Elizabeth Larios"
"Cate Threlkeld" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=707"];
"Katie Kozma" -> "Cate Threlkeld"
"Erika Tapia" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=71"];
"Patrick Doerr" -> "Erika Tapia"
"Melissa Roy" -> "Erika Tapia"
"Robbyn Rozelle" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=72"];
"Jarrod Monroe" -> "Robbyn Rozelle"
"Tiffany Kalland" -> "Robbyn Rozelle"
"Ryan Farris" -> "Ilana Melcher"
"Veronica Villanueva" -> "Ilana Melcher"
"Greg Moody" -> "Ryan Underwood"
"Katie Browne" -> "Ryan Underwood"
"Cameron Brown" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=75"];
"Joseph Butler" -> "Cameron Brown"
"Tiffany Kalland" -> "Cameron Brown"
"Ryan Underwood" -> "Christine Mount"
"Lori Brede" -> "Christine Mount"
"Janay Rabe" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=77"];
"Greg Moody" -> "Janay Rabe"
"Cindy Teel" -> "Janay Rabe"
"Jeremy Browne" -> "Jennie Bogart"
"Tiffany Kalland" -> "Jennie Bogart"
"Ryan Farris" -> "Jeremy Frazier"
"Ilana Melcher" -> "Jeremy Frazier"
"Crystal Bozak" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=8"];
"Patrick Doerr" -> "Crystal Bozak"
"Katie Browne" -> "Crystal Bozak"
"Kameka Smith" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=80"];
"Matthew FitzGerald" -> "Kameka Smith"
"Ilana Melcher" -> "Kameka Smith"
"Kyra Sacco" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=81"];
"Joseph Butler" -> "Kyra Sacco"
"Robbyn Rozelle" -> "Kyra Sacco"
"Samuel Behar" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=82"];
"Ryan Underwood" -> "Samuel Behar"
"Lori Brede" -> "Samuel Behar"
"Patrick Doerr" -> "Sarah Maltese"
"Deanna Jagow" -> "Sarah Maltese"
"David Bronson" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=84"];
"Kristin Alongi-Hutchins" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=87"];
"Tony Sacco" -> "David Bronson"
"Kristin Alongi-Hutchins" -> "David Bronson"
"Cameron Brown" -> "Kristopher Lininger"
"Kameka Smith" -> "Kristopher Lininger"
"Rakan Abu-Rahma" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=852"];
"Christine Coyne" -> "Rakan Abu-Rahma"
"Jennifer Berry" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=270"];
"Jennifer Berry" -> "Janean Angeles"
"Penny Lewis" -> "Kristin Alongi-Hutchins"
"Melissa Bebak" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=88"];
"Greg Moody" -> "Melissa Bebak"
"Sarah Maltese" -> "Melissa Bebak"
"Scott Wright" -> "Jennifer Brandon"
"Japheth Cleaver" -> "Jennifer Brandon"
"Samuel Behar" -> "Robin Ellison"
"Kyra Sacco" -> "Robin Ellison"
"Teresa Simms" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=91"];
"Joseph Butler" -> "Teresa Simms"
"Janay Rabe" -> "Teresa Simms"
"Robert Schmidtke" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=188"];
"Jean Newman" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=166"];
"Robert Schmidtke" -> "John FitzGibbon"
"Jean Newman" -> "John FitzGibbon"
"Brittany DePew" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=928"];
"Elizabeth Larios" -> "Brittany DePew"
"Kathleen Halberg" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=929"];
"Ashley Rehart" -> "Kathleen Halberg"
"Terrance Hirsch" [color=lightblue, URL="http://sdsu.kkytbs.net/members/profile.html?who=96"];
"J. Angeles" -> "Terrance Hirsch"
"Susan Colwell" -> "Terrance Hirsch"
"Monique Arellano" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=972"];
"Ashley Presley" -> "Monique Arellano"
"Anthony Henderson" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=973"];
"Jennifer Cooley" -> "Anthony Henderson"
"Amethyst Tagle" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=974"];
"Cate Threlkeld" -> "Amethyst Tagle"
"Mallory Williams" [color=lightpink, URL="http://sdsu.kkytbs.net/members/profile.html?who=975"];
"Lisa Fleck" -> "Mallory Williams"
} ocamlgraph-2.0.0/dgraph/examples/polygonal.dot 0000644 0001750 0000144 00000000367 13735627615 020016 0 ustar rt users digraph G {
a -> b -> c;
b -> d;
a [shape=polygon,sides=5,peripheries=3,color=lightblue,style=filled];
c [shape=polygon,sides=4,skew=.4,label="hello world"]
d [shape=invtriangle];
e [shape=polygon,sides=4,distortion=.7];
}
ocamlgraph-2.0.0/dgraph/examples/clusters.svg 0000755 0001750 0000144 00000016232 13735627615 017670 0 ustar rt users
]>
G
cluster0
process #1
cluster1
process #2
a0
a0
a1
a1
a0->a1
a2
a2
a1->a2
b3
b3
a1->b3
a3
a3
a2->a3
a3->a0
end
end
a3->end
b0
b0
b1
b1
b0->b1
b2
b2
b1->b2
b2->a3
b2->b3
start
start
start->a0
start->b0
ocamlgraph-2.0.0/dgraph/examples/clusters_with_edges.dot 0000644 0001750 0000144 00000000475 13735627615 022060 0 ustar rt users digraph G {
compound=true;
subgraph cluster0 {
a -> b;
a -> c;
b -> d;
c -> d;
}
subgraph cluster1 {
e -> g;
e -> f;
}
b -> f [lhead=cluster1];
d -> e;
c -> g [ltail=cluster0,
lhead=cluster1];
c -> e [ltail=cluster0];
d -> h;
}
ocamlgraph-2.0.0/dgraph/examples/pmpipe.gv 0000755 0001750 0000144 00000006653 13735627615 017141 0 ustar rt users digraph g {
graph [
];
node [
fontsize = "14"
fontname = "Times-Roman"
fontcolor = "black"
shape = "box"
color = "black"
width = "0.5"
];
edge [
fontsize = "14"
fontname = "Times-Roman"
fontcolor = "black"
color = "black"
];
"23296" [
label = "23296\n?"
pname = "?"
kind = "proc"
];
"182948-1" [
label = "182948-1\n182949-1\npipe"
fontsize = "7"
fname = "pipe"
shape = "doublecircle"
subkind = "pipe"
kind = "file"
];
"23310" [
label = "23310\ncat"
pname = "cat"
kind = "proc"
];
"182950-1" [
label = "182950-1\n182951-1\npipe"
fontsize = "7"
fname = "pipe"
shape = "doublecircle"
subkind = "pipe"
kind = "file"
];
"23311" [
label = "23311\ncat"
pname = "cat"
kind = "proc"
];
"182952-1" [
label = "182952-1\n182953-1\npipe"
fontsize = "7"
fname = "pipe"
shape = "doublecircle"
subkind = "pipe"
kind = "file"
];
"23312" [
label = "23312\ncat"
pname = "cat"
kind = "proc"
];
"182954-1" [
label = "182954-1\n182955-1\npipe"
fontsize = "7"
fname = "pipe"
shape = "doublecircle"
subkind = "pipe"
kind = "file"
];
"23313" [
label = "23313\ncat"
pname = "cat"
kind = "proc"
];
"79893+2568" [
label = "79893+2568\n/usr/share/lib/termcap"
fname = "/usr/share/lib/termcap"
shape = "ellipse"
kind = "file"
];
"85+2560" [
label = "85+2560\n?"
fname = "?"
shape = "ellipse"
kind = "file"
];
"23314" [
label = "23314\ncat"
pname = "cat"
kind = "proc"
];
"4151865284+0" [
label = "4151865284+0\n/tmp/termcap"
fname = "/tmp/termcap"
shape = "ellipse"
kind = "file"
];
"23296" -> "23310" [
fontsize = "14"
fontname = "Times-Roman"
fontcolor = "black"
color = "black"
];
"23296" -> "23311" [
fontsize = "14"
fontname = "Times-Roman"
fontcolor = "black"
color = "black"
];
"23311" -> "182948-1" [
fontsize = "14"
fontname = "Times-Roman"
fontcolor = "black"
dir = "back"
color = "black"
];
"23310" -> "182948-1" [
fontsize = "14"
fontname = "Times-Roman"
fontcolor = "black"
dir = "forward"
color = "black"
];
"23296" -> "23312" [
fontsize = "14"
fontname = "Times-Roman"
fontcolor = "black"
color = "black"
];
"23312" -> "182952-1" [
fontsize = "14"
fontname = "Times-Roman"
fontcolor = "black"
dir = "forward"
color = "black"
];
"23312" -> "182950-1" [
fontsize = "14"
fontname = "Times-Roman"
fontcolor = "black"
dir = "back"
color = "black"
];
"23296" -> "23313" [
fontsize = "14"
fontname = "Times-Roman"
fontcolor = "black"
color = "black"
];
"23313" -> "182954-1" [
fontsize = "14"
fontname = "Times-Roman"
fontcolor = "black"
dir = "forward"
color = "black"
];
"23311" -> "182950-1" [
fontsize = "14"
fontname = "Times-Roman"
fontcolor = "black"
dir = "forward"
color = "black"
];
"23310" -> "79893+2568" [
fontsize = "14"
fontname = "Times-Roman"
fontcolor = "black"
dir = "back"
color = "black"
];
"23296" -> "85+2560" [
fontsize = "14"
fontname = "Times-Roman"
fontcolor = "black"
dir = "both"
color = "black"
];
"23296" -> "23314" [
fontsize = "14"
fontname = "Times-Roman"
fontcolor = "black"
color = "black"
];
"23314" -> "85+2560" [
fontsize = "14"
fontname = "Times-Roman"
fontcolor = "black"
dir = "both"
color = "black"
];
"23314" -> "182954-1" [
fontsize = "14"
fontname = "Times-Roman"
fontcolor = "black"
dir = "back"
color = "black"
];
"23296" -> "85+2560" [
fontsize = "14"
fontname = "Times-Roman"
fontcolor = "black"
dir = "both"
color = "black"
];
"23314" -> "4151865284+0" [
fontsize = "14"
fontname = "Times-Roman"
fontcolor = "black"
dir = "forward"
color = "black"
];
"23313" -> "182952-1" [
fontsize = "14"
fontname = "Times-Roman"
fontcolor = "black"
dir = "back"
color = "black"
];
}
ocamlgraph-2.0.0/dgraph/examples/clusters.dot 0000755 0001750 0000144 00000000621 13735627615 017652 0 ustar rt users digraph G {
subgraph cluster_0 {
style=filled;
color=lightgrey;
node [style=filled,color=white];
a0 -> a1 -> a2 -> a3;
label = "process #1";
}
subgraph cluster_1 {
node [style=filled];
b0 -> b1 -> b2 -> b3;
label = "process #2";
color=blue
}
start -> a0;
start -> b0;
a1 -> b3;
b2 -> a3;
a3 -> a0;
a3 -> end;
b3 -> end;
start [shape=Mdiamond];
end [shape=Msquare];
}
ocamlgraph-2.0.0/dgraph/examples/fsm.dot 0000755 0001750 0000144 00000001150 13735627615 016571 0 ustar rt users digraph finite_state_machine {
rankdir=LR;
size="8,5"
node [shape = doublecircle]; LR_0 LR_3 LR_4 LR_8;
node [shape = circle];
LR_0 -> LR_2 [ label = "SS(B)" ];
LR_0 -> LR_1 [ label = "SS(S)" ];
LR_1 -> LR_3 [ label = "S($end)" ];
LR_2 -> LR_6 [ label = "SS(b)" ];
LR_2 -> LR_5 [ label = "SS(a)" ];
LR_2 -> LR_4 [ label = "S(A)" ];
LR_5 -> LR_7 [ label = "S(b)" ];
LR_5 -> LR_5 [ label = "S(a)" ];
LR_6 -> LR_6 [ label = "S(b)" ];
LR_6 -> LR_5 [ label = "S(a)" ];
LR_7 -> LR_8 [ label = "S(b)" ];
LR_7 -> LR_5 [ label = "S(a)" ];
LR_8 -> LR_6 [ label = "S(b)" ];
LR_8 -> LR_5 [ label = "S(a)" ];
}
ocamlgraph-2.0.0/dgraph/examples/awilliams.gv 0000755 0001750 0000144 00000016211 13735627615 017620 0 ustar rt users digraph pvn {
ordering=out;
node_1 -> node_2;
node_1 [label="ID: 1\ntype: 48\nnbr out: 0\nnbr chi: 11"];
node_2 [label="ID: 2\ntype: 8\nnbr out: 0\nnbr chi: 0"];
node_1 -> node_3;
node_3 [label="ID: 3\ntype: 1\nnbr out: 0\nnbr chi: 0"];
node_1 -> node_4;
node_4 [label="ID: 4\ntype: 6\nnbr out: 0\nnbr chi: 0"];
node_1 -> node_5;
node_5 [label="ID: 5\ntype: 14\nnbr out: 0\nnbr chi: 0"];
node_1 -> node_6;
node_6 [label="ID: 6\ntype: 14\nnbr out: 0\nnbr chi: 0"];
node_1 -> node_7;
node_7 [label="ID: 7\ntype: 49\nnbr out: 0\nnbr chi: 0"];
node_7 -> node_8;
node_8 [label="ID: 8\ntype: 45\nnbr out: 2\nnbr chi: 0"];
node_8 -> node_9;
node_9 [label="ID: 9\ntype: 48\nnbr out: 0\nnbr chi: 4"];
node_9 -> node_10;
node_10 [label="ID: 10\ntype: 8\nnbr out: 0\nnbr chi: 0"];
node_9 -> node_11;
node_11 [label="ID: 11\ntype: 1\nnbr out: 0\nnbr chi: 0"];
node_9 -> node_12;
node_12 [label="ID: 12\ntype: 5\nnbr out: 0\nnbr chi: 0"];
node_9 -> node_13;
node_13 [label="ID: 13\ntype: 16\nnbr out: 0\nnbr chi: 0"];
node_8 -> node_14;
node_14 [label="ID: 14\ntype: 39\nnbr out: 1\nnbr chi: 0"];
node_14 -> node_15;
node_15 [label="ID: 15\ntype: 55\nnbr out: 0\nnbr chi: 0"];
node_15 -> node_16;
node_16 [label="ID: 16\ntype: 48\nnbr out: 0\nnbr chi: 3"];
node_16 -> node_17;
node_17 [label="ID: 17\ntype: 1\nnbr out: 0\nnbr chi: 0"];
node_16 -> node_18;
node_18 [label="ID: 18\ntype: 6\nnbr out: 0\nnbr chi: 0"];
node_16 -> node_19;
node_19 [label="ID: 19\ntype: 45\nnbr out: 1\nnbr chi: 0"];
node_19 -> node_20;
node_20 [label="ID: 20\ntype: 48\nnbr out: 0\nnbr chi: 5"];
node_20 -> node_21;
node_21 [label="ID: 21\ntype: 38\nnbr out: 0\nnbr chi: 0"];
node_20 -> node_22;
node_22 [label="ID: 22\ntype: 8\nnbr out: 0\nnbr chi: 0"];
node_20 -> node_23;
node_23 [label="ID: 23\ntype: 1\nnbr out: 0\nnbr chi: 0"];
node_20 -> node_24;
node_24 [label="ID: 24\ntype: 5\nnbr out: 0\nnbr chi: 0"];
node_20 -> node_25;
node_25 [label="ID: 25\ntype: 16\nnbr out: 0\nnbr chi: 0"];
node_19 -> node_26;
node_26 [label="ID: 26\ntype: 41\nnbr out: 12\nnbr chi: 0"];
node_26 -> node_27;
node_27 [label="ID: 27\ntype: 48\nnbr out: 0\nnbr chi: 5"];
node_27 -> node_28;
node_28 [label="ID: 28\ntype: 38\nnbr out: 0\nnbr chi: 0"];
node_27 -> node_29;
node_29 [label="ID: 29\ntype: 8\nnbr out: 0\nnbr chi: 0"];
node_27 -> node_30;
node_30 [label="ID: 30\ntype: 1\nnbr out: 0\nnbr chi: 0"];
node_27 -> node_31;
node_31 [label="ID: 31\ntype: 5\nnbr out: 0\nnbr chi: 0"];
node_27 -> node_32;
node_32 [label="ID: 32\ntype: 16\nnbr out: 0\nnbr chi: 0"];
node_26 -> node_27;
node_26 -> node_27;
node_26 -> node_27;
node_26 -> node_27;
node_26 -> node_27;
node_26 -> node_27;
node_26 -> node_27;
node_26 -> node_27;
node_26 -> node_27;
node_26 -> node_27;
node_26 -> node_27;
node_26 -> node_33;
node_33 [label="ID: 33\ntype: 48\nnbr out: 0\nnbr chi: 5"];
node_33 -> node_34;
node_34 [label="ID: 34\ntype: 38\nnbr out: 0\nnbr chi: 0"];
node_33 -> node_35;
node_35 [label="ID: 35\ntype: 14\nnbr out: 0\nnbr chi: 0"];
node_33 -> node_36;
node_36 [label="ID: 36\ntype: 14\nnbr out: 0\nnbr chi: 0"];
node_33 -> node_37;
node_37 [label="ID: 37\ntype: 20\nnbr out: 0\nnbr chi: 0"];
node_33 -> node_38;
node_38 [label="ID: 38\ntype: 16\nnbr out: 0\nnbr chi: 0"];
node_15 -> node_39;
node_39 [label="ID: 39\ntype: 45\nnbr out: 1\nnbr chi: 0"];
node_39 -> node_40;
node_40 [label="ID: 40\ntype: 16\nnbr out: 0\nnbr chi: 0"];
node_39 -> node_41;
node_41 [label="ID: 41\ntype: 48\nnbr out: 0\nnbr chi: 3"];
node_41 -> node_42;
node_42 [label="ID: 42\ntype: 14\nnbr out: 0\nnbr chi: 0"];
node_41 -> node_43;
node_43 [label="ID: 43\ntype: 1\nnbr out: 0\nnbr chi: 0"];
node_41 -> node_44;
node_44 [label="ID: 44\ntype: 6\nnbr out: 0\nnbr chi: 0"];
node_15 -> node_45;
node_45 [label="ID: 45\ntype: 48\nnbr out: 0\nnbr chi: 4"];
node_45 -> node_46;
node_46 [label="ID: 46\ntype: 14\nnbr out: 0\nnbr chi: 0"];
node_45 -> node_47;
node_47 [label="ID: 47\ntype: 45\nnbr out: 1\nnbr chi: 0"];
node_47 -> node_48;
node_48 [label="ID: 48\ntype: 14\nnbr out: 0\nnbr chi: 0"];
node_47 -> node_49;
node_49 [label="ID: 49\ntype: 14\nnbr out: 0\nnbr chi: 0"];
node_45 -> node_50;
node_50 [label="ID: 50\ntype: 14\nnbr out: 0\nnbr chi: 0"];
node_45 -> node_51;
node_51 [label="ID: 51\ntype: 45\nnbr out: 1\nnbr chi: 0"];
node_51 -> node_52;
node_52 [label="ID: 52\ntype: 45\nnbr out: 1\nnbr chi: 0"];
node_52 -> node_53;
node_53 [label="ID: 53\ntype: 54\nnbr out: 0\nnbr chi: 0"];
node_52 -> node_54;
node_54 [label="ID: 54\ntype: 16\nnbr out: 0\nnbr chi: 0"];
node_51 -> node_55;
node_55 [label="ID: 55\ntype: 48\nnbr out: 0\nnbr chi: 3"];
node_55 -> node_56;
node_56 [label="ID: 56\ntype: 14\nnbr out: 0\nnbr chi: 0"];
node_55 -> node_57;
node_57 [label="ID: 57\ntype: 1\nnbr out: 0\nnbr chi: 0"];
node_55 -> node_58;
node_58 [label="ID: 58\ntype: 6\nnbr out: 0\nnbr chi: 0"];
node_15 -> node_59;
node_59 [label="ID: 59\ntype: 48\nnbr out: 0\nnbr chi: 5"];
node_59 -> node_60;
node_60 [label="ID: 60\ntype: 38\nnbr out: 0\nnbr chi: 0"];
node_59 -> node_61;
node_61 [label="ID: 61\ntype: 8\nnbr out: 0\nnbr chi: 0"];
node_59 -> node_62;
node_62 [label="ID: 62\ntype: 1\nnbr out: 0\nnbr chi: 0"];
node_59 -> node_63;
node_63 [label="ID: 63\ntype: 5\nnbr out: 0\nnbr chi: 0"];
node_59 -> node_64;
node_64 [label="ID: 64\ntype: 16\nnbr out: 0\nnbr chi: 0"];
node_15 -> node_65;
node_65 [label="ID: 65\ntype: 48\nnbr out: 0\nnbr chi: 5"];
node_65 -> node_66;
node_66 [label="ID: 66\ntype: 38\nnbr out: 0\nnbr chi: 0"];
node_65 -> node_67;
node_67 [label="ID: 67\ntype: 14\nnbr out: 0\nnbr chi: 0"];
node_65 -> node_68;
node_68 [label="ID: 68\ntype: 14\nnbr out: 0\nnbr chi: 0"];
node_65 -> node_69;
node_69 [label="ID: 69\ntype: 20\nnbr out: 0\nnbr chi: 0"];
node_65 -> node_70;
node_70 [label="ID: 70\ntype: 16\nnbr out: 0\nnbr chi: 0"];
node_14 -> node_71;
node_71 [label="ID: 71\ntype: 45\nnbr out: 1\nnbr chi: 0"];
node_71 -> node_72;
node_72 [label="ID: 72\ntype: 16\nnbr out: 0\nnbr chi: 0"];
node_71 -> node_73;
node_73 [label="ID: 73\ntype: 48\nnbr out: 0\nnbr chi: 3"];
node_73 -> node_74;
node_74 [label="ID: 74\ntype: 14\nnbr out: 0\nnbr chi: 0"];
node_73 -> node_75;
node_75 [label="ID: 75\ntype: 1\nnbr out: 0\nnbr chi: 0"];
node_73 -> node_76;
node_76 [label="ID: 76\ntype: 6\nnbr out: 0\nnbr chi: 0"];
node_8 -> node_77;
node_77 [label="ID: 77\ntype: 45\nnbr out: 1\nnbr chi: 0"];
node_77 -> node_78;
node_78 [label="ID: 78\ntype: 16\nnbr out: 0\nnbr chi: 0"];
node_77 -> node_79;
node_79 [label="ID: 79\ntype: 48\nnbr out: 0\nnbr chi: 3"];
node_79 -> node_80;
node_80 [label="ID: 80\ntype: 14\nnbr out: 0\nnbr chi: 0"];
node_79 -> node_81;
node_81 [label="ID: 81\ntype: 1\nnbr out: 0\nnbr chi: 0"];
node_79 -> node_82;
node_82 [label="ID: 82\ntype: 6\nnbr out: 0\nnbr chi: 0"];
node_1 -> node_83;
node_83 [label="ID: 83\ntype: 38\nnbr out: 0\nnbr chi: 0"];
node_1 -> node_84;
node_84 [label="ID: 84\ntype: 8\nnbr out: 0\nnbr chi: 0"];
node_1 -> node_85;
node_85 [label="ID: 85\ntype: 1\nnbr out: 0\nnbr chi: 0"];
node_1 -> node_86;
node_86 [label="ID: 86\ntype: 5\nnbr out: 0\nnbr chi: 0"];
node_1 -> node_87;
node_87 [label="ID: 87\ntype: 16\nnbr out: 0\nnbr chi: 0"];
}
ocamlgraph-2.0.0/dgraph/examples/switch.gv 0000755 0001750 0000144 00000002500 13735627615 017133 0 ustar rt users digraph G {
graph [center=true rankdir=LR bgcolor="#808080"]
edge [dir=none]
node [width=0.3 height=0.3 label=""]
{ node [shape=circle style=invis]
1 2 3 4 5 6 7 8 10 20 30 40 50 60 70 80
}
{ node [shape=circle]
a b c d e f g h i j k l m n o p q r s t u v w x
}
{ node [shape=diamond]
A B C D E F G H I J K L M N O P Q R S T U V W X
}
1 -> a -> {A B} [color="#0000ff"]
2 -> b -> {B A} [color="#ff0000"]
3 -> c -> {C D} [color="#ffff00"]
4 -> d -> {D C} [color="#00ff00"]
5 -> e -> {E F} [color="#000000"]
6 -> f -> {F E} [color="#00ffff"]
7 -> g -> {G H} [color="#ffffff"]
8 -> h -> {H G} [color="#ff00ff"]
{ edge [color="#ff0000:#0000ff"]
A -> i -> {I K}
B -> j -> {J L}
}
{ edge [color="#00ff00:#ffff00"]
C -> k -> {K I}
D -> l -> {L J}
}
{ edge [color="#00ffff:#000000"]
E -> m -> {M O}
F -> n -> {N P}
}
{ edge [color="#ff00ff:#ffffff"]
G -> o -> {O M}
H -> p -> {P N}
}
{ edge [color="#00ff00:#ffff00:#ff0000:#0000ff"]
I -> q -> {Q U}
J -> r -> {R V}
K -> s -> {S W}
L -> t -> {T X}
}
{ edge [color="#ff00ff:#ffffff:#00ffff:#000000"]
M -> u -> {U Q}
N -> v -> {V R}
O -> w -> {W S}
P -> x -> {X T}
}
{ edge [color="#ff00ff:#ffffff:#00ffff:#000000:#00ff00:#ffff00:#ff0000:#0000ff"]
Q -> 10
R -> 20
S -> 30
T -> 40
U -> 50
V -> 60
W -> 70
X -> 80
}
}
ocamlgraph-2.0.0/dgraph/examples/gzip_annot.dot 0000755 0001750 0000144 00000541652 13735627615 020174 0 ustar rt users digraph G {
node [label="\N"];
graph [bb="0,0,9334,994",
_draw_="c 5 -white C 5 -white P 4 0 0 0 994 9334 994 9334 0 ",
xdotversion="1.2"];
subgraph cluster_36 {
graph [label="S 36",
color="#C00000",
style=bold,
lp="3856,421",
bb="3803,356,3909,433",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 3856 416 0 32 4 -S 36 ",
_draw_="S 4 -bold c 7 -#C00000 p 4 3803 356 3803 433 3909 433 3909 356 ",
xdotversion=""];
"UV error (32)" [label=error, width="1.00", height="0.49", style=bold, color="#C00000", pos="3847,382", _draw_="S 4 -bold c 7 -#C00000 e 3847 382 36 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 3847 377 0 35 5 -error "];
"UV error (32)" -> "UV error (32)" [style=invis, minlen=0, pos="e,3869,368 3869,396 3885,401 3901,396 3901,382 3901,371 3891,366 3879,366"];
}
subgraph cluster_37 {
graph [label="S 37",
color="#C00080",
style=bold,
lp="2354,421",
bb="2287,356,2421,433",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 2354 416 0 32 4 -S 37 ",
_draw_="S 4 -bold c 7 -#C00080 p 4 2287 356 2287 433 2421 433 2421 356 ",
xdotversion=""];
"UV memset (47)" [label=memset, width="1.39", height="0.49", style=dotted, color="#C00080", pos="2345,382", _draw_="S 6 -dotted c 7 -#C00080 e 2345 382 50 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 2345 377 0 55 6 -memset "];
"UV memset (47)" -> "UV memset (47)" [style=invis, minlen=0, pos="e,2374,368 2374,396 2394,400 2413,396 2413,382 2413,370 2400,366 2384,367"];
}
subgraph cluster_50 {
graph [label="S 50",
color="#40C000",
style=bold,
lp="8479,251",
bb="8421,186,8537,263",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 8479 246 0 32 4 -S 50 ",
_draw_="S 4 -bold c 7 -#40C000 p 4 8421 186 8421 263 8537 263 8537 186 ",
xdotversion=""];
"UV unlink (111)" [label=unlink, width="1.14", height="0.49", style=dotted, color="#40C000", pos="8470,212", _draw_="S 6 -dotted c 7 -#40C000 e 8470 212 41 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 8470 207 0 43 6 -unlink "];
"UV unlink (111)" -> "UV unlink (111)" [style=invis, minlen=0, pos="e,8494,198 8494,226 8512,231 8529,226 8529,212 8529,201 8518,195 8504,196"];
}
subgraph cluster_38 {
graph [label="S 38",
color="#C08000",
style=bold,
lp="2179,421",
bb="2111,356,2247,433",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 2179 416 0 32 4 -S 38 ",
_draw_="S 4 -bold c 7 -#C08000 p 4 2111 356 2111 433 2247 433 2247 356 ",
xdotversion=""];
"UV memcpy (48)" [label=memcpy, width="1.42", height="0.49", style=dotted, color="#C08000", pos="2170,382", _draw_="S 6 -dotted c 7 -#C08000 e 2170 382 51 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 2170 377 0 57 6 -memcpy "];
"UV memcpy (48)" -> "UV memcpy (48)" [style=invis, minlen=0, pos="e,2200,368 2200,396 2220,400 2239,396 2239,382 2239,370 2226,366 2210,367"];
}
subgraph cluster_51 {
graph [label="S 51",
color="#40C080",
style=bold,
lp="6036,336",
bb="5980,271,6092,348",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 6036 331 0 32 4 -S 51 ",
_draw_="S 4 -bold c 7 -#40C080 p 4 5980 271 5980 348 6092 348 6092 271 ",
xdotversion=""];
"UV isatty (103)" [label=isatty, width="1.08", height="0.49", style=dotted, color="#40C080", pos="6027,297", _draw_="S 6 -dotted c 7 -#40C080 e 6027 297 39 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 6027 292 0 39 6 -isatty "];
"UV isatty (103)" -> "UV isatty (103)" [style=invis, minlen=0, pos="e,6050,283 6050,311 6067,316 6084,311 6084,297 6084,286 6073,280 6060,281"];
}
subgraph cluster_52 {
graph [label="S 52",
color="#C04000",
style=bold,
lp="5742,421",
bb="5691,356,5793,433",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 5742 416 0 32 4 -S 52 ",
_draw_="S 4 -bold c 7 -#C04000 p 4 5691 356 5691 433 5793 433 5793 356 ",
xdotversion=""];
"UV fstat (104)" [label=fstat, width="0.94", height="0.49", style=dotted, color="#C04000", pos="5733,382", _draw_="S 6 -dotted c 7 -#C04000 e 5733 382 34 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 5733 377 0 32 5 -fstat "];
"UV fstat (104)" -> "UV fstat (104)" [style=invis, minlen=0, pos="e,5754,368 5754,396 5769,401 5785,396 5785,382 5785,371 5775,366 5764,366"];
}
subgraph cluster_39 {
graph [label="S 39",
color="#C08080",
style=bold,
lp="1368,336",
bb="1308,271,1428,348",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 1368 331 0 32 4 -S 39 ",
_draw_="S 4 -bold c 7 -#C08080 p 4 1308 271 1308 348 1428 348 1428 271 ",
xdotversion=""];
"UV updcrc (2)" [label=updcrc, width="1.19", height="0.49", style=bold, color="#C08080", pos="1359,297", _draw_="S 4 -bold c 7 -#C08080 e 1359 297 43 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 1359 292 0 45 6 -updcrc "];
"UV updcrc (2)" -> "UV updcrc (2)" [style=invis, minlen=0, pos="e,1385,283 1385,311 1402,316 1420,311 1420,297 1420,286 1408,280 1395,281"];
}
subgraph cluster_53 {
graph [label="S 53",
color="#C04080",
style=bold,
lp="4524,251",
bb="4461,186,4587,263",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 4524 246 0 32 4 -S 53 ",
_draw_="S 4 -bold c 7 -#C04080 p 4 4461 186 4461 263 4587 263 4587 186 ",
xdotversion=""];
"UV strcspn (29)" [label=strcspn, width="1.28", height="0.49", style=dotted, color="#C04080", pos="4515,212", _draw_="S 6 -dotted c 7 -#C04080 e 4515 212 46 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 4515 207 0 50 7 -strcspn "];
"UV strcspn (29)" -> "UV strcspn (29)" [style=invis, minlen=0, pos="e,4542,198 4542,226 4561,230 4579,226 4579,212 4579,201 4567,196 4552,197"];
}
subgraph cluster_54 {
graph [label="S 54",
color="#C0C000",
style=bold,
lp="3766,166",
bb="3719,101,3813,178",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 3766 161 0 32 4 -S 54 ",
_draw_="S 4 -bold c 7 -#C0C000 p 4 3719 101 3719 178 3813 178 3813 101 ",
xdotversion=""];
"UV free (30)" [label=free, width="0.83", height="0.49", style=dotted, color="#C0C000", pos="3757,127", _draw_="S 6 -dotted c 7 -#C0C000 e 3757 127 30 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 3757 122 0 27 4 -free "];
"UV free (30)" -> "UV free (30)" [style=invis, minlen=0, pos="e,3776,113 3776,141 3790,146 3805,141 3805,127 3805,116 3796,111 3786,111"];
}
subgraph cluster_20 {
graph [label="S 20",
color="#804000",
style=bold,
lp="5605,421",
bb="5559,356,5651,433",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 5605 416 0 32 4 -S 20 ",
_draw_="S 4 -bold c 7 -#804000 p 4 5559 356 5559 433 5651 433 5651 356 ",
xdotversion=""];
"UV lzw (78)" [label=lzw, width="0.81", height="0.49", style=bold, color="#804000", pos="5596,382", _draw_="S 4 -bold c 7 -#804000 e 5596 382 29 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 5596 377 0 25 3 -lzw "];
"UV lzw (78)" -> "UV lzw (78)" [style=invis, minlen=0, pos="e,5614,368 5614,396 5628,401 5643,396 5643,382 5643,371 5634,366 5624,366"];
}
subgraph cluster_55 {
graph [label="S 55",
color="#C0C080",
style=bold,
lp="7888,166",
bb="7831,101,7945,178",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 7888 161 0 32 4 -S 55 ",
_draw_="S 4 -bold c 7 -#C0C080 p 4 7831 101 7831 178 7945 178 7945 101 ",
xdotversion=""];
"UV strlwr (19)" [label=strlwr, width="1.11", height="0.49", style=bold, color="#C0C080", pos="7879,127", _draw_="S 4 -bold c 7 -#C0C080 e 7879 127 40 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 7879 122 0 41 6 -strlwr "];
"UV strlwr (19)" -> "UV strlwr (19)" [style=invis, minlen=0, pos="e,7903,113 7903,141 7920,146 7937,141 7937,127 7937,116 7926,110 7913,111"];
}
subgraph cluster_56 {
graph [label="S 56",
color="#404040",
style=bold,
lp="5181,336",
bb="5072,271,5290,348",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 5181 331 0 32 4 -S 56 ",
_draw_="S 4 -bold c 7 -#404040 p 4 5072 271 5072 348 5290 348 5290 271 ",
xdotversion=""];
"UV __errno_location (11)" [label=__errno_location, width="2.56", height="0.49", style=dotted, color="#404040", pos="5172,297", _draw_="S 6 -dotted c 7 -#404040 e 5172 297 92 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 5172 292 0 114 16 -__errno_location "];
"UV __errno_location (11)" -> "UV __errno_location (11)" [style=invis, minlen=0, pos="e,5222,282 5222,312 5253,315 5282,310 5282,297 5282,285 5259,280 5232,281"];
}
subgraph cluster_21 {
graph [label="S 21",
color="#804080",
style=bold,
lp="658,974",
bb="29,356,1287,986",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 658 969 0 32 4 -S 21 ",
_draw_="S 4 -bold c 7 -#804080 p 4 29 356 29 986 1287 986 1287 356 ",
xdotversion=""];
"UV zip (0)" [label=zip, width="0.69", height="0.49", style=bold, color="#804080", pos="640,935", _draw_="S 4 -bold c 7 -#804080 e 640 935 25 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 640 930 0 20 3 -zip "];
"UV flush_outbuf (1)" [label=flush_outbuf, width="1.97", height="0.50", style=bold, color="#804080", pos="1050,382", _draw_="S 4 -bold c 7 -#804080 e 1050 382 71 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 1050 377 0 86 12 -flush_outbuf "];
"UV bi_init (3)" [label=bi_init, width="1.11", height="0.50", style=bold, color="#804080", pos="100,863", _draw_="S 4 -bold c 7 -#804080 e 100 863 40 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 100 858 0 42 7 -bi_init "];
"UV ct_init (4)" [label=ct_init, width="1.14", height="0.50", style=bold, color="#804080", pos="119,714", _draw_="S 4 -bold c 7 -#804080 e 119 714 41 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 119 709 0 43 7 -ct_init "];
"UV lm_init (5)" [label=lm_init, width="1.22", height="0.50", style=bold, color="#804080", pos="1234,863", _draw_="S 4 -bold c 7 -#804080 e 1234 863 44 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 1234 858 0 47 7 -lm_init "];
"UV deflate (7)" [label=deflate, width="1.22", height="0.50", style=bold, color="#804080", pos="487,863", _draw_="S 4 -bold c 7 -#804080 e 487 863 44 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 487 858 0 48 7 -deflate "];
"UV fill_window (133)" [label=fill_window, width="1.81", height="0.50", style=bold, color="#804080", pos="1214,714", _draw_="S 4 -bold c 7 -#804080 e 1214 714 65 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 1214 709 0 78 11 -fill_window "];
"UV longest_match (134)" [label=longest_match, width="2.25", height="0.50", style=bold, color="#804080", pos="444,714", _draw_="S 4 -bold c 7 -#804080 e 444 714 81 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 444 709 0 101 13 -longest_match "];
"UV deflate_fast (135)" [label=deflate_fast, width="1.86", height="0.50", style=bold, color="#804080", pos="444,786", _draw_="S 4 -bold c 7 -#804080 e 444 786 67 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 444 781 0 81 12 -deflate_fast "];
"UV gen_codes (61)" [label=gen_codes, width="1.67", height="0.50", style=bold, color="#804080", pos="137,467", _draw_="S 4 -bold c 7 -#804080 e 137 467 60 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 137 462 0 71 9 -gen_codes "];
"UV bi_reverse (62)" [label=bi_reverse, width="1.67", height="0.50", style=bold, color="#804080", pos="97,382", _draw_="S 4 -bold c 7 -#804080 e 97 382 60 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 97 377 0 71 10 -bi_reverse "];
"UV init_block (63)" [label=init_block, width="1.56", height="0.50", style=bold, color="#804080", pos="173,637", _draw_="S 4 -bold c 7 -#804080 e 173 637 56 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 173 632 0 65 10 -init_block "];
"UV pqdownheap (64)" [label=pqdownheap, width="2.03", height="0.50", style=bold, color="#804080", pos="1023,467", _draw_="S 4 -bold c 7 -#804080 e 1023 467 73 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 1023 462 0 89 10 -pqdownheap "];
"UV gen_bitlen (65)" [label=gen_bitlen, width="1.69", height="0.50", style=bold, color="#804080", pos="1183,467", _draw_="S 4 -bold c 7 -#804080 e 1183 467 61 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 1183 462 0 72 10 -gen_bitlen "];
"UV build_tree_0 (66)" [label=build_tree_0, width="1.97", height="0.50", style=bold, color="#804080", pos="1016,552", _draw_="S 4 -bold c 7 -#804080 e 1016 552 71 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 1016 547 0 86 12 -build_tree_0 "];
"UV scan_tree (67)" [label=scan_tree, width="1.58", height="0.50", style=bold, color="#804080", pos="1162,552", _draw_="S 4 -bold c 7 -#804080 e 1162 552 57 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 1162 547 0 67 9 -scan_tree "];
"UV send_tree (68)" [label=send_tree, width="1.61", height="0.50", style=bold, color="#804080", pos="534,552", _draw_="S 4 -bold c 7 -#804080 e 534 552 58 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 534 547 0 68 9 -send_tree "];
"UV send_bits (69)" [label=send_bits, width="1.56", height="0.50", style=bold, color="#804080", pos="621,467", _draw_="S 4 -bold c 7 -#804080 e 621 467 56 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 621 462 0 65 9 -send_bits "];
"UV build_bl_tree (70)" [label=build_bl_tree, width="2.03", height="0.50", style=bold, color="#804080", pos="1126,637", _draw_="S 4 -bold c 7 -#804080 e 1126 637 73 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 1126 632 0 89 13 -build_bl_tree "];
"UV send_all_trees (71)" [label=send_all_trees, width="2.19", height="0.50", style=bold, color="#804080", pos="534,637", _draw_="S 4 -bold c 7 -#804080 e 534 637 79 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 534 632 0 98 14 -send_all_trees "];
"UV flush_block (72)" [label=flush_block, width="1.78", height="0.50", style=bold, color="#804080", pos="647,714", _draw_="S 4 -bold c 7 -#804080 e 647 714 64 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 647 709 0 77 11 -flush_block "];
"UV set_file_type (73)" [label=set_file_type, width="1.97", height="0.50", style=bold, color="#804080", pos="924,637", _draw_="S 4 -bold c 7 -#804080 e 924 637 71 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 924 632 0 87 13 -set_file_type "];
"UV copy_block (74)" [label=copy_block, width="1.72", height="0.50", style=bold, color="#804080", pos="753,637", _draw_="S 4 -bold c 7 -#804080 e 753 637 62 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 753 632 0 74 10 -copy_block "];
"UV compress_block (75)" [label=compress_block, width="2.36", height="0.50", style=bold, color="#804080", pos="332,637", _draw_="S 4 -bold c 7 -#804080 e 332 637 85 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 332 632 0 107 14 -compress_block "];
"UV bi_windup (76)" [label=bi_windup, width="1.67", height="0.50", style=bold, color="#804080", pos="858,552", _draw_="S 4 -bold c 7 -#804080 e 858 552 60 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 858 547 0 71 9 -bi_windup "];
"UV ct_tally (77)" [label=ct_tally, width="1.28", height="0.50", style=bold, color="#804080", pos="299,714", _draw_="S 4 -bold c 7 -#804080 e 299 714 46 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 299 709 0 50 8 -ct_tally "];
"UV zip (0)" -> "UV zip (0)" [style=invis, minlen=0, pos="e,658,923 658,947 671,951 683,947 683,935 683,926 677,922 668,922"];
"UV zip (0)" -> "UV flush_outbuf (1)" [pos="e,1108,392 665,933 753,927 1046,906 1079,881 1113,854 1100,724 1131,696 1150,679 1166,701 1187,688 1227,663 1234,647 1248,603 12\
71,534 1289,497 1244,441 1228,420 1168,404 1118,394", _draw_="c 5 -black B 19 665 933 753 927 1046 906 1079 881 1113 854 1100 724 1131 696 1150 679 1166 701 1187 688 1227 663 1234 647 1248 6\
03 1271 534 1289 497 1244 441 1228 420 1168 404 1118 394 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 1118 391 1108 392 1117 397 "];
"UV zip (0)" -> "UV bi_init (3)" [pos="e,128,876 615,934 541,931 322,919 145,881 142,881 140,880 137,879", _draw_="c 5 -black B 7 615 934 541 931 322 919 145 881 142 881 140 880 137 879 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 139 876 128 876 136 882 "];
"UV zip (0)" -> "UV ct_init (4)" [pos="e,118,732 615,934 522,929 200,909 165,881 144,863 124,785 119,742", _draw_="c 5 -black B 7 615 934 522 929 200 909 165 881 144 863 124 785 119 742 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 122 742 118 732 116 742 "];
"UV zip (0)" -> "UV lm_init (5)" [pos="e,1197,873 665,934 741,931 977,919 1167,881 1174,880 1180,878 1187,876", _draw_="c 5 -black B 7 665 934 741 931 977 919 1167 881 1174 880 1180 878 1187 876 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 1188 879 1197 873 1186 873 "];
"UV zip (0)" -> "UV deflate (7)" [pos="e,513,878 618,927 593,916 551,897 522,883", _draw_="c 5 -black B 4 618 927 593 916 551 897 522 883 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 523 880 513 878 520 886 "];
"UV flush_outbuf (1)" -> "UV zip (0)" [style=invis, minlen=0, pos="e,665,934 1112,391 1168,400 1244,418 1262,441 1307,497 1289,534 1266,603 1252,647 1245,663 1205,688 1184,701 1168,679 1149,696 1\
118,724 1131,854 1097,881 1064,906 777,927 675,933"];
"UV bi_init (3)" -> "UV zip (0)" [style=invis, minlen=0, pos="e,615,934 134,872 144,876 154,879 163,881 326,916 525,929 605,933"];
"UV ct_init (4)" -> "UV zip (0)" [style=invis, minlen=0, pos="e,615,933 127,732 139,771 160,861 183,881 217,907 503,927 605,932"];
"UV ct_init (4)" -> "UV gen_codes (61)" [pos="e,119,485 100,698 97,695 95,692 93,688 66,621 71,594 93,526 97,514 104,502 112,493", _draw_="c 5 -black B 10 100 698 97 695 95 692 93 688 66 621 71 594 93 526 97 514 104 502 112 493 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 115 495 119 485 110 490 "];
"UV ct_init (4)" -> "UV bi_reverse (62)" [pos="e,86,400 88,702 82,699 76,694 72,688 44,641 56,494 68,441 71,430 76,418 81,409", _draw_="c 5 -black B 10 88 702 82 699 76 694 72 688 44 641 56 494 68 441 71 430 76 418 81 409 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 84 410 86 400 78 407 "];
"UV ct_init (4)" -> "UV init_block (63)" [pos="e,161,655 131,697 138,687 147,674 155,663", _draw_="c 5 -black B 4 131 697 138 687 147 674 155 663 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 158 665 161 655 152 661 "];
"UV lm_init (5)" -> "UV zip (0)" [style=invis, minlen=0, pos="e,665,934 1204,876 1198,878 1191,880 1185,881 996,919 763,931 675,934"];
"UV lm_init (5)" -> "UV fill_window (133)" [pos="e,1216,732 1232,845 1228,819 1222,772 1217,742", _draw_="c 5 -black B 4 1232 845 1228 819 1222 772 1217 742 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 1220 742 1216 732 1214 742 "];
"UV deflate (7)" -> "UV zip (0)" [style=invis, minlen=0, pos="e,621,924 519,876 547,888 585,906 612,919"];
"UV deflate (7)" -> "UV flush_block (72)" [pos="e,633,732 514,849 520,845 526,841 531,837 568,807 605,766 627,740", _draw_="c 5 -black B 7 514 849 520 845 526 841 531 837 568 807 605 766 627 740 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 630 742 633 732 624 738 "];
"UV deflate (7)" -> "UV ct_tally (77)" [pos="e,304,732 445,857 416,853 380,846 368,837 336,813 317,770 307,742", _draw_="c 5 -black B 7 445 857 416 853 380 846 368 837 336 813 317 770 307 742 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 310 741 304 732 304 743 "];
"UV deflate (7)" -> "UV fill_window (133)" [pos="e,1162,725 526,855 646,831 1006,757 1152,727", _draw_="c 5 -black B 4 526 855 646 831 1006 757 1152 727 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 1153 730 1162 725 1152 724 "];
"UV deflate (7)" -> "UV longest_match (134)" [pos="e,480,730 511,848 515,845 518,841 520,837 534,809 535,795 520,768 513,755 501,744 489,735", _draw_="c 5 -black B 10 511 848 515 845 518 841 520 837 534 809 535 795 520 768 513 755 501 744 489 735 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 490 732 480 730 487 738 "];
"UV deflate (7)" -> "UV deflate_fast (135)" [pos="e,454,804 477,845 472,836 465,823 459,813", _draw_="c 5 -black B 4 477 845 472 836 465 823 459 813 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 462 811 454 804 456 814 "];
"UV fill_window (133)" -> "UV zip (0)" [style=invis, minlen=0, pos="e,665,934 1210,732 1201,771 1179,862 1155,881 1117,910 785,928 675,933"];
"UV longest_match (134)" -> "UV zip (0)" [style=invis, minlen=0, pos="e,615,932 408,730 393,739 377,752 368,768 354,795 355,809 368,837 382,864 395,867 422,881 483,911 560,925 605,931"];
"UV deflate_fast (135)" -> "UV zip (0)" [style=invis, minlen=0, pos="e,615,932 435,804 427,825 418,859 434,881 455,907 552,924 605,931"];
"UV deflate_fast (135)" -> "UV flush_block (72)" [pos="e,607,728 485,772 517,760 563,744 597,732", _draw_="c 5 -black B 4 485 772 517 760 563 744 597 732 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 599 735 607 728 596 728 "];
"UV deflate_fast (135)" -> "UV ct_tally (77)" [pos="e,328,728 412,770 390,759 360,744 337,733", _draw_="c 5 -black B 4 412 770 390 759 360 744 337 733 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 338 730 328 728 335 736 "];
"UV deflate_fast (135)" -> "UV fill_window (133)" [pos="e,1152,720 507,780 650,767 992,735 1142,721", _draw_="c 5 -black B 4 507 780 650 767 992 735 1142 721 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 1142 724 1152 720 1142 718 "];
"UV deflate_fast (135)" -> "UV longest_match (134)" [pos="e,444,732 444,768 444,760 444,751 444,742", _draw_="c 5 -black B 4 444 768 444 760 444 751 444 742 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 448 742 444 732 441 742 "];
"UV gen_codes (61)" -> "UV zip (0)" [style=invis, minlen=0, pos="e,615,934 131,485 117,532 82,657 108,688 127,708 149,677 169,696 181,706 195,822 201,837 212,859 213,868 234,881 297,917 518,930\
605,934"];
"UV gen_codes (61)" -> "UV bi_reverse (62)" [pos="e,106,400 129,449 123,438 116,422 110,409", _draw_="c 5 -black B 4 129 449 123 438 116 422 110 409 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 113 408 106 400 107 411 "];
"UV bi_reverse (62)" -> "UV zip (0)" [style=invis, minlen=0, pos="e,615,934 81,399 72,410 61,425 54,441 36,487 38,502 38,552 38,786 38,786 38,786 38,828 21,851 51,881 92,919 484,931 605,934"];
"UV init_block (63)" -> "UV zip (0)" [style=invis, minlen=0, pos="e,615,933 177,655 186,698 209,806 229,837 248,863 258,868 287,881 344,905 527,924 605,932"];
"UV pqdownheap (64)" -> "UV zip (0)" [style=invis, minlen=0, pos="e,665,933 1047,484 1064,496 1089,510 1113,518 1126,521 1220,516 1228,526 1281,581 1237,648 1171,688 1146,703 1127,676 1105,696 1\
074,724 1095,853 1063,881 1034,906 771,926 675,932"];
"UV gen_bitlen (65)" -> "UV zip (0)" [style=invis, minlen=0, pos="e,665,933 1210,483 1223,494 1239,508 1246,526 1260,557 1257,570 1246,603 1233,647 1226,664 1186,688 1163,702 1146,677 1125,696 1\
094,724 1108,853 1075,881 1045,906 773,927 675,932"];
"UV build_tree_0 (66)" -> "UV zip (0)" [style=invis, minlen=0, pos="e,665,933 1019,570 1028,632 1056,838 1010,881 986,903 762,924 675,932"];
"UV build_tree_0 (66)" -> "UV gen_codes (61)" [pos="e,191,475 975,537 960,533 943,528 927,526 846,513 639,523 556,518 429,508 283,489 201,477", _draw_="c 5 -black B 10 975 537 960 533 943 528 927 526 846 513 639 523 556 518 429 508 283 489 201 477 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 201 474 191 475 200 480 "];
"UV build_tree_0 (66)" -> "UV pqdownheap (64)" [pos="e,1022,485 1017,534 1019,523 1020,508 1021,495", _draw_="c 5 -black B 4 1017 534 1019 523 1020 508 1021 495 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 1024 495 1022 485 1018 495 "];
"UV build_tree_0 (66)" -> "UV gen_bitlen (65)" [pos="e,1160,484 1059,538 1074,532 1091,525 1105,518 1121,510 1138,499 1152,490", _draw_="c 5 -black B 7 1059 538 1074 532 1091 525 1105 518 1121 510 1138 499 1152 490 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 1154 493 1160 484 1150 487 "];
"UV scan_tree (67)" -> "UV zip (0)" [style=invis, minlen=0, pos="e,665,933 1181,569 1191,580 1203,595 1208,611 1220,643 1232,663 1208,688 1190,707 1106,677 1085,696 1055,724 1083,853 1051,881 1\
023,904 770,925 675,932"];
"UV send_tree (68)" -> "UV zip (0)" [style=invis, minlen=0, pos="e,630,919 498,566 479,576 457,590 446,611 430,641 423,662 446,688 460,702 519,683 534,696 547,706 573,822 579,837 589,857 594,86\
1 606,881 612,891 619,901 625,911"];
"UV send_tree (68)" -> "UV send_bits (69)" [pos="e,603,484 552,535 565,522 582,505 596,491", _draw_="c 5 -black B 4 552 535 565 522 582 505 596 491 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 598 494 603 484 593 489 "];
"UV send_bits (69)" -> "UV zip (0)" [style=invis, minlen=0, pos="e,649,919 626,485 640,537 681,686 682,688 695,699 710,682 720,696 731,708 723,716 720,732 707,799 673,872 654,910"];
"UV send_bits (69)" -> "UV flush_outbuf (1)" [pos="e,994,393 669,457 746,442 897,412 984,395", _draw_="c 5 -black B 4 669 457 746 442 897 412 984 395 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 985 398 994 393 984 392 "];
"UV build_bl_tree (70)" -> "UV zip (0)" [style=invis, minlen=0, pos="e,665,933 1102,654 1089,664 1074,679 1065,696 1027,769 1095,822 1035,881 1010,905 768,925 675,932"];
"UV build_bl_tree (70)" -> "UV build_tree_0 (66)" [pos="e,1038,569 1104,620 1087,607 1065,589 1046,575", _draw_="c 5 -black B 4 1104 620 1087 607 1065 589 1046 575 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 1048 572 1038 569 1044 578 "];
"UV build_bl_tree (70)" -> "UV scan_tree (67)" [pos="e,1154,570 1134,619 1139,608 1145,592 1150,579", _draw_="c 5 -black B 4 1134 619 1139 608 1145 592 1150 579 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 1153 581 1154 570 1147 578 "];
"UV send_all_trees (71)" -> "UV zip (0)" [style=invis, minlen=0, pos="e,634,918 540,655 558,706 609,848 631,908"];
"UV send_all_trees (71)" -> "UV send_tree (68)" [pos="e,534,570 534,619 534,608 534,593 534,580", _draw_="c 5 -black B 4 534 619 534 608 534 593 534 580 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 538 580 534 570 531 580 "];
"UV send_all_trees (71)" -> "UV send_bits (69)" [pos="e,623,485 578,622 587,617 595,611 601,603 624,571 626,525 624,495", _draw_="c 5 -black B 7 578 622 587 617 595 611 601 603 624 571 626 525 624 495 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 627 495 623 485 621 495 "];
"UV flush_block (72)" -> "UV zip (0)" [style=invis, minlen=0, pos="e,641,917 646,732 645,771 642,861 641,907"];
"UV flush_block (72)" -> "UV init_block (63)" [pos="e,189,654 594,704 575,701 554,698 534,696 502,692 269,699 238,688 223,682 208,671 196,661", _draw_="c 5 -black B 10 594 704 575 701 554 698 534 696 502 692 269 699 238 688 223 682 208 671 196 661 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 199 659 189 654 194 664 "];
"UV flush_block (72)" -> "UV build_tree_0 (66)" [pos="e,993,569 708,708 756,703 816,696 824,688 851,664 818,633 844,611 859,598 910,608 927,603 947,596 968,585 985,574", _draw_="c 5 -black B 13 708 708 756 703 816 696 824 688 851 664 818 633 844 611 859 598 910 608 927 603 947 596 968 585 985 574 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 986 577 993 569 983 571 "];
"UV flush_block (72)" -> "UV send_bits (69)" [pos="e,623,485 645,696 640,653 630,546 624,495", _draw_="c 5 -black B 4 645 696 640 653 630 546 624 495 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 627 495 623 485 621 495 "];
"UV flush_block (72)" -> "UV build_bl_tree (70)" [pos="e,1095,653 711,712 798,708 950,701 1004,688 1033,681 1063,669 1086,657", _draw_="c 5 -black B 7 711 712 798 708 950 701 1004 688 1033 681 1063 669 1086 657 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 1087 660 1095 653 1084 654 "];
"UV flush_block (72)" -> "UV send_all_trees (71)" [pos="e,559,654 622,697 606,687 585,672 567,660", _draw_="c 5 -black B 4 622 697 606 687 585 672 567 660 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 569 657 559 654 565 663 "];
"UV flush_block (72)" -> "UV set_file_type (73)" [pos="e,901,654 708,708 755,704 816,696 839,688 858,681 877,670 893,660", _draw_="c 5 -black B 7 708 708 755 704 816 696 839 688 858 681 877 670 893 660 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 895 663 901 654 891 657 "];
"UV flush_block (72)" -> "UV copy_block (74)" [pos="e,730,654 670,697 685,686 705,671 722,660", _draw_="c 5 -black B 4 670 697 685 686 705 671 722 660 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 724 663 730 654 720 657 "];
"UV flush_block (72)" -> "UV compress_block (75)" [pos="e,363,654 593,704 574,701 553,698 534,696 496,691 484,697 446,688 421,681 394,669 372,658", _draw_="c 5 -black B 10 593 704 574 701 553 698 534 696 496 691 484 697 446 688 421 681 394 669 372 658 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 374 655 363 654 371 661 "];
"UV flush_block (72)" -> "UV bi_windup (76)" [pos="e,801,558 648,696 651,673 659,634 682,611 711,582 755,567 791,560", _draw_="c 5 -black B 7 648 696 651 673 659 634 682 611 711 582 755 567 791 560 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 792 563 801 558 791 557 "];
"UV set_file_type (73)" -> "UV zip (0)" [style=invis, minlen=0, pos="e,665,933 939,655 974,698 1054,812 995,881 974,905 761,925 675,932"];
"UV copy_block (74)" -> "UV zip (0)" [style=invis, minlen=0, pos="e,649,919 751,655 749,675 744,706 735,732 714,798 676,872 654,910"];
"UV copy_block (74)" -> "UV flush_outbuf (1)" [pos="e,995,393 756,619 761,596 771,556 789,526 818,480 830,469 875,441 909,420 951,406 985,396", _draw_="c 5 -black B 10 756 619 761 596 771 556 789 526 818 480 830 469 875 441 909 420 951 406 985 396 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 986 399 995 393 984 393 "];
"UV copy_block (74)" -> "UV bi_windup (76)" [pos="e,837,569 774,620 790,607 812,590 829,576", _draw_="c 5 -black B 4 774 620 790 607 812 590 829 576 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 832 578 837 569 827 573 "];
"UV compress_block (75)" -> "UV zip (0)" [style=invis, minlen=0, pos="e,615,933 292,653 274,663 255,677 244,696 201,777 261,831 338,881 383,909 535,925 605,932"];
"UV compress_block (75)" -> "UV send_bits (69)" [pos="e,579,479 350,619 374,595 421,553 467,526 499,507 538,492 569,482", _draw_="c 5 -black B 7 350 619 374 595 421 553 467 526 499 507 538 492 569 482 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 570 485 579 479 568 479 "];
"UV bi_windup (76)" -> "UV zip (0)" [style=invis, minlen=0, pos="e,663,928 879,569 894,581 915,595 936,603 951,608 994,599 1004,611 1027,636 1021,657 1004,688 932,823 748,898 672,925"];
"UV bi_windup (76)" -> "UV flush_outbuf (1)" [pos="e,1012,397 868,534 882,510 910,468 941,441 959,425 982,411 1003,401", _draw_="c 5 -black B 7 868 534 882 510 910 468 941 441 959 425 982 411 1003 401 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 1004 404 1012 397 1001 398 "];
"UV ct_tally (77)" -> "UV zip (0)" [style=invis, minlen=0, pos="e,615,933 301,732 307,767 323,842 370,881 406,909 541,925 605,932"];
}
subgraph cluster_22 {
graph [label="S 22",
color="#80C000",
style=bold,
lp="6315,591",
bb="6229,526,6401,603",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 6315 586 0 32 4 -S 22 ",
_draw_="S 4 -bold c 7 -#80C000 p 4 6229 526 6229 603 6401 603 6401 526 ",
xdotversion=""];
"UV getopt_long (96)" [label=getopt_long, width="1.92", height="0.49", style=dotted, color="#80C000", pos="6306,552", _draw_="S 6 -dotted c 7 -#80C000 e 6306 552 69 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 6306 547 0 82 11 -getopt_long "];
"UV getopt_long (96)" -> "UV getopt_long (96)" [style=invis, minlen=0, pos="e,6345,537 6345,567 6369,570 6393,565 6393,552 6393,541 6375,536 6355,536"];
}
subgraph cluster_57 {
graph [label="S 57",
color="#4040C0",
style=bold,
lp="2596,421",
bb="2537,356,2655,433",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 2596 416 0 32 4 -S 57 ",
_draw_="S 4 -bold c 7 -#4040C0 p 4 2537 356 2537 433 2655 433 2655 356 ",
xdotversion=""];
"UV malloc (39)" [label=malloc, width="1.17", height="0.49", style=dotted, color="#4040C0", pos="2587,382", _draw_="S 6 -dotted c 7 -#4040C0 e 2587 382 42 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 2587 377 0 44 6 -malloc "];
"UV malloc (39)" -> "UV malloc (39)" [style=invis, minlen=0, pos="e,2612,368 2612,396 2630,401 2647,396 2647,382 2647,371 2636,365 2622,366"];
}
subgraph cluster_23 {
graph [label="S 23",
color="#80C080",
style=bold,
lp="5400,506",
bb="5343,441,5457,518",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 5400 501 0 32 4 -S 23 ",
_draw_="S 4 -bold c 7 -#80C080 p 4 5343 441 5343 518 5457 518 5457 441 ",
xdotversion=""];
"UV usage (87)" [label=usage, width="1.11", height="0.49", style=bold, color="#80C080", pos="5391,467", _draw_="S 4 -bold c 7 -#80C080 e 5391 467 40 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 5391 462 0 41 5 -usage "];
"UV usage (87)" -> "UV usage (87)" [style=invis, minlen=0, pos="e,5415,453 5415,481 5432,486 5449,481 5449,467 5449,456 5438,450 5425,451"];
}
subgraph cluster_58 {
graph [label="S 58",
color="#40C040",
style=bold,
lp="7966,81",
bb="7903,16,8029,93",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 7966 76 0 32 4 -S 58 ",
_draw_="S 4 -bold c 7 -#40C040 p 4 7903 16 7903 93 8029 93 8029 16 ",
xdotversion=""];
"UV isupper (20)" [label=isupper, width="1.28", height="0.49", style=dotted, color="#40C040", pos="7957,42", _draw_="S 6 -dotted c 7 -#40C040 e 7957 42 46 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 7957 37 0 50 7 -isupper "];
"UV isupper (20)" -> "UV isupper (20)" [style=invis, minlen=0, pos="e,7984,28 7984,56 8003,60 8021,56 8021,42 8021,31 8009,26 7994,27"];
}
subgraph cluster_24 {
graph [label="S 24",
color="#004040",
style=bold,
lp="5497,421",
bb="5443,356,5551,433",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 5497 416 0 32 4 -S 24 ",
_draw_="S 4 -bold c 7 -#004040 p 4 5443 356 5443 433 5551 433 5551 356 ",
xdotversion=""];
"UV warn (35)" [label=warn, width="1.03", height="0.49", style=bold, color="#004040", pos="5488,382", _draw_="S 4 -bold c 7 -#004040 e 5488 382 37 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 5488 377 0 36 4 -warn "];
"UV warn (35)" -> "UV warn (35)" [style=invis, minlen=0, pos="e,5510,368 5510,396 5527,401 5543,396 5543,382 5543,371 5533,365 5520,366"];
}
subgraph cluster_25 {
graph [label="S 25",
color="#0040C0",
style=bold,
lp="3058,506",
bb="3007,441,3109,518",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 3058 501 0 32 4 -S 25 ",
_draw_="S 4 -bold c 7 -#0040C0 p 4 3007 441 3007 518 3109 518 3109 441 ",
xdotversion=""];
"UV copy (10)" [label=copy, width="0.94", height="0.49", style=bold, color="#0040C0", pos="3049,467", _draw_="S 4 -bold c 7 -#0040C0 e 3049 467 34 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 3049 462 0 32 4 -copy "];
"UV copy (10)" -> "UV copy (10)" [style=invis, minlen=0, pos="e,3070,453 3070,481 3085,486 3101,481 3101,467 3101,456 3091,451 3080,451"];
}
subgraph cluster_26 {
graph [label="S 26",
color="#00C040",
style=bold,
lp="5400,591",
bb="5351,526,5449,603",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 5400 586 0 32 4 -S 26 ",
_draw_="S 4 -bold c 7 -#00C040 p 4 5351 526 5351 603 5449 603 5449 526 ",
xdotversion=""];
"UV help (88)" [label=help, width="0.89", height="0.49", style=bold, color="#00C040", pos="5391,552", _draw_="S 4 -bold c 7 -#00C040 e 5391 552 32 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 5391 547 0 29 4 -help "];
"UV help (88)" -> "UV help (88)" [style=invis, minlen=0, pos="e,5411,538 5411,566 5426,571 5441,566 5441,552 5441,541 5432,536 5421,536"];
}
subgraph cluster_27 {
graph [label="S 27",
color="#00C0C0",
style=bold,
lp="3184,591",
bb="3117,356,3251,603",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 3184 586 0 32 4 -S 27 ",
_draw_="S 4 -bold c 7 -#00C0C0 p 4 3117 356 3117 603 3251 603 3251 356 ",
xdotversion=""];
"UV read_tree (43)" [label=read_tree, width="1.58", height="0.50", style=bold, color="#00C0C0", pos="3182,552", _draw_="S 4 -bold c 7 -#00C0C0 e 3182 552 57 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 3182 547 0 67 9 -read_tree "];
"UV build_tree (44)" [label=build_tree, width="1.64", height="0.50", style=bold, color="#00C0C0", pos="3184,382", _draw_="S 4 -bold c 7 -#00C0C0 e 3184 382 59 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 3184 377 0 69 10 -build_tree "];
"UV unpack (45)" [label=unpack, width="1.28", height="0.49", style=bold, color="#00C0C0", pos="3179,467", _draw_="S 4 -bold c 7 -#00C0C0 e 3179 467 46 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 3179 462 0 50 6 -unpack "];
"UV read_tree (43)" -> "UV unpack (45)" [style=invis, minlen=0, pos="e,3174,484 3176,534 3174,522 3173,507 3174,494"];
"UV build_tree (44)" -> "UV unpack (45)" [style=invis, minlen=0, pos="e,3186,449 3189,400 3189,411 3188,426 3187,439"];
"UV unpack (45)" -> "UV read_tree (43)" [pos="e,3187,534 3185,484 3187,496 3188,511 3187,524", _draw_="c 5 -black B 4 3185 484 3187 496 3188 511 3187 524 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 3184 524 3187 534 3191 524 "];
"UV unpack (45)" -> "UV build_tree (44)" [pos="e,3177,400 3174,449 3173,438 3174,423 3176,410", _draw_="c 5 -black B 4 3174 449 3173 438 3174 423 3176 410 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 3179 410 3177 400 3173 410 "];
"UV unpack (45)" -> "UV unpack (45)" [style=invis, minlen=0, pos="e,3206,453 3206,481 3225,485 3243,481 3243,467 3243,456 3231,451 3216,452"];
}
subgraph cluster_40 {
graph [label="S 40",
color="#400040",
style=bold,
lp="1421,421",
bb="1325,356,1517,433",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 1421 416 0 32 4 -S 40 ",
_draw_="S 4 -bold c 7 -#400040 p 4 1325 356 1325 433 1517 433 1517 356 ",
xdotversion=""];
"UV flush_window (16)" [label=flush_window, width="2.19", height="0.49", style=bold, color="#400040", pos="1412,382", _draw_="S 4 -bold c 7 -#400040 e 1412 382 79 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 1412 377 0 96 12 -flush_window "];
"UV flush_window (16)" -> "UV flush_window (16)" [style=invis, minlen=0, pos="e,1456,367 1456,397 1483,400 1509,395 1509,382 1509,371 1489,365 1466,366"];
}
subgraph cluster_28 {
graph [label="S 28",
color="#804040",
style=bold,
lp="5518,591",
bb="5457,526,5579,603",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 5518 586 0 32 4 -S 28 ",
_draw_="S 4 -bold c 7 -#804040 p 4 5457 526 5457 603 5579 603 5579 526 ",
xdotversion=""];
"UV license (89)" [label=license, width="1.22", height="0.49", style=bold, color="#804040", pos="5509,552", _draw_="S 4 -bold c 7 -#804040 e 5509 552 44 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 5509 547 0 47 7 -license "];
"UV license (89)" -> "UV license (89)" [style=invis, minlen=0, pos="e,5535,538 5535,566 5553,571 5571,566 5571,552 5571,541 5559,535 5545,536"];
}
subgraph cluster_41 {
graph [label="S 41",
color="#4000C0",
style=bold,
lp="7566,251",
bb="7505,186,7627,263",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 7566 246 0 32 4 -S 41 ",
_draw_="S 4 -bold c 7 -#4000C0 p 4 7505 186 7505 263 7627 263 7627 186 ",
xdotversion=""];
"UV strrchr (21)" [label=strrchr, width="1.22", height="0.49", style=dotted, color="#4000C0", pos="7557,212", _draw_="S 6 -dotted c 7 -#4000C0 e 7557 212 44 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 7557 207 0 47 7 -strrchr "];
"UV strrchr (21)" -> "UV strrchr (21)" [style=invis, minlen=0, pos="e,7583,198 7583,226 7601,231 7619,226 7619,212 7619,201 7607,195 7593,196"];
}
subgraph cluster_42 {
graph [label="S 42",
color="#408040",
style=bold,
lp="5595,506",
bb="5518,441,5672,518",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 5595 501 0 32 4 -S 42 ",
_draw_="S 4 -bold c 7 -#408040 p 4 5518 441 5518 518 5672 518 5672 441 ",
xdotversion=""];
"UV clear_bufs (14)" [label=clear_bufs, width="1.67", height="0.49", style=bold, color="#408040", pos="5586,467", _draw_="S 4 -bold c 7 -#408040 e 5586 467 60 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 5586 462 0 69 10 -clear_bufs "];
"UV clear_bufs (14)" -> "UV clear_bufs (14)" [style=invis, minlen=0, pos="e,5620,453 5620,481 5642,485 5664,481 5664,467 5664,455 5648,450 5630,452"];
}
subgraph cluster_29 {
graph [label="S 29",
color="#8040C0",
style=bold,
lp="4525,421",
bb="4455,356,4595,433",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 4525 416 0 32 4 -S 29 ",
_draw_="S 4 -bold c 7 -#8040C0 p 4 4455 356 4455 433 4595 433 4595 356 ",
xdotversion=""];
"UV file_read (8)" [label=file_read, width="1.47", height="0.49", style=bold, color="#8040C0", pos="4516,382", _draw_="S 4 -bold c 7 -#8040C0 e 4516 382 53 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 4516 377 0 59 9 -file_read "];
"UV file_read (8)" -> "UV file_read (8)" [style=invis, minlen=0, pos="e,4546,368 4546,396 4567,400 4587,396 4587,382 4587,370 4573,366 4556,367"];
}
subgraph cluster_43 {
graph [label="S 43",
color="#4080C0",
style=bold,
lp="5351,421",
bb="5267,356,5435,433",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 5351 416 0 32 4 -S 43 ",
_draw_="S 4 -bold c 7 -#4080C0 p 4 5267 356 5267 433 5435 433 5435 356 ",
xdotversion=""];
"UV write_error (18)" [label=write_error, width="1.86", height="0.49", style=bold, color="#4080C0", pos="5342,382", _draw_="S 4 -bold c 7 -#4080C0 e 5342 382 67 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 5342 377 0 79 11 -write_error "];
"UV write_error (18)" -> "UV write_error (18)" [style=invis, minlen=0, pos="e,5380,367 5380,397 5404,400 5427,395 5427,382 5427,371 5410,366 5390,366"];
}
subgraph cluster_44 {
graph [label="S 44",
color="#C00040",
style=bold,
lp="8189,336",
bb="8131,271,8247,348",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 8189 331 0 32 4 -S 44 ",
_draw_="S 4 -bold c 7 -#C00040 p 4 8131 271 8131 348 8247 348 8247 271 ",
xdotversion=""];
"UV perror (36)" [label=perror, width="1.14", height="0.49", style=dotted, color="#C00040", pos="8180,297", _draw_="S 6 -dotted c 7 -#C00040 e 8180 297 41 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 8180 292 0 43 6 -perror "];
"UV perror (36)" -> "UV perror (36)" [style=invis, minlen=0, pos="e,8204,283 8204,311 8222,316 8239,311 8239,297 8239,286 8228,280 8214,281"];
}
subgraph cluster_10 {
graph [label="S 10",
color="#008040",
style=bold,
lp="8260,166",
bb="8199,101,8321,178",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 8260 161 0 32 4 -S 10 ",
_draw_="S 4 -bold c 7 -#008040 p 4 8199 101 8199 178 8321 178 8321 101 ",
xdotversion=""];
"UV strcmp (92)" [label=strcmp, width="1.22", height="0.49", style=dotted, color="#008040", pos="8251,127", _draw_="S 6 -dotted c 7 -#008040 e 8251 127 44 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 8251 122 0 47 6 -strcmp "];
"UV strcmp (92)" -> "UV strcmp (92)" [style=invis, minlen=0, pos="e,8277,113 8277,141 8295,146 8313,141 8313,127 8313,116 8301,110 8287,111"];
}
subgraph cluster_1 {
graph [label="S 1",
color="#000080",
style=bold,
lp="2404,506",
bb="2346,441,2462,518",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 2404 501 0 23 3 -S 1 ",
_draw_="S 4 -bold c 7 -#000080 p 4 2346 441 2346 518 2462 518 2462 441 ",
xdotversion=""];
"UV unlzw (46)" [label=unlzw, width="1.14", height="0.49", style=bold, color="#000080", pos="2395,467", _draw_="S 4 -bold c 7 -#000080 e 2395 467 41 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 2395 462 0 43 5 -unlzw "];
"UV unlzw (46)" -> "UV unlzw (46)" [style=invis, minlen=0, pos="e,2419,453 2419,481 2437,486 2454,481 2454,467 2454,456 2443,450 2429,451"];
}
subgraph cluster_45 {
graph [label="S 45",
color="#C000C0",
style=bold,
lp="4693,421",
bb="4603,271,4783,433",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 4693 416 0 32 4 -S 45 ",
_draw_="S 4 -bold c 7 -#C000C0 p 4 4603 271 4603 433 4783 433 4783 271 ",
xdotversion=""];
"UV display_ratio (37)" [label=display_ratio, width="2.03", height="0.49", style=bold, color="#C000C0", pos="4684,382", _draw_="S 4 -bold c 7 -#C000C0 e 4684 382 73 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 4684 377 0 87 13 -display_ratio "];
"UV _IO_putc (38)" [label=_IO_putc, width="1.47", height="0.50", style=dotted, color="#C000C0", pos="4684,297", _draw_="S 6 -dotted c 7 -#C000C0 e 4684 297 53 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 4684 292 0 61 8 -_IO_putc "];
"UV display_ratio (37)" -> "UV display_ratio (37)" [style=invis, minlen=0, pos="e,4725,367 4725,397 4750,400 4775,395 4775,382 4775,371 4756,366 4735,366"];
"UV display_ratio (37)" -> "UV _IO_putc (38)" [pos="e,4679,315 4678,364 4677,353 4677,338 4678,325", _draw_="c 5 -black B 4 4678 364 4677 353 4677 338 4678 325 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 4681 325 4679 315 4675 325 "];
"UV _IO_putc (38)" -> "UV display_ratio (37)" [style=invis, minlen=0, pos="e,4690,364 4689,315 4691,326 4691,341 4691,354"];
}
subgraph cluster_46 {
graph [label="S 46",
color="#C08040",
style=bold,
lp="2917,506",
bb="2835,441,2999,518",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 2917 501 0 32 4 -S 46 ",
_draw_="S 4 -bold c 7 -#C08040 p 4 2835 441 2835 518 2999 518 2999 441 ",
xdotversion=""];
"UV (86)" [label="", width="1.81", height="0.49", style=bold, color="#C08040", pos="2908,467", _draw_="S 4 -bold c 7 -#C08040 e 2908 467 65 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 2908 462 0 76 10 - "];
"UV (86)" -> "UV (86)" [style=invis, minlen=0, pos="e,2944,452 2944,482 2968,485 2991,480 2991,467 2991,456 2974,451 2954,451"];
}
subgraph cluster_2 {
graph [label="S 2",
color="#008000",
style=bold,
lp="1814,825",
bb="1525,356,2103,837",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 1814 820 0 23 3 -S 2 ",
_draw_="S 4 -bold c 7 -#008000 p 4 1525 356 1525 837 2103 837 2103 356 ",
xdotversion=""];
"UV unzip (41)" [label=unzip, width="1.06", height="0.49", style=bold, color="#008000", pos="1695,786", _draw_="S 4 -bold c 7 -#008000 e 1695 786 38 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 1695 781 0 38 5 -unzip "];
"UV inflate (42)" [label=inflate, width="1.14", height="0.50", style=bold, color="#008000", pos="1574,714", _draw_="S 4 -bold c 7 -#008000 e 1574 714 41 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 1574 709 0 44 7 -inflate "];
"UV huft_build (79)" [label=huft_build, width="1.64", height="0.50", style=bold, color="#008000", pos="2036,467", _draw_="S 4 -bold c 7 -#008000 e 2036 467 59 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 2036 462 0 69 10 -huft_build "];
"UV huft_free (80)" [label=huft_free, width="1.53", height="0.50", style=bold, color="#008000", pos="1958,382", _draw_="S 4 -bold c 7 -#008000 e 1958 382 55 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 1958 377 0 63 9 -huft_free "];
"UV inflate_codes (81)" [label=inflate_codes, width="2.03", height="0.50", style=bold, color="#008000", pos="1800,467", _draw_="S 4 -bold c 7 -#008000 e 1800 467 73 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 1800 462 0 90 13 -inflate_codes "];
"UV inflate_stored (82)" [label=inflate_stored, width="2.14", height="0.50", style=bold, color="#008000", pos="1806,552", _draw_="S 4 -bold c 7 -#008000 e 1806 552 77 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 1806 547 0 95 14 -inflate_stored "];
"UV inflate_fixed (83)" [label=inflate_fixed, width="1.92", height="0.50", style=bold, color="#008000", pos="1642,552", _draw_="S 4 -bold c 7 -#008000 e 1642 552 69 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 1642 547 0 84 13 -inflate_fixed "];
"UV inflate_dynamic (84)" [label=inflate_dynamic, width="2.42", height="0.50", style=bold, color="#008000", pos="1988,552", _draw_="S 4 -bold c 7 -#008000 e 1988 552 87 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 1988 547 0 109 15 -inflate_dynamic "];
"UV inflate_block (85)" [label=inflate_block, width="1.97", height="0.50", style=bold, color="#008000", pos="1803,637", _draw_="S 4 -bold c 7 -#008000 e 1803 637 71 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 1803 632 0 87 13 -inflate_block "];
"UV unzip (41)" -> "UV unzip (41)" [style=invis, minlen=0, pos="e,1721,773 1721,799 1737,801 1751,797 1751,786 1751,777 1742,773 1731,773"];
"UV unzip (41)" -> "UV inflate (42)" [pos="e,1594,730 1668,773 1649,763 1623,748 1603,735", _draw_="c 5 -black B 4 1668 773 1649 763 1623 748 1603 735 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 1604 732 1594 730 1601 738 "];
"UV inflate (42)" -> "UV unzip (41)" [style=invis, minlen=0, pos="e,1675,771 1602,727 1621,738 1647,753 1666,766"];
"UV inflate (42)" -> "UV inflate_block (85)" [pos="e,1760,652 1607,703 1644,691 1706,670 1750,655", _draw_="c 5 -black B 4 1607 703 1644 691 1706 670 1750 655 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 1751 658 1760 652 1749 652 "];
"UV huft_build (79)" -> "UV unzip (41)" [style=invis, minlen=0, pos="e,1732,782 2056,485 2066,495 2078,510 2084,526 2096,558 2102,573 2084,603 2011,726 1829,768 1742,781"];
"UV huft_build (79)" -> "UV huft_free (80)" [pos="e,1974,399 2020,449 2009,436 1994,420 1981,406", _draw_="c 5 -black B 4 2020 449 2009 436 1994 420 1981 406 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 1984 404 1974 399 1979 409 "];
"UV huft_free (80)" -> "UV unzip (41)" [style=invis, minlen=0, pos="e,1676,771 1903,385 1841,390 1737,403 1655,441 1601,466 1576,471 1549,526 1535,556 1545,569 1549,603 1550,606 1551,607 1551,611 \
1559,645 1541,664 1566,688 1585,705 1604,680 1624,696 1638,706 1630,717 1639,732 1647,744 1658,755 1668,764"];
"UV inflate_codes (81)" -> "UV unzip (41)" [style=invis, minlen=0, pos="e,1685,769 1733,474 1671,483 1585,499 1564,526 1543,552 1553,570 1564,603 1582,653 1609,652 1639,696 1654,717 1670,741 1680,760"];
"UV inflate_stored (82)" -> "UV unzip (41)" [style=invis, minlen=0, pos="e,1694,768 1771,568 1754,578 1734,592 1723,611 1695,656 1692,721 1694,758"];
"UV inflate_fixed (83)" -> "UV unzip (41)" [style=invis, minlen=0, pos="e,1691,768 1646,570 1655,611 1678,710 1689,758"];
"UV inflate_fixed (83)" -> "UV huft_build (79)" [pos="e,2001,482 1680,537 1693,532 1707,528 1720,526 1791,512 1812,531 1882,518 1920,511 1961,496 1992,485", _draw_="c 5 -black B 10 1680 537 1693 532 1707 528 1720 526 1791 512 1812 531 1882 518 1920 511 1961 496 1992 485 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 1993 488 2001 482 1990 482 "];
"UV inflate_fixed (83)" -> "UV huft_free (80)" [pos="e,1908,390 1649,534 1660,509 1684,465 1718,441 1747,420 1837,402 1898,392", _draw_="c 5 -black B 7 1649 534 1660 509 1684 465 1718 441 1747 420 1837 402 1898 392 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 1899 395 1908 390 1898 389 "];
"UV inflate_fixed (83)" -> "UV inflate_codes (81)" [pos="e,1769,483 1672,536 1697,523 1733,503 1760,488", _draw_="c 5 -black B 4 1672 536 1697 523 1733 503 1760 488 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 1762 491 1769 483 1759 485 "];
"UV inflate_dynamic (84)" -> "UV unzip (41)" [style=invis, minlen=0, pos="e,1725,775 1978,570 1961,598 1925,652 1883,688 1838,726 1775,755 1734,771"];
"UV inflate_dynamic (84)" -> "UV huft_build (79)" [pos="e,2026,485 1998,534 2004,523 2013,507 2021,494", _draw_="c 5 -black B 4 1998 534 2004 523 2013 507 2021 494 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 2024 495 2026 485 2018 492 "];
"UV inflate_dynamic (84)" -> "UV huft_free (80)" [pos="e,1957,400 1976,534 1973,529 1970,523 1968,518 1956,482 1956,438 1957,410", _draw_="c 5 -black B 7 1976 534 1973 529 1970 523 1968 518 1956 482 1956 438 1957 410 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 1961 410 1957 400 1954 410 "];
"UV inflate_dynamic (84)" -> "UV inflate_codes (81)" [pos="e,1835,483 1952,536 1921,522 1877,502 1844,487", _draw_="c 5 -black B 4 1952 536 1921 522 1877 502 1844 487 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 1846 484 1835 483 1843 490 "];
"UV inflate_block (85)" -> "UV unzip (41)" [style=invis, minlen=0, pos="e,1707,769 1790,655 1771,681 1734,731 1713,761"];
"UV inflate_block (85)" -> "UV inflate_stored (82)" [pos="e,1806,570 1804,619 1805,608 1805,593 1805,580", _draw_="c 5 -black B 4 1804 619 1805 608 1805 593 1805 580 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 1808 580 1806 570 1802 580 "];
"UV inflate_block (85)" -> "UV inflate_fixed (83)" [pos="e,1666,569 1763,622 1749,616 1734,610 1720,603 1704,595 1688,584 1675,575", _draw_="c 5 -black B 7 1763 622 1749 616 1734 610 1720 603 1704 595 1688 584 1675 575 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 1676 572 1666 569 1672 577 "];
"UV inflate_block (85)" -> "UV inflate_dynamic (84)" [pos="e,1958,569 1844,622 1860,617 1877,610 1892,603 1911,595 1932,583 1949,574", _draw_="c 5 -black B 7 1844 622 1860 617 1877 610 1892 603 1911 595 1932 583 1949 574 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 1951 577 1958 569 1948 571 "];
}
subgraph cluster_11 {
graph [label="S 11",
color="#0080C0",
style=bold,
lp="4312,506",
bb="4177,356,4447,518",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 4312 501 0 32 4 -S 11 ",
_draw_="S 4 -bold c 7 -#0080C0 p 4 4177 356 4177 518 4447 518 4447 356 ",
xdotversion=""];
"UV do_list (101)" [label=do_list, width="1.17", height="0.49", style=bold, color="#0080C0", pos="4312,467", _draw_="S 4 -bold c 7 -#0080C0 e 4312 467 42 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 4312 462 0 44 7 -do_list "];
"UV printf (122)" [label=printf, width="1.03", height="0.50", style=dotted, color="#0080C0", pos="4222,382", _draw_="S 6 -dotted c 7 -#0080C0 e 4222 382 37 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 4222 377 0 38 6 -printf "];
"UV lseek (123)" [label=lseek, width="0.97", height="0.50", style=dotted, color="#0080C0", pos="4312,382", _draw_="S 6 -dotted c 7 -#0080C0 e 4312 382 35 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 4312 377 0 35 5 -lseek "];
"UV ctime (124)" [label=ctime, width="1.03", height="0.50", style=dotted, color="#0080C0", pos="4402,382", _draw_="S 6 -dotted c 7 -#0080C0 e 4402 382 37 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 4402 377 0 38 5 -ctime "];
"UV do_list (101)" -> "UV do_list (101)" [style=invis, minlen=0, pos="e,4337,453 4337,481 4355,486 4372,481 4372,467 4372,456 4361,450 4347,451"];
"UV do_list (101)" -> "UV printf (122)" [pos="e,4229,400 4285,453 4276,447 4267,440 4259,433 4251,426 4242,416 4236,408", _draw_="c 5 -black B 7 4285 453 4276 447 4267 440 4259 433 4251 426 4242 416 4236 408 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 4238 405 4229 400 4233 410 "];
"UV do_list (101)" -> "UV lseek (123)" [pos="e,4307,400 4306,449 4305,438 4305,423 4306,410", _draw_="c 5 -black B 4 4306 449 4305 438 4305 423 4306 410 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 4309 410 4307 400 4303 410 "];
"UV do_list (101)" -> "UV ctime (124)" [pos="e,4382,397 4326,450 4333,445 4340,439 4347,433 4356,424 4366,414 4375,405", _draw_="c 5 -black B 7 4326 450 4333 445 4340 439 4347 433 4356 424 4366 414 4375 405 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 4378 407 4382 397 4373 402 "];
"UV printf (122)" -> "UV do_list (101)" [style=invis, minlen=0, pos="e,4298,450 4242,397 4253,408 4265,422 4277,433 4281,437 4286,440 4290,443"];
"UV lseek (123)" -> "UV do_list (101)" [style=invis, minlen=0, pos="e,4318,449 4317,400 4319,411 4319,426 4319,439"];
"UV ctime (124)" -> "UV do_list (101)" [style=invis, minlen=0, pos="e,4339,453 4395,400 4388,410 4376,423 4365,433 4359,438 4354,443 4347,447"];
}
subgraph cluster_12 {
graph [label="S 12",
color="#800040",
style=bold,
lp="5650,591",
bb="5587,526,5713,603",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 5650 586 0 32 4 -S 12 ",
_draw_="S 4 -bold c 7 -#800040 p 4 5587 526 5587 603 5713 603 5713 526 ",
xdotversion=""];
"UV version (90)" [label=version, width="1.28", height="0.49", style=bold, color="#800040", pos="5641,552", _draw_="S 4 -bold c 7 -#800040 e 5641 552 46 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 5641 547 0 50 7 -version "];
"UV version (90)" -> "UV version (90)" [style=invis, minlen=0, pos="e,5668,538 5668,566 5687,570 5705,566 5705,552 5705,541 5693,536 5678,537"];
}
subgraph cluster_47 {
graph [label="S 47",
color="#C080C0",
style=bold,
lp="7960,336",
bb="7905,271,8015,348",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 7960 331 0 32 4 -S 47 ",
_draw_="S 4 -bold c 7 -#C080C0 p 4 7905 271 7905 348 8015 348 8015 271 ",
xdotversion=""];
"UV fileno (102)" [label=fileno, width="1.06", height="0.49", style=dotted, color="#C080C0", pos="7951,297", _draw_="S 6 -dotted c 7 -#C080C0 e 7951 297 38 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 7951 292 0 38 6 -fileno "];
"UV fileno (102)" -> "UV fileno (102)" [style=invis, minlen=0, pos="e,7974,283 7974,311 7990,316 8007,311 8007,297 8007,286 7996,281 7984,281"];
}
subgraph cluster_3 {
graph [label="S 3",
color="#008080",
style=bold,
lp="7628,336",
bb="7505,271,7751,348",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 7628 331 0 23 3 -S 3 ",
_draw_="S 4 -bold c 7 -#008080 p 4 7505 271 7505 348 7751 348 7751 271 ",
xdotversion=""];
"UV make_simple_name (22)" [label=make_simple_name, width="2.94", height="0.49", style=bold, color="#008080", pos="7619,297", _draw_="S 4 -bold c 7 -#008080 e 7619 297 106 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 7619 292 0 134 16 -make_simple_name "];
"UV make_simple_name (22)" -> "UV make_simple_name (22)" [style=invis, minlen=0, pos="e,7676,282 7676,312 7711,315 7743,310 7743,297 7743,285 7717,280 7686,281"];
}
subgraph cluster_48 {
graph [label="S 48",
color="#404000",
style=bold,
lp="4238,336",
bb="4158,271,4318,348",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 4238 331 0 32 4 -S 48 ",
_draw_="S 4 -bold c 7 -#404000 p 4 4158 271 4158 348 4318 348 4318 271 ",
xdotversion=""];
"UV abort_gzip (34)" [label=abort_gzip, width="1.75", height="0.49", style=bold, color="#404000", pos="4229,297", _draw_="S 4 -bold c 7 -#404000 e 4229 297 63 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 4229 292 0 73 10 -abort_gzip "];
"UV abort_gzip (34)" -> "UV abort_gzip (34)" [style=invis, minlen=0, pos="e,4265,282 4265,312 4288,315 4310,310 4310,297 4310,286 4294,281 4275,281"];
}
subgraph cluster_13 {
graph [label="S 13",
color="#8000C0",
style=bold,
lp="3669,591",
bb="3465,441,3873,603",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 3669 586 0 32 4 -S 13 ",
_draw_="S 4 -bold c 7 -#8000C0 p 4 3465 441 3465 603 3873 603 3873 441 ",
xdotversion=""];
"UV add_envopt (23)" [label=add_envopt, width="1.89", height="0.49", style=bold, color="#8000C0", pos="3779,552", _draw_="S 4 -bold c 7 -#8000C0 e 3779 552 68 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 3779 547 0 80 10 -add_envopt "];
"UV getenv (24)" [label=getenv, width="1.22", height="0.50", style=dotted, color="#8000C0", pos="3517,467", _draw_="S 6 -dotted c 7 -#8000C0 e 3517 467 44 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 3517 462 0 48 6 -getenv "];
"UV xmalloc (26)" [label=xmalloc, width="1.31", height="0.50", style=bold, color="#8000C0", pos="3626,467", _draw_="S 4 -bold c 7 -#8000C0 e 3626 467 47 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 3626 462 0 52 7 -xmalloc "];
"UV strspn (28)" [label=strspn, width="1.14", height="0.50", style=dotted, color="#8000C0", pos="3732,467", _draw_="S 6 -dotted c 7 -#8000C0 e 3732 467 41 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 3732 462 0 43 6 -strspn "];
"UV calloc (31)" [label=calloc, width="1.03", height="0.50", style=dotted, color="#8000C0", pos="3828,467", _draw_="S 6 -dotted c 7 -#8000C0 e 3828 467 37 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 3828 462 0 38 6 -calloc "];
"UV add_envopt (23)" -> "UV add_envopt (23)" [style=invis, minlen=0, pos="e,3817,537 3817,567 3841,570 3865,565 3865,552 3865,541 3847,536 3827,536"];
"UV add_envopt (23)" -> "UV getenv (24)" [pos="e,3523,485 3714,546 3660,541 3587,531 3561,518 3549,512 3538,502 3530,493", _draw_="c 5 -black B 7 3714 546 3660 541 3587 531 3561 518 3549 512 3538 502 3530 493 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 3532 490 3523 485 3527 495 "];
"UV add_envopt (23)" -> "UV xmalloc (26)" [pos="e,3635,485 3727,541 3709,535 3690,528 3673,518 3662,511 3651,501 3642,492", _draw_="c 5 -black B 7 3727 541 3709 535 3690 528 3673 518 3662 511 3651 501 3642 492 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 3645 490 3635 485 3640 495 "];
"UV add_envopt (23)" -> "UV strspn (28)" [pos="e,3737,485 3764,535 3757,523 3748,508 3741,494", _draw_="c 5 -black B 4 3764 535 3757 523 3748 508 3741 494 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 3744 493 3737 485 3738 496 "];
"UV add_envopt (23)" -> "UV calloc (31)" [pos="e,3813,484 3784,534 3790,522 3799,506 3807,493", _draw_="c 5 -black B 4 3784 534 3790 522 3799 506 3807 493 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 3810 494 3813 484 3805 490 "];
"UV getenv (24)" -> "UV add_envopt (23)" [style=invis, minlen=0, pos="e,3716,545 3537,483 3548,495 3563,510 3579,518 3601,529 3659,538 3706,544"];
"UV xmalloc (26)" -> "UV add_envopt (23)" [style=invis, minlen=0, pos="e,3737,538 3648,483 3661,494 3676,508 3691,518 3702,524 3715,530 3727,535"];
"UV strspn (28)" -> "UV add_envopt (23)" [style=invis, minlen=0, pos="e,3775,534 3747,484 3755,495 3764,511 3770,525"];
"UV calloc (31)" -> "UV add_envopt (23)" [style=invis, minlen=0, pos="e,3794,535 3823,485 3817,497 3808,513 3800,526"];
}
subgraph cluster_4 {
graph [label="S 4",
color="#800000",
style=bold,
lp="6919,591",
bb="6409,186,7429,603",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 6919 586 0 23 3 -S 4 ",
_draw_="S 4 -bold c 7 -#800000 p 4 6409 186 6409 603 7429 603 7429 186 ",
xdotversion=""];
"UV treat_file (99)" [label=treat_file, width="1.53", height="0.49", style=bold, color="#800000", pos="6776,552", _draw_="S 4 -bold c 7 -#800000 e 6776 552 55 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 6776 547 0 62 10 -treat_file "];
"UV get_istat (106)" [label=get_istat, width="1.47", height="0.50", style=bold, color="#800000", pos="7196,467", _draw_="S 4 -bold c 7 -#800000 e 7196 467 53 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 7196 462 0 61 9 -get_istat "];
"UV make_ofname (107)" [label=make_ofname, width="2.14", height="0.50", style=bold, color="#800000", pos="7344,467", _draw_="S 4 -bold c 7 -#800000 e 7344 467 77 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 7344 462 0 95 11 -make_ofname "];
"UV open (108)" [label=open, width="0.94", height="0.50", style=dotted, color="#800000", pos="6491,382", _draw_="S 6 -dotted c 7 -#800000 e 6491 382 34 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 6491 377 0 34 4 -open "];
"UV create_outfile (110)" [label=create_outfile, width="2.14", height="0.50", style=bold, color="#800000", pos="6660,467", _draw_="S 4 -bold c 7 -#800000 e 6660 467 77 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 6660 462 0 95 14 -create_outfile "];
"UV copy_stat (112)" [label=copy_stat, width="1.58", height="0.50", style=bold, color="#800000", pos="7008,467", _draw_="S 4 -bold c 7 -#800000 e 7008 467 57 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 7008 462 0 66 9 -copy_stat "];
"UV check_ofname (113)" [label=check_ofname, width="2.19", height="0.50", style=bold, color="#800000", pos="6722,382", _draw_="S 4 -bold c 7 -#800000 e 6722 382 79 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 6722 377 0 98 12 -check_ofname "];
"UV name_too_long (114)" [label=name_too_long, width="2.33", height="0.50", style=bold, color="#800000", pos="6521,297", _draw_="S 4 -bold c 7 -#800000 e 6521 297 84 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 6521 292 0 105 13 -name_too_long "];
"UV shorten_name (115)" [label=shorten_name, width="2.22", height="0.50", style=bold, color="#800000", pos="6703,297", _draw_="S 4 -bold c 7 -#800000 e 6703 297 80 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 6703 292 0 99 12 -shorten_name "];
"UV do_stat (116)" [label=do_stat, width="1.28", height="0.50", style=bold, color="#800000", pos="6885,382", _draw_="S 4 -bold c 7 -#800000 e 6885 382 46 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 6885 377 0 51 7 -do_stat "];
"UV lstat (117)" [label=lstat, width="0.89", height="0.50", style=dotted, color="#800000", pos="7173,297", _draw_="S 6 -dotted c 7 -#800000 e 7173 297 32 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 7173 292 0 31 5 -lstat "];
"UV stat (118)" [label=stat, width="0.83", height="0.50", style=dotted, color="#800000", pos="6848,212", _draw_="S 6 -dotted c 7 -#800000 e 6848 212 30 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 6848 207 0 27 4 -stat "];
"UV get_suffix (119)" [label=get_suffix, width="1.61", height="0.50", style=bold, color="#800000", pos="7361,212", _draw_="S 4 -bold c 7 -#800000 e 7361 212 58 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 7361 207 0 68 10 -get_suffix "];
"UV strcat (120)" [label=strcat, width="1.08", height="0.50", style=dotted, color="#800000", pos="7342,382", _draw_="S 6 -dotted c 7 -#800000 e 7342 382 39 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 7342 377 0 40 6 -strcat "];
"UV same_file (125)" [label=same_file, width="1.53", height="0.50", style=bold, color="#800000", pos="7000,212", _draw_="S 4 -bold c 7 -#800000 e 7000 212 55 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 7000 207 0 64 9 -same_file "];
"UV fflush (126)" [label=fflush, width="1.03", height="0.50", style=dotted, color="#800000", pos="6838,297", _draw_="S 6 -dotted c 7 -#800000 e 6838 297 37 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 6838 292 0 38 6 -fflush "];
"UV fgets (127)" [label=fgets, width="0.94", height="0.50", style=dotted, color="#800000", pos="6927,297", _draw_="S 6 -dotted c 7 -#800000 e 6927 297 34 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 6927 292 0 34 5 -fgets "];
"UV chmod (128)" [label=chmod, width="1.17", height="0.50", style=dotted, color="#800000", pos="7061,297", _draw_="S 6 -dotted c 7 -#800000 e 7061 297 42 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 7061 292 0 45 5 -chmod "];
"UV reset_times (129)" [label=reset_times, width="1.83", height="0.50", style=bold, color="#800000", pos="7199,382", _draw_="S 4 -bold c 7 -#800000 e 7199 382 66 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 7199 377 0 80 11 -reset_times "];
"UV utime (130)" [label=utime, width="1.08", height="0.50", style=dotted, color="#800000", pos="7282,297", _draw_="S 6 -dotted c 7 -#800000 e 7282 297 39 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 7282 292 0 40 5 -utime "];
"UV chown (131)" [label=chown, width="1.19", height="0.50", style=dotted, color="#800000", pos="7052,382", _draw_="S 6 -dotted c 7 -#800000 e 7052 382 43 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 7052 377 0 46 5 -chown "];
"UV treat_file (99)" -> "UV treat_file (99)" [style=invis, minlen=0, pos="e,6808,538 6808,566 6829,570 6849,566 6849,552 6849,540 6835,536 6818,537"];
"UV treat_file (99)" -> "UV get_istat (106)" [pos="e,7173,483 6831,550 6914,547 7069,538 7120,518 7137,511 7152,500 7165,489", _draw_="c 5 -black B 7 6831 550 6914 547 7069 538 7120 518 7137 511 7152 500 7165 489 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 7167 492 7173 483 7163 486 "];
"UV treat_file (99)" -> "UV make_ofname (107)" [pos="e,7315,484 6831,551 6939,549 7172,542 7249,518 7269,511 7289,500 7306,489", _draw_="c 5 -black B 7 6831 551 6939 549 7172 542 7249 518 7269 511 7289 500 7306 489 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 7308 492 7315 484 7305 486 "];
"UV treat_file (99)" -> "UV open (108)" [pos="e,6486,400 6721,551 6657,548 6559,540 6530,518 6498,491 6487,442 6486,410", _draw_="c 5 -black B 7 6721 551 6657 548 6559 540 6530 518 6498 491 6487 442 6486 410 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 6490 410 6486 400 6483 410 "];
"UV treat_file (99)" -> "UV create_outfile (110)" [pos="e,6678,485 6750,537 6731,524 6706,506 6686,491", _draw_="c 5 -black B 4 6750 537 6731 524 6706 506 6686 491 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 6688 488 6678 485 6684 494 "];
"UV treat_file (99)" -> "UV copy_stat (112)" [pos="e,6982,483 6827,545 6858,540 6896,532 6928,518 6945,511 6960,500 6974,489", _draw_="c 5 -black B 7 6827 545 6858 540 6896 532 6928 518 6945 511 6960 500 6974 489 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 6976 492 6982 483 6972 486 "];
"UV get_istat (106)" -> "UV treat_file (99)" [style=invis, minlen=0, pos="e,6831,550 7186,485 7175,496 7157,510 7138,518 7086,538 6930,546 6841,550"];
"UV get_istat (106)" -> "UV do_stat (116)" [pos="e,6912,397 7153,456 7130,451 7101,445 7074,441 7042,435 7032,441 7000,433 6973,425 6943,412 6921,401", _draw_="c 5 -black B 10 7153 456 7130 451 7101 445 7074 441 7042 435 7032 441 7000 433 6973 425 6943 412 6921 401 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 6923 398 6912 397 6920 404 "];
"UV get_istat (106)" -> "UV get_suffix (119)" [pos="e,7367,230 7225,452 7235,448 7247,443 7258,441 7273,437 7380,443 7390,433 7415,405 7386,293 7370,240", _draw_="c 5 -black B 10 7225 452 7235 448 7247 443 7258 441 7273 437 7380 443 7390 433 7415 405 7386 293 7370 240 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 7373 239 7367 230 7367 241 "];
"UV get_istat (106)" -> "UV strcat (120)" [pos="e,7329,399 7228,453 7237,448 7248,444 7258,441 7272,436 7277,439 7289,433 7301,426 7313,416 7322,407", _draw_="c 5 -black B 10 7228 453 7237 448 7248 444 7258 441 7272 436 7277 439 7289 433 7301 426 7313 416 7322 407 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 7325 409 7329 399 7320 404 "];
"UV make_ofname (107)" -> "UV treat_file (99)" [style=invis, minlen=0, pos="e,6831,551 7328,485 7313,496 7290,510 7267,518 7190,542 6956,550 6841,551"];
"UV make_ofname (107)" -> "UV get_suffix (119)" [pos="e,7378,229 7385,452 7393,447 7401,441 7405,433 7409,427 7404,272 7403,271 7399,259 7392,247 7384,237", _draw_="c 5 -black B 10 7385 452 7393 447 7401 441 7405 433 7409 427 7404 272 7403 271 7399 259 7392 247 7384 237 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 7387 235 7378 229 7381 239 "];
"UV make_ofname (107)" -> "UV strcat (120)" [pos="e,7342,400 7344,449 7343,438 7343,423 7343,410", _draw_="c 5 -black B 4 7344 449 7343 438 7343 423 7343 410 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 7346 410 7342 400 7340 410 "];
"UV open (108)" -> "UV treat_file (99)" [style=invis, minlen=0, pos="e,6721,550 6497,400 6503,429 6512,488 6548,518 6573,538 6652,546 6711,549"];
"UV create_outfile (110)" -> "UV treat_file (99)" [style=invis, minlen=0, pos="e,6759,535 6689,484 6708,497 6732,515 6751,529"];
"UV create_outfile (110)" -> "UV open (108)" [pos="e,6514,396 6620,451 6607,446 6592,439 6579,433 6560,423 6539,411 6523,401", _draw_="c 5 -black B 7 6620 451 6607 446 6592 439 6579 433 6560 423 6539 411 6523 401 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 6524 398 6514 396 6521 404 "];
"UV create_outfile (110)" -> "UV check_ofname (113)" [pos="e,6709,400 6673,449 6681,438 6693,421 6703,408", _draw_="c 5 -black B 4 6673 449 6681 438 6693 421 6703 408 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 6706 410 6709 400 6700 406 "];
"UV create_outfile (110)" -> "UV name_too_long (114)" [pos="e,6529,315 6628,450 6620,445 6612,440 6605,433 6573,401 6548,354 6533,324", _draw_="c 5 -black B 7 6628 450 6620 445 6612 440 6605 433 6573 401 6548 354 6533 324 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 6536 323 6529 315 6530 326 "];
"UV create_outfile (110)" -> "UV shorten_name (115)" [pos="e,6666,313 6633,450 6627,445 6622,439 6619,433 6605,402 6604,386 6619,356 6627,340 6642,328 6657,318", _draw_="c 5 -black B 10 6633 450 6627 445 6622 439 6619 433 6605 402 6604 386 6619 356 6627 340 6642 328 6657 318 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 6659 321 6666 313 6656 315 "];
"UV copy_stat (112)" -> "UV treat_file (99)" [style=invis, minlen=0, pos="e,6829,547 6996,485 6984,496 6965,510 6946,518 6912,533 6872,541 6839,546"];
"UV copy_stat (112)" -> "UV chmod (128)" [pos="e,7078,314 7044,453 7056,449 7068,445 7079,441 7091,437 7098,442 7104,433 7125,405 7115,388 7104,356 7100,344 7093,332 7085,322", _draw_="c 5 -black B 13 7044 453 7056 449 7068 445 7079 441 7091 437 7098 442 7104 433 7125 405 7115 388 7104 356 7100 344 7093 332 7085\
322 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 7087 319 7078 314 7082 324 "];
"UV copy_stat (112)" -> "UV reset_times (129)" [pos="e,7177,399 7044,453 7055,449 7067,444 7079,441 7097,436 7103,439 7119,433 7137,426 7155,415 7169,405", _draw_="c 5 -black B 10 7044 453 7055 449 7067 444 7079 441 7097 436 7103 439 7119 433 7137 426 7155 415 7169 405 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 7171 408 7177 399 7167 402 "];
"UV copy_stat (112)" -> "UV chown (131)" [pos="e,7043,400 7017,449 7023,437 7031,422 7038,409", _draw_="c 5 -black B 4 7017 449 7023 437 7031 422 7038 409 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 7041 410 7043 400 7035 407 "];
"UV check_ofname (113)" -> "UV treat_file (99)" [style=invis, minlen=0, pos="e,6776,534 6737,400 6745,411 6755,426 6761,441 6771,468 6775,501 6776,524"];
"UV check_ofname (113)" -> "UV name_too_long (114)" [pos="e,6549,314 6672,368 6653,362 6633,356 6614,348 6595,340 6575,329 6558,319", _draw_="c 5 -black B 7 6672 368 6653 362 6633 356 6614 348 6595 340 6575 329 6558 319 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 6559 316 6549 314 6556 322 "];
"UV check_ofname (113)" -> "UV shorten_name (115)" [pos="e,6707,315 6718,364 6716,353 6712,338 6709,325", _draw_="c 5 -black B 4 6718 364 6716 353 6712 338 6709 325 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 6712 324 6707 315 6706 325 "];
"UV check_ofname (113)" -> "UV stat (118)" [pos="e,6868,226 6767,367 6782,363 6799,358 6815,356 6833,353 6959,360 6970,348 6994,323 6992,297 6970,271 6961,258 6951,268 6936,263 \
6915,255 6893,242 6877,231", _draw_="c 5 -black B 16 6767 367 6782 363 6799 358 6815 356 6833 353 6959 360 6970 348 6994 323 6992 297 6970 271 6961 258 6951 268 6936\
263 6915 255 6893 242 6877 231 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 6878 228 6868 226 6875 234 "];
"UV check_ofname (113)" -> "UV same_file (125)" [pos="e,7004,230 6767,367 6782,363 6799,358 6815,356 6834,353 6970,360 6983,348 7013,320 7011,271 7006,240", _draw_="c 5 -black B 10 6767 367 6782 363 6799 358 6815 356 6834 353 6970 360 6983 348 7013 320 7011 271 7006 240 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 7009 239 7004 230 7003 240 "];
"UV check_ofname (113)" -> "UV fflush (126)" [pos="e,6825,314 6761,366 6772,361 6783,355 6792,348 6802,340 6811,331 6819,322", _draw_="c 5 -black B 7 6761 366 6772 361 6783 355 6792 348 6802 340 6811 331 6819 322 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 6822 324 6825 314 6816 320 "];
"UV check_ofname (113)" -> "UV fgets (127)" [pos="e,6917,314 6769,367 6783,363 6800,359 6815,356 6846,350 6857,362 6884,348 6895,342 6905,332 6911,323", _draw_="c 5 -black B 10 6769 367 6783 363 6800 359 6815 356 6846 350 6857 362 6884 348 6895 342 6905 332 6911 323 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 6914 324 6917 314 6909 320 "];
"UV check_ofname (113)" -> "UV chmod (128)" [pos="e,7048,314 6767,367 6782,363 6799,358 6815,356 6857,349 6966,364 7005,348 7019,342 7032,332 7041,322", _draw_="c 5 -black B 10 6767 367 6782 363 6799 358 6815 356 6857 349 6966 364 7005 348 7019 342 7032 332 7041 322 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 7044 324 7048 314 7039 319 "];
"UV name_too_long (114)" -> "UV treat_file (99)" [style=invis, minlen=0, pos="e,6721,550 6476,312 6456,321 6435,336 6423,356 6388,418 6378,465 6427,518 6446,538 6615,546 6711,550"];
"UV name_too_long (114)" -> "UV stat (118)" [pos="e,6820,219 6572,283 6586,279 6600,275 6614,271 6683,252 6764,232 6810,221", _draw_="c 5 -black B 7 6572 283 6586 279 6600 275 6614 271 6683 252 6764 232 6810 221 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 6811 224 6820 219 6810 218 "];
"UV name_too_long (114)" -> "UV same_file (125)" [pos="e,6973,228 6567,282 6582,277 6598,273 6614,271 6675,261 6828,276 6887,263 6914,257 6943,244 6964,233", _draw_="c 5 -black B 10 6567 282 6582 277 6598 273 6614 271 6675 261 6828 276 6887 263 6914 257 6943 244 6964 233 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 6966 236 6973 228 6963 230 "];
"UV shorten_name (115)" -> "UV treat_file (99)" [style=invis, minlen=0, pos="e,6724,547 6673,314 6646,329 6611,350 6605,356 6559,412 6527,462 6574,518 6583,528 6658,539 6714,546"];
"UV shorten_name (115)" -> "UV get_suffix (119)" [pos="e,7313,222 6747,282 6761,277 6777,273 6792,271 6912,252 6944,275 7064,263 7148,254 7244,236 7303,224", _draw_="c 5 -black B 10 6747 282 6761 277 6777 273 6792 271 6912 252 6944 275 7064 263 7148 254 7244 236 7303 224 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 7304 227 7313 222 7303 221 "];
"UV do_stat (116)" -> "UV treat_file (99)" [style=invis, minlen=0, pos="e,6804,537 6879,400 6867,432 6841,499 6825,518 6821,522 6816,527 6812,530"];
"UV do_stat (116)" -> "UV lstat (117)" [pos="e,7163,314 6913,367 6923,363 6934,358 6945,356 6985,346 7091,365 7127,348 7139,342 7149,332 7157,322", _draw_="c 5 -black B 10 6913 367 6923 363 6934 358 6945 356 6985 346 7091 365 7127 348 7139 342 7149 332 7157 322 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 7160 324 7163 314 7154 320 "];
"UV do_stat (116)" -> "UV stat (118)" [pos="e,6867,226 6913,367 6923,363 6934,358 6945,356 6964,351 7100,361 7112,348 7136,323 7136,295 7112,271 7099,256 6955,268 6936,263 \
6914,256 6892,244 6875,232", _draw_="c 5 -black B 16 6913 367 6923 363 6934 358 6945 356 6964 351 7100 361 7112 348 7136 323 7136 295 7112 271 7099 256 6955 268 6936\
263 6914 256 6892 244 6875 232 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 6877 229 6867 226 6873 235 "];
"UV lstat (117)" -> "UV treat_file (99)" [style=invis, minlen=0, pos="e,6815,540 7162,314 7154,326 7141,340 7126,348 7110,355 6980,345 6965,356 6937,377 6968,409 6940,433 6922,448 6907,426 6887,441 \
6857,463 6877,491 6849,518 6842,525 6833,530 6824,535"];
"UV stat (118)" -> "UV treat_file (99)" [style=invis, minlen=0, pos="e,6723,547 6818,214 6726,220 6454,241 6428,271 6406,296 6405,322 6428,348 6445,365 6518,339 6534,356 6586,406 6500,465 6549,518 \
6560,529 6650,540 6713,546"];
"UV get_suffix (119)" -> "UV treat_file (99)" [style=invis, minlen=0, pos="e,6831,549 7363,230 7364,259 7362,316 7330,348 7319,359 7306,344 7294,356 7269,380 7302,410 7274,433 7246,456 7138,417 7109,441 \
7082,463 7117,494 7090,518 7072,534 6928,544 6841,549"];
"UV strcat (120)" -> "UV treat_file (99)" [style=invis, minlen=0, pos="e,6831,550 7330,399 7320,411 7306,426 7289,433 7274,439 7148,430 7134,441 7106,462 7137,495 7109,518 7090,534 6932,544 6841,549"];
"UV same_file (125)" -> "UV treat_file (99)" [style=invis, minlen=0, pos="e,6825,544 7051,219 7108,227 7195,245 7214,271 7235,298 7238,323 7214,348 7196,367 6996,339 6975,356 6948,378 6984,409 6957,433 \
6938,451 6918,423 6897,441 6870,464 6898,492 6873,518 6862,529 6849,536 6835,541"];
"UV fflush (126)" -> "UV treat_file (99)" [style=invis, minlen=0, pos="e,6722,548 6828,315 6820,326 6807,341 6792,348 6775,355 6462,342 6448,356 6396,409 6434,476 6496,518 6514,529 6635,541 6712,547"];
"UV fgets (127)" -> "UV treat_file (99)" [style=invis, minlen=0, pos="e,6768,535 6918,315 6910,326 6899,341 6884,348 6872,354 6644,346 6634,356 6623,368 6623,420 6634,433 6652,451 6728,424 6746,441 \
6773,464 6751,484 6761,518 6762,520 6763,523 6764,526"];
"UV chmod (128)" -> "UV treat_file (99)" [style=invis, minlen=0, pos="e,6781,534 7046,314 7035,326 7018,341 7000,348 6983,354 6845,344 6830,356 6803,378 6820,398 6810,433 6801,464 6791,500 6784,524"];
"UV reset_times (129)" -> "UV treat_file (99)" [style=invis, minlen=0, pos="e,6830,549 7174,399 7158,409 7136,422 7116,433 7109,436 7105,434 7099,441 7076,467 7102,495 7074,518 7057,532 6922,543 6840,548"];
"UV reset_times (129)" -> "UV utime (130)" [pos="e,7266,314 7216,364 7229,351 7245,335 7259,321", _draw_="c 5 -black B 4 7216 364 7229 351 7245 335 7259 321 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 7261 324 7266 314 7256 319 "];
"UV utime (130)" -> "UV treat_file (99)" [style=invis, minlen=0, pos="e,6824,543 7270,314 7260,326 7246,341 7229,348 7206,357 7021,340 7000,356 6972,377 7003,409 6975,433 6956,449 6937,423 6917,441 \
6891,464 6922,492 6897,518 6888,527 6860,535 6834,541"];
"UV chown (131)" -> "UV treat_file (99)" [style=invis, minlen=0, pos="e,6826,545 7037,399 7027,411 7012,425 6995,433 6974,443 6961,425 6942,441 6915,464 6944,493 6917,518 6905,529 6869,537 6836,543"];
}
subgraph cluster_49 {
graph [label="S 49",
color="#404080",
style=bold,
lp="8361,251",
bb="8309,186,8413,263",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 8361 246 0 32 4 -S 49 ",
_draw_="S 4 -bold c 7 -#404080 p 4 8309 186 8309 263 8413 263 8413 186 ",
xdotversion=""];
"UV close (109)" [label=close, width="0.97", height="0.49", style=dotted, color="#404080", pos="8352,212", _draw_="S 6 -dotted c 7 -#404080 e 8352 212 35 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 8352 207 0 34 5 -close "];
"UV close (109)" -> "UV close (109)" [style=invis, minlen=0, pos="e,8373,198 8373,226 8389,231 8405,226 8405,212 8405,201 8395,196 8383,196"];
}
subgraph cluster_14 {
graph [label="S 14",
color="#808040",
style=bold,
lp="7456,166",
bb="7398,101,7514,178",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 7456 161 0 32 4 -S 14 ",
_draw_="S 4 -bold c 7 -#808040 p 4 7398 101 7398 178 7514 178 7514 101 ",
xdotversion=""];
"UV strcpy (27)" [label=strcpy, width="1.14", height="0.49", style=dotted, color="#808040", pos="7447,127", _draw_="S 6 -dotted c 7 -#808040 e 7447 127 41 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 7447 122 0 42 6 -strcpy "];
"UV strcpy (27)" -> "UV strcpy (27)" [style=invis, minlen=0, pos="e,7471,113 7471,141 7489,146 7506,141 7506,127 7506,116 7495,110 7481,111"];
}
subgraph cluster_5 {
graph [label="S 5",
color="#800080",
style=bold,
lp="6712,166",
bb="6656,101,6768,178",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 6712 161 0 23 3 -S 5 ",
_draw_="S 4 -bold c 7 -#800080 p 4 6656 101 6656 178 6768 178 6768 101 ",
xdotversion=""];
"UV strlen (25)" [label=strlen, width="1.08", height="0.49", style=dotted, color="#800080", pos="6703,127", _draw_="S 6 -dotted c 7 -#800080 e 6703 127 39 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 6703 122 0 40 6 -strlen "];
"UV strlen (25)" -> "UV strlen (25)" [style=invis, minlen=0, pos="e,6726,113 6726,141 6743,146 6760,141 6760,127 6760,116 6749,110 6736,111"];
}
subgraph cluster_15 {
graph [label="S 15",
color="#8080C0",
style=bold,
lp="6017,591",
bb="5949,526,6085,603",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 6017 586 0 32 4 -S 15 ",
_draw_="S 4 -bold c 7 -#8080C0 p 4 5949 526 5949 603 6085 603 6085 526 ",
xdotversion=""];
"UV strncmp (94)" [label=strncmp, width="1.42", height="0.49", style=dotted, color="#8080C0", pos="6008,552", _draw_="S 6 -dotted c 7 -#8080C0 e 6008 552 51 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 6008 547 0 56 7 -strncmp "];
"UV strncmp (94)" -> "UV strncmp (94)" [style=invis, minlen=0, pos="e,6038,538 6038,566 6058,570 6077,566 6077,552 6077,540 6064,536 6048,537"];
}
subgraph cluster_6 {
graph [label="S 6",
color="#808000",
style=bold,
lp="4812,591",
bb="4730,526,4894,603",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 4812 586 0 23 3 -S 6 ",
_draw_="S 4 -bold c 7 -#808000 p 4 4730 526 4730 603 4894 603 4894 526 ",
xdotversion=""];
"UV treat_stdin (100)" [label=treat_stdin, width="1.81", height="0.49", style=bold, color="#808000", pos="4803,552", _draw_="S 4 -bold c 7 -#808000 e 4803 552 65 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 4803 547 0 76 11 -treat_stdin "];
"UV treat_stdin (100)" -> "UV treat_stdin (100)" [style=invis, minlen=0, pos="e,4839,537 4839,567 4863,570 4886,565 4886,552 4886,541 4869,536 4849,536"];
}
subgraph cluster_16 {
graph [label="S 16",
color="#004000",
style=bold,
lp="5605,336",
bb="5547,271,5663,348",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 5605 331 0 32 4 -S 16 ",
_draw_="S 4 -bold c 7 -#004000 p 4 5547 271 5547 348 5663 348 5663 271 ",
xdotversion=""];
"UV fprintf (33)" [label=fprintf, width="1.14", height="0.49", style=dotted, color="#004000", pos="5596,297", _draw_="S 6 -dotted c 7 -#004000 e 5596 297 41 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 5596 292 0 42 7 -fprintf "];
"UV fprintf (33)" -> "UV fprintf (33)" [style=invis, minlen=0, pos="e,5620,283 5620,311 5638,316 5655,311 5655,297 5655,286 5644,280 5630,281"];
}
subgraph cluster_7 {
graph [label="S 7",
color="#808080",
style=bold,
lp="3411,591",
bb="3365,526,3457,603",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 3411 586 0 23 3 -S 7 ",
_draw_="S 4 -bold c 7 -#808080 p 4 3365 526 3365 603 3457 603 3457 526 ",
xdotversion=""];
"UV atoi (97)" [label=atoi, width="0.81", height="0.49", style=dotted, color="#808080", pos="3402,552", _draw_="S 6 -dotted c 7 -#808080 e 3402 552 29 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 3402 547 0 26 4 -atoi "];
"UV atoi (97)" -> "UV atoi (97)" [style=invis, minlen=0, pos="e,3420,538 3420,566 3434,571 3449,566 3449,552 3449,541 3440,536 3430,536"];
}
subgraph cluster_17 {
graph [label="S 17",
color="#004080",
style=bold,
lp="5518,676",
bb="5466,611,5570,688",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 5518 671 0 32 4 -S 17 ",
_draw_="S 4 -bold c 7 -#004080 p 4 5466 611 5466 688 5570 688 5570 611 ",
xdotversion=""];
"UV main (91)" [label=main, width="0.97", height="0.49", style=bold, color="#004080", pos="5509,637", _draw_="S 4 -bold c 7 -#004080 e 5509 637 35 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 5509 632 0 34 4 -main "];
"UV main (91)" -> "UV main (91)" [style=invis, minlen=0, pos="e,5532,624 5532,650 5547,653 5562,649 5562,637 5562,628 5553,623 5542,623"];
}
subgraph cluster_8 {
graph [label="S 8",
color="#000040",
style=bold,
lp="8984,825",
bb="8665,441,9303,837",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 8984 820 0 23 3 -S 8 ",
_draw_="S 4 -bold c 7 -#000040 p 4 8665 441 8665 837 9303 837 9303 441 ",
xdotversion=""];
"UV fillbuf (49)" [label=fillbuf, width="1.03", height="0.50", style=bold, color="#000040", pos="8714,786", _draw_="S 4 -bold c 7 -#000040 e 8714 786 37 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 8714 781 0 38 7 -fillbuf "];
"UV getbits (50)" [label=getbits, width="1.22", height="0.50", style=bold, color="#000040", pos="8930,467", _draw_="S 4 -bold c 7 -#000040 e 8930 467 44 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 8930 462 0 47 7 -getbits "];
"UV init_getbits (51)" [label=init_getbits, width="1.78", height="0.50", style=bold, color="#000040", pos="8837,552", _draw_="S 4 -bold c 7 -#000040 e 8837 552 64 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 8837 547 0 77 12 -init_getbits "];
"UV make_table (52)" [label=make_table, width="1.83", height="0.50", style=bold, color="#000040", pos="9058,467", _draw_="S 4 -bold c 7 -#000040 e 9058 467 66 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 9058 462 0 79 10 -make_table "];
"UV read_pt_len (53)" [label=read_pt_len, width="1.86", height="0.50", style=bold, color="#000040", pos="9026,552", _draw_="S 4 -bold c 7 -#000040 e 9026 552 67 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 9026 547 0 81 11 -read_pt_len "];
"UV read_c_len (54)" [label=read_c_len, width="1.72", height="0.50", style=bold, color="#000040", pos="9173,552", _draw_="S 4 -bold c 7 -#000040 e 9173 552 62 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 9173 547 0 74 10 -read_c_len "];
"UV decode_c (55)" [label=decode_c, width="1.50", height="0.50", style=bold, color="#000040", pos="9181,637", _draw_="S 4 -bold c 7 -#000040 e 9181 637 54 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 9181 632 0 62 8 -decode_c "];
"UV decode_p (56)" [label=decode_p, width="1.53", height="0.50", style=bold, color="#000040", pos="9054,637", _draw_="S 4 -bold c 7 -#000040 e 9054 637 55 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 9054 632 0 64 8 -decode_p "];
"UV huf_decode_start (57)" [label=huf_decode_start, width="2.61", height="0.50", style=bold, color="#000040", pos="8887,637", _draw_="S 4 -bold c 7 -#000040 e 8887 637 94 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 8887 632 0 119 16 -huf_decode_start "];
"UV decode_start (58)" [label=decode_start, width="2.03", height="0.50", style=bold, color="#000040", pos="8924,714", _draw_="S 4 -bold c 7 -#000040 e 8924 714 73 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 8924 709 0 89 12 -decode_start "];
"UV decode (59)" [label=decode, width="1.22", height="0.50", style=bold, color="#000040", pos="9099,714", _draw_="S 4 -bold c 7 -#000040 e 9099 714 44 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 9099 709 0 48 6 -decode "];
"UV unlzh (60)" [label=unlzh, width="1.08", height="0.49", style=bold, color="#000040", pos="9036,786", _draw_="S 4 -bold c 7 -#000040 e 9036 786 39 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 9036 781 0 39 5 -unlzh "];
"UV fillbuf (49)" -> "UV unlzh (60)" [style=invis, minlen=0, pos="e,8997,786 8751,786 8831,786 8908,786 8987,786"];
"UV getbits (50)" -> "UV fillbuf (49)" [pos="e,8708,768 8889,474 8836,484 8748,503 8725,526 8663,587 8688,705 8705,758", _draw_="c 5 -black B 7 8889 474 8836 484 8748 503 8725 526 8663 587 8688 705 8705 758 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 8702 759 8708 768 8708 757 "];
"UV getbits (50)" -> "UV unlzh (60)" [style=invis, minlen=0, pos="e,9074,781 8942,484 8952,496 8966,511 8983,518 8997,523 9234,515 9244,526 9295,577 9281,625 9244,688 9211,745 9134,769 9084,779"];
"UV init_getbits (51)" -> "UV fillbuf (49)" [pos="e,8708,768 8784,562 8757,570 8726,585 8709,611 8681,656 8694,721 8705,758", _draw_="c 5 -black B 7 8784 562 8757 570 8726 585 8709 611 8681 656 8694 721 8705 758 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 8702 759 8708 768 8708 757 "];
"UV init_getbits (51)" -> "UV unlzh (60)" [style=invis, minlen=0, pos="e,8999,780 8815,569 8804,580 8790,595 8784,611 8772,642 8767,658 8784,688 8788,694 8793,691 8799,696 8820,709 8820,720 8842,732 \
8889,756 8949,771 8989,778"];
"UV make_table (52)" -> "UV unlzh (60)" [style=invis, minlen=0, pos="e,8998,781 9039,484 9025,496 9004,511 8983,518 8972,521 8773,517 8764,526 8700,592 8723,679 8799,732 8829,753 8928,770 8988,779"];
"UV read_pt_len (53)" -> "UV fillbuf (49)" [pos="e,8709,768 8997,568 8974,580 8941,596 8910,603 8891,607 8744,597 8729,611 8690,649 8698,719 8707,758", _draw_="c 5 -black B 10 8997 568 8974 580 8941 596 8910 603 8891 607 8744 597 8729 611 8690 649 8698 719 8707 758 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 8704 759 8709 768 8710 758 "];
"UV read_pt_len (53)" -> "UV getbits (50)" [pos="e,8947,484 9004,535 8997,529 8990,524 8983,518 8974,509 8963,500 8954,491", _draw_="c 5 -black B 7 9004 535 8997 529 8990 524 8983 518 8974 509 8963 500 8954 491 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 8957 489 8947 484 8952 494 "];
"UV read_pt_len (53)" -> "UV make_table (52)" [pos="e,9051,485 9033,534 9037,523 9043,508 9047,495", _draw_="c 5 -black B 4 9033 534 9037 523 9043 508 9047 495 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 9051 496 9051 485 9044 493 "];
"UV read_pt_len (53)" -> "UV unlzh (60)" [style=invis, minlen=0, pos="e,9074,781 9046,569 9060,581 9081,596 9102,603 9117,608 9234,599 9244,611 9268,635 9262,658 9244,688 9211,745 9134,769 9084,779"];
"UV read_c_len (54)" -> "UV fillbuf (49)" [pos="e,8715,768 9155,569 9142,581 9122,596 9102,603 9069,614 8815,592 8784,611 8733,642 8719,717 8716,758", _draw_="c 5 -black B 10 9155 569 9142 581 9122 596 9102 603 9069 614 8815 592 8784 611 8733 642 8719 717 8716 758 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 8713 758 8715 768 8719 758 "];
"UV read_c_len (54)" -> "UV getbits (50)" [pos="e,8943,484 9139,537 9127,532 9114,528 9102,526 9077,520 9008,528 8983,518 8970,512 8959,502 8950,492", _draw_="c 5 -black B 10 9139 537 9127 532 9114 528 9102 526 9077 520 9008 528 8983 518 8970 512 8959 502 8950 492 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 8952 489 8943 484 8947 494 "];
"UV read_c_len (54)" -> "UV make_table (52)" [pos="e,9081,484 9150,535 9133,522 9108,504 9089,490", _draw_="c 5 -black B 4 9150 535 9133 522 9108 504 9089 490 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 9091 487 9081 484 9087 493 "];
"UV read_c_len (54)" -> "UV unlzh (60)" [style=invis, minlen=0, pos="e,9074,781 9203,568 9219,578 9236,592 9244,611 9259,641 9262,658 9244,688 9211,745 9134,769 9084,779"];
"UV decode_c (55)" -> "UV fillbuf (49)" [pos="e,8730,770 9166,654 9154,666 9137,681 9118,688 9061,709 8901,676 8842,696 8801,710 8762,741 8737,763", _draw_="c 5 -black B 10 9166 654 9154 666 9137 681 9118 688 9061 709 8901 676 8842 696 8801 710 8762 741 8737 763 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 8735 760 8730 770 8740 765 "];
"UV decode_c (55)" -> "UV getbits (50)" [pos="e,8931,485 9151,622 9141,617 9129,613 9118,611 9100,606 8964,615 8950,603 8943,596 8935,533 8932,495", _draw_="c 5 -black B 10 9151 622 9141 617 9129 613 9118 611 9100 606 8964 615 8950 603 8943 596 8935 533 8932 495 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 8935 495 8931 485 8929 495 "];
"UV decode_c (55)" -> "UV read_pt_len (53)" [pos="e,9050,569 9147,623 9129,616 9110,607 9102,603 9087,595 9071,584 9058,575", _draw_="c 5 -black B 7 9147 623 9129 616 9110 607 9102 603 9087 595 9071 584 9058 575 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 9060 572 9050 569 9056 578 "];
"UV decode_c (55)" -> "UV read_c_len (54)" [pos="e,9175,570 9179,619 9178,608 9177,593 9176,580", _draw_="c 5 -black B 4 9179 619 9178 608 9177 593 9176 580 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 9179 580 9175 570 9173 580 "];
"UV decode_c (55)" -> "UV unlzh (60)" [style=invis, minlen=0, pos="e,9071,778 9180,655 9178,676 9171,710 9152,732 9134,753 9105,766 9081,775"];
"UV decode_p (56)" -> "UV fillbuf (49)" [pos="e,8722,768 9039,654 9027,666 9009,681 8990,688 8967,696 8791,683 8769,696 8757,703 8739,735 8727,759", _draw_="c 5 -black B 10 9039 654 9027 666 9009 681 8990 688 8967 696 8791 683 8769 696 8757 703 8739 735 8727 759 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 8724 758 8722 768 8730 761 "];
"UV decode_p (56)" -> "UV getbits (50)" [pos="e,8924,485 9022,622 9012,618 9001,614 8990,611 8979,607 8944,612 8935,603 8909,573 8914,526 8921,495", _draw_="c 5 -black B 10 9022 622 9012 618 9001 614 8990 611 8979 607 8944 612 8935 603 8909 573 8914 526 8921 495 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 8924 496 8924 485 8918 494 "];
"UV decode_p (56)" -> "UV unlzh (60)" [style=invis, minlen=0, pos="e,9038,768 9052,655 9050,667 9048,682 9046,696 9044,717 9041,740 9039,758"];
"UV huf_decode_start (57)" -> "UV init_getbits (51)" [pos="e,8848,570 8876,619 8870,608 8861,592 8853,579", _draw_="c 5 -black B 4 8876 619 8870 608 8861 592 8853 579 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 8856 577 8848 570 8850 580 "];
"UV huf_decode_start (57)" -> "UV unlzh (60)" [style=invis, minlen=0, pos="e,9034,768 8921,654 8957,671 9006,695 9006,696 9021,713 9029,739 9032,758"];
"UV decode_start (58)" -> "UV huf_decode_start (57)" [pos="e,8896,655 8915,696 8910,687 8905,675 8900,664", _draw_="c 5 -black B 4 8915 696 8910 687 8905 675 8900 664 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 8903 663 8896 655 8897 666 "];
"UV decode_start (58)" -> "UV unlzh (60)" [style=invis, minlen=0, pos="e,9018,771 8955,730 8972,740 8993,754 9009,765"];
"UV decode (59)" -> "UV decode_c (55)" [pos="e,9163,654 9117,697 9129,687 9143,673 9155,661", _draw_="c 5 -black B 4 9117 697 9129 687 9143 673 9155 661 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 9158 663 9163 654 9153 658 "];
"UV decode (59)" -> "UV decode_p (56)" [pos="e,9064,655 9089,696 9083,687 9076,674 9069,663", _draw_="c 5 -black B 4 9089 696 9083 687 9076 674 9069 663 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 9072 662 9064 655 9066 665 "];
"UV decode (59)" -> "UV unlzh (60)" [style=invis, minlen=0, pos="e,9055,770 9089,732 9082,742 9071,753 9062,763"];
"UV unlzh (60)" -> "UV decode_start (58)" [pos="e,8945,731 9010,773 8993,763 8971,749 8953,737", _draw_="c 5 -black B 4 9010 773 8993 763 8971 749 8953 737 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 8955 734 8945 731 8951 740 "];
"UV unlzh (60)" -> "UV decode (59)" [pos="e,9079,731 9045,769 9052,760 9062,748 9072,738", _draw_="c 5 -black B 4 9045 769 9052 760 9062 748 9072 738 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 9074 741 9079 731 9069 736 "];
"UV unlzh (60)" -> "UV unlzh (60)" [style=invis, minlen=0, pos="e,9063,773 9063,799 9079,801 9093,797 9093,786 9093,777 9084,773 9073,773"];
}
subgraph cluster_30 {
graph [label="S 30",
color="#80C040",
style=bold,
lp="3884,251",
bb="3821,101,3947,263",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 3884 246 0 32 4 -S 30 ",
_draw_="S 4 -bold c 7 -#80C040 p 4 3821 101 3821 263 3947 263 3947 101 ",
xdotversion=""];
"UV do_exit (98)" [label=do_exit, width="1.28", height="0.49", style=bold, color="#80C040", pos="3875,212", _draw_="S 4 -bold c 7 -#80C040 e 3875 212 46 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 3875 207 0 50 7 -do_exit "];
"UV exit (132)" [label=exit, width="0.81", height="0.50", style=dotted, color="#80C040", pos="3875,127", _draw_="S 6 -dotted c 7 -#80C040 e 3875 127 29 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 3875 122 0 26 4 -exit "];
"UV do_exit (98)" -> "UV do_exit (98)" [style=invis, minlen=0, pos="e,3902,198 3902,226 3921,230 3939,226 3939,212 3939,201 3927,196 3912,197"];
"UV do_exit (98)" -> "UV exit (132)" [pos="e,3870,145 3869,194 3868,182 3868,168 3869,155", _draw_="c 5 -black B 4 3869 194 3868 182 3868 168 3869 155 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 3872 155 3870 145 3866 155 "];
"UV exit (132)" -> "UV do_exit (98)" [style=invis, minlen=0, pos="e,3881,194 3880,145 3882,156 3882,171 3881,184"];
}
subgraph cluster_18 {
graph [label="S 18",
color="#00C000",
style=bold,
lp="6157,591",
bb="6093,526,6221,603",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 6157 586 0 32 4 -S 18 ",
_draw_="S 4 -bold c 7 -#00C000 p 4 6093 526 6093 603 6221 603 6221 526 ",
xdotversion=""];
"UV strncpy (95)" [label=strncpy, width="1.31", height="0.49", style=dotted, color="#00C000", pos="6148,552", _draw_="S 6 -dotted c 7 -#00C000 e 6148 552 47 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 6148 547 0 51 7 -strncpy "];
"UV strncpy (95)" -> "UV strncpy (95)" [style=invis, minlen=0, pos="e,6175,538 6175,566 6194,570 6213,566 6213,552 6213,541 6200,536 6185,537"];
}
subgraph cluster_9 {
graph [label="S 9",
color="#0000C0",
style=bold,
lp="5885,591",
bb="5829,526,5941,603",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 5885 586 0 23 3 -S 9 ",
_draw_="S 4 -bold c 7 -#0000C0 p 4 5829 526 5829 603 5941 603 5941 526 ",
xdotversion=""];
"UV signal (93)" [label=signal, width="1.08", height="0.49", style=dotted, color="#0000C0", pos="5876,552", _draw_="S 6 -dotted c 7 -#0000C0 e 5876 552 39 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 5876 547 0 40 6 -signal "];
"UV signal (93)" -> "UV signal (93)" [style=invis, minlen=0, pos="e,5899,538 5899,566 5916,571 5933,566 5933,552 5933,541 5922,535 5909,536"];
}
subgraph cluster_31 {
graph [label="S 31",
color="#80C0C0",
style=bold,
lp="2868,336",
bb="2818,271,2918,348",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 2868 331 0 32 4 -S 31 ",
_draw_="S 4 -bold c 7 -#80C0C0 p 4 2818 271 2818 348 2918 348 2918 271 ",
xdotversion=""];
"UV read (9)" [label=read, width="0.92", height="0.49", style=dotted, color="#80C0C0", pos="2859,297", _draw_="S 6 -dotted c 7 -#80C0C0 e 2859 297 33 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 2859 292 0 31 4 -read "];
"UV read (9)" -> "UV read (9)" [style=invis, minlen=0, pos="e,2879,283 2879,311 2895,316 2910,311 2910,297 2910,286 2901,281 2889,281"];
}
subgraph cluster_32 {
graph [label="S 32",
color="#400000",
style=bold,
lp="2593,336",
bb="2518,186,2668,348",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 2593 331 0 32 4 -S 32 ",
_draw_="S 4 -bold c 7 -#400000 p 4 2518 186 2518 348 2668 348 2668 186 ",
xdotversion=""];
"UV write_buf (12)" [label=write_buf, width="1.61", height="0.49", style=bold, color="#400000", pos="2584,297", _draw_="S 4 -bold c 7 -#400000 e 2584 297 58 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 2584 292 0 66 9 -write_buf "];
"UV write (17)" [label=write, width="1.03", height="0.50", style=dotted, color="#400000", pos="2584,212", _draw_="S 6 -dotted c 7 -#400000 e 2584 212 37 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 2584 207 0 37 5 -write "];
"UV write_buf (12)" -> "UV write_buf (12)" [style=invis, minlen=0, pos="e,2617,283 2617,311 2639,315 2660,311 2660,297 2660,285 2645,280 2627,282"];
"UV write_buf (12)" -> "UV write (17)" [pos="e,2579,230 2578,279 2577,268 2577,253 2578,240", _draw_="c 5 -black B 4 2578 279 2577 268 2577 253 2578 240 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 2581 240 2579 230 2575 240 "];
"UV write (17)" -> "UV write_buf (12)" [style=invis, minlen=0, pos="e,2590,279 2589,230 2591,241 2591,256 2591,269"];
}
subgraph cluster_19 {
graph [label="S 19",
color="#00C080",
style=bold,
lp="6253,421",
bb="6175,356,6331,433",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 6253 416 0 32 4 -S 19 ",
_draw_="S 4 -bold c 7 -#00C080 p 4 6175 356 6175 433 6331 433 6331 356 ",
xdotversion=""];
"UV basename (6)" [label=basename, width="1.69", height="0.49", style=bold, color="#00C080", pos="6244,382", _draw_="S 4 -bold c 7 -#00C080 e 6244 382 61 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 6244 377 0 70 8 -basename "];
"UV basename (6)" -> "UV basename (6)" [style=invis, minlen=0, pos="e,6279,367 6279,397 6301,400 6323,395 6323,382 6323,371 6307,366 6289,366"];
}
subgraph cluster_33 {
graph [label="S 33",
color="#400080",
style=bold,
lp="2997,421",
bb="2917,356,3077,433",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 2997 416 0 32 4 -S 33 ",
_draw_="S 4 -bold c 7 -#400080 p 4 2917 356 2917 433 3077 433 3077 356 ",
xdotversion=""];
"UV read_error (13)" [label=read_error, width="1.75", height="0.49", style=bold, color="#400080", pos="2988,382", _draw_="S 4 -bold c 7 -#400080 e 2988 382 63 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 2988 377 0 73 10 -read_error "];
"UV read_error (13)" -> "UV read_error (13)" [style=invis, minlen=0, pos="e,3024,367 3024,397 3047,400 3069,395 3069,382 3069,371 3053,366 3034,366"];
}
subgraph cluster_34 {
graph [label="S 34",
color="#408000",
style=bold,
lp="5117,506",
bb="4975,356,5259,518",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 5117 501 0 32 4 -S 34 ",
_draw_="S 4 -bold c 7 -#408000 p 4 4975 356 4975 518 5259 518 5259 356 ",
xdotversion=""];
"UV get_method (105)" [label=get_method, width="1.94", height="0.49", style=bold, color="#408000", pos="5108,467", _draw_="S 4 -bold c 7 -#408000 e 5108 467 70 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 5108 462 0 83 10 -get_method "];
"UV memcmp (121)" [label=memcmp, width="1.50", height="0.50", style=dotted, color="#408000", pos="5037,382", _draw_="S 6 -dotted c 7 -#408000 e 5037 382 54 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 5037 377 0 62 6 -memcmp "];
"UV check_zipfile (40)" [label=check_zipfile, width="1.97", height="0.50", style=bold, color="#408000", pos="5180,382", _draw_="S 4 -bold c 7 -#408000 e 5180 382 71 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 5180 377 0 87 13 -check_zipfile "];
"UV get_method (105)" -> "UV check_zipfile (40)" [pos="e,5160,399 5117,449 5126,436 5141,420 5153,406", _draw_="c 5 -black B 4 5117 449 5126 436 5141 420 5153 406 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 5155 409 5160 399 5150 404 "];
"UV get_method (105)" -> "UV get_method (105)" [style=invis, minlen=0, pos="e,5147,452 5147,482 5172,485 5196,480 5196,467 5196,456 5178,451 5157,451"];
"UV get_method (105)" -> "UV memcmp (121)" [pos="e,5047,400 5088,450 5077,438 5063,422 5053,409", _draw_="c 5 -black B 4 5088 450 5077 438 5063 422 5053 409 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 5055 406 5047 400 5050 410 "];
"UV memcmp (121)" -> "UV get_method (105)" [style=invis, minlen=0, pos="e,5099,449 5057,399 5069,411 5082,427 5093,441"];
"UV check_zipfile (40)" -> "UV get_method (105)" [style=invis, minlen=0, pos="e,5128,450 5170,400 5161,413 5147,429 5135,442"];
}
subgraph cluster_35 {
graph [label="S 35",
color="#408080",
style=bold,
lp="2732,421",
bb="2663,356,2801,433",
_ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 2732 416 0 32 4 -S 35 ",
_draw_="S 4 -bold c 7 -#408080 p 4 2663 356 2663 433 2801 433 2801 356 ",
xdotversion=""];
"UV fill_inbuf (15)" [label=fill_inbuf, width="1.44", height="0.49", style=bold, color="#408080", pos="2723,382", _draw_="S 4 -bold c 7 -#408080 e 2723 382 52 18 ", _ldraw_="F 14.000000 11 -Times-Roman c 5 -black T 2723 377 0 58 10 -fill_inbuf "];
"UV fill_inbuf (15)" -> "UV fill_inbuf (15)" [style=invis, minlen=0, pos="e,2753,368 2753,396 2773,400 2793,396 2793,382 2793,370 2779,366 2763,367"];
}
"UV zip (0)" -> "UV updcrc (2)" [style=dotted, pos="e,1316,297 615,934 506,932 75,919 30,881 -2,852 9,829 9,786 9,786 9,786 9,467 9,416 -9,389 28,356 77,313 1062,300 1306,297", _draw_="S 6 -dotted c 5 -black B 16 615 934 506 932 75 919 30 881 -2 852 9 829 9 786 9 786 9 786 9 467 9 416 -9 389 28 356 77 313 1062 3\
00 1306 297 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 1306 301 1316 297 1306 294 "];
"UV zip (0)" -> "UV basename (6)" [style=dotted, pos="e,6279,396 665,935 1176,933 9214,906 9307,837 9327,822 9323,809 9323,786 9323,786 9323,786 9323,552 9323,502 9345,473 9307,441 9\
292,427 6425,436 6405,433 6364,427 6320,412 6288,400", _draw_="S 6 -dotted c 5 -black B 19 665 935 1176 933 9214 906 9307 837 9327 822 9323 809 9323 786 9323 786 9323 786 9323 552 9323 502 93\
45 473 9307 441 9292 427 6425 436 6405 433 6364 427 6320 412 6288 400 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 6290 397 6279 396 6287 403 "];
"UV flush_outbuf (1)" -> "UV write_buf (12)" [style=dotted, pos="e,2526,299 1115,375 1170,369 1251,361 1321,356 1778,324 2327,305 2516,299", _draw_="S 6 -dotted c 5 -black B 7 1115 375 1170 369 1251 361 1321 356 1778 324 2327 305 2516 299 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 2516 303 2526 299 2516 296 "];
"UV do_exit (98)" -> "UV free (30)" [style=dotted, pos="e,3773,142 3849,198 3839,192 3827,185 3817,178 3805,169 3792,158 3781,149", _draw_="S 6 -dotted c 5 -black B 7 3849 198 3839 192 3827 185 3817 178 3805 169 3792 158 3781 149 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 3783 146 3773 142 3778 151 "];
"UV treat_file (99)" -> "UV clear_bufs (14)" [style=dotted, pos="e,5626,480 6723,547 6651,541 6519,530 6405,526 6337,523 5853,527 5784,518 5732,511 5676,495 5636,483", _draw_="S 6 -dotted c 5 -black B 10 6723 547 6651 541 6519 530 6405 526 6337 523 5853 527 5784 518 5732 511 5676 495 5636 483 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 5637 480 5626 480 5635 486 "];
"UV treat_file (99)" -> "UV write_error (18)" [style=dotted, pos="e,5366,399 6723,547 6651,541 6519,531 6405,526 6338,522 6170,527 6103,518 5971,498 5945,459 5812,441 5771,435 5480,443 5439,433 \
5417,427 5393,414 5375,404", _draw_="S 6 -dotted c 5 -black B 16 6723 547 6651 541 6519 531 6405 526 6338 522 6170 527 6103 518 5971 498 5945 459 5812 441 5771 435 5\
480 443 5439 433 5417 427 5393 414 5375 404 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 5376 401 5366 399 5373 407 "];
"UV treat_file (99)" -> "UV strlen (25)" [style=dotted, pos="e,6742,130 6722,548 6606,540 6343,521 6339,518 6314,490 6345,376 6375,356 6391,345 7742,361 7755,348 7856,246 7634,186 7631,186 \
7606,177 7421,179 7394,178 7153,164 6864,141 6752,131", _draw_="S 6 -dotted c 5 -black B 19 6722 548 6606 540 6343 521 6339 518 6314 490 6345 376 6375 356 6391 345 7742 361 7755 348 7856 246 7\
634 186 7631 186 7606 177 7421 179 7394 178 7153 164 6864 141 6752 131 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 6752 128 6742 130 6752 134 "];
"UV treat_file (99)" -> "UV strcpy (27)" [style=dotted, pos="e,7487,132 6722,548 6646,542 6515,530 6496,518 6434,476 6396,409 6448,356 6461,342 7760,361 7772,348 7826,293 7779,229 7716,186 \
7681,161 7564,143 7497,133", _draw_="S 6 -dotted c 5 -black B 16 6722 548 6646 542 6515 530 6496 518 6434 476 6396 409 6448 356 6461 342 7760 361 7772 348 7826 293 7\
779 229 7716 186 7681 161 7564 143 7497 133 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 7497 130 7487 132 7497 136 "];
"UV treat_file (99)" -> "UV fprintf (33)" [style=dotted, pos="e,5637,299 6722,548 6599,540 6307,519 6301,518 6172,494 6120,515 6017,433 5987,408 6007,378 5974,356 5923,319 5737,304 5647,299", _draw_="S 6 -dotted c 5 -black B 13 6722 548 6599 540 6307 519 6301 518 6172 494 6120 515 6017 433 5987 408 6007 378 5974 356 5923 319 5\
737 304 5647 299 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 5647 296 5637 299 5647 303 "];
"UV treat_file (99)" -> "UV perror (36)" [style=dotted, pos="e,8160,312 6831,552 6988,550 7431,543 7573,518 7817,474 7881,455 8103,348 8120,340 8138,328 8152,318", _draw_="S 6 -dotted c 5 -black B 10 6831 552 6988 550 7431 543 7573 518 7817 474 7881 455 8103 348 8120 340 8138 328 8152 318 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 8154 321 8160 312 8150 315 "];
"UV treat_file (99)" -> "UV display_ratio (37)" [style=dotted, pos="e,4738,394 6723,547 6651,541 6519,530 6405,526 6373,524 5844,526 5812,518 5745,499 5744,459 5676,441 5639,430 5010,436 4971,433 \
4894,425 4806,408 4748,396", _draw_="S 6 -dotted c 5 -black B 16 6723 547 6651 541 6519 530 6405 526 6373 524 5844 526 5812 518 5745 499 5744 459 5676 441 5639 430 5\
010 436 4971 433 4894 425 4806 408 4748 396 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 4748 393 4738 394 4747 399 "];
"UV treat_file (99)" -> "UV (86)" [style=dotted, pos="e,2931,484 6723,547 6651,540 6519,529 6405,526 6358,524 3049,529 3003,518 2981,512 2958,500 2940,490", _draw_="S 6 -dotted c 5 -black B 10 6723 547 6651 540 6519 529 6405 526 6358 524 3049 529 3003 518 2981 512 2958 500 2940 490 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 2941 487 2931 484 2937 492 "];
"UV treat_file (99)" -> "UV strcmp (92)" [style=dotted, pos="e,8294,130 6831,551 7068,548 7997,533 8127,518 8306,496 8359,506 8522,433 8636,382 8735,280 8653,186 8631,159 8409,139 8304,131", _draw_="S 6 -dotted c 5 -black B 13 6831 551 7068 548 7997 533 8127 518 8306 496 8359 506 8522 433 8636 382 8735 280 8653 186 8631 159 8\
409 139 8304 131 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 8304 128 8294 130 8304 134 "];
"UV treat_file (99)" -> "UV treat_stdin (100)" [style=dotted, pos="e,4861,560 6729,561 6657,574 6517,598 6396,607 6337,611 5386,610 5326,607 5163,598 4971,575 4871,561", _draw_="S 6 -dotted c 5 -black B 10 6729 561 6657 574 6517 598 6396 607 6337 611 5386 610 5326 607 5163 598 4971 575 4871 561 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 4871 558 4861 560 4871 564 "];
"UV treat_file (99)" -> "UV do_list (101)" [style=dotted, pos="e,4353,471 6723,547 6651,541 6519,530 6405,526 6087,513 5290,531 4971,518 4744,508 4474,483 4363,472", _draw_="S 6 -dotted c 5 -black B 10 6723 547 6651 541 6519 530 6405 526 6087 513 5290 531 4971 518 4744 508 4474 483 4363 472 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 4363 469 4353 471 4363 475 "];
"UV treat_file (99)" -> "UV fileno (102)" [style=dotted, pos="e,7933,313 6831,551 6967,549 7317,541 7430,518 7641,474 7695,451 7883,348 7898,340 7913,329 7925,319", _draw_="S 6 -dotted c 5 -black B 10 6831 551 6967 549 7317 541 7430 518 7641 474 7695 451 7883 348 7898 340 7913 329 7925 319 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 7927 322 7933 313 7923 316 "];
"UV treat_file (99)" -> "UV get_method (105)" [style=dotted, pos="e,5155,480 6723,547 6651,541 6519,530 6405,526 6287,521 5457,531 5339,518 5278,511 5211,495 5165,483", _draw_="S 6 -dotted c 5 -black B 10 6723 547 6651 541 6519 530 6405 526 6287 521 5457 531 5339 518 5278 511 5211 495 5165 483 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 5166 480 5155 480 5164 486 "];
"UV treat_file (99)" -> "UV close (109)" [style=dotted, pos="e,8354,230 6831,552 7009,551 7562,546 7737,518 8005,475 8137,545 8322,348 8350,318 8354,271 8354,240", _draw_="S 6 -dotted c 5 -black B 10 6831 552 7009 551 7562 546 7737 518 8005 475 8137 545 8322 348 8350 318 8354 271 8354 240 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 8358 240 8354 230 8351 240 "];
"UV treat_file (99)" -> "UV unlink (111)" [style=dotted, pos="e,8460,229 6831,551 7052,548 7865,535 7979,518 8117,496 8164,508 8281,433 8362,381 8427,284 8455,238", _draw_="S 6 -dotted c 5 -black B 10 6831 551 7052 548 7865 535 7979 518 8117 496 8164 508 8281 433 8362 381 8427 284 8455 238 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 8458 239 8460 229 8452 236 "];
"UV treat_stdin (100)" -> "UV clear_bufs (14)" [style=dotted, pos="e,5556,482 4867,549 5030,541 5447,520 5461,518 5491,511 5523,498 5547,487", _draw_="S 6 -dotted c 5 -black B 7 4867 549 5030 541 5447 520 5461 518 5491 511 5523 498 5547 487 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 5549 490 5556 482 5546 484 "];
"UV treat_stdin (100)" -> "UV strcpy (27)" [style=dotted, pos="e,7407,131 4803,534 4803,503 4803,437 4803,382 4803,382 4803,382 4803,297 4803,187 6663,183 6772,178 7007,166 7285,142 7397,132", _draw_="S 6 -dotted c 5 -black B 13 4803 534 4803 503 4803 437 4803 382 4803 382 4803 382 4803 297 4803 187 6663 183 6772 178 7007 166 7\
285 142 7397 132 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 7397 135 7407 131 7397 129 "];
"UV treat_stdin (100)" -> "UV error (32)" [style=dotted, pos="e,3870,396 4738,550 4584,545 4202,532 4145,518 4042,493 3931,432 3879,401", _draw_="S 6 -dotted c 5 -black B 7 4738 550 4584 545 4202 532 4145 518 4042 493 3931 432 3879 401 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 3880 398 3870 396 3877 404 "];
"UV treat_stdin (100)" -> "UV fprintf (33)" [style=dotted, pos="e,5559,305 4811,534 4813,529 4815,523 4817,518 4842,447 4806,401 4865,356 4875,348 5283,349 5294,348 5386,340 5490,319 5549,307", _draw_="S 6 -dotted c 5 -black B 13 4811 534 4813 529 4815 523 4817 518 4842 447 4806 401 4865 356 4875 348 5283 349 5294 348 5386 340 5\
490 319 5549 307 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 5550 310 5559 305 5549 304 "];
"UV treat_stdin (100)" -> "UV display_ratio (37)" [style=dotted, pos="e,4696,399 4791,535 4770,506 4726,443 4702,407", _draw_="S 6 -dotted c 5 -black B 4 4791 535 4770 506 4726 443 4702 407 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 4705 405 4696 399 4699 409 "];
"UV treat_stdin (100)" -> "UV (86)" [style=dotted, pos="e,2931,484 4738,550 4588,544 4201,532 3877,526 3853,525 3027,524 3003,518 2981,512 2958,500 2940,490", _draw_="S 6 -dotted c 5 -black B 10 4738 550 4588 544 4201 532 3877 526 3853 525 3027 524 3003 518 2981 512 2958 500 2940 490 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 2941 487 2931 484 2937 492 "];
"UV treat_stdin (100)" -> "UV do_exit (98)" [style=dotted, pos="e,3898,227 4738,550 4582,546 4197,533 4173,518 4142,496 4159,471 4135,441 4067,351 3959,270 3906,233", _draw_="S 6 -dotted c 5 -black B 10 4738 550 4582 546 4197 533 4173 518 4142 496 4159 471 4135 441 4067 351 3959 270 3906 233 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 3908 230 3898 227 3904 236 "];
"UV treat_stdin (100)" -> "UV do_list (101)" [style=dotted, pos="e,4351,474 4748,542 4652,526 4453,492 4361,476", _draw_="S 6 -dotted c 5 -black B 4 4748 542 4652 526 4453 492 4361 476 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 4361 473 4351 474 4360 479 "];
"UV treat_stdin (100)" -> "UV fileno (102)" [style=dotted, pos="e,7920,307 4840,538 4851,532 4862,526 4871,518 4905,488 4902,471 4925,433 4946,399 4937,375 4971,356 4988,346 7736,350 7755,348 \
7810,341 7871,323 7910,310", _draw_="S 6 -dotted c 5 -black B 16 4840 538 4851 532 4862 526 4871 518 4905 488 4902 471 4925 433 4946 399 4937 375 4971 356 4988 346 7\
736 350 7755 348 7810 341 7871 323 7910 310 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 7911 313 7920 307 7909 307 "];
"UV treat_stdin (100)" -> "UV isatty (103)" [style=dotted, pos="e,5991,304 4821,535 4827,530 4832,524 4837,518 4891,451 4867,397 4941,356 4959,346 5647,349 5667,348 5781,338 5912,317 5981,306", _draw_="S 6 -dotted c 5 -black B 13 4821 535 4827 530 4832 524 4837 518 4891 451 4867 397 4941 356 4959 346 5647 349 5667 348 5781 338 5\
912 317 5981 306 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 5982 309 5991 304 5981 303 "];
"UV treat_stdin (100)" -> "UV fstat (104)" [style=dotted, pos="e,5718,398 4867,550 4986,545 5228,534 5263,518 5307,497 5295,460 5339,441 5373,426 5634,445 5668,433 5684,427 5699,416 5711,405", _draw_="S 6 -dotted c 5 -black B 13 4867 550 4986 545 5228 534 5263 518 5307 497 5295 460 5339 441 5373 426 5634 445 5668 433 5684 427 5\
699 416 5711 405 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 5713 408 5718 398 5708 403 "];
"UV treat_stdin (100)" -> "UV get_method (105)" [style=dotted, pos="e,5072,482 4858,543 4891,537 4933,528 4969,518 5001,509 5036,496 5062,486", _draw_="S 6 -dotted c 5 -black B 7 4858 543 4891 537 4933 528 4969 518 5001 509 5036 496 5062 486 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 5064 489 5072 482 5061 482 "];
"UV do_list (101)" -> "UV read (9)" [style=dotted, pos="e,2892,298 4276,458 4248,451 4210,442 4176,433 4059,401 4034,376 3913,356 3714,322 3075,303 2902,298", _draw_="S 6 -dotted c 5 -black B 10 4276 458 4248 451 4210 442 4176 433 4059 401 4034 376 3913 356 3714 322 3075 303 2902 298 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 2902 295 2892 298 2902 302 "];
"UV do_list (101)" -> "UV read_error (13)" [style=dotted, pos="e,3018,398 4271,464 4194,458 4022,445 3877,441 3835,439 3155,441 3113,433 3083,427 3051,414 3027,403", _draw_="S 6 -dotted c 5 -black B 10 4271 464 4194 458 4022 445 3877 441 3835 439 3155 441 3113 433 3083 427 3051 414 3027 403 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 3028 400 3018 398 3025 406 "];
"UV do_list (101)" -> "UV display_ratio (37)" [style=dotted, pos="e,4662,399 4353,464 4422,459 4555,448 4599,433 4618,426 4637,415 4653,405", _draw_="S 6 -dotted c 5 -black B 7 4353 464 4422 459 4555 448 4599 433 4618 426 4637 415 4653 405 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 4656 407 4662 399 4652 402 "];
"UV lm_init (5)" -> "UV error (32)" [style=dotted, pos="e,3812,386 1278,863 1438,861 1984,856 2157,837 2396,810 2452,778 2687,732 2728,724 2777,754 2777,714 2777,714 2777,714 2777,552 \
2777,497 2785,470 2831,441 2841,434 3244,433 3255,433 3460,422 3703,398 3802,387", _draw_="S 6 -dotted c 5 -black B 22 1278 863 1438 861 1984 856 2157 837 2396 810 2452 778 2687 732 2728 724 2777 754 2777 714 2777 714 2\
777 714 2777 552 2777 497 2785 470 2831 441 2841 434 3244 433 3255 433 3460 422 3703 398 3802 387 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 3802 390 3812 386 3802 384 "];
"UV lm_init (5)" -> "UV memset (47)" [style=dotted, pos="e,2342,400 1278,863 1451,862 2072,859 2107,837 2267,737 2325,492 2340,410", _draw_="S 6 -dotted c 5 -black B 7 1278 863 1451 862 2072 859 2107 837 2267 737 2325 492 2340 410 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 2343 410 2342 400 2337 409 "];
"UV lm_init (5)" -> "UV (86)" [style=dotted, pos="e,2891,484 1278,863 1530,860 2777,849 2791,837 2834,801 2815,769 2815,714 2815,714 2815,714 2815,637 2815,579 2856,523 2884,492", _draw_="S 6 -dotted c 5 -black B 13 1278 863 1530 860 2777 849 2791 837 2834 801 2815 769 2815 714 2815 714 2815 714 2815 637 2815 579 2\
856 523 2884 492 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 2887 494 2891 484 2882 489 "];
"UV basename (6)" -> "UV strlwr (19)" [style=dotted, pos="e,7875,145 6290,370 6315,365 6346,358 6375,356 6395,354 7739,357 7755,348 7828,305 7861,203 7873,155", _draw_="S 6 -dotted c 5 -black B 10 6290 370 6315 365 6346 358 6375 356 6395 354 7739 357 7755 348 7828 305 7861 203 7873 155 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 7876 155 7875 145 7870 154 "];
"UV basename (6)" -> "UV strrchr (21)" [style=dotted, pos="e,7539,228 6283,368 6299,363 6319,358 6337,356 6353,353 7448,356 7461,348 7494,327 7479,302 7501,271 7510,258 7521,245 7532,235", _draw_="S 6 -dotted c 5 -black B 13 6283 368 6299 363 6319 358 6337 356 6353 353 7448 356 7461 348 7494 327 7479 302 7501 271 7510 258 7\
521 245 7532 235 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 7534 238 7539 228 7529 233 "];
"UV get_method (105)" -> "UV basename (6)" [style=dotted, pos="e,6189,390 5169,458 5216,452 5281,444 5339,441 5543,427 5594,446 5797,433 5934,423 6092,403 6179,391", _draw_="S 6 -dotted c 5 -black B 10 5169 458 5216 452 5281 444 5339 441 5543 427 5594 446 5797 433 5934 423 6092 403 6179 391 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 6179 394 6189 390 6179 388 "];
"UV get_method (105)" -> "UV fill_inbuf (15)" [style=dotted, pos="e,2759,395 5039,463 4920,457 4666,445 4451,441 4366,439 2998,444 2913,433 2863,426 2807,410 2769,398", _draw_="S 6 -dotted c 5 -black B 10 5039 463 4920 457 4666 445 4451 441 4366 439 2998 444 2913 433 2863 426 2807 410 2769 398 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 2770 395 2759 395 2768 401 "];
"UV get_method (105)" -> "UV error (32)" [style=dotted, pos="e,3881,389 5039,464 4920,459 4666,448 4451,441 4328,436 4297,444 4173,433 4071,424 3953,402 3891,391", _draw_="S 6 -dotted c 5 -black B 10 5039 464 4920 459 4666 448 4451 441 4328 436 4297 444 4173 433 4071 424 3953 402 3891 391 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 3891 388 3881 389 3890 394 "];
"UV get_method (105)" -> "UV fprintf (33)" [style=dotted, pos="e,5618,312 5165,457 5200,451 5246,444 5286,441 5297,440 5648,440 5655,433 5679,408 5669,387 5655,356 5649,341 5638,328 5626,318", _draw_="S 6 -dotted c 5 -black B 13 5165 457 5200 451 5246 444 5286 441 5297 440 5648 440 5655 433 5679 408 5669 387 5655 356 5649 341 5\
638 328 5626 318 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 5628 315 5618 312 5624 321 "];
"UV file_read (8)" -> "UV updcrc (2)" [style=dotted, pos="e,1402,299 4487,367 4476,363 4463,358 4451,356 4399,345 2568,349 2514,348 2089,337 1576,309 1412,300", _draw_="S 6 -dotted c 5 -black B 10 4487 367 4476 363 4463 358 4451 356 4399 345 2568 349 2514 348 2089 337 1576 309 1412 300 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 1412 297 1402 299 1412 303 "];
"UV file_read (8)" -> "UV read (9)" [style=dotted, pos="e,2892,298 4486,367 4476,363 4463,358 4451,356 4419,349 4187,349 4154,348 3663,331 3065,306 2902,298", _draw_="S 6 -dotted c 5 -black B 10 4486 367 4476 363 4463 358 4451 356 4419 349 4187 349 4154 348 3663 331 3065 306 2902 298 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 2902 295 2892 298 2902 302 "];
"UV get_istat (106)" -> "UV __errno_location (11)" [style=dotted, pos="e,5241,309 7154,456 7131,450 7101,444 7074,441 6971,429 6241,445 6137,433 5984,415 5951,375 5797,356 5685,341 5656,357 5543,348 \
5443,339 5326,323 5251,311", _draw_="S 6 -dotted c 5 -black B 16 7154 456 7131 450 7101 444 7074 441 6971 429 6241 445 6137 433 5984 415 5951 375 5797 356 5685 341 5\
656 357 5543 348 5443 339 5326 323 5251 311 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 5251 308 5241 309 5250 314 "];
"UV get_istat (106)" -> "UV strlen (25)" [style=dotted, pos="e,6742,131 7225,452 7235,448 7247,443 7258,441 7303,431 7623,436 7668,433 7799,422 8166,447 8251,348 8274,322 8275,295 8251,271 \
8238,257 7918,268 7899,263 7841,244 7844,204 7785,186 7765,179 7416,179 7394,178 7153,166 6864,142 6752,132", _draw_="S 6 -dotted c 5 -black B 25 7225 452 7235 448 7247 443 7258 441 7303 431 7623 436 7668 433 7799 422 8166 447 8251 348 8274 322 8\
275 295 8251 271 8238 257 7918 268 7899 263 7841 244 7844 204 7785 186 7765 179 7416 179 7394 178 7153 166 6864 142 6752 132 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 6752 129 6742 131 6752 135 "];
"UV get_istat (106)" -> "UV strcpy (27)" [style=dotted, pos="e,7486,132 7225,452 7235,448 7247,443 7258,441 7273,438 8309,443 8319,433 8370,381 8365,326 8319,271 8304,252 7918,189 7894,186 \
7865,181 7857,181 7827,178 7708,163 7569,144 7496,133", _draw_="S 6 -dotted c 5 -black B 19 7225 452 7235 448 7247 443 7258 441 7273 438 8309 443 8319 433 8370 381 8365 326 8319 271 8304 252 7\
918 189 7894 186 7865 181 7857 181 7827 178 7708 163 7569 144 7496 133 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 7496 130 7486 132 7496 136 "];
"UV get_istat (106)" -> "UV perror (36)" [style=dotted, pos="e,8167,314 7225,452 7235,448 7247,443 7258,441 7333,425 7524,441 7599,433 7772,413 7811,378 7983,356 8015,351 8096,360 8125,348 \
8138,342 8151,331 8160,321", _draw_="S 6 -dotted c 5 -black B 16 7225 452 7235 448 7247 443 7258 441 7333 425 7524 441 7599 433 7772 413 7811 378 7983 356 8015 351 8\
096 360 8125 348 8138 342 8151 331 8160 321 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 8162 324 8167 314 8157 319 "];
"UV get_istat (106)" -> "UV strcmp (92)" [style=dotted, pos="e,8294,131 7225,452 7235,447 7247,443 7258,441 7291,434 8424,445 8454,433 8577,381 8711,287 8624,186 8604,162 8402,141 8304,132", _draw_="S 6 -dotted c 5 -black B 13 7225 452 7235 447 7247 443 7258 441 7291 434 8424 445 8454 433 8577 381 8711 287 8624 186 8604 162 8\
402 141 8304 132 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 8304 129 8294 131 8304 135 "];
"UV make_ofname (107)" -> "UV strlwr (19)" [style=dotted, pos="e,7915,135 7421,467 7673,466 8454,461 8499,433 8536,410 8532,388 8546,348 8571,280 8614,237 8563,186 8556,178 8206,178 8195,178 \
8099,169 7987,148 7925,137", _draw_="S 6 -dotted c 5 -black B 16 7421 467 7673 466 8454 461 8499 433 8536 410 8532 388 8546 348 8571 280 8614 237 8563 186 8556 178 8\
206 178 8195 178 8099 169 7987 148 7925 137 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 7925 134 7915 135 7924 140 "];
"UV make_ofname (107)" -> "UV strcpy (27)" [style=dotted, pos="e,7485,134 7421,467 7666,466 8411,460 8454,433 8526,387 8522,345 8541,263 8550,229 8566,210 8541,186 8535,178 7837,178 7827,178 \
7708,168 7568,147 7495,136", _draw_="S 6 -dotted c 5 -black B 16 7421 467 7666 466 8411 460 8454 433 8526 387 8522 345 8541 263 8550 229 8566 210 8541 186 8535 178 7\
837 178 7827 178 7708 168 7568 147 7495 136 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 7495 133 7485 134 7494 139 "];
"UV make_ofname (107)" -> "UV fprintf (33)" [style=dotted, pos="e,5635,303 7303,452 7289,447 7273,443 7258,441 7244,438 6184,441 6171,433 6141,412 6171,377 6141,356 6127,345 5995,349 5976,348 \
5857,337 5717,316 5645,305", _draw_="S 6 -dotted c 5 -black B 16 7303 452 7289 447 7273 443 7258 441 7244 438 6184 441 6171 433 6141 412 6171 377 6141 356 6127 345 5\
995 349 5976 348 5857 337 5717 316 5645 305 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 5645 302 5635 303 5644 308 "];
"UV make_ofname (107)" -> "UV strcmp (92)" [style=dotted, pos="e,8295,128 7421,466 7681,462 8511,447 8534,433 8630,372 8663,272 8590,186 8554,143 8391,132 8305,128", _draw_="S 6 -dotted c 5 -black B 10 7421 466 7681 462 8511 447 8534 433 8630 372 8663 272 8590 186 8554 143 8391 132 8305 128 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 8305 125 8295 128 8305 132 "];
"UV copy (10)" -> "UV read (9)" [style=dotted, pos="e,2856,315 3029,453 3021,448 3012,443 3003,441 2991,437 2893,441 2883,433 2853,406 2852,356 2855,325", _draw_="S 6 -dotted c 5 -black B 10 3029 453 3021 448 3012 443 3003 441 2991 437 2893 441 2883 433 2853 406 2852 356 2855 325 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 2858 325 2856 315 2852 325 "];
"UV copy (10)" -> "UV __errno_location (11)" [style=dotted, pos="e,5104,309 3029,453 3021,448 3012,443 3003,441 2984,435 2927,447 2913,433 2890,407 2889,380 2913,356 2923,346 4775,348 4787,348 \
4894,340 5016,323 5094,311", _draw_="S 6 -dotted c 5 -black B 16 3029 453 3021 448 3012 443 3003 441 2984 435 2927 447 2913 433 2890 407 2889 380 2913 356 2923 346 4\
775 348 4787 348 4894 340 5016 323 5094 311 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 5095 314 5104 309 5094 308 "];
"UV copy (10)" -> "UV write_buf (12)" [style=dotted, pos="e,2634,306 3029,453 3021,448 3012,443 3003,441 2971,431 2881,450 2852,433 2818,412 2838,380 2805,356 2780,337 2701,318 2644,308", _draw_="S 6 -dotted c 5 -black B 13 3029 453 3021 448 3012 443 3003 441 2971 431 2881 450 2852 433 2818 412 2838 380 2805 356 2780 337 2\
701 318 2644 308 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 2644 305 2634 306 2643 311 "];
"UV copy (10)" -> "UV read_error (13)" [style=dotted, pos="e,3000,399 3037,450 3028,438 3016,421 3006,407", _draw_="S 6 -dotted c 5 -black B 4 3037 450 3028 438 3016 421 3006 407 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 3009 405 3000 399 3003 409 "];
"UV write_buf (12)" -> "UV write_error (18)" [style=dotted, pos="e,5306,367 2626,309 2672,322 2748,340 2814,348 2882,355 5196,345 5263,356 5274,358 5286,360 5297,364", _draw_="S 6 -dotted c 5 -black B 10 2626 309 2672 322 2748 340 2814 348 2882 355 5196 345 5263 356 5274 358 5286 360 5297 364 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 5295 367 5306 367 5298 361 "];
"UV read_error (13)" -> "UV __errno_location (11)" [style=dotted, pos="e,5104,309 3028,368 3045,363 3065,358 3083,356 3177,343 4693,354 4787,348 4894,340 5016,323 5094,311", _draw_="S 6 -dotted c 5 -black B 10 3028 368 3045 363 3065 358 3083 356 3177 343 4693 354 4787 348 4894 340 5016 323 5094 311 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 5095 314 5104 309 5094 308 "];
"UV read_error (13)" -> "UV fprintf (33)" [style=dotted, pos="e,5560,305 3028,368 3045,363 3065,358 3083,356 3205,339 5172,358 5294,348 5386,339 5491,319 5550,307", _draw_="S 6 -dotted c 5 -black B 10 3028 368 3045 363 3065 358 3083 356 3205 339 5172 358 5294 348 5386 339 5491 319 5550 307 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 5551 310 5560 305 5550 304 "];
"UV read_error (13)" -> "UV abort_gzip (34)" [style=dotted, pos="e,4166,298 3028,369 3045,364 3065,359 3083,356 3292,323 3937,304 4156,298", _draw_="S 6 -dotted c 5 -black B 7 3028 369 3045 364 3065 359 3083 356 3292 323 3937 304 4156 298 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 4156 302 4166 298 4156 295 "];
"UV read_error (13)" -> "UV perror (36)" [style=dotted, pos="e,8151,309 3034,370 3057,364 3087,358 3113,356 3181,348 7952,358 8019,348 8062,341 8109,325 8141,313", _draw_="S 6 -dotted c 5 -black B 10 3034 370 3057 364 3087 358 3113 356 3181 348 7952 358 8019 348 8062 341 8109 325 8141 313 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 8143 316 8151 309 8140 309 "];
"UV create_outfile (110)" -> "UV fprintf (33)" [style=dotted, pos="e,5635,302 6583,465 6441,461 6147,450 6103,433 6056,413 6064,377 6017,356 6009,352 5756,318 5645,303", _draw_="S 6 -dotted c 5 -black B 10 6583 465 6441 461 6147 450 6103 433 6056 413 6064 377 6017 356 6009 352 5756 318 5645 303 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 5645 300 5635 302 5645 306 "];
"UV create_outfile (110)" -> "UV perror (36)" [style=dotted, pos="e,8167,314 6729,459 6786,453 6869,444 6942,441 6967,439 7367,442 7390,433 7438,414 7427,374 7474,356 7508,342 8092,361 8125,348 \
8139,342 8151,332 8160,322", _draw_="S 6 -dotted c 5 -black B 16 6729 459 6786 453 6869 444 6942 441 6967 439 7367 442 7390 433 7438 414 7427 374 7474 356 7508 342 8\
092 361 8125 348 8139 342 8151 332 8160 322 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 8163 324 8167 314 8158 319 "];
"UV create_outfile (110)" -> "UV fstat (104)" [style=dotted, pos="e,5755,396 6584,464 6381,456 5842,434 5837,433 5811,426 5784,412 5764,401", _draw_="S 6 -dotted c 5 -black B 7 6584 464 6381 456 5842 434 5837 433 5811 426 5784 412 5764 401 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 5765 398 5755 396 5762 404 "];
"UV create_outfile (110)" -> "UV close (109)" [style=dotted, pos="e,8348,229 6729,459 6786,453 6869,444 6942,441 7107,432 7518,445 7681,433 7816,422 8172,425 8281,348 8318,322 8337,271 8345,239", _draw_="S 6 -dotted c 5 -black B 13 6729 459 6786 453 6869 444 6942 441 7107 432 7518 445 7681 433 7816 422 8172 425 8281 348 8318 322 8\
337 271 8345 239 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 8348 240 8348 229 8342 238 "];
"UV create_outfile (110)" -> "UV unlink (111)" [style=dotted, pos="e,8457,229 6729,459 6786,453 6869,444 6942,441 7057,435 7857,446 7970,433 8130,413 8180,422 8322,348 8376,320 8425,268 8450,237", _draw_="S 6 -dotted c 5 -black B 13 6729 459 6786 453 6869 444 6942 441 7057 435 7857 446 7970 433 8130 413 8180 422 8322 348 8376 320 8\
425 268 8450 237 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 8453 239 8457 229 8448 234 "];
"UV copy_stat (112)" -> "UV fprintf (33)" [style=dotted, pos="e,5635,303 6955,460 6902,454 6819,445 6746,441 6730,440 6157,440 6141,433 6102,413 6118,376 6079,356 6059,345 5999,350 5976,348 \
5857,336 5718,315 5645,304", _draw_="S 6 -dotted c 5 -black B 16 6955 460 6902 454 6819 445 6746 441 6730 440 6157 440 6141 433 6102 413 6118 376 6079 356 6059 345 5\
999 350 5976 348 5857 336 5718 315 5645 304 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 5645 301 5635 303 5645 307 "];
"UV copy_stat (112)" -> "UV perror (36)" [style=dotted, pos="e,8167,314 7053,456 7077,450 7107,444 7134,441 7172,436 7438,443 7474,433 7537,414 7537,374 7599,356 7628,347 8098,358 8125,348 \
8139,342 8151,332 8160,322", _draw_="S 6 -dotted c 5 -black B 16 7053 456 7077 450 7107 444 7134 441 7172 436 7438 443 7474 433 7537 414 7537 374 7599 356 7628 347 8\
098 358 8125 348 8139 342 8151 332 8160 322 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 8163 324 8167 314 8158 319 "];
"UV copy_stat (112)" -> "UV unlink (111)" [style=dotted, pos="e,8474,230 7052,455 7076,450 7107,443 7134,441 7152,439 8420,444 8433,433 8489,385 8482,287 8476,240", _draw_="S 6 -dotted c 5 -black B 10 7052 455 7076 450 7107 443 7134 441 7152 439 8420 444 8433 433 8489 385 8482 287 8476 240 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 8479 239 8474 230 8473 240 "];
"UV fill_inbuf (15)" -> "UV read (9)" [style=dotted, pos="e,2837,311 2748,366 2770,352 2804,331 2828,316", _draw_="S 6 -dotted c 5 -black B 4 2748 366 2770 352 2804 331 2828 316 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 2830 319 2837 311 2827 313 "];
"UV fill_inbuf (15)" -> "UV __errno_location (11)" [style=dotted, pos="e,5104,309 2767,373 2799,366 2844,359 2883,356 3094,338 4576,362 4787,348 4894,340 5016,323 5094,311", _draw_="S 6 -dotted c 5 -black B 10 2767 373 2799 366 2844 359 2883 356 3094 338 4576 362 4787 348 4894 340 5016 323 5094 311 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 5095 314 5104 309 5094 308 "];
"UV fill_inbuf (15)" -> "UV read_error (13)" [style=dotted, pos="e,2925,382 2775,382 2822,382 2868,382 2915,382", _draw_="S 6 -dotted c 5 -black B 4 2775 382 2822 382 2868 382 2915 382 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 2915 386 2925 382 2915 379 "];
"UV check_ofname (113)" -> "UV __errno_location (11)" [style=dotted, pos="e,5240,309 6659,371 6623,365 6576,359 6534,356 6315,339 5763,363 5543,348 5442,340 5325,323 5250,311", _draw_="S 6 -dotted c 5 -black B 10 6659 371 6623 365 6576 359 6534 356 6315 339 5763 363 5543 348 5442 340 5325 323 5250 311 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 5250 308 5240 309 5249 314 "];
"UV check_ofname (113)" -> "UV isupper (20)" [style=dotted, pos="e,7964,59 6770,368 6788,363 6810,358 6830,356 6847,353 8008,359 8019,348 8058,308 7995,136 7968,69", _draw_="S 6 -dotted c 5 -black B 10 6770 368 6788 363 6810 358 6830 356 6847 353 8008 359 8019 348 8058 308 7995 136 7968 69 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 7971 67 7964 59 7964 70 "];
"UV check_ofname (113)" -> "UV strcpy (27)" [style=dotted, pos="e,7486,132 6771,368 6789,363 6810,358 6830,356 6845,354 7851,358 7861,348 7912,296 7909,240 7861,186 7855,179 7605,147 7496,133", _draw_="S 6 -dotted c 5 -black B 13 6771 368 6789 363 6810 358 6830 356 6845 354 7851 358 7861 348 7912 296 7909 240 7861 186 7855 179 7\
605 147 7496 133 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 7496 130 7486 132 7496 136 "];
"UV check_ofname (113)" -> "UV fprintf (33)" [style=dotted, pos="e,5634,304 6659,371 6623,365 6576,359 6534,356 6287,337 6224,366 5976,348 5857,338 5717,317 5644,306", _draw_="S 6 -dotted c 5 -black B 10 6659 371 6623 365 6576 359 6534 356 6287 337 6224 366 5976 348 5857 338 5717 317 5644 306 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 5644 303 5634 304 5643 309 "];
"UV check_ofname (113)" -> "UV perror (36)" [style=dotted, pos="e,8167,314 6770,368 6788,363 6810,358 6830,356 6866,351 8092,361 8125,348 8139,342 8151,332 8160,322", _draw_="S 6 -dotted c 5 -black B 10 6770 368 6788 363 6810 358 6830 356 6866 351 8092 361 8125 348 8139 342 8151 332 8160 322 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 8163 324 8167 314 8158 319 "];
"UV check_ofname (113)" -> "UV strcmp (92)" [style=dotted, pos="e,8229,142 6770,368 6788,363 6810,358 6830,356 6847,353 8035,356 8049,348 8082,327 8064,301 8087,271 8127,220 8185,174 8220,148", _draw_="S 6 -dotted c 5 -black B 13 6770 368 6788 363 6810 358 6830 356 6847 353 8035 356 8049 348 8082 327 8064 301 8087 271 8127 220 8\
185 174 8220 148 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 8223 150 8229 142 8219 145 "];
"UV check_ofname (113)" -> "UV fileno (102)" [style=dotted, pos="e,7939,314 6771,368 6789,363 6810,358 6830,356 6860,352 7872,359 7899,348 7912,342 7924,332 7933,322", _draw_="S 6 -dotted c 5 -black B 10 6771 368 6789 363 6810 358 6830 356 6860 352 7872 359 7899 348 7912 342 7924 332 7933 322 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 7936 324 7939 314 7930 320 "];
"UV check_ofname (113)" -> "UV isatty (103)" [style=dotted, pos="e,6064,303 6657,372 6621,366 6575,360 6534,356 6477,350 6463,353 6405,348 6286,336 6146,315 6074,304", _draw_="S 6 -dotted c 5 -black B 10 6657 372 6621 366 6575 360 6534 356 6477 350 6463 353 6405 348 6286 336 6146 315 6074 304 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 6074 301 6064 303 6074 307 "];
"UV check_ofname (113)" -> "UV unlink (111)" [style=dotted, pos="e,8458,229 6770,368 6788,363 6810,358 6830,356 6848,353 8073,357 8087,348 8120,327 8095,291 8127,271 8155,253 8388,275 8417,263 \
8430,257 8443,247 8452,237", _draw_="S 6 -dotted c 5 -black B 16 6770 368 6788 363 6810 358 6830 356 6848 353 8073 357 8087 348 8120 327 8095 291 8127 271 8155 253 8\
388 275 8417 263 8430 257 8443 247 8452 237 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 8455 239 8458 229 8449 235 "];
"UV flush_window (16)" -> "UV updcrc (2)" [style=dotted, pos="e,1370,314 1401,364 1394,352 1384,336 1375,323", _draw_="S 6 -dotted c 5 -black B 4 1401 364 1394 352 1384 336 1375 323 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 1378 321 1370 314 1372 324 "];
"UV flush_window (16)" -> "UV write_buf (12)" [style=dotted, pos="e,2526,299 1461,368 1480,364 1501,359 1521,356 1715,327 2313,306 2516,299", _draw_="S 6 -dotted c 5 -black B 7 1461 368 1480 364 1501 359 1521 356 1715 327 2313 306 2516 299 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 2516 303 2526 299 2516 296 "];
"UV name_too_long (114)" -> "UV strlen (25)" [style=dotted, pos="e,6686,143 6540,279 6573,248 6642,184 6679,150", _draw_="S 6 -dotted c 5 -black B 4 6540 279 6573 248 6642 184 6679 150 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 6681 153 6686 143 6676 148 "];
"UV shorten_name (115)" -> "UV strrchr (21)" [style=dotted, pos="e,7544,229 6747,282 6761,277 6777,273 6792,271 6831,265 7463,277 7499,263 7513,257 7527,247 7537,236", _draw_="S 6 -dotted c 5 -black B 10 6747 282 6761 277 6777 273 6792 271 6831 265 7463 277 7499 263 7513 257 7527 247 7537 236 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 7539 239 7544 229 7534 234 "];
"UV shorten_name (115)" -> "UV strlen (25)" [style=dotted, pos="e,6703,145 6703,279 6703,249 6703,190 6703,155", _draw_="S 6 -dotted c 5 -black B 4 6703 279 6703 249 6703 190 6703 155 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 6707 155 6703 145 6700 155 "];
"UV shorten_name (115)" -> "UV strcpy (27)" [style=dotted, pos="e,7406,129 6714,279 6731,253 6766,206 6809,186 6862,161 7254,137 7396,130", _draw_="S 6 -dotted c 5 -black B 7 6714 279 6731 253 6766 206 6809 186 6862 161 7254 137 7396 130 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 7396 133 7406 129 7396 127 "];
"UV shorten_name (115)" -> "UV strcspn (29)" [style=dotted, pos="e,4561,213 6660,282 6645,277 6629,273 6614,271 6588,266 4904,222 4571,213", _draw_="S 6 -dotted c 5 -black B 7 6660 282 6645 277 6629 273 6614 271 6588 266 4904 222 4571 213 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 4571 210 4561 213 4571 217 "];
"UV shorten_name (115)" -> "UV error (32)" [style=dotted, pos="e,3882,378 6681,314 6664,326 6639,341 6614,348 6582,356 4207,354 4173,356 4073,360 3955,371 3892,377", _draw_="S 6 -dotted c 5 -black B 10 6681 314 6664 326 6639 341 6614 348 6582 356 4207 354 4173 356 4073 360 3955 371 3892 377 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 3892 374 3882 378 3892 380 "];
"UV shorten_name (115)" -> "UV strcmp (92)" [style=dotted, pos="e,8212,135 6747,282 6761,277 6777,273 6792,271 6827,265 7396,277 7428,263 7472,244 7458,205 7501,186 7524,175 7925,180 7949,178 \
8040,169 8143,149 8202,137", _draw_="S 6 -dotted c 5 -black B 16 6747 282 6761 277 6777 273 6792 271 6827 265 7396 277 7428 263 7472 244 7458 205 7501 186 7524 175 7\
925 180 7949 178 8040 169 8143 149 8202 137 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 8203 140 8212 135 8202 134 "];
"UV write_error (18)" -> "UV fprintf (33)" [style=dotted, pos="e,5563,308 5383,368 5430,352 5506,327 5553,311", _draw_="S 6 -dotted c 5 -black B 4 5383 368 5430 352 5506 327 5553 311 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 5554 314 5563 308 5552 308 "];
"UV write_error (18)" -> "UV abort_gzip (34)" [style=dotted, pos="e,4283,306 5305,367 5292,363 5277,358 5263,356 5191,343 4673,353 4599,348 4491,339 4366,320 4293,308", _draw_="S 6 -dotted c 5 -black B 10 5305 367 5292 363 5277 358 5263 356 5191 343 4673 353 4599 348 4491 339 4366 320 4293 308 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 4293 305 4283 306 4292 311 "];
"UV write_error (18)" -> "UV perror (36)" [style=dotted, pos="e,8151,309 5383,368 5400,363 5420,358 5439,356 5582,337 7878,370 8019,348 8062,341 8109,325 8141,313", _draw_="S 6 -dotted c 5 -black B 10 5383 368 5400 363 5420 358 5439 356 5582 337 7878 370 8019 348 8062 341 8109 325 8141 313 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 8143 316 8151 309 8140 309 "];
"UV strlwr (19)" -> "UV isupper (20)" [style=dotted, pos="e,7942,59 7894,111 7906,98 7922,81 7935,66", _draw_="S 6 -dotted c 5 -black B 4 7894 111 7906 98 7922 81 7935 66 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 7937 69 7942 59 7932 64 "];
"UV do_stat (116)" -> "UV __errno_location (11)" [style=dotted, pos="e,5239,309 6854,368 6841,363 6825,358 6810,356 6741,344 5614,353 5543,348 5441,340 5324,323 5249,311", _draw_="S 6 -dotted c 5 -black B 10 6854 368 6841 363 6825 358 6810 356 6741 344 5614 353 5543 348 5441 340 5324 323 5249 311 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 5249 308 5239 309 5248 314 "];
"UV make_simple_name (22)" -> "UV strrchr (21)" [style=dotted, pos="e,7569,229 7606,279 7597,267 7585,250 7575,237", _draw_="S 6 -dotted c 5 -black B 4 7606 279 7597 267 7585 250 7575 237 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 7578 235 7569 229 7572 239 "];
"UV get_suffix (119)" -> "UV strlwr (19)" [style=dotted, pos="e,7841,132 7406,200 7426,195 7449,190 7471,186 7506,179 7730,147 7831,133", _draw_="S 6 -dotted c 5 -black B 7 7406 200 7426 195 7449 190 7471 186 7506 179 7730 147 7831 133 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 7831 136 7841 132 7831 130 "];
"UV get_suffix (119)" -> "UV strlen (25)" [style=dotted, pos="e,6741,132 7307,205 7182,189 6870,148 6751,133", _draw_="S 6 -dotted c 5 -black B 4 7307 205 7182 189 6870 148 6751 133 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 6751 130 6741 132 6751 136 "];
"UV get_suffix (119)" -> "UV strcpy (27)" [style=dotted, pos="e,7431,143 7378,195 7392,182 7410,164 7424,150", _draw_="S 6 -dotted c 5 -black B 4 7378 195 7392 182 7410 164 7424 150 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 7426 153 7431 143 7421 148 "];
"UV get_suffix (119)" -> "UV strcmp (92)" [style=dotted, pos="e,8212,135 7404,200 7424,194 7449,189 7471,186 7577,172 7844,187 7949,178 8040,169 8143,149 8202,137", _draw_="S 6 -dotted c 5 -black B 10 7404 200 7424 194 7449 189 7471 186 7577 172 7844 187 7949 178 8040 169 8143 149 8202 137 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 8203 140 8212 135 8202 134 "];
"UV add_envopt (23)" -> "UV strlen (25)" [style=dotted, pos="e,6664,127 3839,544 3875,538 3915,529 3928,518 4050,414 3934,274 4067,186 4123,148 6298,130 6654,127", _draw_="S 6 -dotted c 5 -black B 10 3839 544 3875 538 3915 529 3928 518 4050 414 3934 274 4067 186 4123 148 6298 130 6654 127 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 6654 131 6664 127 6654 124 "];
"UV add_envopt (23)" -> "UV strcpy (27)" [style=dotted, pos="e,7407,131 3842,546 3889,540 3947,531 3967,518 4003,495 3997,474 4021,441 4079,363 4075,324 4154,271 4271,193 4319,205 4457,186 \
4521,177 6708,180 6772,178 7007,168 7285,143 7397,132", _draw_="S 6 -dotted c 5 -black B 19 3842 546 3889 540 3947 531 3967 518 4003 495 3997 474 4021 441 4079 363 4075 324 4154 271 4271 193 4\
319 205 4457 186 4521 177 6708 180 6772 178 7007 168 7285 143 7397 132 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 7397 135 7407 131 7397 129 "];
"UV add_envopt (23)" -> "UV strcspn (29)" [style=dotted, pos="e,4498,229 3845,548 3906,543 3991,533 4021,518 4109,472 4084,397 4173,356 4204,342 4291,358 4322,348 4391,324 4457,268 4490,236", _draw_="S 6 -dotted c 5 -black B 13 3845 548 3906 543 3991 533 4021 518 4109 472 4084 397 4173 356 4204 342 4291 358 4322 348 4391 324 4\
457 268 4490 236 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 4493 238 4498 229 4488 233 "];
"UV add_envopt (23)" -> "UV free (30)" [style=dotted, pos="e,3762,144 3833,541 3859,535 3886,527 3895,518 3945,464 3942,422 3913,356 3890,301 3851,311 3817,263 3794,228 3775,182 3765,154", _draw_="S 6 -dotted c 5 -black B 13 3833 541 3859 535 3886 527 3895 518 3945 464 3942 422 3913 356 3890 301 3851 311 3817 263 3794 228 3\
775 182 3765 154 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 3768 153 3762 144 3762 155 "];
"UV add_envopt (23)" -> "UV error (32)" [style=dotted, pos="e,3858,399 3828,540 3849,534 3869,526 3874,518 3897,485 3879,437 3863,408", _draw_="S 6 -dotted c 5 -black B 7 3828 540 3849 534 3869 526 3874 518 3897 485 3879 437 3863 408 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 3866 406 3858 399 3860 409 "];
"UV xmalloc (26)" -> "UV error (32)" [style=dotted, pos="e,3817,392 3655,453 3664,449 3673,445 3682,441 3725,424 3774,407 3807,395", _draw_="S 6 -dotted c 5 -black B 7 3655 453 3664 449 3673 445 3682 441 3725 424 3774 407 3807 395 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 3808 398 3817 392 3806 392 "];
"UV xmalloc (26)" -> "UV malloc (39)" [style=dotted, pos="e,2604,398 3600,452 3591,448 3580,443 3570,441 3521,429 2708,448 2659,433 2642,427 2625,415 2612,405", _draw_="S 6 -dotted c 5 -black B 10 3600 452 3591 448 3580 443 3570 441 3521 429 2708 448 2659 433 2642 427 2625 415 2612 405 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 2614 402 2604 398 2609 407 "];
"UV reset_times (129)" -> "UV fprintf (33)" [style=dotted, pos="e,5634,304 7158,368 7142,363 7122,358 7104,356 6980,338 6102,356 5976,348 5857,339 5716,317 5644,306", _draw_="S 6 -dotted c 5 -black B 10 7158 368 7142 363 7122 358 7104 356 6980 338 6102 356 5976 348 5857 339 5716 317 5644 306 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 5644 303 5634 304 5643 309 "];
"UV reset_times (129)" -> "UV perror (36)" [style=dotted, pos="e,8167,314 7241,368 7258,363 7277,358 7294,356 7317,352 8104,356 8125,348 8139,342 8151,332 8160,322", _draw_="S 6 -dotted c 5 -black B 10 7241 368 7258 363 7277 358 7294 356 7317 352 8104 356 8125 348 8139 342 8151 332 8160 322 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 8163 324 8167 314 8158 319 "];
"UV error (32)" -> "UV fprintf (33)" [style=dotted, pos="e,5560,305 3882,378 3942,372 4067,360 4173,356 4298,350 5170,358 5294,348 5386,339 5491,319 5550,307", _draw_="S 6 -dotted c 5 -black B 10 3882 378 3942 372 4067 360 4173 356 4298 350 5170 358 5294 348 5386 339 5491 319 5550 307 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 5551 310 5560 305 5550 304 "];
"UV error (32)" -> "UV abort_gzip (34)" [style=dotted, pos="e,4180,308 3880,375 3944,361 4089,329 4170,310", _draw_="S 6 -dotted c 5 -black B 4 3880 375 3944 361 4089 329 4170 310 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 4171 313 4180 308 4170 307 "];
"UV abort_gzip (34)" -> "UV do_exit (98)" [style=dotted, pos="e,3917,219 4191,283 4179,279 4165,274 4152,271 4075,249 3983,231 3927,221", _draw_="S 6 -dotted c 5 -black B 7 4191 283 4179 279 4165 274 4152 271 4075 249 3983 231 3927 221 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 3927 218 3917 219 3926 224 "];
"UV abort_gzip (34)" -> "UV close (109)" [style=dotted, pos="e,8318,215 4289,291 4362,285 4490,274 4599,271 4936,258 7295,275 7631,263 7888,253 8195,227 8308,216", _draw_="S 6 -dotted c 5 -black B 10 4289 291 4362 285 4490 274 4599 271 4936 258 7295 275 7631 263 7888 253 8195 227 8308 216 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 8308 219 8318 215 8308 213 "];
"UV abort_gzip (34)" -> "UV unlink (111)" [style=dotted, pos="e,8458,229 4289,291 4362,285 4490,274 4599,271 4626,270 8393,272 8417,263 8430,257 8443,247 8452,237", _draw_="S 6 -dotted c 5 -black B 10 4289 291 4362 285 4490 274 4599 271 4626 270 8393 272 8417 263 8430 257 8443 247 8452 237 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 8455 239 8458 229 8449 235 "];
"UV warn (35)" -> "UV fprintf (33)" [style=dotted, pos="e,5576,313 5507,367 5524,354 5549,334 5568,319", _draw_="S 6 -dotted c 5 -black B 4 5507 367 5524 354 5549 334 5568 319 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 5570 322 5576 313 5566 316 "];
"UV fill_window (133)" -> "UV memcpy (48)" [style=dotted, pos="e,2155,399 1258,701 1267,697 1276,693 1283,688 1411,604 1382,501 1521,441 1551,428 2077,444 2107,433 2122,427 2137,416 2148,406", _draw_="S 6 -dotted c 5 -black B 13 1258 701 1267 697 1276 693 1283 688 1411 604 1382 501 1521 441 1551 428 2077 444 2107 433 2122 427 2\
137 416 2148 406 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 2150 409 2155 399 2145 404 "];
"UV fill_window (133)" -> "UV (86)" [style=dotted, pos="e,2870,481 1277,709 1339,705 1437,698 1521,696 1587,693 2043,697 2107,688 2400,645 2738,529 2860,484", _draw_="S 6 -dotted c 5 -black B 10 1277 709 1339 705 1437 698 1521 696 1587 693 2043 697 2107 688 2400 645 2738 529 2860 484 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 2861 487 2870 481 2859 481 "];
"UV display_ratio (37)" -> "UV fprintf (33)" [style=dotted, pos="e,5559,305 4737,370 4764,365 4797,359 4827,356 5034,335 5088,367 5294,348 5386,340 5490,319 5549,307", _draw_="S 6 -dotted c 5 -black B 10 4737 370 4764 365 4797 359 4827 356 5034 335 5088 367 5294 348 5386 340 5490 319 5549 307 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 5550 310 5559 305 5549 304 "];
"UV check_zipfile (40)" -> "UV fprintf (33)" [style=dotted, pos="e,5557,302 5223,368 5236,363 5250,359 5263,356 5364,331 5481,313 5547,303", _draw_="S 6 -dotted c 5 -black B 7 5223 368 5236 363 5250 359 5263 356 5364 331 5481 313 5547 303 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 5547 306 5557 302 5547 300 "];
"UV unzip (41)" -> "UV updcrc (2)" [style=dotted, pos="e,1345,314 1658,782 1608,776 1518,762 1447,732 1378,702 1307,712 1307,637 1307,637 1307,637 1307,552 1307,464 1294,438 1321,356 \
1325,344 1332,332 1339,322", _draw_="S 6 -dotted c 5 -black B 16 1658 782 1608 776 1518 762 1447 732 1378 702 1307 712 1307 637 1307 637 1307 637 1307 552 1307 464 1\
294 438 1321 356 1325 344 1332 332 1339 322 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 1342 324 1345 314 1336 320 "];
"UV unzip (41)" -> "UV fill_inbuf (15)" [style=dotted, pos="e,2706,399 1731,780 1782,770 1877,752 1957,732 2238,659 2352,705 2572,518 2603,491 2587,464 2620,441 2635,430 2643,440 2659,433 \
2673,426 2687,415 2698,406", _draw_="S 6 -dotted c 5 -black B 16 1731 780 1782 770 1877 752 1957 732 2238 659 2352 705 2572 518 2603 491 2587 464 2620 441 2635 430 2\
643 440 2659 433 2673 426 2687 415 2698 406 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 2701 408 2706 399 2696 403 "];
"UV unzip (41)" -> "UV flush_window (16)" [style=dotted, pos="e,1408,400 1662,777 1583,756 1391,697 1391,637 1391,637 1391,637 1391,552 1391,501 1400,443 1406,410", _draw_="S 6 -dotted c 5 -black B 10 1662 777 1583 756 1391 697 1391 637 1391 637 1391 637 1391 552 1391 501 1400 443 1406 410 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 1409 410 1408 400 1403 409 "];
"UV unzip (41)" -> "UV error (32)" [style=dotted, pos="e,3812,386 1733,785 1899,782 2555,768 2639,732 2696,707 2739,698 2739,637 2739,637 2739,637 2739,552 2739,501 2724,473 2763,441 \
2774,432 3242,433 3255,433 3460,422 3703,398 3802,387", _draw_="S 6 -dotted c 5 -black B 19 1733 785 1899 782 2555 768 2639 732 2696 707 2739 698 2739 637 2739 637 2739 637 2739 552 2739 501 2\
724 473 2763 441 2774 432 3242 433 3255 433 3460 422 3703 398 3802 387 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 3802 390 3812 386 3802 384 "];
"UV unzip (41)" -> "UV fprintf (33)" [style=dotted, pos="e,5560,305 1731,780 1795,771 1933,750 2049,732 2266,697 2335,712 2524,603 2626,544 2623,480 2733,441 2752,434 3066,443 3081,433 \
3112,412 3083,376 3113,356 3126,347 5279,349 5294,348 5386,339 5491,319 5550,307", _draw_="S 6 -dotted c 5 -black B 22 1731 780 1795 771 1933 750 2049 732 2266 697 2335 712 2524 603 2626 544 2623 480 2733 441 2752 434 3\
066 443 3081 433 3112 412 3083 376 3113 356 3126 347 5279 349 5294 348 5386 339 5491 319 5550 307 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 5551 310 5560 305 5550 304 "];
"UV inflate (42)" -> "UV flush_window (16)" [style=dotted, pos="e,1419,400 1560,697 1558,694 1556,691 1554,688 1496,589 1444,463 1423,409", _draw_="S 6 -dotted c 5 -black B 7 1560 697 1558 694 1556 691 1554 688 1496 589 1444 463 1423 409 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 1426 408 1419 400 1420 411 "];
"UV read_tree (43)" -> "UV fill_inbuf (15)" [style=dotted, pos="e,2731,399 3126,549 3033,543 2857,531 2831,518 2786,493 2753,441 2736,408", _draw_="S 6 -dotted c 5 -black B 7 3126 549 3033 543 2857 531 2831 518 2786 493 2753 441 2736 408 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 2739 406 2731 399 2733 409 "];
"UV read_tree (43)" -> "UV error (32)" [style=dotted, pos="e,3811,385 3213,537 3264,513 3368,466 3461,441 3582,408 3729,392 3801,386", _draw_="S 6 -dotted c 5 -black B 7 3213 537 3264 513 3368 466 3461 441 3582 408 3729 392 3801 386 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 3801 389 3811 385 3801 383 "];
"UV unpack (45)" -> "UV fill_inbuf (15)" [style=dotted, pos="e,2760,394 3150,453 3139,448 3126,443 3113,441 3026,422 3001,446 2913,433 2863,425 2808,409 2770,397", _draw_="S 6 -dotted c 5 -black B 10 3150 453 3139 448 3126 443 3113 441 3026 422 3001 446 2913 433 2863 425 2808 409 2770 397 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 2771 394 2760 394 2769 400 "];
"UV unpack (45)" -> "UV flush_window (16)" [style=dotted, pos="e,1439,399 3151,453 3140,448 3126,443 3113,441 3027,424 1608,452 1521,433 1496,427 1468,415 1448,404", _draw_="S 6 -dotted c 5 -black B 10 3151 453 3140 448 3126 443 3113 441 3027 424 1608 452 1521 433 1496 427 1468 415 1448 404 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 1449 401 1439 399 1446 407 "];
"UV unpack (45)" -> "UV error (32)" [style=dotted, pos="e,3812,386 3223,461 3343,446 3680,404 3802,387", _draw_="S 6 -dotted c 5 -black B 4 3223 461 3343 446 3680 404 3802 387 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 3802 390 3812 386 3802 384 "];
"UV unlzw (46)" -> "UV read (9)" [style=dotted, pos="e,2831,307 2425,455 2437,450 2449,442 2459,433 2488,405 2470,376 2503,356 2520,346 2654,350 2672,348 2725,340 2784,322 2821,310", _draw_="S 6 -dotted c 5 -black B 13 2425 455 2437 450 2449 442 2459 433 2488 405 2470 376 2503 356 2520 346 2654 350 2672 348 2725 340 2\
784 322 2821 310 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 2822 313 2831 307 2820 307 "];
"UV unlzw (46)" -> "UV write_buf (12)" [style=dotted, pos="e,2543,310 2411,451 2416,445 2421,439 2425,433 2447,401 2438,383 2465,356 2484,337 2511,323 2534,314", _draw_="S 6 -dotted c 5 -black B 10 2411 451 2416 445 2421 439 2425 433 2447 401 2438 383 2465 356 2484 337 2511 323 2534 314 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 2535 317 2543 310 2532 311 "];
"UV unlzw (46)" -> "UV read_error (13)" [style=dotted, pos="e,2948,396 2435,463 2488,457 2585,447 2668,441 2729,436 2745,443 2805,433 2852,426 2902,411 2938,399", _draw_="S 6 -dotted c 5 -black B 10 2435 463 2488 457 2585 447 2668 441 2729 436 2745 443 2805 433 2852 426 2902 411 2938 399 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 2939 402 2948 396 2937 396 "];
"UV unlzw (46)" -> "UV fill_inbuf (15)" [style=dotted, pos="e,2708,399 2424,454 2437,449 2453,444 2468,441 2510,432 2620,447 2659,433 2675,427 2690,416 2701,406", _draw_="S 6 -dotted c 5 -black B 10 2424 454 2437 449 2453 444 2468 441 2510 432 2620 447 2659 433 2675 427 2690 416 2701 406 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 2703 409 2708 399 2698 404 "];
"UV unlzw (46)" -> "UV error (32)" [style=dotted, pos="e,3812,386 2435,463 2497,457 2621,445 2725,441 2961,429 3020,444 3255,433 3460,422 3703,398 3802,387", _draw_="S 6 -dotted c 5 -black B 10 2435 463 2497 457 2621 445 2725 441 2961 429 3020 444 3255 433 3460 422 3703 398 3802 387 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 3802 390 3812 386 3802 384 "];
"UV unlzw (46)" -> "UV fprintf (33)" [style=dotted, pos="e,5560,305 2419,453 2427,448 2436,444 2445,441 2467,433 2477,446 2495,433 2526,410 2501,376 2533,356 2550,345 5275,349 5294,348 \
5386,339 5491,319 5550,307", _draw_="S 6 -dotted c 5 -black B 16 2419 453 2427 448 2436 444 2445 441 2467 433 2477 446 2495 433 2526 410 2501 376 2533 356 2550 345 5\
275 349 5294 348 5386 339 5491 319 5550 307 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 5551 310 5560 305 5550 304 "];
"UV unlzw (46)" -> "UV memset (47)" [style=dotted, pos="e,2355,399 2385,450 2378,438 2368,421 2360,408", _draw_="S 6 -dotted c 5 -black B 4 2385 450 2378 438 2368 421 2360 408 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 2363 406 2355 399 2357 409 "];
"UV unlzw (46)" -> "UV memcpy (48)" [style=dotted, pos="e,2199,396 2360,457 2338,451 2308,442 2283,433 2258,423 2230,411 2208,400", _draw_="S 6 -dotted c 5 -black B 7 2360 457 2338 451 2308 442 2283 433 2258 423 2230 411 2208 400 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 2210 397 2199 396 2207 403 "];
"UV fillbuf (49)" -> "UV fill_inbuf (15)" [style=dotted, pos="e,2719,400 8677,786 8205,784 3397,761 3255,732 3010,682 2881,720 2733,518 2711,486 2713,440 2717,410", _draw_="S 6 -dotted c 5 -black B 10 8677 786 8205 784 3397 761 3255 732 3010 682 2881 720 2733 518 2711 486 2713 440 2717 410 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 2720 410 2719 400 2714 409 "];
"UV make_table (52)" -> "UV error (32)" [style=dotted, pos="e,3880,389 9023,452 9011,447 8996,443 8983,441 8918,429 4240,438 4173,433 4071,424 3952,403 3890,391", _draw_="S 6 -dotted c 5 -black B 10 9023 452 9011 447 8996 443 8983 441 8918 429 4240 438 4173 433 4071 424 3952 403 3890 391 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 3890 388 3880 389 3889 394 "];
"UV unlzh (60)" -> "UV write_buf (12)" [style=dotted, pos="e,2627,309 8997,783 8944,779 8845,771 8760,768 8457,754 3530,801 3300,603 3216,529 3341,428 3255,356 3246,348 2827,349 2814,348 \
2753,341 2683,324 2637,312", _draw_="S 6 -dotted c 5 -black B 16 8997 783 8944 779 8845 771 8760 768 8457 754 3530 801 3300 603 3216 529 3341 428 3255 356 3246 348 2\
827 349 2814 348 2753 341 2683 324 2637 312 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 2638 309 2627 309 2636 315 "];
"UV lzw (78)" -> "UV fprintf (33)" [style=dotted, pos="e,5596,315 5596,364 5596,352 5596,338 5596,325", _draw_="S 6 -dotted c 5 -black B 4 5596 364 5596 352 5596 338 5596 325 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 5600 325 5596 315 5593 325 "];
"UV huft_build (79)" -> "UV malloc (39)" [style=dotted, pos="e,2556,394 2093,462 2199,453 2417,435 2425,433 2468,425 2514,409 2546,398", _draw_="S 6 -dotted c 5 -black B 7 2093 462 2199 453 2417 435 2425 433 2468 425 2514 409 2546 398 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 2548 401 2556 394 2545 394 "];
"UV huft_build (79)" -> "UV memset (47)" [style=dotted, pos="e,2322,398 2094,463 2138,459 2200,450 2251,433 2273,425 2295,413 2313,403", _draw_="S 6 -dotted c 5 -black B 7 2094 463 2138 459 2200 450 2251 433 2273 425 2295 413 2313 403 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 2315 406 2322 398 2312 400 "];
"UV huft_free (80)" -> "UV free (30)" [style=dotted, pos="e,3727,127 1990,367 2073,329 2307,226 2514,186 2752,139 3531,129 3717,127", _draw_="S 6 -dotted c 5 -black B 7 1990 367 2073 329 2307 226 2514 186 2752 139 3531 129 3717 127 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 3717 131 3727 127 3717 124 "];
"UV inflate_codes (81)" -> "UV fill_inbuf (15)" [style=dotted, pos="e,2708,399 1858,456 1890,450 1931,444 1968,441 2007,437 2623,445 2659,433 2675,427 2690,416 2701,406", _draw_="S 6 -dotted c 5 -black B 10 1858 456 1890 450 1931 444 1968 441 2007 437 2623 445 2659 433 2675 427 2690 416 2701 406 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 2703 409 2708 399 2698 404 "];
"UV inflate_codes (81)" -> "UV flush_window (16)" [style=dotted, pos="e,1441,398 1731,461 1662,455 1560,444 1521,433 1497,426 1470,414 1450,403", _draw_="S 6 -dotted c 5 -black B 7 1731 461 1662 455 1560 444 1521 433 1497 426 1470 414 1450 403 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 1451 400 1441 398 1448 406 "];
"UV inflate_codes (81)" -> "UV memcpy (48)" [style=dotted, pos="e,2155,399 1859,456 1891,451 1932,444 1968,441 1999,437 2079,444 2107,433 2122,427 2137,416 2148,406", _draw_="S 6 -dotted c 5 -black B 10 1859 456 1891 451 1932 444 1968 441 1999 437 2079 444 2107 433 2122 427 2137 416 2148 406 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 2150 409 2155 399 2145 404 "];
"UV inflate_stored (82)" -> "UV fill_inbuf (15)" [style=dotted, pos="e,2708,399 1848,537 1862,532 1878,528 1892,526 1908,523 2453,527 2466,518 2497,497 2467,462 2496,441 2511,430 2643,439 2659,433 \
2675,427 2690,416 2701,406", _draw_="S 6 -dotted c 5 -black B 16 1848 537 1862 532 1878 528 1892 526 1908 523 2453 527 2466 518 2497 497 2467 462 2496 441 2511 430 2\
643 439 2659 433 2675 427 2690 416 2701 406 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 2703 409 2708 399 2698 404 "];
"UV inflate_stored (82)" -> "UV flush_window (16)" [style=dotted, pos="e,1446,398 1766,537 1751,531 1734,524 1718,518 1630,481 1608,472 1521,433 1500,423 1475,412 1455,402", _draw_="S 6 -dotted c 5 -black B 10 1766 537 1751 531 1734 524 1718 518 1630 481 1608 472 1521 433 1500 423 1475 412 1455 402 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 1457 399 1446 398 1454 405 "];
"UV inflate_dynamic (84)" -> "UV fill_inbuf (15)" [style=dotted, pos="e,2707,399 2075,550 2210,547 2461,539 2496,518 2531,497 2510,461 2544,441 2566,427 2636,442 2659,433 2674,427 2688,416 2699,406", _draw_="S 6 -dotted c 5 -black B 13 2075 550 2210 547 2461 539 2496 518 2531 497 2510 461 2544 441 2566 427 2636 442 2659 433 2674 427 2\
688 416 2699 406 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 2702 408 2707 399 2697 403 "];
"UV inflate_dynamic (84)" -> "UV fprintf (33)" [style=dotted, pos="e,5560,305 2045,538 2064,533 2085,526 2104,518 2174,488 2202,489 2251,433 2276,405 2253,376 2283,356 2301,344 5274,349 5294,348 \
5386,339 5491,319 5550,307", _draw_="S 6 -dotted c 5 -black B 16 2045 538 2064 533 2085 526 2104 518 2174 488 2202 489 2251 433 2276 405 2253 376 2283 356 2301 344 5\
274 349 5294 348 5386 339 5491 319 5550 307 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 5551 310 5560 305 5550 304 "];
"UV inflate_block (85)" -> "UV fill_inbuf (15)" [style=dotted, pos="e,2707,399 1872,633 2033,623 2426,591 2533,518 2567,495 2548,462 2582,441 2612,422 2628,446 2659,433 2674,427 2688,416 2699,406", _draw_="S 6 -dotted c 5 -black B 13 1872 633 2033 623 2426 591 2533 518 2567 495 2548 462 2582 441 2612 422 2628 446 2659 433 2674 427 2\
688 416 2699 406 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 2702 408 2707 399 2697 403 "];
"UV usage (87)" -> "UV fprintf (33)" [style=dotted, pos="e,5635,303 5425,458 5450,452 5484,444 5514,441 5530,439 5787,444 5797,433 5821,408 5818,383 5797,356 5779,332 5699,313 5645,305", _draw_="S 6 -dotted c 5 -black B 13 5425 458 5450 452 5484 444 5514 441 5530 439 5787 444 5797 433 5821 408 5818 383 5797 356 5779 332 5\
699 313 5645 305 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 5645 302 5635 303 5644 308 "];
"UV help (88)" -> "UV fprintf (33)" [style=dotted, pos="e,5636,302 5414,540 5426,534 5440,529 5453,526 5502,515 5629,532 5676,518 5747,497 5782,496 5818,433 5835,403 5839,383 5818,356 \
5797,329 5705,311 5646,303", _draw_="S 6 -dotted c 5 -black B 16 5414 540 5426 534 5440 529 5453 526 5502 515 5629 532 5676 518 5747 497 5782 496 5818 433 5835 403 5\
839 383 5818 356 5797 329 5705 311 5646 303 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 5646 300 5636 302 5646 306 "];
"UV help (88)" -> "UV usage (87)" [style=dotted, pos="e,5391,485 5391,534 5391,522 5391,508 5391,495", _draw_="S 6 -dotted c 5 -black B 4 5391 534 5391 522 5391 508 5391 495 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 5395 495 5391 485 5388 495 "];
"UV license (89)" -> "UV fprintf (33)" [style=dotted, pos="e,5637,299 5539,539 5552,534 5568,529 5583,526 5601,522 5891,530 5903,518 5954,466 5949,411 5903,356 5871,317 5726,303 5647,299", _draw_="S 6 -dotted c 5 -black B 13 5539 539 5552 534 5568 529 5583 526 5601 522 5891 530 5903 518 5954 466 5949 411 5903 356 5871 317 5\
726 303 5647 299 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 5647 296 5637 299 5647 303 "];
"UV version (90)" -> "UV fprintf (33)" [style=dotted, pos="e,5636,301 5673,539 5687,534 5704,529 5719,526 5732,523 5933,526 5941,518 5991,466 5988,411 5941,356 5923,334 5738,312 5646,302", _draw_="S 6 -dotted c 5 -black B 13 5673 539 5687 534 5704 529 5719 526 5732 523 5933 526 5941 518 5991 466 5988 411 5941 356 5923 334 5\
738 312 5646 302 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 5646 299 5636 301 5646 305 "];
"UV main (91)" -> "UV basename (6)" [style=dotted, pos="e,6228,399 5544,636 5602,633 5715,624 5747,603 5781,580 5761,546 5795,526 5821,511 6028,527 6055,518 6123,495 6187,438 6220,406", _draw_="S 6 -dotted c 5 -black B 13 5544 636 5602 633 5715 624 5747 603 5781 580 5761 546 5795 526 5821 511 6028 527 6055 518 6123 495 6\
187 438 6220 406 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 6223 408 6228 399 6218 403 "];
"UV main (91)" -> "UV add_envopt (23)" [style=dotted, pos="e,3834,562 5474,637 5285,635 4385,627 4107,603 4016,594 3910,576 3844,564", _draw_="S 6 -dotted c 5 -black B 7 5474 637 5285 635 4385 627 4107 603 4016 594 3910 576 3844 564 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 3844 561 3834 562 3843 567 "];
"UV main (91)" -> "UV strlen (25)" [style=dotted, pos="e,6664,127 5474,637 5268,635 4226,622 4135,518 4103,479 4110,322 4154,271 4245,164 4319,206 4457,186 4680,151 6345,131 6654,127", _draw_="S 6 -dotted c 5 -black B 13 5474 637 5268 635 4226 622 4135 518 4103 479 4110 322 4154 271 4245 164 4319 206 4457 186 4680 151 6\
345 131 6654 127 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 6654 131 6664 127 6654 124 "];
"UV main (91)" -> "UV strcpy (27)" [style=dotted, pos="e,7449,145 5544,635 5597,632 5691,624 5717,603 5746,579 5718,547 5747,526 5768,511 5948,527 5970,518 6018,498 6016,473 6055,441 \
6105,400 6111,376 6171,356 6188,350 7421,360 7433,348 7460,322 7454,208 7450,155", _draw_="S 6 -dotted c 5 -black B 22 5544 635 5597 632 5691 624 5717 603 5746 579 5718 547 5747 526 5768 511 5948 527 5970 518 6018 498 6\
016 473 6055 441 6105 400 6111 376 6171 356 6188 350 7421 360 7433 348 7460 322 7454 208 7450 155 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 7453 155 7449 145 7447 155 "];
"UV main (91)" -> "UV fprintf (33)" [style=dotted, pos="e,5559,305 5474,635 5365,627 5035,597 4971,518 4927,461 4921,407 4971,356 4978,349 5286,348 5294,348 5386,339 5490,318 5549,307", _draw_="S 6 -dotted c 5 -black B 13 5474 635 5365 627 5035 597 4971 518 4927 461 4921 407 4971 356 4978 349 5286 348 5294 348 5386 339 5\
490 318 5549 307 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 5550 310 5559 305 5549 304 "];
"UV main (91)" -> "UV usage (87)" [style=dotted, pos="e,5374,483 5474,635 5431,631 5363,622 5347,603 5326,576 5337,558 5347,526 5352,513 5360,501 5368,491", _draw_="S 6 -dotted c 5 -black B 10 5474 635 5431 631 5363 622 5347 603 5326 576 5337 558 5347 526 5352 513 5360 501 5368 491 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 5371 493 5374 483 5365 489 "];
"UV main (91)" -> "UV help (88)" [style=dotted, pos="e,5408,567 5486,624 5476,618 5464,610 5453,603 5440,594 5427,583 5416,574", _draw_="S 6 -dotted c 5 -black B 7 5486 624 5476 618 5464 610 5453 603 5440 594 5427 583 5416 574 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 5418 571 5408 567 5413 576 "];
"UV main (91)" -> "UV license (89)" [style=dotted, pos="e,5509,570 5509,619 5509,607 5509,593 5509,580", _draw_="S 6 -dotted c 5 -black B 4 5509 619 5509 607 5509 593 5509 580 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 5513 580 5509 570 5506 580 "];
"UV main (91)" -> "UV version (90)" [style=dotted, pos="e,5625,568 5537,626 5551,620 5569,612 5583,603 5595,595 5608,585 5618,575", _draw_="S 6 -dotted c 5 -black B 7 5537 626 5551 620 5569 612 5583 603 5595 595 5608 585 5618 575 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 5620 578 5625 568 5615 573 "];
"UV main (91)" -> "UV strcmp (92)" [style=dotted, pos="e,8258,144 5544,634 5613,629 5765,616 5784,603 5816,581 5793,546 5825,526 5845,513 6008,520 6030,518 6199,497 6236,458 6405,441 \
6519,429 7319,439 7433,433 7616,422 8129,483 8251,348 8299,294 8277,200 8261,154", _draw_="S 6 -dotted c 5 -black B 22 5544 634 5613 629 5765 616 5784 603 5816 581 5793 546 5825 526 5845 513 6008 520 6030 518 6199 497 6\
236 458 6405 441 6519 429 7319 439 7433 433 7616 422 8129 483 8251 348 8299 294 8277 200 8261 154 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 8264 153 8258 144 8258 155 "];
"UV main (91)" -> "UV signal (93)" [style=dotted, pos="e,5864,569 5544,636 5616,633 5775,625 5823,603 5836,597 5848,586 5857,576", _draw_="S 6 -dotted c 5 -black B 7 5544 636 5616 633 5775 625 5823 603 5836 597 5848 586 5857 576 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 5859 579 5864 569 5854 574 "];
"UV main (91)" -> "UV strncmp (94)" [style=dotted, pos="e,5993,569 5544,635 5641,631 5908,617 5945,603 5960,597 5974,586 5985,576", _draw_="S 6 -dotted c 5 -black B 7 5544 635 5641 631 5908 617 5945 603 5960 597 5974 586 5985 576 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 5988 578 5993 569 5983 573 "];
"UV main (91)" -> "UV strncpy (95)" [style=dotted, pos="e,6134,569 5544,636 5662,633 6039,623 6089,603 6103,597 6117,586 6127,576", _draw_="S 6 -dotted c 5 -black B 7 5544 636 5662 633 6039 623 6089 603 6103 597 6117 586 6127 576 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 6129 579 6134 569 6124 574 "];
"UV main (91)" -> "UV getopt_long (96)" [style=dotted, pos="e,6286,569 5544,636 5679,634 6161,623 6225,603 6244,597 6263,586 6278,575", _draw_="S 6 -dotted c 5 -black B 7 5544 636 5679 634 6161 623 6225 603 6244 597 6263 586 6278 575 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 6280 578 6286 569 6276 572 "];
"UV main (91)" -> "UV atoi (97)" [style=dotted, pos="e,3415,568 5474,637 5207,635 3511,621 3461,603 3447,597 3433,586 3422,575", _draw_="S 6 -dotted c 5 -black B 7 5474 637 5207 635 3511 621 3461 603 3447 597 3433 586 3422 575 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 3425 573 3415 568 3420 578 "];
"UV main (91)" -> "UV do_exit (98)" [style=dotted, pos="e,3837,222 5474,637 5196,635 3359,622 3339,603 3165,425 3666,269 3827,225", _draw_="S 6 -dotted c 5 -black B 7 5474 637 5196 635 3359 622 3339 603 3165 425 3666 269 3827 225 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 3828 228 3837 222 3826 222 "];
"UV main (91)" -> "UV treat_file (99)" [style=dotted, pos="e,6727,560 5544,636 5688,632 6234,618 6405,603 6516,593 6644,574 6717,562", _draw_="S 6 -dotted c 5 -black B 7 5544 636 5688 632 6234 618 6405 603 6516 593 6644 574 6717 562 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 6718 565 6727 560 6717 559 "];
"UV main (91)" -> "UV treat_stdin (100)" [style=dotted, pos="e,4827,568 5474,636 5353,632 4956,618 4900,603 4878,597 4854,584 4836,573", _draw_="S 6 -dotted c 5 -black B 7 5474 636 5353 632 4956 618 4900 603 4878 597 4854 584 4836 573 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 4837 570 4827 568 4834 576 "];
"UV main (91)" -> "UV do_list (101)" [style=dotted, pos="e,4272,473 5474,637 5197,635 3380,622 3361,603 3337,578 3337,550 3361,526 3372,515 3863,518 3877,518 4018,508 4181,486 4262,474", _draw_="S 6 -dotted c 5 -black B 13 5474 637 5197 635 3380 622 3361 603 3337 578 3337 550 3361 526 3372 515 3863 518 3877 518 4018 508 4\
181 486 4262 474 ", _hdraw_="S 5 -solid S 15 -setlinewidth(1) c 5 -black C 5 -black P 3 4262 477 4272 473 4262 471 "];
}
ocamlgraph-2.0.0/dgraph/examples/crazy.dot 0000755 0001750 0000144 00000012704 13735627615 017143 0 ustar rt users digraph "unix" {
graph [ fontname = "Helvetica-Oblique",
fontsize = 36,
label = "\n\n\n\nObject Oriented Graphs\nStephen North, 3/19/93",
size = "6,6" ];
node [ shape = polygon,
sides = 4,
distortion = "0.0",
orientation = "0.0",
skew = "0.0",
color = white,
style = filled,
fontname = "Helvetica-Outline" ];
"5th Edition" [sides=9, distortion="0.936354", orientation=28, skew="-0.126818", color=salmon2];
"6th Edition" [sides=5, distortion="0.238792", orientation=11, skew="0.995935", color=deepskyblue];
"PWB 1.0" [sides=8, distortion="0.019636", orientation=79, skew="-0.440424", color=goldenrod2];
LSX [sides=9, distortion="-0.698271", orientation=22, skew="-0.195492", color=burlywood2];
"1 BSD" [sides=7, distortion="0.265084", orientation=26, skew="0.403659", color=gold1];
"Mini Unix" [distortion="0.039386", orientation=2, skew="-0.461120", color=greenyellow];
Wollongong [sides=5, distortion="0.228564", orientation=63, skew="-0.062846", color=darkseagreen];
Interdata [distortion="0.624013", orientation=56, skew="0.101396", color=dodgerblue1];
"Unix/TS 3.0" [sides=8, distortion="0.731383", orientation=43, skew="-0.824612", color=thistle2];
"PWB 2.0" [sides=6, distortion="0.592100", orientation=34, skew="-0.719269", color=darkolivegreen3];
"7th Edition" [sides=10, distortion="0.298417", orientation=65, skew="0.310367", color=chocolate];
"8th Edition" [distortion="-0.997093", orientation=50, skew="-0.061117", color=turquoise3];
"32V" [sides=7, distortion="0.878516", orientation=19, skew="0.592905", color=steelblue3];
V7M [sides=10, distortion="-0.960249", orientation=32, skew="0.460424", color=navy];
"Ultrix-11" [sides=10, distortion="-0.633186", orientation=10, skew="0.333125", color=darkseagreen4];
Xenix [sides=8, distortion="-0.337997", orientation=52, skew="-0.760726", color=coral];
"UniPlus+" [sides=7, distortion="0.788483", orientation=39, skew="-0.526284", color=darkolivegreen3];
"9th Edition" [sides=7, distortion="0.138690", orientation=55, skew="0.554049", color=coral3];
"2 BSD" [sides=7, distortion="-0.010661", orientation=84, skew="0.179249", color=blanchedalmond];
"2.8 BSD" [distortion="-0.239422", orientation=44, skew="0.053841", color=lightskyblue1];
"2.9 BSD" [distortion="-0.843381", orientation=70, skew="-0.601395", color=aquamarine2];
"3 BSD" [sides=10, distortion="0.251820", orientation=18, skew="-0.530618", color=lemonchiffon];
"4 BSD" [sides=5, distortion="-0.772300", orientation=24, skew="-0.028475", color=darkorange1];
"4.1 BSD" [distortion="-0.226170", orientation=38, skew="0.504053", color=lightyellow1];
"4.2 BSD" [sides=10, distortion="-0.807349", orientation=50, skew="-0.908842", color=darkorchid4];
"4.3 BSD" [sides=10, distortion="-0.030619", orientation=76, skew="0.985021", color=lemonchiffon2];
"Ultrix-32" [distortion="-0.644209", orientation=21, skew="0.307836", color=goldenrod3];
"PWB 1.2" [sides=7, distortion="0.640971", orientation=84, skew="-0.768455", color=cyan];
"USG 1.0" [distortion="0.758942", orientation=42, skew="0.039886", color=blue];
"CB Unix 1" [sides=9, distortion="-0.348692", orientation=42, skew="0.767058", color=firebrick];
"USG 2.0" [distortion="0.748625", orientation=74, skew="-0.647656", color=chartreuse4];
"CB Unix 2" [sides=10, distortion="0.851818", orientation=32, skew="-0.020120", color=greenyellow];
"CB Unix 3" [sides=10, distortion="0.992237", orientation=29, skew="0.256102", color=bisque4];
"Unix/TS++" [sides=6, distortion="0.545461", orientation=16, skew="0.313589", color=mistyrose2];
"PDP-11 Sys V" [sides=9, distortion="-0.267769", orientation=40, skew="0.271226", color=cadetblue1];
"USG 3.0" [distortion="-0.848455", orientation=44, skew="0.267152", color=bisque2];
"Unix/TS 1.0" [distortion="0.305594", orientation=75, skew="0.070516", color=orangered];
"TS 4.0" [sides=10, distortion="-0.641701", orientation=50, skew="-0.952502", color=crimson];
"System V.0" [sides=9, distortion="0.021556", orientation=26, skew="-0.729938", color=darkorange1];
"System V.2" [sides=6, distortion="0.985153", orientation=33, skew="-0.399752", color=darkolivegreen4];
"System V.3" [sides=7, distortion="-0.687574", orientation=58, skew="-0.180116", color=lightsteelblue1];
"5th Edition" -> "6th Edition";
"5th Edition" -> "PWB 1.0";
"6th Edition" -> LSX;
"6th Edition" -> "1 BSD";
"6th Edition" -> "Mini Unix";
"6th Edition" -> Wollongong;
"6th Edition" -> Interdata;
Interdata -> "Unix/TS 3.0";
Interdata -> "PWB 2.0";
Interdata -> "7th Edition";
"7th Edition" -> "8th Edition";
"7th Edition" -> "32V";
"7th Edition" -> V7M;
"7th Edition" -> "Ultrix-11";
"7th Edition" -> Xenix;
"7th Edition" -> "UniPlus+";
V7M -> "Ultrix-11";
"8th Edition" -> "9th Edition";
"1 BSD" -> "2 BSD";
"2 BSD" -> "2.8 BSD";
"2.8 BSD" -> "Ultrix-11";
"2.8 BSD" -> "2.9 BSD";
"32V" -> "3 BSD";
"3 BSD" -> "4 BSD";
"4 BSD" -> "4.1 BSD";
"4.1 BSD" -> "4.2 BSD";
"4.1 BSD" -> "2.8 BSD";
"4.1 BSD" -> "8th Edition";
"4.2 BSD" -> "4.3 BSD";
"4.2 BSD" -> "Ultrix-32";
"PWB 1.0" -> "PWB 1.2";
"PWB 1.0" -> "USG 1.0";
"PWB 1.2" -> "PWB 2.0";
"USG 1.0" -> "CB Unix 1";
"USG 1.0" -> "USG 2.0";
"CB Unix 1" -> "CB Unix 2";
"CB Unix 2" -> "CB Unix 3";
"CB Unix 3" -> "Unix/TS++";
"CB Unix 3" -> "PDP-11 Sys V";
"USG 2.0" -> "USG 3.0";
"USG 3.0" -> "Unix/TS 3.0";
"PWB 2.0" -> "Unix/TS 3.0";
"Unix/TS 1.0" -> "Unix/TS 3.0";
"Unix/TS 3.0" -> "TS 4.0";
"Unix/TS++" -> "TS 4.0";
"CB Unix 3" -> "TS 4.0";
"TS 4.0" -> "System V.0";
"System V.0" -> "System V.2";
"System V.2" -> "System V.3";
}
ocamlgraph-2.0.0/dgraph/examples/unix2.gv 0000755 0001750 0000144 00000003267 13735627615 016712 0 ustar rt users /* Courtesy of Ian Darwin
* and Geoff Collyer
* Mildly updated by Ian Darwin in 2000.
*/
digraph unix {
size="6,6";
node [color=lightblue2, style=filled];
"5th Edition" -> "6th Edition";
"5th Edition" -> "PWB 1.0";
"6th Edition" -> "LSX";
"6th Edition" -> "1 BSD";
"6th Edition" -> "Mini Unix";
"6th Edition" -> "Wollongong";
"6th Edition" -> "Interdata";
"Interdata" -> "Unix/TS 3.0";
"Interdata" -> "PWB 2.0";
"Interdata" -> "7th Edition";
"7th Edition" -> "8th Edition";
"7th Edition" -> "32V";
"7th Edition" -> "V7M";
"7th Edition" -> "Ultrix-11";
"7th Edition" -> "Xenix";
"7th Edition" -> "UniPlus+";
"V7M" -> "Ultrix-11";
"8th Edition" -> "9th Edition";
"9th Edition" -> "10th Edition";
"1 BSD" -> "2 BSD";
"2 BSD" -> "2.8 BSD";
"2.8 BSD" -> "Ultrix-11";
"2.8 BSD" -> "2.9 BSD";
"32V" -> "3 BSD";
"3 BSD" -> "4 BSD";
"4 BSD" -> "4.1 BSD";
"4.1 BSD" -> "4.2 BSD";
"4.1 BSD" -> "2.8 BSD";
"4.1 BSD" -> "8th Edition";
"4.2 BSD" -> "4.3 BSD";
"4.2 BSD" -> "Ultrix-32";
"4.3 BSD" -> "4.4 BSD";
"4.4 BSD" -> "FreeBSD";
"4.4 BSD" -> "NetBSD";
"4.4 BSD" -> "OpenBSD";
"PWB 1.0" -> "PWB 1.2";
"PWB 1.0" -> "USG 1.0";
"PWB 1.2" -> "PWB 2.0";
"USG 1.0" -> "CB Unix 1";
"USG 1.0" -> "USG 2.0";
"CB Unix 1" -> "CB Unix 2";
"CB Unix 2" -> "CB Unix 3";
"CB Unix 3" -> "Unix/TS++";
"CB Unix 3" -> "PDP-11 Sys V";
"USG 2.0" -> "USG 3.0";
"USG 3.0" -> "Unix/TS 3.0";
"PWB 2.0" -> "Unix/TS 3.0";
"Unix/TS 1.0" -> "Unix/TS 3.0";
"Unix/TS 3.0" -> "TS 4.0";
"Unix/TS++" -> "TS 4.0";
"CB Unix 3" -> "TS 4.0";
"TS 4.0" -> "System V.0";
"System V.0" -> "System V.2";
"System V.2" -> "System V.3";
"System V.3" -> "System V.4";
}
ocamlgraph-2.0.0/dgraph/examples/dep.dot 0000755 0001750 0000144 00000054234 13735627615 016567 0 ustar rt users digraph G {
"";
"-slice-loop-var is set";
"-inout is set";
"-sparecode-verbose is set";
"message_table";
"-copy is set";
"contextfree_only_globals";
" is set";
"Components.compute";
"-scg-help";
"-security-analysis";
"-continue-annot-error";
"-orig-name";
"-dominators-verbose is set";
"pdg_node lattice_set offsetmap_bitwise G[base] ptmap hashconsing_table 9";
"-dominators-help is set";
"-cg-init-func";
"(bool lattice_base, bool lattice_base) lattice_product offsetmap_bitwise G[base] ptmap hashconsing_table 10";
"Cluster_info offsetmaphashconsing_table";
"(bool lattice_base, bool lattice_base) lattice_product offsetmap_bitwise G[base] ptmap hashconsing_table 12";
"-overflow is set";
"-journal-enable";
"-occurrence-verbose is set";
"-slicing-verbose";
"-unicode";
"-debug is set";
"message_counter";
"-slicing-keep-annotations";
"-security-help is set";
"Users";
"-cg-help is set";
"big_int lattice_mod G[base] ptmap hashconsing_table 3";
"-slice-undef-functions is set";
"-value-debug is set";
"-sparecode-analysis";
"-simplify-cfg is set";
"-no-type";
"V_Or_Uninitialized offsetmap G[base] ptmap hashconsing_table 6";
"postdominator";
"-obfuscate";
"FileIndex";
"-slicing-level is set";
"int lattice_set offsetmap_bitwise G[base] ptmap hashconsing_table 13";
"-impact-pragma is set";
"Components.Nodes";
"-pdg is set";
"Dynamic_Alloc_Table";
"-sparecode-debug is set";
"-scope-help is set";
"-security-debug";
"-input is set";
"-slice-pragma";
"Annotations";
"Components";
"-quiet is set";
"-slice-loop-inv is set";
"-security-verbose is set";
"-metrics-debug";
"-dump-dependencies";
"-slice-assert is set";
"-value-verbose";
"-wp-help is set";
"-cast-from-constant";
"-inout-debug is set";
"-cpp-extra-args";
"FileIndex.compute";
"-lib-entry";
"-unspecified-access";
"-security-annotation";
"Globals.Vars";
"-users-verbose";
"builtin logic functions table";
"-slice-return";
"-sparecode-help";
"-security-analysis is set";
"-no-obj";
"-float-digits";
"-annot";
"-cg is set";
"-impact-help is set";
"-ocode is set";
"-impact-verbose is set";
"-users-debug is set";
"-wp-cfg";
"-wp-help";
"-slice-calls";
"-security-annotation is set";
"-print";
"alarms";
"-constfold is set";
"-slice-rd";
"-deps is set";
"-machdep is set";
"logic types table";
"-val is set";
"UseRelations";
"-sparecode-help is set";
"-slice-loop-var";
"-semantic-const-fold";
"-main is set";
"AST";
"FormalsDecl";
"-out-external";
"-wp-cfg is set";
"-value-help is set";
"external_inputs";
"-scope-debug is set";
"-from-help is set";
"internal_inouts";
"-security-lattice is set";
"-inout-help is set";
"metrics";
"-memory-footprint is set";
"-impact-slicing";
"-print-path";
"-scf-help";
"-metrics-verbose";
"!Db.Value.compute";
"-overflow";
"-semantic-const-fold is set";
"callwise_from";
"vid";
"-verbose";
"-security-slicing";
"-input-with-formals is set";
"-slevel is set";
"-value-debug";
"Leaf_Table";
"-dominators-verbose";
"-dominators-debug";
"-semantic-const-folding";
"-cpp-command";
"-add-path is set";
"-val";
"-slice-calls is set";
"-unicode is set";
"-pdg-help";
"-wp-proof";
"-slice-value";
"-help is set";
"-users-help is set";
"-scf-help is set";
"-occurrence-debug is set";
"-verbose is set";
"called_functions";
"-deref";
"-version is set";
"Location_Bytes offsetmaphashconsing_table";
"-cg-verbose";
"-debug";
"-ulevel";
"-context-valid-pointers is set";
"-keep-switch";
"-pdg-debug";
"File.t";
"Functions";
"value_table";
"-load-module is set";
"-time is set";
"-security-help";
"-slicing-debug";
"-input-with-formals";
"Buckx.MemoryFootprint";
"-dump-dependencies is set";
"-slice-wr is set";
"-wp-bot is set";
"-slicing-help";
"-scg-verbose is set";
"-occurrence";
"-cast-from-constant is set";
"-security-slicing is set";
"-propagate-top";
"-ulevel is set";
"-scg-init-func is set";
"unit G[base] ptmap hashconsing_table 2";
"-metrics-debug is set";
"-journal-name";
"Pdg.State";
"internal_outs";
"-keep-switch is set";
"-wp-dot is set";
"((bool lattice_base, bool lattice_base) lattice_product, (bool lattice_base, bool lattice_base) lattice_product) lattice_product offsetmap_bitwise G[base] ptmap hashconsing_table 11";
"-typecheck is set";
"-load-script";
"builtin logic contructors table";
"-slicing-debug is set";
"-wp-builtin-why-file";
"-pp-annot is set";
"-no-obj is set";
"-memory-footprint";
"-from-debug is set";
"BuiltinFunctions";
"CurrentLoc";
"SCQueue";
"Binary_cache.MemoryFootprint";
"-save";
"-copy";
"-scf-debug is set";
"-journal-name is set";
"-slice-print is set";
"vglobals";
"-impact-slicing is set";
"reachable_stmts";
"unit G[varinfo] ptmap hashconsing_table 1";
"-slice-wr";
"-occurrence-verbose";
"external_derefs";
"-slice-value is set";
"Callers";
"Mem_Exec";
"-metrics-dump";
"-slicing-level";
"sid";
"-slicing-help is set";
"-journal-enable is set";
"base";
"Int_Intervals G[base] ptmap hashconsing_table 4";
"-dominators-debug is set";
"VarInfos";
"-safe-arrays";
"Slicing.Project";
"Untyped AST";
"-keep-comments";
"-metrics-dump is set";
"-klr is set";
"-constfold";
"-sparecode-annot";
"-mem-exec-all is set";
"-access-path is set";
"-inout-verbose is set";
"SemanticsServicestate";
"-dot-postdom";
"-occurrence-debug";
"external_outs";
"-context-valid-pointers";
"logic functions table";
"-slicing-verbose is set";
"-load";
"-metrics-help is set";
"-wp-dot";
"-timeout";
"-context-width is set";
"-security-lattice";
"eid";
"-plevel is set";
"-inout-debug";
"!Db.From.compute_all";
"Sparecode";
"Widen.Hints";
"-cg";
"-main";
"logic contructors table";
"-no-type is set";
"-cpp-command is set";
"LoopStmts";
"-slice-assert";
"-rm-unused-globals";
"-check";
"-wp-proof is set";
"Location_Bytes offsetmap G[base] ptmap hashconsing_table 7";
"-orig-name is set";
"-pdg-help is set";
"-scf-verbose";
"-rm-unused-globals is set";
"-slicing-keep-annotations is set";
"-impact-print";
"-scg-init-func";
"-scg";
"-fct-pdg is set";
"-mem-exec is set";
"-load is set";
"natural_loops";
"-scf-verbose is set";
"Components.Annotations";
"-absolute-valid-range";
"-context-depth is set";
"-cg-help";
"-dot-pdg";
"-pdg-debug is set";
"-slice-print";
"-impact-help";
"MinValidAbsoluteAddress";
"-slice-callers";
"Occurrence.compute";
"-context-width";
"-from-help";
"-from-debug";
"-slice-return is set";
"-typecheck";
"-impact-print is set";
"-deref is set";
"is_called";
"-quiet";
"-cg-init-func is set";
"-users-debug";
"Cluster_info offsetmap G[base] ptmap hashconsing_table 8";
"external_inouts";
"-klr";
"-scg-debug";
"-wp-verbose";
"-add-path";
"-plevel";
"SGState";
"-continue-annot-error is set";
"-save is set";
"-occurrence is set";
"-input";
"-pdg-verbose is set";
"-help";
"-wp-bot";
"-sparecode-debug";
"-load-script is set";
"-fct-pdg";
"-codpds is set";
"-wp-debug is set";
"-security-propagate-assertions";
"-pp-annot";
"internal derefs";
"-machdep";
"-users";
"-propagate-top is set";
"-slice-undef-functions";
"-print-libpath is set";
"-scf-debug";
"-deps";
"-metrics";
"-scg is set";
"-occurrence-help";
"V_Or_Uninitialized offsetmaphashconsing_table";
"-wp-mm";
"-users-verbose is set";
"-timeout is set";
"-ocode";
"-print is set";
"-wlevel is set";
"-semantic-const-folding is set";
"-unspecified-access is set";
"-version";
"-obfuscate is set";
"-metrics-verbose is set";
"-from-verbose";
"-impact-debug";
"KF";
"-cpp-extra-args is set";
"dominator";
"internal_inputs";
"-inout";
"MaxValidAbsoluteAddress";
"Occurrences.LastResult";
"-float-digits is set";
"Sparecode.Globs.Result";
"syntactic callgraph";
"-mem-exec";
"-out is set";
"-dot-postdom is set";
"-check is set";
"Eval.Got_Imprecise_Value";
"-value-verbose is set";
"with_formals_inputs";
"-print-path is set";
"-out";
"-wp-fct";
"Never_Terminates";
"-occurrence-help is set";
"-context-depth";
"-wp-behav is set";
"GlobalAnnotations";
"-wlevel";
"-calldeps is set";
"-pdg-verbose";
"-metrics-help";
"-slice-threat";
"-scope-verbose";
"-annot is set";
"Non linear assignments";
"-scg-verbose";
"-wp-builtin-why-file is set";
"-keep-comments is set";
"-simplify-cfg";
"-slice-loop-inv";
"-absolute-valid-range is set";
"-wp-verbose is set";
"-wp-fct is set";
"-access-path";
"-warn-unspecified-order";
"-users is set";
"-inout-help";
"-scope-debug";
"-out-external is set";
"-inout-verbose";
"-pdg";
"-sparecode-analysis is set";
"-slevel";
"-print-plugin-path";
"-cg-verbose is set";
"theMachine";
"-load-module";
"-users-help";
"-security-propagate-assertions is set";
"-metrics is set";
"-impact-verbose";
"-slice-rd is set";
"-scg-help is set";
"-sparecode-annot is set";
"-slice-callers is set";
"builtin logic types table";
"-security-debug is set";
"-wp-mm is set";
"-print-libpath";
"-security-verbose";
"Int_Intervals map_lattice offsetmap_bitwise G[base] ptmap hashconsing_table 5";
"-cg-debug is set";
"-scg-debug is set";
"-warn-unspecified-order is set";
"-impact-debug is set";
"-wp-debug";
"-scope-verbose is set";
"-wp-behav";
"-value-help";
"-time";
"-print-plugin-path is set";
"-slice-threat is set";
"-dot-pdg is set";
"-mem-exec-all";
"-lib-entry is set";
"-sparecode-verbose";
"Occurrences.State";
"-safe-arrays is set";
"-codpds";
"-dominators-help";
"-scope-help";
"-slice-pragma is set";
"-calldeps";
"-from-verbose is set";
"Constant_Propagation";
"-cg-debug";
"functionwise_from";
"compinfokey";
"-impact-pragma";
"" -> " is set";
"" -> "File.t";
"Components.compute" -> "Components";
"Components.compute" -> "Components.Nodes";
"-scg-help" -> "-scg-help is set";
"-security-analysis" -> "-security-analysis is set";
"-continue-annot-error" -> "-continue-annot-error is set";
"-orig-name" -> "-orig-name is set";
"-cg-init-func" -> "-cg-init-func is set";
"-journal-enable" -> "-journal-enable is set";
"-slicing-verbose" -> "-slicing-verbose is set";
"-unicode" -> "-unicode is set";
"-slicing-keep-annotations" -> "-slicing-keep-annotations is set";
"-sparecode-analysis" -> "-sparecode-analysis is set";
"-no-type" -> "-no-type is set";
"-obfuscate" -> "-obfuscate is set";
"FileIndex" -> "FileIndex.compute";
"-security-debug" -> "-security-debug is set";
"-slice-pragma" -> "-slice-pragma is set";
"-metrics-debug" -> "-metrics-debug is set";
"-dump-dependencies" -> "-dump-dependencies is set";
"-value-verbose" -> "-value-verbose is set";
"-cast-from-constant" -> "-cast-from-constant is set";
"-cpp-extra-args" -> "-cpp-extra-args is set";
"-cpp-extra-args" -> "File.t";
"-lib-entry" -> "-lib-entry is set";
"-lib-entry" -> "contextfree_only_globals";
"-lib-entry" -> "value_table";
"-unspecified-access" -> "-unspecified-access is set";
"-security-annotation" -> "-security-annotation is set";
"-users-verbose" -> "-users-verbose is set";
"builtin logic functions table" -> "logic functions table";
"-slice-return" -> "-slice-return is set";
"-sparecode-help" -> "-sparecode-help is set";
"-no-obj" -> "-no-obj is set";
"-float-digits" -> "-float-digits is set";
"-annot" -> "-annot is set";
"-annot" -> "AST";
"-wp-cfg" -> "-wp-cfg is set";
"-wp-help" -> "-wp-help is set";
"-slice-calls" -> "-slice-calls is set";
"-print" -> "-print is set";
"-slice-rd" -> "-slice-rd is set";
"UseRelations" -> "value_table";
"-slice-loop-var" -> "-slice-loop-var is set";
"-semantic-const-fold" -> "-semantic-const-fold is set";
"AST" -> "((bool lattice_base, bool lattice_base) lattice_product, (bool lattice_base, bool lattice_base) lattice_product) lattice_product offsetmap_bitwise G[base] ptmap hashconsing_table 11";
"AST" -> "(bool lattice_base, bool lattice_base) lattice_product offsetmap_bitwise G[base] ptmap hashconsing_table 10";
"AST" -> "(bool lattice_base, bool lattice_base) lattice_product offsetmap_bitwise G[base] ptmap hashconsing_table 12";
"AST" -> "Annotations";
"AST" -> "Cluster_info offsetmap G[base] ptmap hashconsing_table 8";
"AST" -> "Cluster_info offsetmaphashconsing_table";
"AST" -> "Components.Annotations";
"AST" -> "FileIndex";
"AST" -> "FormalsDecl";
"AST" -> "Functions";
"AST" -> "GlobalAnnotations";
"AST" -> "Globals.Vars";
"AST" -> "Int_Intervals G[base] ptmap hashconsing_table 4";
"AST" -> "Int_Intervals map_lattice offsetmap_bitwise G[base] ptmap hashconsing_table 5";
"AST" -> "KF";
"AST" -> "Location_Bytes offsetmap G[base] ptmap hashconsing_table 7";
"AST" -> "Location_Bytes offsetmaphashconsing_table";
"AST" -> "LoopStmts";
"AST" -> "Non linear assignments";
"AST" -> "Occurrences.LastResult";
"AST" -> "V_Or_Uninitialized offsetmap G[base] ptmap hashconsing_table 6";
"AST" -> "V_Or_Uninitialized offsetmaphashconsing_table";
"AST" -> "VarInfos";
"AST" -> "Widen.Hints";
"AST" -> "big_int lattice_mod G[base] ptmap hashconsing_table 3";
"AST" -> "contextfree_only_globals";
"AST" -> "dominator";
"AST" -> "int lattice_set offsetmap_bitwise G[base] ptmap hashconsing_table 13";
"AST" -> "logic contructors table";
"AST" -> "logic functions table";
"AST" -> "logic types table";
"AST" -> "message_counter";
"AST" -> "message_table";
"AST" -> "metrics";
"AST" -> "natural_loops";
"AST" -> "pdg_node lattice_set offsetmap_bitwise G[base] ptmap hashconsing_table 9";
"AST" -> "postdominator";
"AST" -> "reachable_stmts";
"AST" -> "syntactic callgraph";
"AST" -> "unit G[base] ptmap hashconsing_table 2";
"AST" -> "unit G[varinfo] ptmap hashconsing_table 1";
"AST" -> "value_table";
"-out-external" -> "-out-external is set";
"external_inputs" -> "Slicing.Project";
"internal_inouts" -> "external_inouts";
"-impact-slicing" -> "-impact-slicing is set";
"-print-path" -> "-print-path is set";
"-scf-help" -> "-scf-help is set";
"-metrics-verbose" -> "-metrics-verbose is set";
"-overflow" -> "-overflow is set";
"-overflow" -> "value_table";
"-verbose" -> "-verbose is set";
"-security-slicing" -> "-security-slicing is set";
"-value-debug" -> "-value-debug is set";
"-dominators-verbose" -> "-dominators-verbose is set";
"-dominators-debug" -> "-dominators-debug is set";
"-semantic-const-folding" -> "-semantic-const-folding is set";
"-cpp-command" -> "-cpp-command is set";
"-cpp-command" -> "File.t";
"-val" -> "-val is set";
"-pdg-help" -> "-pdg-help is set";
"-wp-proof" -> "-wp-proof is set";
"-slice-value" -> "-slice-value is set";
"-deref" -> "-deref is set";
"-cg-verbose" -> "-cg-verbose is set";
"-debug" -> "-debug is set";
"-ulevel" -> "-ulevel is set";
"-ulevel" -> "AST";
"-keep-switch" -> "-keep-switch is set";
"-keep-switch" -> "AST";
"-pdg-debug" -> "-pdg-debug is set";
"File.t" -> "AST";
"File.t" -> "Untyped AST";
"value_table" -> "!Db.Value.compute";
"value_table" -> "Callers";
"value_table" -> "Constant_Propagation";
"value_table" -> "Dynamic_Alloc_Table";
"value_table" -> "Eval.Got_Imprecise_Value";
"value_table" -> "Leaf_Table";
"value_table" -> "Mem_Exec";
"value_table" -> "Never_Terminates";
"value_table" -> "Occurrences.State";
"value_table" -> "SGState";
"value_table" -> "Users";
"value_table" -> "alarms";
"value_table" -> "called_functions";
"value_table" -> "callwise_from";
"value_table" -> "functionwise_from";
"value_table" -> "internal derefs";
"value_table" -> "internal_inouts";
"value_table" -> "internal_inputs";
"value_table" -> "internal_outs";
"value_table" -> "is_called";
"value_table" -> "vglobals";
"-security-help" -> "-security-help is set";
"-slicing-debug" -> "-slicing-debug is set";
"-input-with-formals" -> "-input-with-formals is set";
"-slicing-help" -> "-slicing-help is set";
"-occurrence" -> "-occurrence is set";
"-propagate-top" -> "-propagate-top is set";
"-propagate-top" -> "value_table";
"-journal-name" -> "-journal-name is set";
"Pdg.State" -> "Components.compute";
"Pdg.State" -> "Slicing.Project";
"internal_outs" -> "external_outs";
"-load-script" -> "-load-script is set";
"builtin logic contructors table" -> "logic contructors table";
"-wp-builtin-why-file" -> "-wp-builtin-why-file is set";
"-memory-footprint" -> "-memory-footprint is set";
"-memory-footprint" -> "Binary_cache.MemoryFootprint";
"-memory-footprint" -> "Buckx.MemoryFootprint";
"-save" -> "-save is set";
"-copy" -> "-copy is set";
"-slice-wr" -> "-slice-wr is set";
"-occurrence-verbose" -> "-occurrence-verbose is set";
"-metrics-dump" -> "-metrics-dump is set";
"-slicing-level" -> "-slicing-level is set";
"-safe-arrays" -> "-safe-arrays is set";
"-safe-arrays" -> "value_table";
"-keep-comments" -> "-keep-comments is set";
"-constfold" -> "-constfold is set";
"-constfold" -> "AST";
"-sparecode-annot" -> "-sparecode-annot is set";
"-dot-postdom" -> "-dot-postdom is set";
"-occurrence-debug" -> "-occurrence-debug is set";
"external_outs" -> "Slicing.Project";
"-context-valid-pointers" -> "-context-valid-pointers is set";
"-context-valid-pointers" -> "value_table";
"-load" -> "-load is set";
"-wp-dot" -> "-wp-dot is set";
"-timeout" -> "-timeout is set";
"-security-lattice" -> "-security-lattice is set";
"-inout-debug" -> "-inout-debug is set";
"-cg" -> "-cg is set";
"-main" -> "-main is set";
"-main" -> "SemanticsServicestate";
"-main" -> "contextfree_only_globals";
"-main" -> "value_table";
"-slice-assert" -> "-slice-assert is set";
"-rm-unused-globals" -> "-rm-unused-globals is set";
"-check" -> "-check is set";
"-scf-verbose" -> "-scf-verbose is set";
"-impact-print" -> "-impact-print is set";
"-scg-init-func" -> "-scg-init-func is set";
"-scg-init-func" -> "SemanticsServicestate";
"-scg" -> "-scg is set";
"Components.Annotations" -> "Components.Nodes";
"Components.Annotations" -> "Components.compute";
"-absolute-valid-range" -> "-absolute-valid-range is set";
"-absolute-valid-range" -> "value_table";
"-cg-help" -> "-cg-help is set";
"-dot-pdg" -> "-dot-pdg is set";
"-slice-print" -> "-slice-print is set";
"-impact-help" -> "-impact-help is set";
"-slice-callers" -> "-slice-callers is set";
"-context-width" -> "-context-width is set";
"-context-width" -> "value_table";
"-from-help" -> "-from-help is set";
"-from-debug" -> "-from-debug is set";
"-typecheck" -> "-typecheck is set";
"-quiet" -> "-quiet is set";
"-users-debug" -> "-users-debug is set";
"-klr" -> "-klr is set";
"-klr" -> "value_table";
"-scg-debug" -> "-scg-debug is set";
"-wp-verbose" -> "-wp-verbose is set";
"-add-path" -> "-add-path is set";
"-plevel" -> "-plevel is set";
"-plevel" -> "value_table";
"SGState" -> "SCQueue";
"SGState" -> "SemanticsServicestate";
"-input" -> "-input is set";
"-help" -> "-help is set";
"-wp-bot" -> "-wp-bot is set";
"-sparecode-debug" -> "-sparecode-debug is set";
"-fct-pdg" -> "-fct-pdg is set";
"-security-propagate-assertions" -> "-security-propagate-assertions is set";
"-pp-annot" -> "-pp-annot is set";
"-pp-annot" -> "AST";
"internal derefs" -> "external_derefs";
"-machdep" -> "-machdep is set";
"-machdep" -> "theMachine";
"-users" -> "-users is set";
"-users" -> "Users";
"-slice-undef-functions" -> "-slice-undef-functions is set";
"-scf-debug" -> "-scf-debug is set";
"-deps" -> "-deps is set";
"-metrics" -> "-metrics is set";
"-occurrence-help" -> "-occurrence-help is set";
"-wp-mm" -> "-wp-mm is set";
"-ocode" -> "-ocode is set";
"-version" -> "-version is set";
"-from-verbose" -> "-from-verbose is set";
"-impact-debug" -> "-impact-debug is set";
"internal_inputs" -> "external_inputs";
"internal_inputs" -> "with_formals_inputs";
"-inout" -> "-inout is set";
"-mem-exec" -> "-mem-exec is set";
"-mem-exec" -> "value_table";
"-out" -> "-out is set";
"-wp-fct" -> "-wp-fct is set";
"-context-depth" -> "-context-depth is set";
"-context-depth" -> "value_table";
"-wlevel" -> "-wlevel is set";
"-wlevel" -> "value_table";
"-pdg-verbose" -> "-pdg-verbose is set";
"-metrics-help" -> "-metrics-help is set";
"-slice-threat" -> "-slice-threat is set";
"-scope-verbose" -> "-scope-verbose is set";
"-scg-verbose" -> "-scg-verbose is set";
"-simplify-cfg" -> "-simplify-cfg is set";
"-simplify-cfg" -> "AST";
"-slice-loop-inv" -> "-slice-loop-inv is set";
"-access-path" -> "-access-path is set";
"-warn-unspecified-order" -> "-warn-unspecified-order is set";
"-inout-help" -> "-inout-help is set";
"-scope-debug" -> "-scope-debug is set";
"-inout-verbose" -> "-inout-verbose is set";
"-pdg" -> "-pdg is set";
"-slevel" -> "-slevel is set";
"-slevel" -> "value_table";
"-print-plugin-path" -> "-print-plugin-path is set";
"theMachine" -> "AST";
"theMachine" -> "BuiltinFunctions";
"theMachine" -> "Untyped AST";
"theMachine" -> "builtin logic contructors table";
"theMachine" -> "builtin logic functions table";
"theMachine" -> "builtin logic types table";
"-load-module" -> "-load-module is set";
"-users-help" -> "-users-help is set";
"-impact-verbose" -> "-impact-verbose is set";
"builtin logic types table" -> "logic types table";
"-print-libpath" -> "-print-libpath is set";
"-security-verbose" -> "-security-verbose is set";
"-wp-debug" -> "-wp-debug is set";
"-wp-behav" -> "-wp-behav is set";
"-value-help" -> "-value-help is set";
"-time" -> "-time is set";
"-mem-exec-all" -> "-mem-exec-all is set";
"-mem-exec-all" -> "value_table";
"-sparecode-verbose" -> "-sparecode-verbose is set";
"Occurrences.State" -> "Occurrence.compute";
"Occurrences.State" -> "Occurrences.LastResult";
"-codpds" -> "-codpds is set";
"-dominators-help" -> "-dominators-help is set";
"-scope-help" -> "-scope-help is set";
"-calldeps" -> "-calldeps is set";
"-cg-debug" -> "-cg-debug is set";
"functionwise_from" -> "!Db.From.compute_all";
"functionwise_from" -> "Pdg.State";
"-impact-pragma" -> "-impact-pragma is set";
} ocamlgraph-2.0.0/dgraph/examples/jsort.dot 0000755 0001750 0000144 00000014055 13735627615 017155 0 ustar rt users digraph prof {
size="6,4"; ratio = fill;
node [style=filled];
start -> main [color="0.002 0.999 0.999"];
start -> on_exit [color="0.649 0.701 0.701"];
main -> sort [color="0.348 0.839 0.839"];
main -> merge [color="0.515 0.762 0.762"];
main -> term [color="0.647 0.702 0.702"];
main -> signal [color="0.650 0.700 0.700"];
main -> sbrk [color="0.650 0.700 0.700"];
main -> unlink [color="0.650 0.700 0.700"];
main -> newfile [color="0.650 0.700 0.700"];
main -> fclose [color="0.650 0.700 0.700"];
main -> close [color="0.650 0.700 0.700"];
main -> brk [color="0.650 0.700 0.700"];
main -> setbuf [color="0.650 0.700 0.700"];
main -> copyproto [color="0.650 0.700 0.700"];
main -> initree [color="0.650 0.700 0.700"];
main -> safeoutfil [color="0.650 0.700 0.700"];
main -> getpid [color="0.650 0.700 0.700"];
main -> sprintf [color="0.650 0.700 0.700"];
main -> creat [color="0.650 0.700 0.700"];
main -> rem [color="0.650 0.700 0.700"];
main -> oldfile [color="0.650 0.700 0.700"];
sort -> msort [color="0.619 0.714 0.714"];
sort -> filbuf [color="0.650 0.700 0.700"];
sort -> newfile [color="0.650 0.700 0.700"];
sort -> fclose [color="0.650 0.700 0.700"];
sort -> setbuf [color="0.650 0.700 0.700"];
sort -> setfil [color="0.650 0.700 0.700"];
msort -> qsort [color="0.650 0.700 0.700"];
msort -> insert [color="0.650 0.700 0.700"];
msort -> wline [color="0.650 0.700 0.700"];
msort -> div [color="0.650 0.700 0.700"];
msort -> cmpsave [color="0.650 0.700 0.700"];
merge -> insert [color="0.650 0.700 0.700"];
merge -> rline [color="0.650 0.700 0.700"];
merge -> wline [color="0.650 0.700 0.700"];
merge -> unlink [color="0.650 0.700 0.700"];
merge -> fopen [color="0.650 0.700 0.700"];
merge -> fclose [color="0.650 0.700 0.700"];
merge -> setfil [color="0.650 0.700 0.700"];
merge -> mul [color="0.650 0.700 0.700"];
merge -> setbuf [color="0.650 0.700 0.700"];
merge -> cmpsave [color="0.650 0.700 0.700"];
insert -> cmpa [color="0.650 0.700 0.700"];
wline -> flsbuf [color="0.649 0.700 0.700"];
qsort -> cmpa [color="0.650 0.700 0.700"];
rline -> filbuf [color="0.649 0.700 0.700"];
xflsbuf -> write [color="0.650 0.700 0.700"];
flsbuf -> xflsbuf [color="0.649 0.700 0.700"];
filbuf -> read [color="0.650 0.700 0.700"];
term -> unlink [color="0.650 0.700 0.700"];
term -> signal [color="0.650 0.700 0.700"];
term -> setfil [color="0.650 0.700 0.700"];
term -> exit [color="0.650 0.700 0.700"];
endopen -> open [color="0.650 0.700 0.700"];
fopen -> endopen [color="0.639 0.705 0.705"];
fopen -> findiop [color="0.650 0.700 0.700"];
newfile -> fopen [color="0.634 0.707 0.707"];
newfile -> setfil [color="0.650 0.700 0.700"];
fclose -> fflush [color="0.642 0.704 0.704"];
fclose -> close [color="0.650 0.700 0.700"];
fflush -> xflsbuf [color="0.635 0.707 0.707"];
malloc -> morecore [color="0.325 0.850 0.850"];
malloc -> demote [color="0.650 0.700 0.700"];
morecore -> sbrk [color="0.650 0.700 0.700"];
morecore -> getfreehdr [color="0.650 0.700 0.700"];
morecore -> free [color="0.650 0.700 0.700"];
morecore -> getpagesize [color="0.650 0.700 0.700"];
morecore -> putfreehdr [color="0.650 0.700 0.700"];
morecore -> udiv [color="0.650 0.700 0.700"];
morecore -> umul [color="0.650 0.700 0.700"];
on_exit -> malloc [color="0.325 0.850 0.850"];
signal -> sigvec [color="0.650 0.700 0.700"];
moncontrol -> profil [color="0.650 0.700 0.700"];
getfreehdr -> sbrk [color="0.650 0.700 0.700"];
free -> insert [color="0.650 0.700 0.700"];
insert -> getfreehdr [color="0.650 0.700 0.700"];
setfil -> div [color="0.650 0.700 0.700"];
setfil -> rem [color="0.650 0.700 0.700"];
sigvec -> sigblock [color="0.650 0.700 0.700"];
sigvec -> sigsetmask [color="0.650 0.700 0.700"];
doprnt -> urem [color="0.650 0.700 0.700"];
doprnt -> udiv [color="0.650 0.700 0.700"];
doprnt -> strlen [color="0.650 0.700 0.700"];
doprnt -> localeconv [color="0.650 0.700 0.700"];
sprintf -> doprnt [color="0.650 0.700 0.700"];
cmpa [color="0.000 1.000 1.000"];
wline [color="0.201 0.753 1.000"];
insert [color="0.305 0.625 1.000"];
rline [color="0.355 0.563 1.000"];
sort [color="0.408 0.498 1.000"];
qsort [color="0.449 0.447 1.000"];
write [color="0.499 0.386 1.000"];
read [color="0.578 0.289 1.000"];
msort [color="0.590 0.273 1.000"];
merge [color="0.603 0.258 1.000"];
unlink [color="0.628 0.227 1.000"];
filbuf [color="0.641 0.212 1.000"];
open [color="0.641 0.212 1.000"];
sbrk [color="0.647 0.204 1.000"];
signal [color="0.647 0.204 1.000"];
moncontrol [color="0.647 0.204 1.000"];
xflsbuf [color="0.650 0.200 1.000"];
flsbuf [color="0.650 0.200 1.000"];
div [color="0.650 0.200 1.000"];
cmpsave [color="0.650 0.200 1.000"];
rem [color="0.650 0.200 1.000"];
setfil [color="0.650 0.200 1.000"];
close [color="0.650 0.200 1.000"];
fclose [color="0.650 0.200 1.000"];
fflush [color="0.650 0.200 1.000"];
setbuf [color="0.650 0.200 1.000"];
endopen [color="0.650 0.200 1.000"];
findiop [color="0.650 0.200 1.000"];
fopen [color="0.650 0.200 1.000"];
mul [color="0.650 0.200 1.000"];
newfile [color="0.650 0.200 1.000"];
sigblock [color="0.650 0.200 1.000"];
sigsetmask [color="0.650 0.200 1.000"];
sigvec [color="0.650 0.200 1.000"];
udiv [color="0.650 0.200 1.000"];
urem [color="0.650 0.200 1.000"];
brk [color="0.650 0.200 1.000"];
getfreehdr [color="0.650 0.200 1.000"];
strlen [color="0.650 0.200 1.000"];
umul [color="0.650 0.200 1.000"];
doprnt [color="0.650 0.200 1.000"];
copyproto [color="0.650 0.200 1.000"];
creat [color="0.650 0.200 1.000"];
demote [color="0.650 0.200 1.000"];
exit [color="0.650 0.200 1.000"];
free [color="0.650 0.200 1.000"];
getpagesize [color="0.650 0.200 1.000"];
getpid [color="0.650 0.200 1.000"];
initree [color="0.650 0.200 1.000"];
insert [color="0.650 0.200 1.000"];
localeconv [color="0.650 0.200 1.000"];
main [color="0.650 0.200 1.000"];
malloc [color="0.650 0.200 1.000"];
morecore [color="0.650 0.200 1.000"];
oldfile [color="0.650 0.200 1.000"];
on_exit [color="0.650 0.200 1.000"];
profil [color="0.650 0.200 1.000"];
putfreehdr [color="0.650 0.200 1.000"];
safeoutfil [color="0.650 0.200 1.000"];
sprintf [color="0.650 0.200 1.000"];
term [color="0.650 0.200 1.000"];
}
ocamlgraph-2.0.0/dgraph/examples/services.dot 0000755 0001750 0000144 00000025547 13735627615 017647 0 ustar rt users digraph G {
"unlzw (1)" [height=0.200000, width=0.200000, shape=box, color="#000080",
style=bold];
"unzip (9)" [height=1.800000, width=1.800000, shape=box, color="#008000",
style=bold];
"make_simple_name (1)" [height=0.200000, width=0.200000, shape=box,
color="#008080", style=bold];
"treat_file (21)" [height=4.200000, width=4.200000, shape=box,
color="#800000", style=bold];
"strlen (1)" [height=0.200000, width=0.200000, shape=box, color="#800080",
style=dotted];
"treat_stdin (1)" [height=0.200000, width=0.200000, shape=box,
color="#808000", style=bold];
"atoi (1)" [height=0.200000, width=0.200000, shape=box, color="#808080",
style=dotted];
"unlzh (12)" [height=2.400000, width=2.400000, shape=box, color="#000040",
style=bold];
"signal (1)" [height=0.200000, width=0.200000, shape=box, color="#0000C0",
style=dotted];
"strcmp (1)" [height=0.200000, width=0.200000, shape=box, color="#008040",
style=dotted];
"do_list (4)" [height=0.800000, width=0.800000, shape=box, color="#0080C0",
style=bold];
"version (1)" [height=0.200000, width=0.200000, shape=box, color="#800040",
style=bold];
"add_envopt (5)" [height=1.000000, width=1.000000, shape=box,
color="#8000C0", style=bold];
"strcpy (1)" [height=0.200000, width=0.200000, shape=box, color="#808040",
style=dotted];
"strncmp (1)" [height=0.200000, width=0.200000, shape=box, color="#8080C0",
style=dotted];
"fprintf (1)" [height=0.200000, width=0.200000, shape=box, color="#004000",
style=dotted];
"main (1)" [height=0.200000, width=0.200000, shape=box, color="#004080",
style=bold];
"strncpy (1)" [height=0.200000, width=0.200000, shape=box, color="#00C000",
style=dotted];
"basename (1)" [height=0.200000, width=0.200000, shape=box,
color="#00C080", style=bold];
"lzw (1)" [height=0.200000, width=0.200000, shape=box, color="#804000",
style=bold];
"zip (26)" [height=5.200000, width=5.200000, shape=box, color="#804080",
style=bold];
"getopt_long (1)" [height=0.200000, width=0.200000, shape=box,
color="#80C000", style=dotted];
"usage (1)" [height=0.200000, width=0.200000, shape=box, color="#80C080",
style=bold];
"warn (1)" [height=0.200000, width=0.200000, shape=box, color="#004040",
style=bold];
"copy (1)" [height=0.200000, width=0.200000, shape=box, color="#0040C0",
style=bold];
"help (1)" [height=0.200000, width=0.200000, shape=box, color="#00C040",
style=bold];
"unpack (3)" [height=0.600000, width=0.600000, shape=box, color="#00C0C0",
style=bold];
"license (1)" [height=0.200000, width=0.200000, shape=box, color="#804040",
style=bold];
"file_read (1)" [height=0.200000, width=0.200000, shape=box,
color="#8040C0", style=bold];
"do_exit (2)" [height=0.400000, width=0.400000, shape=box, color="#80C040",
style=bold];
"read (1)" [height=0.200000, width=0.200000, shape=box, color="#80C0C0",
style=dotted];
"write_buf (2)" [height=0.400000, width=0.400000, shape=box,
color="#400000", style=bold];
"read_error (1)" [height=0.200000, width=0.200000, shape=box,
color="#400080", style=bold];
"get_method (3)" [height=0.600000, width=0.600000, shape=box,
color="#408000", style=bold];
"fill_inbuf (1)" [height=0.200000, width=0.200000, shape=box,
color="#408080", style=bold];
"error (1)" [height=0.200000, width=0.200000, shape=box, color="#C00000",
style=bold];
"memset (1)" [height=0.200000, width=0.200000, shape=box, color="#C00080",
style=dotted];
"memcpy (1)" [height=0.200000, width=0.200000, shape=box, color="#C08000",
style=dotted];
"updcrc (1)" [height=0.200000, width=0.200000, shape=box, color="#C08080",
style=bold];
"flush_window (1)" [height=0.200000, width=0.200000, shape=box,
color="#400040", style=bold];
"strrchr (1)" [height=0.200000, width=0.200000, shape=box, color="#4000C0",
style=dotted];
"clear_bufs (1)" [height=0.200000, width=0.200000, shape=box,
color="#408040", style=bold];
"write_error (1)" [height=0.200000, width=0.200000, shape=box,
color="#4080C0", style=bold];
"perror (1)" [height=0.200000, width=0.200000, shape=box, color="#C00040",
style=dotted];
"display_ratio (2)" [height=0.400000, width=0.400000, shape=box,
color="#C000C0", style=bold];
" (1)" [height=0.200000, width=0.200000, shape=box,
color="#C08040", style=bold];
"fileno (1)" [height=0.200000, width=0.200000, shape=box, color="#C080C0",
style=dotted];
"abort_gzip (1)" [height=0.200000, width=0.200000, shape=box,
color="#404000", style=bold];
"close (1)" [height=0.200000, width=0.200000, shape=box, color="#404080",
style=dotted];
"unlink (1)" [height=0.200000, width=0.200000, shape=box, color="#40C000",
style=dotted];
"isatty (1)" [height=0.200000, width=0.200000, shape=box, color="#40C080",
style=dotted];
"fstat (1)" [height=0.200000, width=0.200000, shape=box, color="#C04000",
style=dotted];
"strcspn (1)" [height=0.200000, width=0.200000, shape=box, color="#C04080",
style=dotted];
"free (1)" [height=0.200000, width=0.200000, shape=box, color="#C0C000",
style=dotted];
"strlwr (1)" [height=0.200000, width=0.200000, shape=box, color="#C0C080",
style=bold];
"__errno_location (1)" [height=0.200000, width=0.200000, shape=box,
color="#404040", style=dotted];
"malloc (1)" [height=0.200000, width=0.200000, shape=box, color="#4040C0",
style=dotted];
"__ctype_b_loc (1)" [height=0.200000, width=0.200000, shape=box,
color="#40C040", style=dotted];
"unlzw (1)" -> "fprintf (1)";
"unlzw (1)" -> "read (1)";
"unlzw (1)" -> "write_buf (2)";
"unlzw (1)" -> "read_error (1)";
"unlzw (1)" -> "fill_inbuf (1)";
"unlzw (1)" -> "error (1)";
"unlzw (1)" -> "memset (1)";
"unlzw (1)" -> "memcpy (1)";
"unzip (9)" -> "fprintf (1)";
"unzip (9)" -> "fill_inbuf (1)";
"unzip (9)" -> "error (1)";
"unzip (9)" -> "memset (1)";
"unzip (9)" -> "memcpy (1)";
"unzip (9)" -> "updcrc (1)";
"unzip (9)" -> "flush_window (1)";
"unzip (9)" -> "free (1)";
"unzip (9)" -> "malloc (1)";
"make_simple_name (1)" -> "strrchr (1)";
"treat_file (21)" -> "strlen (1)";
"treat_file (21)" -> "treat_stdin (1)";
"treat_file (21)" -> "strcmp (1)";
"treat_file (21)" -> "do_list (4)";
"treat_file (21)" -> "strcpy (1)";
"treat_file (21)" -> "fprintf (1)";
"treat_file (21)" -> "get_method (3)";
"treat_file (21)" -> "error (1)";
"treat_file (21)" -> "strrchr (1)";
"treat_file (21)" -> "clear_bufs (1)";
"treat_file (21)" -> "write_error (1)";
"treat_file (21)" -> "perror (1)";
"treat_file (21)" -> "display_ratio (2)";
"treat_file (21)" -> " (1)";
"treat_file (21)" -> "fileno (1)";
"treat_file (21)" -> "close (1)";
"treat_file (21)" -> "unlink (1)";
"treat_file (21)" -> "isatty (1)";
"treat_file (21)" -> "fstat (1)";
"treat_file (21)" -> "strcspn (1)";
"treat_file (21)" -> "strlwr (1)";
"treat_file (21)" -> "__errno_location (1)";
"treat_file (21)" -> "__ctype_b_loc (1)";
"treat_stdin (1)" -> "do_list (4)";
"treat_stdin (1)" -> "strcpy (1)";
"treat_stdin (1)" -> "fprintf (1)";
"treat_stdin (1)" -> "do_exit (2)";
"treat_stdin (1)" -> "get_method (3)";
"treat_stdin (1)" -> "error (1)";
"treat_stdin (1)" -> "clear_bufs (1)";
"treat_stdin (1)" -> "display_ratio (2)";
"treat_stdin (1)" -> " (1)";
"treat_stdin (1)" -> "fileno (1)";
"treat_stdin (1)" -> "isatty (1)";
"treat_stdin (1)" -> "fstat (1)";
"unlzh (12)" -> "write_buf (2)";
"unlzh (12)" -> "fill_inbuf (1)";
"unlzh (12)" -> "error (1)";
"do_list (4)" -> "read (1)";
"do_list (4)" -> "read_error (1)";
"do_list (4)" -> "display_ratio (2)";
"version (1)" -> "fprintf (1)";
"add_envopt (5)" -> "strlen (1)";
"add_envopt (5)" -> "strcpy (1)";
"add_envopt (5)" -> "error (1)";
"add_envopt (5)" -> "strcspn (1)";
"add_envopt (5)" -> "free (1)";
"add_envopt (5)" -> "malloc (1)";
"main (1)" -> "treat_file (21)";
"main (1)" -> "strlen (1)";
"main (1)" -> "treat_stdin (1)";
"main (1)" -> "atoi (1)";
"main (1)" -> "signal (1)";
"main (1)" -> "strcmp (1)";
"main (1)" -> "do_list (4)";
"main (1)" -> "version (1)";
"main (1)" -> "add_envopt (5)";
"main (1)" -> "strcpy (1)";
"main (1)" -> "strncmp (1)";
"main (1)" -> "fprintf (1)";
"main (1)" -> "strncpy (1)";
"main (1)" -> "basename (1)";
"main (1)" -> "getopt_long (1)";
"main (1)" -> "usage (1)";
"main (1)" -> "help (1)";
"main (1)" -> "license (1)";
"main (1)" -> "do_exit (2)";
"basename (1)" -> "strrchr (1)";
"basename (1)" -> "strlwr (1)";
"lzw (1)" -> "fprintf (1)";
"zip (26)" -> "basename (1)";
"zip (26)" -> "write_buf (2)";
"zip (26)" -> "error (1)";
"zip (26)" -> "memset (1)";
"zip (26)" -> "memcpy (1)";
"zip (26)" -> "updcrc (1)";
"zip (26)" -> " (1)";
"usage (1)" -> "fprintf (1)";
"warn (1)" -> "fprintf (1)";
"copy (1)" -> "read (1)";
"copy (1)" -> "write_buf (2)";
"copy (1)" -> "read_error (1)";
"copy (1)" -> "__errno_location (1)";
"help (1)" -> "fprintf (1)";
"help (1)" -> "usage (1)";
"unpack (3)" -> "fill_inbuf (1)";
"unpack (3)" -> "error (1)";
"unpack (3)" -> "flush_window (1)";
"license (1)" -> "fprintf (1)";
"file_read (1)" -> "read (1)";
"file_read (1)" -> "updcrc (1)";
"do_exit (2)" -> "free (1)";
"write_buf (2)" -> "write_error (1)";
"read_error (1)" -> "fprintf (1)";
"read_error (1)" -> "perror (1)";
"read_error (1)" -> "abort_gzip (1)";
"read_error (1)" -> "__errno_location (1)";
"get_method (3)" -> "fprintf (1)";
"get_method (3)" -> "basename (1)";
"get_method (3)" -> "fill_inbuf (1)";
"get_method (3)" -> "error (1)";
"fill_inbuf (1)" -> "read (1)";
"fill_inbuf (1)" -> "read_error (1)";
"fill_inbuf (1)" -> "__errno_location (1)";
"error (1)" -> "fprintf (1)";
"error (1)" -> "abort_gzip (1)";
"flush_window (1)" -> "write_buf (2)";
"flush_window (1)" -> "updcrc (1)";
"write_error (1)" -> "fprintf (1)";
"write_error (1)" -> "perror (1)";
"write_error (1)" -> "abort_gzip (1)";
"display_ratio (2)" -> "fprintf (1)";
"abort_gzip (1)" -> "do_exit (2)";
"abort_gzip (1)" -> "close (1)";
"abort_gzip (1)" -> "unlink (1)";
"strlwr (1)" -> "__ctype_b_loc (1)";
} ocamlgraph-2.0.0/dgraph/examples/fancy.dot 0000644 0001750 0000144 00000000766 13735627615 017115 0 ustar rt users digraph G {
size ="4,4";
main [shape=box]; /* this is a comment */
main -> parse [weight=8];
parse -> execute;
main -> init [style=dotted, comment="youhou"];
main -> cleanup;
execute -> { make_string; printf}
init -> make_string;
edge [color=red]; // so is this
main -> printf [style=bold,label="100 times"];
make_string [label="make a\nstring"];
node [shape=box,style=filled,color=".7 .3 1.0"];
execute -> compare;
}
ocamlgraph-2.0.0/dgraph/examples/viewfile.gv 0000755 0001750 0000144 00000003347 13735627615 017456 0 ustar rt users digraph Viewfile {
node [ style = filled ];
atoi [color=green];
chkmalloc [color=green];
close [color=green];
error [color=blue];
exit [color=blue];
fclose [color=green];
fgets [color=red];
fopen [color=green];
fprintf [color=blue];
free [color=blue];
free_list [color=blue];
fstat [color=green];
getopt [color=green];
init_list [color=green];
insert_list [color=green];
main [color=green];
makeargs [color=blue];
makepairs [color=green];
malloc [color=green];
open [color=green];
printf [color=red];
read [color=green];
rewind [color=green];
viewline [color=green];
viewlines [color=green];
walk_list [color=green];
write [color=green];
fclose -> close [color=green];
fgets -> fstat [color=green];
fgets -> read [color=green];
fopen -> open [color=green];
printf -> write [color=green];
main -> fgets [color=blue];
main -> getopt [color=green];
main -> makeargs [color=blue];
main -> makepairs [color=green];
main -> chkmalloc [color=green];
main -> error [color=blue];
main -> viewlines [color=green];
makeargs -> chkmalloc [color=blue];
makepairs -> atoi [color=green];
makepairs -> init_list [color=green];
makepairs -> insert_list [color=green];
makepairs -> chkmalloc [color=green];
free_list -> free [color=blue];
init_list -> chkmalloc [color=green];
insert_list -> chkmalloc [color=green];
walk_list -> error [color=blue];
walk_list -> viewline [color=green];
chkmalloc -> malloc [color=green];
chkmalloc -> error [color=blue];
error -> exit [color=blue];
error -> fprintf [color=blue];
error -> error [color=blue];
viewline -> fgets [color=red];
viewline -> printf [color=red];
viewline -> rewind [color=green];
viewlines -> fclose [color=green];
viewlines -> fopen [color=green];
viewlines -> walk_list [color=green];
viewlines -> viewline [color=blue];
}
ocamlgraph-2.0.0/dgraph/examples/polypoly.gv 0000755 0001750 0000144 00000012043 13735627615 017524 0 ustar rt users digraph polypoly {
size="7,9.5";
page="8.5,11";
ratio=fill;
node [shape=polygon];
{ rank=same;
node [sides=0];
node [peripheries=1];
0000 [label="M"];
0001 [label="MMMMMMMMMM"];
0002 [label="M\nM\nM\nM\nM\nM"];
0003 [label="MMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM"];
node [peripheries=2];
0010 [label="M"];
0011 [label="MMMMMMMMMM"];
0012 [label="M\nM\nM\nM\nM\nM"];
0013 [label="MMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM"];
node [distortion=-.3];
0110 [label="M"];
0111 [label="MMMMMMMMMM"];
0112 [label="M\nM\nM\nM\nM\nM"];
0113 [label="MMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM"];
}
{ rank=same;
node [sides=3];
node [peripheries=1];
node [orientation=0];
3000 [label="M"];
3001 [label="MMMMMMMMMM"];
3002 [label="M\nM\nM\nM\nM\nM"];
3003 [label="MMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM"];
node [peripheries=2];
node [orientation=60];
3110 [label="M"];
3111 [label="MMMMMMMMMM"];
3112 [label="M\nM\nM\nM\nM\nM"];
3113 [label="MMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM"];
}
3000->0000;
{ rank=same;
node [sides=4];
node [peripheries=1];
node [orientation=0];
4000 [label="M"];
4001 [label="MMMMMMMMMM"];
4002 [label="M\nM\nM\nM\nM\nM"];
4003 [label="MMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM"];
node [peripheries=2];
node [orientation=45];
4110 [label="M"];
4111 [label="MMMMMMMMMM"];
4112 [label="M\nM\nM\nM\nM\nM"];
4113 [label="MMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM"];
}
4000->3000;
{ rank=same;
node [sides=5];
node [peripheries=1];
node [orientation=0];
5000 [label="M"];
5001 [label="MMMMMMMMMM"];
5002 [label="M\nM\nM\nM\nM\nM"];
5003 [label="MMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM"];
node [peripheries=2];
node [orientation=36];
5110 [label="M"];
5111 [label="MMMMMMMMMM"];
5112 [label="M\nM\nM\nM\nM\nM"];
5113 [label="MMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM"];
}
5000->4000;
{ rank=same;
node [sides=6];
node [peripheries=1];
node [orientation=0];
6000 [label="M"];
6001 [label="MMMMMMMMMM"];
6002 [label="M\nM\nM\nM\nM\nM"];
6003 [label="MMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM"];
node [peripheries=2];
node [orientation=30];
6110 [label="M"];
6111 [label="MMMMMMMMMM"];
6112 [label="M\nM\nM\nM\nM\nM"];
6113 [label="MMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM"];
}
6000->5000;
{ rank=same;
node [sides=7];
node [peripheries=1];
node [orientation=0];
7000 [label="M"];
7001 [label="MMMMMMMMMM"];
7002 [label="M\nM\nM\nM\nM\nM"];
7003 [label="MMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM"];
node [peripheries=2];
node [orientation=25.7];
7110 [label="M"];
7111 [label="MMMMMMMMMM"];
7112 [label="M\nM\nM\nM\nM\nM"];
7113 [label="MMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM"];
}
7000->6000;
{ rank=same;
node [sides=8];
node [peripheries=1];
node [orientation=0];
8000 [label="M"];
8001 [label="MMMMMMMMMM"];
8002 [label="M\nM\nM\nM\nM\nM"];
8003 [label="MMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM"];
node [peripheries=2];
node [orientation=22.5];
8110 [label="M"];
8111 [label="MMMMMMMMMM"];
8112 [label="M\nM\nM\nM\nM\nM"];
8113 [label="MMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM\nMMMMMMMMMM"];
}
8000->7000;
{ rank=same;
node [sides=4];
node [peripheries=1];
node [regular=1];
node [distortion=.5];
node [orientation=0];
9000 [label="M"];
node [orientation=45.];
9001 [label="M"];
node [orientation=90.];
9002 [label="M"];
node [orientation=135.];
9003 [label="M"];
node [orientation=180.];
9004 [label="M"];
node [orientation=225.];
9005 [label="M"];
node [orientation=270.];
9006 [label="M"];
node [orientation=315.];
9007 [label="M"];
node [peripheries=2];
node [orientation=0];
9010 [label="M"];
node [orientation=45.];
9011 [label="M"];
node [orientation=90.];
9012 [label="M"];
node [orientation=135.];
9013 [label="M"];
node [orientation=180.];
9014 [label="M"];
node [orientation=225.];
9015 [label="M"];
node [orientation=270.];
9016 [label="M"];
node [orientation=315.];
9017 [label="M"];
}
9000->8000;
}
ocamlgraph-2.0.0/dgraph/examples/dfa.gv 0000755 0001750 0000144 00000001677 13735627615 016402 0 ustar rt users digraph g {
"start" [ label = "MWGC-" ];
"n1" [ label = "WC-MG" ];
"n2" [ label = "MWC-G" ];
"n3" [ label = "C-MWG" ];
"n4" [ label = "W-MGC" ];
"n5" [ label = "MGC-W" ];
"n6" [ label = "MWG-C" ];
"n7" [ label = "G-MWC" ];
"n8" [ label = "MG-WC" ];
"n9" [ label = "-MWGC" ];
"start" -> "n1" [ label = "g" ];
"n1" -> "start" [ label = "g" ];
subgraph l { rank = same; "n3" "n4" }
subgraph r { rank = same; "n5" "n6" }
"n1" -> "n2" [ label = "m" ];
"n2" -> "n1" [ label = "m" ];
"n2" -> "n3" [ label = "w" ];
"n3" -> "n2" [ label = "w" ];
"n2" -> "n4" [ label = "c" ];
"n4" -> "n2" [ label = "c" ];
"n3" -> "n5" [ label = "g" ];
"n5" -> "n3" [ label = "g" ];
"n4" -> "n6" [ label = "g" ];
"n6" -> "n4" [ label = "g" ];
"n5" -> "n7" [ label = "c" ];
"n7" -> "n5" [ label = "c" ];
"n6" -> "n7" [ label = "w" ];
"n7" -> "n6" [ label = "w" ];
"n7" -> "n8" [ label = "m" ];
"n8" -> "n7" [ label = "m" ];
"n8" -> "n9" [ label = "g" ];
"n9" -> "n8" [ label = "g" ];
}
ocamlgraph-2.0.0/dgraph/examples/crazy2.dot 0000755 0001750 0000144 00000000661 13735627615 017224 0 ustar rt users digraph "unix" {
graph [ fontname = "Helvetica-Oblique",
fontsize = 36,
label = "\n\n\n\nObject Oriented Graphs\nStephen North, 3/19/93",
size = "6,6" ];
node [ shape = polygon,
sides = 4,
distortion = "0.0",
orientation = "0.0",
skew = "0.0",
color = blue,
style = filled,
fontname = "Helvetica-Outline" ];
"CB Unix 2" [sides=10, distortion="0.851818", orientation=32, skew="-0.020120", color=greenyellow];
}
ocamlgraph-2.0.0/dgraph/examples/gzip.dot 0000755 0001750 0000144 00000114664 13735627615 016774 0 ustar rt users digraph G {
"UV atoi (97)" [shape=diamond, label="atoi", color="#4000A0", style=dotted];
"UV zip (0)" [shape=diamond, label="zip", color="#000000", style=bold];
"UV do_exit (98)" [shape=diamond, label="do_exit", color="#408020",
style=bold];
"UV flush_outbuf (1)" [label="flush_outbuf", color="#000000", style=bold];
"UV updcrc (2)" [shape=diamond, label="updcrc", color="#008000", style=bold];
"UV treat_file (99)" [shape=diamond, label="treat_file", color="#4080A0",
style=bold];
"UV treat_stdin (100)" [shape=diamond, label="treat_stdin",
color="#C00020", style=bold];
"UV bi_init (3)" [label="bi_init", color="#000000", style=bold];
"UV do_list (101)" [shape=diamond, label="do_list", color="#C000A0",
style=bold];
"UV ct_init (4)" [label="ct_init", color="#000000", style=bold];
"UV fileno (102)" [shape=diamond, label="fileno", color="#C08020",
style=dotted];
"UV lm_init (5)" [label="lm_init", color="#000000", style=bold];
"UV basename (6)" [shape=diamond, label="basename", color="#808000",
style=bold];
"UV isatty (103)" [shape=diamond, label="isatty", color="#C080A0",
style=dotted];
"UV fstat (104)" [shape=diamond, label="fstat", color="#400060",
style=dotted];
"UV deflate (7)" [label="deflate", color="#000000", style=bold];
"UV get_method (105)" [shape=diamond, label="get_method", color="#4000E0",
style=bold];
"UV file_read (8)" [shape=diamond, label="file_read", color="#000040",
style=bold];
"UV read (9)" [shape=diamond, label="read", color="#0000C0", style=dotted];
"UV get_istat (106)" [label="get_istat", color="#4080A0", style=bold];
"UV make_ofname (107)" [label="make_ofname", color="#4080A0", style=bold];
"UV copy (10)" [shape=diamond, label="copy", color="#008040", style=bold];
"UV __errno_location (11)" [shape=diamond, label="__errno_location",
color="#0080C0", style=dotted];
"UV open (108)" [label="open", color="#4080A0", style=dotted];
"UV close (109)" [shape=diamond, label="close", color="#C000E0",
style=dotted];
"UV write_buf (12)" [shape=diamond, label="write_buf", color="#800040",
style=bold];
"UV read_error (13)" [shape=diamond, label="read_error", color="#8000C0",
style=bold];
"UV create_outfile (110)" [label="create_outfile", color="#4080A0",
style=bold];
"UV unlink (111)" [shape=diamond, label="unlink", color="#C080E0",
style=dotted];
"UV clear_bufs (14)" [shape=diamond, label="clear_bufs", color="#808040",
style=bold];
"UV fill_inbuf (15)" [shape=diamond, label="fill_inbuf", color="#8080C0",
style=bold];
"UV copy_stat (112)" [label="copy_stat", color="#4080A0", style=bold];
"UV flush_window (16)" [shape=diamond, label="flush_window",
color="#004000", style=bold];
"UV check_ofname (113)" [label="check_ofname", color="#4080A0", style=bold];
"UV write (17)" [label="write", color="#800040", style=dotted];
"UV name_too_long (114)" [label="name_too_long", color="#4080A0",
style=bold];
"UV write_error (18)" [shape=diamond, label="write_error", color="#00C000",
style=bold];
"UV shorten_name (115)" [label="shorten_name", color="#4080A0", style=bold];
"UV strlwr (19)" [shape=diamond, label="strlwr", color="#00C080",
style=bold];
"UV do_stat (116)" [label="do_stat", color="#4080A0", style=bold];
"UV isupper (20)" [shape=diamond, label="isupper", color="#804000",
style=dotted];
"UV lstat (117)" [label="lstat", color="#4080A0", style=dotted];
"UV strrchr (21)" [shape=diamond, label="strrchr", color="#804080",
style=dotted];
"UV stat (118)" [label="stat", color="#4080A0", style=dotted];
"UV get_suffix (119)" [label="get_suffix", color="#4080A0", style=bold];
"UV make_simple_name (22)" [shape=diamond, label="make_simple_name",
color="#80C000", style=bold];
"UV strcat (120)" [label="strcat", color="#4080A0", style=dotted];
"UV add_envopt (23)" [shape=diamond, label="add_envopt", color="#80C080",
style=bold];
"UV memcmp (121)" [label="memcmp", color="#4000E0", style=dotted];
"UV getenv (24)" [label="getenv", color="#80C080", style=dotted];
"UV strlen (25)" [shape=diamond, label="strlen", color="#0040C0",
style=dotted];
"UV printf (122)" [label="printf", color="#C000A0", style=dotted];
"UV lseek (123)" [label="lseek", color="#C000A0", style=dotted];
"UV xmalloc (26)" [label="xmalloc", color="#80C080", style=bold];
"UV strcpy (27)" [shape=diamond, label="strcpy", color="#00C0C0",
style=dotted];
"UV ctime (124)" [label="ctime", color="#C000A0", style=dotted];
"UV same_file (125)" [label="same_file", color="#4080A0", style=bold];
"UV strspn (28)" [label="strspn", color="#80C080", style=dotted];
"UV strcspn (29)" [shape=diamond, label="strcspn", color="#8040C0",
style=dotted];
"UV fflush (126)" [label="fflush", color="#4080A0", style=dotted];
"UV free (30)" [shape=diamond, label="free", color="#80C040", style=dotted];
"UV fgets (127)" [label="fgets", color="#4080A0", style=dotted];
"UV chmod (128)" [label="chmod", color="#4080A0", style=dotted];
"UV calloc (31)" [label="calloc", color="#80C080", style=dotted];
"UV error (32)" [shape=diamond, label="error", color="#400000", style=bold];
"UV reset_times (129)" [label="reset_times", color="#4080A0", style=bold];
"UV fprintf (33)" [shape=diamond, label="fprintf", color="#400080",
style=dotted];
"UV utime (130)" [label="utime", color="#4080A0", style=dotted];
"UV abort_gzip (34)" [shape=diamond, label="abort_gzip", color="#408000",
style=bold];
"UV chown (131)" [label="chown", color="#4080A0", style=dotted];
"UV exit (132)" [label="exit", color="#408020", style=dotted];
"UV warn (35)" [shape=diamond, label="warn", color="#408080", style=bold];
"UV perror (36)" [shape=diamond, label="perror", color="#C00000",
style=dotted];
"UV fill_window (133)" [label="fill_window", color="#000000", style=bold];
"UV display_ratio (37)" [shape=diamond, label="display_ratio",
color="#C00080", style=bold];
"UV longest_match (134)" [label="longest_match", color="#000000",
style=bold];
"UV _IO_putc (38)" [label="_IO_putc", color="#C00080", style=dotted];
"UV deflate_fast (135)" [label="deflate_fast", color="#000000", style=bold];
"UV malloc (39)" [shape=diamond, label="malloc", color="#C08080",
style=dotted];
"UV check_zipfile (40)" [label="check_zipfile", color="#4000E0", style=bold];
"UV unzip (41)" [shape=diamond, label="unzip", color="#4000C0", style=bold];
"UV inflate (42)" [label="inflate", color="#4000C0", style=bold];
"UV read_tree (43)" [label="read_tree", color="#C000C0", style=bold];
"UV build_tree (44)" [label="build_tree", color="#C000C0", style=bold];
"UV unpack (45)" [shape=diamond, label="unpack", color="#C000C0",
style=bold];
"UV unlzw (46)" [shape=diamond, label="unlzw", color="#C08040", style=bold];
"UV memset (47)" [shape=diamond, label="memset", color="#C080C0",
style=dotted];
"UV memcpy (48)" [shape=diamond, label="memcpy", color="#404000",
style=dotted];
"UV fillbuf (49)" [label="fillbuf", color="#C04040", style=bold];
"UV getbits (50)" [label="getbits", color="#C04040", style=bold];
"UV init_getbits (51)" [label="init_getbits", color="#C04040", style=bold];
"UV make_table (52)" [label="make_table", color="#C04040", style=bold];
"UV read_pt_len (53)" [label="read_pt_len", color="#C04040", style=bold];
"UV read_c_len (54)" [label="read_c_len", color="#C04040", style=bold];
"UV decode_c (55)" [label="decode_c", color="#C04040", style=bold];
"UV decode_p (56)" [label="decode_p", color="#C04040", style=bold];
"UV huf_decode_start (57)" [label="huf_decode_start", color="#C04040",
style=bold];
"UV decode_start (58)" [label="decode_start", color="#C04040", style=bold];
"UV decode (59)" [label="decode", color="#C04040", style=bold];
"UV unlzh (60)" [shape=diamond, label="unlzh", color="#C04040", style=bold];
"UV gen_codes (61)" [label="gen_codes", color="#000000", style=bold];
"UV bi_reverse (62)" [label="bi_reverse", color="#000000", style=bold];
"UV init_block (63)" [label="init_block", color="#000000", style=bold];
"UV pqdownheap (64)" [label="pqdownheap", color="#000000", style=bold];
"UV gen_bitlen (65)" [label="gen_bitlen", color="#000000", style=bold];
"UV build_tree_0 (66)" [label="build_tree_0", color="#000000", style=bold];
"UV scan_tree (67)" [label="scan_tree", color="#000000", style=bold];
"UV send_tree (68)" [label="send_tree", color="#000000", style=bold];
"UV send_bits (69)" [label="send_bits", color="#000000", style=bold];
"UV build_bl_tree (70)" [label="build_bl_tree", color="#000000", style=bold];
"UV send_all_trees (71)" [label="send_all_trees", color="#000000",
style=bold];
"UV flush_block (72)" [label="flush_block", color="#000000", style=bold];
"UV set_file_type (73)" [label="set_file_type", color="#000000", style=bold];
"UV copy_block (74)" [label="copy_block", color="#000000", style=bold];
"UV compress_block (75)" [label="compress_block", color="#000000",
style=bold];
"UV bi_windup (76)" [label="bi_windup", color="#000000", style=bold];
"UV ct_tally (77)" [label="ct_tally", color="#000000", style=bold];
"UV lzw (78)" [shape=diamond, label="lzw", color="#808060", style=bold];
"UV huft_build (79)" [label="huft_build", color="#4000C0", style=bold];
"UV huft_free (80)" [label="huft_free", color="#4000C0", style=bold];
"UV inflate_codes (81)" [label="inflate_codes", color="#4000C0", style=bold];
"UV inflate_stored (82)" [label="inflate_stored", color="#4000C0",
style=bold];
"UV inflate_fixed (83)" [label="inflate_fixed", color="#4000C0", style=bold];
"UV inflate_dynamic (84)" [label="inflate_dynamic", color="#4000C0",
style=bold];
"UV inflate_block (85)" [label="inflate_block", color="#4000C0", style=bold];
"UV (86)" [shape=diamond, label="", color="#80C020",
style=bold];
"UV usage (87)" [shape=diamond, label="usage", color="#80C0A0", style=bold];
"UV help (88)" [shape=diamond, label="help", color="#004060", style=bold];
"UV license (89)" [shape=diamond, label="license", color="#0040E0",
style=bold];
"UV version (90)" [shape=diamond, label="version", color="#00C060",
style=bold];
"UV main (91)" [shape=diamond, label="main", color="#00C0E0", style=bold];
"UV strcmp (92)" [shape=diamond, label="strcmp", color="#804060",
style=dotted];
"UV signal (93)" [shape=diamond, label="signal", color="#8040E0",
style=dotted];
"UV strncmp (94)" [shape=diamond, label="strncmp", color="#80C060",
style=dotted];
"UV strncpy (95)" [shape=diamond, label="strncpy", color="#80C0E0",
style=dotted];
"UV getopt_long (96)" [shape=diamond, label="getopt_long", color="#400020",
style=dotted];
subgraph cluster_36 { label="S 36";
color="#C00000";
style=bold;
"UV perror (36)"; };
subgraph cluster_37 { label="S 37";
color="#C00080";
style=bold;
"UV _IO_putc (38)";"UV display_ratio (37)"; };
subgraph cluster_86 { label="S 86";
color="#80C020";
style=bold;
"UV (86)"; };
subgraph cluster_87 { label="S 87";
color="#80C0A0";
style=bold;
"UV usage (87)"; };
subgraph cluster_39 { label="S 39";
color="#C08080";
style=bold;
"UV malloc (39)"; };
subgraph cluster_88 { label="S 88";
color="#004060";
style=bold;
"UV help (88)"; };
subgraph cluster_89 { label="S 89";
color="#0040E0";
style=bold;
"UV license (89)"; };
subgraph cluster_20 { label="S 20";
color="#804000";
style=bold;
"UV isupper (20)"; };
subgraph cluster_21 { label="S 21";
color="#804080";
style=bold;
"UV strrchr (21)"; };
subgraph cluster_111 { label="S 111";
color="#C080E0";
style=bold;
"UV unlink (111)"; };
subgraph cluster_22 { label="S 22";
color="#80C000";
style=bold;
"UV make_simple_name (22)"; };
subgraph cluster_23 { label="S 23";
color="#80C080";
style=bold;
"UV calloc (31)";"UV strspn (28)";"UV xmalloc (26)";"UV getenv (24)";"UV add_envopt (23)"; };
subgraph cluster_25 { label="S 25";
color="#0040C0";
style=bold;
"UV strlen (25)"; };
subgraph cluster_27 { label="S 27";
color="#00C0C0";
style=bold;
"UV strcpy (27)"; };
subgraph cluster_41 { label="S 41";
color="#4000C0";
style=bold;
"UV inflate_block (85)";"UV inflate_dynamic (84)";"UV inflate_fixed (83)";"UV inflate_stored (82)";"UV inflate_codes (81)";"UV huft_free (80)";"UV huft_build (79)";"UV inflate (42)";"UV unzip (41)"; };
subgraph cluster_90 { label="S 90";
color="#00C060";
style=bold;
"UV version (90)"; };
subgraph cluster_29 { label="S 29";
color="#8040C0";
style=bold;
"UV strcspn (29)"; };
subgraph cluster_91 { label="S 91";
color="#00C0E0";
style=bold;
"UV main (91)"; };
subgraph cluster_78 { label="S 78";
color="#808060";
style=bold;
"UV lzw (78)"; };
subgraph cluster_92 { label="S 92";
color="#804060";
style=bold;
"UV strcmp (92)"; };
subgraph cluster_0 { label="S 0";
color="#000000";
style=bold;
"UV ct_tally (77)";"UV bi_windup (76)";"UV compress_block (75)";"UV copy_block (74)";"UV set_file_type (73)";"UV flush_block (72)";"UV send_all_trees (71)";"UV build_bl_tree (70)";"UV send_bits (69)";"UV send_tree (68)";"UV scan_tree (67)";"UV build_tree_0 (66)";"UV gen_bitlen (65)";"UV pqdownheap (64)";"UV init_block (63)";"UV bi_reverse (62)";"UV gen_codes (61)";"UV deflate_fast (135)";"UV longest_match (134)";"UV fill_window (133)";"UV deflate (7)";"UV lm_init (5)";"UV ct_init (4)";"UV bi_init (3)";"UV flush_outbuf (1)";"UV zip (0)"; };
subgraph cluster_93 { label="S 93";
color="#8040E0";
style=bold;
"UV signal (93)"; };
subgraph cluster_45 { label="S 45";
color="#C000C0";
style=bold;
"UV unpack (45)";"UV build_tree (44)";"UV read_tree (43)"; };
subgraph cluster_10 { label="S 10";
color="#008040";
style=bold;
"UV copy (10)"; };
subgraph cluster_100 { label="S 100";
color="#C00020";
style=bold;
"UV treat_stdin (100)"; };
subgraph cluster_94 { label="S 94";
color="#80C060";
style=bold;
"UV strncmp (94)"; };
subgraph cluster_46 { label="S 46";
color="#C08040";
style=bold;
"UV unlzw (46)"; };
subgraph cluster_11 { label="S 11";
color="#0080C0";
style=bold;
"UV __errno_location (11)"; };
subgraph cluster_101 { label="S 101";
color="#C000A0";
style=bold;
"UV ctime (124)";"UV lseek (123)";"UV printf (122)";"UV do_list (101)"; };
subgraph cluster_2 { label="S 2";
color="#008000";
style=bold;
"UV updcrc (2)"; };
subgraph cluster_95 { label="S 95";
color="#80C0E0";
style=bold;
"UV strncpy (95)"; };
subgraph cluster_60 { label="S 60";
color="#C04040";
style=bold;
"UV unlzh (60)";"UV decode (59)";"UV decode_start (58)";"UV huf_decode_start (57)";"UV decode_p (56)";"UV decode_c (55)";"UV read_c_len (54)";"UV read_pt_len (53)";"UV make_table (52)";"UV init_getbits (51)";"UV getbits (50)";"UV fillbuf (49)"; };
subgraph cluster_47 { label="S 47";
color="#C080C0";
style=bold;
"UV memset (47)"; };
subgraph cluster_12 { label="S 12";
color="#800040";
style=bold;
"UV write (17)";"UV write_buf (12)"; };
subgraph cluster_102 { label="S 102";
color="#C08020";
style=bold;
"UV fileno (102)"; };
subgraph cluster_96 { label="S 96";
color="#400020";
style=bold;
"UV getopt_long (96)"; };
subgraph cluster_48 { label="S 48";
color="#404000";
style=bold;
"UV memcpy (48)"; };
subgraph cluster_13 { label="S 13";
color="#8000C0";
style=bold;
"UV read_error (13)"; };
subgraph cluster_103 { label="S 103";
color="#C080A0";
style=bold;
"UV isatty (103)"; };
subgraph cluster_97 { label="S 97";
color="#4000A0";
style=bold;
"UV atoi (97)"; };
subgraph cluster_14 { label="S 14";
color="#808040";
style=bold;
"UV clear_bufs (14)"; };
subgraph cluster_104 { label="S 104";
color="#400060";
style=bold;
"UV fstat (104)"; };
subgraph cluster_98 { label="S 98";
color="#408020";
style=bold;
"UV exit (132)";"UV do_exit (98)"; };
subgraph cluster_15 { label="S 15";
color="#8080C0";
style=bold;
"UV fill_inbuf (15)"; };
subgraph cluster_105 { label="S 105";
color="#4000E0";
style=bold;
"UV check_zipfile (40)";"UV memcmp (121)";"UV get_method (105)"; };
subgraph cluster_6 { label="S 6";
color="#808000";
style=bold;
"UV basename (6)"; };
subgraph cluster_16 { label="S 16";
color="#004000";
style=bold;
"UV flush_window (16)"; };
subgraph cluster_99 { label="S 99";
color="#4080A0";
style=bold;
"UV chown (131)";"UV utime (130)";"UV reset_times (129)";"UV chmod (128)";"UV fgets (127)";"UV fflush (126)";"UV same_file (125)";"UV strcat (120)";"UV get_suffix (119)";"UV stat (118)";"UV lstat (117)";"UV do_stat (116)";"UV shorten_name (115)";"UV name_too_long (114)";"UV check_ofname (113)";"UV copy_stat (112)";"UV create_outfile (110)";"UV open (108)";"UV make_ofname (107)";"UV get_istat (106)";"UV treat_file (99)"; };
subgraph cluster_30 { label="S 30";
color="#80C040";
style=bold;
"UV free (30)"; };
subgraph cluster_8 { label="S 8";
color="#000040";
style=bold;
"UV file_read (8)"; };
subgraph cluster_18 { label="S 18";
color="#00C000";
style=bold;
"UV write_error (18)"; };
subgraph cluster_9 { label="S 9";
color="#0000C0";
style=bold;
"UV read (9)"; };
subgraph cluster_32 { label="S 32";
color="#400000";
style=bold;
"UV error (32)"; };
subgraph cluster_19 { label="S 19";
color="#00C080";
style=bold;
"UV strlwr (19)"; };
subgraph cluster_109 { label="S 109";
color="#C000E0";
style=bold;
"UV close (109)"; };
subgraph cluster_33 { label="S 33";
color="#400080";
style=bold;
"UV fprintf (33)"; };
subgraph cluster_34 { label="S 34";
color="#408000";
style=bold;
"UV abort_gzip (34)"; };
subgraph cluster_35 { label="S 35";
color="#408080";
style=bold;
"UV warn (35)"; };
"UV zip (0)" -> "UV flush_outbuf (1)" [color="#000000"];
"UV zip (0)" -> "UV updcrc (2)" [color="#000000"];
"UV zip (0)" -> "UV bi_init (3)" [color="#000000"];
"UV zip (0)" -> "UV ct_init (4)" [color="#000000"];
"UV zip (0)" -> "UV lm_init (5)" [color="#000000"];
"UV zip (0)" -> "UV basename (6)" [color="#000000"];
"UV zip (0)" -> "UV deflate (7)" [color="#000000"];
"UV zip (0)" -> "UV write_buf (12)" [color="#000000"];
"UV zip (0)" -> "UV error (32)" [color="#000000"];
"UV zip (0)" -> "UV memset (47)" [color="#000000"];
"UV zip (0)" -> "UV memcpy (48)" [color="#000000"];
"UV zip (0)" -> "UV (86)" [color="#000000"];
"UV do_exit (98)" -> "UV free (30)" [color="#408020"];
"UV do_exit (98)" -> "UV exit (132)" [color="#408020"];
"UV flush_outbuf (1)" -> "UV write_buf (12)" [color="#000000"];
"UV treat_file (99)" -> "UV __errno_location (11)" [color="#4080A0"];
"UV treat_file (99)" -> "UV clear_bufs (14)" [color="#4080A0"];
"UV treat_file (99)" -> "UV write_error (18)" [color="#4080A0"];
"UV treat_file (99)" -> "UV strlwr (19)" [color="#4080A0"];
"UV treat_file (99)" -> "UV isupper (20)" [color="#4080A0"];
"UV treat_file (99)" -> "UV strrchr (21)" [color="#4080A0"];
"UV treat_file (99)" -> "UV strlen (25)" [color="#4080A0"];
"UV treat_file (99)" -> "UV strcpy (27)" [color="#4080A0"];
"UV treat_file (99)" -> "UV strcspn (29)" [color="#4080A0"];
"UV treat_file (99)" -> "UV error (32)" [color="#4080A0"];
"UV treat_file (99)" -> "UV fprintf (33)" [color="#4080A0"];
"UV treat_file (99)" -> "UV perror (36)" [color="#4080A0"];
"UV treat_file (99)" -> "UV display_ratio (37)" [color="#4080A0"];
"UV treat_file (99)" -> "UV (86)" [color="#4080A0"];
"UV treat_file (99)" -> "UV strcmp (92)" [color="#4080A0"];
"UV treat_file (99)" -> "UV treat_stdin (100)" [color="#4080A0"];
"UV treat_file (99)" -> "UV do_list (101)" [color="#4080A0"];
"UV treat_file (99)" -> "UV fileno (102)" [color="#4080A0"];
"UV treat_file (99)" -> "UV isatty (103)" [color="#4080A0"];
"UV treat_file (99)" -> "UV fstat (104)" [color="#4080A0"];
"UV treat_file (99)" -> "UV get_method (105)" [color="#4080A0"];
"UV treat_file (99)" -> "UV get_istat (106)" [color="#4080A0"];
"UV treat_file (99)" -> "UV make_ofname (107)" [color="#4080A0"];
"UV treat_file (99)" -> "UV open (108)" [color="#4080A0"];
"UV treat_file (99)" -> "UV close (109)" [color="#4080A0"];
"UV treat_file (99)" -> "UV create_outfile (110)" [color="#4080A0"];
"UV treat_file (99)" -> "UV unlink (111)" [color="#4080A0"];
"UV treat_file (99)" -> "UV copy_stat (112)" [color="#4080A0"];
"UV treat_stdin (100)" -> "UV clear_bufs (14)" [color="#C00020"];
"UV treat_stdin (100)" -> "UV strcpy (27)" [color="#C00020"];
"UV treat_stdin (100)" -> "UV error (32)" [color="#C00020"];
"UV treat_stdin (100)" -> "UV fprintf (33)" [color="#C00020"];
"UV treat_stdin (100)" -> "UV display_ratio (37)" [color="#C00020"];
"UV treat_stdin (100)" -> "UV (86)" [color="#C00020"];
"UV treat_stdin (100)" -> "UV do_exit (98)" [color="#C00020"];
"UV treat_stdin (100)" -> "UV do_list (101)" [color="#C00020"];
"UV treat_stdin (100)" -> "UV fileno (102)" [color="#C00020"];
"UV treat_stdin (100)" -> "UV isatty (103)" [color="#C00020"];
"UV treat_stdin (100)" -> "UV fstat (104)" [color="#C00020"];
"UV treat_stdin (100)" -> "UV get_method (105)" [color="#C00020"];
"UV do_list (101)" -> "UV read (9)" [color="#C000A0"];
"UV do_list (101)" -> "UV read_error (13)" [color="#C000A0"];
"UV do_list (101)" -> "UV display_ratio (37)" [color="#C000A0"];
"UV do_list (101)" -> "UV printf (122)" [color="#C000A0"];
"UV do_list (101)" -> "UV lseek (123)" [color="#C000A0"];
"UV do_list (101)" -> "UV ctime (124)" [color="#C000A0"];
"UV ct_init (4)" -> "UV gen_codes (61)" [color="#000000"];
"UV ct_init (4)" -> "UV bi_reverse (62)" [color="#000000"];
"UV ct_init (4)" -> "UV init_block (63)" [color="#000000"];
"UV lm_init (5)" -> "UV error (32)" [color="#000000"];
"UV lm_init (5)" -> "UV memset (47)" [color="#000000"];
"UV lm_init (5)" -> "UV (86)" [color="#000000"];
"UV lm_init (5)" -> "UV fill_window (133)" [color="#000000"];
"UV basename (6)" -> "UV strlwr (19)" [color="#808000"];
"UV basename (6)" -> "UV strrchr (21)" [color="#808000"];
"UV deflate (7)" -> "UV flush_block (72)" [color="#000000"];
"UV deflate (7)" -> "UV ct_tally (77)" [color="#000000"];
"UV deflate (7)" -> "UV fill_window (133)" [color="#000000"];
"UV deflate (7)" -> "UV longest_match (134)" [color="#000000"];
"UV deflate (7)" -> "UV deflate_fast (135)" [color="#000000"];
"UV get_method (105)" -> "UV basename (6)" [color="#4000E0"];
"UV get_method (105)" -> "UV fill_inbuf (15)" [color="#4000E0"];
"UV get_method (105)" -> "UV error (32)" [color="#4000E0"];
"UV get_method (105)" -> "UV fprintf (33)" [color="#4000E0"];
"UV get_method (105)" -> "UV check_zipfile (40)" [color="#4000E0"];
"UV get_method (105)" -> "UV memcmp (121)" [color="#4000E0"];
"UV file_read (8)" -> "UV updcrc (2)" [color="#000040"];
"UV file_read (8)" -> "UV read (9)" [color="#000040"];
"UV get_istat (106)" -> "UV __errno_location (11)" [color="#4080A0"];
"UV get_istat (106)" -> "UV strlen (25)" [color="#4080A0"];
"UV get_istat (106)" -> "UV strcpy (27)" [color="#4080A0"];
"UV get_istat (106)" -> "UV perror (36)" [color="#4080A0"];
"UV get_istat (106)" -> "UV strcmp (92)" [color="#4080A0"];
"UV get_istat (106)" -> "UV do_stat (116)" [color="#4080A0"];
"UV get_istat (106)" -> "UV get_suffix (119)" [color="#4080A0"];
"UV get_istat (106)" -> "UV strcat (120)" [color="#4080A0"];
"UV make_ofname (107)" -> "UV strlwr (19)" [color="#4080A0"];
"UV make_ofname (107)" -> "UV strcpy (27)" [color="#4080A0"];
"UV make_ofname (107)" -> "UV fprintf (33)" [color="#4080A0"];
"UV make_ofname (107)" -> "UV strcmp (92)" [color="#4080A0"];
"UV make_ofname (107)" -> "UV get_suffix (119)" [color="#4080A0"];
"UV make_ofname (107)" -> "UV strcat (120)" [color="#4080A0"];
"UV copy (10)" -> "UV read (9)" [color="#008040"];
"UV copy (10)" -> "UV __errno_location (11)" [color="#008040"];
"UV copy (10)" -> "UV write_buf (12)" [color="#008040"];
"UV copy (10)" -> "UV read_error (13)" [color="#008040"];
"UV write_buf (12)" -> "UV write (17)" [color="#800040"];
"UV write_buf (12)" -> "UV write_error (18)" [color="#800040"];
"UV read_error (13)" -> "UV __errno_location (11)" [color="#8000C0"];
"UV read_error (13)" -> "UV fprintf (33)" [color="#8000C0"];
"UV read_error (13)" -> "UV abort_gzip (34)" [color="#8000C0"];
"UV read_error (13)" -> "UV perror (36)" [color="#8000C0"];
"UV create_outfile (110)" -> "UV fprintf (33)" [color="#4080A0"];
"UV create_outfile (110)" -> "UV perror (36)" [color="#4080A0"];
"UV create_outfile (110)" -> "UV fstat (104)" [color="#4080A0"];
"UV create_outfile (110)" -> "UV open (108)" [color="#4080A0"];
"UV create_outfile (110)" -> "UV close (109)" [color="#4080A0"];
"UV create_outfile (110)" -> "UV unlink (111)" [color="#4080A0"];
"UV create_outfile (110)" -> "UV check_ofname (113)" [color="#4080A0"];
"UV create_outfile (110)" -> "UV name_too_long (114)" [color="#4080A0"];
"UV create_outfile (110)" -> "UV shorten_name (115)" [color="#4080A0"];
"UV fill_inbuf (15)" -> "UV read (9)" [color="#8080C0"];
"UV fill_inbuf (15)" -> "UV __errno_location (11)" [color="#8080C0"];
"UV fill_inbuf (15)" -> "UV read_error (13)" [color="#8080C0"];
"UV copy_stat (112)" -> "UV fprintf (33)" [color="#4080A0"];
"UV copy_stat (112)" -> "UV perror (36)" [color="#4080A0"];
"UV copy_stat (112)" -> "UV unlink (111)" [color="#4080A0"];
"UV copy_stat (112)" -> "UV chmod (128)" [color="#4080A0"];
"UV copy_stat (112)" -> "UV reset_times (129)" [color="#4080A0"];
"UV copy_stat (112)" -> "UV chown (131)" [color="#4080A0"];
"UV flush_window (16)" -> "UV updcrc (2)" [color="#004000"];
"UV flush_window (16)" -> "UV write_buf (12)" [color="#004000"];
"UV check_ofname (113)" -> "UV __errno_location (11)" [color="#4080A0"];
"UV check_ofname (113)" -> "UV isupper (20)" [color="#4080A0"];
"UV check_ofname (113)" -> "UV strcpy (27)" [color="#4080A0"];
"UV check_ofname (113)" -> "UV fprintf (33)" [color="#4080A0"];
"UV check_ofname (113)" -> "UV perror (36)" [color="#4080A0"];
"UV check_ofname (113)" -> "UV strcmp (92)" [color="#4080A0"];
"UV check_ofname (113)" -> "UV fileno (102)" [color="#4080A0"];
"UV check_ofname (113)" -> "UV isatty (103)" [color="#4080A0"];
"UV check_ofname (113)" -> "UV unlink (111)" [color="#4080A0"];
"UV check_ofname (113)" -> "UV name_too_long (114)" [color="#4080A0"];
"UV check_ofname (113)" -> "UV shorten_name (115)" [color="#4080A0"];
"UV check_ofname (113)" -> "UV stat (118)" [color="#4080A0"];
"UV check_ofname (113)" -> "UV same_file (125)" [color="#4080A0"];
"UV check_ofname (113)" -> "UV fflush (126)" [color="#4080A0"];
"UV check_ofname (113)" -> "UV fgets (127)" [color="#4080A0"];
"UV check_ofname (113)" -> "UV chmod (128)" [color="#4080A0"];
"UV name_too_long (114)" -> "UV strlen (25)" [color="#4080A0"];
"UV name_too_long (114)" -> "UV stat (118)" [color="#4080A0"];
"UV name_too_long (114)" -> "UV same_file (125)" [color="#4080A0"];
"UV write_error (18)" -> "UV fprintf (33)" [color="#00C000"];
"UV write_error (18)" -> "UV abort_gzip (34)" [color="#00C000"];
"UV write_error (18)" -> "UV perror (36)" [color="#00C000"];
"UV shorten_name (115)" -> "UV strrchr (21)" [color="#4080A0"];
"UV shorten_name (115)" -> "UV strlen (25)" [color="#4080A0"];
"UV shorten_name (115)" -> "UV strcpy (27)" [color="#4080A0"];
"UV shorten_name (115)" -> "UV strcspn (29)" [color="#4080A0"];
"UV shorten_name (115)" -> "UV error (32)" [color="#4080A0"];
"UV shorten_name (115)" -> "UV strcmp (92)" [color="#4080A0"];
"UV shorten_name (115)" -> "UV get_suffix (119)" [color="#4080A0"];
"UV strlwr (19)" -> "UV isupper (20)" [color="#00C080"];
"UV do_stat (116)" -> "UV __errno_location (11)" [color="#4080A0"];
"UV do_stat (116)" -> "UV lstat (117)" [color="#4080A0"];
"UV do_stat (116)" -> "UV stat (118)" [color="#4080A0"];
"UV get_suffix (119)" -> "UV strlwr (19)" [color="#4080A0"];
"UV get_suffix (119)" -> "UV strlen (25)" [color="#4080A0"];
"UV get_suffix (119)" -> "UV strcpy (27)" [color="#4080A0"];
"UV get_suffix (119)" -> "UV strcmp (92)" [color="#4080A0"];
"UV make_simple_name (22)" -> "UV strrchr (21)" [color="#80C000"];
"UV add_envopt (23)" -> "UV getenv (24)" [color="#80C080"];
"UV add_envopt (23)" -> "UV strlen (25)" [color="#80C080"];
"UV add_envopt (23)" -> "UV xmalloc (26)" [color="#80C080"];
"UV add_envopt (23)" -> "UV strcpy (27)" [color="#80C080"];
"UV add_envopt (23)" -> "UV strspn (28)" [color="#80C080"];
"UV add_envopt (23)" -> "UV strcspn (29)" [color="#80C080"];
"UV add_envopt (23)" -> "UV free (30)" [color="#80C080"];
"UV add_envopt (23)" -> "UV calloc (31)" [color="#80C080"];
"UV add_envopt (23)" -> "UV error (32)" [color="#80C080"];
"UV add_envopt (23)" -> "UV malloc (39)" [color="#80C080"];
"UV xmalloc (26)" -> "UV error (32)" [color="#80C080"];
"UV xmalloc (26)" -> "UV malloc (39)" [color="#80C080"];
"UV error (32)" -> "UV fprintf (33)" [color="#400000"];
"UV error (32)" -> "UV abort_gzip (34)" [color="#400000"];
"UV reset_times (129)" -> "UV fprintf (33)" [color="#4080A0"];
"UV reset_times (129)" -> "UV perror (36)" [color="#4080A0"];
"UV reset_times (129)" -> "UV utime (130)" [color="#4080A0"];
"UV abort_gzip (34)" -> "UV do_exit (98)" [color="#408000"];
"UV abort_gzip (34)" -> "UV close (109)" [color="#408000"];
"UV abort_gzip (34)" -> "UV unlink (111)" [color="#408000"];
"UV warn (35)" -> "UV fprintf (33)" [color="#408080"];
"UV fill_window (133)" -> "UV memcpy (48)" [color="#000000"];
"UV fill_window (133)" -> "UV (86)" [color="#000000"];
"UV display_ratio (37)" -> "UV fprintf (33)" [color="#C00080"];
"UV display_ratio (37)" -> "UV _IO_putc (38)" [color="#C00080"];
"UV deflate_fast (135)" -> "UV flush_block (72)" [color="#000000"];
"UV deflate_fast (135)" -> "UV ct_tally (77)" [color="#000000"];
"UV deflate_fast (135)" -> "UV fill_window (133)" [color="#000000"];
"UV deflate_fast (135)" -> "UV longest_match (134)" [color="#000000"];
"UV check_zipfile (40)" -> "UV fprintf (33)" [color="#4000E0"];
"UV unzip (41)" -> "UV updcrc (2)" [color="#4000C0"];
"UV unzip (41)" -> "UV fill_inbuf (15)" [color="#4000C0"];
"UV unzip (41)" -> "UV flush_window (16)" [color="#4000C0"];
"UV unzip (41)" -> "UV free (30)" [color="#4000C0"];
"UV unzip (41)" -> "UV error (32)" [color="#4000C0"];
"UV unzip (41)" -> "UV fprintf (33)" [color="#4000C0"];
"UV unzip (41)" -> "UV malloc (39)" [color="#4000C0"];
"UV unzip (41)" -> "UV inflate (42)" [color="#4000C0"];
"UV unzip (41)" -> "UV memset (47)" [color="#4000C0"];
"UV unzip (41)" -> "UV memcpy (48)" [color="#4000C0"];
"UV inflate (42)" -> "UV flush_window (16)" [color="#4000C0"];
"UV inflate (42)" -> "UV inflate_block (85)" [color="#4000C0"];
"UV read_tree (43)" -> "UV fill_inbuf (15)" [color="#C000C0"];
"UV read_tree (43)" -> "UV error (32)" [color="#C000C0"];
"UV unpack (45)" -> "UV fill_inbuf (15)" [color="#C000C0"];
"UV unpack (45)" -> "UV flush_window (16)" [color="#C000C0"];
"UV unpack (45)" -> "UV error (32)" [color="#C000C0"];
"UV unpack (45)" -> "UV read_tree (43)" [color="#C000C0"];
"UV unpack (45)" -> "UV build_tree (44)" [color="#C000C0"];
"UV unlzw (46)" -> "UV read (9)" [color="#C08040"];
"UV unlzw (46)" -> "UV write_buf (12)" [color="#C08040"];
"UV unlzw (46)" -> "UV read_error (13)" [color="#C08040"];
"UV unlzw (46)" -> "UV fill_inbuf (15)" [color="#C08040"];
"UV unlzw (46)" -> "UV error (32)" [color="#C08040"];
"UV unlzw (46)" -> "UV fprintf (33)" [color="#C08040"];
"UV unlzw (46)" -> "UV memset (47)" [color="#C08040"];
"UV unlzw (46)" -> "UV memcpy (48)" [color="#C08040"];
"UV fillbuf (49)" -> "UV fill_inbuf (15)" [color="#C04040"];
"UV getbits (50)" -> "UV fillbuf (49)" [color="#C04040"];
"UV init_getbits (51)" -> "UV fillbuf (49)" [color="#C04040"];
"UV make_table (52)" -> "UV error (32)" [color="#C04040"];
"UV read_pt_len (53)" -> "UV fillbuf (49)" [color="#C04040"];
"UV read_pt_len (53)" -> "UV getbits (50)" [color="#C04040"];
"UV read_pt_len (53)" -> "UV make_table (52)" [color="#C04040"];
"UV read_c_len (54)" -> "UV fillbuf (49)" [color="#C04040"];
"UV read_c_len (54)" -> "UV getbits (50)" [color="#C04040"];
"UV read_c_len (54)" -> "UV make_table (52)" [color="#C04040"];
"UV decode_c (55)" -> "UV fillbuf (49)" [color="#C04040"];
"UV decode_c (55)" -> "UV getbits (50)" [color="#C04040"];
"UV decode_c (55)" -> "UV read_pt_len (53)" [color="#C04040"];
"UV decode_c (55)" -> "UV read_c_len (54)" [color="#C04040"];
"UV decode_p (56)" -> "UV fillbuf (49)" [color="#C04040"];
"UV decode_p (56)" -> "UV getbits (50)" [color="#C04040"];
"UV huf_decode_start (57)" -> "UV init_getbits (51)" [color="#C04040"];
"UV decode_start (58)" -> "UV huf_decode_start (57)" [color="#C04040"];
"UV decode (59)" -> "UV decode_c (55)" [color="#C04040"];
"UV decode (59)" -> "UV decode_p (56)" [color="#C04040"];
"UV unlzh (60)" -> "UV write_buf (12)" [color="#C04040"];
"UV unlzh (60)" -> "UV fill_inbuf (15)" [color="#C04040"];
"UV unlzh (60)" -> "UV error (32)" [color="#C04040"];
"UV unlzh (60)" -> "UV decode_start (58)" [color="#C04040"];
"UV unlzh (60)" -> "UV decode (59)" [color="#C04040"];
"UV gen_codes (61)" -> "UV bi_reverse (62)" [color="#000000"];
"UV build_tree_0 (66)" -> "UV gen_codes (61)" [color="#000000"];
"UV build_tree_0 (66)" -> "UV pqdownheap (64)" [color="#000000"];
"UV build_tree_0 (66)" -> "UV gen_bitlen (65)" [color="#000000"];
"UV send_tree (68)" -> "UV send_bits (69)" [color="#000000"];
"UV send_bits (69)" -> "UV flush_outbuf (1)" [color="#000000"];
"UV build_bl_tree (70)" -> "UV build_tree_0 (66)" [color="#000000"];
"UV build_bl_tree (70)" -> "UV scan_tree (67)" [color="#000000"];
"UV send_all_trees (71)" -> "UV send_tree (68)" [color="#000000"];
"UV send_all_trees (71)" -> "UV send_bits (69)" [color="#000000"];
"UV flush_block (72)" -> "UV init_block (63)" [color="#000000"];
"UV flush_block (72)" -> "UV build_tree_0 (66)" [color="#000000"];
"UV flush_block (72)" -> "UV send_bits (69)" [color="#000000"];
"UV flush_block (72)" -> "UV build_bl_tree (70)" [color="#000000"];
"UV flush_block (72)" -> "UV send_all_trees (71)" [color="#000000"];
"UV flush_block (72)" -> "UV set_file_type (73)" [color="#000000"];
"UV flush_block (72)" -> "UV copy_block (74)" [color="#000000"];
"UV flush_block (72)" -> "UV compress_block (75)" [color="#000000"];
"UV flush_block (72)" -> "UV bi_windup (76)" [color="#000000"];
"UV copy_block (74)" -> "UV flush_outbuf (1)" [color="#000000"];
"UV copy_block (74)" -> "UV bi_windup (76)" [color="#000000"];
"UV compress_block (75)" -> "UV send_bits (69)" [color="#000000"];
"UV bi_windup (76)" -> "UV flush_outbuf (1)" [color="#000000"];
"UV lzw (78)" -> "UV fprintf (33)" [color="#808060"];
"UV huft_build (79)" -> "UV malloc (39)" [color="#4000C0"];
"UV huft_build (79)" -> "UV memset (47)" [color="#4000C0"];
"UV huft_build (79)" -> "UV huft_free (80)" [color="#4000C0"];
"UV huft_free (80)" -> "UV free (30)" [color="#4000C0"];
"UV inflate_codes (81)" -> "UV fill_inbuf (15)" [color="#4000C0"];
"UV inflate_codes (81)" -> "UV flush_window (16)" [color="#4000C0"];
"UV inflate_codes (81)" -> "UV memcpy (48)" [color="#4000C0"];
"UV inflate_stored (82)" -> "UV fill_inbuf (15)" [color="#4000C0"];
"UV inflate_stored (82)" -> "UV flush_window (16)" [color="#4000C0"];
"UV inflate_fixed (83)" -> "UV huft_build (79)" [color="#4000C0"];
"UV inflate_fixed (83)" -> "UV huft_free (80)" [color="#4000C0"];
"UV inflate_fixed (83)" -> "UV inflate_codes (81)" [color="#4000C0"];
"UV inflate_dynamic (84)" -> "UV fill_inbuf (15)" [color="#4000C0"];
"UV inflate_dynamic (84)" -> "UV fprintf (33)" [color="#4000C0"];
"UV inflate_dynamic (84)" -> "UV huft_build (79)" [color="#4000C0"];
"UV inflate_dynamic (84)" -> "UV huft_free (80)" [color="#4000C0"];
"UV inflate_dynamic (84)" -> "UV inflate_codes (81)" [color="#4000C0"];
"UV inflate_block (85)" -> "UV fill_inbuf (15)" [color="#4000C0"];
"UV inflate_block (85)" -> "UV inflate_stored (82)" [color="#4000C0"];
"UV inflate_block (85)" -> "UV inflate_fixed (83)" [color="#4000C0"];
"UV inflate_block (85)" -> "UV inflate_dynamic (84)" [color="#4000C0"];
"UV usage (87)" -> "UV fprintf (33)" [color="#80C0A0"];
"UV help (88)" -> "UV fprintf (33)" [color="#004060"];
"UV help (88)" -> "UV usage (87)" [color="#004060"];
"UV license (89)" -> "UV fprintf (33)" [color="#0040E0"];
"UV version (90)" -> "UV fprintf (33)" [color="#00C060"];
"UV main (91)" -> "UV basename (6)" [color="#00C0E0"];
"UV main (91)" -> "UV add_envopt (23)" [color="#00C0E0"];
"UV main (91)" -> "UV strlen (25)" [color="#00C0E0"];
"UV main (91)" -> "UV strcpy (27)" [color="#00C0E0"];
"UV main (91)" -> "UV fprintf (33)" [color="#00C0E0"];
"UV main (91)" -> "UV usage (87)" [color="#00C0E0"];
"UV main (91)" -> "UV help (88)" [color="#00C0E0"];
"UV main (91)" -> "UV license (89)" [color="#00C0E0"];
"UV main (91)" -> "UV version (90)" [color="#00C0E0"];
"UV main (91)" -> "UV strcmp (92)" [color="#00C0E0"];
"UV main (91)" -> "UV signal (93)" [color="#00C0E0"];
"UV main (91)" -> "UV strncmp (94)" [color="#00C0E0"];
"UV main (91)" -> "UV strncpy (95)" [color="#00C0E0"];
"UV main (91)" -> "UV getopt_long (96)" [color="#00C0E0"];
"UV main (91)" -> "UV atoi (97)" [color="#00C0E0"];
"UV main (91)" -> "UV do_exit (98)" [color="#00C0E0"];
"UV main (91)" -> "UV treat_file (99)" [color="#00C0E0"];
"UV main (91)" -> "UV treat_stdin (100)" [color="#00C0E0"];
"UV main (91)" -> "UV do_list (101)" [color="#00C0E0"];
} ocamlgraph-2.0.0/editor/ 0000755 0001750 0000144 00000000000 13735627615 013477 5 ustar rt users ocamlgraph-2.0.0/editor/dirTree.mli 0000644 0001750 0000144 00000002602 13735627615 015600 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
type t
val id : t -> int
type label
val children : t -> t list ;;
val label : t -> label ;;
val string_of_label : label -> string ;;
val from_dir : string -> string -> t ;;
ocamlgraph-2.0.0/editor/ed_graph.ml 0000644 0001750 0000144 00000021065 13735627615 015606 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(* This file is a contribution of Benjamin Vadon *)
open Graph
open Ed_hyper
type visibility = Visible | BorderNode | Hidden
type mode = Normal | Selected | Focused | Selected_Focused
type node_info =
{
label : string;
mutable visible : visibility;
mutable depth : int;
mutable vertex_mode : mode;
mutable turtle : turtle;
}
let make_node_info s =
{
label = s;
visible = Hidden;
depth = 0;
vertex_mode = Normal;
turtle = dummy_turtle
}
type edge_info =
{
mutable visited : bool;
mutable edge_mode : mode;
mutable edge_turtle : turtle;
mutable edge_distance : float;
mutable edge_steps : int;
}
let make_edge_info () =
{
visited = false;
edge_mode = Normal;
edge_turtle = dummy_turtle;
edge_distance = 0.;
edge_steps = 0;
}
module EDGE = struct
type t = edge_info
let compare : t -> t -> int = Stdlib.compare
let default = make_edge_info ()
end
module G =
Imperative.Graph.AbstractLabeled(struct type t = node_info end)(EDGE)
module B = Builder.I(G)
(* current graph *)
let graph = ref (G.create ())
type name = string option
let graph_name = ref (None: name)
(* useful functions for vertex and edge *)
let string_of_label x = (G.V.label x).label
let edge v w = G.mem_edge !graph v w || G.mem_edge !graph w v
(* two Parser modules *)
module GmlParser =
Gml.Parse
(B)
(struct
let node l =
make_node_info
(try
match List.assoc "id" l
with Gml.Int n -> string_of_int n | _ -> ""
with Not_found -> "")
let edge _ = make_edge_info ()
end)
module DotParser =
Dot.Parse
(B)
(struct
let node (id,_) _ = match id with
| Dot_ast.Ident s
| Dot_ast.Number s
| Dot_ast.String s
| Dot_ast.Html s -> make_node_info s
let edge _ = make_edge_info ()
end)
(* a parsing file function *)
let parse_file f =
if Filename.check_suffix f ".gml" then
GmlParser.parse f
else
DotParser.parse f
(* two Printer Modules *)
module GmlPrinter =
Gml.Print
(G)
(struct
let node (v: G.V.label) = ["label", Gml.Int (int_of_string v.label)]
let edge (_: G.E.label) = []
end)
module DotPrinter =
Graphviz.Dot
( struct
include G
let vertex_name vertex = string_of_label vertex
let graph_attributes _ = []
let default_vertex_attributes _ = []
let vertex_attributes _ = []
let default_edge_attributes _ = []
let edge_attributes _ = []
let get_subgraph _ = None
end )
(* two outputs functions, and a save graph function *)
let gml_output g f =
let c = open_out f in
let fmt = Format.formatter_of_out_channel c in
Format.fprintf fmt "%a@." GmlPrinter.print g;
close_out c
let dot_output g f =
let oc = open_out f in
DotPrinter.output_graph oc g;
close_out oc
let save_graph name =
if Filename.check_suffix name "gml"
then ( gml_output !graph name; graph_name := Some name)
else if Filename.check_suffix name "dot"
then ( dot_output !graph name; graph_name := Some name)
else ( let name = name^".dot" in
dot_output !graph name;
graph_name := Some name )
module Components = Components.Make(G)
module Dfs = Traverse.Dfs(G)
exception Choose of G.V.t
let choose_root () =
try
G.iter_vertex (fun v -> raise (Choose v)) !graph;
None
with Choose v ->
Some v
(* Parsing of the command line *)
let load_graph f =
graph := parse_file f;
graph_name := Some f
let dfs = ref false
let refresh_rate = ref 10
let aa = ref true
let () =
Arg.parse
["-dfs", Arg.Set dfs, "DFS drawing strategy";
"-bfs", Arg.Clear dfs, "BFS drawing strategy";
"-rr", Arg.Set_int refresh_rate, "set the refresh rate, must be greater than 0";
"-aa", Arg.Clear aa, "turn off anti-aliased mode";
]
load_graph
"editor [options] "
(* successor edges *)
module H2 =
Hashtbl.Make
(struct
type t = G.V.t * G.V.t
let hash (v,w) = Hashtbl.hash (G.V.hash v, G.V.hash w)
let equal (v1,w1) (v2,w2) = G.V.equal v1 v2 && G.V.equal w1 w2
end)
module H = Hashtbl.Make(G.V)
(* vertex select and unselect *)
(* a counter for selected vertices *)
let nb_selected = ref 0
(* a belonging test to selection *)
let is_selected (x:G.V.t) =
let mode =(G.V.label x).vertex_mode in
mode = Selected ||
mode = Selected_Focused
type mode_select_list =
REMOVE_FROM of G.V.t
| ADD_FROM of G.V.t
| NONE
let selected_list mode =
let vertex_selection =ref [] in
G.iter_vertex (fun v ->
if (is_selected v)
&& (match mode with
| ADD_FROM vertex -> not (edge v vertex)
| REMOVE_FROM vertex -> (edge v vertex)
| NONE -> true)
then vertex_selection := v::(!vertex_selection)) !graph;
let compare s1 s2 = String.compare (string_of_label s1) (string_of_label s2) in
List.sort compare !vertex_selection
type ed_event = Select | Unselect | Focus | Unfocus
let update_vertex vertex event =
let vertex_info = G.V.label vertex in
begin
match vertex_info.vertex_mode, event with
| Normal, Select -> vertex_info.vertex_mode <- Selected; incr nb_selected
| Normal, Focus -> vertex_info.vertex_mode <- Focused
| Normal, _ -> ()
| Selected, Focus -> vertex_info.vertex_mode <- Selected_Focused
| Selected, Unselect -> vertex_info.vertex_mode <- Normal; decr nb_selected
| Selected, _ -> ()
| Focused, Select -> vertex_info.vertex_mode <- Selected_Focused; incr nb_selected
| Focused, Unfocus -> vertex_info.vertex_mode <- Normal
| Focused, _ -> ()
| Selected_Focused, Unselect -> vertex_info.vertex_mode <- Focused; decr nb_selected
| Selected_Focused, Unfocus -> vertex_info.vertex_mode <- Selected
| Selected_Focused, _ -> ()
end;
G.iter_succ_e
( fun edge ->
let edge_info = G.E.label edge in
let dest_vertex = G.E.dst edge in
begin match edge_info.edge_mode, event with
| Normal, Select -> edge_info.edge_mode <- Selected
| Normal, Focus -> edge_info.edge_mode <- Focused
| Normal, _ -> ()
| Selected, Focus -> edge_info.edge_mode <- Selected_Focused
| Selected, Unselect -> if not(is_selected dest_vertex) then edge_info.edge_mode <- Normal
| Selected, _ -> ()
| Focused, Select -> edge_info.edge_mode <- Selected_Focused
| Focused, Unfocus -> edge_info.edge_mode <- Normal
| Focused, _ -> ()
| Selected_Focused, Unselect -> if not(is_selected dest_vertex) then edge_info.edge_mode <- Focused; decr nb_selected
| Selected_Focused, Unfocus -> edge_info.edge_mode <- Selected
| Selected_Focused, _ -> ()
end;
) !graph vertex
(* to select and unselect all vertices *)
let select_all () =
G.iter_vertex (fun v ->
if not(is_selected v)
then begin
let v = G.V.label v in
v.vertex_mode <- Selected;
incr nb_selected
end
) !graph;
G.iter_edges_e (fun e -> let e = G.E.label e in e.edge_mode <- Selected) !graph
let unselect_all () =
G.iter_vertex (fun v ->
if (is_selected v)
then begin
let l = G.V.label v in
l.vertex_mode <- Normal;
decr nb_selected
end
) !graph;
G.iter_edges_e (fun e -> let e = G.E.label e in e.edge_mode <- Normal) !graph
ocamlgraph-2.0.0/editor/outils_tort.ml 0000644 0001750 0000144 00000007606 13735627615 016431 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
open Outils_math
let debug_outil_tort = ref false
let (w,h)= (600.,600.)
(*** Tortue Hyperbolique ***)
type coord = float * float
type turtle =
{
pos : coord ; (* with |pos| < 1 *)
dir : coord (* with |dir| = 1 *)
}
let make_turtle pos angle =
{
pos = pos ;
dir = expi angle
}
let make_turtle_dir pos dir =
{
pos = pos ;
dir = dir
}
let advance turt step =
{ pos = gamma turt.pos turt.dir step ;
dir = delta turt.pos turt.dir step }
let turn turtle u =
{ turtle with dir = turtle.dir *& u }
let turn_left turtle angle =
turn turtle (expi angle) (*** a comprendre pourquoi je dois inverser + et - de l'angle ***)
let turn_right turtle angle =
turn turtle (expi (-.angle)) (*** a comprendre pourquoi je dois inverser + et - de l'angle ***)
let to_tortue(x,y)=
((float x*.(2./.w) -. 1.),(1. -. float y *.(2./.h)))
(* ((float x*.(2./.w) ),(float y *.(2./.h) ))*)
let from_tortue (x,y) =
let xzoom = (w/.2.)
and yzoom = (h/.2.) in
(truncate (x*.xzoom +. xzoom), truncate(yzoom -. y*.yzoom))
let depart = to_tortue (truncate(w/.2.), truncate(h/.2.))
let origine =ref depart
(* GTK *)
let point_courant = ref (0,0)
(*let canvas = graphEdGTK.root *)
let moveto_gtk x y = point_courant := (x,y)
let tmoveto_gtk tor =
let (x,y)= from_tortue tor.pos in
point_courant := (x,y)
let tlineto_gtk tor line =
let (x',y')= from_tortue tor.pos in
point_courant := (x',y');
List.append line [(float x'); (float y') ]
let tdraw_string_gtk tor (ellipse : GnoCanvas.ellipse) =
let (x,y) = from_tortue tor.pos in
(* debug *)
if !debug_outil_tort then Format.eprintf "tdraw_string_gtk x=%d y=%d@." x y;
(* /debug *)
moveto_gtk x y;
ellipse#parent#move ~x:(float x) ~y:(float y);
ellipse#parent#set [`X (float x); `Y (float y)]
(* avance la tortue en tra�ant, d'une distance d, en un certain nombre d'etapes,
et retourne la nouvelle position de la tortue *)
let tdraw_edge_gtk tor d etapes line =
let d = d /. (float etapes) in
let rec list_points t liste = function
| 0 -> (t,liste)
| n ->let t = advance t d in
list_points t (tlineto_gtk t liste) (n-1)
in
let l = let (x,y) =from_tortue tor.pos in [(float x); (float y)] in
let t,lpoints = list_points tor l etapes in
(* debug *)
if (!debug_outil_tort)
then
(let ltext=
let rec chaine = function
|[]->""
|e::l->(string_of_float e)^" "^chaine l
in chaine lpoints in
Format.eprintf "taille %d %s @." (List.length lpoints) ltext);
(* /debug *)
let p = Array.of_list lpoints in
line#set [`POINTS p];
t
ocamlgraph-2.0.0/editor/dirTree.ml 0000644 0001750 0000144 00000005064 13735627615 015434 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
open Unix ;;
type t = {
id : int;
name : string ;
children : t list Lazy.t
} ;;
let id t = t.id
let newid = let r = ref 0 in fun () -> incr r; !r
type label = string ;;
let children t = Lazy.force t.children ;;
let label t = t.name ;;
let string_of_label s = s ;;
let is_dir path =
try (lstat path).st_kind = S_DIR
with Unix_error _ -> false ;;
let less t1 t2 = t1.name <= t2.name ;;
let rec tree_list_from_path path =
let opt_handle =
try Some(opendir path)
with Unix_error _ -> None in
match opt_handle with
| None -> []
| Some handle ->
let list = Sort.list less (tree_list_from_handle path handle) in
closedir handle ; list
and tree_list_from_handle path handle =
let opt_name =
try Some(readdir handle)
with End_of_file -> None in
match opt_name with
| None -> []
| Some name ->
let path' = path ^ "/" ^ name in
if name <> "." && name <> ".." && is_dir path' then
{ id = newid(); name = name ; children = lazy (tree_list_from_path path') } ::
tree_list_from_handle path handle
else
tree_list_from_handle path handle ;;
let from_dir path name =
try
let path' = path ^ "/" ^ name in
if is_dir path' then
{ id = newid(); name = name ;
children = lazy (tree_list_from_path path') }
else invalid_arg "DirTree.from_dir"
with _ -> failwith "DirTree.from_dir" ;;
ocamlgraph-2.0.0/editor/gtree.mli 0000644 0001750 0000144 00000002575 13735627615 015321 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(*
module T : sig
type t = DirTree.t
val root : t
end
*)
module T : sig
type t
val root : t
end
val show_tree : #GnoCanvas.group -> T.t -> int -> int -> unit
ocamlgraph-2.0.0/editor/graphEdGTK.ml 0000644 0001750 0000144 00000060070 13735627615 015754 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
open Format
open Outils_tort
open Outils_math
open Graph
(* graph data structure *)
module Gr = struct
module G = Imperative.Graph.Abstract(String)
module B = Builder.I(G)
module GmlParser =
Gml.Parse
(B)
(struct
let node l =
try
match List.assoc "id" l
with Gml.Int n -> string_of_int n | _ -> ""
with Not_found -> ""
let edge _ = ()
end)
module DotParser =
Dot.Parse
(B)
(struct
let node (id,_) _ = match id with
| Dot_ast.Ident s
| Dot_ast.Number s
| Dot_ast.String s
| Dot_ast.Html s -> s
let edge _ = ()
end)
let parse_file f =
if Filename.check_suffix f ".gml" then
GmlParser.parse f
else
DotParser.parse f
module Components = Components.Make(G)
module Dfs = Traverse.Dfs(G)
end
open Gr
open Gr.G
let debug_graphEdGTK = ref false
let trace f x = try f x with e -> eprintf "TRACE: %s@." (Printexc.to_string e); raise e
let _ = GMain.Main.init ()
let graph = ref (Gr.parse_file Sys.argv.(1))
exception Choose of V.t
type t = V.t
type label = V.t
let label x = x
let string_of_label x = V.label x
let label_of_string x = x
(* [step_from n] computes the best `distance' for solving the
dictator's problem in the complex hyperbolic plane for [n]
dictators. In a half-plane, we have to use the distance
given by [step_from (2*n)] or, better, the distance given
by [step_from (2*max(3 n))]. *)
let step_from n =
ath (tan (pi_over_4 -. pi/.float(2*n)))
(* [hspace_dist_sqr turtle] computes the square of the distance
between the origin and the half-space in front of [turtle]. *)
let hspace_dist_sqr turtle =
let (ax, ay) = turtle.pos
and (dx, dy) = turtle.dir in
(* if ax*.dx +. ay*.dy < 0.0 then 0.0 else*)
begin
let ux = dy and uy = -.dx in
let alpha = ax*.ax +. ay*.ay
and beta = 2.0*.(ax*.ux +. ay*.uy) in
if beta = 0.0 then
alpha
else
begin
let gamma = (1.0 +. alpha)/.beta in
let delta = gamma*.gamma -. 1.0 in
let sol =
if beta > 0.0
then -.gamma +. sqrt(delta)
else -.gamma -. sqrt(delta) in
let (zx, zy) = translate (ax, ay) (ux*.sol, uy*.sol) in
zx*.zx +. zy*.zy
end
end ;;
let edge v w = mem_edge !graph v w || mem_edge !graph w v
let make_subgraph l =
let gl = create () in
List.iter (fun v -> add_vertex gl v) l;
List.iter
(fun v -> List.iter (fun w -> if edge v w then add_edge gl v w) l)
l;
(* TODO: efficacite *)
gl
let order_children l =
let gl = make_subgraph l in
let scc = Components.scc_list gl in
let order_component c =
let gc = make_subgraph c in
let v = match c with
| v :: l ->
List.fold_left
(fun m v -> if out_degree gc v < out_degree gc m then v else m)
v l
| [] ->
assert false
in
let l = ref [] in
Dfs.prefix_component (fun w -> l := w :: !l) gc v;
!l
in
let scc = List.map order_component scc in
List.flatten scc
let rlimit = 0.90
let rlimit_sqr = rlimit *. rlimit
module Model = struct
open Gobject.Data
let cols = new GTree.column_list
let name = cols#add string
let vertex = cols#add caml
let model = GTree.tree_store cols
let rows = Hashtbl.create 97
let add_vertex v =
let row = model#append () in
model#set ~row ~column:name (V.label v);
model#set ~row ~column:vertex v;
Hashtbl.add rows v row;
row
let add_edge_1 row_v w =
let row = model#append ~parent:row_v () in
model#set ~row ~column:name (V.label w)
let reset () =
Hashtbl.clear rows;
model#clear ();
iter_vertex
(fun v ->
let row = add_vertex v in
iter_succ (add_edge_1 row) !graph v)
!graph
let add_edge v w =
let row_v = Hashtbl.find rows v in
add_edge_1 row_v w;
if not is_directed then
let row_w = Hashtbl.find rows w in
add_edge_1 row_w v
end
let () = Model.reset ()
let model = ref Model.model
open GtkTree
(* Ouverture fenetre GTK *)
let window = GWindow.window ~border_width: 10 ~title:"GraphEd" ~position: `CENTER ()
(* une Verticale Box pour contenir le menu de la fenetre principale *)
let v_box = GPack.vbox ~homogeneous:false ~spacing:30 ~packing:window#add ()
(* la barre de Menu ajoutée dans la V_box *)
let menu_bar = GMenu.menu_bar ~packing:v_box#pack ()
let h_box = GPack.hbox ~homogeneous:false ~spacing:30 ~packing:v_box#add ()
let sw = GBin.scrolled_window ~shadow_type:`ETCHED_IN ~hpolicy:`NEVER
~vpolicy:`AUTOMATIC ~packing:h_box#add ()
let canvas = GnoCanvas.canvas ~aa:true ~width:(truncate w) ~height:(truncate h) ~packing:h_box#add ()
let canvas_root = canvas#root
let choose_root () =
try
iter_vertex (fun v -> raise (Choose v)) !graph;
Format.eprintf "empty graph@."; exit 0
with Choose v ->
v
let root = ref (choose_root ())
let load_graph f =
graph := parse_file f;
Model.reset ();
root := choose_root ()
module Vset = Set.Make(V)
let vset_of_list = List.fold_left (fun s x -> Vset.add x s) Vset.empty
module H = Hashtbl.Make(V)
(* table donnant pour chaque noeud sa profondeur et sa tortue *)
let pos = H.create 97
(* table des ellipses existantes *)
let ellipses = H.create 97
let tdraw_string_gtk v tor canvas =
let ellipse =
try
let item = H.find ellipses v in
item#parent#show();
item
with Not_found ->
let s = string_of_label v in
let (w,h) = (40,20) in
let noeud = GnoCanvas.group ~x:0.0 ~y:0.0 canvas in
let ellipse = GnoCanvas.ellipse
~props:[ `X1 ( float_of_int (-w/2)); `Y1 (float_of_int (-h/2));
`X2 (float_of_int (w/2)) ; `Y2 ( float_of_int (h/2)) ;
`FILL_COLOR "grey" ; `OUTLINE_COLOR "black" ;
`WIDTH_PIXELS 0 ] noeud
in
let texte = GnoCanvas.text ~props:[`X 0.0; `Y 0.0 ; `TEXT s;
`FILL_COLOR "blue"] noeud
in
let w2 = texte#text_width in
if w2 > float_of_int w
then
ellipse#set [ `X1 (-.( w2+.6.)/.2.); `X2 ((w2+.6.)/.2.)];
H.add ellipses v ellipse;
ellipse
in
tdraw_string_gtk tor ellipse;
ellipse
module H2 =
Hashtbl.Make
(struct
type t = V.t * V.t
let hash (v,w) = Hashtbl.hash (V.hash v, V.hash w)
let equal (v1,w1) (v2,w2) = V.equal v1 v2 && V.equal w1 w2
end)
let grey_edges = H2.create 97
let black_edges = H2.create 97
let draw_grey_edge vw tv tw canvas =
(* debug *)
if !debug_graphEdGTK
then
(
let (v,w)=
let (v,w) = vw in
(string_of_label v, string_of_label w) in
eprintf "tortue %s \t tortue %s@." v w
);
(* /debug *)
let p,l =
try
let _,l as pl = H2.find grey_edges vw in
l#show();
pl
with Not_found ->
let p = GnomeCanvas.PathDef.new_path () in
let l = GnoCanvas.bpath canvas
~props:[ `BPATH p ; `OUTLINE_COLOR "SlateGrey" ; `WIDTH_PIXELS 1 ] in
l#lower_to_bottom ();
H2.add grey_edges vw (p,l);
p,l
in
let (x,y) = let (x ,y ) = from_tortue tv.pos in ((float_of_int x),(float_of_int y)) in
let (x',y') = let (x',y') = from_tortue tw.pos in ((float_of_int x'),(float_of_int y')) in
let rapport = 1.95 in
GnomeCanvas.PathDef.reset p;
GnomeCanvas.PathDef.moveto p x y ;
GnomeCanvas.PathDef.curveto p ((x+. x')/.rapport) ((y +. y')/.rapport)
((x +.x')/.rapport) ((y +. y')/.rapport)
x' y';
l#set [`BPATH p]
let tdraw_edge_gtk vw t distance etapes canvas =
let line =
try
let l = H2.find black_edges vw in
l#show ();
l
with Not_found ->
let color = "black" in
let l = GnoCanvas.line canvas ~props:[ `FILL_COLOR color ;
`WIDTH_PIXELS 1; `SMOOTH true]
in
H2.add black_edges vw l;
l
in
tdraw_edge_gtk t distance etapes line
let color_change_intern_edge color node =
iter_edges
(fun _ w ->
try
let _,n = H2.find grey_edges (node,w) in
n#set [`OUTLINE_COLOR color]
with Not_found ->
try
let _,n = H2.find grey_edges (w,node) in
n#set [`OUTLINE_COLOR color]
with Not_found ->
()
)
!graph
let color_change_direct_edge color node =
iter_succ
(fun w ->
try
let n = H2.find black_edges (node,w) in
n#set [`FILL_COLOR color]
with Not_found ->
try
let n = H2.find black_edges (w,node) in
n#set [`FILL_COLOR color]
with Not_found ->
()
)
!graph node
let select = ref None
let is_selected_node v = match !select with
| None -> false
| Some (w,_) -> V.equal v w
let step = ref 0
let rec draw_graph depth noeud tortue canvas =
if !debug_graphEdGTK
then
(let (x,y) = tortue.pos in
Format.eprintf " hspace : %f\t pos : %f %f \tnoeud : %s@."
( hspace_dist_sqr tortue )x y(string_of_label noeud);
);
if hspace_dist_sqr tortue <= rlimit_sqr then
begin
H.replace pos noeud (depth, Some tortue);
tmoveto_gtk tortue;
(* draw label *)
let ellipse = tdraw_string_gtk noeud tortue canvas in
let sigs = ellipse#parent#connect in
let _ = sigs#event (drag_label noeud ellipse) in
let l = succ !graph noeud in
let l = List.filter (fun x -> not (H.mem pos x) ) l in
List.iter (fun w -> H.add pos w (depth+1, None)) l;
let l = order_children l in
let n = List.length l in
if n > 0 then
begin
let distance = step_from (max 3 n)
and angle = (if depth = 0 then 2. else 1.) *. pi /. (float_of_int n) in
let tortue = if depth = 0 then tortue else turn_right tortue ((pi -. angle) /. 2.) in
let _ = draw_edges noeud (depth+1) tortue distance angle canvas l in
()
end;
ellipse#parent#raise_to_top();
end
else if noeud <> !root
then
try
let ellipse = tdraw_string_gtk noeud tortue canvas in
ellipse#parent#hide();
iter_succ
(fun w ->
try
ignore (H.find pos w)
with Not_found ->
try
let n = H2.find black_edges (noeud,w) in
n#hide()
with Not_found ->
try
let n = H2.find black_edges (w,noeud) in
n#hide()
with Not_found ->
()
)
!graph noeud
(* H.remove pos noeud*)
with Not_found -> Format.eprintf"je devrai pas etre la@."
and draw_edges noeud depth t distance angle canvas= function
| [] ->
[]
| v :: l ->
let etapes = 10 in
let tv = tdraw_edge_gtk (noeud,v) t distance etapes canvas in
(*if hspace_dist_sqr t <= rlimit_sqr then H.add pos v (depth,tv);*)
let t = turn_left t angle in
let l = (v,tv) :: draw_edges noeud depth t distance angle canvas l in
draw_graph depth v tv canvas;
l
and drag_label noeud item ev =
begin match ev with
| `ENTER_NOTIFY _ ->
if not (is_selected_node noeud)
then begin
item#set [ `FILL_COLOR "steelblue" ];
color_change_intern_edge "blue" noeud ;
color_change_direct_edge "blue" noeud
end;
| `LEAVE_NOTIFY ev ->
if not (is_selected_node noeud)
then begin
let state = GdkEvent.Crossing.state ev in
if not (Gdk.Convert.test_modifier `BUTTON1 state)
then item#set [ `FILL_COLOR "grey" ; ];
color_change_intern_edge "SlateGrey" noeud ;
color_change_direct_edge "black" noeud;
begin match !select with
| None -> ()
| Some (n,i) -> begin
color_change_intern_edge "red" n ;
color_change_direct_edge "red" n
end
end;
end
| `BUTTON_RELEASE ev ->
item#parent#ungrab (GdkEvent.Button.time ev)
| `MOTION_NOTIFY ev ->
incr step;
let state = GdkEvent.Motion.state ev in
if Gdk.Convert.test_modifier `BUTTON1 state && !step mod 10 = 0 then
begin
let curs = Gdk.Cursor.create `FLEUR in
item#parent#grab [`POINTER_MOTION; `BUTTON_RELEASE] curs (GdkEvent.Button.time ev);
let ibounds = item#parent#get_bounds in
let z1 = to_tortue(truncate((ibounds.(0)+.ibounds.(2))/.2.),
truncate((ibounds.(1)+. ibounds.(3))/.2.)) in
let mx = GdkEvent.Motion.x ev in
let my = GdkEvent.Motion.y ev in
let z2 = to_tortue (truncate mx, truncate my) in
let tmp = !origine in
let (x,y) = drag_origin !origine z1 z2 in
origine := (x,y);
let tor = make_turtle !origine 0.0 in
if hspace_dist_sqr tor <= rlimit_sqr
then begin
draw tor canvas_root;
if !step mod 15 = 0 then
canvas_root#canvas#update_now ()
end else
origine := tmp
end
| `TWO_BUTTON_PRESS ev->
if (GdkEvent.Button.button ev) = 1
then selectionner_noeud noeud item;
| `BUTTON_PRESS ev ->
if (GdkEvent.Button.button ev) = 1
then deselectionner_noeud noeud item ;
if (GdkEvent.Button.button ev) = 3
then
begin
let loc_menu = GMenu.menu () in
let factory =
new GMenu.factory loc_menu in
ignore (factory#add_item " Ajouter un successeur" ~callback: (ajout_successeur noeud));
begin match !select with
| None -> ()
| Some (n,_) ->
if not(V.equal n noeud)
then begin
ignore (factory#add_item " Ajouter une arrête" ~callback: (ajout_arrete n noeud));
end
end;
loc_menu#popup
~button:3
~time:(GdkEvent.Button.time ev);
end
| _ ->
()
end;
true
and ajout_successeur noeud () =
let window = GWindow.window ~title: "Choix du nom du label" ~width: 300 ~height: 50 () in
let vbox = GPack.vbox ~packing: window#add () in
let entry = GEdit.entry ~max_length: 50 ~packing: vbox#add () in
entry#set_text "Label";
entry#select_region ~start:0 ~stop:entry#text_length;
window#show ();
let _ = entry#connect#activate
~callback: (fun () ->
let text = entry#text in
let label = label_of_string text in
let vertex = V.create label in
add_vertex !graph vertex;
add_edge !graph noeud vertex;
window#destroy ();
ignore (Model.add_vertex vertex);
Model.add_edge noeud vertex;
let tor = make_turtle !origine 0.0 in
draw tor canvas_root)
in
()
and ajout_arrete n1 n2 () =
if not( edge n1 n2)
then begin
add_edge !graph n1 n2;
Model.add_edge n1 n2;
let tor = make_turtle !origine 0.0 in
draw tor canvas_root
end
and selectionner_noeud noeud item=
begin
begin match !select with
| None -> ()
| Some (n,i) -> begin
i#set [ `FILL_COLOR "grey" ; ];
color_change_intern_edge "SlateGrey" n ;
color_change_direct_edge "black" n
end
end;
select := Some (noeud, item);
item#set [ `FILL_COLOR "red" ];
color_change_intern_edge "red" noeud ;
color_change_direct_edge "red" noeud
end
and deselectionner_noeud noeud item =
begin
if is_selected_node noeud
then
begin
item#set [ `FILL_COLOR "steelblue" ];
color_change_intern_edge "blue" noeud ;
color_change_direct_edge "blue" noeud
end
else
match !select with
| None -> ()
| Some (n,i) ->
begin
i#set [ `FILL_COLOR "grey" ; ];
color_change_intern_edge "SlateGrey" n ;
color_change_direct_edge "black" n;
(*
color_change_intern_edge "red" n ;
color_change_direct_edge "red" n
*)
end;
end;
select := None;
and draw tortue canvas =
H.clear pos;
canvas#hide();
draw_graph 0 !root tortue canvas;
(* H.iter (fun v ev -> if not (H.mem pos v) then ev#parent#hide ()) ellipses;
*)
(* draw intern edges *)
iter_edges
(fun v w ->
try
begin match H.find pos v, H.find pos w with
| (lv, Some tv), (lw, Some tw) ->
if abs (lw - lv) <> 1 && (lv <> 0 || lw <> 0)
then
begin
(* debug *)
if !debug_graphEdGTK
then
(Format.eprintf "tortue : %s\t\t\t tortue : %s@." (string_of_label v) (string_of_label w);
let (x ,y ) = from_tortue tv.pos
and (x',y') = from_tortue tw.pos in
Format.eprintf "pos x:%d y:%d \t pos x:%d y:%d@." x y x' y';
);
(* /debug *)
ignore(draw_grey_edge (v,w) tv tw canvas)
end
else
raise Not_found
| (_, None), _ | _, (_, None) ->
raise Not_found
end
with Not_found ->
begin
(* debug *)
if !debug_graphEdGTK then
Format.eprintf"Je vais tenter de détruire un edge@.";
(* /debug *)
try
let _,l = H2.find grey_edges (w,v) in l#hide();
(* debug *)
if !debug_graphEdGTK then Format.eprintf"J'ai effacé un grey edge@.";
(* /debug *)
with Not_found -> ();
try
let _,l = H2.find grey_edges (v,w) in l#hide();
(* debug *)
if !debug_graphEdGTK then Format.eprintf"J'ai effacé un grey edge@.";
(* /debug *)
with Not_found -> ();
end
)
!graph;
canvas#show()
let ajout_noeud () =
let window = GWindow.window ~title: "Choix du nom du label" ~width: 300 ~height: 50 () in
let vbox = GPack.vbox ~packing: window#add () in
let entry = GEdit.entry ~max_length: 50 ~packing: vbox#add () in
entry#set_text "Label";
entry#select_region ~start:0 ~stop:entry#text_length;
window#show ();
let _ = entry#connect#activate
~callback: (fun () ->
let text = entry#text in
let label = label_of_string text in
let vertex = V.create label in
add_vertex !graph vertex;
window#destroy ();
ignore (Model.add_vertex vertex);
let tor = make_turtle !origine 0.0 in
draw tor canvas_root)
in
()
let canvas_event ev =
(* Format.eprintf "toto suis-je empty ? : %b@." (is_empty !graph);
*)
begin match ev with
| `BUTTON_PRESS ev ->
if (GdkEvent.Button.button ev) = 1
then begin
match !select with
| None -> ()
| Some(noeud,item) ->
deselectionner_noeud noeud item ;
end;
if (GdkEvent.Button.button ev) = 3 (* && (is_empty !graph)*)
then
begin
let loc_menu = GMenu.menu () in
let factory =
new GMenu.factory loc_menu in
ignore (factory#add_item " Ajouter un noeud" ~callback: ajout_noeud);
loc_menu#popup
~button:3
~time:(GdkEvent.Button.time ev);
end
| _ ->
()
end;
true
let _ = canvas#root#connect#event (canvas_event)
let node_selection ~(model : GTree.tree_store) path =
let row = model#get_iter path in
let v = model#get ~row ~column: Model.vertex in
root := v;
let tortue =
origine := depart;
let (x,y) = from_tortue !origine in
moveto_gtk x y;
make_turtle !origine 0.0;
in
let l = canvas_root#get_items in
Format.eprintf "il y a %d elements dans le canvas @." (List.length l);
List.iter (fun v -> v#hide()) l;
draw tortue canvas_root
let add_columns ~(view : GTree.view) ~model =
let renderer = GTree.cell_renderer_text [`XALIGN 0.] in
let vc =
GTree.view_column ~title:"Nodes" ~renderer:(renderer, ["text", Model.name]) ()
in
ignore (view#append_column vc);
vc#set_sizing `FIXED;
vc#set_fixed_width 100;
(* vc#set_resizable true;*)
vc#set_sizing `GROW_ONLY;
view#selection#connect#after#changed ~callback:
begin fun () ->
List.iter
(fun p -> node_selection ~model p)
view#selection#get_selected_rows;
end
let _ = window#connect#destroy~callback:GMain.Main.quit
let treeview = GTree.view ~model:!model ~packing:sw#add ()
let () = treeview#set_rules_hint true
let () = treeview#selection#set_mode `MULTIPLE
let _ = add_columns ~view:treeview ~model:!model
(*let _ = treeview#misc#connect#realize ~callback:treeview#expand_all*)
let reset_table_and_canvas () =
let l = canvas_root#get_items in
List.iter (fun v -> trace v#destroy ()) l;
H2.clear grey_edges;
H2.clear black_edges;
H.clear ellipses;
H.clear pos;
origine := depart
let open_graph() =
let default d = function
| None -> d
| Some v -> v
in
let all_files () =
let f = GFile.filter ~name:"All" () in
f#add_pattern "*" ;
f
in
let graph_filter () =
GFile.filter
~name:"Fichier de graphes"
~patterns:[ "*.dot"; "*.gml" ] ()
in
let ask_for_file parent =
let dialog = GWindow.file_chooser_dialog
~action:`OPEN
~title:"Ouvrir un fichier"
~parent () in
dialog#add_button_stock `CANCEL `CANCEL ;
dialog#add_select_button_stock `OPEN `OPEN ;
dialog#add_filter (graph_filter ()) ;
dialog#add_filter (all_files ()) ;
let f = match dialog#run () with
| `OPEN ->default "" dialog#filename
| `DELETE_EVENT | `CANCEL -> ""
in
dialog#destroy ();
f
in
let fichier = ask_for_file window in
if fichier <> ""
then
begin
load_graph fichier;
reset_table_and_canvas ();
let tortue =
let (x,y) = from_tortue !origine in
moveto_gtk x y;
make_turtle !origine 0.0
in
draw tortue canvas_root
end
let new_graph () =
graph := create ();
model := Model.model;
Model.reset();
reset_table_and_canvas ()
let create_menu label menubar =
let item = GMenu.menu_item ~label ~packing:menubar#append () in
GMenu.menu ~packing:item#set_submenu ()
let print msg () =
print_endline msg;
flush stdout
(* le menu file : la description puis l'ajout au menu_bar *)
let menu_files =
[
`I ("_New Graph", new_graph);
`I ("_Open Graph", open_graph);
`I ("_Save Graph", print "todo save graph");
`I ("Save Graph _As ...", print "todo save graph as...");
`S;
`I ("_Quit", GMain.Main.quit )
]
let menu =
create_menu "File" menu_bar
let _ = GToolbox.build_menu menu ~entries:menu_files
(* la zone d'affichage du graph, le canvas *)
let tortue =
let (x,y) = from_tortue !origine in
moveto_gtk x y;
make_turtle !origine 0.0
let () = canvas#set_scroll_region 0. 0. w h
(* l'affichage de la fenetre principale *)
let () = window#show ()
let _ = draw tortue canvas_root
let () = GMain.Main.main ()
ocamlgraph-2.0.0/editor/tests/ 0000755 0001750 0000144 00000000000 13735627615 014641 5 ustar rt users ocamlgraph-2.0.0/editor/tests/ring_100.gml 0000644 0001750 0000144 00000021255 13735627615 016666 0 ustar rt users graph [
node [
id 1
label 0
]
node [
id 2
label 1
]
node [
id 3
label 2
]
node [
id 4
label 3
]
node [
id 5
label 4
]
node [
id 6
label 5
]
node [
id 7
label 6
]
node [
id 8
label 7
]
node [
id 9
label 8
]
node [
id 10
label 9
]
node [
id 11
label 10
]
node [
id 12
label 11
]
node [
id 13
label 12
]
node [
id 14
label 13
]
node [
id 15
label 14
]
node [
id 16
label 15
]
node [
id 17
label 16
]
node [
id 18
label 17
]
node [
id 19
label 18
]
node [
id 20
label 19
]
node [
id 21
label 20
]
node [
id 22
label 21
]
node [
id 23
label 22
]
node [
id 24
label 23
]
node [
id 25
label 24
]
node [
id 26
label 25
]
node [
id 27
label 26
]
node [
id 28
label 27
]
node [
id 29
label 28
]
node [
id 30
label 29
]
node [
id 31
label 30
]
node [
id 32
label 31
]
node [
id 33
label 32
]
node [
id 34
label 33
]
node [
id 35
label 34
]
node [
id 36
label 35
]
node [
id 37
label 36
]
node [
id 38
label 37
]
node [
id 39
label 38
]
node [
id 40
label 39
]
node [
id 41
label 40
]
node [
id 42
label 41
]
node [
id 43
label 42
]
node [
id 44
label 43
]
node [
id 45
label 44
]
node [
id 46
label 45
]
node [
id 47
label 46
]
node [
id 48
label 47
]
node [
id 49
label 48
]
node [
id 50
label 49
]
node [
id 51
label 50
]
node [
id 52
label 51
]
node [
id 53
label 52
]
node [
id 54
label 53
]
node [
id 55
label 54
]
node [
id 56
label 55
]
node [
id 57
label 56
]
node [
id 58
label 57
]
node [
id 59
label 58
]
node [
id 60
label 59
]
node [
id 61
label 60
]
node [
id 62
label 61
]
node [
id 63
label 62
]
node [
id 64
label 63
]
node [
id 65
label 64
]
node [
id 66
label 65
]
node [
id 67
label 66
]
node [
id 68
label 67
]
node [
id 69
label 68
]
node [
id 70
label 69
]
node [
id 71
label 70
]
node [
id 72
label 71
]
node [
id 73
label 72
]
node [
id 74
label 73
]
node [
id 75
label 74
]
node [
id 76
label 75
]
node [
id 77
label 76
]
node [
id 78
label 77
]
node [
id 79
label 78
]
node [
id 80
label 79
]
node [
id 81
label 80
]
node [
id 82
label 81
]
node [
id 83
label 82
]
node [
id 84
label 83
]
node [
id 85
label 84
]
node [
id 86
label 85
]
node [
id 87
label 86
]
node [
id 88
label 87
]
node [
id 89
label 88
]
node [
id 90
label 89
]
node [
id 91
label 90
]
node [
id 92
label 91
]
node [
id 93
label 92
]
node [
id 94
label 93
]
node [
id 95
label 94
]
node [
id 96
label 95
]
node [
id 97
label 96
]
node [
id 98
label 97
]
node [
id 99
label 98
]
node [
id 100
label 99
]
edge [
source 2
target 1
label 0
]
edge [
source 3
target 2
label 0
]
edge [
source 4
target 3
label 0
]
edge [
source 5
target 4
label 0
]
edge [
source 6
target 5
label 0
]
edge [
source 7
target 6
label 0
]
edge [
source 8
target 7
label 0
]
edge [
source 9
target 8
label 0
]
edge [
source 10
target 9
label 0
]
edge [
source 11
target 10
label 0
]
edge [
source 12
target 11
label 0
]
edge [
source 13
target 12
label 0
]
edge [
source 14
target 13
label 0
]
edge [
source 15
target 14
label 0
]
edge [
source 16
target 15
label 0
]
edge [
source 17
target 16
label 0
]
edge [
source 18
target 17
label 0
]
edge [
source 19
target 18
label 0
]
edge [
source 20
target 19
label 0
]
edge [
source 21
target 20
label 0
]
edge [
source 22
target 21
label 0
]
edge [
source 23
target 22
label 0
]
edge [
source 24
target 23
label 0
]
edge [
source 25
target 24
label 0
]
edge [
source 26
target 25
label 0
]
edge [
source 27
target 26
label 0
]
edge [
source 28
target 27
label 0
]
edge [
source 29
target 28
label 0
]
edge [
source 30
target 29
label 0
]
edge [
source 31
target 30
label 0
]
edge [
source 32
target 31
label 0
]
edge [
source 33
target 32
label 0
]
edge [
source 34
target 33
label 0
]
edge [
source 35
target 34
label 0
]
edge [
source 36
target 35
label 0
]
edge [
source 37
target 36
label 0
]
edge [
source 38
target 37
label 0
]
edge [
source 39
target 38
label 0
]
edge [
source 40
target 39
label 0
]
edge [
source 41
target 40
label 0
]
edge [
source 42
target 41
label 0
]
edge [
source 43
target 42
label 0
]
edge [
source 44
target 43
label 0
]
edge [
source 45
target 44
label 0
]
edge [
source 46
target 45
label 0
]
edge [
source 47
target 46
label 0
]
edge [
source 48
target 47
label 0
]
edge [
source 49
target 48
label 0
]
edge [
source 50
target 49
label 0
]
edge [
source 51
target 50
label 0
]
edge [
source 52
target 51
label 0
]
edge [
source 53
target 52
label 0
]
edge [
source 54
target 53
label 0
]
edge [
source 55
target 54
label 0
]
edge [
source 56
target 55
label 0
]
edge [
source 57
target 56
label 0
]
edge [
source 58
target 57
label 0
]
edge [
source 59
target 58
label 0
]
edge [
source 60
target 59
label 0
]
edge [
source 61
target 60
label 0
]
edge [
source 62
target 61
label 0
]
edge [
source 63
target 62
label 0
]
edge [
source 64
target 63
label 0
]
edge [
source 65
target 64
label 0
]
edge [
source 66
target 65
label 0
]
edge [
source 67
target 66
label 0
]
edge [
source 68
target 67
label 0
]
edge [
source 69
target 68
label 0
]
edge [
source 70
target 69
label 0
]
edge [
source 71
target 70
label 0
]
edge [
source 72
target 71
label 0
]
edge [
source 73
target 72
label 0
]
edge [
source 74
target 73
label 0
]
edge [
source 75
target 74
label 0
]
edge [
source 76
target 75
label 0
]
edge [
source 77
target 76
label 0
]
edge [
source 78
target 77
label 0
]
edge [
source 79
target 78
label 0
]
edge [
source 80
target 79
label 0
]
edge [
source 81
target 80
label 0
]
edge [
source 82
target 81
label 0
]
edge [
source 83
target 82
label 0
]
edge [
source 84
target 83
label 0
]
edge [
source 85
target 84
label 0
]
edge [
source 86
target 85
label 0
]
edge [
source 87
target 86
label 0
]
edge [
source 88
target 87
label 0
]
edge [
source 89
target 88
label 0
]
edge [
source 90
target 89
label 0
]
edge [
source 91
target 90
label 0
]
edge [
source 92
target 91
label 0
]
edge [
source 93
target 92
label 0
]
edge [
source 94
target 93
label 0
]
edge [
source 95
target 94
label 0
]
edge [
source 96
target 95
label 0
]
edge [
source 97
target 96
label 0
]
edge [
source 98
target 97
label 0
]
edge [
source 99
target 98
label 0
]
edge [
source 100
target 1
label 0
]
edge [
source 100
target 99
label 0
]
]
ocamlgraph-2.0.0/editor/tests/de_bruijn4.gml 0000644 0001750 0000144 00000004200 13735627615 017363 0 ustar rt users graph [
node [
id 1
label 0
]
node [
id 2
label 1
]
node [
id 3
label 2
]
node [
id 4
label 3
]
node [
id 5
label 4
]
node [
id 6
label 5
]
node [
id 7
label 6
]
node [
id 8
label 7
]
node [
id 9
label 8
]
node [
id 10
label 9
]
node [
id 11
label 10
]
node [
id 12
label 11
]
node [
id 13
label 12
]
node [
id 14
label 13
]
node [
id 15
label 14
]
node [
id 16
label 15
]
edge [
source 1
target 1
label 0
]
edge [
source 2
target 1
label 0
]
edge [
source 3
target 2
label 0
]
edge [
source 4
target 2
label 0
]
edge [
source 5
target 3
label 0
]
edge [
source 6
target 3
label 0
]
edge [
source 7
target 4
label 0
]
edge [
source 8
target 4
label 0
]
edge [
source 9
target 1
label 0
]
edge [
source 9
target 2
label 0
]
edge [
source 9
target 5
label 0
]
edge [
source 10
target 3
label 0
]
edge [
source 10
target 4
label 0
]
edge [
source 10
target 5
label 0
]
edge [
source 11
target 5
label 0
]
edge [
source 11
target 6
label 0
]
edge [
source 12
target 6
label 0
]
edge [
source 12
target 7
label 0
]
edge [
source 12
target 8
label 0
]
edge [
source 13
target 7
label 0
]
edge [
source 13
target 9
label 0
]
edge [
source 13
target 10
label 0
]
edge [
source 14
target 7
label 0
]
edge [
source 14
target 11
label 0
]
edge [
source 14
target 12
label 0
]
edge [
source 15
target 8
label 0
]
edge [
source 15
target 13
label 0
]
edge [
source 15
target 14
label 0
]
edge [
source 16
target 8
label 0
]
edge [
source 16
target 15
label 0
]
edge [
source 16
target 16
label 0
]
]
ocamlgraph-2.0.0/editor/tests/full20.gml 0000644 0001750 0000144 00000026606 13735627615 016460 0 ustar rt users graph [
node [
id 1
label 1
]
node [
id 2
label 2
]
node [
id 3
label 3
]
node [
id 4
label 4
]
node [
id 5
label 5
]
node [
id 6
label 6
]
node [
id 7
label 7
]
node [
id 8
label 8
]
node [
id 9
label 9
]
node [
id 10
label 10
]
node [
id 11
label 11
]
node [
id 12
label 12
]
node [
id 13
label 13
]
node [
id 14
label 14
]
node [
id 15
label 15
]
node [
id 16
label 16
]
node [
id 17
label 17
]
node [
id 18
label 18
]
node [
id 19
label 19
]
node [
id 20
label 20
]
edge [
source 1
target 1
label 0
]
edge [
source 2
target 1
label 0
]
edge [
source 2
target 2
label 0
]
edge [
source 3
target 1
label 0
]
edge [
source 3
target 2
label 0
]
edge [
source 3
target 3
label 0
]
edge [
source 4
target 1
label 0
]
edge [
source 4
target 2
label 0
]
edge [
source 4
target 3
label 0
]
edge [
source 4
target 4
label 0
]
edge [
source 5
target 1
label 0
]
edge [
source 5
target 2
label 0
]
edge [
source 5
target 3
label 0
]
edge [
source 5
target 4
label 0
]
edge [
source 5
target 5
label 0
]
edge [
source 6
target 1
label 0
]
edge [
source 6
target 2
label 0
]
edge [
source 6
target 3
label 0
]
edge [
source 6
target 4
label 0
]
edge [
source 6
target 5
label 0
]
edge [
source 6
target 6
label 0
]
edge [
source 7
target 1
label 0
]
edge [
source 7
target 2
label 0
]
edge [
source 7
target 3
label 0
]
edge [
source 7
target 4
label 0
]
edge [
source 7
target 5
label 0
]
edge [
source 7
target 6
label 0
]
edge [
source 7
target 7
label 0
]
edge [
source 8
target 1
label 0
]
edge [
source 8
target 2
label 0
]
edge [
source 8
target 3
label 0
]
edge [
source 8
target 4
label 0
]
edge [
source 8
target 5
label 0
]
edge [
source 8
target 6
label 0
]
edge [
source 8
target 7
label 0
]
edge [
source 8
target 8
label 0
]
edge [
source 9
target 1
label 0
]
edge [
source 9
target 2
label 0
]
edge [
source 9
target 3
label 0
]
edge [
source 9
target 4
label 0
]
edge [
source 9
target 5
label 0
]
edge [
source 9
target 6
label 0
]
edge [
source 9
target 7
label 0
]
edge [
source 9
target 8
label 0
]
edge [
source 9
target 9
label 0
]
edge [
source 10
target 1
label 0
]
edge [
source 10
target 2
label 0
]
edge [
source 10
target 3
label 0
]
edge [
source 10
target 4
label 0
]
edge [
source 10
target 5
label 0
]
edge [
source 10
target 6
label 0
]
edge [
source 10
target 7
label 0
]
edge [
source 10
target 8
label 0
]
edge [
source 10
target 9
label 0
]
edge [
source 10
target 10
label 0
]
edge [
source 11
target 1
label 0
]
edge [
source 11
target 2
label 0
]
edge [
source 11
target 3
label 0
]
edge [
source 11
target 4
label 0
]
edge [
source 11
target 5
label 0
]
edge [
source 11
target 6
label 0
]
edge [
source 11
target 7
label 0
]
edge [
source 11
target 8
label 0
]
edge [
source 11
target 9
label 0
]
edge [
source 11
target 10
label 0
]
edge [
source 11
target 11
label 0
]
edge [
source 12
target 1
label 0
]
edge [
source 12
target 2
label 0
]
edge [
source 12
target 3
label 0
]
edge [
source 12
target 4
label 0
]
edge [
source 12
target 5
label 0
]
edge [
source 12
target 6
label 0
]
edge [
source 12
target 7
label 0
]
edge [
source 12
target 8
label 0
]
edge [
source 12
target 9
label 0
]
edge [
source 12
target 10
label 0
]
edge [
source 12
target 11
label 0
]
edge [
source 12
target 12
label 0
]
edge [
source 13
target 1
label 0
]
edge [
source 13
target 2
label 0
]
edge [
source 13
target 3
label 0
]
edge [
source 13
target 4
label 0
]
edge [
source 13
target 5
label 0
]
edge [
source 13
target 6
label 0
]
edge [
source 13
target 7
label 0
]
edge [
source 13
target 8
label 0
]
edge [
source 13
target 9
label 0
]
edge [
source 13
target 10
label 0
]
edge [
source 13
target 11
label 0
]
edge [
source 13
target 12
label 0
]
edge [
source 13
target 13
label 0
]
edge [
source 14
target 1
label 0
]
edge [
source 14
target 2
label 0
]
edge [
source 14
target 3
label 0
]
edge [
source 14
target 4
label 0
]
edge [
source 14
target 5
label 0
]
edge [
source 14
target 6
label 0
]
edge [
source 14
target 7
label 0
]
edge [
source 14
target 8
label 0
]
edge [
source 14
target 9
label 0
]
edge [
source 14
target 10
label 0
]
edge [
source 14
target 11
label 0
]
edge [
source 14
target 12
label 0
]
edge [
source 14
target 13
label 0
]
edge [
source 14
target 14
label 0
]
edge [
source 15
target 1
label 0
]
edge [
source 15
target 2
label 0
]
edge [
source 15
target 3
label 0
]
edge [
source 15
target 4
label 0
]
edge [
source 15
target 5
label 0
]
edge [
source 15
target 6
label 0
]
edge [
source 15
target 7
label 0
]
edge [
source 15
target 8
label 0
]
edge [
source 15
target 9
label 0
]
edge [
source 15
target 10
label 0
]
edge [
source 15
target 11
label 0
]
edge [
source 15
target 12
label 0
]
edge [
source 15
target 13
label 0
]
edge [
source 15
target 14
label 0
]
edge [
source 15
target 15
label 0
]
edge [
source 16
target 1
label 0
]
edge [
source 16
target 2
label 0
]
edge [
source 16
target 3
label 0
]
edge [
source 16
target 4
label 0
]
edge [
source 16
target 5
label 0
]
edge [
source 16
target 6
label 0
]
edge [
source 16
target 7
label 0
]
edge [
source 16
target 8
label 0
]
edge [
source 16
target 9
label 0
]
edge [
source 16
target 10
label 0
]
edge [
source 16
target 11
label 0
]
edge [
source 16
target 12
label 0
]
edge [
source 16
target 13
label 0
]
edge [
source 16
target 14
label 0
]
edge [
source 16
target 15
label 0
]
edge [
source 16
target 16
label 0
]
edge [
source 17
target 1
label 0
]
edge [
source 17
target 2
label 0
]
edge [
source 17
target 3
label 0
]
edge [
source 17
target 4
label 0
]
edge [
source 17
target 5
label 0
]
edge [
source 17
target 6
label 0
]
edge [
source 17
target 7
label 0
]
edge [
source 17
target 8
label 0
]
edge [
source 17
target 9
label 0
]
edge [
source 17
target 10
label 0
]
edge [
source 17
target 11
label 0
]
edge [
source 17
target 12
label 0
]
edge [
source 17
target 13
label 0
]
edge [
source 17
target 14
label 0
]
edge [
source 17
target 15
label 0
]
edge [
source 17
target 16
label 0
]
edge [
source 17
target 17
label 0
]
edge [
source 18
target 1
label 0
]
edge [
source 18
target 2
label 0
]
edge [
source 18
target 3
label 0
]
edge [
source 18
target 4
label 0
]
edge [
source 18
target 5
label 0
]
edge [
source 18
target 6
label 0
]
edge [
source 18
target 7
label 0
]
edge [
source 18
target 8
label 0
]
edge [
source 18
target 9
label 0
]
edge [
source 18
target 10
label 0
]
edge [
source 18
target 11
label 0
]
edge [
source 18
target 12
label 0
]
edge [
source 18
target 13
label 0
]
edge [
source 18
target 14
label 0
]
edge [
source 18
target 15
label 0
]
edge [
source 18
target 16
label 0
]
edge [
source 18
target 17
label 0
]
edge [
source 18
target 18
label 0
]
edge [
source 19
target 1
label 0
]
edge [
source 19
target 2
label 0
]
edge [
source 19
target 3
label 0
]
edge [
source 19
target 4
label 0
]
edge [
source 19
target 5
label 0
]
edge [
source 19
target 6
label 0
]
edge [
source 19
target 7
label 0
]
edge [
source 19
target 8
label 0
]
edge [
source 19
target 9
label 0
]
edge [
source 19
target 10
label 0
]
edge [
source 19
target 11
label 0
]
edge [
source 19
target 12
label 0
]
edge [
source 19
target 13
label 0
]
edge [
source 19
target 14
label 0
]
edge [
source 19
target 15
label 0
]
edge [
source 19
target 16
label 0
]
edge [
source 19
target 17
label 0
]
edge [
source 19
target 18
label 0
]
edge [
source 19
target 19
label 0
]
edge [
source 20
target 1
label 0
]
edge [
source 20
target 2
label 0
]
edge [
source 20
target 3
label 0
]
edge [
source 20
target 4
label 0
]
edge [
source 20
target 5
label 0
]
edge [
source 20
target 6
label 0
]
edge [
source 20
target 7
label 0
]
edge [
source 20
target 8
label 0
]
edge [
source 20
target 9
label 0
]
edge [
source 20
target 10
label 0
]
edge [
source 20
target 11
label 0
]
edge [
source 20
target 12
label 0
]
edge [
source 20
target 13
label 0
]
edge [
source 20
target 14
label 0
]
edge [
source 20
target 15
label 0
]
edge [
source 20
target 16
label 0
]
edge [
source 20
target 17
label 0
]
edge [
source 20
target 18
label 0
]
edge [
source 20
target 19
label 0
]
edge [
source 20
target 20
label 0
]
]
ocamlgraph-2.0.0/editor/tests/softmaint.dot 0000644 0001750 0000144 00000035152 13735627615 017363 0 ustar rt users digraph G {
// size="7,10"
// page="8.5,11"
// center=""
// node[width=.25,height=.375,fontsize=9]
fcfpr1_1_2t_17 -> 341411;
fcfpr1_1t_1 -> 341411;
rdlfpr2_0_rdlt_4 -> 341411;
fpfpr1_0_1t_1 -> 341411;
fpfpr1_1_2t_11 -> 341411;
rtafpr1_1_2t_28 -> 341411;
rtafpr1_1_3t_6 -> 341411;
rdlfpr1_1t_1 -> 358866;
rtafpr1_1_3t_6 -> 358866;
tmfpr1_1_3t_5 -> 358930;
fcfpr1_1_3t_9 -> 358930;
pcfpr1_1_3t_7 -> 358930;
fpfpr1_1_3g_1 -> 358930;
fpfpr1_1_3t_1 -> 358930;
aufpr1_1_3t_1 -> 358930;
rtafpr1_0_3g_1 -> 358930;
rtafpr1_1_3t_6 -> 358930;
msgfpr1_1_1g_12 -> 371943;
rtafpr1_1_1g_8 -> 371943;
rtafpr1_1_1t_35 -> 371943;
rtafpr1_1_1t_45 -> 371943;
rtafpr1_1_3t_6 -> 371943;
tlfpr2_0_rdlg_2 -> 374300;
fcfpr1_1_3t_8 -> 374300;
fcfpr1_1_3t_9 -> 374300;
rtafpr1_1_3t_6 -> 374300;
fcfpr1_0_5g_1 -> 371942;
fcfpr1_1_1t_19 -> 371942;
fcfpr1_1_3t_9 -> 371942;
fcfpr1_1_3t_9 -> 374700;
tymsgfpr1_1_3t_3 -> 374700;
fpfpr1_1_3t_1 -> 374700;
rtafpr1_1_3t_7 -> 374700;
fcfpr1_1_3g_2 -> 374741;
fcfpr1_1_3t_9 -> 374741;
fpfpr1_1_3t_1 -> 374741;
rtafpr1_1_3t_7 -> 374741;
fcfpr1_1_1t_18 -> 374886;
fcfpr1_1_3t_9 -> 374886;
fpfpr1_1_3t_1 -> 374886;
rtafpr1_1_3t_7 -> 374886;
fcfpr1_1_3t_9 -> 375039;
fpfpr1_1_3t_1 -> 375039;
fcfpr1_1_3t_42 -> 375507;
fcfpr1_1_3t_9 -> 375507;
rdlfpr2_0_rdlt_158 -> 375507;
rtafpr1_1_3t_7 -> 375507;
rtafpr1_1_3t_71 -> 375507;
dbfpr1_1_3t_2 -> 375507;
fcfpr1_1_3t_9 -> 375508;
rdlfpr1_1g_13 -> 375508;
rtafpr1_1_3t_7 -> 375508;
rtafpr2_1_rdlg_1 -> 375508;
dbfpr1_1_3t_2 -> 375508;
fcfpr1_1_3t_9 -> 375519;
fpfpr1_1_3g_1 -> 375519;
fpfpr1_1_3t_1 -> 375519;
fcfpr1_1_3t_9 -> 377380;
rdlfpr1_1g_16 -> 377380;
rdlfpr1_1t_100 -> 377380;
fcfpr1_0_2g_1 -> 377719;
fcfpr1_1_3t_10 -> 377719;
fcfpr1_1_3t_7 -> 377719;
fcfpr1_1_3t_9 -> 377719;
rdlfpr2_0_rdlg_12 -> 377719;
rdlfpr2_0_rdlt_108 -> 377719;
rdlfpr2_0_rdlt_27 -> 377719;
rdlfpr2_0_rdlt_30 -> 377719;
fcfpr1_1_3t_9 -> 377763;
fcfpr1_1_3t_9 -> 379848;
fpfpr1_1_3t_1 -> 379848;
fcfpr1_1_3t_9 -> 380571;
fcfpr1_1_3t_9 -> 380604;
fpfpr1_1_3t_1 -> 380604;
fcfpr1_1_3t_9 -> 381211;
fpfpr1_1_3t_1 -> 381211;
fcfpr1_1_3t_9 -> 381835;
fcfpr1_1_3t_9 -> 381897;
fcfpr1_1_3t_9 -> 381901;
fpfpr1_1_3t_1 -> 381901;
fcfpr1_1_3t_9 -> 382103;
rtafpr1_1_3t_7 -> 382103;
fcfpr1_1_3t_9 -> 382161;
fcfpr1_1_3t_9 -> 383174;
fpfpr1_1_3t_1 -> 383174;
rtafpr1_1_3t_7 -> 383174;
fpfpr1_1_3g_1 -> 352010;
fpfpr1_1_3t_1 -> 352010;
fpfpr1_1_3t_1 -> 382409;
fpfpr1_1_3t_1 -> 382827;
fpfpr1_1_3t_1 -> 382928;
rtafpr1_1_3t_7 -> 382928;
tlfpr1_1_1t_5 -> 358224;
tymsgfpr1_1_1t_23 -> 358224;
tymsgfpr1_1_3t_3 -> 358224;
rcfpr0_0_1t_9 -> 358224;
rcfpr1_1_1t_5 -> 358224;
odfpr0_0_1t_8 -> 358224;
odfpr1_1_1t_6 -> 358224;
ecdsgfpr1_1_1t_4 -> 358224;
tymsgfpr1_1_1t_18 -> 358900;
tymsgfpr1_1_3t_3 -> 358900;
rcfpr1_1_1t_100 -> 358900;
rcfpr1_1_1t_22 -> 358900;
rcfpr1_1_1t_37 -> 358900;
odfpr1_1_1t_21 -> 358900;
tymsgfpr1_1_3t_3 -> 372568;
rcfpr1_1_1t_30 -> 372568;
odfpr1_1_1t_31 -> 372568;
tlfpr1_1_1t_20 -> 375557;
tymsgfpr1_1_1t_24 -> 375557;
tymsgfpr1_1_3t_3 -> 375557;
rcfpr1_1_1t_11 -> 375557;
odfpr1_1_1t_9 -> 375557;
ecdsgfpr1_1_1t_19 -> 375557;
rtafpr1_1_1g_14 -> 376956;
rtafpr1_1_1t_64 -> 376956;
rtafpr1_1_2t_18 -> 376956;
rtafpr1_1_3t_30 -> 376956;
rtafpr1_1_3t_7 -> 376956;
rtafpr1_1_3t_7 -> 379339;
rtafpr1_1_1t_14 -> 379422;
rtafpr1_1_1t_20 -> 379422;
rtafpr1_1_3t_7 -> 379422;
rtafpr1_1_3t_7 -> 383039;
fcfpr1_1_1t_18 -> 359471;
fcfpr2_0_1t_1 -> 359471;
fcfpr2_0_1t_2 -> 359471;
ccsfpr2_0_1t_99 -> 359471;
fcfpr1_1_3t_42 -> 384096;
rtafpr1_1_3t_71 -> 384096;
tlfpr1_0_4g_4 -> 354290;
rcfpr0_0_1t_9 -> 354290;
odfpr0_0_1t_8 -> 354290;
pagfpr1_1_1t_23 -> 354290;
rcfpr1_1_1t_5 -> 379864;
rcfpr1_1_1t_100 -> 382574;
rcfpr1_1_1t_22 -> 382574;
rcfpr1_1_1t_37 -> 382574;
rcfpr1_1_1t_30 -> 370706;
rcfpr1_1_1t_30 -> 377908;
rcfpr1_1_1t_30 -> 377924;
rcfpr1_1_1t_30 -> 377971;
rcfpr1_1_1t_30 -> 377980;
odfpr1_1_1t_31 -> 377980;
rcfpr1_1_1t_30 -> 378362;
rcfpr1_1_1t_30 -> 378656;
rcfpr1_1_1t_30 -> 378666;
rcfpr1_1_1t_30 -> 379169;
odfpr1_1_1t_31 -> 379169;
rcfpr1_1_1t_110 -> 379341;
rcfpr1_1_1t_30 -> 379341;
rcfpr1_1_1t_62 -> 379341;
odfpr1_1_1t_31 -> 379341;
rcfpr1_1_1t_30 -> 379972;
rcfpr1_1_1t_30 -> 380298;
rcfpr1_1_1t_30 -> 380448;
rcfpr1_1_1t_30 -> 380475;
odfpr1_1_1t_31 -> 380475;
rcfpr1_1_1t_30 -> 380526;
odfpr1_1_1t_31 -> 357430;
rcfpr1_1_1t_11 -> 379968;
odfpr1_1_1t_9 -> 379968;
ccsfpr2_0_1t_99 -> 359100;
ccsfpr2_0_1t_99 -> 376529;
ccsfpr2_0_1t_99 -> 377801;
ccsfpr2_0_1t_99 -> 379126;
ccsfpr2_0_1t_99 -> 379212;
ccsfpr2_0_1t_99 -> 380285;
ccsfpr2_0_1t_99 -> 380963;
ccsfpr2_0_1t_99 -> 384909;
tlfpr1_0_4g_4 -> 358471;
odfpr0_0_1t_7 -> 358471;
odfpr1_0_1t_36 -> 358471;
odfpr1_0_3t_18 -> 358471;
odfpr1_0_3t_21 -> 358471;
tlfpr1_0_4g_4 -> 375024;
tlfpr1_0_4g_4 -> 375027;
rcfpr1_1_1t_110 -> 381710;
rcfpr1_1_1t_62 -> 381710;
rcfpr1_1_1t_110 -> 381775;
rcfpr1_1_1t_62 -> 381775;
rcfpr1_1_1t_110 -> 382436;
fcfpr1_1_3t_34 -> 382528;
rcfpr1_1_1t_110 -> 382528;
rtafpr1_1_3t_48 -> 382528;
rcfpr1_1_1t_110 -> 382566;
rcfpr1_1_1t_110 -> 382572;
odfpr0_0_1t_7 -> 353506;
rcfpr1_0_1t_35 -> 370509;
odfpr0_0_1t_7 -> 370509;
odfpr0_0_1t_7 -> 370510;
odfpr1_0_1t_38 -> 370510;
tlfpr1_0_4g_5 -> 354546;
rcfpr1_1_1t_61 -> 354546;
odfpr1_0_3t_18 -> 354546;
odfpr1_0_3t_20 -> 354546;
odfpr1_0_3t_18 -> 354757;
odfpr1_0_3t_20 -> 354757;
odfpr1_0_3t_18 -> 354766;
odfpr1_0_3t_20 -> 354766;
odfpr1_0_3t_18 -> 354771;
odfpr1_0_3t_20 -> 354771;
odfpr1_0_3t_18 -> 354785;
odfpr1_0_3t_23 -> 354785;
odfpr1_0_3t_24 -> 354785;
odfpr1_0_3t_18 -> 354878;
odfpr1_0_3t_23 -> 354878;
odfpr1_0_3t_24 -> 354878;
odfpr1_0_3t_18 -> 355080;
odfpr1_0_3t_23 -> 355080;
odfpr1_0_3t_24 -> 355080;
odfpr1_0_3t_18 -> 355288;
odfpr1_0_3t_23 -> 355288;
odfpr1_0_3t_24 -> 355288;
odfpr2_0_03t_13 -> 355288;
odfpr1_0_3t_18 -> 355800;
odfpr1_0_3t_21 -> 355800;
odfpr1_0_3t_18 -> 356116;
odfpr1_0_3t_21 -> 356116;
odfpr1_0_3t_18 -> 356741;
odfpr1_0_3t_21 -> 356741;
odfpr1_0_3t_18 -> 357340;
odfpr1_0_3t_21 -> 357340;
odfpr1_0_3t_18 -> 357538;
odfpr1_0_3t_21 -> 357538;
odfpr1_0_3t_18 -> 357769;
odfpr1_0_3t_21 -> 357769;
odfpr1_0_3t_18 -> 357793;
odfpr1_0_3t_21 -> 357793;
odfpr1_0_3t_18 -> 358155;
odfpr1_0_3t_21 -> 358155;
odfpr1_0_3t_18 -> 358157;
odfpr1_0_3t_21 -> 358157;
odfpr1_0_3t_18 -> 358159;
odfpr1_0_3t_21 -> 358159;
odfpr1_0_3t_18 -> 358584;
odfpr1_0_3t_21 -> 358584;
odfpr1_0_3t_18 -> 360104;
odfpr1_0_3t_21 -> 360104;
odfpr1_0_3t_18 -> 360144;
odfpr1_0_3t_21 -> 360144;
odfpr1_0_3t_18 -> 360672;
odfpr1_0_3t_21 -> 360672;
odfpr1_0_3t_5 -> 360672;
odfpr1_0_3t_18 -> 360839;
odfpr1_0_3t_21 -> 360839;
odfpr1_0_3t_18 -> 371187;
tlfpr1_0_3g_5 -> 373300;
odfpr1_0_3t_12 -> 373300;
odfpr1_0_3t_18 -> 373300;
odfpr1_0_3t_18 -> 375134;
odfpr1_0_5t_18 -> 375134;
rcfpr0_0_1t_10 -> 375319;
odfpr1_0_3t_18 -> 375319;
odfpr1_0_3t_36 -> 375319;
odfpr1_0_5t_17 -> 375319;
odfpr1_0_5t_19 -> 375319;
odfpr1_0_3t_18 -> 375499;
odfpr1_0_3t_18 -> 377220;
odfpr1_0_5t_21 -> 377220;
tlfpr1_0_3g_7 -> 377562;
tlfpr1_1_1t_3 -> 377562;
odfpr1_0_3t_18 -> 377562;
odfpr1_0_3t_36 -> 377562;
odfpr1_0_5t_20 -> 377562;
odfpr1_0_3t_18 -> 378108;
odfpr1_0_3t_6 -> 378108;
odfpr1_0_5t_20 -> 354221;
odfpr0_0_1t_7 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
tlfpr1_0_3g_5 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
odfpr0_0_1t_8 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rcfpr1_1_1t_61 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
fcfpr1_1t_1 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
odfpr1_0_3t_18 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
tlfpr1_0_3g_7 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rcfpr1_1_1t_62 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
ccsfpr2_0_1t_99 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
tymsgfpr1_1_3t_3 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rcfpr0_0_1t_9 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rtafpr1_1_1t_14 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rtafpr1_1_3t_30 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rcfpr1_1_1t_110 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
dbfpr1_1_3t_2 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rtafpr1_1_1g_8 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rcfpr1_1_1t_30 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
tlfpr1_1_1t_20 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rtafpr1_1_1t_64 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
tlfpr2_0_rdlg_2 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rtafpr1_1_2t_28 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
tlfpr1_1_1t_3 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
odfpr1_1_1t_6 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
fpfpr1_1_3t_1 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
aufpr1_1_3t_1 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
fcfpr1_1_3t_34 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rcfpr1_1_1t_5 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
fcfpr1_1_1t_18 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
odfpr1_0_3t_36 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
tlfpr1_1_1t_5 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
fcfpr1_1_1t_19 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
odfpr1_1_1t_9 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
fcfpr1_1_3t_7 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rcfpr1_1_1t_37 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
fcfpr1_1_3t_8 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
odfpr1_1_1t_21 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
fcfpr1_1_3t_9 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rdlfpr2_0_rdlt_27 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
fcfpr1_1_3g_2 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rtafpr1_1_1t_35 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
odfpr1_0_5t_20 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
fpfpr1_1_3g_1 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
odfpr1_0_5t_21 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
fpfpr1_1_2t_11 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
ecdsgfpr1_1_1t_19 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
odfpr1_0_1t_36 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rtafpr1_1_1g_14 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
tymsgfpr1_1_1t_23 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
tymsgfpr1_1_1t_24 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
odfpr1_0_1t_38 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
fcfpr1_0_2g_1 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rdlfpr1_1t_1 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rcfpr0_0_1t_10 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rcfpr1_1_1t_100 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rdlfpr2_0_rdlt_108 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
pcfpr1_1_3t_7 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
odfpr1_0_3t_20 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
ecdsgfpr1_1_1t_4 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
tmfpr1_1_3t_5 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
odfpr1_0_3t_21 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
fpfpr1_0_1t_1 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
odfpr1_0_3t_23 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rcfpr1_1_1t_22 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
pagfpr1_1_1t_23 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rtafpr1_1_3t_71 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rtafpr1_1_2t_18 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rdlfpr2_0_rdlt_158 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rtafpr1_1_3t_6 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
odfpr1_0_3t_24 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rtafpr1_1_3t_7 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rtafpr1_0_3g_1 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rtafpr1_1_1t_20 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rdlfpr1_1g_13 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rcfpr1_0_1t_35 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
fcfpr1_1_2t_17 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rtafpr2_1_rdlg_1 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rdlfpr2_0_rdlt_4 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rdlfpr1_1g_16 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
fcfpr2_0_1t_1 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
fcfpr2_0_1t_2 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rdlfpr1_1t_100 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
msgfpr1_1_1g_12 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rdlfpr2_0_rdlt_30 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
odfpr1_0_3t_5 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
tlfpr1_0_4g_4 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
fcfpr1_1_3t_42 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
odfpr1_0_3t_6 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
tlfpr1_0_4g_5 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rtafpr1_1_3t_48 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
odfpr1_0_5t_17 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
odfpr1_0_5t_18 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
tymsgfpr1_1_1t_18 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
odfpr1_0_5t_19 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
fcfpr1_1_3t_10 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
fcfpr1_0_5g_1 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
odfpr1_0_3t_12 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
odfpr2_0_03t_13 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rcfpr1_1_1t_11 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
odfpr1_1_1t_31 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rdlfpr2_0_rdlg_12 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
rtafpr1_1_1t_45 [label="",shape=circle,height=0.12,width=0.12,fontsize=1];
}
ocamlgraph-2.0.0/editor/tests/full50.gml 0000644 0001750 0000144 00000206455 13735627615 016465 0 ustar rt users graph [
node [
id 1
label 1
]
node [
id 2
label 2
]
node [
id 3
label 3
]
node [
id 4
label 4
]
node [
id 5
label 5
]
node [
id 6
label 6
]
node [
id 7
label 7
]
node [
id 8
label 8
]
node [
id 9
label 9
]
node [
id 10
label 10
]
node [
id 11
label 11
]
node [
id 12
label 12
]
node [
id 13
label 13
]
node [
id 14
label 14
]
node [
id 15
label 15
]
node [
id 16
label 16
]
node [
id 17
label 17
]
node [
id 18
label 18
]
node [
id 19
label 19
]
node [
id 20
label 20
]
node [
id 21
label 21
]
node [
id 22
label 22
]
node [
id 23
label 23
]
node [
id 24
label 24
]
node [
id 25
label 25
]
node [
id 26
label 26
]
node [
id 27
label 27
]
node [
id 28
label 28
]
node [
id 29
label 29
]
node [
id 30
label 30
]
node [
id 31
label 31
]
node [
id 32
label 32
]
node [
id 33
label 33
]
node [
id 34
label 34
]
node [
id 35
label 35
]
node [
id 36
label 36
]
node [
id 37
label 37
]
node [
id 38
label 38
]
node [
id 39
label 39
]
node [
id 40
label 40
]
node [
id 41
label 41
]
node [
id 42
label 42
]
node [
id 43
label 43
]
node [
id 44
label 44
]
node [
id 45
label 45
]
node [
id 46
label 46
]
node [
id 47
label 47
]
node [
id 48
label 48
]
node [
id 49
label 49
]
node [
id 50
label 50
]
edge [
source 1
target 1
label 0
]
edge [
source 2
target 1
label 0
]
edge [
source 2
target 2
label 0
]
edge [
source 3
target 1
label 0
]
edge [
source 3
target 2
label 0
]
edge [
source 3
target 3
label 0
]
edge [
source 4
target 1
label 0
]
edge [
source 4
target 2
label 0
]
edge [
source 4
target 3
label 0
]
edge [
source 4
target 4
label 0
]
edge [
source 5
target 1
label 0
]
edge [
source 5
target 2
label 0
]
edge [
source 5
target 3
label 0
]
edge [
source 5
target 4
label 0
]
edge [
source 5
target 5
label 0
]
edge [
source 6
target 1
label 0
]
edge [
source 6
target 2
label 0
]
edge [
source 6
target 3
label 0
]
edge [
source 6
target 4
label 0
]
edge [
source 6
target 5
label 0
]
edge [
source 6
target 6
label 0
]
edge [
source 7
target 1
label 0
]
edge [
source 7
target 2
label 0
]
edge [
source 7
target 3
label 0
]
edge [
source 7
target 4
label 0
]
edge [
source 7
target 5
label 0
]
edge [
source 7
target 6
label 0
]
edge [
source 7
target 7
label 0
]
edge [
source 8
target 1
label 0
]
edge [
source 8
target 2
label 0
]
edge [
source 8
target 3
label 0
]
edge [
source 8
target 4
label 0
]
edge [
source 8
target 5
label 0
]
edge [
source 8
target 6
label 0
]
edge [
source 8
target 7
label 0
]
edge [
source 8
target 8
label 0
]
edge [
source 9
target 1
label 0
]
edge [
source 9
target 2
label 0
]
edge [
source 9
target 3
label 0
]
edge [
source 9
target 4
label 0
]
edge [
source 9
target 5
label 0
]
edge [
source 9
target 6
label 0
]
edge [
source 9
target 7
label 0
]
edge [
source 9
target 8
label 0
]
edge [
source 9
target 9
label 0
]
edge [
source 10
target 1
label 0
]
edge [
source 10
target 2
label 0
]
edge [
source 10
target 3
label 0
]
edge [
source 10
target 4
label 0
]
edge [
source 10
target 5
label 0
]
edge [
source 10
target 6
label 0
]
edge [
source 10
target 7
label 0
]
edge [
source 10
target 8
label 0
]
edge [
source 10
target 9
label 0
]
edge [
source 10
target 10
label 0
]
edge [
source 11
target 1
label 0
]
edge [
source 11
target 2
label 0
]
edge [
source 11
target 3
label 0
]
edge [
source 11
target 4
label 0
]
edge [
source 11
target 5
label 0
]
edge [
source 11
target 6
label 0
]
edge [
source 11
target 7
label 0
]
edge [
source 11
target 8
label 0
]
edge [
source 11
target 9
label 0
]
edge [
source 11
target 10
label 0
]
edge [
source 11
target 11
label 0
]
edge [
source 12
target 1
label 0
]
edge [
source 12
target 2
label 0
]
edge [
source 12
target 3
label 0
]
edge [
source 12
target 4
label 0
]
edge [
source 12
target 5
label 0
]
edge [
source 12
target 6
label 0
]
edge [
source 12
target 7
label 0
]
edge [
source 12
target 8
label 0
]
edge [
source 12
target 9
label 0
]
edge [
source 12
target 10
label 0
]
edge [
source 12
target 11
label 0
]
edge [
source 12
target 12
label 0
]
edge [
source 13
target 1
label 0
]
edge [
source 13
target 2
label 0
]
edge [
source 13
target 3
label 0
]
edge [
source 13
target 4
label 0
]
edge [
source 13
target 5
label 0
]
edge [
source 13
target 6
label 0
]
edge [
source 13
target 7
label 0
]
edge [
source 13
target 8
label 0
]
edge [
source 13
target 9
label 0
]
edge [
source 13
target 10
label 0
]
edge [
source 13
target 11
label 0
]
edge [
source 13
target 12
label 0
]
edge [
source 13
target 13
label 0
]
edge [
source 14
target 1
label 0
]
edge [
source 14
target 2
label 0
]
edge [
source 14
target 3
label 0
]
edge [
source 14
target 4
label 0
]
edge [
source 14
target 5
label 0
]
edge [
source 14
target 6
label 0
]
edge [
source 14
target 7
label 0
]
edge [
source 14
target 8
label 0
]
edge [
source 14
target 9
label 0
]
edge [
source 14
target 10
label 0
]
edge [
source 14
target 11
label 0
]
edge [
source 14
target 12
label 0
]
edge [
source 14
target 13
label 0
]
edge [
source 14
target 14
label 0
]
edge [
source 15
target 1
label 0
]
edge [
source 15
target 2
label 0
]
edge [
source 15
target 3
label 0
]
edge [
source 15
target 4
label 0
]
edge [
source 15
target 5
label 0
]
edge [
source 15
target 6
label 0
]
edge [
source 15
target 7
label 0
]
edge [
source 15
target 8
label 0
]
edge [
source 15
target 9
label 0
]
edge [
source 15
target 10
label 0
]
edge [
source 15
target 11
label 0
]
edge [
source 15
target 12
label 0
]
edge [
source 15
target 13
label 0
]
edge [
source 15
target 14
label 0
]
edge [
source 15
target 15
label 0
]
edge [
source 16
target 1
label 0
]
edge [
source 16
target 2
label 0
]
edge [
source 16
target 3
label 0
]
edge [
source 16
target 4
label 0
]
edge [
source 16
target 5
label 0
]
edge [
source 16
target 6
label 0
]
edge [
source 16
target 7
label 0
]
edge [
source 16
target 8
label 0
]
edge [
source 16
target 9
label 0
]
edge [
source 16
target 10
label 0
]
edge [
source 16
target 11
label 0
]
edge [
source 16
target 12
label 0
]
edge [
source 16
target 13
label 0
]
edge [
source 16
target 14
label 0
]
edge [
source 16
target 15
label 0
]
edge [
source 16
target 16
label 0
]
edge [
source 17
target 1
label 0
]
edge [
source 17
target 2
label 0
]
edge [
source 17
target 3
label 0
]
edge [
source 17
target 4
label 0
]
edge [
source 17
target 5
label 0
]
edge [
source 17
target 6
label 0
]
edge [
source 17
target 7
label 0
]
edge [
source 17
target 8
label 0
]
edge [
source 17
target 9
label 0
]
edge [
source 17
target 10
label 0
]
edge [
source 17
target 11
label 0
]
edge [
source 17
target 12
label 0
]
edge [
source 17
target 13
label 0
]
edge [
source 17
target 14
label 0
]
edge [
source 17
target 15
label 0
]
edge [
source 17
target 16
label 0
]
edge [
source 17
target 17
label 0
]
edge [
source 18
target 1
label 0
]
edge [
source 18
target 2
label 0
]
edge [
source 18
target 3
label 0
]
edge [
source 18
target 4
label 0
]
edge [
source 18
target 5
label 0
]
edge [
source 18
target 6
label 0
]
edge [
source 18
target 7
label 0
]
edge [
source 18
target 8
label 0
]
edge [
source 18
target 9
label 0
]
edge [
source 18
target 10
label 0
]
edge [
source 18
target 11
label 0
]
edge [
source 18
target 12
label 0
]
edge [
source 18
target 13
label 0
]
edge [
source 18
target 14
label 0
]
edge [
source 18
target 15
label 0
]
edge [
source 18
target 16
label 0
]
edge [
source 18
target 17
label 0
]
edge [
source 18
target 18
label 0
]
edge [
source 19
target 1
label 0
]
edge [
source 19
target 2
label 0
]
edge [
source 19
target 3
label 0
]
edge [
source 19
target 4
label 0
]
edge [
source 19
target 5
label 0
]
edge [
source 19
target 6
label 0
]
edge [
source 19
target 7
label 0
]
edge [
source 19
target 8
label 0
]
edge [
source 19
target 9
label 0
]
edge [
source 19
target 10
label 0
]
edge [
source 19
target 11
label 0
]
edge [
source 19
target 12
label 0
]
edge [
source 19
target 13
label 0
]
edge [
source 19
target 14
label 0
]
edge [
source 19
target 15
label 0
]
edge [
source 19
target 16
label 0
]
edge [
source 19
target 17
label 0
]
edge [
source 19
target 18
label 0
]
edge [
source 19
target 19
label 0
]
edge [
source 20
target 1
label 0
]
edge [
source 20
target 2
label 0
]
edge [
source 20
target 3
label 0
]
edge [
source 20
target 4
label 0
]
edge [
source 20
target 5
label 0
]
edge [
source 20
target 6
label 0
]
edge [
source 20
target 7
label 0
]
edge [
source 20
target 8
label 0
]
edge [
source 20
target 9
label 0
]
edge [
source 20
target 10
label 0
]
edge [
source 20
target 11
label 0
]
edge [
source 20
target 12
label 0
]
edge [
source 20
target 13
label 0
]
edge [
source 20
target 14
label 0
]
edge [
source 20
target 15
label 0
]
edge [
source 20
target 16
label 0
]
edge [
source 20
target 17
label 0
]
edge [
source 20
target 18
label 0
]
edge [
source 20
target 19
label 0
]
edge [
source 20
target 20
label 0
]
edge [
source 21
target 1
label 0
]
edge [
source 21
target 2
label 0
]
edge [
source 21
target 3
label 0
]
edge [
source 21
target 4
label 0
]
edge [
source 21
target 5
label 0
]
edge [
source 21
target 6
label 0
]
edge [
source 21
target 7
label 0
]
edge [
source 21
target 8
label 0
]
edge [
source 21
target 9
label 0
]
edge [
source 21
target 10
label 0
]
edge [
source 21
target 11
label 0
]
edge [
source 21
target 12
label 0
]
edge [
source 21
target 13
label 0
]
edge [
source 21
target 14
label 0
]
edge [
source 21
target 15
label 0
]
edge [
source 21
target 16
label 0
]
edge [
source 21
target 17
label 0
]
edge [
source 21
target 18
label 0
]
edge [
source 21
target 19
label 0
]
edge [
source 21
target 20
label 0
]
edge [
source 21
target 21
label 0
]
edge [
source 22
target 1
label 0
]
edge [
source 22
target 2
label 0
]
edge [
source 22
target 3
label 0
]
edge [
source 22
target 4
label 0
]
edge [
source 22
target 5
label 0
]
edge [
source 22
target 6
label 0
]
edge [
source 22
target 7
label 0
]
edge [
source 22
target 8
label 0
]
edge [
source 22
target 9
label 0
]
edge [
source 22
target 10
label 0
]
edge [
source 22
target 11
label 0
]
edge [
source 22
target 12
label 0
]
edge [
source 22
target 13
label 0
]
edge [
source 22
target 14
label 0
]
edge [
source 22
target 15
label 0
]
edge [
source 22
target 16
label 0
]
edge [
source 22
target 17
label 0
]
edge [
source 22
target 18
label 0
]
edge [
source 22
target 19
label 0
]
edge [
source 22
target 20
label 0
]
edge [
source 22
target 21
label 0
]
edge [
source 22
target 22
label 0
]
edge [
source 23
target 1
label 0
]
edge [
source 23
target 2
label 0
]
edge [
source 23
target 3
label 0
]
edge [
source 23
target 4
label 0
]
edge [
source 23
target 5
label 0
]
edge [
source 23
target 6
label 0
]
edge [
source 23
target 7
label 0
]
edge [
source 23
target 8
label 0
]
edge [
source 23
target 9
label 0
]
edge [
source 23
target 10
label 0
]
edge [
source 23
target 11
label 0
]
edge [
source 23
target 12
label 0
]
edge [
source 23
target 13
label 0
]
edge [
source 23
target 14
label 0
]
edge [
source 23
target 15
label 0
]
edge [
source 23
target 16
label 0
]
edge [
source 23
target 17
label 0
]
edge [
source 23
target 18
label 0
]
edge [
source 23
target 19
label 0
]
edge [
source 23
target 20
label 0
]
edge [
source 23
target 21
label 0
]
edge [
source 23
target 22
label 0
]
edge [
source 23
target 23
label 0
]
edge [
source 24
target 1
label 0
]
edge [
source 24
target 2
label 0
]
edge [
source 24
target 3
label 0
]
edge [
source 24
target 4
label 0
]
edge [
source 24
target 5
label 0
]
edge [
source 24
target 6
label 0
]
edge [
source 24
target 7
label 0
]
edge [
source 24
target 8
label 0
]
edge [
source 24
target 9
label 0
]
edge [
source 24
target 10
label 0
]
edge [
source 24
target 11
label 0
]
edge [
source 24
target 12
label 0
]
edge [
source 24
target 13
label 0
]
edge [
source 24
target 14
label 0
]
edge [
source 24
target 15
label 0
]
edge [
source 24
target 16
label 0
]
edge [
source 24
target 17
label 0
]
edge [
source 24
target 18
label 0
]
edge [
source 24
target 19
label 0
]
edge [
source 24
target 20
label 0
]
edge [
source 24
target 21
label 0
]
edge [
source 24
target 22
label 0
]
edge [
source 24
target 23
label 0
]
edge [
source 24
target 24
label 0
]
edge [
source 25
target 1
label 0
]
edge [
source 25
target 2
label 0
]
edge [
source 25
target 3
label 0
]
edge [
source 25
target 4
label 0
]
edge [
source 25
target 5
label 0
]
edge [
source 25
target 6
label 0
]
edge [
source 25
target 7
label 0
]
edge [
source 25
target 8
label 0
]
edge [
source 25
target 9
label 0
]
edge [
source 25
target 10
label 0
]
edge [
source 25
target 11
label 0
]
edge [
source 25
target 12
label 0
]
edge [
source 25
target 13
label 0
]
edge [
source 25
target 14
label 0
]
edge [
source 25
target 15
label 0
]
edge [
source 25
target 16
label 0
]
edge [
source 25
target 17
label 0
]
edge [
source 25
target 18
label 0
]
edge [
source 25
target 19
label 0
]
edge [
source 25
target 20
label 0
]
edge [
source 25
target 21
label 0
]
edge [
source 25
target 22
label 0
]
edge [
source 25
target 23
label 0
]
edge [
source 25
target 24
label 0
]
edge [
source 25
target 25
label 0
]
edge [
source 26
target 1
label 0
]
edge [
source 26
target 2
label 0
]
edge [
source 26
target 3
label 0
]
edge [
source 26
target 4
label 0
]
edge [
source 26
target 5
label 0
]
edge [
source 26
target 6
label 0
]
edge [
source 26
target 7
label 0
]
edge [
source 26
target 8
label 0
]
edge [
source 26
target 9
label 0
]
edge [
source 26
target 10
label 0
]
edge [
source 26
target 11
label 0
]
edge [
source 26
target 12
label 0
]
edge [
source 26
target 13
label 0
]
edge [
source 26
target 14
label 0
]
edge [
source 26
target 15
label 0
]
edge [
source 26
target 16
label 0
]
edge [
source 26
target 17
label 0
]
edge [
source 26
target 18
label 0
]
edge [
source 26
target 19
label 0
]
edge [
source 26
target 20
label 0
]
edge [
source 26
target 21
label 0
]
edge [
source 26
target 22
label 0
]
edge [
source 26
target 23
label 0
]
edge [
source 26
target 24
label 0
]
edge [
source 26
target 25
label 0
]
edge [
source 26
target 26
label 0
]
edge [
source 27
target 1
label 0
]
edge [
source 27
target 2
label 0
]
edge [
source 27
target 3
label 0
]
edge [
source 27
target 4
label 0
]
edge [
source 27
target 5
label 0
]
edge [
source 27
target 6
label 0
]
edge [
source 27
target 7
label 0
]
edge [
source 27
target 8
label 0
]
edge [
source 27
target 9
label 0
]
edge [
source 27
target 10
label 0
]
edge [
source 27
target 11
label 0
]
edge [
source 27
target 12
label 0
]
edge [
source 27
target 13
label 0
]
edge [
source 27
target 14
label 0
]
edge [
source 27
target 15
label 0
]
edge [
source 27
target 16
label 0
]
edge [
source 27
target 17
label 0
]
edge [
source 27
target 18
label 0
]
edge [
source 27
target 19
label 0
]
edge [
source 27
target 20
label 0
]
edge [
source 27
target 21
label 0
]
edge [
source 27
target 22
label 0
]
edge [
source 27
target 23
label 0
]
edge [
source 27
target 24
label 0
]
edge [
source 27
target 25
label 0
]
edge [
source 27
target 26
label 0
]
edge [
source 27
target 27
label 0
]
edge [
source 28
target 1
label 0
]
edge [
source 28
target 2
label 0
]
edge [
source 28
target 3
label 0
]
edge [
source 28
target 4
label 0
]
edge [
source 28
target 5
label 0
]
edge [
source 28
target 6
label 0
]
edge [
source 28
target 7
label 0
]
edge [
source 28
target 8
label 0
]
edge [
source 28
target 9
label 0
]
edge [
source 28
target 10
label 0
]
edge [
source 28
target 11
label 0
]
edge [
source 28
target 12
label 0
]
edge [
source 28
target 13
label 0
]
edge [
source 28
target 14
label 0
]
edge [
source 28
target 15
label 0
]
edge [
source 28
target 16
label 0
]
edge [
source 28
target 17
label 0
]
edge [
source 28
target 18
label 0
]
edge [
source 28
target 19
label 0
]
edge [
source 28
target 20
label 0
]
edge [
source 28
target 21
label 0
]
edge [
source 28
target 22
label 0
]
edge [
source 28
target 23
label 0
]
edge [
source 28
target 24
label 0
]
edge [
source 28
target 25
label 0
]
edge [
source 28
target 26
label 0
]
edge [
source 28
target 27
label 0
]
edge [
source 28
target 28
label 0
]
edge [
source 29
target 1
label 0
]
edge [
source 29
target 2
label 0
]
edge [
source 29
target 3
label 0
]
edge [
source 29
target 4
label 0
]
edge [
source 29
target 5
label 0
]
edge [
source 29
target 6
label 0
]
edge [
source 29
target 7
label 0
]
edge [
source 29
target 8
label 0
]
edge [
source 29
target 9
label 0
]
edge [
source 29
target 10
label 0
]
edge [
source 29
target 11
label 0
]
edge [
source 29
target 12
label 0
]
edge [
source 29
target 13
label 0
]
edge [
source 29
target 14
label 0
]
edge [
source 29
target 15
label 0
]
edge [
source 29
target 16
label 0
]
edge [
source 29
target 17
label 0
]
edge [
source 29
target 18
label 0
]
edge [
source 29
target 19
label 0
]
edge [
source 29
target 20
label 0
]
edge [
source 29
target 21
label 0
]
edge [
source 29
target 22
label 0
]
edge [
source 29
target 23
label 0
]
edge [
source 29
target 24
label 0
]
edge [
source 29
target 25
label 0
]
edge [
source 29
target 26
label 0
]
edge [
source 29
target 27
label 0
]
edge [
source 29
target 28
label 0
]
edge [
source 29
target 29
label 0
]
edge [
source 30
target 1
label 0
]
edge [
source 30
target 2
label 0
]
edge [
source 30
target 3
label 0
]
edge [
source 30
target 4
label 0
]
edge [
source 30
target 5
label 0
]
edge [
source 30
target 6
label 0
]
edge [
source 30
target 7
label 0
]
edge [
source 30
target 8
label 0
]
edge [
source 30
target 9
label 0
]
edge [
source 30
target 10
label 0
]
edge [
source 30
target 11
label 0
]
edge [
source 30
target 12
label 0
]
edge [
source 30
target 13
label 0
]
edge [
source 30
target 14
label 0
]
edge [
source 30
target 15
label 0
]
edge [
source 30
target 16
label 0
]
edge [
source 30
target 17
label 0
]
edge [
source 30
target 18
label 0
]
edge [
source 30
target 19
label 0
]
edge [
source 30
target 20
label 0
]
edge [
source 30
target 21
label 0
]
edge [
source 30
target 22
label 0
]
edge [
source 30
target 23
label 0
]
edge [
source 30
target 24
label 0
]
edge [
source 30
target 25
label 0
]
edge [
source 30
target 26
label 0
]
edge [
source 30
target 27
label 0
]
edge [
source 30
target 28
label 0
]
edge [
source 30
target 29
label 0
]
edge [
source 30
target 30
label 0
]
edge [
source 31
target 1
label 0
]
edge [
source 31
target 2
label 0
]
edge [
source 31
target 3
label 0
]
edge [
source 31
target 4
label 0
]
edge [
source 31
target 5
label 0
]
edge [
source 31
target 6
label 0
]
edge [
source 31
target 7
label 0
]
edge [
source 31
target 8
label 0
]
edge [
source 31
target 9
label 0
]
edge [
source 31
target 10
label 0
]
edge [
source 31
target 11
label 0
]
edge [
source 31
target 12
label 0
]
edge [
source 31
target 13
label 0
]
edge [
source 31
target 14
label 0
]
edge [
source 31
target 15
label 0
]
edge [
source 31
target 16
label 0
]
edge [
source 31
target 17
label 0
]
edge [
source 31
target 18
label 0
]
edge [
source 31
target 19
label 0
]
edge [
source 31
target 20
label 0
]
edge [
source 31
target 21
label 0
]
edge [
source 31
target 22
label 0
]
edge [
source 31
target 23
label 0
]
edge [
source 31
target 24
label 0
]
edge [
source 31
target 25
label 0
]
edge [
source 31
target 26
label 0
]
edge [
source 31
target 27
label 0
]
edge [
source 31
target 28
label 0
]
edge [
source 31
target 29
label 0
]
edge [
source 31
target 30
label 0
]
edge [
source 31
target 31
label 0
]
edge [
source 32
target 1
label 0
]
edge [
source 32
target 2
label 0
]
edge [
source 32
target 3
label 0
]
edge [
source 32
target 4
label 0
]
edge [
source 32
target 5
label 0
]
edge [
source 32
target 6
label 0
]
edge [
source 32
target 7
label 0
]
edge [
source 32
target 8
label 0
]
edge [
source 32
target 9
label 0
]
edge [
source 32
target 10
label 0
]
edge [
source 32
target 11
label 0
]
edge [
source 32
target 12
label 0
]
edge [
source 32
target 13
label 0
]
edge [
source 32
target 14
label 0
]
edge [
source 32
target 15
label 0
]
edge [
source 32
target 16
label 0
]
edge [
source 32
target 17
label 0
]
edge [
source 32
target 18
label 0
]
edge [
source 32
target 19
label 0
]
edge [
source 32
target 20
label 0
]
edge [
source 32
target 21
label 0
]
edge [
source 32
target 22
label 0
]
edge [
source 32
target 23
label 0
]
edge [
source 32
target 24
label 0
]
edge [
source 32
target 25
label 0
]
edge [
source 32
target 26
label 0
]
edge [
source 32
target 27
label 0
]
edge [
source 32
target 28
label 0
]
edge [
source 32
target 29
label 0
]
edge [
source 32
target 30
label 0
]
edge [
source 32
target 31
label 0
]
edge [
source 32
target 32
label 0
]
edge [
source 33
target 1
label 0
]
edge [
source 33
target 2
label 0
]
edge [
source 33
target 3
label 0
]
edge [
source 33
target 4
label 0
]
edge [
source 33
target 5
label 0
]
edge [
source 33
target 6
label 0
]
edge [
source 33
target 7
label 0
]
edge [
source 33
target 8
label 0
]
edge [
source 33
target 9
label 0
]
edge [
source 33
target 10
label 0
]
edge [
source 33
target 11
label 0
]
edge [
source 33
target 12
label 0
]
edge [
source 33
target 13
label 0
]
edge [
source 33
target 14
label 0
]
edge [
source 33
target 15
label 0
]
edge [
source 33
target 16
label 0
]
edge [
source 33
target 17
label 0
]
edge [
source 33
target 18
label 0
]
edge [
source 33
target 19
label 0
]
edge [
source 33
target 20
label 0
]
edge [
source 33
target 21
label 0
]
edge [
source 33
target 22
label 0
]
edge [
source 33
target 23
label 0
]
edge [
source 33
target 24
label 0
]
edge [
source 33
target 25
label 0
]
edge [
source 33
target 26
label 0
]
edge [
source 33
target 27
label 0
]
edge [
source 33
target 28
label 0
]
edge [
source 33
target 29
label 0
]
edge [
source 33
target 30
label 0
]
edge [
source 33
target 31
label 0
]
edge [
source 33
target 32
label 0
]
edge [
source 33
target 33
label 0
]
edge [
source 34
target 1
label 0
]
edge [
source 34
target 2
label 0
]
edge [
source 34
target 3
label 0
]
edge [
source 34
target 4
label 0
]
edge [
source 34
target 5
label 0
]
edge [
source 34
target 6
label 0
]
edge [
source 34
target 7
label 0
]
edge [
source 34
target 8
label 0
]
edge [
source 34
target 9
label 0
]
edge [
source 34
target 10
label 0
]
edge [
source 34
target 11
label 0
]
edge [
source 34
target 12
label 0
]
edge [
source 34
target 13
label 0
]
edge [
source 34
target 14
label 0
]
edge [
source 34
target 15
label 0
]
edge [
source 34
target 16
label 0
]
edge [
source 34
target 17
label 0
]
edge [
source 34
target 18
label 0
]
edge [
source 34
target 19
label 0
]
edge [
source 34
target 20
label 0
]
edge [
source 34
target 21
label 0
]
edge [
source 34
target 22
label 0
]
edge [
source 34
target 23
label 0
]
edge [
source 34
target 24
label 0
]
edge [
source 34
target 25
label 0
]
edge [
source 34
target 26
label 0
]
edge [
source 34
target 27
label 0
]
edge [
source 34
target 28
label 0
]
edge [
source 34
target 29
label 0
]
edge [
source 34
target 30
label 0
]
edge [
source 34
target 31
label 0
]
edge [
source 34
target 32
label 0
]
edge [
source 34
target 33
label 0
]
edge [
source 34
target 34
label 0
]
edge [
source 35
target 1
label 0
]
edge [
source 35
target 2
label 0
]
edge [
source 35
target 3
label 0
]
edge [
source 35
target 4
label 0
]
edge [
source 35
target 5
label 0
]
edge [
source 35
target 6
label 0
]
edge [
source 35
target 7
label 0
]
edge [
source 35
target 8
label 0
]
edge [
source 35
target 9
label 0
]
edge [
source 35
target 10
label 0
]
edge [
source 35
target 11
label 0
]
edge [
source 35
target 12
label 0
]
edge [
source 35
target 13
label 0
]
edge [
source 35
target 14
label 0
]
edge [
source 35
target 15
label 0
]
edge [
source 35
target 16
label 0
]
edge [
source 35
target 17
label 0
]
edge [
source 35
target 18
label 0
]
edge [
source 35
target 19
label 0
]
edge [
source 35
target 20
label 0
]
edge [
source 35
target 21
label 0
]
edge [
source 35
target 22
label 0
]
edge [
source 35
target 23
label 0
]
edge [
source 35
target 24
label 0
]
edge [
source 35
target 25
label 0
]
edge [
source 35
target 26
label 0
]
edge [
source 35
target 27
label 0
]
edge [
source 35
target 28
label 0
]
edge [
source 35
target 29
label 0
]
edge [
source 35
target 30
label 0
]
edge [
source 35
target 31
label 0
]
edge [
source 35
target 32
label 0
]
edge [
source 35
target 33
label 0
]
edge [
source 35
target 34
label 0
]
edge [
source 35
target 35
label 0
]
edge [
source 36
target 1
label 0
]
edge [
source 36
target 2
label 0
]
edge [
source 36
target 3
label 0
]
edge [
source 36
target 4
label 0
]
edge [
source 36
target 5
label 0
]
edge [
source 36
target 6
label 0
]
edge [
source 36
target 7
label 0
]
edge [
source 36
target 8
label 0
]
edge [
source 36
target 9
label 0
]
edge [
source 36
target 10
label 0
]
edge [
source 36
target 11
label 0
]
edge [
source 36
target 12
label 0
]
edge [
source 36
target 13
label 0
]
edge [
source 36
target 14
label 0
]
edge [
source 36
target 15
label 0
]
edge [
source 36
target 16
label 0
]
edge [
source 36
target 17
label 0
]
edge [
source 36
target 18
label 0
]
edge [
source 36
target 19
label 0
]
edge [
source 36
target 20
label 0
]
edge [
source 36
target 21
label 0
]
edge [
source 36
target 22
label 0
]
edge [
source 36
target 23
label 0
]
edge [
source 36
target 24
label 0
]
edge [
source 36
target 25
label 0
]
edge [
source 36
target 26
label 0
]
edge [
source 36
target 27
label 0
]
edge [
source 36
target 28
label 0
]
edge [
source 36
target 29
label 0
]
edge [
source 36
target 30
label 0
]
edge [
source 36
target 31
label 0
]
edge [
source 36
target 32
label 0
]
edge [
source 36
target 33
label 0
]
edge [
source 36
target 34
label 0
]
edge [
source 36
target 35
label 0
]
edge [
source 36
target 36
label 0
]
edge [
source 37
target 1
label 0
]
edge [
source 37
target 2
label 0
]
edge [
source 37
target 3
label 0
]
edge [
source 37
target 4
label 0
]
edge [
source 37
target 5
label 0
]
edge [
source 37
target 6
label 0
]
edge [
source 37
target 7
label 0
]
edge [
source 37
target 8
label 0
]
edge [
source 37
target 9
label 0
]
edge [
source 37
target 10
label 0
]
edge [
source 37
target 11
label 0
]
edge [
source 37
target 12
label 0
]
edge [
source 37
target 13
label 0
]
edge [
source 37
target 14
label 0
]
edge [
source 37
target 15
label 0
]
edge [
source 37
target 16
label 0
]
edge [
source 37
target 17
label 0
]
edge [
source 37
target 18
label 0
]
edge [
source 37
target 19
label 0
]
edge [
source 37
target 20
label 0
]
edge [
source 37
target 21
label 0
]
edge [
source 37
target 22
label 0
]
edge [
source 37
target 23
label 0
]
edge [
source 37
target 24
label 0
]
edge [
source 37
target 25
label 0
]
edge [
source 37
target 26
label 0
]
edge [
source 37
target 27
label 0
]
edge [
source 37
target 28
label 0
]
edge [
source 37
target 29
label 0
]
edge [
source 37
target 30
label 0
]
edge [
source 37
target 31
label 0
]
edge [
source 37
target 32
label 0
]
edge [
source 37
target 33
label 0
]
edge [
source 37
target 34
label 0
]
edge [
source 37
target 35
label 0
]
edge [
source 37
target 36
label 0
]
edge [
source 37
target 37
label 0
]
edge [
source 38
target 1
label 0
]
edge [
source 38
target 2
label 0
]
edge [
source 38
target 3
label 0
]
edge [
source 38
target 4
label 0
]
edge [
source 38
target 5
label 0
]
edge [
source 38
target 6
label 0
]
edge [
source 38
target 7
label 0
]
edge [
source 38
target 8
label 0
]
edge [
source 38
target 9
label 0
]
edge [
source 38
target 10
label 0
]
edge [
source 38
target 11
label 0
]
edge [
source 38
target 12
label 0
]
edge [
source 38
target 13
label 0
]
edge [
source 38
target 14
label 0
]
edge [
source 38
target 15
label 0
]
edge [
source 38
target 16
label 0
]
edge [
source 38
target 17
label 0
]
edge [
source 38
target 18
label 0
]
edge [
source 38
target 19
label 0
]
edge [
source 38
target 20
label 0
]
edge [
source 38
target 21
label 0
]
edge [
source 38
target 22
label 0
]
edge [
source 38
target 23
label 0
]
edge [
source 38
target 24
label 0
]
edge [
source 38
target 25
label 0
]
edge [
source 38
target 26
label 0
]
edge [
source 38
target 27
label 0
]
edge [
source 38
target 28
label 0
]
edge [
source 38
target 29
label 0
]
edge [
source 38
target 30
label 0
]
edge [
source 38
target 31
label 0
]
edge [
source 38
target 32
label 0
]
edge [
source 38
target 33
label 0
]
edge [
source 38
target 34
label 0
]
edge [
source 38
target 35
label 0
]
edge [
source 38
target 36
label 0
]
edge [
source 38
target 37
label 0
]
edge [
source 38
target 38
label 0
]
edge [
source 39
target 1
label 0
]
edge [
source 39
target 2
label 0
]
edge [
source 39
target 3
label 0
]
edge [
source 39
target 4
label 0
]
edge [
source 39
target 5
label 0
]
edge [
source 39
target 6
label 0
]
edge [
source 39
target 7
label 0
]
edge [
source 39
target 8
label 0
]
edge [
source 39
target 9
label 0
]
edge [
source 39
target 10
label 0
]
edge [
source 39
target 11
label 0
]
edge [
source 39
target 12
label 0
]
edge [
source 39
target 13
label 0
]
edge [
source 39
target 14
label 0
]
edge [
source 39
target 15
label 0
]
edge [
source 39
target 16
label 0
]
edge [
source 39
target 17
label 0
]
edge [
source 39
target 18
label 0
]
edge [
source 39
target 19
label 0
]
edge [
source 39
target 20
label 0
]
edge [
source 39
target 21
label 0
]
edge [
source 39
target 22
label 0
]
edge [
source 39
target 23
label 0
]
edge [
source 39
target 24
label 0
]
edge [
source 39
target 25
label 0
]
edge [
source 39
target 26
label 0
]
edge [
source 39
target 27
label 0
]
edge [
source 39
target 28
label 0
]
edge [
source 39
target 29
label 0
]
edge [
source 39
target 30
label 0
]
edge [
source 39
target 31
label 0
]
edge [
source 39
target 32
label 0
]
edge [
source 39
target 33
label 0
]
edge [
source 39
target 34
label 0
]
edge [
source 39
target 35
label 0
]
edge [
source 39
target 36
label 0
]
edge [
source 39
target 37
label 0
]
edge [
source 39
target 38
label 0
]
edge [
source 39
target 39
label 0
]
edge [
source 40
target 1
label 0
]
edge [
source 40
target 2
label 0
]
edge [
source 40
target 3
label 0
]
edge [
source 40
target 4
label 0
]
edge [
source 40
target 5
label 0
]
edge [
source 40
target 6
label 0
]
edge [
source 40
target 7
label 0
]
edge [
source 40
target 8
label 0
]
edge [
source 40
target 9
label 0
]
edge [
source 40
target 10
label 0
]
edge [
source 40
target 11
label 0
]
edge [
source 40
target 12
label 0
]
edge [
source 40
target 13
label 0
]
edge [
source 40
target 14
label 0
]
edge [
source 40
target 15
label 0
]
edge [
source 40
target 16
label 0
]
edge [
source 40
target 17
label 0
]
edge [
source 40
target 18
label 0
]
edge [
source 40
target 19
label 0
]
edge [
source 40
target 20
label 0
]
edge [
source 40
target 21
label 0
]
edge [
source 40
target 22
label 0
]
edge [
source 40
target 23
label 0
]
edge [
source 40
target 24
label 0
]
edge [
source 40
target 25
label 0
]
edge [
source 40
target 26
label 0
]
edge [
source 40
target 27
label 0
]
edge [
source 40
target 28
label 0
]
edge [
source 40
target 29
label 0
]
edge [
source 40
target 30
label 0
]
edge [
source 40
target 31
label 0
]
edge [
source 40
target 32
label 0
]
edge [
source 40
target 33
label 0
]
edge [
source 40
target 34
label 0
]
edge [
source 40
target 35
label 0
]
edge [
source 40
target 36
label 0
]
edge [
source 40
target 37
label 0
]
edge [
source 40
target 38
label 0
]
edge [
source 40
target 39
label 0
]
edge [
source 40
target 40
label 0
]
edge [
source 41
target 1
label 0
]
edge [
source 41
target 2
label 0
]
edge [
source 41
target 3
label 0
]
edge [
source 41
target 4
label 0
]
edge [
source 41
target 5
label 0
]
edge [
source 41
target 6
label 0
]
edge [
source 41
target 7
label 0
]
edge [
source 41
target 8
label 0
]
edge [
source 41
target 9
label 0
]
edge [
source 41
target 10
label 0
]
edge [
source 41
target 11
label 0
]
edge [
source 41
target 12
label 0
]
edge [
source 41
target 13
label 0
]
edge [
source 41
target 14
label 0
]
edge [
source 41
target 15
label 0
]
edge [
source 41
target 16
label 0
]
edge [
source 41
target 17
label 0
]
edge [
source 41
target 18
label 0
]
edge [
source 41
target 19
label 0
]
edge [
source 41
target 20
label 0
]
edge [
source 41
target 21
label 0
]
edge [
source 41
target 22
label 0
]
edge [
source 41
target 23
label 0
]
edge [
source 41
target 24
label 0
]
edge [
source 41
target 25
label 0
]
edge [
source 41
target 26
label 0
]
edge [
source 41
target 27
label 0
]
edge [
source 41
target 28
label 0
]
edge [
source 41
target 29
label 0
]
edge [
source 41
target 30
label 0
]
edge [
source 41
target 31
label 0
]
edge [
source 41
target 32
label 0
]
edge [
source 41
target 33
label 0
]
edge [
source 41
target 34
label 0
]
edge [
source 41
target 35
label 0
]
edge [
source 41
target 36
label 0
]
edge [
source 41
target 37
label 0
]
edge [
source 41
target 38
label 0
]
edge [
source 41
target 39
label 0
]
edge [
source 41
target 40
label 0
]
edge [
source 41
target 41
label 0
]
edge [
source 42
target 1
label 0
]
edge [
source 42
target 2
label 0
]
edge [
source 42
target 3
label 0
]
edge [
source 42
target 4
label 0
]
edge [
source 42
target 5
label 0
]
edge [
source 42
target 6
label 0
]
edge [
source 42
target 7
label 0
]
edge [
source 42
target 8
label 0
]
edge [
source 42
target 9
label 0
]
edge [
source 42
target 10
label 0
]
edge [
source 42
target 11
label 0
]
edge [
source 42
target 12
label 0
]
edge [
source 42
target 13
label 0
]
edge [
source 42
target 14
label 0
]
edge [
source 42
target 15
label 0
]
edge [
source 42
target 16
label 0
]
edge [
source 42
target 17
label 0
]
edge [
source 42
target 18
label 0
]
edge [
source 42
target 19
label 0
]
edge [
source 42
target 20
label 0
]
edge [
source 42
target 21
label 0
]
edge [
source 42
target 22
label 0
]
edge [
source 42
target 23
label 0
]
edge [
source 42
target 24
label 0
]
edge [
source 42
target 25
label 0
]
edge [
source 42
target 26
label 0
]
edge [
source 42
target 27
label 0
]
edge [
source 42
target 28
label 0
]
edge [
source 42
target 29
label 0
]
edge [
source 42
target 30
label 0
]
edge [
source 42
target 31
label 0
]
edge [
source 42
target 32
label 0
]
edge [
source 42
target 33
label 0
]
edge [
source 42
target 34
label 0
]
edge [
source 42
target 35
label 0
]
edge [
source 42
target 36
label 0
]
edge [
source 42
target 37
label 0
]
edge [
source 42
target 38
label 0
]
edge [
source 42
target 39
label 0
]
edge [
source 42
target 40
label 0
]
edge [
source 42
target 41
label 0
]
edge [
source 42
target 42
label 0
]
edge [
source 43
target 1
label 0
]
edge [
source 43
target 2
label 0
]
edge [
source 43
target 3
label 0
]
edge [
source 43
target 4
label 0
]
edge [
source 43
target 5
label 0
]
edge [
source 43
target 6
label 0
]
edge [
source 43
target 7
label 0
]
edge [
source 43
target 8
label 0
]
edge [
source 43
target 9
label 0
]
edge [
source 43
target 10
label 0
]
edge [
source 43
target 11
label 0
]
edge [
source 43
target 12
label 0
]
edge [
source 43
target 13
label 0
]
edge [
source 43
target 14
label 0
]
edge [
source 43
target 15
label 0
]
edge [
source 43
target 16
label 0
]
edge [
source 43
target 17
label 0
]
edge [
source 43
target 18
label 0
]
edge [
source 43
target 19
label 0
]
edge [
source 43
target 20
label 0
]
edge [
source 43
target 21
label 0
]
edge [
source 43
target 22
label 0
]
edge [
source 43
target 23
label 0
]
edge [
source 43
target 24
label 0
]
edge [
source 43
target 25
label 0
]
edge [
source 43
target 26
label 0
]
edge [
source 43
target 27
label 0
]
edge [
source 43
target 28
label 0
]
edge [
source 43
target 29
label 0
]
edge [
source 43
target 30
label 0
]
edge [
source 43
target 31
label 0
]
edge [
source 43
target 32
label 0
]
edge [
source 43
target 33
label 0
]
edge [
source 43
target 34
label 0
]
edge [
source 43
target 35
label 0
]
edge [
source 43
target 36
label 0
]
edge [
source 43
target 37
label 0
]
edge [
source 43
target 38
label 0
]
edge [
source 43
target 39
label 0
]
edge [
source 43
target 40
label 0
]
edge [
source 43
target 41
label 0
]
edge [
source 43
target 42
label 0
]
edge [
source 43
target 43
label 0
]
edge [
source 44
target 1
label 0
]
edge [
source 44
target 2
label 0
]
edge [
source 44
target 3
label 0
]
edge [
source 44
target 4
label 0
]
edge [
source 44
target 5
label 0
]
edge [
source 44
target 6
label 0
]
edge [
source 44
target 7
label 0
]
edge [
source 44
target 8
label 0
]
edge [
source 44
target 9
label 0
]
edge [
source 44
target 10
label 0
]
edge [
source 44
target 11
label 0
]
edge [
source 44
target 12
label 0
]
edge [
source 44
target 13
label 0
]
edge [
source 44
target 14
label 0
]
edge [
source 44
target 15
label 0
]
edge [
source 44
target 16
label 0
]
edge [
source 44
target 17
label 0
]
edge [
source 44
target 18
label 0
]
edge [
source 44
target 19
label 0
]
edge [
source 44
target 20
label 0
]
edge [
source 44
target 21
label 0
]
edge [
source 44
target 22
label 0
]
edge [
source 44
target 23
label 0
]
edge [
source 44
target 24
label 0
]
edge [
source 44
target 25
label 0
]
edge [
source 44
target 26
label 0
]
edge [
source 44
target 27
label 0
]
edge [
source 44
target 28
label 0
]
edge [
source 44
target 29
label 0
]
edge [
source 44
target 30
label 0
]
edge [
source 44
target 31
label 0
]
edge [
source 44
target 32
label 0
]
edge [
source 44
target 33
label 0
]
edge [
source 44
target 34
label 0
]
edge [
source 44
target 35
label 0
]
edge [
source 44
target 36
label 0
]
edge [
source 44
target 37
label 0
]
edge [
source 44
target 38
label 0
]
edge [
source 44
target 39
label 0
]
edge [
source 44
target 40
label 0
]
edge [
source 44
target 41
label 0
]
edge [
source 44
target 42
label 0
]
edge [
source 44
target 43
label 0
]
edge [
source 44
target 44
label 0
]
edge [
source 45
target 1
label 0
]
edge [
source 45
target 2
label 0
]
edge [
source 45
target 3
label 0
]
edge [
source 45
target 4
label 0
]
edge [
source 45
target 5
label 0
]
edge [
source 45
target 6
label 0
]
edge [
source 45
target 7
label 0
]
edge [
source 45
target 8
label 0
]
edge [
source 45
target 9
label 0
]
edge [
source 45
target 10
label 0
]
edge [
source 45
target 11
label 0
]
edge [
source 45
target 12
label 0
]
edge [
source 45
target 13
label 0
]
edge [
source 45
target 14
label 0
]
edge [
source 45
target 15
label 0
]
edge [
source 45
target 16
label 0
]
edge [
source 45
target 17
label 0
]
edge [
source 45
target 18
label 0
]
edge [
source 45
target 19
label 0
]
edge [
source 45
target 20
label 0
]
edge [
source 45
target 21
label 0
]
edge [
source 45
target 22
label 0
]
edge [
source 45
target 23
label 0
]
edge [
source 45
target 24
label 0
]
edge [
source 45
target 25
label 0
]
edge [
source 45
target 26
label 0
]
edge [
source 45
target 27
label 0
]
edge [
source 45
target 28
label 0
]
edge [
source 45
target 29
label 0
]
edge [
source 45
target 30
label 0
]
edge [
source 45
target 31
label 0
]
edge [
source 45
target 32
label 0
]
edge [
source 45
target 33
label 0
]
edge [
source 45
target 34
label 0
]
edge [
source 45
target 35
label 0
]
edge [
source 45
target 36
label 0
]
edge [
source 45
target 37
label 0
]
edge [
source 45
target 38
label 0
]
edge [
source 45
target 39
label 0
]
edge [
source 45
target 40
label 0
]
edge [
source 45
target 41
label 0
]
edge [
source 45
target 42
label 0
]
edge [
source 45
target 43
label 0
]
edge [
source 45
target 44
label 0
]
edge [
source 45
target 45
label 0
]
edge [
source 46
target 1
label 0
]
edge [
source 46
target 2
label 0
]
edge [
source 46
target 3
label 0
]
edge [
source 46
target 4
label 0
]
edge [
source 46
target 5
label 0
]
edge [
source 46
target 6
label 0
]
edge [
source 46
target 7
label 0
]
edge [
source 46
target 8
label 0
]
edge [
source 46
target 9
label 0
]
edge [
source 46
target 10
label 0
]
edge [
source 46
target 11
label 0
]
edge [
source 46
target 12
label 0
]
edge [
source 46
target 13
label 0
]
edge [
source 46
target 14
label 0
]
edge [
source 46
target 15
label 0
]
edge [
source 46
target 16
label 0
]
edge [
source 46
target 17
label 0
]
edge [
source 46
target 18
label 0
]
edge [
source 46
target 19
label 0
]
edge [
source 46
target 20
label 0
]
edge [
source 46
target 21
label 0
]
edge [
source 46
target 22
label 0
]
edge [
source 46
target 23
label 0
]
edge [
source 46
target 24
label 0
]
edge [
source 46
target 25
label 0
]
edge [
source 46
target 26
label 0
]
edge [
source 46
target 27
label 0
]
edge [
source 46
target 28
label 0
]
edge [
source 46
target 29
label 0
]
edge [
source 46
target 30
label 0
]
edge [
source 46
target 31
label 0
]
edge [
source 46
target 32
label 0
]
edge [
source 46
target 33
label 0
]
edge [
source 46
target 34
label 0
]
edge [
source 46
target 35
label 0
]
edge [
source 46
target 36
label 0
]
edge [
source 46
target 37
label 0
]
edge [
source 46
target 38
label 0
]
edge [
source 46
target 39
label 0
]
edge [
source 46
target 40
label 0
]
edge [
source 46
target 41
label 0
]
edge [
source 46
target 42
label 0
]
edge [
source 46
target 43
label 0
]
edge [
source 46
target 44
label 0
]
edge [
source 46
target 45
label 0
]
edge [
source 46
target 46
label 0
]
edge [
source 47
target 1
label 0
]
edge [
source 47
target 2
label 0
]
edge [
source 47
target 3
label 0
]
edge [
source 47
target 4
label 0
]
edge [
source 47
target 5
label 0
]
edge [
source 47
target 6
label 0
]
edge [
source 47
target 7
label 0
]
edge [
source 47
target 8
label 0
]
edge [
source 47
target 9
label 0
]
edge [
source 47
target 10
label 0
]
edge [
source 47
target 11
label 0
]
edge [
source 47
target 12
label 0
]
edge [
source 47
target 13
label 0
]
edge [
source 47
target 14
label 0
]
edge [
source 47
target 15
label 0
]
edge [
source 47
target 16
label 0
]
edge [
source 47
target 17
label 0
]
edge [
source 47
target 18
label 0
]
edge [
source 47
target 19
label 0
]
edge [
source 47
target 20
label 0
]
edge [
source 47
target 21
label 0
]
edge [
source 47
target 22
label 0
]
edge [
source 47
target 23
label 0
]
edge [
source 47
target 24
label 0
]
edge [
source 47
target 25
label 0
]
edge [
source 47
target 26
label 0
]
edge [
source 47
target 27
label 0
]
edge [
source 47
target 28
label 0
]
edge [
source 47
target 29
label 0
]
edge [
source 47
target 30
label 0
]
edge [
source 47
target 31
label 0
]
edge [
source 47
target 32
label 0
]
edge [
source 47
target 33
label 0
]
edge [
source 47
target 34
label 0
]
edge [
source 47
target 35
label 0
]
edge [
source 47
target 36
label 0
]
edge [
source 47
target 37
label 0
]
edge [
source 47
target 38
label 0
]
edge [
source 47
target 39
label 0
]
edge [
source 47
target 40
label 0
]
edge [
source 47
target 41
label 0
]
edge [
source 47
target 42
label 0
]
edge [
source 47
target 43
label 0
]
edge [
source 47
target 44
label 0
]
edge [
source 47
target 45
label 0
]
edge [
source 47
target 46
label 0
]
edge [
source 47
target 47
label 0
]
edge [
source 48
target 1
label 0
]
edge [
source 48
target 2
label 0
]
edge [
source 48
target 3
label 0
]
edge [
source 48
target 4
label 0
]
edge [
source 48
target 5
label 0
]
edge [
source 48
target 6
label 0
]
edge [
source 48
target 7
label 0
]
edge [
source 48
target 8
label 0
]
edge [
source 48
target 9
label 0
]
edge [
source 48
target 10
label 0
]
edge [
source 48
target 11
label 0
]
edge [
source 48
target 12
label 0
]
edge [
source 48
target 13
label 0
]
edge [
source 48
target 14
label 0
]
edge [
source 48
target 15
label 0
]
edge [
source 48
target 16
label 0
]
edge [
source 48
target 17
label 0
]
edge [
source 48
target 18
label 0
]
edge [
source 48
target 19
label 0
]
edge [
source 48
target 20
label 0
]
edge [
source 48
target 21
label 0
]
edge [
source 48
target 22
label 0
]
edge [
source 48
target 23
label 0
]
edge [
source 48
target 24
label 0
]
edge [
source 48
target 25
label 0
]
edge [
source 48
target 26
label 0
]
edge [
source 48
target 27
label 0
]
edge [
source 48
target 28
label 0
]
edge [
source 48
target 29
label 0
]
edge [
source 48
target 30
label 0
]
edge [
source 48
target 31
label 0
]
edge [
source 48
target 32
label 0
]
edge [
source 48
target 33
label 0
]
edge [
source 48
target 34
label 0
]
edge [
source 48
target 35
label 0
]
edge [
source 48
target 36
label 0
]
edge [
source 48
target 37
label 0
]
edge [
source 48
target 38
label 0
]
edge [
source 48
target 39
label 0
]
edge [
source 48
target 40
label 0
]
edge [
source 48
target 41
label 0
]
edge [
source 48
target 42
label 0
]
edge [
source 48
target 43
label 0
]
edge [
source 48
target 44
label 0
]
edge [
source 48
target 45
label 0
]
edge [
source 48
target 46
label 0
]
edge [
source 48
target 47
label 0
]
edge [
source 48
target 48
label 0
]
edge [
source 49
target 1
label 0
]
edge [
source 49
target 2
label 0
]
edge [
source 49
target 3
label 0
]
edge [
source 49
target 4
label 0
]
edge [
source 49
target 5
label 0
]
edge [
source 49
target 6
label 0
]
edge [
source 49
target 7
label 0
]
edge [
source 49
target 8
label 0
]
edge [
source 49
target 9
label 0
]
edge [
source 49
target 10
label 0
]
edge [
source 49
target 11
label 0
]
edge [
source 49
target 12
label 0
]
edge [
source 49
target 13
label 0
]
edge [
source 49
target 14
label 0
]
edge [
source 49
target 15
label 0
]
edge [
source 49
target 16
label 0
]
edge [
source 49
target 17
label 0
]
edge [
source 49
target 18
label 0
]
edge [
source 49
target 19
label 0
]
edge [
source 49
target 20
label 0
]
edge [
source 49
target 21
label 0
]
edge [
source 49
target 22
label 0
]
edge [
source 49
target 23
label 0
]
edge [
source 49
target 24
label 0
]
edge [
source 49
target 25
label 0
]
edge [
source 49
target 26
label 0
]
edge [
source 49
target 27
label 0
]
edge [
source 49
target 28
label 0
]
edge [
source 49
target 29
label 0
]
edge [
source 49
target 30
label 0
]
edge [
source 49
target 31
label 0
]
edge [
source 49
target 32
label 0
]
edge [
source 49
target 33
label 0
]
edge [
source 49
target 34
label 0
]
edge [
source 49
target 35
label 0
]
edge [
source 49
target 36
label 0
]
edge [
source 49
target 37
label 0
]
edge [
source 49
target 38
label 0
]
edge [
source 49
target 39
label 0
]
edge [
source 49
target 40
label 0
]
edge [
source 49
target 41
label 0
]
edge [
source 49
target 42
label 0
]
edge [
source 49
target 43
label 0
]
edge [
source 49
target 44
label 0
]
edge [
source 49
target 45
label 0
]
edge [
source 49
target 46
label 0
]
edge [
source 49
target 47
label 0
]
edge [
source 49
target 48
label 0
]
edge [
source 49
target 49
label 0
]
edge [
source 50
target 1
label 0
]
edge [
source 50
target 2
label 0
]
edge [
source 50
target 3
label 0
]
edge [
source 50
target 4
label 0
]
edge [
source 50
target 5
label 0
]
edge [
source 50
target 6
label 0
]
edge [
source 50
target 7
label 0
]
edge [
source 50
target 8
label 0
]
edge [
source 50
target 9
label 0
]
edge [
source 50
target 10
label 0
]
edge [
source 50
target 11
label 0
]
edge [
source 50
target 12
label 0
]
edge [
source 50
target 13
label 0
]
edge [
source 50
target 14
label 0
]
edge [
source 50
target 15
label 0
]
edge [
source 50
target 16
label 0
]
edge [
source 50
target 17
label 0
]
edge [
source 50
target 18
label 0
]
edge [
source 50
target 19
label 0
]
edge [
source 50
target 20
label 0
]
edge [
source 50
target 21
label 0
]
edge [
source 50
target 22
label 0
]
edge [
source 50
target 23
label 0
]
edge [
source 50
target 24
label 0
]
edge [
source 50
target 25
label 0
]
edge [
source 50
target 26
label 0
]
edge [
source 50
target 27
label 0
]
edge [
source 50
target 28
label 0
]
edge [
source 50
target 29
label 0
]
edge [
source 50
target 30
label 0
]
edge [
source 50
target 31
label 0
]
edge [
source 50
target 32
label 0
]
edge [
source 50
target 33
label 0
]
edge [
source 50
target 34
label 0
]
edge [
source 50
target 35
label 0
]
edge [
source 50
target 36
label 0
]
edge [
source 50
target 37
label 0
]
edge [
source 50
target 38
label 0
]
edge [
source 50
target 39
label 0
]
edge [
source 50
target 40
label 0
]
edge [
source 50
target 41
label 0
]
edge [
source 50
target 42
label 0
]
edge [
source 50
target 43
label 0
]
edge [
source 50
target 44
label 0
]
edge [
source 50
target 45
label 0
]
edge [
source 50
target 46
label 0
]
edge [
source 50
target 47
label 0
]
edge [
source 50
target 48
label 0
]
edge [
source 50
target 49
label 0
]
edge [
source 50
target 50
label 0
]
]
ocamlgraph-2.0.0/editor/tests/rand_10_40.gml 0000644 0001750 0000144 00000004540 13735627615 017074 0 ustar rt users graph [
node [
id 1
label 0
]
node [
id 2
label 1
]
node [
id 3
label 2
]
node [
id 4
label 3
]
node [
id 5
label 4
]
node [
id 6
label 5
]
node [
id 7
label 6
]
node [
id 8
label 7
]
node [
id 9
label 8
]
node [
id 10
label 9
]
edge [
source 2
target 1
label 0
]
edge [
source 3
target 1
label 0
]
edge [
source 3
target 2
label 0
]
edge [
source 4
target 1
label 0
]
edge [
source 4
target 2
label 0
]
edge [
source 5
target 1
label 0
]
edge [
source 5
target 2
label 0
]
edge [
source 5
target 3
label 0
]
edge [
source 5
target 4
label 0
]
edge [
source 6
target 1
label 0
]
edge [
source 6
target 2
label 0
]
edge [
source 6
target 5
label 0
]
edge [
source 7
target 1
label 0
]
edge [
source 7
target 2
label 0
]
edge [
source 7
target 3
label 0
]
edge [
source 7
target 4
label 0
]
edge [
source 7
target 5
label 0
]
edge [
source 7
target 6
label 0
]
edge [
source 8
target 1
label 0
]
edge [
source 8
target 2
label 0
]
edge [
source 8
target 3
label 0
]
edge [
source 8
target 4
label 0
]
edge [
source 8
target 5
label 0
]
edge [
source 8
target 6
label 0
]
edge [
source 8
target 7
label 0
]
edge [
source 9
target 1
label 0
]
edge [
source 9
target 2
label 0
]
edge [
source 9
target 3
label 0
]
edge [
source 9
target 4
label 0
]
edge [
source 9
target 5
label 0
]
edge [
source 9
target 6
label 0
]
edge [
source 9
target 8
label 0
]
edge [
source 10
target 1
label 0
]
edge [
source 10
target 3
label 0
]
edge [
source 10
target 4
label 0
]
edge [
source 10
target 5
label 0
]
edge [
source 10
target 6
label 0
]
edge [
source 10
target 7
label 0
]
edge [
source 10
target 8
label 0
]
edge [
source 10
target 9
label 0
]
]
ocamlgraph-2.0.0/editor/tests/twopi2.dot 0000644 0001750 0000144 00000432713 13735627615 016607 0 ustar rt users digraph G {
ranksep=3;
ratio=auto;
"1" [ label="02f5daf56e299b8a8ecea892",shape="hexagon",style="filled",color="green" ];
"189E" [ label="ca5af2",shape="box",style="filled",color="grey" ];
"790E" [ label="b4dfef6",shape="box",style="filled",color="grey" ];
"2" [ label="171192dc1f8e6ea551548a910c00",shape="hexagon",style="filled",color="green" ];
"191E" [ label="629e42",shape="box",style="filled",color="grey" ];
"3" [ label="6bce02baf91781a831e1b95",shape="hexagon",style="filled",color="green" ];
"193E" [ label="1c08373",shape="box",style="filled",color="grey" ];
"4" [ label="6236a67933a619a6a3d48",shape="hexagon",style="filled",color="green" ];
"195E" [ label="be8f4199f",shape="box",style="filled",color="grey" ];
"5" [ label="50962c93b4cb293f5beb59eb",shape="hexagon",style="filled",color="green" ];
"197E" [ label="be8f4199f",shape="box",style="filled",color="grey" ];
"6" [ label="05d4b1ed6a6135eec3abd3f2",shape="hexagon",style="filled",color="green" ];
"199E" [ label="",shape="box",style="filled",color="grey" ];
"7" [ label="08769f73d31c1a99be2d9363f",shape="hexagon",style="filled",color="green" ];
"201E" [ label="629e42",shape="box",style="filled",color="grey" ];
"8" [ label="a6a196a504c3a7657d1fa41",shape="hexagon",style="filled",color="green" ];
"203E" [ label="cd856f",shape="box",style="filled",color="grey" ];
"9" [ label="837ebf4bde22e1f1535cb662",shape="hexagon",style="filled",color="green" ];
"725E" [ label="d0eb84",shape="box",style="filled",color="grey" ];
"785E" [ label="dd2ba36",shape="box",style="filled",color="grey" ];
"10" [ label="5f865c374cb3fe976dd376b8",shape="hexagon",style="filled",color="green" ];
"205E" [ label="23ad1",shape="box",style="filled",color="grey" ];
"11" [ label="8be752bc95d436a90493bec9",shape="hexagon",style="filled",color="green" ];
"207E" [ label="ee91c97828",shape="box",style="filled",color="grey" ];
"12" [ label="969a58db14386cb9d2f51ec",shape="hexagon",style="filled",color="green" ];
"209E" [ label="7c7c",shape="box",style="filled",color="grey" ];
"13" [ label="da24f74aad2ff519009d1f38c",shape="hexagon",style="filled",color="green" ];
"211E" [ label="460aed10cc9",shape="box",style="filled",color="grey" ];
"14" [ label="3124d3a6ed3381a6341c6",shape="hexagon",style="filled",color="green" ];
"213E" [ label="bbe0a8f93dc1",shape="box",style="filled",color="grey" ];
"15" [ label="71512ec7d43f958f2b6da",shape="hexagon",style="filled",color="green" ];
"215E" [ label="3f0a2b4eb62f",shape="box",style="filled",color="grey" ];
"16" [ label="3828a2c682419423cf",shape="hexagon",style="filled",color="green" ];
"727E" [ label="2",shape="box",style="filled",color="grey" ];
"784E" [ label="",shape="box",style="filled",color="grey" ];
"17" [ label="aa868f65c34cdb64f1fad19a",shape="hexagon",style="filled",color="green" ];
"217E" [ label="3089106e3b",shape="box",style="filled",color="grey" ];
"787E" [ label="1aaaab063",shape="box",style="filled",color="grey" ];
"18" [ label="dca32af03698c988b22",shape="hexagon",style="filled",color="green" ];
"219E" [ label="eb8",shape="box",style="filled",color="grey" ];
"19" [ label="d8f4a9e463a1e89217f",shape="hexagon",style="filled",color="green" ];
"221E" [ label="4c6c8c",shape="box",style="filled",color="grey" ];
"20" [ label="c96782ef56711c5d6a3f69",shape="hexagon",style="filled",color="green" ];
"223E" [ label="6a8f5bafb1",shape="box",style="filled",color="grey" ];
"21" [ label="4f04c39708f",shape="hexagon",style="filled",color="green" ];
"225E" [ label="a49284e9",shape="box",style="filled",color="grey" ];
"22" [ label="97284d4c3a5d499853f0e",shape="hexagon",style="filled",color="green" ];
"227E" [ label="53069e384a2",shape="box",style="filled",color="grey" ];
"792E" [ label="79b69c612",shape="box",style="filled",color="grey" ];
"23" [ label="c4d32527b670afb370d643",shape="hexagon",style="filled",color="green" ];
"231E" [ label="e851f5ddd920",shape="box",style="filled",color="grey" ];
"24" [ label="5e9156098c064",shape="hexagon",style="filled",color="green" ];
"233E" [ label="",shape="box",style="filled",color="grey" ];
"25" [ label="3d475ea3aeca51b60212dd",shape="hexagon",style="filled",color="green" ];
"235E" [ label="4280833ef80172",shape="box",style="filled",color="grey" ];
"26" [ label="966d271c22e75c7538",shape="hexagon",style="filled",color="green" ];
"237E" [ label="cab04b7c14a",shape="box",style="filled",color="grey" ];
"27" [ label="b630e1af6ae1997f0e8ba750",shape="hexagon",style="filled",color="green" ];
"239E" [ label="bb828f1a326",shape="box",style="filled",color="grey" ];
"783E" [ label="499f6985db294c",shape="box",style="filled",color="grey" ];
"28" [ label="ebd8ffc2ac3a90efb8af9",shape="hexagon",style="filled",color="green" ];
"241E" [ label="1ebeec",shape="box",style="filled",color="grey" ];
"791E" [ label="c0b727",shape="box",style="filled",color="grey" ];
"29" [ label="69fdd1a1f4768c5efe7",shape="hexagon",style="filled",color="green" ];
"243E" [ label="35b8742610",shape="box",style="filled",color="grey" ];
"30" [ label="d93a80739fc1edb41a11b7294",shape="hexagon",style="filled",color="green" ];
"245E" [ label="e03b8bc0435a",shape="box",style="filled",color="grey" ];
"31" [ label="bf65cfddeb00ff847feae0c",shape="hexagon",style="filled",color="green" ];
"247E" [ label="8df",shape="box",style="filled",color="grey" ];
"32" [ label="916c686a1e82dba72524a",shape="hexagon",style="filled",color="green" ];
"249E" [ label="a849f9d352e",shape="box",style="filled",color="grey" ];
"33" [ label="f496bcf0889b301d77819c",shape="hexagon",style="filled",color="green" ];
"251E" [ label="f29dfb9",shape="box",style="filled",color="grey" ];
"34" [ label="76889f7d35e",shape="hexagon",style="filled",color="green" ];
"253E" [ label="e7ef998",shape="box",style="filled",color="grey" ];
"35" [ label="668d636002",shape="hexagon",style="filled",color="green" ];
"255E" [ label="4379b5ed",shape="box",style="filled",color="grey" ];
"36" [ label="e1e4c23db39d8bd633c3a",shape="hexagon",style="filled",color="green" ];
"257E" [ label="1ed5d7f63b8c6",shape="box",style="filled",color="grey" ];
"37" [ label="842bc5775657c1e0d67",shape="hexagon",style="filled",color="green" ];
"259E" [ label="a387210a27b",shape="box",style="filled",color="grey" ];
"38" [ label="e4e2f4e6d",shape="hexagon",style="filled",color="green" ];
"261E" [ label="1f4f0fdf",shape="box",style="filled",color="grey" ];
"39" [ label="04390dec6f1779353c07f5",shape="hexagon",style="filled",color="green" ];
"263E" [ label="bac77c3f414a",shape="box",style="filled",color="grey" ];
"40" [ label="69f2611acc42c36ed7cc",shape="hexagon",style="filled",color="green" ];
"265E" [ label="cab04b7c14a",shape="box",style="filled",color="grey" ];
"41" [ label="1562abef0d8241",shape="hexagon",style="filled",color="green" ];
"267E" [ label="6a8f5bafb1",shape="box",style="filled",color="grey" ];
"42" [ label="e49aaa5cc4e44355d6a0",shape="hexagon",style="filled",color="green" ];
"269E" [ label="cc3f63d",shape="box",style="filled",color="grey" ];
"43" [ label="e8ebe1bf5f421c1223",shape="hexagon",style="filled",color="green" ];
"271E" [ label="96325ea",shape="box",style="filled",color="grey" ];
"44" [ label="2759e82e30d6d",shape="hexagon",style="filled",color="green" ];
"273E" [ label="ca5af2",shape="box",style="filled",color="grey" ];
"45" [ label="23c1ec53358d237c1",shape="hexagon",style="filled",color="green" ];
"275E" [ label="cab04b7c14a",shape="box",style="filled",color="grey" ];
"46" [ label="5838586c293d455",shape="hexagon",style="filled",color="green" ];
"277E" [ label="83c397b8bf7f",shape="box",style="filled",color="grey" ];
"47" [ label="f841118350a27b7ea29a9c9d",shape="hexagon",style="filled",color="green" ];
"279E" [ label="69f4ecb77d",shape="box",style="filled",color="grey" ];
"48" [ label="658d208447d8ec5d6de8",shape="hexagon",style="filled",color="green" ];
"281E" [ label="f7b22b9640",shape="box",style="filled",color="grey" ];
"49" [ label="11180ae7706510211bc4",shape="hexagon",style="filled",color="green" ];
"283E" [ label="052bb6e3",shape="box",style="filled",color="grey" ];
"50" [ label="5807acd8d58e006f43",shape="hexagon",style="filled",color="green" ];
"285E" [ label="",shape="box",style="filled",color="grey" ];
"51" [ label="fe4e848cb5291ee59a2",shape="hexagon",style="filled",color="green" ];
"287E" [ label="e3aefac763",shape="box",style="filled",color="grey" ];
"52" [ label="c4f31ea3844e12da27ad47c6",shape="hexagon",style="filled",color="green" ];
"289E" [ label="fb16636aae",shape="box",style="filled",color="grey" ];
"53" [ label="00cbeb87c182ca0785f",shape="hexagon",style="filled",color="green" ];
"291E" [ label="3089106e3b",shape="box",style="filled",color="grey" ];
"54" [ label="11f088bfd8",shape="hexagon",style="filled",color="green" ];
"293E" [ label="6a80cbe",shape="box",style="filled",color="grey" ];
"55" [ label="64a9ec24428099ad8ed82ba6",shape="hexagon",style="filled",color="green" ];
"745E" [ label="68d8993e61d8c82cd29e8d0182b0",shape="box",style="filled",color="grey" ];
"56" [ label="3c2a62e0e5e9f7",shape="hexagon",style="filled",color="green" ];
"295E" [ label="ae32701",shape="box",style="filled",color="grey" ];
"57" [ label="dd84fe6a65cfac7bca03ebd",shape="hexagon",style="filled",color="green" ];
"297E" [ label="",shape="box",style="filled",color="grey" ];
"58" [ label="b06bbfa920aa95dd",shape="hexagon",style="filled",color="green" ];
"299E" [ label="07",shape="box",style="filled",color="grey" ];
"59" [ label="6b5aaa4bdf44b2c898854",shape="hexagon",style="filled",color="green" ];
"301E" [ label="4c6c8c",shape="box",style="filled",color="grey" ];
"789E" [ label="3a0ff0",shape="box",style="filled",color="grey" ];
"60" [ label="855d26296eda4eb7",shape="hexagon",style="filled",color="green" ];
"303E" [ label="53069e384a2",shape="box",style="filled",color="grey" ];
"61" [ label="e82f47b8d4949ba4af69b38cbc19",shape="hexagon",style="filled",color="green" ];
"305E" [ label="b62cd1d0a0",shape="box",style="filled",color="grey" ];
"62" [ label="86569bffb49adf6b3d0ebac",shape="hexagon",style="filled",color="green" ];
"307E" [ label="660ffeb76fc59",shape="box",style="filled",color="grey" ];
"63" [ label="a96e47ff37983425a3e452095",shape="hexagon",style="filled",color="green" ];
"309E" [ label="cab04b7c14a",shape="box",style="filled",color="grey" ];
"64" [ label="71a48d11b2e7e56b1df128bd",shape="hexagon",style="filled",color="green" ];
"311E" [ label="be8f4199f",shape="box",style="filled",color="grey" ];
"65" [ label="a0befe6dd1ca7b165786835",shape="hexagon",style="filled",color="green" ];
"313E" [ label="3cfae",shape="box",style="filled",color="grey" ];
"66" [ label="f33ec11db496f7bfcb024f",shape="hexagon",style="filled",color="green" ];
"315E" [ label="71e6b",shape="box",style="filled",color="grey" ];
"67" [ label="fe6be3206549f5b5564acde84783",shape="hexagon",style="filled",color="green" ];
"317E" [ label="",shape="box",style="filled",color="grey" ];
"68" [ label="e4dba079d5fcb1f165920a3bf",shape="hexagon",style="filled",color="green" ];
"319E" [ label="",shape="box",style="filled",color="grey" ];
"69" [ label="35dfbee3123dc389cba0b15",shape="hexagon",style="filled",color="green" ];
"746E" [ label="4c865eec228e41e7f4e5fc68a9a6",shape="box",style="filled",color="grey" ];
"70" [ label="16c508ab98483d430bbe",shape="hexagon",style="filled",color="green" ];
"321E" [ label="cab04b7c14a",shape="box",style="filled",color="grey" ];
"71" [ label="9c9e2e0f2da8758e436c",shape="hexagon",style="filled",color="green" ];
"327E" [ label="cd0d985a366cad7e",shape="box",style="filled",color="grey" ];
"72" [ label="fb039d7a2a9fe73b5f468eba9",shape="hexagon",style="filled",color="green" ];
"329E" [ label="81dabfaba8",shape="box",style="filled",color="grey" ];
"73" [ label="2ef949c4a39b",shape="hexagon",style="filled",color="green" ];
"331E" [ label="617809d979f",shape="box",style="filled",color="grey" ];
"74" [ label="a9497e0757b0969bde707ed5",shape="hexagon",style="filled",color="green" ];
"333E" [ label="541ab86a2e",shape="box",style="filled",color="grey" ];
"75" [ label="230cc6bbc66b24eae94fa03d",shape="hexagon",style="filled",color="green" ];
"335E" [ label="",shape="box",style="filled",color="grey" ];
"76" [ label="1d163eac141def176461c",shape="hexagon",style="filled",color="green" ];
"337E" [ label="0acc5bb8ca4",shape="box",style="filled",color="grey" ];
"77" [ label="32979f8cf86",shape="hexagon",style="filled",color="green" ];
"339E" [ label="a7e89580",shape="box",style="filled",color="grey" ];
"78" [ label="37d80ae421dba4a70730338860",shape="hexagon",style="filled",color="green" ];
"341E" [ label="",shape="box",style="filled",color="grey" ];
"79" [ label="fbba7215e7c13173a60206",shape="hexagon",style="filled",color="green" ];
"343E" [ label="617809d979f",shape="box",style="filled",color="grey" ];
"80" [ label="2dd8cc4d693415f93c0f8fc",shape="hexagon",style="filled",color="green" ];
"345E" [ label="94da691e20e3",shape="box",style="filled",color="grey" ];
"81" [ label="00880e6f50c765ebc1f85d3e9",shape="hexagon",style="filled",color="green" ];
"347E" [ label="e7ef998",shape="box",style="filled",color="grey" ];
"82" [ label="ef13d45b1277ac9a0444adb",shape="hexagon",style="filled",color="green" ];
"349E" [ label="a7fe7",shape="box",style="filled",color="grey" ];
"83" [ label="2573e1bf51f1b307f4640",shape="hexagon",style="filled",color="green" ];
"351E" [ label="84e4ede82074",shape="box",style="filled",color="grey" ];
"84" [ label="162d8039483d8",shape="hexagon",style="filled",color="green" ];
"353E" [ label="a8e9",shape="box",style="filled",color="grey" ];
"85" [ label="f490de272a7f6e4af346d40",shape="hexagon",style="filled",color="green" ];
"355E" [ label="460aed10cc9",shape="box",style="filled",color="grey" ];
"788E" [ label="391256c872",shape="box",style="filled",color="grey" ];
"86" [ label="678bf739c344b9ad41da1",shape="hexagon",style="filled",color="green" ];
"357E" [ label="396b16a892fe",shape="box",style="filled",color="grey" ];
"87" [ label="876d120b38b0e88817",shape="hexagon",style="filled",color="green" ];
"359E" [ label="e5",shape="box",style="filled",color="grey" ];
"88" [ label="503737b64d432c60d6ac557e0e6",shape="hexagon",style="filled",color="green" ];
"361E" [ label="9937ccba1469",shape="box",style="filled",color="grey" ];
"89" [ label="b36e0be6f67fc25286127456",shape="hexagon",style="filled",color="green" ];
"363E" [ label="87a7e69a72412",shape="box",style="filled",color="grey" ];
"90" [ label="4cc20a0b7651e486",shape="hexagon",style="filled",color="green" ];
"365E" [ label="e079d2c",shape="box",style="filled",color="grey" ];
"91" [ label="08dade990b2282",shape="hexagon",style="filled",color="green" ];
"367E" [ label="45827dbdd8",shape="box",style="filled",color="grey" ];
"92" [ label="f8128d574c356631b8a9",shape="hexagon",style="filled",color="green" ];
"369E" [ label="",shape="box",style="filled",color="grey" ];
"93" [ label="88a4f0337c2189c3fc7b31",shape="hexagon",style="filled",color="green" ];
"729E" [ label="da0d7bbcf30",shape="box",style="filled",color="grey" ];
"94" [ label="1b13908a9f0763c0ae54af9062080",shape="hexagon",style="filled",color="green" ];
"371E" [ label="8b06a67a",shape="box",style="filled",color="grey" ];
"95" [ label="e2a5d11499b7e",shape="hexagon",style="filled",color="green" ];
"373E" [ label="66abc181ac4",shape="box",style="filled",color="grey" ];
"96" [ label="90cc275011c2013c61eb11",shape="hexagon",style="filled",color="green" ];
"375E" [ label="",shape="box",style="filled",color="grey" ];
"97" [ label="1e003bfe8fc840df0163f4c",shape="hexagon",style="filled",color="green" ];
"747E" [ label="8983ffbc30deb364dd92c3ad85c9",shape="box",style="filled",color="grey" ];
"98" [ label="1927c743a0d440a5a0",shape="hexagon",style="filled",color="green" ];
"377E" [ label="b12441ecff15fa12c",shape="box",style="filled",color="grey" ];
"99" [ label="155d892827c33ed3cae3",shape="hexagon",style="filled",color="green" ];
"379E" [ label="71e6b",shape="box",style="filled",color="grey" ];
"100" [ label="9f24ba80192c339a64c0",shape="hexagon",style="filled",color="green" ];
"381E" [ label="",shape="box",style="filled",color="grey" ];
"101" [ label="3e814305b42beb41b8c706",shape="hexagon",style="filled",color="green" ];
"383E" [ label="1c08373",shape="box",style="filled",color="grey" ];
"102" [ label="eccfe5ff0af70fe9fbec8b2360f90",shape="hexagon",style="filled",color="green" ];
"385E" [ label="be8f4199f",shape="box",style="filled",color="grey" ];
"103" [ label="8fa622d9f842c5572a545ed72982",shape="hexagon",style="filled",color="green" ];
"387E" [ label="4dccb",shape="box",style="filled",color="grey" ];
"104" [ label="ad9142a65f5eab78b4ca5e",shape="hexagon",style="filled",color="green" ];
"389E" [ label="f36cce089",shape="box",style="filled",color="grey" ];
"105" [ label="20f234fdcd0e1fc50261ce8",shape="hexagon",style="filled",color="green" ];
"391E" [ label="67219ef689f0146b544",shape="box",style="filled",color="grey" ];
"106" [ label="e06cc38155ff6781cf944d745",shape="hexagon",style="filled",color="green" ];
"393E" [ label="87a7e69a72412",shape="box",style="filled",color="grey" ];
"107" [ label="cfdf1932665dcb4cd3c",shape="hexagon",style="filled",color="green" ];
"395E" [ label="964b86fc1bba0e",shape="box",style="filled",color="grey" ];
"108" [ label="6d4a4a5a5af91b895272c30",shape="hexagon",style="filled",color="green" ];
"397E" [ label="b5e86c73d1198f",shape="box",style="filled",color="grey" ];
"109" [ label="e0ad365c2fb444358201",shape="hexagon",style="filled",color="green" ];
"399E" [ label="bb5e89c8963",shape="box",style="filled",color="grey" ];
"110" [ label="b07bbdc8cca5985d4c4",shape="hexagon",style="filled",color="green" ];
"401E" [ label="50023f6f88",shape="box",style="filled",color="grey" ];
"111" [ label="df5dba74c75b228de48c",shape="hexagon",style="filled",color="green" ];
"403E" [ label="7e493ee44b28",shape="box",style="filled",color="grey" ];
"112" [ label="0b8694c9ef9b27b9c3d8",shape="hexagon",style="filled",color="green" ];
"405E" [ label="2342b759c03",shape="box",style="filled",color="grey" ];
"113" [ label="81e20155999fa64e0ae6fd",shape="hexagon",style="filled",color="green" ];
"407E" [ label="4280833ef80172",shape="box",style="filled",color="grey" ];
"114" [ label="3ef07ae75d29a707",shape="hexagon",style="filled",color="green" ];
"409E" [ label="4280833ef80172",shape="box",style="filled",color="grey" ];
"115" [ label="4a36db80f1ab1e97",shape="hexagon",style="filled",color="green" ];
"411E" [ label="460aed10cc9",shape="box",style="filled",color="grey" ];
"116" [ label="16da5f1301b36df4df0f",shape="hexagon",style="filled",color="green" ];
"413E" [ label="460aed10cc9",shape="box",style="filled",color="grey" ];
"117" [ label="6b3f3fa236bb90592d23a",shape="hexagon",style="filled",color="green" ];
"415E" [ label="83c397b8bf7f",shape="box",style="filled",color="grey" ];
"118" [ label="f2a57e4d4f0cec516891e3",shape="hexagon",style="filled",color="green" ];
"417E" [ label="bd2484",shape="box",style="filled",color="grey" ];
"119" [ label="deb3089920548bf1ecb23f0d",shape="hexagon",style="filled",color="green" ];
"419E" [ label="87a7e69a72412",shape="box",style="filled",color="grey" ];
"120" [ label="bf01c8a262",shape="hexagon",style="filled",color="green" ];
"421E" [ label="01",shape="box",style="filled",color="grey" ];
"121" [ label="23dc3a52fed9c119610b5e8",shape="hexagon",style="filled",color="green" ];
"423E" [ label="71e6b",shape="box",style="filled",color="grey" ];
"122" [ label="aff7fc220edc93572bb2",shape="hexagon",style="filled",color="green" ];
"748E" [ label="68d8993e61d8c82cd29e8d0182b0",shape="box",style="filled",color="grey" ];
"123" [ label="78cc16f965adc5f712ea2372c6",shape="hexagon",style="filled",color="green" ];
"425E" [ label="23ad1",shape="box",style="filled",color="grey" ];
"124" [ label="5be631dff7b97697be7dc0a2f07f2",shape="hexagon",style="filled",color="green" ];
"427E" [ label="",shape="box",style="filled",color="grey" ];
"786E" [ label="421",shape="box",style="filled",color="grey" ];
"125" [ label="48398d080dfcccced48da1980",shape="hexagon",style="filled",color="green" ];
"431E" [ label="866808df",shape="box",style="filled",color="grey" ];
"126" [ label="03716a2c341e5edaa31",shape="hexagon",style="filled",color="green" ];
"433E" [ label="21407f8a6d7",shape="box",style="filled",color="grey" ];
"127" [ label="ddfeabe456a9de5f5784",shape="hexagon",style="filled",color="green" ];
"435E" [ label="aac615ae78",shape="box",style="filled",color="grey" ];
"128" [ label="d550a7f392c787661aadd48",shape="hexagon",style="filled",color="green" ];
"437E" [ label="e3aefac763",shape="box",style="filled",color="grey" ];
"129" [ label="4c82921f4ad3f07066540",shape="hexagon",style="filled",color="green" ];
"439E" [ label="a7fe7",shape="box",style="filled",color="grey" ];
"130" [ label="0bc7f8f513e0e74b270",shape="hexagon",style="filled",color="green" ];
"441E" [ label="a849f9d352e",shape="box",style="filled",color="grey" ];
"131" [ label="3b1563a23eb9",shape="hexagon",style="filled",color="green" ];
"443E" [ label="a8e9",shape="box",style="filled",color="grey" ];
"132" [ label="be233fafa38d931d894",shape="hexagon",style="filled",color="green" ];
"445E" [ label="a849f9d352e",shape="box",style="filled",color="grey" ];
"133" [ label="f906dc5244ee6a371f8",shape="hexagon",style="filled",color="green" ];
"749E" [ label="4c865eec228e41e7f4e5fc68a9a6",shape="box",style="filled",color="grey" ];
"134" [ label="e7a887d88c2318beba51",shape="hexagon",style="filled",color="green" ];
"447E" [ label="9d8988c0945d6",shape="box",style="filled",color="grey" ];
"135" [ label="be6b73bd46a7a5183e8c91a",shape="hexagon",style="filled",color="green" ];
"449E" [ label="ee91c97828",shape="box",style="filled",color="grey" ];
"769E" [ label="444189d179b5db71fe",shape="box",style="filled",color="grey" ];
"770E" [ label="1e1fbbe14ac24e0518",shape="box",style="filled",color="grey" ];
"136" [ label="644f112bb0aa452ee7040a",shape="hexagon",style="filled",color="green" ];
"451E" [ label="52f247fc3b",shape="box",style="filled",color="grey" ];
"137" [ label="010957669f3770aac",shape="hexagon",style="filled",color="green" ];
"453E" [ label="78",shape="box",style="filled",color="grey" ];
"138" [ label="0a185946ee443342b07d8e1",shape="hexagon",style="filled",color="green" ];
"455E" [ label="87a7e69a72412",shape="box",style="filled",color="grey" ];
"139" [ label="f66fe4df3d189e69ce10c9c",shape="hexagon",style="filled",color="green" ];
"457E" [ label="21407f8a6d7",shape="box",style="filled",color="grey" ];
"140" [ label="247e407f45b353f8",shape="hexagon",style="filled",color="green" ];
"459E" [ label="",shape="box",style="filled",color="grey" ];
"141" [ label="84907547f36d0ff7",shape="hexagon",style="filled",color="green" ];
"461E" [ label="e920b915087",shape="box",style="filled",color="grey" ];
"142" [ label="805004328dad9d315d",shape="hexagon",style="filled",color="green" ];
"463E" [ label="4280833ef80172",shape="box",style="filled",color="grey" ];
"143" [ label="4f0cbd3fbf0cb1e8c",shape="hexagon",style="filled",color="green" ];
"465E" [ label="403126",shape="box",style="filled",color="grey" ];
"144" [ label="4869e993f2bb10f",shape="hexagon",style="filled",color="green" ];
"467E" [ label="ff",shape="box",style="filled",color="grey" ];
"145" [ label="665b76844ff78fc2cf66ca2",shape="hexagon",style="filled",color="green" ];
"469E" [ label="af0268dddd",shape="box",style="filled",color="grey" ];
"146" [ label="3f16509139c7dad5163b91799",shape="hexagon",style="filled",color="green" ];
"471E" [ label="3089106e3b",shape="box",style="filled",color="grey" ];
"147" [ label="01db23a60422ba93a68611cc0",shape="hexagon",style="filled",color="green" ];
"473E" [ label="",shape="box",style="filled",color="grey" ];
"148" [ label="46125fcc583c0f494a3a1d3",shape="hexagon",style="filled",color="green" ];
"475E" [ label="db6c4213a717bc",shape="box",style="filled",color="grey" ];
"149" [ label="731857fe189fb398e80a0594",shape="hexagon",style="filled",color="green" ];
"477E" [ label="3089106e3b",shape="box",style="filled",color="grey" ];
"150" [ label="6fb7a84e370ef70feac5cb",shape="hexagon",style="filled",color="green" ];
"479E" [ label="396b16a892fe",shape="box",style="filled",color="grey" ];
"151" [ label="e343cea291b79a2ed4e",shape="hexagon",style="filled",color="green" ];
"481E" [ label="88d8b220746882d",shape="box",style="filled",color="grey" ];
"152" [ label="5f2592b20f13356b7fc8b42",shape="hexagon",style="filled",color="green" ];
"483E" [ label="",shape="box",style="filled",color="grey" ];
"153" [ label="275a0407e33e9b8aa9cdd051",shape="hexagon",style="filled",color="green" ];
"731E" [ label="",shape="box",style="filled",color="grey" ];
"154" [ label="011d119375cf494ca2fa8d59",shape="hexagon",style="filled",color="green" ];
"750E" [ label="8983ffbc30deb364dd92c3ad85c9",shape="box",style="filled",color="grey" ];
"155" [ label="173fd00917644f0f1f3e3",shape="hexagon",style="filled",color="green" ];
"485E" [ label="0acc5bb8ca4",shape="box",style="filled",color="grey" ];
"156" [ label="c72df69b40156a3254",shape="hexagon",style="filled",color="green" ];
"487E" [ label="fff03efcd",shape="box",style="filled",color="grey" ];
"157" [ label="6c632ad9c42228bb337",shape="hexagon",style="filled",color="green" ];
"489E" [ label="eb8",shape="box",style="filled",color="grey" ];
"158" [ label="bbb13dc62adf2de2a42b6",shape="hexagon",style="filled",color="green" ];
"491E" [ label="69ce90c9b2",shape="box",style="filled",color="grey" ];
"159" [ label="6282bc21f6",shape="hexagon",style="filled",color="green" ];
"495E" [ label="de34214b4c258c9333ec3",shape="box",style="filled",color="grey" ];
"160" [ label="71cf45dd4e91bcca945137b40e",shape="hexagon",style="filled",color="green" ];
"499E" [ label="65fd8495",shape="box",style="filled",color="grey" ];
"161" [ label="a3b6df27179b175c88fa4c9cf9f",shape="hexagon",style="filled",color="green" ];
"501E" [ label="6577",shape="box",style="filled",color="grey" ];
"162" [ label="284f14a259991806654e74",shape="hexagon",style="filled",color="green" ];
"503E" [ label="4280833ef80172",shape="box",style="filled",color="grey" ];
"163" [ label="a7c99ccf6ddf6f5ebbe",shape="hexagon",style="filled",color="green" ];
"505E" [ label="c4fd8",shape="box",style="filled",color="grey" ];
"164" [ label="c32d2697e8",shape="hexagon",style="filled",color="green" ];
"507E" [ label="52f247fc3b",shape="box",style="filled",color="grey" ];
"165" [ label="d12bd75c24b110ef90cdd35d3",shape="hexagon",style="filled",color="green" ];
"509E" [ label="0668",shape="box",style="filled",color="grey" ];
"166" [ label="1c07453d584f3d14b1876fdb",shape="hexagon",style="filled",color="green" ];
"511E" [ label="460aed10cc9",shape="box",style="filled",color="grey" ];
"167" [ label="f713a8b311ffa05ce3683ad10",shape="hexagon",style="filled",color="green" ];
"513E" [ label="30d6138b63eb",shape="box",style="filled",color="grey" ];
"168" [ label="3cdc90c57243373efaba65a",shape="hexagon",style="filled",color="green" ];
"515E" [ label="fa2afbd869",shape="box",style="filled",color="grey" ];
"169" [ label="e3bdbca0e2256fffa8a59018",shape="hexagon",style="filled",color="green" ];
"517E" [ label="81dabfaba8",shape="box",style="filled",color="grey" ];
"170" [ label="75ba8d840070942eb4e737849",shape="hexagon",style="filled",color="green" ];
"519E" [ label="81dabfaba8",shape="box",style="filled",color="grey" ];
"171" [ label="fbdc3ca37406f66635c8b226e",shape="hexagon",style="filled",color="green" ];
"521E" [ label="8cbcf5cb5",shape="box",style="filled",color="grey" ];
"172" [ label="40b49a5a9bb256c7a3286e56",shape="hexagon",style="filled",color="green" ];
"523E" [ label="f72564578be",shape="box",style="filled",color="grey" ];
"173" [ label="3b2f08d52e4bca3f9ca7bbbd6",shape="hexagon",style="filled",color="green" ];
"525E" [ label="81dabfaba8",shape="box",style="filled",color="grey" ];
"174" [ label="4a38abc630c82b0c48dfbf5271",shape="hexagon",style="filled",color="green" ];
"527E" [ label="f0bd1521",shape="box",style="filled",color="grey" ];
"175" [ label="2d7b7fb6c9ad6821752651f7",shape="hexagon",style="filled",color="green" ];
"529E" [ label="47b2da3d",shape="box",style="filled",color="grey" ];
"176" [ label="910b00285f11bb90d0a15641",shape="hexagon",style="filled",color="green" ];
"531E" [ label="81dabfaba8",shape="box",style="filled",color="grey" ];
"177" [ label="24431c3eb075102f07cc2c1be",shape="hexagon",style="filled",color="green" ];
"533E" [ label="",shape="box",style="filled",color="grey" ];
"178" [ label="07f8a9e55a16beddb3c9153b0",shape="hexagon",style="filled",color="green" ];
"535E" [ label="81dabfaba8",shape="box",style="filled",color="grey" ];
"179" [ label="c1c30f30d40c4f1f84924622f",shape="hexagon",style="filled",color="green" ];
"537E" [ label="c5d5be3942",shape="box",style="filled",color="grey" ];
"180" [ label="86276bb1e23f2c7ffcbe82a0",shape="hexagon",style="filled",color="green" ];
"539E" [ label="0f940646",shape="box",style="filled",color="grey" ];
"181" [ label="f78e145a127014eb43345a0c",shape="hexagon",style="filled",color="green" ];
"541E" [ label="d370c12dbc",shape="box",style="filled",color="grey" ];
"182" [ label="a27037332d9fa5c43bcfe94c0",shape="hexagon",style="filled",color="green" ];
"543E" [ label="80874aa8",shape="box",style="filled",color="grey" ];
"183" [ label="c29ce10bb8d19b498355aa04",shape="hexagon",style="filled",color="green" ];
"545E" [ label="1c08373",shape="box",style="filled",color="grey" ];
"184" [ label="4f8c642b53c349c687534bda35db",shape="hexagon",style="filled",color="green" ];
"547E" [ label="46969c4",shape="box",style="filled",color="grey" ];
"185" [ label="30cc206b1878485",shape="hexagon",style="filled",color="green" ];
"549E" [ label="23ad1",shape="box",style="filled",color="grey" ];
"186" [ label="5d69639a5e3bdd3d",shape="hexagon",style="filled",color="green" ];
"551E" [ label="6139fa6adc88d",shape="box",style="filled",color="grey" ];
"187" [ label="b656f0ed2202b8e46eb",shape="hexagon",style="filled",color="green" ];
"553E" [ label="f6e6236b48bc3",shape="box",style="filled",color="grey" ];
"188" [ label="3b566eaa70ed401479d43a9",shape="hexagon",style="filled",color="green" ];
"555E" [ label="4c6c8c",shape="box",style="filled",color="grey" ];
"189" [ label="d6125ef42bd9958",shape="hexagon",style="filled",color="green" ];
"557E" [ label="4c6c8c",shape="box",style="filled",color="grey" ];
"190" [ label="dd12f26f8d9bb55",shape="hexagon",style="filled",color="green" ];
"559E" [ label="83c397b8bf7f",shape="box",style="filled",color="grey" ];
"191" [ label="ea890ccca2f7c2107351",shape="hexagon",style="filled",color="green" ];
"561E" [ label="eb8",shape="box",style="filled",color="grey" ];
"192" [ label="84e4f1c582427a98d7b",shape="hexagon",style="filled",color="green" ];
"563E" [ label="eb8",shape="box",style="filled",color="grey" ];
"193" [ label="d378760b814eaecb6efe636e0efc4",shape="hexagon",style="filled",color="green" ];
"565E" [ label="81bcc35f82891",shape="box",style="filled",color="grey" ];
"194" [ label="f722890f70a32dce3baff371a",shape="hexagon",style="filled",color="green" ];
"567E" [ label="84e4ede82074",shape="box",style="filled",color="grey" ];
"195" [ label="666f11bb45c3a8dcf26e1ed79",shape="hexagon",style="filled",color="green" ];
"569E" [ label="c90f755c8b6612d",shape="box",style="filled",color="grey" ];
"196" [ label="91ecbe29a71f00ed5a3",shape="hexagon",style="filled",color="green" ];
"571E" [ label="0a963fef9",shape="box",style="filled",color="grey" ];
"197" [ label="30c3f3bf8463d3843dc57d8e98",shape="hexagon",style="filled",color="green" ];
"573E" [ label="3089106e3b",shape="box",style="filled",color="grey" ];
"198" [ label="8ea965ab6ee8dedb6c3333e9",shape="hexagon",style="filled",color="green" ];
"575E" [ label="84e4ede82074",shape="box",style="filled",color="grey" ];
"199" [ label="3eecb304bab2136a76deda",shape="hexagon",style="filled",color="green" ];
"577E" [ label="8df",shape="box",style="filled",color="grey" ];
"200" [ label="d886e4b76537a99bc71b8a9331c94",shape="hexagon",style="filled",color="green" ];
"579E" [ label="1172dca23",shape="box",style="filled",color="grey" ];
"201" [ label="dcc5d5e9d6c4e",shape="hexagon",style="filled",color="green" ];
"581E" [ label="a8e9",shape="box",style="filled",color="grey" ];
"202" [ label="8292af691429f8d9ed481ff71ffd",shape="hexagon",style="filled",color="green" ];
"583E" [ label="212af4",shape="box",style="filled",color="grey" ];
"203" [ label="12fcb26b3de00ef98719c2ca",shape="hexagon",style="filled",color="green" ];
"585E" [ label="",shape="box",style="filled",color="grey" ];
"204" [ label="a141a557a60912051f3c135",shape="hexagon",style="filled",color="green" ];
"587E" [ label="",shape="box",style="filled",color="grey" ];
"205" [ label="64eeeddfc34489ff396",shape="hexagon",style="filled",color="green" ];
"751E" [ label="8983ffbc30deb364dd92c3ad85c9",shape="box",style="filled",color="grey" ];
"206" [ label="f5d636e14a6cd716362158d",shape="hexagon",style="filled",color="green" ];
"589E" [ label="32c958c9997",shape="box",style="filled",color="grey" ];
"207" [ label="84e4978afc069d5a1aecbf2b",shape="hexagon",style="filled",color="green" ];
"593E" [ label="56caa96d171a9ac2da7c",shape="box",style="filled",color="grey" ];
"208" [ label="52a6c2063bccd83110c32",shape="hexagon",style="filled",color="green" ];
"597E" [ label="",shape="box",style="filled",color="grey" ];
"209" [ label="46f754ea06f070dbc023e571a876",shape="hexagon",style="filled",color="green" ];
"599E" [ label="ffccaa9e3",shape="box",style="filled",color="grey" ];
"210" [ label="c10cb9baf4dcb43e24",shape="hexagon",style="filled",color="green" ];
"601E" [ label="ac6e99186",shape="box",style="filled",color="grey" ];
"211" [ label="3dafe1619016463f521f",shape="hexagon",style="filled",color="green" ];
"603E" [ label="b9",shape="box",style="filled",color="grey" ];
"212" [ label="0f5db6ce12751ddcc64e",shape="hexagon",style="filled",color="green" ];
"605E" [ label="bb828f1a326",shape="box",style="filled",color="grey" ];
"213" [ label="34c8c8dc0f6e41c7e7b2",shape="hexagon",style="filled",color="green" ];
"607E" [ label="2832ed5cea6",shape="box",style="filled",color="grey" ];
"214" [ label="0a49c95f107c0aa57c9b5748",shape="hexagon",style="filled",color="green" ];
"609E" [ label="",shape="box",style="filled",color="grey" ];
"215" [ label="3b4fdad8e0429d112",shape="hexagon",style="filled",color="green" ];
"611E" [ label="cab04b7c14a",shape="box",style="filled",color="grey" ];
"216" [ label="17dafa5ebaafd48440e3",shape="hexagon",style="filled",color="green" ];
"613E" [ label="b5f038f79a3",shape="box",style="filled",color="grey" ];
"217" [ label="f4c69e5e212f89348122e8",shape="hexagon",style="filled",color="green" ];
"615E" [ label="396b16a892fe",shape="box",style="filled",color="grey" ];
"218" [ label="4f2e020854dfacce46a12",shape="hexagon",style="filled",color="green" ];
"617E" [ label="e079d2c",shape="box",style="filled",color="grey" ];
"219" [ label="6448451ac2ceade90715378b",shape="hexagon",style="filled",color="green" ];
"619E" [ label="",shape="box",style="filled",color="grey" ];
"220" [ label="7d7b14baa649330",shape="hexagon",style="filled",color="green" ];
"621E" [ label="77d145b32328880440c7a",shape="box",style="filled",color="grey" ];
"221" [ label="d7c27cc6f7b02a31eb64d",shape="hexagon",style="filled",color="green" ];
"623E" [ label="87a7e69a72412",shape="box",style="filled",color="grey" ];
"222" [ label="8f5a69ece1",shape="hexagon",style="filled",color="green" ];
"752E" [ label="eb9cf6456613d4cd06f7c0894bd6",shape="box",style="filled",color="grey" ];
"223" [ label="eccf7c722ddf",shape="hexagon",style="filled",color="green" ];
"625E" [ label="df61d5f5fc",shape="box",style="filled",color="grey" ];
"224" [ label="86633c26be93ada8b",shape="hexagon",style="filled",color="green" ];
"627E" [ label="08500a6044",shape="box",style="filled",color="grey" ];
"225" [ label="3f9ddf1ffbc0d38b",shape="hexagon",style="filled",color="green" ];
"629E" [ label="07",shape="box",style="filled",color="grey" ];
"226" [ label="e33792703",shape="hexagon",style="filled",color="green" ];
"631E" [ label="6a8f5bafb1",shape="box",style="filled",color="grey" ];
"227" [ label="293a225dc56dd1e0564e6bb",shape="hexagon",style="filled",color="green" ];
"633E" [ label="e3aefac763",shape="box",style="filled",color="grey" ];
"228" [ label="57c77c341f94afddef07e6",shape="hexagon",style="filled",color="green" ];
"635E" [ label="5e80f85274",shape="box",style="filled",color="grey" ];
"229" [ label="3bbfc7bfdbbb1ba1bfad7517",shape="hexagon",style="filled",color="green" ];
"637E" [ label="",shape="box",style="filled",color="grey" ];
"230" [ label="a7167d5eb5408b3839903",shape="hexagon",style="filled",color="green" ];
"639E" [ label="8c8b5bde6",shape="box",style="filled",color="grey" ];
"231" [ label="34d7bb6af4fcd8d630de72500c8",shape="hexagon",style="filled",color="green" ];
"641E" [ label="32fe7eee5283",shape="box",style="filled",color="grey" ];
"232" [ label="8e69341faa4489",shape="hexagon",style="filled",color="green" ];
"643E" [ label="cab04b7c14a",shape="box",style="filled",color="grey" ];
"233" [ label="459236f07c73814faf5",shape="hexagon",style="filled",color="green" ];
"645E" [ label="18083a711d",shape="box",style="filled",color="grey" ];
"234" [ label="c71aa521578164debd0c5",shape="hexagon",style="filled",color="green" ];
"647E" [ label="78",shape="box",style="filled",color="grey" ];
"235" [ label="a5520019b8a73bc141b5fd416a",shape="hexagon",style="filled",color="green" ];
"649E" [ label="3219b6b71443",shape="box",style="filled",color="grey" ];
"236" [ label="6c89dc59ee7aaebbbd6bb64",shape="hexagon",style="filled",color="green" ];
"651E" [ label="8c8b5bde6",shape="box",style="filled",color="grey" ];
"237" [ label="a9a36ef02f",shape="hexagon",style="filled",color="green" ];
"653E" [ label="6a80cbe",shape="box",style="filled",color="grey" ];
"238" [ label="3db761b596844f133c",shape="hexagon",style="filled",color="green" ];
"655E" [ label="e920b915087",shape="box",style="filled",color="grey" ];
"239" [ label="383db224d7508ef072bea21d0",shape="hexagon",style="filled",color="green" ];
"657E" [ label="975fedfb64df",shape="box",style="filled",color="grey" ];
"240" [ label="8e307415fb435445ced7",shape="hexagon",style="filled",color="green" ];
"659E" [ label="21dff35936370ae5f",shape="box",style="filled",color="grey" ];
"241" [ label="aff6d7896e0e142bbc3e78",shape="hexagon",style="filled",color="green" ];
"661E" [ label="d2498",shape="box",style="filled",color="grey" ];
"242" [ label="e153c6e676c7369b285b4e9033a",shape="hexagon",style="filled",color="green" ];
"663E" [ label="",shape="box",style="filled",color="grey" ];
"243" [ label="f3c4311de0e931f08c232b",shape="hexagon",style="filled",color="green" ];
"665E" [ label="a849f9d352e",shape="box",style="filled",color="grey" ];
"244" [ label="0c72a426929600000f5",shape="hexagon",style="filled",color="green" ];
"667E" [ label="45827dbdd8",shape="box",style="filled",color="grey" ];
"245" [ label="38fa61352f5086d2cb51",shape="hexagon",style="filled",color="green" ];
"669E" [ label="af0268dddd",shape="box",style="filled",color="grey" ];
"246" [ label="ad1dd724f1c3e",shape="hexagon",style="filled",color="green" ];
"671E" [ label="cab04b7c14a",shape="box",style="filled",color="grey" ];
"247" [ label="11bb8ed3ae227d3acefc",shape="hexagon",style="filled",color="green" ];
"673E" [ label="eb8",shape="box",style="filled",color="grey" ];
"248" [ label="f2c7b3bb4d44f977d0ab8a42351",shape="hexagon",style="filled",color="green" ];
"675E" [ label="",shape="box",style="filled",color="grey" ];
"249" [ label="51e045ca826077ae765",shape="hexagon",style="filled",color="green" ];
"679E" [ label="e842",shape="box",style="filled",color="grey" ];
"250" [ label="aa0adc8978020629574",shape="hexagon",style="filled",color="green" ];
"753E" [ label="68d8993e61d8c82cd29e8d0182b0",shape="box",style="filled",color="grey" ];
"251" [ label="3b6b2c549de670d7bf5fc0ee",shape="hexagon",style="filled",color="green" ];
"681E" [ label="",shape="box",style="filled",color="grey" ];
"252" [ label="5eea496cc301b2a9721",shape="hexagon",style="filled",color="green" ];
"683E" [ label="",shape="box",style="filled",color="grey" ];
"253" [ label="bfc6564cbdeeffac00a141",shape="hexagon",style="filled",color="green" ];
"685E" [ label="3b0a8a1c2e5050bd",shape="box",style="filled",color="grey" ];
"254" [ label="c360aaeb167487c9578a8f",shape="hexagon",style="filled",color="green" ];
"687E" [ label="d",shape="box",style="filled",color="grey" ];
"255" [ label="39d025b265f9790490781cb201",shape="hexagon",style="filled",color="green" ];
"689E" [ label="5e80f85274",shape="box",style="filled",color="grey" ];
"256" [ label="b4ce21e0a3df1d097277d6",shape="hexagon",style="filled",color="green" ];
"691E" [ label="a849f9d352e",shape="box",style="filled",color="grey" ];
"257" [ label="8bdb6a91c6dee925b557c705b3",shape="hexagon",style="filled",color="green" ];
"693E" [ label="53069e384a2",shape="box",style="filled",color="grey" ];
"258" [ label="ac487676a04e4",shape="hexagon",style="filled",color="green" ];
"695E" [ label="a8e9",shape="box",style="filled",color="grey" ];
"259" [ label="18115fa32ff1cb99",shape="hexagon",style="filled",color="green" ];
"697E" [ label="45827dbdd8",shape="box",style="filled",color="grey" ];
"260" [ label="b7b899dc8bc6a32b28cb098fa16",shape="hexagon",style="filled",color="green" ];
"699E" [ label="32fe7eee5283",shape="box",style="filled",color="grey" ];
"261" [ label="b69e426d974e1907e88",shape="hexagon",style="filled",color="green" ];
"703E" [ label="e842",shape="box",style="filled",color="grey" ];
"262" [ label="60d0128bdb61ae40e98638bd1391",shape="hexagon",style="filled",color="green" ];
"705E" [ label="23ad1",shape="box",style="filled",color="grey" ];
"264" [ label="8fb60d769e4c387",shape="hexagon",style="filled",color="green" ];
"709E" [ label="6a8f5bafb1",shape="box",style="filled",color="grey" ];
"265" [ label="e1fa7f549e5a0893bb42da5",shape="hexagon",style="filled",color="green" ];
"711E" [ label="6a3c6921b0aeceda3",shape="box",style="filled",color="grey" ];
"266" [ label="a77622f2ff77ffeeb2",shape="hexagon",style="filled",color="green" ];
"713E" [ label="21dff35936370ae5f",shape="box",style="filled",color="grey" ];
"267" [ label="30d9d350943c0e3ff7594b50",shape="hexagon",style="filled",color="green" ];
"715E" [ label="b5e86c73d1198f",shape="box",style="filled",color="grey" ];
"268" [ label="89ced1a7906d58d687d5a04",shape="hexagon",style="filled",color="green" ];
"717E" [ label="c0174bbe7ae8",shape="box",style="filled",color="grey" ];
"269" [ label="1de26f6b12b0d292f94184",shape="hexagon",style="filled",color="green" ];
"719E" [ label="65fd8495",shape="box",style="filled",color="grey" ];
"270" [ label="26fa7360ab81be9d4434a",shape="hexagon",style="filled",color="green" ];
"721E" [ label="af0268dddd",shape="box",style="filled",color="grey" ];
"272" [ label="4a9d79c960b8d33e39251e5f66",shape="hexagon" ];
"34E" [ label="330342f283ef2",shape="box",style="filled",color="grey" ];
"252E" [ label="3dafb9a29c00",shape="box",style="filled",color="grey" ];
"436E" [ label="8d5137b16a",shape="box",style="filled",color="grey" ];
"274" [ label="10a7d61c201c67a5e78542807cd",shape="hexagon" ];
"59E" [ label="ef6361295eba07",shape="box",style="filled",color="grey" ];
"500E" [ label="a8f0fe2eb7bc1471",shape="box",style="filled",color="grey" ];
"720E" [ label="cfff3acd8e9d",shape="box",style="filled",color="grey" ];
"275" [ label="f8ff39eab120851f143bf19",shape="hexagon" ];
"98E" [ label="4e3cfd27a",shape="box",style="filled",color="grey" ];
"278" [ label="4995c71223c9f6067324d387a2",shape="hexagon" ];
"35E" [ label="57948adb5dead",shape="box",style="filled",color="grey" ];
"488E" [ label="a738ba39",shape="box",style="filled",color="grey" ];
"598E" [ label="be7d637c50c",shape="box",style="filled",color="grey" ];
"604E" [ label="8d52f183ec",shape="box",style="filled",color="grey" ];
"628E" [ label="cef12b6",shape="box",style="filled",color="grey" ];
"279" [ label="b9ae94e6935503603341ecf4",shape="hexagon" ];
"99E" [ label="14a3c17f3d",shape="box",style="filled",color="grey" ];
"280" [ label="fd28c194a46fde909b019c52f",shape="hexagon" ];
"242E" [ label="9fe65061641",shape="box",style="filled",color="grey" ];
"270E" [ label="34d06d1ed6",shape="box",style="filled",color="grey" ];
"272E" [ label="713db1c1",shape="box",style="filled",color="grey" ];
"284E" [ label="90dccb18c0",shape="box",style="filled",color="grey" ];
"286E" [ label="e17fea65",shape="box",style="filled",color="grey" ];
"288E" [ label="aebb7b91b",shape="box",style="filled",color="grey" ];
"586E" [ label="4348f3abcb7716",shape="box",style="filled",color="grey" ];
"763E" [ label="b082f7a5ff",shape="box",style="filled",color="grey" ];
"281" [ label="7c0ab977f5a3c4ab6d625f5033",shape="hexagon" ];
"45E" [ label="20949455f573f",shape="box",style="filled",color="grey" ];
"470E" [ label="c338481d79773",shape="box",style="filled",color="grey" ];
"670E" [ label="e1d01ef89f",shape="box",style="filled",color="grey" ];
"722E" [ label="c4507c22d19",shape="box",style="filled",color="grey" ];
"282" [ label="7e0b91491c8c8566892cd9a0889",shape="hexagon" ];
"103E" [ label="de9efa12873949",shape="box",style="filled",color="grey" ];
"283" [ label="d58478d9c273ad4f4b2e091324",shape="hexagon" ];
"165E" [ label="1a220eb692c",shape="box",style="filled",color="grey" ];
"284" [ label="8be0efdd94a6383e87fbfded4f",shape="hexagon" ];
"39E" [ label="c8a6c26d4fd9f",shape="box",style="filled",color="grey" ];
"224E" [ label="8cbae42a3900",shape="box",style="filled",color="grey" ];
"268E" [ label="fc73",shape="box",style="filled",color="grey" ];
"632E" [ label="",shape="box",style="filled",color="grey" ];
"710E" [ label="102f1",shape="box",style="filled",color="grey" ];
"285" [ label="3aeb78ea51020a44f2d2615436dae",shape="hexagon" ];
"53E" [ label="96deede0c6b44119",shape="box",style="filled",color="grey" ];
"286" [ label="6bbd5b422edb8e358dcc20eecf9",shape="hexagon" ];
"38E" [ label="4f2de229621272",shape="box",style="filled",color="grey" ];
"166E" [ label="d495de0b35f6",shape="box",style="filled",color="grey" ];
"288" [ label="4856000a6802ddfc121ef40432297",shape="hexagon",style="filled",color="#ff0000" ];
"40E" [ label="04904a458422a5b9",shape="box",style="filled",color="grey" ];
"218E" [ label="8cd4d",shape="box",style="filled",color="grey" ];
"244E" [ label="",shape="box",style="filled",color="grey" ];
"246E" [ label="9be88247",shape="box",style="filled",color="grey" ];
"258E" [ label="4f05b",shape="box",style="filled",color="grey" ];
"290E" [ label="8b092",shape="box",style="filled",color="grey" ];
"292E" [ label="c3bbf4",shape="box",style="filled",color="grey" ];
"308E" [ label="6331b3f",shape="box",style="filled",color="grey" ];
"318E" [ label="",shape="box",style="filled",color="grey" ];
"388E" [ label="3711",shape="box",style="filled",color="grey" ];
"472E" [ label="c5255d",shape="box",style="filled",color="grey" ];
"478E" [ label="5c6a2",shape="box",style="filled",color="grey" ];
"566E" [ label="51ec95518d1b3",shape="box",style="filled",color="grey" ];
"570E" [ label="82a65ed4b69",shape="box",style="filled",color="grey" ];
"574E" [ label="05fed5e",shape="box",style="filled",color="grey" ];
"608E" [ label="bf",shape="box",style="filled",color="grey" ];
"614E" [ label="ce",shape="box",style="filled",color="grey" ];
"658E" [ label="1a830d9f",shape="box",style="filled",color="grey" ];
"664E" [ label="",shape="box",style="filled",color="grey" ];
"682E" [ label="",shape="box",style="filled",color="grey" ];
"289" [ label="2e31175cbd52fcd08360fe86d20",shape="hexagon" ];
"41E" [ label="4ad5d68f07981a",shape="box",style="filled",color="grey" ];
"636E" [ label="51192117f9b4",shape="box",style="filled",color="grey" ];
"642E" [ label="6bf214d9e7fa5f2df",shape="box",style="filled",color="grey" ];
"690E" [ label="558d8534f92fddfe",shape="box",style="filled",color="grey" ];
"700E" [ label="6819fd5a6cdd280dd",shape="box",style="filled",color="grey" ];
"290" [ label="3aa0ce5efcf79bc3ecced1886e89",shape="hexagon" ];
"56E" [ label="ff9d64ddf49a20f",shape="box",style="filled",color="grey" ];
"264E" [ label="6c93f24516f01d",shape="box",style="filled",color="grey" ];
"510E" [ label="32b98f11f3d01d6",shape="box",style="filled",color="grey" ];
"718E" [ label="8f7c875500073",shape="box",style="filled",color="grey" ];
"291" [ label="7c1767485953d9c2",shape="hexagon" ];
"66E" [ label="086",shape="box",style="filled",color="grey" ];
"76E" [ label="",shape="box",style="filled",color="grey" ];
"610E" [ label="450d3a2d49cbfd",shape="box",style="filled",color="grey" ];
"292" [ label="9c1305d59c37e9be9f13d7d049c",shape="hexagon" ];
"73E" [ label="817",shape="box",style="filled",color="grey" ];
"293" [ label="efe092824916a5637ee35d439589",shape="hexagon" ];
"49E" [ label="",shape="box",style="filled",color="grey" ];
"214E" [ label="",shape="box",style="filled",color="grey" ];
"216E" [ label="",shape="box",style="filled",color="grey" ];
"236E" [ label="",shape="box",style="filled",color="grey" ];
"278E" [ label="",shape="box",style="filled",color="grey" ];
"358E" [ label="",shape="box",style="filled",color="grey" ];
"398E" [ label="",shape="box",style="filled",color="grey" ];
"400E" [ label="",shape="box",style="filled",color="grey" ];
"402E" [ label="",shape="box",style="filled",color="grey" ];
"404E" [ label="",shape="box",style="filled",color="grey" ];
"406E" [ label="",shape="box",style="filled",color="grey" ];
"408E" [ label="",shape="box",style="filled",color="grey" ];
"412E" [ label="",shape="box",style="filled",color="grey" ];
"438E" [ label="",shape="box",style="filled",color="grey" ];
"448E" [ label="",shape="box",style="filled",color="grey" ];
"476E" [ label="",shape="box",style="filled",color="grey" ];
"504E" [ label="",shape="box",style="filled",color="grey" ];
"552E" [ label="",shape="box",style="filled",color="grey" ];
"634E" [ label="",shape="box",style="filled",color="grey" ];
"768E" [ label="",shape="box",style="filled",color="grey" ];
"295" [ label="70815f0352b43dc1562133ab6eb",shape="hexagon",style="filled",color="#A52A2A" ];
"44E" [ label="ef2d4636934472",shape="box",style="filled",color="grey" ];
"92E" [ label="22bd92e302816",shape="box",style="filled",color="grey" ];
"250E" [ label="74e86",shape="box",style="filled",color="grey" ];
"316E" [ label="",shape="box",style="filled",color="grey" ];
"380E" [ label="",shape="box",style="filled",color="grey" ];
"424E" [ label="c",shape="box",style="filled",color="grey" ];
"442E" [ label="a5a",shape="box",style="filled",color="grey" ];
"446E" [ label="bce",shape="box",style="filled",color="grey" ];
"454E" [ label="",shape="box",style="filled",color="grey" ];
"460E" [ label="",shape="box",style="filled",color="grey" ];
"462E" [ label="",shape="box",style="filled",color="grey" ];
"648E" [ label="",shape="box",style="filled",color="grey" ];
"656E" [ label="e9",shape="box",style="filled",color="grey" ];
"666E" [ label="b701e7",shape="box",style="filled",color="grey" ];
"692E" [ label="f2e7cc",shape="box",style="filled",color="grey" ];
"712E" [ label="8a9eb2806b0aa",shape="box",style="filled",color="grey" ];
"296" [ label="e287d497450664a4c0f4efc338",shape="hexagon",style="filled",color="#ff0000" ];
"47E" [ label="06eff1db45cdf",shape="box",style="filled",color="grey" ];
"330E" [ label="c0f34a600",shape="box",style="filled",color="grey" ];
"514E" [ label="bd7aca295ca",shape="box",style="filled",color="grey" ];
"516E" [ label="0da9135",shape="box",style="filled",color="grey" ];
"518E" [ label="fe821bce",shape="box",style="filled",color="grey" ];
"520E" [ label="e64f22a31",shape="box",style="filled",color="grey" ];
"522E" [ label="46e412a3",shape="box",style="filled",color="grey" ];
"526E" [ label="99da1f8a5",shape="box",style="filled",color="grey" ];
"528E" [ label="0f167280",shape="box",style="filled",color="grey" ];
"530E" [ label="82d201",shape="box",style="filled",color="grey" ];
"532E" [ label="1d529eb4",shape="box",style="filled",color="grey" ];
"534E" [ label="",shape="box",style="filled",color="grey" ];
"536E" [ label="bf141dbce",shape="box",style="filled",color="grey" ];
"538E" [ label="e3fd0c7b3",shape="box",style="filled",color="grey" ];
"540E" [ label="c96cb3",shape="box",style="filled",color="grey" ];
"542E" [ label="0fabab47",shape="box",style="filled",color="grey" ];
"544E" [ label="1b82200",shape="box",style="filled",color="grey" ];
"297" [ label="2ced414a91575a48f2dd29a",shape="hexagon" ];
"46E" [ label="85221d5e9e",shape="box",style="filled",color="grey" ];
"93E" [ label="97a7eea3f",shape="box",style="filled",color="grey" ];
"206E" [ label="4d22e1",shape="box",style="filled",color="grey" ];
"426E" [ label="e65185ca",shape="box",style="filled",color="grey" ];
"550E" [ label="",shape="box",style="filled",color="grey" ];
"706E" [ label="a9012b7bb5",shape="box",style="filled",color="grey" ];
"298" [ label="38f162cf917ce7298663a1f1c607",shape="hexagon" ];
"36E" [ label="a031c9192ae8e75",shape="box",style="filled",color="grey" ];
"95E" [ label="062fc905b9eb35",shape="box",style="filled",color="grey" ];
"364E" [ label="c8fc17180bea86",shape="box",style="filled",color="grey" ];
"394E" [ label="09e64744536c5e1",shape="box",style="filled",color="grey" ];
"420E" [ label="af4a1fac3e2076",shape="box",style="filled",color="grey" ];
"456E" [ label="238805e2194c3",shape="box",style="filled",color="grey" ];
"624E" [ label="73e6ed83012",shape="box",style="filled",color="grey" ];
"299" [ label="549fa15d68f0b3bee6192f888cd8",shape="hexagon" ];
"48E" [ label="d17f8f4eeb8e63d",shape="box",style="filled",color="grey" ];
"168E" [ label="cca7040e47789",shape="box",style="filled",color="grey" ];
"260E" [ label="47ebc3f17",shape="box",style="filled",color="grey" ];
"282E" [ label="cf5a6049ad",shape="box",style="filled",color="grey" ];
"554E" [ label="2a47a6a27",shape="box",style="filled",color="grey" ];
"590E" [ label="eff3468631dd4",shape="box",style="filled",color="grey" ];
"767E" [ label="efb52b499303115c33fd",shape="box",style="filled",color="grey" ];
"300" [ label="8593dcf973b110d00cecdc1e756",shape="hexagon",style="filled",color="#ff7f00" ];
"62E" [ label="472a156cf2b55f",shape="box",style="filled",color="grey" ];
"190E" [ label="647",shape="box",style="filled",color="grey" ];
"226E" [ label="",shape="box",style="filled",color="grey" ];
"238E" [ label="8a",shape="box",style="filled",color="grey" ];
"254E" [ label="",shape="box",style="filled",color="grey" ];
"256E" [ label="",shape="box",style="filled",color="grey" ];
"262E" [ label="",shape="box",style="filled",color="grey" ];
"266E" [ label="e8b",shape="box",style="filled",color="grey" ];
"274E" [ label="",shape="box",style="filled",color="grey" ];
"276E" [ label="f",shape="box",style="filled",color="grey" ];
"294E" [ label="",shape="box",style="filled",color="grey" ];
"296E" [ label="",shape="box",style="filled",color="grey" ];
"310E" [ label="1b34fb150",shape="box",style="filled",color="grey" ];
"320E" [ label="",shape="box",style="filled",color="grey" ];
"322E" [ label="a7d2",shape="box",style="filled",color="grey" ];
"332E" [ label="",shape="box",style="filled",color="grey" ];
"340E" [ label="",shape="box",style="filled",color="grey" ];
"344E" [ label="f55670",shape="box",style="filled",color="grey" ];
"346E" [ label="1ed67841",shape="box",style="filled",color="grey" ];
"348E" [ label="07283",shape="box",style="filled",color="grey" ];
"374E" [ label="73ba1714ee",shape="box",style="filled",color="grey" ];
"378E" [ label="27709106",shape="box",style="filled",color="grey" ];
"452E" [ label="93ea0",shape="box",style="filled",color="grey" ];
"508E" [ label="",shape="box",style="filled",color="grey" ];
"524E" [ label="1d792d81",shape="box",style="filled",color="grey" ];
"612E" [ label="a",shape="box",style="filled",color="grey" ];
"626E" [ label="",shape="box",style="filled",color="grey" ];
"638E" [ label="",shape="box",style="filled",color="grey" ];
"644E" [ label="",shape="box",style="filled",color="grey" ];
"654E" [ label="",shape="box",style="filled",color="grey" ];
"672E" [ label="",shape="box",style="filled",color="grey" ];
"302" [ label="23f94655294d3ff537f2915fa",shape="hexagon" ];
"797E" [ label="",shape="box",style="filled",color="grey" ];
"798E" [ label="a2eab7c9fa641e5f",shape="box",style="filled",color="grey" ];
"303" [ label="a9058241db5b6b6c25569acdf5",shape="hexagon" ];
"52E" [ label="b2babf3244213",shape="box",style="filled",color="grey" ];
"650E" [ label="b354cd9e9dbb0bfa",shape="box",style="filled",color="grey" ];
"304" [ label="bdbdb31bd777fb65dd6dd2d0e7",shape="hexagon" ];
"50E" [ label="3bec1c012b498",shape="box",style="filled",color="grey" ];
"640E" [ label="c54f0fc1e05",shape="box",style="filled",color="grey" ];
"646E" [ label="9ab6c66dc",shape="box",style="filled",color="grey" ];
"652E" [ label="699e3db878047",shape="box",style="filled",color="grey" ];
"306" [ label="1d4ea80c7194689d69f9592186",shape="hexagon" ];
"55E" [ label="8066f87a88f4e",shape="box",style="filled",color="grey" ];
"220E" [ label="3a8173d6c",shape="box",style="filled",color="grey" ];
"338E" [ label="24dfe1a997a",shape="box",style="filled",color="grey" ];
"368E" [ label="65a1",shape="box",style="filled",color="grey" ];
"486E" [ label="59a8b435ccd",shape="box",style="filled",color="grey" ];
"490E" [ label="86e9b0428",shape="box",style="filled",color="grey" ];
"562E" [ label="5a7a610a8a",shape="box",style="filled",color="grey" ];
"564E" [ label="8f143077e",shape="box",style="filled",color="grey" ];
"600E" [ label="6472c2861e0e0dd681",shape="box",style="filled",color="grey" ];
"668E" [ label="f0f45e707",shape="box",style="filled",color="grey" ];
"674E" [ label="95e93c4a13",shape="box",style="filled",color="grey" ];
"698E" [ label="33e1de",shape="box",style="filled",color="grey" ];
"307" [ label="7204950f6233bf9c9e1f00d4a870",shape="hexagon" ];
"107E" [ label="ccceeef40edda78",shape="box",style="filled",color="grey" ];
"308" [ label="a2c4b1d72e2da483a86ae0c62e5",shape="hexagon" ];
"108E" [ label="eedc819a68add6",shape="box",style="filled",color="grey" ];
"309" [ label="f603819d560c5603259aa05dca",shape="hexagon" ];
"109E" [ label="acacfc83af504",shape="box",style="filled",color="grey" ];
"310" [ label="2f43cba12702078b4e0d3bfdae2bc",shape="hexagon" ];
"110E" [ label="3c1edc8de4795936",shape="box",style="filled",color="grey" ];
"311" [ label="8f9cdc26798117dd3e9ee4a8770",shape="hexagon" ];
"58E" [ label="881d373",shape="box",style="filled",color="grey" ];
"234E" [ label="",shape="box",style="filled",color="grey" ];
"300E" [ label="",shape="box",style="filled",color="grey" ];
"306E" [ label="8c7cd9b93b1cbe48e1",shape="box",style="filled",color="grey" ];
"314E" [ label="616d8a7b",shape="box",style="filled",color="grey" ];
"342E" [ label="",shape="box",style="filled",color="grey" ];
"354E" [ label="",shape="box",style="filled",color="grey" ];
"370E" [ label="",shape="box",style="filled",color="grey" ];
"382E" [ label="",shape="box",style="filled",color="grey" ];
"422E" [ label="",shape="box",style="filled",color="grey" ];
"444E" [ label="",shape="box",style="filled",color="grey" ];
"582E" [ label="",shape="box",style="filled",color="grey" ];
"620E" [ label="",shape="box",style="filled",color="grey" ];
"630E" [ label="",shape="box",style="filled",color="grey" ];
"684E" [ label="",shape="box",style="filled",color="grey" ];
"696E" [ label="",shape="box",style="filled",color="grey" ];
"801E" [ label="",shape="box",style="filled",color="grey" ];
"312" [ label="97c9d726e27304311901a52ce",shape="hexagon",style="filled",color="#ff0000" ];
"42E" [ label="1112164c2f7a",shape="box",style="filled",color="grey" ];
"192E" [ label="5c609b12c",shape="box",style="filled",color="grey" ];
"194E" [ label="00265",shape="box",style="filled",color="grey" ];
"196E" [ label="04767",shape="box",style="filled",color="grey" ];
"198E" [ label="f0d99f16",shape="box",style="filled",color="grey" ];
"200E" [ label="",shape="box",style="filled",color="grey" ];
"202E" [ label="6e186b",shape="box",style="filled",color="grey" ];
"204E" [ label="d382",shape="box",style="filled",color="grey" ];
"312E" [ label="c6b5321a",shape="box",style="filled",color="grey" ];
"336E" [ label="",shape="box",style="filled",color="grey" ];
"376E" [ label="",shape="box",style="filled",color="grey" ];
"384E" [ label="aeb8",shape="box",style="filled",color="grey" ];
"386E" [ label="2e53009d4a375",shape="box",style="filled",color="grey" ];
"428E" [ label="",shape="box",style="filled",color="grey" ];
"474E" [ label="",shape="box",style="filled",color="grey" ];
"484E" [ label="",shape="box",style="filled",color="grey" ];
"546E" [ label="dea1d1",shape="box",style="filled",color="grey" ];
"548E" [ label="5a0b4b906a",shape="box",style="filled",color="grey" ];
"314" [ label="1727041c622518c9dd24f7c211",shape="hexagon" ];
"113E" [ label="49704867bee95",shape="box",style="filled",color="grey" ];
"315" [ label="31f2f9aef958979f9f3532b9b",shape="hexagon",style="filled",color="#ff0000" ];
"43E" [ label="47cd70f",shape="box",style="filled",color="grey" ];
"240E" [ label="248df40dae",shape="box",style="filled",color="grey" ];
"298E" [ label="",shape="box",style="filled",color="grey" ];
"334E" [ label="9dd5bf47f",shape="box",style="filled",color="grey" ];
"360E" [ label="",shape="box",style="filled",color="grey" ];
"390E" [ label="28533c",shape="box",style="filled",color="grey" ];
"418E" [ label="",shape="box",style="filled",color="grey" ];
"492E" [ label="a4c7d0",shape="box",style="filled",color="grey" ];
"502E" [ label="4f6f7f",shape="box",style="filled",color="grey" ];
"584E" [ label="7ab64a969",shape="box",style="filled",color="grey" ];
"588E" [ label="",shape="box",style="filled",color="grey" ];
"602E" [ label="69",shape="box",style="filled",color="grey" ];
"606E" [ label="67513d",shape="box",style="filled",color="grey" ];
"662E" [ label="cf",shape="box",style="filled",color="grey" ];
"316" [ label="a54092a3033f7d5e41e0a76c1",shape="hexagon" ];
"51E" [ label="1467f017b74e",shape="box",style="filled",color="grey" ];
"317" [ label="2043b477ac0393676a4309514d0",shape="hexagon" ];
"116E" [ label="bdec8c86db51b9",shape="box",style="filled",color="grey" ];
"318" [ label="ab48d1f65812bc0f8ab6941c3b5",shape="hexagon" ];
"74E" [ label="81",shape="box",style="filled",color="grey" ];
"319" [ label="ca3d67754cf62fdafbf0a1e0",shape="hexagon" ];
"57E" [ label="75b14f1719d",shape="box",style="filled",color="grey" ];
"94E" [ label="62f36ea98a",shape="box",style="filled",color="grey" ];
"350E" [ label="e3a76d31ca59a",shape="box",style="filled",color="grey" ];
"440E" [ label="b3cadc253f7",shape="box",style="filled",color="grey" ];
"466E" [ label="fb58e11",shape="box",style="filled",color="grey" ];
"676E" [ label="8606837526d81cdec",shape="box",style="filled",color="grey" ];
"320" [ label="a7a7f3681dad1250b01cf80bc17",shape="hexagon" ];
"60E" [ label="2c514b0cd8f7d3",shape="box",style="filled",color="grey" ];
"366E" [ label="7e494b",shape="box",style="filled",color="grey" ];
"434E" [ label="15d44ab97",shape="box",style="filled",color="grey" ];
"458E" [ label="78b2d75d00166",shape="box",style="filled",color="grey" ];
"618E" [ label="761e0f72f95",shape="box",style="filled",color="grey" ];
"321" [ label="275afb2b215b966d9fac51b96b9",shape="hexagon" ];
"72E" [ label="ac284d73563",shape="box",style="filled",color="grey" ];
"362E" [ label="7e74e1587f3a4d208",shape="box",style="filled",color="grey" ];
"372E" [ label="ffd1b1af3b6864078f3",shape="box",style="filled",color="grey" ];
"572E" [ label="b38049e00",shape="box",style="filled",color="grey" ];
"322" [ label="c3c93c700edc0cb4f95f03c04",shape="hexagon" ];
"54E" [ label="99237fce1358",shape="box",style="filled",color="grey" ];
"222E" [ label="3dcf8f454",shape="box",style="filled",color="grey" ];
"302E" [ label="c5acd20cad2",shape="box",style="filled",color="grey" ];
"556E" [ label="6c998bf2a5edd",shape="box",style="filled",color="grey" ];
"558E" [ label="4b683",shape="box",style="filled",color="grey" ];
"323" [ label="63a3d4fb9d38a0182be6e39e76",shape="hexagon" ];
"37E" [ label="bba6e6e194ccf",shape="box",style="filled",color="grey" ];
"208E" [ label="01938827",shape="box",style="filled",color="grey" ];
"210E" [ label="9",shape="box",style="filled",color="grey" ];
"352E" [ label="64ef1d545",shape="box",style="filled",color="grey" ];
"450E" [ label="b473716",shape="box",style="filled",color="grey" ];
"568E" [ label="7c13bf753da",shape="box",style="filled",color="grey" ];
"576E" [ label="4e4a79111d",shape="box",style="filled",color="grey" ];
"686E" [ label="af4abb0d6a99",shape="box",style="filled",color="grey" ];
"324" [ label="4399cf78123dedd0dfe9776104",shape="hexagon" ];
"228E" [ label="af9c489df53",shape="box",style="filled",color="grey" ];
"248E" [ label="3703059dbc5a8",shape="box",style="filled",color="grey" ];
"304E" [ label="8a46e6",shape="box",style="filled",color="grey" ];
"468E" [ label="f9d09",shape="box",style="filled",color="grey" ];
"578E" [ label="cd1e9af3dec2",shape="box",style="filled",color="grey" ];
"660E" [ label="9e650e89bb",shape="box",style="filled",color="grey" ];
"688E" [ label="f62b136b2171",shape="box",style="filled",color="grey" ];
"694E" [ label="4727c415d06bcbef",shape="box",style="filled",color="grey" ];
"714E" [ label="38b3b0d9",shape="box",style="filled",color="grey" ];
"766E" [ label="a153512d982",shape="box",style="filled",color="grey" ];
"325" [ label="40f253cd228f7ac2d0aee",shape="hexagon" ];
"97E" [ label="a3ff993",shape="box",style="filled",color="grey" ];
"506E" [ label="7528dd86b",shape="box",style="filled",color="grey" ];
"326" [ label="89a2505da6179a80202d4a6c3",shape="hexagon" ];
"61E" [ label="75eea05672a5",shape="box",style="filled",color="grey" ];
"175E" [ label="3b0c08dd2ca",shape="box",style="filled",color="grey" ];
"482E" [ label="a3781072b",shape="box",style="filled",color="grey" ];
"328" [ label="2601085bde1b2450d64509f36",shape="hexagon" ];
"75E" [ label="0efbd",shape="box",style="filled",color="grey" ];
"580E" [ label="bb92d1da1f38d52f8ff",shape="box",style="filled",color="grey" ];
"329" [ label="5c81103c751345d0ee0f4bd",shape="hexagon" ];
"96E" [ label="b23526044",shape="box",style="filled",color="grey" ];
"330" [ label="fcbd9ad14139718bc6fcc8b4",shape="hexagon" ];
"100E" [ label="73ca543bf1",shape="box",style="filled",color="grey" ];
"170E" [ label="c2f32e2cf9",shape="box",style="filled",color="grey" ];
"333" [ label="44cbb41a9cfc15497eacd294",color="yellow",style="filled",shape="doubleoctagon" ];
"63E" [ label="6a91",shape="box",style="filled",color="grey" ];
"67E" [ label="b074e",shape="box",style="filled",color="grey" ];
"68E" [ label="06209",shape="box",style="filled",color="grey" ];
"69E" [ label="58e3dcc618",shape="box",style="filled",color="grey" ];
"70E" [ label="eee44624da",shape="box",style="filled",color="grey" ];
"71E" [ label="6a91",shape="box",style="filled",color="grey" ];
"802E" [ label="e1e8c",shape="box",style="filled",color="grey" ];
"793E" [ label="",shape="box",style="filled",color="grey" ];
"334" [ label="b46b0756dba915943839e90a55",color="yellow",style="filled",shape="doubleoctagon" ];
"64E" [ label="5fdf",shape="box",style="filled",color="grey" ];
"81E" [ label="3eca1f94dc181",shape="box",style="filled",color="grey" ];
"82E" [ label="6b1bb9b0e",shape="box",style="filled",color="grey" ];
"83E" [ label="a54d477232",shape="box",style="filled",color="grey" ];
"84E" [ label="a164d9f60fbbdd",shape="box",style="filled",color="grey" ];
"85E" [ label="78c8463ea",shape="box",style="filled",color="grey" ];
"86E" [ label="c110ba7",shape="box",style="filled",color="grey" ];
"87E" [ label="3b63cdc0f",shape="box",style="filled",color="grey" ];
"88E" [ label="6f578c5128",shape="box",style="filled",color="grey" ];
"89E" [ label="3e048573fd",shape="box",style="filled",color="grey" ];
"336" [ URL="tes hi",area="test",label="825c7994d5da13afe519861818",color="#ff0000",style="filled",shape="tripleoctagon" ];
"1E" [ label="f4bef37b6a94bfd00",shape="box",style="filled",color="grey" ];
"2E" [ label="d2647f8b6d8661d08",shape="box",style="filled",color="grey" ];
"3E" [ label="964cb56d8f69ff058",shape="box",style="filled",color="grey" ];
"4E" [ label="4f35e206816c3bd22",shape="box",style="filled",color="grey" ];
"5E" [ label="affb2d716803a2d3e",shape="box",style="filled",color="grey" ];
"6E" [ label="e4ae306d9bd669c70",shape="box",style="filled",color="grey" ];
"7E" [ label="4dbf4395236fb03ed",shape="box",style="filled",color="grey" ];
"8E" [ label="15b3ad672cd2f713a",shape="box",style="filled",color="grey" ];
"9E" [ label="8d6e6e0cd9b842a47",shape="box",style="filled",color="grey" ];
"10E" [ label="00d0dd018fe879f96",shape="box",style="filled",color="grey" ];
"11E" [ label="f28b78d4803c",shape="box",style="filled",color="grey" ];
"12E" [ label="2d886da042b5384b4",shape="box",style="filled",color="grey" ];
"13E" [ label="548c0081a62132b44",shape="box",style="filled",color="grey" ];
"14E" [ label="52126553e52385d16",shape="box",style="filled",color="grey" ];
"15E" [ label="9fe716e738eaea34e",shape="box",style="filled",color="grey" ];
"16E" [ label="5782807b5f575e0a8",shape="box",style="filled",color="grey" ];
"17E" [ label="792fd6f9df1fa1e33",shape="box",style="filled",color="grey" ];
"18E" [ label="c471b6fdbfb852661",shape="box",style="filled",color="grey" ];
"19E" [ label="a84844dfd0052b3b5",shape="box",style="filled",color="grey" ];
"20E" [ label="724dabdce9744d061",shape="box",style="filled",color="grey" ];
"21E" [ label="57f7fd2eecec93c8b",shape="box",style="filled",color="grey" ];
"22E" [ label="baba65f670ee34a88",shape="box",style="filled",color="grey" ];
"23E" [ label="ac34ec0f0488b17ec",shape="box",style="filled",color="grey" ];
"24E" [ label="51e74bec5513083bb",shape="box",style="filled",color="grey" ];
"25E" [ label="8e2d970b2f820ee35",shape="box",style="filled",color="grey" ];
"26E" [ label="19398d3cd6b9c674f",shape="box",style="filled",color="grey" ];
"27E" [ label="6505e29f4a11d9530",shape="box",style="filled",color="grey" ];
"28E" [ label="bc4824f07a9d2bba6",shape="box",style="filled",color="grey" ];
"29E" [ label="3acbf8a1537e4e1a1",shape="box",style="filled",color="grey" ];
"30E" [ label="536264e787cf70469",shape="box",style="filled",color="grey" ];
"31E" [ label="d",shape="box",style="filled",color="grey" ];
"65E" [ label="d4b2",shape="box",style="filled",color="grey" ];
"119E" [ label="2a9caef7",shape="box",style="filled",color="grey" ];
"150E" [ label="73d12",shape="box",style="filled",color="grey" ];
"176E" [ label="8896166adc0",shape="box",style="filled",color="grey" ];
"743E" [ label="9f",shape="box",style="filled",color="grey" ];
"744E" [ label="2e1313c",shape="box",style="filled",color="grey" ];
"764E" [ label="cd6",shape="box",style="filled",color="grey" ];
"337" [ label="8304a439f91fc90b3fe8dd35be8",color="yellow",style="filled",shape="doubleoctagon" ];
"120E" [ label="345d26b3f821fe",shape="box",style="filled",color="grey" ];
"121E" [ label="357679fea1e2f",shape="box",style="filled",color="grey" ];
"122E" [ label="c71043819b6a79",shape="box",style="filled",color="grey" ];
"123E" [ label="f9df653b86fb8df",shape="box",style="filled",color="grey" ];
"124E" [ label="020df871874cd",shape="box",style="filled",color="grey" ];
"125E" [ label="4c52fdd8e396692",shape="box",style="filled",color="grey" ];
"126E" [ label="8b98c3ddbe0b336",shape="box",style="filled",color="grey" ];
"127E" [ label="d9f4abac731a9e",shape="box",style="filled",color="grey" ];
"128E" [ label="50f4d9b97aefe",shape="box",style="filled",color="grey" ];
"129E" [ label="ea920d9f5b295119",shape="box",style="filled",color="grey" ];
"130E" [ label="ff5c9b242337c",shape="box",style="filled",color="grey" ];
"131E" [ label="4e12f7ff0918",shape="box",style="filled",color="grey" ];
"132E" [ label="ee3b6be71d59b",shape="box",style="filled",color="grey" ];
"133E" [ label="615cd6b5e3d21c",shape="box",style="filled",color="grey" ];
"134E" [ label="6d52dd1b198bb",shape="box",style="filled",color="grey" ];
"135E" [ label="8c932e1e502dca",shape="box",style="filled",color="grey" ];
"136E" [ label="e84330eef281284a",shape="box",style="filled",color="grey" ];
"137E" [ label="85fc23f1c88b4",shape="box",style="filled",color="grey" ];
"138E" [ label="5997cb0c083422",shape="box",style="filled",color="grey" ];
"339" [ label="b1ffbabb24d71f67d1e0ce23c51",color="yellow",style="filled",shape="doubleoctagon" ];
"151E" [ label="",shape="box",style="filled",color="grey" ];
"153E" [ label="41a8b095c7fd3",shape="box",style="filled",color="grey" ];
"154E" [ label="151bcc2a8de7ea634",shape="box",style="filled",color="grey" ];
"155E" [ label="6c541cad8de1b15",shape="box",style="filled",color="grey" ];
"156E" [ label="c935c7f4d1090ac",shape="box",style="filled",color="grey" ];
"157E" [ label="5ce1fcfb042b",shape="box",style="filled",color="grey" ];
"158E" [ label="531806429433",shape="box",style="filled",color="grey" ];
"159E" [ label="d285240b89cb",shape="box",style="filled",color="grey" ];
"160E" [ label="f22c27c0f0a54e",shape="box",style="filled",color="grey" ];
"161E" [ label="8d0d8314d211d80",shape="box",style="filled",color="grey" ];
"162E" [ label="",shape="box",style="filled",color="grey" ];
"347" [ label="9652ab8b55fdb2a36d1f3fe020",shape="hexagon" ];
"139E" [ label="ef8b68bb5772f3",shape="box",style="filled",color="grey" ];
"795E" [ label="16c3ae29c0bc713",shape="box",style="filled",color="grey" ];
"348" [ label="676bbe7d1c1fb71742df534ce8",shape="hexagon" ];
"799E" [ label="a78eb40ae56aaa9",shape="box",style="filled",color="grey" ];
"800E" [ label="6aae8d25951",shape="box",style="filled",color="grey" ];
"349" [ label="66c0220688a999aaf7f1702d1",shape="hexagon" ];
"141E" [ label="67b6a4dca3a6d",shape="box",style="filled",color="grey" ];
"350" [ label="1322fb0818783e6f9a4f173d47c52",shape="hexagon" ];
"142E" [ label="9696c0950295d8cb5",shape="box",style="filled",color="grey" ];
"678E" [ label="b5c747cc9",shape="box",style="filled",color="grey" ];
"351" [ label="ff07977fca5513098d220d1eb3a",shape="hexagon" ];
"143E" [ label="89a36b13f8c344b",shape="box",style="filled",color="grey" ];
"232E" [ label="56292d076643",shape="box",style="filled",color="grey" ];
"680E" [ label="b5c747cc9",shape="box",style="filled",color="grey" ];
"704E" [ label="431430c49",shape="box",style="filled",color="grey" ];
"352" [ label="a97ef281eafc34b1630d450a1df",shape="hexagon" ];
"144E" [ label="4ff4e275c710c3b",shape="box",style="filled",color="grey" ];
"432E" [ label="d13da6273c9b4da",shape="box",style="filled",color="grey" ];
"353" [ label="72cbb37db85ed3c6eda5dcf8",shape="hexagon" ];
"145E" [ label="33ff9e43d5ab",shape="box",style="filled",color="grey" ];
"354" [ label="0f6784e49852c0be0da23b16",shape="hexagon" ];
"146E" [ label="d4f958b03a98",shape="box",style="filled",color="grey" ];
"396E" [ label="8e24e9b4e",shape="box",style="filled",color="grey" ];
"355" [ label="383f5c65cc6c25aa0a0e6dbb",shape="hexagon" ];
"147E" [ label="1ff8ff951ee9",shape="box",style="filled",color="grey" ];
"356" [ label="f52a45620969f0df4e6ae1dcd7",shape="hexagon" ];
"148E" [ label="5256925081c812",shape="box",style="filled",color="grey" ];
"357" [ label="1f5df34ad75a55a76ef4afa0a47",shape="hexagon" ];
"149E" [ label="26a185dde9a93dd",shape="box",style="filled",color="grey" ];
"358" [ label="45ba4d4c61c9601a26d59e47e0260",shape="hexagon" ];
"167E" [ label="99bd3e7feeb710",shape="box",style="filled",color="grey" ];
"359" [ label="f95344b0ae31693f3a2746597d4",shape="hexagon" ];
"169E" [ label="4e8259973f1f",shape="box",style="filled",color="grey" ];
"360" [ label="b79798b186d6b82288e8be4017d",shape="hexagon" ];
"171E" [ label="63b079bd5847",shape="box",style="filled",color="grey" ];
"361" [ label="47e0067f4d853afd2012f04daa8",shape="hexagon" ];
"172E" [ label="92fb5d4a0805",shape="box",style="filled",color="grey" ];
"362" [ label="f2b6201774de40a29b504b1f716",shape="hexagon" ];
"173E" [ label="d7203571944b",shape="box",style="filled",color="grey" ];
"363" [ label="800422ab81d804eef3e7b91dfba91",shape="hexagon" ];
"174E" [ label="952316a1a5a785",shape="box",style="filled",color="grey" ];
"364" [ label="35b941379e1af658078cffb83a2",shape="hexagon" ];
"101E" [ label="331675c046693f",shape="box",style="filled",color="grey" ];
"365" [ label="d4f7b7fba7afcf7a72397353ec",shape="hexagon" ];
"102E" [ label="32c4684b55361",shape="box",style="filled",color="grey" ];
"367" [ label="e4b45b7a2f884d3734bfd5985656",shape="hexagon" ];
"104E" [ label="1333074979f2d0b",shape="box",style="filled",color="grey" ];
"368" [ label="02c2ba83680ab57f236a33d702",shape="hexagon" ];
"105E" [ label="084d4bfa5853e",shape="box",style="filled",color="grey" ];
"369" [ label="9ccd974150a18260b207b6584caa",shape="hexagon" ];
"106E" [ label="28f7bfc40c88e6a",shape="box",style="filled",color="grey" ];
"374" [ label="653ae44d45dcadeb481b53027d",shape="hexagon" ];
"111E" [ label="8f95518f48528",shape="box",style="filled",color="grey" ];
"375" [ label="d66f542ef1ce4d02c59bec65e",shape="hexagon" ];
"112E" [ label="2ef209509e2a",shape="box",style="filled",color="grey" ];
"377" [ label="a2984b7a11e49440420058c1d80",shape="hexagon" ];
"114E" [ label="ef42184297591d",shape="box",style="filled",color="grey" ];
"378" [ label="31055116421c96b37f72a262bb",shape="hexagon" ];
"115E" [ label="be9c5958196ed",shape="box",style="filled",color="grey" ];
"380" [ label="8462bb2eec1a62d19a15865e57c92",shape="hexagon" ];
"117E" [ label="16a795a1d63f30df",shape="box",style="filled",color="grey" ];
"392E" [ label="85a34bc9616ff",shape="box",style="filled",color="grey" ];
"381" [ label="c21eb96fe100a1efaa128181b7",shape="hexagon" ];
"118E" [ label="f1b0d754353a6",shape="box",style="filled",color="grey" ];
"382" [ label="e3e284d0cc803d98d674f9c3f6d",color="yellow",style="filled",shape="doubleoctagon" ];
"177E" [ label="30417faf916",shape="box",style="filled",color="grey" ];
"178E" [ label="e618df70814a",shape="box",style="filled",color="grey" ];
"179E" [ label="fa90ddf10bd574",shape="box",style="filled",color="grey" ];
"180E" [ label="815cc0b83d733",shape="box",style="filled",color="grey" ];
"181E" [ label="f787d827958c",shape="box",style="filled",color="grey" ];
"182E" [ label="f20f7f513e",shape="box",style="filled",color="grey" ];
"183E" [ label="290907417e13",shape="box",style="filled",color="grey" ];
"184E" [ label="e8386a8e1c8a",shape="box",style="filled",color="grey" ];
"185E" [ label="319bc900218b",shape="box",style="filled",color="grey" ];
"186E" [ label="3ba7afb0e48ae1",shape="box",style="filled",color="grey" ];
"187E" [ label="6ba0776fc8e",shape="box",style="filled",color="grey" ];
"188E" [ label="09847696ae",shape="box",style="filled",color="grey" ];
"383" [ label="908f9ad506eae9ab6ada185e3",color="yellow",style="filled",shape="doubleoctagon" ];
"730E" [ label="65694ca6d575",shape="box",style="filled",color="grey" ];
"732E" [ label="37f57e81ebed95",shape="box",style="filled",color="grey" ];
"741E" [ label="9b6c",shape="box",style="filled",color="grey" ];
"765E" [ label="88ebe2e8782c",shape="box",style="filled",color="grey" ];
"796E" [ label="901b2105a902ee7791",shape="box",style="filled",color="grey" ];
"384" [ label="593caebf2037317648bb451aa79",color="yellow",style="filled",shape="doubleoctagon" ];
"726E" [ label="351dd0aefe480c",shape="box",style="filled",color="grey" ];
"728E" [ label="56e1a896",shape="box",style="filled",color="grey" ];
"742E" [ label="5ba4693031",shape="box",style="filled",color="grey" ];
"385" [ label="717c254aeffbb527dabfc",shape="hexagon" ];
"328E" [ label="123cc6d1ac",shape="box",style="filled",color="grey" ];
"496E" [ label="",shape="box",style="filled",color="grey" ];
"594E" [ label="7f8c557bcf3889",shape="box",style="filled",color="grey" ];
"622E" [ label="da3d5",shape="box",style="filled",color="grey" ];
"754E" [ label="68d8993e61d8c82cd29e8d0182b0",shape="box",style="filled",color="grey" ];
"755E" [ label="4c865eec228e41e7f4e5fc68a9a6",shape="box",style="filled",color="grey" ];
"756E" [ label="8983ffbc30deb364dd92c3ad85c9",shape="box",style="filled",color="grey" ];
"757E" [ label="68d8993e61d8c82cd29e8d0182b0",shape="box",style="filled",color="grey" ];
"758E" [ label="4c865eec228e41e7f4e5fc68a9a6",shape="box",style="filled",color="grey" ];
"759E" [ label="8983ffbc30deb364dd92c3ad85c9",shape="box",style="filled",color="grey" ];
"760E" [ label="8983ffbc30deb364dd92c3ad85c9",shape="box",style="filled",color="grey" ];
"761E" [ label="eb9cf6456613d4cd06f7c0894bd6",shape="box",style="filled",color="grey" ];
"762E" [ label="1e2298c4bb",shape="box",style="filled",color="grey" ];
"1" -> "189E" [ label=" ",color="blue",arrowhead="dot" ];
"1" -> "790E" [ label=" ",color="blue",arrowhead="dot" ];
"2" -> "191E" [ label=" ",color="blue",arrowhead="dot" ];
"3" -> "193E" [ label=" ",color="blue",arrowhead="dot" ];
"4" -> "195E" [ label=" ",color="blue",arrowhead="dot" ];
"5" -> "197E" [ label=" ",color="blue",arrowhead="dot" ];
"6" -> "199E" [ label=" ",color="blue",arrowhead="dot" ];
"7" -> "201E" [ label=" ",color="blue",arrowhead="dot" ];
"8" -> "203E" [ label=" ",color="blue",arrowhead="dot" ];
"9" -> "725E" [ label=" ",color="blue",arrowhead="dot" ];
"9" -> "785E" [ label=" ",color="blue",arrowhead="dot" ];
"10" -> "205E" [ label=" ",color="blue",arrowhead="dot" ];
"11" -> "207E" [ label=" ",color="blue",arrowhead="dot" ];
"12" -> "209E" [ label=" ",color="blue",arrowhead="dot" ];
"13" -> "211E" [ label=" ",color="blue",arrowhead="dot" ];
"14" -> "213E" [ label=" ",color="blue",arrowhead="dot" ];
"15" -> "215E" [ label=" ",color="blue",arrowhead="dot" ];
"16" -> "727E" [ label=" ",color="blue",arrowhead="dot" ];
"16" -> "784E" [ label=" ",color="blue",arrowhead="dot" ];
"17" -> "217E" [ label=" ",color="blue",arrowhead="dot" ];
"17" -> "787E" [ label=" ",color="blue",arrowhead="dot" ];
"18" -> "219E" [ label=" ",color="blue",arrowhead="dot" ];
"19" -> "221E" [ label=" ",color="blue",arrowhead="dot" ];
"20" -> "223E" [ label=" ",color="blue",arrowhead="dot" ];
"21" -> "225E" [ label=" ",color="blue",arrowhead="dot" ];
"22" -> "227E" [ label=" ",color="blue",arrowhead="dot" ];
"22" -> "792E" [ label=" ",color="blue",arrowhead="dot" ];
"23" -> "231E" [ label=" ",color="blue",arrowhead="dot" ];
"24" -> "233E" [ label=" ",color="blue",arrowhead="dot" ];
"25" -> "235E" [ label=" ",color="blue",arrowhead="dot" ];
"26" -> "237E" [ label=" ",color="blue",arrowhead="dot" ];
"27" -> "239E" [ label=" ",color="blue",arrowhead="dot" ];
"27" -> "783E" [ label=" ",color="blue",arrowhead="dot" ];
"28" -> "241E" [ label=" ",color="blue",arrowhead="dot" ];
"28" -> "791E" [ label=" ",color="blue",arrowhead="dot" ];
"29" -> "243E" [ label=" ",color="blue",arrowhead="dot" ];
"30" -> "245E" [ label=" ",color="blue",arrowhead="dot" ];
"31" -> "247E" [ label=" ",color="blue",arrowhead="dot" ];
"32" -> "249E" [ label=" ",color="blue",arrowhead="dot" ];
"33" -> "251E" [ label=" ",color="blue",arrowhead="dot" ];
"34" -> "253E" [ label=" ",color="blue",arrowhead="dot" ];
"35" -> "255E" [ label=" ",color="blue",arrowhead="dot" ];
"36" -> "257E" [ label=" ",color="blue",arrowhead="dot" ];
"37" -> "259E" [ label=" ",color="blue",arrowhead="dot" ];
"38" -> "261E" [ label=" ",color="blue",arrowhead="dot" ];
"39" -> "263E" [ label=" ",color="blue",arrowhead="dot" ];
"40" -> "265E" [ label=" ",color="blue",arrowhead="dot" ];
"41" -> "267E" [ label=" ",color="blue",arrowhead="dot" ];
"42" -> "269E" [ label=" ",color="blue",arrowhead="dot" ];
"43" -> "271E" [ label=" ",color="blue",arrowhead="dot" ];
"44" -> "273E" [ label=" ",color="blue",arrowhead="dot" ];
"45" -> "275E" [ label=" ",color="blue",arrowhead="dot" ];
"46" -> "277E" [ label=" ",color="blue",arrowhead="dot" ];
"47" -> "279E" [ label=" ",color="blue",arrowhead="dot" ];
"48" -> "281E" [ label=" ",color="blue",arrowhead="dot" ];
"49" -> "283E" [ label=" ",color="blue",arrowhead="dot" ];
"50" -> "285E" [ label=" ",color="blue",arrowhead="dot" ];
"51" -> "287E" [ label=" ",color="blue",arrowhead="dot" ];
"52" -> "289E" [ label=" ",color="blue",arrowhead="dot" ];
"53" -> "291E" [ label=" ",color="blue",arrowhead="dot" ];
"54" -> "293E" [ label=" ",color="blue",arrowhead="dot" ];
"55" -> "745E" [ label=" ",color="blue",arrowhead="dot" ];
"56" -> "295E" [ label=" ",color="blue",arrowhead="dot" ];
"57" -> "297E" [ label=" ",color="blue",arrowhead="dot" ];
"58" -> "299E" [ label=" ",color="blue",arrowhead="dot" ];
"59" -> "301E" [ label=" ",color="blue",arrowhead="dot" ];
"59" -> "789E" [ label=" ",color="blue",arrowhead="dot" ];
"60" -> "303E" [ label=" ",color="blue",arrowhead="dot" ];
"61" -> "305E" [ label=" ",color="blue",arrowhead="dot" ];
"62" -> "307E" [ label=" ",color="blue",arrowhead="dot" ];
"63" -> "309E" [ label=" ",color="blue",arrowhead="dot" ];
"64" -> "311E" [ label=" ",color="blue",arrowhead="dot" ];
"65" -> "313E" [ label=" ",color="blue",arrowhead="dot" ];
"66" -> "315E" [ label=" ",color="blue",arrowhead="dot" ];
"67" -> "317E" [ label=" ",color="blue",arrowhead="dot" ];
"68" -> "319E" [ label=" ",color="blue",arrowhead="dot" ];
"69" -> "746E" [ label=" ",color="blue",arrowhead="dot" ];
"70" -> "321E" [ label=" ",color="blue",arrowhead="dot" ];
"71" -> "327E" [ label=" ",color="blue",arrowhead="dot" ];
"72" -> "329E" [ label=" ",color="blue",arrowhead="dot" ];
"73" -> "331E" [ label=" ",color="blue",arrowhead="dot" ];
"74" -> "333E" [ label=" ",color="blue",arrowhead="dot" ];
"75" -> "335E" [ label=" ",color="blue",arrowhead="dot" ];
"76" -> "337E" [ label=" ",color="blue",arrowhead="dot" ];
"77" -> "339E" [ label=" ",color="blue",arrowhead="dot" ];
"78" -> "341E" [ label=" ",color="blue",arrowhead="dot" ];
"79" -> "343E" [ label=" ",color="blue",arrowhead="dot" ];
"80" -> "345E" [ label=" ",color="blue",arrowhead="dot" ];
"81" -> "347E" [ label=" ",color="blue",arrowhead="dot" ];
"82" -> "349E" [ label=" ",color="blue",arrowhead="dot" ];
"83" -> "351E" [ label=" ",color="blue",arrowhead="dot" ];
"84" -> "353E" [ label=" ",color="blue",arrowhead="dot" ];
"85" -> "355E" [ label=" ",color="blue",arrowhead="dot" ];
"85" -> "788E" [ label=" ",color="blue",arrowhead="dot" ];
"86" -> "357E" [ label=" ",color="blue",arrowhead="dot" ];
"87" -> "359E" [ label=" ",color="blue",arrowhead="dot" ];
"88" -> "361E" [ label=" ",color="blue",arrowhead="dot" ];
"89" -> "363E" [ label=" ",color="blue",arrowhead="dot" ];
"90" -> "365E" [ label=" ",color="blue",arrowhead="dot" ];
"91" -> "367E" [ label=" ",color="blue",arrowhead="dot" ];
"92" -> "369E" [ label=" ",color="blue",arrowhead="dot" ];
"93" -> "729E" [ label=" ",color="blue",arrowhead="dot" ];
"94" -> "371E" [ label=" ",color="blue",arrowhead="dot" ];
"95" -> "373E" [ label=" ",color="blue",arrowhead="dot" ];
"96" -> "375E" [ label=" ",color="blue",arrowhead="dot" ];
"97" -> "747E" [ label=" ",color="blue",arrowhead="dot" ];
"98" -> "377E" [ label=" ",color="blue",arrowhead="dot" ];
"99" -> "379E" [ label=" ",color="blue",arrowhead="dot" ];
"100" -> "381E" [ label=" ",color="blue",arrowhead="dot" ];
"101" -> "383E" [ label=" ",color="blue",arrowhead="dot" ];
"102" -> "385E" [ label=" ",color="blue",arrowhead="dot" ];
"103" -> "387E" [ label=" ",color="blue",arrowhead="dot" ];
"104" -> "389E" [ label=" ",color="blue",arrowhead="dot" ];
"105" -> "391E" [ label=" ",color="blue",arrowhead="dot" ];
"106" -> "393E" [ label=" ",color="blue",arrowhead="dot" ];
"107" -> "395E" [ label=" ",color="blue",arrowhead="dot" ];
"108" -> "397E" [ label=" ",color="blue",arrowhead="dot" ];
"109" -> "399E" [ label=" ",color="blue",arrowhead="dot" ];
"110" -> "401E" [ label=" ",color="blue",arrowhead="dot" ];
"111" -> "403E" [ label=" ",color="blue",arrowhead="dot" ];
"112" -> "405E" [ label=" ",color="blue",arrowhead="dot" ];
"113" -> "407E" [ label=" ",color="blue",arrowhead="dot" ];
"114" -> "409E" [ label=" ",color="blue",arrowhead="dot" ];
"115" -> "411E" [ label=" ",color="blue",arrowhead="dot" ];
"116" -> "413E" [ label=" ",color="blue",arrowhead="dot" ];
"117" -> "415E" [ label=" ",color="blue",arrowhead="dot" ];
"118" -> "417E" [ label=" ",color="blue",arrowhead="dot" ];
"119" -> "419E" [ label=" ",color="blue",arrowhead="dot" ];
"120" -> "421E" [ label=" ",color="blue",arrowhead="dot" ];
"121" -> "423E" [ label=" ",color="blue",arrowhead="dot" ];
"122" -> "748E" [ label=" ",color="blue",arrowhead="dot" ];
"123" -> "425E" [ label=" ",color="blue",arrowhead="dot" ];
"124" -> "427E" [ label=" ",color="blue",arrowhead="dot" ];
"124" -> "786E" [ label=" ",color="blue",arrowhead="dot" ];
"125" -> "431E" [ label=" ",color="blue",arrowhead="dot" ];
"126" -> "433E" [ label=" ",color="blue",arrowhead="dot" ];
"127" -> "435E" [ label=" ",color="blue",arrowhead="dot" ];
"128" -> "437E" [ label=" ",color="blue",arrowhead="dot" ];
"129" -> "439E" [ label=" ",color="blue",arrowhead="dot" ];
"130" -> "441E" [ label=" ",color="blue",arrowhead="dot" ];
"131" -> "443E" [ label=" ",color="blue",arrowhead="dot" ];
"132" -> "445E" [ label=" ",color="blue",arrowhead="dot" ];
"133" -> "749E" [ label=" ",color="blue",arrowhead="dot" ];
"134" -> "447E" [ label=" ",color="blue",arrowhead="dot" ];
"135" -> "449E" [ label=" ",color="blue",arrowhead="dot" ];
"135" -> "769E" [ label=" ",color="blue",arrowhead="dot" ];
"135" -> "770E" [ label=" ",color="blue",arrowhead="dot" ];
"136" -> "451E" [ label=" ",color="blue",arrowhead="dot" ];
"137" -> "453E" [ label=" ",color="blue",arrowhead="dot" ];
"138" -> "455E" [ label=" ",color="blue",arrowhead="dot" ];
"139" -> "457E" [ label=" ",color="blue",arrowhead="dot" ];
"140" -> "459E" [ label=" ",color="blue",arrowhead="dot" ];
"141" -> "461E" [ label=" ",color="blue",arrowhead="dot" ];
"142" -> "463E" [ label=" ",color="blue",arrowhead="dot" ];
"143" -> "465E" [ label=" ",color="blue",arrowhead="dot" ];
"144" -> "467E" [ label=" ",color="blue",arrowhead="dot" ];
"145" -> "469E" [ label=" ",color="blue",arrowhead="dot" ];
"146" -> "471E" [ label=" ",color="blue",arrowhead="dot" ];
"147" -> "473E" [ label=" ",color="blue",arrowhead="dot" ];
"148" -> "475E" [ label=" ",color="blue",arrowhead="dot" ];
"149" -> "477E" [ label=" ",color="blue",arrowhead="dot" ];
"150" -> "479E" [ label=" ",color="blue",arrowhead="dot" ];
"151" -> "481E" [ label=" ",color="blue",arrowhead="dot" ];
"152" -> "483E" [ label=" ",color="blue",arrowhead="dot" ];
"153" -> "731E" [ label=" ",color="blue",arrowhead="dot" ];
"154" -> "750E" [ label=" ",color="blue",arrowhead="dot" ];
"155" -> "485E" [ label=" ",color="blue",arrowhead="dot" ];
"156" -> "487E" [ label=" ",color="blue",arrowhead="dot" ];
"157" -> "489E" [ label=" ",color="blue",arrowhead="dot" ];
"158" -> "491E" [ label=" ",color="blue",arrowhead="dot" ];
"159" -> "495E" [ label=" ",color="blue",arrowhead="dot" ];
"160" -> "499E" [ label=" ",color="blue",arrowhead="dot" ];
"161" -> "501E" [ label=" ",color="blue",arrowhead="dot" ];
"162" -> "503E" [ label=" ",color="blue",arrowhead="dot" ];
"163" -> "505E" [ label=" ",color="blue",arrowhead="dot" ];
"164" -> "507E" [ label=" ",color="blue",arrowhead="dot" ];
"165" -> "509E" [ label=" ",color="blue",arrowhead="dot" ];
"166" -> "511E" [ label=" ",color="blue",arrowhead="dot" ];
"167" -> "513E" [ label=" ",color="blue",arrowhead="dot" ];
"168" -> "515E" [ label=" ",color="blue",arrowhead="dot" ];
"169" -> "517E" [ label=" ",color="blue",arrowhead="dot" ];
"170" -> "519E" [ label=" ",color="blue",arrowhead="dot" ];
"171" -> "521E" [ label=" ",color="blue",arrowhead="dot" ];
"172" -> "523E" [ label=" ",color="blue",arrowhead="dot" ];
"173" -> "525E" [ label=" ",color="blue",arrowhead="dot" ];
"174" -> "527E" [ label=" ",color="blue",arrowhead="dot" ];
"175" -> "529E" [ label=" ",color="blue",arrowhead="dot" ];
"176" -> "531E" [ label=" ",color="blue",arrowhead="dot" ];
"177" -> "533E" [ label=" ",color="blue",arrowhead="dot" ];
"178" -> "535E" [ label=" ",color="blue",arrowhead="dot" ];
"179" -> "537E" [ label=" ",color="blue",arrowhead="dot" ];
"180" -> "539E" [ label=" ",color="blue",arrowhead="dot" ];
"181" -> "541E" [ label=" ",color="blue",arrowhead="dot" ];
"182" -> "543E" [ label=" ",color="blue",arrowhead="dot" ];
"183" -> "545E" [ label=" ",color="blue",arrowhead="dot" ];
"184" -> "547E" [ label=" ",color="blue",arrowhead="dot" ];
"185" -> "549E" [ label=" ",color="blue",arrowhead="dot" ];
"186" -> "551E" [ label=" ",color="blue",arrowhead="dot" ];
"187" -> "553E" [ label=" ",color="blue",arrowhead="dot" ];
"188" -> "555E" [ label=" ",color="blue",arrowhead="dot" ];
"189" -> "557E" [ label=" ",color="blue",arrowhead="dot" ];
"190" -> "559E" [ label=" ",color="blue",arrowhead="dot" ];
"191" -> "561E" [ label=" ",color="blue",arrowhead="dot" ];
"192" -> "563E" [ label=" ",color="blue",arrowhead="dot" ];
"193" -> "565E" [ label=" ",color="blue",arrowhead="dot" ];
"194" -> "567E" [ label=" ",color="blue",arrowhead="dot" ];
"195" -> "569E" [ label=" ",color="blue",arrowhead="dot" ];
"196" -> "571E" [ label=" ",color="blue",arrowhead="dot" ];
"197" -> "573E" [ label=" ",color="blue",arrowhead="dot" ];
"198" -> "575E" [ label=" ",color="blue",arrowhead="dot" ];
"199" -> "577E" [ label=" ",color="blue",arrowhead="dot" ];
"200" -> "579E" [ label=" ",color="blue",arrowhead="dot" ];
"201" -> "581E" [ label=" ",color="blue",arrowhead="dot" ];
"202" -> "583E" [ label=" ",color="blue",arrowhead="dot" ];
"203" -> "585E" [ label=" ",color="blue",arrowhead="dot" ];
"204" -> "587E" [ label=" ",color="blue",arrowhead="dot" ];
"205" -> "751E" [ label=" ",color="blue",arrowhead="dot" ];
"206" -> "589E" [ label=" ",color="blue",arrowhead="dot" ];
"207" -> "593E" [ label=" ",color="blue",arrowhead="dot" ];
"208" -> "597E" [ label=" ",color="blue",arrowhead="dot" ];
"209" -> "599E" [ label=" ",color="blue",arrowhead="dot" ];
"210" -> "601E" [ label=" ",color="blue",arrowhead="dot" ];
"211" -> "603E" [ label=" ",color="blue",arrowhead="dot" ];
"212" -> "605E" [ label=" ",color="blue",arrowhead="dot" ];
"213" -> "607E" [ label=" ",color="blue",arrowhead="dot" ];
"214" -> "609E" [ label=" ",color="blue",arrowhead="dot" ];
"215" -> "611E" [ label=" ",color="blue",arrowhead="dot" ];
"216" -> "613E" [ label=" ",color="blue",arrowhead="dot" ];
"217" -> "615E" [ label=" ",color="blue",arrowhead="dot" ];
"218" -> "617E" [ label=" ",color="blue",arrowhead="dot" ];
"219" -> "619E" [ label=" ",color="blue",arrowhead="dot" ];
"220" -> "621E" [ label=" ",color="blue",arrowhead="dot" ];
"221" -> "623E" [ label=" ",color="blue",arrowhead="dot" ];
"222" -> "752E" [ label=" ",color="blue",arrowhead="dot" ];
"223" -> "625E" [ label=" ",color="blue",arrowhead="dot" ];
"224" -> "627E" [ label=" ",color="blue",arrowhead="dot" ];
"225" -> "629E" [ label=" ",color="blue",arrowhead="dot" ];
"226" -> "631E" [ label=" ",color="blue",arrowhead="dot" ];
"227" -> "633E" [ label=" ",color="blue",arrowhead="dot" ];
"228" -> "635E" [ label=" ",color="blue",arrowhead="dot" ];
"229" -> "637E" [ label=" ",color="blue",arrowhead="dot" ];
"230" -> "639E" [ label=" ",color="blue",arrowhead="dot" ];
"231" -> "641E" [ label=" ",color="blue",arrowhead="dot" ];
"232" -> "643E" [ label=" ",color="blue",arrowhead="dot" ];
"233" -> "645E" [ label=" ",color="blue",arrowhead="dot" ];
"234" -> "647E" [ label=" ",color="blue",arrowhead="dot" ];
"235" -> "649E" [ label=" ",color="blue",arrowhead="dot" ];
"236" -> "651E" [ label=" ",color="blue",arrowhead="dot" ];
"237" -> "653E" [ label=" ",color="blue",arrowhead="dot" ];
"238" -> "655E" [ label=" ",color="blue",arrowhead="dot" ];
"239" -> "657E" [ label=" ",color="blue",arrowhead="dot" ];
"240" -> "659E" [ label=" ",color="blue",arrowhead="dot" ];
"241" -> "661E" [ label=" ",color="blue",arrowhead="dot" ];
"242" -> "663E" [ label=" ",color="blue",arrowhead="dot" ];
"243" -> "665E" [ label=" ",color="blue",arrowhead="dot" ];
"244" -> "667E" [ label=" ",color="blue",arrowhead="dot" ];
"245" -> "669E" [ label=" ",color="blue",arrowhead="dot" ];
"246" -> "671E" [ label=" ",color="blue",arrowhead="dot" ];
"247" -> "673E" [ label=" ",color="blue",arrowhead="dot" ];
"248" -> "675E" [ label=" ",color="blue",arrowhead="dot" ];
"249" -> "679E" [ label=" ",color="blue",arrowhead="dot" ];
"250" -> "753E" [ label=" ",color="blue",arrowhead="dot" ];
"251" -> "681E" [ label=" ",color="blue",arrowhead="dot" ];
"252" -> "683E" [ label=" ",color="blue",arrowhead="dot" ];
"253" -> "685E" [ label=" ",color="blue",arrowhead="dot" ];
"254" -> "687E" [ label=" ",color="blue",arrowhead="dot" ];
"255" -> "689E" [ label=" ",color="blue",arrowhead="dot" ];
"256" -> "691E" [ label=" ",color="blue",arrowhead="dot" ];
"257" -> "693E" [ label=" ",color="blue",arrowhead="dot" ];
"258" -> "695E" [ label=" ",color="blue",arrowhead="dot" ];
"259" -> "697E" [ label=" ",color="blue",arrowhead="dot" ];
"260" -> "699E" [ label=" ",color="blue",arrowhead="dot" ];
"261" -> "703E" [ label=" ",color="blue",arrowhead="dot" ];
"262" -> "705E" [ label=" ",color="blue",arrowhead="dot" ];
"264" -> "709E" [ label=" ",color="blue",arrowhead="dot" ];
"265" -> "711E" [ label=" ",color="blue",arrowhead="dot" ];
"266" -> "713E" [ label=" ",color="blue",arrowhead="dot" ];
"267" -> "715E" [ label=" ",color="blue",arrowhead="dot" ];
"268" -> "717E" [ label=" ",color="blue",arrowhead="dot" ];
"269" -> "719E" [ label=" ",color="blue",arrowhead="dot" ];
"270" -> "721E" [ label=" ",color="blue",arrowhead="dot" ];
"272" -> "34E" [ label=" ",color="blue",arrowhead="dot" ];
"272" -> "252E" [ label=" ",color="blue",arrowhead="dot" ];
"272" -> "436E" [ label=" ",color="blue",arrowhead="dot" ];
"274" -> "59E" [ label=" ",color="blue",arrowhead="dot" ];
"274" -> "500E" [ label=" ",color="blue",arrowhead="dot" ];
"274" -> "720E" [ label=" ",color="blue",arrowhead="dot" ];
"275" -> "98E" [ label=" ",color="blue",arrowhead="dot" ];
"278" -> "35E" [ label=" ",color="blue",arrowhead="dot" ];
"278" -> "488E" [ label=" ",color="blue",arrowhead="dot" ];
"278" -> "598E" [ label=" ",color="blue",arrowhead="dot" ];
"278" -> "604E" [ label=" ",color="blue",arrowhead="dot" ];
"278" -> "628E" [ label=" ",color="blue",arrowhead="dot" ];
"279" -> "99E" [ label=" ",color="blue",arrowhead="dot" ];
"280" -> "242E" [ label=" ",color="blue",arrowhead="dot" ];
"280" -> "270E" [ label=" ",color="blue",arrowhead="dot" ];
"280" -> "272E" [ label=" ",color="blue",arrowhead="dot" ];
"280" -> "284E" [ label=" ",color="blue",arrowhead="dot" ];
"280" -> "286E" [ label=" ",color="blue",arrowhead="dot" ];
"280" -> "288E" [ label=" ",color="blue",arrowhead="dot" ];
"280" -> "586E" [ label=" ",color="blue",arrowhead="dot" ];
"280" -> "763E" [ label=" ",color="blue",arrowhead="dot" ];
"281" -> "45E" [ label=" ",color="blue",arrowhead="dot" ];
"281" -> "470E" [ label=" ",color="blue",arrowhead="dot" ];
"281" -> "670E" [ label=" ",color="blue",arrowhead="dot" ];
"281" -> "722E" [ label=" ",color="blue",arrowhead="dot" ];
"282" -> "103E" [ label=" ",color="blue",arrowhead="dot" ];
"283" -> "165E" [ label=" ",color="blue",arrowhead="dot" ];
"284" -> "39E" [ label=" ",color="blue",arrowhead="dot" ];
"284" -> "224E" [ label=" ",color="blue",arrowhead="dot" ];
"284" -> "268E" [ label=" ",color="blue",arrowhead="dot" ];
"284" -> "632E" [ label=" ",color="blue",arrowhead="dot" ];
"284" -> "710E" [ label=" ",color="blue",arrowhead="dot" ];
"285" -> "53E" [ label=" ",color="blue",arrowhead="dot" ];
"286" -> "38E" [ label=" ",color="blue",arrowhead="dot" ];
"286" -> "166E" [ label=" ",color="blue",arrowhead="dot" ];
"288" -> "40E" [ label=" ",color="blue",arrowhead="dot" ];
"288" -> "218E" [ label=" ",color="blue",arrowhead="dot" ];
"288" -> "244E" [ label=" ",color="blue",arrowhead="dot" ];
"288" -> "246E" [ label=" ",color="blue",arrowhead="dot" ];
"288" -> "258E" [ label=" ",color="blue",arrowhead="dot" ];
"288" -> "290E" [ label=" ",color="blue",arrowhead="dot" ];
"288" -> "292E" [ label=" ",color="blue",arrowhead="dot" ];
"288" -> "308E" [ label=" ",color="blue",arrowhead="dot" ];
"288" -> "318E" [ label=" ",color="blue",arrowhead="dot" ];
"288" -> "388E" [ label=" ",color="blue",arrowhead="dot" ];
"288" -> "472E" [ label=" ",color="blue",arrowhead="dot" ];
"288" -> "478E" [ label=" ",color="blue",arrowhead="dot" ];
"288" -> "566E" [ label=" ",color="blue",arrowhead="dot" ];
"288" -> "570E" [ label=" ",color="blue",arrowhead="dot" ];
"288" -> "574E" [ label=" ",color="blue",arrowhead="dot" ];
"288" -> "608E" [ label=" ",color="blue",arrowhead="dot" ];
"288" -> "614E" [ label=" ",color="blue",arrowhead="dot" ];
"288" -> "658E" [ label=" ",color="blue",arrowhead="dot" ];
"288" -> "664E" [ label=" ",color="blue",arrowhead="dot" ];
"288" -> "682E" [ label=" ",color="blue",arrowhead="dot" ];
"289" -> "41E" [ label=" ",color="blue",arrowhead="dot" ];
"289" -> "636E" [ label=" ",color="blue",arrowhead="dot" ];
"289" -> "642E" [ label=" ",color="blue",arrowhead="dot" ];
"289" -> "690E" [ label=" ",color="blue",arrowhead="dot" ];
"289" -> "700E" [ label=" ",color="blue",arrowhead="dot" ];
"290" -> "56E" [ label=" ",color="blue",arrowhead="dot" ];
"290" -> "264E" [ label=" ",color="blue",arrowhead="dot" ];
"290" -> "510E" [ label=" ",color="blue",arrowhead="dot" ];
"290" -> "718E" [ label=" ",color="blue",arrowhead="dot" ];
"291" -> "66E" [ label=" ",color="blue",arrowhead="dot" ];
"291" -> "76E" [ label=" ",color="blue",arrowhead="dot" ];
"291" -> "610E" [ label=" ",color="blue",arrowhead="dot" ];
"292" -> "73E" [ label=" ",color="blue",arrowhead="dot" ];
"293" -> "49E" [ label=" ",color="blue",arrowhead="dot" ];
"293" -> "214E" [ label=" ",color="blue",arrowhead="dot" ];
"293" -> "216E" [ label=" ",color="blue",arrowhead="dot" ];
"293" -> "236E" [ label=" ",color="blue",arrowhead="dot" ];
"293" -> "278E" [ label=" ",color="blue",arrowhead="dot" ];
"293" -> "358E" [ label=" ",color="blue",arrowhead="dot" ];
"293" -> "398E" [ label=" ",color="blue",arrowhead="dot" ];
"293" -> "400E" [ label=" ",color="blue",arrowhead="dot" ];
"293" -> "402E" [ label=" ",color="blue",arrowhead="dot" ];
"293" -> "404E" [ label=" ",color="blue",arrowhead="dot" ];
"293" -> "406E" [ label=" ",color="blue",arrowhead="dot" ];
"293" -> "408E" [ label=" ",color="blue",arrowhead="dot" ];
"293" -> "412E" [ label=" ",color="blue",arrowhead="dot" ];
"293" -> "438E" [ label=" ",color="blue",arrowhead="dot" ];
"293" -> "448E" [ label=" ",color="blue",arrowhead="dot" ];
"293" -> "476E" [ label=" ",color="blue",arrowhead="dot" ];
"293" -> "504E" [ label=" ",color="blue",arrowhead="dot" ];
"293" -> "552E" [ label=" ",color="blue",arrowhead="dot" ];
"293" -> "634E" [ label=" ",color="blue",arrowhead="dot" ];
"293" -> "768E" [ label=" ",color="blue",arrowhead="dot" ];
"295" -> "44E" [ label=" ",color="blue",arrowhead="dot" ];
"295" -> "92E" [ label=" ",color="blue",arrowhead="dot" ];
"295" -> "250E" [ label=" ",color="blue",arrowhead="dot" ];
"295" -> "316E" [ label=" ",color="blue",arrowhead="dot" ];
"295" -> "380E" [ label=" ",color="blue",arrowhead="dot" ];
"295" -> "424E" [ label=" ",color="blue",arrowhead="dot" ];
"295" -> "442E" [ label=" ",color="blue",arrowhead="dot" ];
"295" -> "446E" [ label=" ",color="blue",arrowhead="dot" ];
"295" -> "454E" [ label=" ",color="blue",arrowhead="dot" ];
"295" -> "460E" [ label=" ",color="blue",arrowhead="dot" ];
"295" -> "462E" [ label=" ",color="blue",arrowhead="dot" ];
"295" -> "648E" [ label=" ",color="blue",arrowhead="dot" ];
"295" -> "656E" [ label=" ",color="blue",arrowhead="dot" ];
"295" -> "666E" [ label=" ",color="blue",arrowhead="dot" ];
"295" -> "692E" [ label=" ",color="blue",arrowhead="dot" ];
"295" -> "712E" [ label=" ",color="blue",arrowhead="dot" ];
"296" -> "47E" [ label=" ",color="blue",arrowhead="dot" ];
"296" -> "330E" [ label=" ",color="blue",arrowhead="dot" ];
"296" -> "514E" [ label=" ",color="blue",arrowhead="dot" ];
"296" -> "516E" [ label=" ",color="blue",arrowhead="dot" ];
"296" -> "518E" [ label=" ",color="blue",arrowhead="dot" ];
"296" -> "520E" [ label=" ",color="blue",arrowhead="dot" ];
"296" -> "522E" [ label=" ",color="blue",arrowhead="dot" ];
"296" -> "526E" [ label=" ",color="blue",arrowhead="dot" ];
"296" -> "528E" [ label=" ",color="blue",arrowhead="dot" ];
"296" -> "530E" [ label=" ",color="blue",arrowhead="dot" ];
"296" -> "532E" [ label=" ",color="blue",arrowhead="dot" ];
"296" -> "534E" [ label=" ",color="blue",arrowhead="dot" ];
"296" -> "536E" [ label=" ",color="blue",arrowhead="dot" ];
"296" -> "538E" [ label=" ",color="blue",arrowhead="dot" ];
"296" -> "540E" [ label=" ",color="blue",arrowhead="dot" ];
"296" -> "542E" [ label=" ",color="blue",arrowhead="dot" ];
"296" -> "544E" [ label=" ",color="blue",arrowhead="dot" ];
"297" -> "46E" [ label=" ",color="blue",arrowhead="dot" ];
"297" -> "93E" [ label=" ",color="blue",arrowhead="dot" ];
"297" -> "206E" [ label=" ",color="blue",arrowhead="dot" ];
"297" -> "426E" [ label=" ",color="blue",arrowhead="dot" ];
"297" -> "550E" [ label=" ",color="blue",arrowhead="dot" ];
"297" -> "706E" [ label=" ",color="blue",arrowhead="dot" ];
"298" -> "36E" [ label=" ",color="blue",arrowhead="dot" ];
"298" -> "95E" [ label=" ",color="blue",arrowhead="dot" ];
"298" -> "364E" [ label=" ",color="blue",arrowhead="dot" ];
"298" -> "394E" [ label=" ",color="blue",arrowhead="dot" ];
"298" -> "420E" [ label=" ",color="blue",arrowhead="dot" ];
"298" -> "456E" [ label=" ",color="blue",arrowhead="dot" ];
"298" -> "624E" [ label=" ",color="blue",arrowhead="dot" ];
"299" -> "48E" [ label=" ",color="blue",arrowhead="dot" ];
"299" -> "168E" [ label=" ",color="blue",arrowhead="dot" ];
"299" -> "260E" [ label=" ",color="blue",arrowhead="dot" ];
"299" -> "282E" [ label=" ",color="blue",arrowhead="dot" ];
"299" -> "554E" [ label=" ",color="blue",arrowhead="dot" ];
"299" -> "590E" [ label=" ",color="blue",arrowhead="dot" ];
"299" -> "767E" [ label=" ",color="blue",arrowhead="dot" ];
"300" -> "62E" [ label=" ",color="blue",arrowhead="dot" ];
"300" -> "190E" [ label=" ",color="blue",arrowhead="dot" ];
"300" -> "226E" [ label=" ",color="blue",arrowhead="dot" ];
"300" -> "238E" [ label=" ",color="blue",arrowhead="dot" ];
"300" -> "254E" [ label=" ",color="blue",arrowhead="dot" ];
"300" -> "256E" [ label=" ",color="blue",arrowhead="dot" ];
"300" -> "262E" [ label=" ",color="blue",arrowhead="dot" ];
"300" -> "266E" [ label=" ",color="blue",arrowhead="dot" ];
"300" -> "274E" [ label=" ",color="blue",arrowhead="dot" ];
"300" -> "276E" [ label=" ",color="blue",arrowhead="dot" ];
"300" -> "294E" [ label=" ",color="blue",arrowhead="dot" ];
"300" -> "296E" [ label=" ",color="blue",arrowhead="dot" ];
"300" -> "310E" [ label=" ",color="blue",arrowhead="dot" ];
"300" -> "320E" [ label=" ",color="blue",arrowhead="dot" ];
"300" -> "322E" [ label=" ",color="blue",arrowhead="dot" ];
"300" -> "332E" [ label=" ",color="blue",arrowhead="dot" ];
"300" -> "340E" [ label=" ",color="blue",arrowhead="dot" ];
"300" -> "344E" [ label=" ",color="blue",arrowhead="dot" ];
"300" -> "346E" [ label=" ",color="blue",arrowhead="dot" ];
"300" -> "348E" [ label=" ",color="blue",arrowhead="dot" ];
"300" -> "374E" [ label=" ",color="blue",arrowhead="dot" ];
"300" -> "378E" [ label=" ",color="blue",arrowhead="dot" ];
"300" -> "452E" [ label=" ",color="blue",arrowhead="dot" ];
"300" -> "508E" [ label=" ",color="blue",arrowhead="dot" ];
"300" -> "524E" [ label=" ",color="blue",arrowhead="dot" ];
"300" -> "612E" [ label=" ",color="blue",arrowhead="dot" ];
"300" -> "626E" [ label=" ",color="blue",arrowhead="dot" ];
"300" -> "638E" [ label=" ",color="blue",arrowhead="dot" ];
"300" -> "644E" [ label=" ",color="blue",arrowhead="dot" ];
"300" -> "654E" [ label=" ",color="blue",arrowhead="dot" ];
"300" -> "672E" [ label=" ",color="blue",arrowhead="dot" ];
"302" -> "797E" [ label=" ",color="blue",arrowhead="dot" ];
"302" -> "798E" [ label=" ",color="blue",arrowhead="dot" ];
"303" -> "52E" [ label=" ",color="blue",arrowhead="dot" ];
"303" -> "650E" [ label=" ",color="blue",arrowhead="dot" ];
"304" -> "50E" [ label=" ",color="blue",arrowhead="dot" ];
"304" -> "640E" [ label=" ",color="blue",arrowhead="dot" ];
"304" -> "646E" [ label=" ",color="blue",arrowhead="dot" ];
"304" -> "652E" [ label=" ",color="blue",arrowhead="dot" ];
"306" -> "55E" [ label=" ",color="blue",arrowhead="dot" ];
"306" -> "220E" [ label=" ",color="blue",arrowhead="dot" ];
"306" -> "338E" [ label=" ",color="blue",arrowhead="dot" ];
"306" -> "368E" [ label=" ",color="blue",arrowhead="dot" ];
"306" -> "486E" [ label=" ",color="blue",arrowhead="dot" ];
"306" -> "490E" [ label=" ",color="blue",arrowhead="dot" ];
"306" -> "562E" [ label=" ",color="blue",arrowhead="dot" ];
"306" -> "564E" [ label=" ",color="blue",arrowhead="dot" ];
"306" -> "600E" [ label=" ",color="blue",arrowhead="dot" ];
"306" -> "668E" [ label=" ",color="blue",arrowhead="dot" ];
"306" -> "674E" [ label=" ",color="blue",arrowhead="dot" ];
"306" -> "698E" [ label=" ",color="blue",arrowhead="dot" ];
"307" -> "107E" [ label=" ",color="blue",arrowhead="dot" ];
"308" -> "108E" [ label=" ",color="blue",arrowhead="dot" ];
"309" -> "109E" [ label=" ",color="blue",arrowhead="dot" ];
"310" -> "110E" [ label=" ",color="blue",arrowhead="dot" ];
"311" -> "58E" [ label=" ",color="blue",arrowhead="dot" ];
"311" -> "234E" [ label=" ",color="blue",arrowhead="dot" ];
"311" -> "300E" [ label=" ",color="blue",arrowhead="dot" ];
"311" -> "306E" [ label=" ",color="blue",arrowhead="dot" ];
"311" -> "314E" [ label=" ",color="blue",arrowhead="dot" ];
"311" -> "342E" [ label=" ",color="blue",arrowhead="dot" ];
"311" -> "354E" [ label=" ",color="blue",arrowhead="dot" ];
"311" -> "370E" [ label=" ",color="blue",arrowhead="dot" ];
"311" -> "382E" [ label=" ",color="blue",arrowhead="dot" ];
"311" -> "422E" [ label=" ",color="blue",arrowhead="dot" ];
"311" -> "444E" [ label=" ",color="blue",arrowhead="dot" ];
"311" -> "582E" [ label=" ",color="blue",arrowhead="dot" ];
"311" -> "620E" [ label=" ",color="blue",arrowhead="dot" ];
"311" -> "630E" [ label=" ",color="blue",arrowhead="dot" ];
"311" -> "684E" [ label=" ",color="blue",arrowhead="dot" ];
"311" -> "696E" [ label=" ",color="blue",arrowhead="dot" ];
"311" -> "801E" [ label=" ",color="blue",arrowhead="dot" ];
"312" -> "42E" [ label=" ",color="blue",arrowhead="dot" ];
"312" -> "192E" [ label=" ",color="blue",arrowhead="dot" ];
"312" -> "194E" [ label=" ",color="blue",arrowhead="dot" ];
"312" -> "196E" [ label=" ",color="blue",arrowhead="dot" ];
"312" -> "198E" [ label=" ",color="blue",arrowhead="dot" ];
"312" -> "200E" [ label=" ",color="blue",arrowhead="dot" ];
"312" -> "202E" [ label=" ",color="blue",arrowhead="dot" ];
"312" -> "204E" [ label=" ",color="blue",arrowhead="dot" ];
"312" -> "312E" [ label=" ",color="blue",arrowhead="dot" ];
"312" -> "336E" [ label=" ",color="blue",arrowhead="dot" ];
"312" -> "376E" [ label=" ",color="blue",arrowhead="dot" ];
"312" -> "384E" [ label=" ",color="blue",arrowhead="dot" ];
"312" -> "386E" [ label=" ",color="blue",arrowhead="dot" ];
"312" -> "428E" [ label=" ",color="blue",arrowhead="dot" ];
"312" -> "474E" [ label=" ",color="blue",arrowhead="dot" ];
"312" -> "484E" [ label=" ",color="blue",arrowhead="dot" ];
"312" -> "546E" [ label=" ",color="blue",arrowhead="dot" ];
"312" -> "548E" [ label=" ",color="blue",arrowhead="dot" ];
"314" -> "113E" [ label=" ",color="blue",arrowhead="dot" ];
"315" -> "43E" [ label=" ",color="blue",arrowhead="dot" ];
"315" -> "240E" [ label=" ",color="blue",arrowhead="dot" ];
"315" -> "298E" [ label=" ",color="blue",arrowhead="dot" ];
"315" -> "334E" [ label=" ",color="blue",arrowhead="dot" ];
"315" -> "360E" [ label=" ",color="blue",arrowhead="dot" ];
"315" -> "390E" [ label=" ",color="blue",arrowhead="dot" ];
"315" -> "418E" [ label=" ",color="blue",arrowhead="dot" ];
"315" -> "492E" [ label=" ",color="blue",arrowhead="dot" ];
"315" -> "502E" [ label=" ",color="blue",arrowhead="dot" ];
"315" -> "584E" [ label=" ",color="blue",arrowhead="dot" ];
"315" -> "588E" [ label=" ",color="blue",arrowhead="dot" ];
"315" -> "602E" [ label=" ",color="blue",arrowhead="dot" ];
"315" -> "606E" [ label=" ",color="blue",arrowhead="dot" ];
"315" -> "662E" [ label=" ",color="blue",arrowhead="dot" ];
"316" -> "51E" [ label=" ",color="blue",arrowhead="dot" ];
"317" -> "116E" [ label=" ",color="blue",arrowhead="dot" ];
"318" -> "74E" [ label=" ",color="blue",arrowhead="dot" ];
"319" -> "57E" [ label=" ",color="blue",arrowhead="dot" ];
"319" -> "94E" [ label=" ",color="blue",arrowhead="dot" ];
"319" -> "350E" [ label=" ",color="blue",arrowhead="dot" ];
"319" -> "440E" [ label=" ",color="blue",arrowhead="dot" ];
"319" -> "466E" [ label=" ",color="blue",arrowhead="dot" ];
"319" -> "676E" [ label=" ",color="blue",arrowhead="dot" ];
"320" -> "60E" [ label=" ",color="blue",arrowhead="dot" ];
"320" -> "366E" [ label=" ",color="blue",arrowhead="dot" ];
"320" -> "434E" [ label=" ",color="blue",arrowhead="dot" ];
"320" -> "458E" [ label=" ",color="blue",arrowhead="dot" ];
"320" -> "618E" [ label=" ",color="blue",arrowhead="dot" ];
"321" -> "72E" [ label=" ",color="blue",arrowhead="dot" ];
"321" -> "362E" [ label=" ",color="blue",arrowhead="dot" ];
"321" -> "372E" [ label=" ",color="blue",arrowhead="dot" ];
"321" -> "572E" [ label=" ",color="blue",arrowhead="dot" ];
"322" -> "54E" [ label=" ",color="blue",arrowhead="dot" ];
"322" -> "222E" [ label=" ",color="blue",arrowhead="dot" ];
"322" -> "302E" [ label=" ",color="blue",arrowhead="dot" ];
"322" -> "556E" [ label=" ",color="blue",arrowhead="dot" ];
"322" -> "558E" [ label=" ",color="blue",arrowhead="dot" ];
"323" -> "37E" [ label=" ",color="blue",arrowhead="dot" ];
"323" -> "208E" [ label=" ",color="blue",arrowhead="dot" ];
"323" -> "210E" [ label=" ",color="blue",arrowhead="dot" ];
"323" -> "352E" [ label=" ",color="blue",arrowhead="dot" ];
"323" -> "450E" [ label=" ",color="blue",arrowhead="dot" ];
"323" -> "568E" [ label=" ",color="blue",arrowhead="dot" ];
"323" -> "576E" [ label=" ",color="blue",arrowhead="dot" ];
"323" -> "686E" [ label=" ",color="blue",arrowhead="dot" ];
"324" -> "228E" [ label=" ",color="blue",arrowhead="dot" ];
"324" -> "248E" [ label=" ",color="blue",arrowhead="dot" ];
"324" -> "304E" [ label=" ",color="blue",arrowhead="dot" ];
"324" -> "468E" [ label=" ",color="blue",arrowhead="dot" ];
"324" -> "578E" [ label=" ",color="blue",arrowhead="dot" ];
"324" -> "660E" [ label=" ",color="blue",arrowhead="dot" ];
"324" -> "688E" [ label=" ",color="blue",arrowhead="dot" ];
"324" -> "694E" [ label=" ",color="blue",arrowhead="dot" ];
"324" -> "714E" [ label=" ",color="blue",arrowhead="dot" ];
"324" -> "766E" [ label=" ",color="blue",arrowhead="dot" ];
"325" -> "97E" [ label=" ",color="blue",arrowhead="dot" ];
"325" -> "506E" [ label=" ",color="blue",arrowhead="dot" ];
"326" -> "61E" [ label=" ",color="blue",arrowhead="dot" ];
"326" -> "175E" [ label=" ",color="blue",arrowhead="dot" ];
"326" -> "482E" [ label=" ",color="blue",arrowhead="dot" ];
"328" -> "75E" [ label=" ",color="blue",arrowhead="dot" ];
"328" -> "580E" [ label=" ",color="blue",arrowhead="dot" ];
"329" -> "96E" [ label=" ",color="blue",arrowhead="dot" ];
"330" -> "100E" [ label=" ",color="blue",arrowhead="dot" ];
"330" -> "170E" [ label=" ",color="blue",arrowhead="dot" ];
"333" -> "63E" [ label=" ",color="blue",arrowhead="dot" ];
"333" -> "67E" [ label=" ",color="blue",arrowhead="dot" ];
"333" -> "68E" [ label=" ",color="blue",arrowhead="dot" ];
"333" -> "69E" [ label=" ",color="blue",arrowhead="dot" ];
"333" -> "70E" [ label=" ",color="blue",arrowhead="dot" ];
"333" -> "71E" [ label=" ",color="blue",arrowhead="dot" ];
"333" -> "802E" [ label=" ",color="blue",arrowhead="dot" ];
"333" -> "793E" [ label=" ",color="blue",arrowhead="dot" ];
"334" -> "64E" [ label=" ",color="blue",arrowhead="dot" ];
"334" -> "81E" [ label=" ",color="blue",arrowhead="dot" ];
"334" -> "82E" [ label=" ",color="blue",arrowhead="dot" ];
"334" -> "83E" [ label=" ",color="blue",arrowhead="dot" ];
"334" -> "84E" [ label=" ",color="blue",arrowhead="dot" ];
"334" -> "85E" [ label=" ",color="blue",arrowhead="dot" ];
"334" -> "86E" [ label=" ",color="blue",arrowhead="dot" ];
"334" -> "87E" [ label=" ",color="blue",arrowhead="dot" ];
"334" -> "88E" [ label=" ",color="blue",arrowhead="dot" ];
"334" -> "89E" [ label=" ",color="blue",arrowhead="dot" ];
"336" -> "1E" [ label=" ",color="blue",arrowhead="dot" ];
"336" -> "2E" [ label=" ",color="blue",arrowhead="dot" ];
"336" -> "3E" [ label=" ",color="blue",arrowhead="dot" ];
"336" -> "4E" [ label=" ",color="blue",arrowhead="dot" ];
"336" -> "5E" [ label=" ",color="blue",arrowhead="dot" ];
"336" -> "6E" [ label=" ",color="blue",arrowhead="dot" ];
"336" -> "7E" [ label=" ",color="blue",arrowhead="dot" ];
"336" -> "8E" [ label=" ",color="blue",arrowhead="dot" ];
"336" -> "9E" [ label=" ",color="blue",arrowhead="dot" ];
"336" -> "10E" [ label=" ",color="blue",arrowhead="dot" ];
"336" -> "11E" [ label=" ",color="blue",arrowhead="dot" ];
"336" -> "12E" [ label=" ",color="blue",arrowhead="dot" ];
"336" -> "13E" [ label=" ",color="blue",arrowhead="dot" ];
"336" -> "14E" [ label=" ",color="blue",arrowhead="dot" ];
"336" -> "15E" [ label=" ",color="blue",arrowhead="dot" ];
"336" -> "16E" [ label=" ",color="blue",arrowhead="dot" ];
"336" -> "17E" [ label=" ",color="blue",arrowhead="dot" ];
"336" -> "18E" [ label=" ",color="blue",arrowhead="dot" ];
"336" -> "19E" [ label=" ",color="blue",arrowhead="dot" ];
"336" -> "20E" [ label=" ",color="blue",arrowhead="dot" ];
"336" -> "21E" [ label=" ",color="blue",arrowhead="dot" ];
"336" -> "22E" [ label=" ",color="blue",arrowhead="dot" ];
"336" -> "23E" [ label=" ",color="blue",arrowhead="dot" ];
"336" -> "24E" [ label=" ",color="blue",arrowhead="dot" ];
"336" -> "25E" [ label=" ",color="blue",arrowhead="dot" ];
"336" -> "26E" [ label=" ",color="blue",arrowhead="dot" ];
"336" -> "27E" [ label=" ",color="blue",arrowhead="dot" ];
"336" -> "28E" [ label=" ",color="blue",arrowhead="dot" ];
"336" -> "29E" [ label=" ",color="blue",arrowhead="dot" ];
"336" -> "30E" [ label=" ",color="blue",arrowhead="dot" ];
"336" -> "31E" [ label=" ",color="blue",arrowhead="dot" ];
"336" -> "65E" [ label=" ",color="blue",arrowhead="dot" ];
"336" -> "119E" [ label=" ",color="blue",arrowhead="dot" ];
"336" -> "150E" [ label=" ",color="blue",arrowhead="dot" ];
"336" -> "176E" [ label=" ",color="blue",arrowhead="dot" ];
"336" -> "743E" [ label=" ",color="blue",arrowhead="dot" ];
"336" -> "744E" [ label=" ",color="blue",arrowhead="dot" ];
"336" -> "764E" [ label=" ",color="blue",arrowhead="dot" ];
"337" -> "120E" [ label=" ",color="blue",arrowhead="dot" ];
"337" -> "121E" [ label=" ",color="blue",arrowhead="dot" ];
"337" -> "122E" [ label=" ",color="blue",arrowhead="dot" ];
"337" -> "123E" [ label=" ",color="blue",arrowhead="dot" ];
"337" -> "124E" [ label=" ",color="blue",arrowhead="dot" ];
"337" -> "125E" [ label=" ",color="blue",arrowhead="dot" ];
"337" -> "126E" [ label=" ",color="blue",arrowhead="dot" ];
"337" -> "127E" [ label=" ",color="blue",arrowhead="dot" ];
"337" -> "128E" [ label=" ",color="blue",arrowhead="dot" ];
"337" -> "129E" [ label=" ",color="blue",arrowhead="dot" ];
"337" -> "130E" [ label=" ",color="blue",arrowhead="dot" ];
"337" -> "131E" [ label=" ",color="blue",arrowhead="dot" ];
"337" -> "132E" [ label=" ",color="blue",arrowhead="dot" ];
"337" -> "133E" [ label=" ",color="blue",arrowhead="dot" ];
"337" -> "134E" [ label=" ",color="blue",arrowhead="dot" ];
"337" -> "135E" [ label=" ",color="blue",arrowhead="dot" ];
"337" -> "136E" [ label=" ",color="blue",arrowhead="dot" ];
"337" -> "137E" [ label=" ",color="blue",arrowhead="dot" ];
"337" -> "138E" [ label=" ",color="blue",arrowhead="dot" ];
"339" -> "151E" [ label=" ",color="blue",arrowhead="dot" ];
"339" -> "153E" [ label=" ",color="blue",arrowhead="dot" ];
"339" -> "154E" [ label=" ",color="blue",arrowhead="dot" ];
"339" -> "155E" [ label=" ",color="blue",arrowhead="dot" ];
"339" -> "156E" [ label=" ",color="blue",arrowhead="dot" ];
"339" -> "157E" [ label=" ",color="blue",arrowhead="dot" ];
"339" -> "158E" [ label=" ",color="blue",arrowhead="dot" ];
"339" -> "159E" [ label=" ",color="blue",arrowhead="dot" ];
"339" -> "160E" [ label=" ",color="blue",arrowhead="dot" ];
"339" -> "161E" [ label=" ",color="blue",arrowhead="dot" ];
"339" -> "162E" [ label=" ",color="blue",arrowhead="dot" ];
"347" -> "139E" [ label=" ",color="blue",arrowhead="dot" ];
"347" -> "795E" [ label=" ",color="blue",arrowhead="dot" ];
"348" -> "799E" [ label=" ",color="blue",arrowhead="dot" ];
"348" -> "800E" [ label=" ",color="blue",arrowhead="dot" ];
"349" -> "141E" [ label=" ",color="blue",arrowhead="dot" ];
"350" -> "142E" [ label=" ",color="blue",arrowhead="dot" ];
"350" -> "678E" [ label=" ",color="blue",arrowhead="dot" ];
"351" -> "143E" [ label=" ",color="blue",arrowhead="dot" ];
"351" -> "232E" [ label=" ",color="blue",arrowhead="dot" ];
"351" -> "680E" [ label=" ",color="blue",arrowhead="dot" ];
"351" -> "704E" [ label=" ",color="blue",arrowhead="dot" ];
"352" -> "144E" [ label=" ",color="blue",arrowhead="dot" ];
"352" -> "432E" [ label=" ",color="blue",arrowhead="dot" ];
"353" -> "145E" [ label=" ",color="blue",arrowhead="dot" ];
"354" -> "146E" [ label=" ",color="blue",arrowhead="dot" ];
"354" -> "396E" [ label=" ",color="blue",arrowhead="dot" ];
"355" -> "147E" [ label=" ",color="blue",arrowhead="dot" ];
"356" -> "148E" [ label=" ",color="blue",arrowhead="dot" ];
"357" -> "149E" [ label=" ",color="blue",arrowhead="dot" ];
"358" -> "167E" [ label=" ",color="blue",arrowhead="dot" ];
"359" -> "169E" [ label=" ",color="blue",arrowhead="dot" ];
"360" -> "171E" [ label=" ",color="blue",arrowhead="dot" ];
"361" -> "172E" [ label=" ",color="blue",arrowhead="dot" ];
"362" -> "173E" [ label=" ",color="blue",arrowhead="dot" ];
"363" -> "174E" [ label=" ",color="blue",arrowhead="dot" ];
"364" -> "101E" [ label=" ",color="blue",arrowhead="dot" ];
"365" -> "102E" [ label=" ",color="blue",arrowhead="dot" ];
"367" -> "104E" [ label=" ",color="blue",arrowhead="dot" ];
"368" -> "105E" [ label=" ",color="blue",arrowhead="dot" ];
"369" -> "106E" [ label=" ",color="blue",arrowhead="dot" ];
"374" -> "111E" [ label=" ",color="blue",arrowhead="dot" ];
"375" -> "112E" [ label=" ",color="blue",arrowhead="dot" ];
"377" -> "114E" [ label=" ",color="blue",arrowhead="dot" ];
"378" -> "115E" [ label=" ",color="blue",arrowhead="dot" ];
"380" -> "117E" [ label=" ",color="blue",arrowhead="dot" ];
"380" -> "392E" [ label=" ",color="blue",arrowhead="dot" ];
"381" -> "118E" [ label=" ",color="blue",arrowhead="dot" ];
"382" -> "177E" [ label=" ",color="blue",arrowhead="dot" ];
"382" -> "178E" [ label=" ",color="blue",arrowhead="dot" ];
"382" -> "179E" [ label=" ",color="blue",arrowhead="dot" ];
"382" -> "180E" [ label=" ",color="blue",arrowhead="dot" ];
"382" -> "181E" [ label=" ",color="blue",arrowhead="dot" ];
"382" -> "182E" [ label=" ",color="blue",arrowhead="dot" ];
"382" -> "183E" [ label=" ",color="blue",arrowhead="dot" ];
"382" -> "184E" [ label=" ",color="blue",arrowhead="dot" ];
"382" -> "185E" [ label=" ",color="blue",arrowhead="dot" ];
"382" -> "186E" [ label=" ",color="blue",arrowhead="dot" ];
"382" -> "187E" [ label=" ",color="blue",arrowhead="dot" ];
"382" -> "188E" [ label=" ",color="blue",arrowhead="dot" ];
"383" -> "730E" [ label=" ",color="blue",arrowhead="dot" ];
"383" -> "732E" [ label=" ",color="blue",arrowhead="dot" ];
"383" -> "741E" [ label=" ",color="blue",arrowhead="dot" ];
"383" -> "765E" [ label=" ",color="blue",arrowhead="dot" ];
"383" -> "796E" [ label=" ",color="blue",arrowhead="dot" ];
"384" -> "726E" [ label=" ",color="blue",arrowhead="dot" ];
"384" -> "728E" [ label=" ",color="blue",arrowhead="dot" ];
"384" -> "742E" [ label=" ",color="blue",arrowhead="dot" ];
"385" -> "328E" [ label=" ",color="blue",arrowhead="dot" ];
"385" -> "496E" [ label=" ",color="blue",arrowhead="dot" ];
"385" -> "594E" [ label=" ",color="blue",arrowhead="dot" ];
"385" -> "622E" [ label=" ",color="blue",arrowhead="dot" ];
"385" -> "754E" [ label=" ",color="blue",arrowhead="dot" ];
"385" -> "755E" [ label=" ",color="blue",arrowhead="dot" ];
"385" -> "756E" [ label=" ",color="blue",arrowhead="dot" ];
"385" -> "757E" [ label=" ",color="blue",arrowhead="dot" ];
"385" -> "758E" [ label=" ",color="blue",arrowhead="dot" ];
"385" -> "759E" [ label=" ",color="blue",arrowhead="dot" ];
"385" -> "760E" [ label=" ",color="blue",arrowhead="dot" ];
"385" -> "761E" [ label=" ",color="blue",arrowhead="dot" ];
"385" -> "762E" [ label=" ",color="blue",arrowhead="dot" ];
"1E" -> "34E" [ color="purple",arrowhead="none" ];
"2E" -> "35E" [ color="purple",arrowhead="none" ];
"3E" -> "36E" [ color="purple",arrowhead="none" ];
"4E" -> "37E" [ color="purple",arrowhead="none" ];
"5E" -> "38E" [ color="purple",arrowhead="none" ];
"6E" -> "39E" [ color="purple",arrowhead="none" ];
"7E" -> "40E" [ color="purple",arrowhead="none" ];
"9E" -> "41E" [ color="purple",arrowhead="none" ];
"10E" -> "42E" [ color="purple",arrowhead="none" ];
"11E" -> "43E" [ color="purple",arrowhead="none" ];
"12E" -> "44E" [ color="purple",arrowhead="none" ];
"13E" -> "45E" [ color="purple",arrowhead="none" ];
"14E" -> "46E" [ color="purple",arrowhead="none" ];
"15E" -> "47E" [ color="purple",arrowhead="none" ];
"16E" -> "48E" [ color="purple",arrowhead="none" ];
"49E" -> "17E" [ color="purple",arrowhead="none" ];
"18E" -> "50E" [ color="purple",arrowhead="none" ];
"19E" -> "51E" [ color="purple",arrowhead="none" ];
"20E" -> "52E" [ color="purple",arrowhead="none" ];
"21E" -> "53E" [ color="purple",arrowhead="none" ];
"22E" -> "54E" [ color="purple",arrowhead="none" ];
"23E" -> "55E" [ color="purple",arrowhead="none" ];
"24E" -> "56E" [ color="purple",arrowhead="none" ];
"25E" -> "57E" [ color="purple",arrowhead="none" ];
"26E" -> "58E" [ color="purple",arrowhead="none" ];
"27E" -> "59E" [ color="purple",arrowhead="none" ];
"28E" -> "60E" [ color="purple",arrowhead="none" ];
"29E" -> "61E" [ color="purple",arrowhead="none" ];
"30E" -> "62E" [ color="purple",arrowhead="none" ];
"31E" -> "63E" [ color="purple",arrowhead="none" ];
"64E" -> "65E" [ color="purple",arrowhead="none" ];
"66E" -> "8E" [ color="purple",arrowhead="none" ];
"71E" -> "76E" [ color="purple",arrowhead="none" ];
"67E" -> "72E" [ color="purple",arrowhead="none" ];
"68E" -> "73E" [ color="purple",arrowhead="none" ];
"69E" -> "74E" [ color="purple",arrowhead="none" ];
"70E" -> "75E" [ color="purple",arrowhead="none" ];
"81E" -> "92E" [ color="purple",arrowhead="none" ];
"82E" -> "93E" [ color="purple",arrowhead="none" ];
"83E" -> "94E" [ color="purple",arrowhead="none" ];
"84E" -> "95E" [ color="purple",arrowhead="none" ];
"85E" -> "96E" [ color="purple",arrowhead="none" ];
"86E" -> "97E" [ color="purple",arrowhead="none" ];
"87E" -> "98E" [ color="purple",arrowhead="none" ];
"88E" -> "99E" [ color="purple",arrowhead="none" ];
"89E" -> "100E" [ color="purple",arrowhead="none" ];
"101E" -> "120E" [ color="purple",arrowhead="none" ];
"102E" -> "121E" [ color="purple",arrowhead="none" ];
"103E" -> "122E" [ color="purple",arrowhead="none" ];
"104E" -> "123E" [ color="purple",arrowhead="none" ];
"105E" -> "124E" [ color="purple",arrowhead="none" ];
"106E" -> "125E" [ color="purple",arrowhead="none" ];
"107E" -> "126E" [ color="purple",arrowhead="none" ];
"108E" -> "127E" [ color="purple",arrowhead="none" ];
"109E" -> "128E" [ color="purple",arrowhead="none" ];
"110E" -> "129E" [ color="purple",arrowhead="none" ];
"111E" -> "130E" [ color="purple",arrowhead="none" ];
"112E" -> "131E" [ color="purple",arrowhead="none" ];
"113E" -> "132E" [ color="purple",arrowhead="none" ];
"114E" -> "133E" [ color="purple",arrowhead="none" ];
"115E" -> "134E" [ color="purple",arrowhead="none" ];
"116E" -> "135E" [ color="purple",arrowhead="none" ];
"117E" -> "136E" [ color="purple",arrowhead="none" ];
"118E" -> "137E" [ color="purple",arrowhead="none" ];
"119E" -> "138E" [ color="purple",arrowhead="none" ];
"139E" -> "151E" [ color="purple",arrowhead="none" ];
"141E" -> "153E" [ color="purple",arrowhead="none" ];
"142E" -> "154E" [ color="purple",arrowhead="none" ];
"143E" -> "155E" [ color="purple",arrowhead="none" ];
"144E" -> "156E" [ color="purple",arrowhead="none" ];
"145E" -> "157E" [ color="purple",arrowhead="none" ];
"146E" -> "158E" [ color="purple",arrowhead="none" ];
"147E" -> "159E" [ color="purple",arrowhead="none" ];
"148E" -> "160E" [ color="purple",arrowhead="none" ];
"149E" -> "161E" [ color="purple",arrowhead="none" ];
"150E" -> "162E" [ color="purple",arrowhead="none" ];
"165E" -> "177E" [ color="purple",arrowhead="none" ];
"166E" -> "178E" [ color="purple",arrowhead="none" ];
"167E" -> "179E" [ color="purple",arrowhead="none" ];
"168E" -> "180E" [ color="purple",arrowhead="none" ];
"169E" -> "181E" [ color="purple",arrowhead="none" ];
"170E" -> "182E" [ color="purple",arrowhead="none" ];
"171E" -> "183E" [ color="purple",arrowhead="none" ];
"172E" -> "184E" [ color="purple",arrowhead="none" ];
"173E" -> "185E" [ color="purple",arrowhead="none" ];
"174E" -> "186E" [ color="purple",arrowhead="none" ];
"175E" -> "187E" [ color="purple",arrowhead="none" ];
"176E" -> "188E" [ color="purple",arrowhead="none" ];
"189E" -> "190E" [ color="purple",arrowhead="none" ];
"191E" -> "192E" [ color="purple",arrowhead="none" ];
"193E" -> "194E" [ color="purple",arrowhead="none" ];
"195E" -> "196E" [ color="purple",arrowhead="none" ];
"197E" -> "198E" [ color="purple",arrowhead="none" ];
"199E" -> "200E" [ color="purple",arrowhead="none" ];
"201E" -> "202E" [ color="purple",arrowhead="none" ];
"203E" -> "204E" [ color="purple",arrowhead="none" ];
"205E" -> "206E" [ color="purple",arrowhead="none" ];
"207E" -> "208E" [ color="purple",arrowhead="none" ];
"209E" -> "210E" [ color="purple",arrowhead="none" ];
"412E" -> "211E" [ color="purple",arrowhead="none" ];
"214E" -> "213E" [ color="purple",arrowhead="none" ];
"216E" -> "215E" [ color="purple",arrowhead="none" ];
"217E" -> "218E" [ color="purple",arrowhead="none" ];
"219E" -> "220E" [ color="purple",arrowhead="none" ];
"221E" -> "222E" [ color="purple",arrowhead="none" ];
"223E" -> "224E" [ color="purple",arrowhead="none" ];
"225E" -> "226E" [ color="purple",arrowhead="none" ];
"227E" -> "228E" [ color="purple",arrowhead="none" ];
"231E" -> "232E" [ color="purple",arrowhead="none" ];
"233E" -> "234E" [ color="purple",arrowhead="none" ];
"236E" -> "235E" [ color="purple",arrowhead="none" ];
"237E" -> "238E" [ color="purple",arrowhead="none" ];
"239E" -> "240E" [ color="purple",arrowhead="none" ];
"241E" -> "242E" [ color="purple",arrowhead="none" ];
"243E" -> "244E" [ color="purple",arrowhead="none" ];
"245E" -> "246E" [ color="purple",arrowhead="none" ];
"247E" -> "248E" [ color="purple",arrowhead="none" ];
"249E" -> "250E" [ color="purple",arrowhead="none" ];
"251E" -> "252E" [ color="purple",arrowhead="none" ];
"253E" -> "254E" [ color="purple",arrowhead="none" ];
"255E" -> "256E" [ color="purple",arrowhead="none" ];
"257E" -> "258E" [ color="purple",arrowhead="none" ];
"259E" -> "260E" [ color="purple",arrowhead="none" ];
"261E" -> "262E" [ color="purple",arrowhead="none" ];
"263E" -> "264E" [ color="purple",arrowhead="none" ];
"265E" -> "266E" [ color="purple",arrowhead="none" ];
"267E" -> "268E" [ color="purple",arrowhead="none" ];
"269E" -> "270E" [ color="purple",arrowhead="none" ];
"271E" -> "272E" [ color="purple",arrowhead="none" ];
"273E" -> "274E" [ color="purple",arrowhead="none" ];
"275E" -> "276E" [ color="purple",arrowhead="none" ];
"278E" -> "277E" [ color="purple",arrowhead="none" ];
"279E" -> "767E" [ color="purple",arrowhead="none" ];
"281E" -> "282E" [ color="purple",arrowhead="none" ];
"283E" -> "284E" [ color="purple",arrowhead="none" ];
"285E" -> "286E" [ color="purple",arrowhead="none" ];
"768E" -> "287E" [ color="purple",arrowhead="none" ];
"289E" -> "290E" [ color="purple",arrowhead="none" ];
"291E" -> "292E" [ color="purple",arrowhead="none" ];
"293E" -> "294E" [ color="purple",arrowhead="none" ];
"295E" -> "296E" [ color="purple",arrowhead="none" ];
"297E" -> "298E" [ color="purple",arrowhead="none" ];
"299E" -> "300E" [ color="purple",arrowhead="none" ];
"301E" -> "302E" [ color="purple",arrowhead="none" ];
"303E" -> "304E" [ color="purple",arrowhead="none" ];
"305E" -> "306E" [ color="purple",arrowhead="none" ];
"307E" -> "308E" [ color="purple",arrowhead="none" ];
"309E" -> "310E" [ color="purple",arrowhead="none" ];
"311E" -> "312E" [ color="purple",arrowhead="none" ];
"313E" -> "314E" [ color="purple",arrowhead="none" ];
"315E" -> "316E" [ color="purple",arrowhead="none" ];
"317E" -> "318E" [ color="purple",arrowhead="none" ];
"319E" -> "320E" [ color="purple",arrowhead="none" ];
"321E" -> "322E" [ color="purple",arrowhead="none" ];
"327E" -> "800E" [ color="purple",arrowhead="none" ];
"329E" -> "330E" [ color="purple",arrowhead="none" ];
"331E" -> "332E" [ color="purple",arrowhead="none" ];
"333E" -> "334E" [ color="purple",arrowhead="none" ];
"335E" -> "336E" [ color="purple",arrowhead="none" ];
"337E" -> "338E" [ color="purple",arrowhead="none" ];
"339E" -> "340E" [ color="purple",arrowhead="none" ];
"341E" -> "342E" [ color="purple",arrowhead="none" ];
"343E" -> "344E" [ color="purple",arrowhead="none" ];
"345E" -> "346E" [ color="purple",arrowhead="none" ];
"347E" -> "348E" [ color="purple",arrowhead="none" ];
"349E" -> "350E" [ color="purple",arrowhead="none" ];
"351E" -> "352E" [ color="purple",arrowhead="none" ];
"353E" -> "354E" [ color="purple",arrowhead="none" ];
"412E" -> "355E" [ color="purple",arrowhead="none" ];
"357E" -> "358E" [ color="purple",arrowhead="none" ];
"359E" -> "360E" [ color="purple",arrowhead="none" ];
"361E" -> "362E" [ color="purple",arrowhead="none" ];
"363E" -> "364E" [ color="purple",arrowhead="none" ];
"365E" -> "366E" [ color="purple",arrowhead="none" ];
"367E" -> "368E" [ color="purple",arrowhead="none" ];
"369E" -> "370E" [ color="purple",arrowhead="none" ];
"371E" -> "372E" [ color="purple",arrowhead="none" ];
"373E" -> "374E" [ color="purple",arrowhead="none" ];
"375E" -> "376E" [ color="purple",arrowhead="none" ];
"377E" -> "378E" [ color="purple",arrowhead="none" ];
"379E" -> "380E" [ color="purple",arrowhead="none" ];
"381E" -> "382E" [ color="purple",arrowhead="none" ];
"383E" -> "384E" [ color="purple",arrowhead="none" ];
"385E" -> "386E" [ color="purple",arrowhead="none" ];
"387E" -> "388E" [ color="purple",arrowhead="none" ];
"389E" -> "390E" [ color="purple",arrowhead="none" ];
"391E" -> "392E" [ color="purple",arrowhead="none" ];
"393E" -> "394E" [ color="purple",arrowhead="none" ];
"395E" -> "396E" [ color="purple",arrowhead="none" ];
"397E" -> "398E" [ color="purple",arrowhead="none" ];
"399E" -> "400E" [ color="purple",arrowhead="none" ];
"402E" -> "401E" [ color="purple",arrowhead="none" ];
"404E" -> "403E" [ color="purple",arrowhead="none" ];
"406E" -> "405E" [ color="purple",arrowhead="none" ];
"408E" -> "407E" [ color="purple",arrowhead="none" ];
"236E" -> "409E" [ color="purple",arrowhead="none" ];
"412E" -> "411E" [ color="purple",arrowhead="none" ];
"412E" -> "413E" [ color="purple",arrowhead="none" ];
"278E" -> "415E" [ color="purple",arrowhead="none" ];
"417E" -> "418E" [ color="purple",arrowhead="none" ];
"419E" -> "420E" [ color="purple",arrowhead="none" ];
"421E" -> "422E" [ color="purple",arrowhead="none" ];
"423E" -> "424E" [ color="purple",arrowhead="none" ];
"425E" -> "426E" [ color="purple",arrowhead="none" ];
"427E" -> "428E" [ color="purple",arrowhead="none" ];
"431E" -> "432E" [ color="purple",arrowhead="none" ];
"433E" -> "434E" [ color="purple",arrowhead="none" ];
"435E" -> "436E" [ color="purple",arrowhead="none" ];
"438E" -> "437E" [ color="purple",arrowhead="none" ];
"439E" -> "440E" [ color="purple",arrowhead="none" ];
"441E" -> "442E" [ color="purple",arrowhead="none" ];
"443E" -> "444E" [ color="purple",arrowhead="none" ];
"445E" -> "446E" [ color="purple",arrowhead="none" ];
"448E" -> "447E" [ color="purple",arrowhead="none" ];
"449E" -> "450E" [ color="purple",arrowhead="none" ];
"451E" -> "452E" [ color="purple",arrowhead="none" ];
"453E" -> "454E" [ color="purple",arrowhead="none" ];
"455E" -> "456E" [ color="purple",arrowhead="none" ];
"457E" -> "458E" [ color="purple",arrowhead="none" ];
"459E" -> "460E" [ color="purple",arrowhead="none" ];
"461E" -> "462E" [ color="purple",arrowhead="none" ];
"236E" -> "463E" [ color="purple",arrowhead="none" ];
"465E" -> "466E" [ color="purple",arrowhead="none" ];
"467E" -> "468E" [ color="purple",arrowhead="none" ];
"469E" -> "470E" [ color="purple",arrowhead="none" ];
"471E" -> "472E" [ color="purple",arrowhead="none" ];
"473E" -> "474E" [ color="purple",arrowhead="none" ];
"476E" -> "475E" [ color="purple",arrowhead="none" ];
"477E" -> "478E" [ color="purple",arrowhead="none" ];
"479E" -> "358E" [ color="purple",arrowhead="none" ];
"481E" -> "482E" [ color="purple",arrowhead="none" ];
"483E" -> "484E" [ color="purple",arrowhead="none" ];
"485E" -> "486E" [ color="purple",arrowhead="none" ];
"487E" -> "488E" [ color="purple",arrowhead="none" ];
"489E" -> "490E" [ color="purple",arrowhead="none" ];
"491E" -> "492E" [ color="purple",arrowhead="none" ];
"495E" -> "795E" [ color="purple",arrowhead="none" ];
"499E" -> "500E" [ color="purple",arrowhead="none" ];
"501E" -> "502E" [ color="purple",arrowhead="none" ];
"504E" -> "503E" [ color="purple",arrowhead="none" ];
"505E" -> "506E" [ color="purple",arrowhead="none" ];
"507E" -> "508E" [ color="purple",arrowhead="none" ];
"509E" -> "510E" [ color="purple",arrowhead="none" ];
"412E" -> "511E" [ color="purple",arrowhead="none" ];
"513E" -> "514E" [ color="purple",arrowhead="none" ];
"515E" -> "516E" [ color="purple",arrowhead="none" ];
"517E" -> "518E" [ color="purple",arrowhead="none" ];
"519E" -> "520E" [ color="purple",arrowhead="none" ];
"521E" -> "522E" [ color="purple",arrowhead="none" ];
"523E" -> "524E" [ color="purple",arrowhead="none" ];
"525E" -> "526E" [ color="purple",arrowhead="none" ];
"527E" -> "528E" [ color="purple",arrowhead="none" ];
"529E" -> "530E" [ color="purple",arrowhead="none" ];
"531E" -> "532E" [ color="purple",arrowhead="none" ];
"533E" -> "534E" [ color="purple",arrowhead="none" ];
"535E" -> "536E" [ color="purple",arrowhead="none" ];
"537E" -> "538E" [ color="purple",arrowhead="none" ];
"539E" -> "540E" [ color="purple",arrowhead="none" ];
"541E" -> "542E" [ color="purple",arrowhead="none" ];
"543E" -> "544E" [ color="purple",arrowhead="none" ];
"545E" -> "546E" [ color="purple",arrowhead="none" ];
"547E" -> "548E" [ color="purple",arrowhead="none" ];
"549E" -> "550E" [ color="purple",arrowhead="none" ];
"551E" -> "552E" [ color="purple",arrowhead="none" ];
"553E" -> "554E" [ color="purple",arrowhead="none" ];
"555E" -> "556E" [ color="purple",arrowhead="none" ];
"557E" -> "558E" [ color="purple",arrowhead="none" ];
"278E" -> "559E" [ color="purple",arrowhead="none" ];
"561E" -> "562E" [ color="purple",arrowhead="none" ];
"563E" -> "564E" [ color="purple",arrowhead="none" ];
"565E" -> "566E" [ color="purple",arrowhead="none" ];
"567E" -> "568E" [ color="purple",arrowhead="none" ];
"569E" -> "570E" [ color="purple",arrowhead="none" ];
"571E" -> "572E" [ color="purple",arrowhead="none" ];
"573E" -> "574E" [ color="purple",arrowhead="none" ];
"575E" -> "576E" [ color="purple",arrowhead="none" ];
"577E" -> "578E" [ color="purple",arrowhead="none" ];
"579E" -> "580E" [ color="purple",arrowhead="none" ];
"581E" -> "582E" [ color="purple",arrowhead="none" ];
"583E" -> "584E" [ color="purple",arrowhead="none" ];
"585E" -> "586E" [ color="purple",arrowhead="none" ];
"587E" -> "588E" [ color="purple",arrowhead="none" ];
"589E" -> "590E" [ color="purple",arrowhead="none" ];
"593E" -> "594E" [ color="purple",arrowhead="none" ];
"597E" -> "598E" [ color="purple",arrowhead="none" ];
"599E" -> "600E" [ color="purple",arrowhead="none" ];
"601E" -> "602E" [ color="purple",arrowhead="none" ];
"603E" -> "604E" [ color="purple",arrowhead="none" ];
"605E" -> "606E" [ color="purple",arrowhead="none" ];
"607E" -> "608E" [ color="purple",arrowhead="none" ];
"609E" -> "610E" [ color="purple",arrowhead="none" ];
"611E" -> "612E" [ color="purple",arrowhead="none" ];
"613E" -> "614E" [ color="purple",arrowhead="none" ];
"615E" -> "358E" [ color="purple",arrowhead="none" ];
"617E" -> "618E" [ color="purple",arrowhead="none" ];
"619E" -> "620E" [ color="purple",arrowhead="none" ];
"621E" -> "622E" [ color="purple",arrowhead="none" ];
"623E" -> "624E" [ color="purple",arrowhead="none" ];
"625E" -> "626E" [ color="purple",arrowhead="none" ];
"627E" -> "628E" [ color="purple",arrowhead="none" ];
"629E" -> "630E" [ color="purple",arrowhead="none" ];
"631E" -> "632E" [ color="purple",arrowhead="none" ];
"634E" -> "633E" [ color="purple",arrowhead="none" ];
"635E" -> "636E" [ color="purple",arrowhead="none" ];
"637E" -> "638E" [ color="purple",arrowhead="none" ];
"639E" -> "640E" [ color="purple",arrowhead="none" ];
"641E" -> "642E" [ color="purple",arrowhead="none" ];
"643E" -> "644E" [ color="purple",arrowhead="none" ];
"645E" -> "646E" [ color="purple",arrowhead="none" ];
"647E" -> "648E" [ color="purple",arrowhead="none" ];
"649E" -> "650E" [ color="purple",arrowhead="none" ];
"651E" -> "652E" [ color="purple",arrowhead="none" ];
"653E" -> "654E" [ color="purple",arrowhead="none" ];
"655E" -> "656E" [ color="purple",arrowhead="none" ];
"657E" -> "658E" [ color="purple",arrowhead="none" ];
"659E" -> "660E" [ color="purple",arrowhead="none" ];
"661E" -> "662E" [ color="purple",arrowhead="none" ];
"663E" -> "664E" [ color="purple",arrowhead="none" ];
"665E" -> "666E" [ color="purple",arrowhead="none" ];
"667E" -> "668E" [ color="purple",arrowhead="none" ];
"669E" -> "670E" [ color="purple",arrowhead="none" ];
"671E" -> "672E" [ color="purple",arrowhead="none" ];
"673E" -> "674E" [ color="purple",arrowhead="none" ];
"675E" -> "676E" [ color="purple",arrowhead="none" ];
"679E" -> "680E" [ color="purple",arrowhead="none" ];
"681E" -> "682E" [ color="purple",arrowhead="none" ];
"683E" -> "684E" [ color="purple",arrowhead="none" ];
"685E" -> "686E" [ color="purple",arrowhead="none" ];
"687E" -> "688E" [ color="purple",arrowhead="none" ];
"689E" -> "690E" [ color="purple",arrowhead="none" ];
"691E" -> "692E" [ color="purple",arrowhead="none" ];
"693E" -> "694E" [ color="purple",arrowhead="none" ];
"695E" -> "696E" [ color="purple",arrowhead="none" ];
"697E" -> "698E" [ color="purple",arrowhead="none" ];
"699E" -> "700E" [ color="purple",arrowhead="none" ];
"703E" -> "704E" [ color="purple",arrowhead="none" ];
"705E" -> "706E" [ color="purple",arrowhead="none" ];
"709E" -> "710E" [ color="purple",arrowhead="none" ];
"711E" -> "712E" [ color="purple",arrowhead="none" ];
"713E" -> "714E" [ color="purple",arrowhead="none" ];
"715E" -> "398E" [ color="purple",arrowhead="none" ];
"717E" -> "718E" [ color="purple",arrowhead="none" ];
"719E" -> "720E" [ color="purple",arrowhead="none" ];
"721E" -> "722E" [ color="purple",arrowhead="none" ];
"725E" -> "726E" [ color="purple",arrowhead="none" ];
"727E" -> "728E" [ color="purple",arrowhead="none" ];
"729E" -> "730E" [ color="purple",arrowhead="none" ];
"731E" -> "732E" [ color="purple",arrowhead="none" ];
"741E" -> "743E" [ color="purple",arrowhead="none" ];
"742E" -> "744E" [ color="purple",arrowhead="none" ];
"745E" -> "754E" [ color="purple",arrowhead="none" ];
"746E" -> "755E" [ color="purple",arrowhead="none" ];
"747E" -> "756E" [ color="purple",arrowhead="none" ];
"748E" -> "757E" [ color="purple",arrowhead="none" ];
"749E" -> "758E" [ color="purple",arrowhead="none" ];
"750E" -> "759E" [ color="purple",arrowhead="none" ];
"751E" -> "760E" [ color="purple",arrowhead="none" ];
"752E" -> "761E" [ color="purple",arrowhead="none" ];
"753E" -> "762E" [ color="purple",arrowhead="none" ];
"763E" -> "764E" [ color="purple",arrowhead="none" ];
"765E" -> "766E" [ color="purple",arrowhead="none" ];
"770E" -> "783E" [ color="purple",arrowhead="none" ];
"770E" -> "784E" [ color="purple",arrowhead="none" ];
"769E" -> "785E" [ color="purple",arrowhead="none" ];
"769E" -> "786E" [ color="purple",arrowhead="none" ];
"769E" -> "787E" [ color="purple",arrowhead="none" ];
"770E" -> "788E" [ color="purple",arrowhead="none" ];
"770E" -> "789E" [ color="purple",arrowhead="none" ];
"769E" -> "790E" [ color="purple",arrowhead="none" ];
"770E" -> "791E" [ color="purple",arrowhead="none" ];
"769E" -> "792E" [ color="purple",arrowhead="none" ];
"793E" -> "769E" [ color="purple",arrowhead="none" ];
"769E" -> "784E" [ color="purple",arrowhead="none" ];
"770E" -> "785E" [ color="purple",arrowhead="none" ];
"788E" -> "787E" [ color="purple",arrowhead="none" ];
"770E" -> "792E" [ color="purple",arrowhead="none" ];
"798E" -> "799E" [ color="purple",arrowhead="none" ];
"796E" -> "797E" [ color="purple",arrowhead="none" ];
"793E" -> "789E" [ color="purple",arrowhead="none" ];
"783E" -> "787E" [ color="purple",arrowhead="none" ];
"784E" -> "792E" [ color="purple",arrowhead="none" ];
"787E" -> "789E" [ color="purple",arrowhead="none" ];
"769E" -> "791E" [ color="purple",arrowhead="none" ];
"802E" -> "801E" [ color="purple",arrowhead="none" ];
}
ocamlgraph-2.0.0/editor/tests/test2_2.gml 0000644 0001750 0000144 00000000710 13735627615 016622 0 ustar rt users graph [
comment "This is a sample graph"
directed 1
id 42
label "Hello, I am a graph"
node [ id 1 label "Node 1" ]
node [ id 2 label "node 2" ]
node [ id 3 label "node 3" ]
node [ id 4 label "node 4" ]
node [ id 5 label "node 5" ]
edge [ source 1 target 2 ]
edge [ source 1 target 3 ]
edge [ source 1 target 4 ]
edge [ source 1 target 5 ]
edge [ source 2 target 3 ]
edge [ source 4 target 5 ]
] ocamlgraph-2.0.0/editor/tests/test2,1_2.gml 0000644 0001750 0000144 00000001007 13735627615 016757 0 ustar rt users graph [
comment "This is a sample graph"
directed 1
id 42
label "Hello, I am a graph"
node [ id 1 label "Node 1" ]
node [ id 2 label "node 2" ]
node [ id 3 label "node 3" ]
node [ id 4 label "node 4" ]
node [ id 5 label "node 5" ]
node [ id 6 label "node 6" ]
edge [ source 1 target 2 ]
edge [ source 1 target 3 ]
edge [ source 1 target 4 ]
edge [ source 1 target 5 ]
edge [ source 1 target 6 ]
edge [ source 2 target 4 ]
edge [ source 5 target 6]
] ocamlgraph-2.0.0/editor/tests/rand_100_300.gml 0000644 0001750 0000144 00000045767 13735627615 017253 0 ustar rt users graph [
node [
id 1
label 0
]
node [
id 2
label 1
]
node [
id 3
label 2
]
node [
id 4
label 3
]
node [
id 5
label 4
]
node [
id 6
label 5
]
node [
id 7
label 6
]
node [
id 8
label 7
]
node [
id 9
label 8
]
node [
id 10
label 9
]
node [
id 11
label 10
]
node [
id 12
label 11
]
node [
id 13
label 12
]
node [
id 14
label 13
]
node [
id 15
label 14
]
node [
id 16
label 15
]
node [
id 17
label 16
]
node [
id 18
label 17
]
node [
id 19
label 18
]
node [
id 20
label 19
]
node [
id 21
label 20
]
node [
id 22
label 21
]
node [
id 23
label 22
]
node [
id 24
label 23
]
node [
id 25
label 24
]
node [
id 26
label 25
]
node [
id 27
label 26
]
node [
id 28
label 27
]
node [
id 29
label 28
]
node [
id 30
label 29
]
node [
id 31
label 30
]
node [
id 32
label 31
]
node [
id 33
label 32
]
node [
id 34
label 33
]
node [
id 35
label 34
]
node [
id 36
label 35
]
node [
id 37
label 36
]
node [
id 38
label 37
]
node [
id 39
label 38
]
node [
id 40
label 39
]
node [
id 41
label 40
]
node [
id 42
label 41
]
node [
id 43
label 42
]
node [
id 44
label 43
]
node [
id 45
label 44
]
node [
id 46
label 45
]
node [
id 47
label 46
]
node [
id 48
label 47
]
node [
id 49
label 48
]
node [
id 50
label 49
]
node [
id 51
label 50
]
node [
id 52
label 51
]
node [
id 53
label 52
]
node [
id 54
label 53
]
node [
id 55
label 54
]
node [
id 56
label 55
]
node [
id 57
label 56
]
node [
id 58
label 57
]
node [
id 59
label 58
]
node [
id 60
label 59
]
node [
id 61
label 60
]
node [
id 62
label 61
]
node [
id 63
label 62
]
node [
id 64
label 63
]
node [
id 65
label 64
]
node [
id 66
label 65
]
node [
id 67
label 66
]
node [
id 68
label 67
]
node [
id 69
label 68
]
node [
id 70
label 69
]
node [
id 71
label 70
]
node [
id 72
label 71
]
node [
id 73
label 72
]
node [
id 74
label 73
]
node [
id 75
label 74
]
node [
id 76
label 75
]
node [
id 77
label 76
]
node [
id 78
label 77
]
node [
id 79
label 78
]
node [
id 80
label 79
]
node [
id 81
label 80
]
node [
id 82
label 81
]
node [
id 83
label 82
]
node [
id 84
label 83
]
node [
id 85
label 84
]
node [
id 86
label 85
]
node [
id 87
label 86
]
node [
id 88
label 87
]
node [
id 89
label 88
]
node [
id 90
label 89
]
node [
id 91
label 90
]
node [
id 92
label 91
]
node [
id 93
label 92
]
node [
id 94
label 93
]
node [
id 95
label 94
]
node [
id 96
label 95
]
node [
id 97
label 96
]
node [
id 98
label 97
]
node [
id 99
label 98
]
node [
id 100
label 99
]
edge [
source 6
target 5
label 0
]
edge [
source 7
target 1
label 0
]
edge [
source 8
target 2
label 0
]
edge [
source 10
target 2
label 0
]
edge [
source 12
target 6
label 0
]
edge [
source 12
target 11
label 0
]
edge [
source 13
target 1
label 0
]
edge [
source 14
target 9
label 0
]
edge [
source 15
target 3
label 0
]
edge [
source 16
target 14
label 0
]
edge [
source 18
target 1
label 0
]
edge [
source 19
target 11
label 0
]
edge [
source 21
target 17
label 0
]
edge [
source 22
target 5
label 0
]
edge [
source 22
target 13
label 0
]
edge [
source 22
target 17
label 0
]
edge [
source 23
target 15
label 0
]
edge [
source 23
target 19
label 0
]
edge [
source 27
target 22
label 0
]
edge [
source 28
target 4
label 0
]
edge [
source 28
target 19
label 0
]
edge [
source 29
target 12
label 0
]
edge [
source 29
target 15
label 0
]
edge [
source 29
target 19
label 0
]
edge [
source 29
target 20
label 0
]
edge [
source 29
target 28
label 0
]
edge [
source 31
target 10
label 0
]
edge [
source 31
target 24
label 0
]
edge [
source 32
target 3
label 0
]
edge [
source 32
target 22
label 0
]
edge [
source 32
target 28
label 0
]
edge [
source 34
target 3
label 0
]
edge [
source 35
target 26
label 0
]
edge [
source 35
target 29
label 0
]
edge [
source 36
target 16
label 0
]
edge [
source 37
target 23
label 0
]
edge [
source 37
target 28
label 0
]
edge [
source 38
target 32
label 0
]
edge [
source 38
target 33
label 0
]
edge [
source 39
target 4
label 0
]
edge [
source 39
target 15
label 0
]
edge [
source 39
target 33
label 0
]
edge [
source 40
target 4
label 0
]
edge [
source 40
target 6
label 0
]
edge [
source 40
target 7
label 0
]
edge [
source 40
target 20
label 0
]
edge [
source 40
target 29
label 0
]
edge [
source 40
target 34
label 0
]
edge [
source 41
target 25
label 0
]
edge [
source 43
target 22
label 0
]
edge [
source 44
target 4
label 0
]
edge [
source 44
target 9
label 0
]
edge [
source 44
target 28
label 0
]
edge [
source 44
target 32
label 0
]
edge [
source 45
target 17
label 0
]
edge [
source 45
target 30
label 0
]
edge [
source 46
target 19
label 0
]
edge [
source 46
target 43
label 0
]
edge [
source 47
target 37
label 0
]
edge [
source 47
target 43
label 0
]
edge [
source 48
target 28
label 0
]
edge [
source 48
target 35
label 0
]
edge [
source 49
target 5
label 0
]
edge [
source 49
target 26
label 0
]
edge [
source 50
target 9
label 0
]
edge [
source 51
target 13
label 0
]
edge [
source 51
target 30
label 0
]
edge [
source 52
target 3
label 0
]
edge [
source 52
target 11
label 0
]
edge [
source 52
target 13
label 0
]
edge [
source 52
target 46
label 0
]
edge [
source 52
target 48
label 0
]
edge [
source 53
target 9
label 0
]
edge [
source 53
target 14
label 0
]
edge [
source 53
target 23
label 0
]
edge [
source 53
target 24
label 0
]
edge [
source 53
target 25
label 0
]
edge [
source 53
target 36
label 0
]
edge [
source 53
target 41
label 0
]
edge [
source 53
target 46
label 0
]
edge [
source 53
target 47
label 0
]
edge [
source 54
target 7
label 0
]
edge [
source 54
target 9
label 0
]
edge [
source 54
target 26
label 0
]
edge [
source 55
target 3
label 0
]
edge [
source 55
target 4
label 0
]
edge [
source 55
target 19
label 0
]
edge [
source 55
target 39
label 0
]
edge [
source 56
target 23
label 0
]
edge [
source 56
target 40
label 0
]
edge [
source 56
target 42
label 0
]
edge [
source 57
target 3
label 0
]
edge [
source 57
target 24
label 0
]
edge [
source 57
target 25
label 0
]
edge [
source 57
target 44
label 0
]
edge [
source 57
target 51
label 0
]
edge [
source 57
target 55
label 0
]
edge [
source 58
target 1
label 0
]
edge [
source 58
target 4
label 0
]
edge [
source 58
target 37
label 0
]
edge [
source 60
target 37
label 0
]
edge [
source 61
target 4
label 0
]
edge [
source 61
target 27
label 0
]
edge [
source 62
target 2
label 0
]
edge [
source 62
target 14
label 0
]
edge [
source 62
target 43
label 0
]
edge [
source 63
target 17
label 0
]
edge [
source 63
target 32
label 0
]
edge [
source 64
target 23
label 0
]
edge [
source 64
target 27
label 0
]
edge [
source 64
target 48
label 0
]
edge [
source 64
target 61
label 0
]
edge [
source 65
target 7
label 0
]
edge [
source 65
target 9
label 0
]
edge [
source 65
target 19
label 0
]
edge [
source 65
target 42
label 0
]
edge [
source 65
target 49
label 0
]
edge [
source 66
target 11
label 0
]
edge [
source 66
target 43
label 0
]
edge [
source 66
target 50
label 0
]
edge [
source 66
target 51
label 0
]
edge [
source 66
target 58
label 0
]
edge [
source 67
target 23
label 0
]
edge [
source 67
target 24
label 0
]
edge [
source 67
target 28
label 0
]
edge [
source 67
target 29
label 0
]
edge [
source 67
target 31
label 0
]
edge [
source 67
target 49
label 0
]
edge [
source 67
target 56
label 0
]
edge [
source 68
target 1
label 0
]
edge [
source 68
target 27
label 0
]
edge [
source 70
target 2
label 0
]
edge [
source 70
target 35
label 0
]
edge [
source 70
target 53
label 0
]
edge [
source 71
target 15
label 0
]
edge [
source 71
target 24
label 0
]
edge [
source 71
target 29
label 0
]
edge [
source 71
target 39
label 0
]
edge [
source 72
target 33
label 0
]
edge [
source 72
target 71
label 0
]
edge [
source 73
target 26
label 0
]
edge [
source 73
target 56
label 0
]
edge [
source 73
target 62
label 0
]
edge [
source 74
target 22
label 0
]
edge [
source 74
target 28
label 0
]
edge [
source 74
target 60
label 0
]
edge [
source 75
target 15
label 0
]
edge [
source 75
target 18
label 0
]
edge [
source 75
target 26
label 0
]
edge [
source 75
target 33
label 0
]
edge [
source 75
target 53
label 0
]
edge [
source 75
target 54
label 0
]
edge [
source 76
target 73
label 0
]
edge [
source 76
target 74
label 0
]
edge [
source 77
target 61
label 0
]
edge [
source 77
target 65
label 0
]
edge [
source 77
target 76
label 0
]
edge [
source 78
target 12
label 0
]
edge [
source 78
target 14
label 0
]
edge [
source 78
target 19
label 0
]
edge [
source 78
target 35
label 0
]
edge [
source 78
target 48
label 0
]
edge [
source 78
target 76
label 0
]
edge [
source 79
target 24
label 0
]
edge [
source 79
target 25
label 0
]
edge [
source 79
target 35
label 0
]
edge [
source 79
target 67
label 0
]
edge [
source 80
target 9
label 0
]
edge [
source 80
target 23
label 0
]
edge [
source 80
target 56
label 0
]
edge [
source 80
target 57
label 0
]
edge [
source 80
target 67
label 0
]
edge [
source 81
target 61
label 0
]
edge [
source 82
target 39
label 0
]
edge [
source 82
target 41
label 0
]
edge [
source 82
target 44
label 0
]
edge [
source 82
target 52
label 0
]
edge [
source 82
target 63
label 0
]
edge [
source 82
target 65
label 0
]
edge [
source 82
target 72
label 0
]
edge [
source 82
target 77
label 0
]
edge [
source 83
target 7
label 0
]
edge [
source 83
target 36
label 0
]
edge [
source 83
target 46
label 0
]
edge [
source 83
target 47
label 0
]
edge [
source 83
target 54
label 0
]
edge [
source 83
target 81
label 0
]
edge [
source 83
target 82
label 0
]
edge [
source 84
target 10
label 0
]
edge [
source 84
target 67
label 0
]
edge [
source 84
target 68
label 0
]
edge [
source 84
target 76
label 0
]
edge [
source 85
target 20
label 0
]
edge [
source 85
target 21
label 0
]
edge [
source 85
target 27
label 0
]
edge [
source 85
target 31
label 0
]
edge [
source 85
target 59
label 0
]
edge [
source 86
target 13
label 0
]
edge [
source 86
target 15
label 0
]
edge [
source 86
target 39
label 0
]
edge [
source 86
target 54
label 0
]
edge [
source 86
target 64
label 0
]
edge [
source 86
target 79
label 0
]
edge [
source 87
target 34
label 0
]
edge [
source 87
target 37
label 0
]
edge [
source 87
target 46
label 0
]
edge [
source 87
target 50
label 0
]
edge [
source 87
target 60
label 0
]
edge [
source 87
target 76
label 0
]
edge [
source 88
target 29
label 0
]
edge [
source 88
target 40
label 0
]
edge [
source 88
target 41
label 0
]
edge [
source 88
target 44
label 0
]
edge [
source 88
target 48
label 0
]
edge [
source 88
target 61
label 0
]
edge [
source 88
target 78
label 0
]
edge [
source 88
target 85
label 0
]
edge [
source 89
target 4
label 0
]
edge [
source 89
target 9
label 0
]
edge [
source 89
target 13
label 0
]
edge [
source 89
target 43
label 0
]
edge [
source 89
target 49
label 0
]
edge [
source 89
target 81
label 0
]
edge [
source 90
target 16
label 0
]
edge [
source 90
target 17
label 0
]
edge [
source 90
target 54
label 0
]
edge [
source 90
target 89
label 0
]
edge [
source 91
target 1
label 0
]
edge [
source 91
target 4
label 0
]
edge [
source 91
target 14
label 0
]
edge [
source 91
target 48
label 0
]
edge [
source 91
target 59
label 0
]
edge [
source 91
target 63
label 0
]
edge [
source 91
target 70
label 0
]
edge [
source 91
target 74
label 0
]
edge [
source 92
target 1
label 0
]
edge [
source 92
target 3
label 0
]
edge [
source 92
target 23
label 0
]
edge [
source 92
target 32
label 0
]
edge [
source 92
target 42
label 0
]
edge [
source 92
target 53
label 0
]
edge [
source 92
target 55
label 0
]
edge [
source 92
target 58
label 0
]
edge [
source 92
target 61
label 0
]
edge [
source 92
target 81
label 0
]
edge [
source 92
target 84
label 0
]
edge [
source 93
target 19
label 0
]
edge [
source 93
target 21
label 0
]
edge [
source 93
target 25
label 0
]
edge [
source 93
target 38
label 0
]
edge [
source 93
target 53
label 0
]
edge [
source 93
target 60
label 0
]
edge [
source 93
target 81
label 0
]
edge [
source 94
target 39
label 0
]
edge [
source 94
target 53
label 0
]
edge [
source 94
target 56
label 0
]
edge [
source 94
target 70
label 0
]
edge [
source 94
target 83
label 0
]
edge [
source 95
target 6
label 0
]
edge [
source 95
target 18
label 0
]
edge [
source 95
target 35
label 0
]
edge [
source 95
target 54
label 0
]
edge [
source 95
target 71
label 0
]
edge [
source 96
target 6
label 0
]
edge [
source 96
target 17
label 0
]
edge [
source 96
target 21
label 0
]
edge [
source 96
target 32
label 0
]
edge [
source 96
target 38
label 0
]
edge [
source 96
target 52
label 0
]
edge [
source 96
target 59
label 0
]
edge [
source 96
target 60
label 0
]
edge [
source 96
target 93
label 0
]
edge [
source 97
target 3
label 0
]
edge [
source 97
target 17
label 0
]
edge [
source 97
target 30
label 0
]
edge [
source 97
target 51
label 0
]
edge [
source 97
target 52
label 0
]
edge [
source 97
target 80
label 0
]
edge [
source 97
target 81
label 0
]
edge [
source 97
target 85
label 0
]
edge [
source 97
target 93
label 0
]
edge [
source 98
target 4
label 0
]
edge [
source 98
target 10
label 0
]
edge [
source 98
target 11
label 0
]
edge [
source 98
target 50
label 0
]
edge [
source 98
target 56
label 0
]
edge [
source 98
target 63
label 0
]
edge [
source 98
target 68
label 0
]
edge [
source 98
target 74
label 0
]
edge [
source 98
target 91
label 0
]
edge [
source 99
target 13
label 0
]
edge [
source 99
target 32
label 0
]
edge [
source 99
target 67
label 0
]
edge [
source 99
target 73
label 0
]
edge [
source 100
target 2
label 0
]
edge [
source 100
target 25
label 0
]
edge [
source 100
target 27
label 0
]
edge [
source 100
target 31
label 0
]
edge [
source 100
target 86
label 0
]
edge [
source 100
target 87
label 0
]
]
ocamlgraph-2.0.0/editor/tests/rand_10_10.gml 0000644 0001750 0000144 00000001541 13735627615 017067 0 ustar rt users graph [
node [
id 1
label 0
]
node [
id 2
label 1
]
node [
id 3
label 2
]
node [
id 4
label 3
]
node [
id 5
label 4
]
node [
id 6
label 5
]
node [
id 7
label 6
]
node [
id 8
label 7
]
node [
id 9
label 8
]
node [
id 10
label 9
]
edge [
source 3
target 1
label 0
]
edge [
source 5
target 2
label 0
]
edge [
source 5
target 3
label 0
]
edge [
source 6
target 3
label 0
]
edge [
source 7
target 3
label 0
]
edge [
source 9
target 5
label 0
]
edge [
source 9
target 6
label 0
]
edge [
source 10
target 6
label 0
]
edge [
source 10
target 7
label 0
]
edge [
source 10
target 9
label 0
]
]
ocamlgraph-2.0.0/editor/tests/fsm.dot 0000644 0001750 0000144 00000001004 13735627615 016131 0 ustar rt users digraph finite_state_machine {
LR_0 -> LR_2 [ label = "SS(B)" ];
LR_0 -> LR_1 [ label = "SS(S)" ];
LR_1 -> LR_3 [ label = "S($end)" ];
LR_2 -> LR_6 [ label = "SS(b)" ];
LR_2 -> LR_5 [ label = "SS(a)" ];
LR_2 -> LR_4 [ label = "S(A)" ];
LR_5 -> LR_7 [ label = "S(b)" ];
LR_5 -> LR_5 [ label = "S(a)" ];
LR_6 -> LR_6 [ label = "S(b)" ];
LR_6 -> LR_5 [ label = "S(a)" ];
LR_7 -> LR_8 [ label = "S(b)" ];
LR_7 -> LR_5 [ label = "S(a)" ];
LR_8 -> LR_6 [ label = "S(b)" ];
LR_8 -> LR_5 [ label = "S(a)" ];
}
ocamlgraph-2.0.0/editor/tests/parcours.dot 0000644 0001750 0000144 00000000417 13735627615 017211 0 ustar rt users digraph g {
r -> U;
r -> D;
r -> T;
U -> Ua;
U -> Ub;
Ua -> Uaa;
Ub -> Ubb;
Ua -> Ubb;
Ub -> Uaa;
D -> Da;
D -> Db;
Da -> Daa;
Db -> Dbb;
Da -> Dbb;
Db -> Daa;
T -> Ta;
T -> Tb;
Ta -> Taa;
Tb -> Tbb;
Ta -> Tbb;
Tb -> Taa;
Ua -> Da;
Db -> Ta;
Tb -> Ub;
} ocamlgraph-2.0.0/editor/tests/transparency.dot 0000644 0001750 0000144 00000003454 13735627615 020070 0 ustar rt users graph G {
graph [splines=true overlap=false]
graph [truecolor bgcolor="#ff00005f"]
node [style=filled fillcolor="#00ff005f"]
1 -- 30 [f=1];
1 -- 40 [f=14];
8 -- 46 [f=1];
8 -- 16 [f=18];
10 -- 25 [f=1];
10 -- 19 [f=5];
10 -- 33 [f=1];
12 -- 8 [f=1];
12 -- 36 [f=5];
12 -- 17 [f=16];
13 -- 38 [f=1];
13 -- 24 [f=19];
24 -- 49 [f=1];
24 -- 13 [f=1];
24 -- 47 [f=12];
24 -- 12 [f=19];
25 -- 27 [f=1];
25 -- 12 [f=1];
27 -- 12 [f=1];
27 -- 14 [f=8];
29 -- 10 [f=1];
29 -- 8 [f=17];
30 -- 24 [f=1];
30 -- 44 [f=15];
38 -- 29 [f=1];
38 -- 35 [f=15];
2 -- 42 [f=2];
2 -- 35 [f=3];
2 -- 11 [f=19];
14 -- 18 [f=2];
14 -- 24 [f=15];
14 -- 38 [f=18];
18 -- 49 [f=2];
18 -- 47 [f=20];
26 -- 41 [f=2];
26 -- 42 [f=15];
31 -- 39 [f=2];
31 -- 47 [f=17];
31 -- 25 [f=14];
37 -- 26 [f=2];
37 -- 16 [f=14];
39 -- 50 [f=2];
39 -- 14 [f=2];
39 -- 18 [f=17];
39 -- 47 [f=10];
41 -- 31 [f=2];
41 -- 8 [f=16];
42 -- 44 [f=2];
42 -- 29 [f=12];
44 -- 37 [f=2];
44 -- 32 [f=15];
3 -- 20 [f=2];
3 -- 28 [f=19];
6 -- 45 [f=2];
6 -- 28 [f=10];
9 -- 6 [f=2];
9 -- 16 [f=1];
15 -- 16 [f=2];
15 -- 48 [f=2];
16 -- 50 [f=2];
16 -- 32 [f=14];
16 -- 39 [f=8];
20 -- 33 [f=2];
33 -- 9 [f=2];
33 -- 46 [f=3];
33 -- 48 [f=17];
45 -- 15 [f=2];
4 -- 17 [f=4];
4 -- 15 [f=6];
4 -- 12 [f=16];
17 -- 21 [f=4];
19 -- 35 [f=4];
19 -- 15 [f=9];
19 -- 43 [f=4];
21 -- 19 [f=4];
21 -- 50 [f=4];
23 -- 36 [f=4];
34 -- 23 [f=4];
34 -- 24 [f=11];
35 -- 34 [f=4];
35 -- 16 [f=6];
35 -- 18 [f=16];
36 -- 46 [f=4];
5 -- 7 [f=1];
5 -- 36 [f=6];
7 -- 32 [f=1];
7 -- 11 [f=2];
7 -- 14 [f=17];
11 -- 40 [f=1];
11 -- 50 [f=1];
22 -- 46 [f=1];
28 -- 43 [f=1];
28 -- 8 [f=18];
32 -- 28 [f=1];
32 -- 39 [f=13];
32 -- 42 [f=15];
40 -- 22 [f=1];
40 -- 47 [f=1];
43 -- 11 [f=1];
43 -- 17 [f=19];
}
ocamlgraph-2.0.0/editor/tests/test2,1_3.gml 0000644 0001750 0000144 00000001147 13735627615 016765 0 ustar rt users graph [
comment "This is a sample graph"
directed 1
id 42
label "Hello, I am a graph"
node [ id 1 label "Node 1" ]
node [ id 2 label "node 2" ]
node [ id 3 label "node 3" ]
node [ id 4 label "node 4" ]
node [ id 5 label "node 5" ]
node [ id 6 label "node 6" ]
node [ id 7 label "node 7" ]
edge [ source 1 target 2 ]
edge [ source 1 target 3 ]
edge [ source 1 target 4 ]
edge [ source 1 target 6 ]
edge [ source 1 target 5 ]
edge [ source 1 target 7 ]
edge [ source 2 target 4 ]
edge [ source 6 target 5 ]
edge [ source 5 target 7 ]
] ocamlgraph-2.0.0/editor/tests/dep_why.dot 0000644 0001750 0000144 00000005023 13735627615 017010 0 ustar rt users digraph G {
size="7.5,10" ;
rankdir = TB ;
"Why" -> "Main" ;
"Theoryreducer" -> "Logic_decl" ;
"Theoryreducer" -> "Pp" ;
"Theoryreducer" -> "Unionfind" ;
"Theory_filtering" -> "Logic_decl" ;
"Theory_filtering" -> "Pp" ;
"Theory_filtering" -> "Unionfind" ;
"Options" -> "Lib" ;
"Options" -> "Version" ;
"Main" -> "Coq" ;
"Main" -> "Dispatcher" ;
"Main" -> "Fastwp" ;
"Main" -> "Gappa" ;
"Main" -> "Hol4" ;
"Main" -> "Holl" ;
"Main" -> "Hypotheses_filtering" ;
"Main" -> "Isabelle" ;
"Main" -> "Mizar" ;
"Main" -> "Monad" ;
"Main" -> "Ocaml" ;
"Main" -> "PredDefExpansor" ;
"Main" -> "Pvs" ;
"Main" -> "Wp" ;
"Hypotheses_filtering" -> "Util" ;
"Encoding_mono" -> "Util" ;
"Zenon" -> "Encoding" ;
"Zenon" -> "Ltyping" ;
"Wp" -> "Typing" ;
"Vcg" -> "Log" ;
"Vcg" -> "Util" ;
"Util" -> "Logic_decl" ;
"Util" -> "Rename" ;
"Typing" -> "Ltyping" ;
"Types" -> "Effect" ;
"Smtlib" -> "Encoding" ;
"Simplify" -> "Encoding" ;
"Report" -> "Lexer" ;
"Report" -> "Misc" ;
"Rename" -> "Pp" ;
"Rename" -> "Report" ;
"Regen" -> "Vcg" ;
"Red" -> "Util" ;
"Pvs" -> "Vcg" ;
"Purify" -> "Env" ;
"Ptree" -> "Loc" ;
"Ptree" -> "Types" ;
"Pretty" -> "Logic_decl" ;
"Pretty" -> "Pp" ;
"PredDefExpansor" -> "Util" ;
"Parser" -> "Error" ;
"Parser" -> "Float_lexer" ;
"Parser" -> "Ptree" ;
"Ocaml" -> "Util" ;
"Monomorph" -> "Vcg" ;
"Monad" -> "Typing" ;
"Mlize" -> "Monad" ;
"Mizar" -> "Regen" ;
"Misc" -> "Ast" ;
"Misc" -> "Option_misc" ;
"Misc" -> "Options" ;
"Ltyping" -> "Util" ;
"Logic" -> "Ident" ;
"Logic_decl" -> "Env" ;
"Lexer" -> "Parser" ;
"Isabelle" -> "Regen" ;
"Holl" -> "Vcg" ;
"Hol4" -> "Vcg" ;
"Harvey" -> "Encoding" ;
"Gappa" -> "Logic_decl" ;
"Gappa" -> "Pp" ;
"Fpi" -> "Misc" ;
"Fpi" -> "Pp" ;
"Fastwp" -> "Util" ;
"Error" -> "Effect" ;
"Env" -> "Report" ;
"Encoding_strat" -> "Util" ;
"Encoding_rec" -> "Logic_decl" ;
"Encoding_pred" -> "Logic_decl" ;
"Encoding" -> "Encoding_mono" ;
"Encoding" -> "Encoding_pred" ;
"Encoding" -> "Encoding_rec" ;
"Encoding" -> "Encoding_strat" ;
"Encoding" -> "Monomorph" ;
"Effect" -> "Logic" ;
"Dispatcher" -> "Cvcl" ;
"Dispatcher" -> "Harvey" ;
"Dispatcher" -> "Pretty" ;
"Dispatcher" -> "Simplify" ;
"Dispatcher" -> "Smtlib" ;
"Dispatcher" -> "Theory_filtering" ;
"Dispatcher" -> "Zenon" ;
"Cvcl" -> "Encoding" ;
"Cvcl" -> "Ltyping" ;
"Coq" -> "Regen" ;
"Cc" -> "Loc" ;
"Cc" -> "Logic" ;
"Ast" -> "Cc" ;
"Ast" -> "Ptree" ;
"Annot" -> "Util" ;
}
ocamlgraph-2.0.0/editor/tests/rand_50_300.gml 0000644 0001750 0000144 00000042243 13735627615 017161 0 ustar rt users graph [
node [
id 1
label 0
]
node [
id 2
label 1
]
node [
id 3
label 2
]
node [
id 4
label 3
]
node [
id 5
label 4
]
node [
id 6
label 5
]
node [
id 7
label 6
]
node [
id 8
label 7
]
node [
id 9
label 8
]
node [
id 10
label 9
]
node [
id 11
label 10
]
node [
id 12
label 11
]
node [
id 13
label 12
]
node [
id 14
label 13
]
node [
id 15
label 14
]
node [
id 16
label 15
]
node [
id 17
label 16
]
node [
id 18
label 17
]
node [
id 19
label 18
]
node [
id 20
label 19
]
node [
id 21
label 20
]
node [
id 22
label 21
]
node [
id 23
label 22
]
node [
id 24
label 23
]
node [
id 25
label 24
]
node [
id 26
label 25
]
node [
id 27
label 26
]
node [
id 28
label 27
]
node [
id 29
label 28
]
node [
id 30
label 29
]
node [
id 31
label 30
]
node [
id 32
label 31
]
node [
id 33
label 32
]
node [
id 34
label 33
]
node [
id 35
label 34
]
node [
id 36
label 35
]
node [
id 37
label 36
]
node [
id 38
label 37
]
node [
id 39
label 38
]
node [
id 40
label 39
]
node [
id 41
label 40
]
node [
id 42
label 41
]
node [
id 43
label 42
]
node [
id 44
label 43
]
node [
id 45
label 44
]
node [
id 46
label 45
]
node [
id 47
label 46
]
node [
id 48
label 47
]
node [
id 49
label 48
]
node [
id 50
label 49
]
edge [
source 8
target 1
label 0
]
edge [
source 8
target 3
label 0
]
edge [
source 8
target 5
label 0
]
edge [
source 9
target 1
label 0
]
edge [
source 9
target 2
label 0
]
edge [
source 9
target 4
label 0
]
edge [
source 10
target 2
label 0
]
edge [
source 12
target 2
label 0
]
edge [
source 12
target 7
label 0
]
edge [
source 13
target 1
label 0
]
edge [
source 13
target 8
label 0
]
edge [
source 13
target 9
label 0
]
edge [
source 14
target 1
label 0
]
edge [
source 14
target 4
label 0
]
edge [
source 14
target 6
label 0
]
edge [
source 14
target 9
label 0
]
edge [
source 15
target 2
label 0
]
edge [
source 15
target 3
label 0
]
edge [
source 15
target 5
label 0
]
edge [
source 15
target 6
label 0
]
edge [
source 15
target 8
label 0
]
edge [
source 15
target 13
label 0
]
edge [
source 16
target 7
label 0
]
edge [
source 16
target 12
label 0
]
edge [
source 16
target 15
label 0
]
edge [
source 17
target 1
label 0
]
edge [
source 17
target 4
label 0
]
edge [
source 17
target 8
label 0
]
edge [
source 17
target 9
label 0
]
edge [
source 17
target 11
label 0
]
edge [
source 17
target 13
label 0
]
edge [
source 17
target 16
label 0
]
edge [
source 18
target 1
label 0
]
edge [
source 18
target 2
label 0
]
edge [
source 18
target 3
label 0
]
edge [
source 18
target 9
label 0
]
edge [
source 18
target 14
label 0
]
edge [
source 18
target 17
label 0
]
edge [
source 19
target 6
label 0
]
edge [
source 19
target 9
label 0
]
edge [
source 19
target 11
label 0
]
edge [
source 19
target 12
label 0
]
edge [
source 20
target 4
label 0
]
edge [
source 20
target 10
label 0
]
edge [
source 20
target 11
label 0
]
edge [
source 20
target 12
label 0
]
edge [
source 21
target 4
label 0
]
edge [
source 21
target 6
label 0
]
edge [
source 21
target 9
label 0
]
edge [
source 21
target 11
label 0
]
edge [
source 21
target 12
label 0
]
edge [
source 22
target 7
label 0
]
edge [
source 22
target 8
label 0
]
edge [
source 22
target 9
label 0
]
edge [
source 22
target 13
label 0
]
edge [
source 23
target 1
label 0
]
edge [
source 23
target 8
label 0
]
edge [
source 23
target 9
label 0
]
edge [
source 23
target 13
label 0
]
edge [
source 23
target 16
label 0
]
edge [
source 23
target 18
label 0
]
edge [
source 23
target 19
label 0
]
edge [
source 23
target 20
label 0
]
edge [
source 23
target 21
label 0
]
edge [
source 24
target 1
label 0
]
edge [
source 24
target 2
label 0
]
edge [
source 24
target 4
label 0
]
edge [
source 24
target 6
label 0
]
edge [
source 24
target 10
label 0
]
edge [
source 24
target 12
label 0
]
edge [
source 24
target 13
label 0
]
edge [
source 24
target 14
label 0
]
edge [
source 24
target 16
label 0
]
edge [
source 24
target 18
label 0
]
edge [
source 25
target 2
label 0
]
edge [
source 25
target 3
label 0
]
edge [
source 25
target 6
label 0
]
edge [
source 25
target 8
label 0
]
edge [
source 25
target 14
label 0
]
edge [
source 25
target 24
label 0
]
edge [
source 26
target 5
label 0
]
edge [
source 26
target 9
label 0
]
edge [
source 26
target 10
label 0
]
edge [
source 26
target 14
label 0
]
edge [
source 26
target 15
label 0
]
edge [
source 26
target 23
label 0
]
edge [
source 27
target 3
label 0
]
edge [
source 27
target 8
label 0
]
edge [
source 27
target 12
label 0
]
edge [
source 27
target 18
label 0
]
edge [
source 27
target 23
label 0
]
edge [
source 28
target 2
label 0
]
edge [
source 28
target 7
label 0
]
edge [
source 28
target 10
label 0
]
edge [
source 28
target 15
label 0
]
edge [
source 28
target 18
label 0
]
edge [
source 28
target 19
label 0
]
edge [
source 28
target 20
label 0
]
edge [
source 28
target 22
label 0
]
edge [
source 28
target 27
label 0
]
edge [
source 29
target 1
label 0
]
edge [
source 29
target 7
label 0
]
edge [
source 29
target 8
label 0
]
edge [
source 29
target 9
label 0
]
edge [
source 29
target 13
label 0
]
edge [
source 29
target 14
label 0
]
edge [
source 29
target 18
label 0
]
edge [
source 29
target 19
label 0
]
edge [
source 29
target 20
label 0
]
edge [
source 30
target 1
label 0
]
edge [
source 30
target 3
label 0
]
edge [
source 30
target 4
label 0
]
edge [
source 30
target 17
label 0
]
edge [
source 30
target 20
label 0
]
edge [
source 30
target 21
label 0
]
edge [
source 30
target 26
label 0
]
edge [
source 31
target 2
label 0
]
edge [
source 31
target 4
label 0
]
edge [
source 31
target 7
label 0
]
edge [
source 31
target 8
label 0
]
edge [
source 31
target 14
label 0
]
edge [
source 31
target 18
label 0
]
edge [
source 31
target 19
label 0
]
edge [
source 31
target 26
label 0
]
edge [
source 31
target 28
label 0
]
edge [
source 32
target 13
label 0
]
edge [
source 32
target 18
label 0
]
edge [
source 32
target 22
label 0
]
edge [
source 32
target 29
label 0
]
edge [
source 33
target 7
label 0
]
edge [
source 33
target 16
label 0
]
edge [
source 33
target 18
label 0
]
edge [
source 33
target 22
label 0
]
edge [
source 33
target 24
label 0
]
edge [
source 33
target 25
label 0
]
edge [
source 33
target 27
label 0
]
edge [
source 34
target 1
label 0
]
edge [
source 34
target 3
label 0
]
edge [
source 34
target 4
label 0
]
edge [
source 34
target 5
label 0
]
edge [
source 34
target 6
label 0
]
edge [
source 34
target 8
label 0
]
edge [
source 34
target 15
label 0
]
edge [
source 34
target 16
label 0
]
edge [
source 34
target 22
label 0
]
edge [
source 34
target 23
label 0
]
edge [
source 34
target 26
label 0
]
edge [
source 35
target 2
label 0
]
edge [
source 35
target 7
label 0
]
edge [
source 35
target 8
label 0
]
edge [
source 35
target 11
label 0
]
edge [
source 35
target 14
label 0
]
edge [
source 35
target 22
label 0
]
edge [
source 35
target 32
label 0
]
edge [
source 36
target 13
label 0
]
edge [
source 36
target 16
label 0
]
edge [
source 36
target 19
label 0
]
edge [
source 36
target 23
label 0
]
edge [
source 37
target 2
label 0
]
edge [
source 37
target 3
label 0
]
edge [
source 37
target 6
label 0
]
edge [
source 37
target 7
label 0
]
edge [
source 37
target 9
label 0
]
edge [
source 37
target 16
label 0
]
edge [
source 37
target 21
label 0
]
edge [
source 37
target 23
label 0
]
edge [
source 37
target 24
label 0
]
edge [
source 37
target 26
label 0
]
edge [
source 37
target 27
label 0
]
edge [
source 37
target 29
label 0
]
edge [
source 37
target 32
label 0
]
edge [
source 37
target 33
label 0
]
edge [
source 37
target 34
label 0
]
edge [
source 38
target 2
label 0
]
edge [
source 38
target 3
label 0
]
edge [
source 38
target 4
label 0
]
edge [
source 38
target 7
label 0
]
edge [
source 38
target 9
label 0
]
edge [
source 38
target 17
label 0
]
edge [
source 38
target 18
label 0
]
edge [
source 38
target 33
label 0
]
edge [
source 38
target 34
label 0
]
edge [
source 38
target 37
label 0
]
edge [
source 39
target 4
label 0
]
edge [
source 39
target 8
label 0
]
edge [
source 39
target 15
label 0
]
edge [
source 39
target 18
label 0
]
edge [
source 39
target 19
label 0
]
edge [
source 39
target 28
label 0
]
edge [
source 39
target 29
label 0
]
edge [
source 39
target 31
label 0
]
edge [
source 40
target 3
label 0
]
edge [
source 40
target 4
label 0
]
edge [
source 40
target 7
label 0
]
edge [
source 40
target 8
label 0
]
edge [
source 40
target 14
label 0
]
edge [
source 40
target 18
label 0
]
edge [
source 40
target 19
label 0
]
edge [
source 40
target 20
label 0
]
edge [
source 40
target 23
label 0
]
edge [
source 40
target 25
label 0
]
edge [
source 40
target 35
label 0
]
edge [
source 41
target 1
label 0
]
edge [
source 41
target 2
label 0
]
edge [
source 41
target 3
label 0
]
edge [
source 41
target 5
label 0
]
edge [
source 41
target 27
label 0
]
edge [
source 41
target 29
label 0
]
edge [
source 41
target 39
label 0
]
edge [
source 42
target 1
label 0
]
edge [
source 42
target 5
label 0
]
edge [
source 42
target 20
label 0
]
edge [
source 42
target 21
label 0
]
edge [
source 42
target 35
label 0
]
edge [
source 42
target 37
label 0
]
edge [
source 43
target 3
label 0
]
edge [
source 43
target 4
label 0
]
edge [
source 43
target 13
label 0
]
edge [
source 43
target 14
label 0
]
edge [
source 43
target 20
label 0
]
edge [
source 43
target 25
label 0
]
edge [
source 43
target 32
label 0
]
edge [
source 43
target 37
label 0
]
edge [
source 43
target 41
label 0
]
edge [
source 44
target 1
label 0
]
edge [
source 44
target 7
label 0
]
edge [
source 44
target 8
label 0
]
edge [
source 44
target 14
label 0
]
edge [
source 44
target 19
label 0
]
edge [
source 44
target 20
label 0
]
edge [
source 44
target 22
label 0
]
edge [
source 44
target 30
label 0
]
edge [
source 44
target 39
label 0
]
edge [
source 44
target 40
label 0
]
edge [
source 45
target 4
label 0
]
edge [
source 45
target 17
label 0
]
edge [
source 45
target 21
label 0
]
edge [
source 45
target 30
label 0
]
edge [
source 45
target 35
label 0
]
edge [
source 45
target 38
label 0
]
edge [
source 46
target 2
label 0
]
edge [
source 46
target 6
label 0
]
edge [
source 46
target 7
label 0
]
edge [
source 46
target 20
label 0
]
edge [
source 46
target 32
label 0
]
edge [
source 46
target 34
label 0
]
edge [
source 46
target 36
label 0
]
edge [
source 46
target 37
label 0
]
edge [
source 46
target 38
label 0
]
edge [
source 46
target 39
label 0
]
edge [
source 47
target 5
label 0
]
edge [
source 47
target 6
label 0
]
edge [
source 47
target 8
label 0
]
edge [
source 47
target 10
label 0
]
edge [
source 47
target 13
label 0
]
edge [
source 47
target 15
label 0
]
edge [
source 47
target 16
label 0
]
edge [
source 47
target 17
label 0
]
edge [
source 47
target 21
label 0
]
edge [
source 47
target 23
label 0
]
edge [
source 47
target 25
label 0
]
edge [
source 47
target 26
label 0
]
edge [
source 47
target 28
label 0
]
edge [
source 47
target 31
label 0
]
edge [
source 47
target 33
label 0
]
edge [
source 47
target 38
label 0
]
edge [
source 47
target 41
label 0
]
edge [
source 47
target 43
label 0
]
edge [
source 47
target 46
label 0
]
edge [
source 48
target 3
label 0
]
edge [
source 48
target 9
label 0
]
edge [
source 48
target 11
label 0
]
edge [
source 48
target 12
label 0
]
edge [
source 48
target 15
label 0
]
edge [
source 48
target 20
label 0
]
edge [
source 48
target 22
label 0
]
edge [
source 48
target 30
label 0
]
edge [
source 48
target 33
label 0
]
edge [
source 48
target 39
label 0
]
edge [
source 48
target 43
label 0
]
edge [
source 48
target 46
label 0
]
edge [
source 48
target 47
label 0
]
edge [
source 49
target 2
label 0
]
edge [
source 49
target 13
label 0
]
edge [
source 49
target 18
label 0
]
edge [
source 49
target 28
label 0
]
edge [
source 49
target 39
label 0
]
edge [
source 49
target 43
label 0
]
edge [
source 49
target 44
label 0
]
edge [
source 49
target 47
label 0
]
edge [
source 50
target 4
label 0
]
edge [
source 50
target 13
label 0
]
edge [
source 50
target 23
label 0
]
edge [
source 50
target 26
label 0
]
edge [
source 50
target 27
label 0
]
edge [
source 50
target 28
label 0
]
edge [
source 50
target 33
label 0
]
edge [
source 50
target 39
label 0
]
edge [
source 50
target 40
label 0
]
edge [
source 50
target 45
label 0
]
]
ocamlgraph-2.0.0/editor/tests/unix.dot 0000644 0001750 0000144 00000002616 13735627615 016341 0 ustar rt users /* courtesy Ian Darwin and Geoff Collyer, Softquad Inc. */
digraph unix {
"5th Edition" -> "6th Edition";
"5th Edition" -> "PWB 1.0";
"6th Edition" -> "LSX";
"6th Edition" -> "1 BSD";
"6th Edition" -> "Mini Unix";
"6th Edition" -> "Wollongong";
"6th Edition" -> "Interdata";
"Interdata" -> "Unix/TS 3.0";
"Interdata" -> "PWB 2.0";
"Interdata" -> "7th Edition";
"7th Edition" -> "8th Edition";
"7th Edition" -> "32V";
"7th Edition" -> "V7M";
"7th Edition" -> "Ultrix-11";
"7th Edition" -> "Xenix";
"7th Edition" -> "UniPlus+";
"V7M" -> "Ultrix-11";
"8th Edition" -> "9th Edition";
"1 BSD" -> "2 BSD";
"2 BSD" -> "2.8 BSD";
"2.8 BSD" -> "Ultrix-11";
"2.8 BSD" -> "2.9 BSD";
"32V" -> "3 BSD";
"3 BSD" -> "4 BSD";
"4 BSD" -> "4.1 BSD";
"4.1 BSD" -> "4.2 BSD";
"4.1 BSD" -> "2.8 BSD";
"4.1 BSD" -> "8th Edition";
"4.2 BSD" -> "4.3 BSD";
"4.2 BSD" -> "Ultrix-32";
"PWB 1.0" -> "PWB 1.2";
"PWB 1.0" -> "USG 1.0";
"PWB 1.2" -> "PWB 2.0";
"USG 1.0" -> "CB Unix 1";
"USG 1.0" -> "USG 2.0";
"CB Unix 1" -> "CB Unix 2";
"CB Unix 2" -> "CB Unix 3";
"CB Unix 3" -> "Unix/TS++";
"CB Unix 3" -> "PDP-11 Sys V";
"USG 2.0" -> "USG 3.0";
"USG 3.0" -> "Unix/TS 3.0";
"PWB 2.0" -> "Unix/TS 3.0";
"Unix/TS 1.0" -> "Unix/TS 3.0";
"Unix/TS 3.0" -> "TS 4.0";
"Unix/TS++" -> "TS 4.0";
"CB Unix 3" -> "TS 4.0";
"TS 4.0" -> "System V.0";
"System V.0" -> "System V.2";
"System V.2" -> "System V.3";
}
ocamlgraph-2.0.0/editor/tests/rand_100_10.gml 0000644 0001750 0000144 00000010032 13735627615 017142 0 ustar rt users graph [
node [
id 1
label 0
]
node [
id 2
label 1
]
node [
id 3
label 2
]
node [
id 4
label 3
]
node [
id 5
label 4
]
node [
id 6
label 5
]
node [
id 7
label 6
]
node [
id 8
label 7
]
node [
id 9
label 8
]
node [
id 10
label 9
]
node [
id 11
label 10
]
node [
id 12
label 11
]
node [
id 13
label 12
]
node [
id 14
label 13
]
node [
id 15
label 14
]
node [
id 16
label 15
]
node [
id 17
label 16
]
node [
id 18
label 17
]
node [
id 19
label 18
]
node [
id 20
label 19
]
node [
id 21
label 20
]
node [
id 22
label 21
]
node [
id 23
label 22
]
node [
id 24
label 23
]
node [
id 25
label 24
]
node [
id 26
label 25
]
node [
id 27
label 26
]
node [
id 28
label 27
]
node [
id 29
label 28
]
node [
id 30
label 29
]
node [
id 31
label 30
]
node [
id 32
label 31
]
node [
id 33
label 32
]
node [
id 34
label 33
]
node [
id 35
label 34
]
node [
id 36
label 35
]
node [
id 37
label 36
]
node [
id 38
label 37
]
node [
id 39
label 38
]
node [
id 40
label 39
]
node [
id 41
label 40
]
node [
id 42
label 41
]
node [
id 43
label 42
]
node [
id 44
label 43
]
node [
id 45
label 44
]
node [
id 46
label 45
]
node [
id 47
label 46
]
node [
id 48
label 47
]
node [
id 49
label 48
]
node [
id 50
label 49
]
node [
id 51
label 50
]
node [
id 52
label 51
]
node [
id 53
label 52
]
node [
id 54
label 53
]
node [
id 55
label 54
]
node [
id 56
label 55
]
node [
id 57
label 56
]
node [
id 58
label 57
]
node [
id 59
label 58
]
node [
id 60
label 59
]
node [
id 61
label 60
]
node [
id 62
label 61
]
node [
id 63
label 62
]
node [
id 64
label 63
]
node [
id 65
label 64
]
node [
id 66
label 65
]
node [
id 67
label 66
]
node [
id 68
label 67
]
node [
id 69
label 68
]
node [
id 70
label 69
]
node [
id 71
label 70
]
node [
id 72
label 71
]
node [
id 73
label 72
]
node [
id 74
label 73
]
node [
id 75
label 74
]
node [
id 76
label 75
]
node [
id 77
label 76
]
node [
id 78
label 77
]
node [
id 79
label 78
]
node [
id 80
label 79
]
node [
id 81
label 80
]
node [
id 82
label 81
]
node [
id 83
label 82
]
node [
id 84
label 83
]
node [
id 85
label 84
]
node [
id 86
label 85
]
node [
id 87
label 86
]
node [
id 88
label 87
]
node [
id 89
label 88
]
node [
id 90
label 89
]
node [
id 91
label 90
]
node [
id 92
label 91
]
node [
id 93
label 92
]
node [
id 94
label 93
]
node [
id 95
label 94
]
node [
id 96
label 95
]
node [
id 97
label 96
]
node [
id 98
label 97
]
node [
id 99
label 98
]
node [
id 100
label 99
]
edge [
source 18
target 1
label 0
]
edge [
source 29
target 15
label 0
]
edge [
source 48
target 35
label 0
]
edge [
source 49
target 26
label 0
]
edge [
source 66
target 58
label 0
]
edge [
source 75
target 33
label 0
]
edge [
source 77
target 61
label 0
]
edge [
source 84
target 76
label 0
]
edge [
source 89
target 13
label 0
]
edge [
source 93
target 21
label 0
]
]
ocamlgraph-2.0.0/editor/tests/test.gml 0000644 0001750 0000144 00000001653 13735627615 016326 0 ustar rt users graph [
comment "This is a sample graph"
directed 1
id 42
label "Hello, I am a graph"
node [ id 1 label "Node 1" ]
node [ id 2 label "node 2" ]
node [ id 3 label "node 3" ]
node [ id 4 label "node 3" ]
node [ id 5 label "node 3" ]
node [ id 6 label "node 3" ]
node [ id 7 label "node 3" ]
node [ id 8 label "node 3" ]
node [ id 9 label "node 3" ]
node [ id 10 label "node 3" ]
node [ id 11 label "node 3" ]
node [ id 12 label "node 3" ]
edge [ source 1 target 2 ]
edge [ source 1 target 4 ]
edge [ source 1 target 5 ]
edge [ source 1 target 6 ]
edge [ source 1 target 7 ]
edge [ source 2 target 7 ]
edge [ source 3 target 7 ]
edge [ source 1 target 8 ]
edge [ source 2 target 3 ]
edge [ source 3 target 1 ]
edge [ source 8 target 9 ]
edge [ source 8 target 10 ]
edge [ source 8 target 11 ]
edge [ source 8 target 12 ]
] ocamlgraph-2.0.0/editor/tests/test2,1_3tot.gml 0000644 0001750 0000144 00000001206 13735627615 017510 0 ustar rt users graph [
comment "This is a sample graph"
directed 1
id 42
label "Hello, I am a graph"
node [ id 1 label "Node 1" ]
node [ id 2 label "node 2" ]
node [ id 3 label "node 3" ]
node [ id 4 label "node 4" ]
node [ id 5 label "node 5" ]
node [ id 6 label "node 6" ]
node [ id 7 label "node 7" ]
edge [ source 1 target 2 ]
edge [ source 1 target 3 ]
edge [ source 1 target 4 ]
edge [ source 1 target 5 ]
edge [ source 1 target 6 ]
edge [ source 1 target 7 ]
edge [ source 2 target 4 ]
edge [ source 5 target 6 ]
edge [ source 6 target 7 ]
edge [ source 5 target 7 ]
] ocamlgraph-2.0.0/editor/tests/divisors12.gml 0000644 0001750 0000144 00000001631 13735627615 017350 0 ustar rt users graph [
node [
id 1
label 1
]
node [
id 2
label 2
]
node [
id 3
label 3
]
node [
id 4
label 4
]
node [
id 5
label 5
]
node [
id 6
label 6
]
node [
id 7
label 7
]
node [
id 8
label 8
]
node [
id 9
label 9
]
node [
id 10
label 10
]
node [
id 11
label 11
]
edge [
source 3
target 1
]
edge [
source 5
target 1
]
edge [
source 5
target 2
]
edge [
source 7
target 1
]
edge [
source 7
target 3
]
edge [
source 8
target 2
]
edge [
source 9
target 1
]
edge [
source 9
target 4
]
edge [
source 11
target 1
]
edge [
source 11
target 2
]
edge [
source 11
target 3
]
edge [
source 11
target 5
]
]
ocamlgraph-2.0.0/editor/tests/full10.gml 0000644 0001750 0000144 00000006141 13735627615 016447 0 ustar rt users graph [
node [
id 1
label 1
]
node [
id 2
label 2
]
node [
id 3
label 3
]
node [
id 4
label 4
]
node [
id 5
label 5
]
node [
id 6
label 6
]
node [
id 7
label 7
]
node [
id 8
label 8
]
node [
id 9
label 9
]
node [
id 10
label 10
]
edge [
source 1
target 1
label 0
]
edge [
source 2
target 1
label 0
]
edge [
source 2
target 2
label 0
]
edge [
source 3
target 1
label 0
]
edge [
source 3
target 2
label 0
]
edge [
source 3
target 3
label 0
]
edge [
source 4
target 1
label 0
]
edge [
source 4
target 2
label 0
]
edge [
source 4
target 3
label 0
]
edge [
source 4
target 4
label 0
]
edge [
source 5
target 1
label 0
]
edge [
source 5
target 2
label 0
]
edge [
source 5
target 3
label 0
]
edge [
source 5
target 4
label 0
]
edge [
source 5
target 5
label 0
]
edge [
source 6
target 1
label 0
]
edge [
source 6
target 2
label 0
]
edge [
source 6
target 3
label 0
]
edge [
source 6
target 4
label 0
]
edge [
source 6
target 5
label 0
]
edge [
source 6
target 6
label 0
]
edge [
source 7
target 1
label 0
]
edge [
source 7
target 2
label 0
]
edge [
source 7
target 3
label 0
]
edge [
source 7
target 4
label 0
]
edge [
source 7
target 5
label 0
]
edge [
source 7
target 6
label 0
]
edge [
source 7
target 7
label 0
]
edge [
source 8
target 1
label 0
]
edge [
source 8
target 2
label 0
]
edge [
source 8
target 3
label 0
]
edge [
source 8
target 4
label 0
]
edge [
source 8
target 5
label 0
]
edge [
source 8
target 6
label 0
]
edge [
source 8
target 7
label 0
]
edge [
source 8
target 8
label 0
]
edge [
source 9
target 1
label 0
]
edge [
source 9
target 2
label 0
]
edge [
source 9
target 3
label 0
]
edge [
source 9
target 4
label 0
]
edge [
source 9
target 5
label 0
]
edge [
source 9
target 6
label 0
]
edge [
source 9
target 7
label 0
]
edge [
source 9
target 8
label 0
]
edge [
source 9
target 9
label 0
]
edge [
source 10
target 1
label 0
]
edge [
source 10
target 2
label 0
]
edge [
source 10
target 3
label 0
]
edge [
source 10
target 4
label 0
]
edge [
source 10
target 5
label 0
]
edge [
source 10
target 6
label 0
]
edge [
source 10
target 7
label 0
]
edge [
source 10
target 8
label 0
]
edge [
source 10
target 9
label 0
]
edge [
source 10
target 10
label 0
]
]
ocamlgraph-2.0.0/editor/tests/full30.gml 0000644 0001750 0000144 00000061537 13735627615 016463 0 ustar rt users graph [
node [
id 1
label 1
]
node [
id 2
label 2
]
node [
id 3
label 3
]
node [
id 4
label 4
]
node [
id 5
label 5
]
node [
id 6
label 6
]
node [
id 7
label 7
]
node [
id 8
label 8
]
node [
id 9
label 9
]
node [
id 10
label 10
]
node [
id 11
label 11
]
node [
id 12
label 12
]
node [
id 13
label 13
]
node [
id 14
label 14
]
node [
id 15
label 15
]
node [
id 16
label 16
]
node [
id 17
label 17
]
node [
id 18
label 18
]
node [
id 19
label 19
]
node [
id 20
label 20
]
node [
id 21
label 21
]
node [
id 22
label 22
]
node [
id 23
label 23
]
node [
id 24
label 24
]
node [
id 25
label 25
]
node [
id 26
label 26
]
node [
id 27
label 27
]
node [
id 28
label 28
]
node [
id 29
label 29
]
node [
id 30
label 30
]
edge [
source 1
target 1
label 0
]
edge [
source 2
target 1
label 0
]
edge [
source 2
target 2
label 0
]
edge [
source 3
target 1
label 0
]
edge [
source 3
target 2
label 0
]
edge [
source 3
target 3
label 0
]
edge [
source 4
target 1
label 0
]
edge [
source 4
target 2
label 0
]
edge [
source 4
target 3
label 0
]
edge [
source 4
target 4
label 0
]
edge [
source 5
target 1
label 0
]
edge [
source 5
target 2
label 0
]
edge [
source 5
target 3
label 0
]
edge [
source 5
target 4
label 0
]
edge [
source 5
target 5
label 0
]
edge [
source 6
target 1
label 0
]
edge [
source 6
target 2
label 0
]
edge [
source 6
target 3
label 0
]
edge [
source 6
target 4
label 0
]
edge [
source 6
target 5
label 0
]
edge [
source 6
target 6
label 0
]
edge [
source 7
target 1
label 0
]
edge [
source 7
target 2
label 0
]
edge [
source 7
target 3
label 0
]
edge [
source 7
target 4
label 0
]
edge [
source 7
target 5
label 0
]
edge [
source 7
target 6
label 0
]
edge [
source 7
target 7
label 0
]
edge [
source 8
target 1
label 0
]
edge [
source 8
target 2
label 0
]
edge [
source 8
target 3
label 0
]
edge [
source 8
target 4
label 0
]
edge [
source 8
target 5
label 0
]
edge [
source 8
target 6
label 0
]
edge [
source 8
target 7
label 0
]
edge [
source 8
target 8
label 0
]
edge [
source 9
target 1
label 0
]
edge [
source 9
target 2
label 0
]
edge [
source 9
target 3
label 0
]
edge [
source 9
target 4
label 0
]
edge [
source 9
target 5
label 0
]
edge [
source 9
target 6
label 0
]
edge [
source 9
target 7
label 0
]
edge [
source 9
target 8
label 0
]
edge [
source 9
target 9
label 0
]
edge [
source 10
target 1
label 0
]
edge [
source 10
target 2
label 0
]
edge [
source 10
target 3
label 0
]
edge [
source 10
target 4
label 0
]
edge [
source 10
target 5
label 0
]
edge [
source 10
target 6
label 0
]
edge [
source 10
target 7
label 0
]
edge [
source 10
target 8
label 0
]
edge [
source 10
target 9
label 0
]
edge [
source 10
target 10
label 0
]
edge [
source 11
target 1
label 0
]
edge [
source 11
target 2
label 0
]
edge [
source 11
target 3
label 0
]
edge [
source 11
target 4
label 0
]
edge [
source 11
target 5
label 0
]
edge [
source 11
target 6
label 0
]
edge [
source 11
target 7
label 0
]
edge [
source 11
target 8
label 0
]
edge [
source 11
target 9
label 0
]
edge [
source 11
target 10
label 0
]
edge [
source 11
target 11
label 0
]
edge [
source 12
target 1
label 0
]
edge [
source 12
target 2
label 0
]
edge [
source 12
target 3
label 0
]
edge [
source 12
target 4
label 0
]
edge [
source 12
target 5
label 0
]
edge [
source 12
target 6
label 0
]
edge [
source 12
target 7
label 0
]
edge [
source 12
target 8
label 0
]
edge [
source 12
target 9
label 0
]
edge [
source 12
target 10
label 0
]
edge [
source 12
target 11
label 0
]
edge [
source 12
target 12
label 0
]
edge [
source 13
target 1
label 0
]
edge [
source 13
target 2
label 0
]
edge [
source 13
target 3
label 0
]
edge [
source 13
target 4
label 0
]
edge [
source 13
target 5
label 0
]
edge [
source 13
target 6
label 0
]
edge [
source 13
target 7
label 0
]
edge [
source 13
target 8
label 0
]
edge [
source 13
target 9
label 0
]
edge [
source 13
target 10
label 0
]
edge [
source 13
target 11
label 0
]
edge [
source 13
target 12
label 0
]
edge [
source 13
target 13
label 0
]
edge [
source 14
target 1
label 0
]
edge [
source 14
target 2
label 0
]
edge [
source 14
target 3
label 0
]
edge [
source 14
target 4
label 0
]
edge [
source 14
target 5
label 0
]
edge [
source 14
target 6
label 0
]
edge [
source 14
target 7
label 0
]
edge [
source 14
target 8
label 0
]
edge [
source 14
target 9
label 0
]
edge [
source 14
target 10
label 0
]
edge [
source 14
target 11
label 0
]
edge [
source 14
target 12
label 0
]
edge [
source 14
target 13
label 0
]
edge [
source 14
target 14
label 0
]
edge [
source 15
target 1
label 0
]
edge [
source 15
target 2
label 0
]
edge [
source 15
target 3
label 0
]
edge [
source 15
target 4
label 0
]
edge [
source 15
target 5
label 0
]
edge [
source 15
target 6
label 0
]
edge [
source 15
target 7
label 0
]
edge [
source 15
target 8
label 0
]
edge [
source 15
target 9
label 0
]
edge [
source 15
target 10
label 0
]
edge [
source 15
target 11
label 0
]
edge [
source 15
target 12
label 0
]
edge [
source 15
target 13
label 0
]
edge [
source 15
target 14
label 0
]
edge [
source 15
target 15
label 0
]
edge [
source 16
target 1
label 0
]
edge [
source 16
target 2
label 0
]
edge [
source 16
target 3
label 0
]
edge [
source 16
target 4
label 0
]
edge [
source 16
target 5
label 0
]
edge [
source 16
target 6
label 0
]
edge [
source 16
target 7
label 0
]
edge [
source 16
target 8
label 0
]
edge [
source 16
target 9
label 0
]
edge [
source 16
target 10
label 0
]
edge [
source 16
target 11
label 0
]
edge [
source 16
target 12
label 0
]
edge [
source 16
target 13
label 0
]
edge [
source 16
target 14
label 0
]
edge [
source 16
target 15
label 0
]
edge [
source 16
target 16
label 0
]
edge [
source 17
target 1
label 0
]
edge [
source 17
target 2
label 0
]
edge [
source 17
target 3
label 0
]
edge [
source 17
target 4
label 0
]
edge [
source 17
target 5
label 0
]
edge [
source 17
target 6
label 0
]
edge [
source 17
target 7
label 0
]
edge [
source 17
target 8
label 0
]
edge [
source 17
target 9
label 0
]
edge [
source 17
target 10
label 0
]
edge [
source 17
target 11
label 0
]
edge [
source 17
target 12
label 0
]
edge [
source 17
target 13
label 0
]
edge [
source 17
target 14
label 0
]
edge [
source 17
target 15
label 0
]
edge [
source 17
target 16
label 0
]
edge [
source 17
target 17
label 0
]
edge [
source 18
target 1
label 0
]
edge [
source 18
target 2
label 0
]
edge [
source 18
target 3
label 0
]
edge [
source 18
target 4
label 0
]
edge [
source 18
target 5
label 0
]
edge [
source 18
target 6
label 0
]
edge [
source 18
target 7
label 0
]
edge [
source 18
target 8
label 0
]
edge [
source 18
target 9
label 0
]
edge [
source 18
target 10
label 0
]
edge [
source 18
target 11
label 0
]
edge [
source 18
target 12
label 0
]
edge [
source 18
target 13
label 0
]
edge [
source 18
target 14
label 0
]
edge [
source 18
target 15
label 0
]
edge [
source 18
target 16
label 0
]
edge [
source 18
target 17
label 0
]
edge [
source 18
target 18
label 0
]
edge [
source 19
target 1
label 0
]
edge [
source 19
target 2
label 0
]
edge [
source 19
target 3
label 0
]
edge [
source 19
target 4
label 0
]
edge [
source 19
target 5
label 0
]
edge [
source 19
target 6
label 0
]
edge [
source 19
target 7
label 0
]
edge [
source 19
target 8
label 0
]
edge [
source 19
target 9
label 0
]
edge [
source 19
target 10
label 0
]
edge [
source 19
target 11
label 0
]
edge [
source 19
target 12
label 0
]
edge [
source 19
target 13
label 0
]
edge [
source 19
target 14
label 0
]
edge [
source 19
target 15
label 0
]
edge [
source 19
target 16
label 0
]
edge [
source 19
target 17
label 0
]
edge [
source 19
target 18
label 0
]
edge [
source 19
target 19
label 0
]
edge [
source 20
target 1
label 0
]
edge [
source 20
target 2
label 0
]
edge [
source 20
target 3
label 0
]
edge [
source 20
target 4
label 0
]
edge [
source 20
target 5
label 0
]
edge [
source 20
target 6
label 0
]
edge [
source 20
target 7
label 0
]
edge [
source 20
target 8
label 0
]
edge [
source 20
target 9
label 0
]
edge [
source 20
target 10
label 0
]
edge [
source 20
target 11
label 0
]
edge [
source 20
target 12
label 0
]
edge [
source 20
target 13
label 0
]
edge [
source 20
target 14
label 0
]
edge [
source 20
target 15
label 0
]
edge [
source 20
target 16
label 0
]
edge [
source 20
target 17
label 0
]
edge [
source 20
target 18
label 0
]
edge [
source 20
target 19
label 0
]
edge [
source 20
target 20
label 0
]
edge [
source 21
target 1
label 0
]
edge [
source 21
target 2
label 0
]
edge [
source 21
target 3
label 0
]
edge [
source 21
target 4
label 0
]
edge [
source 21
target 5
label 0
]
edge [
source 21
target 6
label 0
]
edge [
source 21
target 7
label 0
]
edge [
source 21
target 8
label 0
]
edge [
source 21
target 9
label 0
]
edge [
source 21
target 10
label 0
]
edge [
source 21
target 11
label 0
]
edge [
source 21
target 12
label 0
]
edge [
source 21
target 13
label 0
]
edge [
source 21
target 14
label 0
]
edge [
source 21
target 15
label 0
]
edge [
source 21
target 16
label 0
]
edge [
source 21
target 17
label 0
]
edge [
source 21
target 18
label 0
]
edge [
source 21
target 19
label 0
]
edge [
source 21
target 20
label 0
]
edge [
source 21
target 21
label 0
]
edge [
source 22
target 1
label 0
]
edge [
source 22
target 2
label 0
]
edge [
source 22
target 3
label 0
]
edge [
source 22
target 4
label 0
]
edge [
source 22
target 5
label 0
]
edge [
source 22
target 6
label 0
]
edge [
source 22
target 7
label 0
]
edge [
source 22
target 8
label 0
]
edge [
source 22
target 9
label 0
]
edge [
source 22
target 10
label 0
]
edge [
source 22
target 11
label 0
]
edge [
source 22
target 12
label 0
]
edge [
source 22
target 13
label 0
]
edge [
source 22
target 14
label 0
]
edge [
source 22
target 15
label 0
]
edge [
source 22
target 16
label 0
]
edge [
source 22
target 17
label 0
]
edge [
source 22
target 18
label 0
]
edge [
source 22
target 19
label 0
]
edge [
source 22
target 20
label 0
]
edge [
source 22
target 21
label 0
]
edge [
source 22
target 22
label 0
]
edge [
source 23
target 1
label 0
]
edge [
source 23
target 2
label 0
]
edge [
source 23
target 3
label 0
]
edge [
source 23
target 4
label 0
]
edge [
source 23
target 5
label 0
]
edge [
source 23
target 6
label 0
]
edge [
source 23
target 7
label 0
]
edge [
source 23
target 8
label 0
]
edge [
source 23
target 9
label 0
]
edge [
source 23
target 10
label 0
]
edge [
source 23
target 11
label 0
]
edge [
source 23
target 12
label 0
]
edge [
source 23
target 13
label 0
]
edge [
source 23
target 14
label 0
]
edge [
source 23
target 15
label 0
]
edge [
source 23
target 16
label 0
]
edge [
source 23
target 17
label 0
]
edge [
source 23
target 18
label 0
]
edge [
source 23
target 19
label 0
]
edge [
source 23
target 20
label 0
]
edge [
source 23
target 21
label 0
]
edge [
source 23
target 22
label 0
]
edge [
source 23
target 23
label 0
]
edge [
source 24
target 1
label 0
]
edge [
source 24
target 2
label 0
]
edge [
source 24
target 3
label 0
]
edge [
source 24
target 4
label 0
]
edge [
source 24
target 5
label 0
]
edge [
source 24
target 6
label 0
]
edge [
source 24
target 7
label 0
]
edge [
source 24
target 8
label 0
]
edge [
source 24
target 9
label 0
]
edge [
source 24
target 10
label 0
]
edge [
source 24
target 11
label 0
]
edge [
source 24
target 12
label 0
]
edge [
source 24
target 13
label 0
]
edge [
source 24
target 14
label 0
]
edge [
source 24
target 15
label 0
]
edge [
source 24
target 16
label 0
]
edge [
source 24
target 17
label 0
]
edge [
source 24
target 18
label 0
]
edge [
source 24
target 19
label 0
]
edge [
source 24
target 20
label 0
]
edge [
source 24
target 21
label 0
]
edge [
source 24
target 22
label 0
]
edge [
source 24
target 23
label 0
]
edge [
source 24
target 24
label 0
]
edge [
source 25
target 1
label 0
]
edge [
source 25
target 2
label 0
]
edge [
source 25
target 3
label 0
]
edge [
source 25
target 4
label 0
]
edge [
source 25
target 5
label 0
]
edge [
source 25
target 6
label 0
]
edge [
source 25
target 7
label 0
]
edge [
source 25
target 8
label 0
]
edge [
source 25
target 9
label 0
]
edge [
source 25
target 10
label 0
]
edge [
source 25
target 11
label 0
]
edge [
source 25
target 12
label 0
]
edge [
source 25
target 13
label 0
]
edge [
source 25
target 14
label 0
]
edge [
source 25
target 15
label 0
]
edge [
source 25
target 16
label 0
]
edge [
source 25
target 17
label 0
]
edge [
source 25
target 18
label 0
]
edge [
source 25
target 19
label 0
]
edge [
source 25
target 20
label 0
]
edge [
source 25
target 21
label 0
]
edge [
source 25
target 22
label 0
]
edge [
source 25
target 23
label 0
]
edge [
source 25
target 24
label 0
]
edge [
source 25
target 25
label 0
]
edge [
source 26
target 1
label 0
]
edge [
source 26
target 2
label 0
]
edge [
source 26
target 3
label 0
]
edge [
source 26
target 4
label 0
]
edge [
source 26
target 5
label 0
]
edge [
source 26
target 6
label 0
]
edge [
source 26
target 7
label 0
]
edge [
source 26
target 8
label 0
]
edge [
source 26
target 9
label 0
]
edge [
source 26
target 10
label 0
]
edge [
source 26
target 11
label 0
]
edge [
source 26
target 12
label 0
]
edge [
source 26
target 13
label 0
]
edge [
source 26
target 14
label 0
]
edge [
source 26
target 15
label 0
]
edge [
source 26
target 16
label 0
]
edge [
source 26
target 17
label 0
]
edge [
source 26
target 18
label 0
]
edge [
source 26
target 19
label 0
]
edge [
source 26
target 20
label 0
]
edge [
source 26
target 21
label 0
]
edge [
source 26
target 22
label 0
]
edge [
source 26
target 23
label 0
]
edge [
source 26
target 24
label 0
]
edge [
source 26
target 25
label 0
]
edge [
source 26
target 26
label 0
]
edge [
source 27
target 1
label 0
]
edge [
source 27
target 2
label 0
]
edge [
source 27
target 3
label 0
]
edge [
source 27
target 4
label 0
]
edge [
source 27
target 5
label 0
]
edge [
source 27
target 6
label 0
]
edge [
source 27
target 7
label 0
]
edge [
source 27
target 8
label 0
]
edge [
source 27
target 9
label 0
]
edge [
source 27
target 10
label 0
]
edge [
source 27
target 11
label 0
]
edge [
source 27
target 12
label 0
]
edge [
source 27
target 13
label 0
]
edge [
source 27
target 14
label 0
]
edge [
source 27
target 15
label 0
]
edge [
source 27
target 16
label 0
]
edge [
source 27
target 17
label 0
]
edge [
source 27
target 18
label 0
]
edge [
source 27
target 19
label 0
]
edge [
source 27
target 20
label 0
]
edge [
source 27
target 21
label 0
]
edge [
source 27
target 22
label 0
]
edge [
source 27
target 23
label 0
]
edge [
source 27
target 24
label 0
]
edge [
source 27
target 25
label 0
]
edge [
source 27
target 26
label 0
]
edge [
source 27
target 27
label 0
]
edge [
source 28
target 1
label 0
]
edge [
source 28
target 2
label 0
]
edge [
source 28
target 3
label 0
]
edge [
source 28
target 4
label 0
]
edge [
source 28
target 5
label 0
]
edge [
source 28
target 6
label 0
]
edge [
source 28
target 7
label 0
]
edge [
source 28
target 8
label 0
]
edge [
source 28
target 9
label 0
]
edge [
source 28
target 10
label 0
]
edge [
source 28
target 11
label 0
]
edge [
source 28
target 12
label 0
]
edge [
source 28
target 13
label 0
]
edge [
source 28
target 14
label 0
]
edge [
source 28
target 15
label 0
]
edge [
source 28
target 16
label 0
]
edge [
source 28
target 17
label 0
]
edge [
source 28
target 18
label 0
]
edge [
source 28
target 19
label 0
]
edge [
source 28
target 20
label 0
]
edge [
source 28
target 21
label 0
]
edge [
source 28
target 22
label 0
]
edge [
source 28
target 23
label 0
]
edge [
source 28
target 24
label 0
]
edge [
source 28
target 25
label 0
]
edge [
source 28
target 26
label 0
]
edge [
source 28
target 27
label 0
]
edge [
source 28
target 28
label 0
]
edge [
source 29
target 1
label 0
]
edge [
source 29
target 2
label 0
]
edge [
source 29
target 3
label 0
]
edge [
source 29
target 4
label 0
]
edge [
source 29
target 5
label 0
]
edge [
source 29
target 6
label 0
]
edge [
source 29
target 7
label 0
]
edge [
source 29
target 8
label 0
]
edge [
source 29
target 9
label 0
]
edge [
source 29
target 10
label 0
]
edge [
source 29
target 11
label 0
]
edge [
source 29
target 12
label 0
]
edge [
source 29
target 13
label 0
]
edge [
source 29
target 14
label 0
]
edge [
source 29
target 15
label 0
]
edge [
source 29
target 16
label 0
]
edge [
source 29
target 17
label 0
]
edge [
source 29
target 18
label 0
]
edge [
source 29
target 19
label 0
]
edge [
source 29
target 20
label 0
]
edge [
source 29
target 21
label 0
]
edge [
source 29
target 22
label 0
]
edge [
source 29
target 23
label 0
]
edge [
source 29
target 24
label 0
]
edge [
source 29
target 25
label 0
]
edge [
source 29
target 26
label 0
]
edge [
source 29
target 27
label 0
]
edge [
source 29
target 28
label 0
]
edge [
source 29
target 29
label 0
]
edge [
source 30
target 1
label 0
]
edge [
source 30
target 2
label 0
]
edge [
source 30
target 3
label 0
]
edge [
source 30
target 4
label 0
]
edge [
source 30
target 5
label 0
]
edge [
source 30
target 6
label 0
]
edge [
source 30
target 7
label 0
]
edge [
source 30
target 8
label 0
]
edge [
source 30
target 9
label 0
]
edge [
source 30
target 10
label 0
]
edge [
source 30
target 11
label 0
]
edge [
source 30
target 12
label 0
]
edge [
source 30
target 13
label 0
]
edge [
source 30
target 14
label 0
]
edge [
source 30
target 15
label 0
]
edge [
source 30
target 16
label 0
]
edge [
source 30
target 17
label 0
]
edge [
source 30
target 18
label 0
]
edge [
source 30
target 19
label 0
]
edge [
source 30
target 20
label 0
]
edge [
source 30
target 21
label 0
]
edge [
source 30
target 22
label 0
]
edge [
source 30
target 23
label 0
]
edge [
source 30
target 24
label 0
]
edge [
source 30
target 25
label 0
]
edge [
source 30
target 26
label 0
]
edge [
source 30
target 27
label 0
]
edge [
source 30
target 28
label 0
]
edge [
source 30
target 29
label 0
]
edge [
source 30
target 30
label 0
]
]
ocamlgraph-2.0.0/editor/tests/world.dot 0000644 0001750 0000144 00000001724 13735627615 016504 0 ustar rt users digraph world {
size="7,7";
{rank=same; S8 S24 S1 S35 S30;}
{rank=same; T8 T24 T1 T35 T30;}
{rank=same; 43 37 36 10 2;}
{rank=same; 25 9 38 40 13 17 12 18;}
{rank=same; 26 42 11 3 33 19 39 14 16;}
{rank=same; 4 31 34 21 41 28 20;}
{rank=same; 27 5 22 32 29 15;}
{rank=same; 6 23;}
{rank=same; 7;}
S8 -> 9;
S24 -> 25;
S24 -> 27;
S1 -> 2;
S1 -> 10;
S35 -> 43;
S35 -> 36;
S30 -> 31;
S30 -> 33;
9 -> 42;
9 -> T1;
25 -> T1;
25 -> 26;
27 -> T24;
2 -> {3 ; 16 ; 17 ; T1 ; 18}
10 -> { 11 ; 14 ; T1 ; 13; 12;}
31 -> T1;
31 -> 32;
33 -> T30;
33 -> 34;
42 -> 4;
26 -> 4;
3 -> 4;
16 -> 15;
17 -> 19;
18 -> 29;
11 -> 4;
14 -> 15;
37 -> {39 ; 41 ; 38 ; 40;}
13 -> 19;
12 -> 29;
43 -> 38;
43 -> 40;
36 -> 19;
32 -> 23;
34 -> 29;
39 -> 15;
41 -> 29;
38 -> 4;
40 -> 19;
4 -> 5;
19 -> {21 ; 20 ; 28;}
5 -> {6 ; T35 ; 23;}
21 -> 22;
20 -> 15;
28 -> 29;
6 -> 7;
15 -> T1;
22 -> T35;
22 -> 23;
29 -> T30;
7 -> T8;
23 -> T24;
23 -> T1;
}
ocamlgraph-2.0.0/editor/tests/dep_ed.dot 0000644 0001750 0000144 00000000302 13735627615 016564 0 ustar rt users digraph G {
size="7.5,10" ;
rankdir = TB ;
"Ed_main" -> "Ed_display" ;
"Ed_main" -> "Ed_draw" ;
"Ed_graph" -> "Ed_hyper" ;
"Ed_draw" -> "Ed_graph" ;
"Ed_display" -> "Ed_graph" ;
}
ocamlgraph-2.0.0/editor/ed_icon.xpm 0000644 0001750 0000144 00000140732 13735627615 015634 0 ustar rt users /* XPM */
static char * ed_icon_xpm[] = {
"128 128 1018 2",
" c None",
". c #CDCAC4",
"+ c #B4B1AD",
"@ c #9E9C98",
"# c #94928E",
"$ c #908E8B",
"% c #8E8C89",
"& c #8C8A87",
"* c #8B8986",
"= c #CFCBC6",
"- c #A3A09C",
"; c #8B8987",
"> c #8B8A88",
", c #8D8C8B",
"' c #9A9A9A",
") c #B2B2B2",
"! c #CCCCCC",
"~ c #E4E4E4",
"{ c #F0F0F0",
"] c #F4F4F4",
"^ c #F8F8F8",
"/ c #FAFAFA",
"( c #FCFCFC",
"_ c #D1CDC8",
": c #969390",
"< c #888785",
"[ c #90908F",
"} c #B0AFAF",
"| c #DEDEDE",
"1 c #F9F9F9",
"2 c #C2BFBA",
"3 c #8A8A89",
"4 c #AAAAAA",
"5 c #EBEBEB",
"6 c #D4D1CB",
"7 c #918F8C",
"8 c #8A8988",
"9 c #B8B8B8",
"0 c #F5F5F5",
"a c #B7B4AF",
"b c #848280",
"c c #A3A3A2",
"d c #ECECEC",
"e c #A5A29E",
"f c #848382",
"g c #C2C2C2",
"h c #FBFBFB",
"i c #A7A4A0",
"j c #858483",
"k c #D1D1D1",
"l c #B9B6B1",
"m c #82817F",
"n c #CECECE",
"o c #D7D3CE",
"p c #817F7D",
"q c #B9B9B9",
"r c #9B9995",
"s c #959494",
"t c #F6F6F6",
"u c #D0CCC7",
"v c #7F7E7C",
"w c #D5D5D5",
"x c #989797",
"y c #F7F7F7",
"z c #C5C5C5",
"A c #D2CFCA",
"B c #7E7D7B",
"C c #E8E8E8",
"D c #BDBAB5",
"E c #8C8C8B",
"F c #ABA8A4",
"G c #A0A09F",
"H c #9F9C99",
"I c #9A9794",
"J c #BBBBBB",
"K c #EFEFEF",
"L c #C9C9C9",
"M c #E0E0E0",
"N c #BFBFBF",
"O c #C4C4C4",
"P c #A6A6A6",
"Q c #ADADAD",
"R c #9F9D99",
"S c #BCBCBC",
"T c #DDDDDD",
"U c #D8D8D8",
"V c #ABAAAA",
"W c #A5A5A5",
"X c #A0A1A6",
"Y c #CCCDE4",
"Z c #F3F3F3",
"` c #DCDCDC",
" . c #DBDBDB",
".. c #D6D3D3",
"+. c #BD8383",
"@. c #807F7F",
"#. c #B9B9BA",
"$. c #BEBFD3",
"%. c #A9ABD5",
"&. c #DADAEC",
"*. c #BEBAB6",
"=. c #A0A0A0",
"-. c #E6E6E6",
";. c #D9D9D9",
">. c #D39A9A",
",. c #D8CACA",
"'. c #717171",
"). c #E8E8E9",
"!. c #CACBE4",
"~. c #ABADD5",
"{. c #E4E5F1",
"]. c #D3CFCA",
"^. c #8B8B8A",
"/. c #E2E2E2",
"(. c #F2F2F2",
"_. c #E5E5E5",
":. c #E0B8B8",
"<. c #E6C7C7",
"[. c #C0C0C0",
"}. c #8C8C8C",
"|. c #F9F9FB",
"1. c #BFC1DF",
"2. c #AEB0D7",
"3. c #ECEDF5",
"4. c #BEBEBE",
"5. c #AEAEAE",
"6. c #C1C1C1",
"7. c #DFDFDF",
"8. c #EEDADA",
"9. c #D8A5A5",
"0. c #949494",
"a. c #DADADA",
"b. c #F5F5F9",
"c. c #B7B9DB",
"d. c #B5B6DA",
"e. c #F3F3F8",
"f. c #B7B7B7",
"g. c #7E7E7E",
"h. c #9FA0A9",
"i. c #9D9FC4",
"j. c #B9BBD7",
"k. c #DDDDEB",
"l. c #F5F6F9",
"m. c #E1E1E1",
"n. c #F8F2F2",
"o. c #CF8F8F",
"p. c #FBFAFA",
"q. c #888888",
"r. c #E3E3E3",
"s. c #EFEFF6",
"t. c #B0B2D8",
"u. c #BEC0DF",
"v. c #F8F8FA",
"w. c #A4A19D",
"x. c #B9B0B0",
"y. c #ABA5A5",
"z. c #DADAE4",
"A. c #CCCDE5",
"B. c #B6B8DB",
"C. c #B1B2D8",
"D. c #D6D6EA",
"E. c #F4F4F8",
"F. c #D7D7D7",
"G. c #FCFBFB",
"H. c #D19292",
"I. c #F6EEEE",
"J. c #8F8F8F",
"K. c #D6D6D6",
"L. c #E5E5F1",
"M. c #ABADD6",
"N. c #CBCCE5",
"O. c #979696",
"P. c #C89292",
"Q. c #D5D0D0",
"R. c #8E8E8E",
"S. c #ABABAB",
"T. c #D7D8EA",
"U. c #B8BADC",
"V. c #E8E9F3",
"W. c #DBADAD",
"X. c #EBD2D2",
"Y. c #919191",
"Z. c #D8D9EB",
"`. c #DCDCED",
" + c #F1F1F1",
".+ c #DFDEDE",
"++ c #D39898",
"@+ c #787878",
"#+ c #F6F6F9",
"$+ c #E2E2EF",
"%+ c #C4C5E1",
"&+ c #A3A5CA",
"*+ c #A0A1C8",
"=+ c #ABADD2",
"-+ c #C2C4E1",
";+ c #DFE0EE",
">+ c #E9CFCF",
",+ c #DDB0B0",
"'+ c #E7E7E7",
")+ c #9E9E9E",
"!+ c #FAFAFB",
"~+ c #C7C8E3",
"{+ c #EDEEF5",
"]+ c #9A9894",
"^+ c #F1E2E2",
"/+ c #B3B3B3",
"(+ c #A2A2A2",
"_+ c #EAEAF3",
":+ c #CECFE6",
"<+ c #ABA5CB",
"[+ c #98769C",
"}+ c #D0D1E7",
"|+ c #EEEEF5",
"1+ c #EEEEEE",
"2+ c #E9E9E9",
"3+ c #B4B6DA",
"4+ c #BCBEDE",
"5+ c #D8A6A6",
"6+ c #F6EDED",
"7+ c #878787",
"8+ c #EDEDED",
"9+ c #FBF9F9",
"0+ c #CE8D8D",
"a+ c #F9F5F5",
"b+ c #F7F7FA",
"c+ c #DDDDED",
"d+ c #BDBFDD",
"e+ c #9FA1C6",
"f+ c #6D6E86",
"g+ c #A8AACD",
"h+ c #B5B6D6",
"i+ c #C8C9DB",
"j+ c #F1F1F7",
"k+ c #A9AAD4",
"l+ c #EAEAEA",
"m+ c #D39797",
"n+ c #D2D2D2",
"o+ c #A4A4A4",
"p+ c #D7A1A1",
"q+ c #EFDDDD",
"r+ c #E9E9EF",
"s+ c #C1C2D5",
"t+ c #BCBDDE",
"u+ c #AFB0D6",
"v+ c #A2A3C8",
"w+ c #C0C1DF",
"x+ c #EEEFF6",
"y+ c #FBFBFC",
"z+ c #EFF0F6",
"A+ c #B8B5B1",
"B+ c #F4E8E8",
"C+ c #DBABAB",
"D+ c #909090",
"E+ c #E4C1C1",
"F+ c #E2BDBD",
"G+ c #DADADB",
"H+ c #EAEAF2",
"I+ c #D5D6E9",
"J+ c #B2B4D9",
"K+ c #A7A9C6",
"L+ c #C7C8DA",
"M+ c #D1D2E8",
"N+ c #EBECF4",
"O+ c #B1B3D9",
"P+ c #C4C6E2",
"Q+ c #FAFBFB",
"R+ c #DCAFAF",
"S+ c #F2E4E4",
"T+ c #929292",
"U+ c #F1E1E1",
"V+ c #D59D9D",
"W+ c #A3A3A3",
"X+ c #D8D8DA",
"Y+ c #D0D1E1",
"Z+ c #C1C3E0",
"`+ c #B1B3D8",
" @ c #B4B5DA",
".@ c #C6C7E2",
"+@ c #E1E1EF",
"@@ c #F7F8FA",
"#@ c #DCDDED",
"$@ c #A8AAD4",
"%@ c #D7D7E4",
"&@ c #6B6B6D",
"*@ c #676769",
"=@ c #D3D3D3",
"-@ c #F9F4F4",
";@ c #C7C7C7",
">@ c #E7E7F2",
",@ c #B5B7DA",
"'@ c #4E4F6D",
")@ c #363977",
"!@ c #32356E",
"~@ c #7F7F80",
"{@ c #E2E1E1",
"]@ c #C29E9E",
"^@ c #EFE4E4",
"/@ c #A7A7A7",
"(@ c #E0E0EF",
"_@ c #BFC0DF",
":@ c #ADAFD6",
"<@ c #55485D",
"[@ c #3C3F83",
"}@ c #363876",
"|@ c #757576",
"1@ c #DEB4B4",
"2@ c #F0DFDF",
"3@ c #CBCBCB",
"4@ c #A8A8A8",
"5@ c #DEB2B2",
"6@ c #E4C8C8",
"7@ c #959595",
"8@ c #C7C9E3",
"9@ c #ECE2EA",
"0@ c #EE888A",
"a@ c #7D4879",
"b@ c #303145",
"c@ c #272840",
"d@ c #D4D5D9",
"e@ c #EBD3D3",
"f@ c #DBACAC",
"g@ c #F2F2F7",
"h@ c #D3D4E9",
"i@ c #B7B9DC",
"j@ c #ADAFD3",
"k@ c #AEAFC4",
"l@ c #FBFCFC",
"m@ c #F7B9B9",
"n@ c #E67C82",
"o@ c #8E82B9",
"p@ c #D69F9F",
"q@ c #EDEDF0",
"r@ c #C8C9D8",
"s@ c #BABCDD",
"t@ c #D9D9EB",
"u@ c #FAE7E7",
"v@ c #F38888",
"w@ c #DDA6B3",
"x@ c #A4A6D2",
"y@ c #A0A2D0",
"z@ c #F0F1F6",
"A@ c #848381",
"B@ c #E0B9B9",
"C@ c #FBF8F8",
"D@ c #CF8E8E",
"E@ c #F8F3F3",
"F@ c #CACACA",
"G@ c #F9FAFB",
"H@ c #C3C5E1",
"I@ c #B5B6CD",
"J@ c #E4E3E3",
"K@ c #F6ACAC",
"L@ c #F49292",
"M@ c #CCC3DB",
"N@ c #ECECF4",
"O@ c #F0F0F6",
"P@ c #CC9999",
"Q@ c #D49D9D",
"R@ c #A7A7A8",
"S@ c #E5E6F1",
"T@ c #B3B4D9",
"U@ c #9E9FC6",
"V@ c #E9E9F3",
"W@ c #FADDDD",
"X@ c #DC9393",
"Y@ c #E6BFC0",
"Z@ c #CDCEE6",
"`@ c #D2D3E8",
" # c #AFB0D7",
".# c #B3B5D9",
"+# c #D7D4D4",
"@# c #CFB1B1",
"## c #B5B5B5",
"$# c #C8C8C8",
"%# c #DCB5B5",
" c #CEACAC",
"*# c #C7C7D6",
"=# c #BEC0DD",
"-# c #757690",
";# c #ACADC2",
"># c #BBBCCA",
",# c #D8D8E3",
"'# c #FCF7F7",
")# c #F5A0A0",
"!# c #F49C9C",
"~# c #EFEBF1",
"{# c #9597C2",
"]# c #DBDBE7",
"^# c #B6B7DB",
"/# c #888786",
"(# c #E1BEBE",
"_# c #858585",
":# c #D8A4A4",
"<# c #B4B5CD",
"[# c #EBEBF4",
"}# c #939393",
"|# c #F9D1D1",
"1# c #F28383",
"2# c #F9D9D9",
"3# c #AAACD5",
"4# c #D7D7D8",
"5# c #ABACD2",
"6# c #F9F9FA",
"7# c #C3C4E1",
"8# c #E7E8F2",
"9# c #F1F2F7",
"0# c #A8A5AA",
"a# c #AC768A",
"b# c #B7B8DA",
"c# c #A6A7CD",
"d# c #A4A6CA",
"e# c #C0C2E0",
"f# c #CDCDCD",
"g# c #FBF4F4",
"h# c #F5A8A8",
"i# c #FCFAFA",
"j# c #C8CAE4",
"k# c #BABBDD",
"l# c #B3B5D8",
"m# c #D2D3D5",
"n# c #AFB1D7",
"o# c #E2E3F0",
"p# c #C8C9E3",
"q# c #A6A8CA",
"r# c #ADAFD5",
"s# c #B0B0D5",
"t# c #563B4B",
"u# c #D3D3E4",
"v# c #F7BFBF",
"w# c #F38585",
"x# c #E3BFBF",
"y# c #EAEBF4",
"z# c #B2B4D3",
"A# c #A9ABD1",
"B# c #B8B9DC",
"C# c #CACCE4",
"D# c #F0F0F4",
"E# c #DEDEDF",
"F# c #D6A1A1",
"G# c #CEBBBB",
"H# c #A1A1A1",
"I# c #9D9D9D",
"J# c #FBEAEA",
"K# c #E87E7E",
"L# c #EEB0B0",
"M# c #DEDFEE",
"N# c #E6E7F2",
"O# c #BFC0D1",
"P# c #C1C2E0",
"Q# c #EDEDF5",
"R# c #BBBCDD",
"S# c #D8D8EB",
"T# c #A582A1",
"U# c #B0B0D6",
"V# c #DBDCEC",
"W# c #DFDFE6",
"X# c #E0BABA",
"Y# c #E4C2C2",
"Z# c #C6C6C6",
"`# c #DAD9D9",
" $ c #F0B2B2",
".$ c #F38F8F",
"+$ c #F9EEEE",
"@$ c #A6A8D3",
"#$ c #E9EAF3",
"$$ c #BBBCD0",
"%$ c #E1E2EF",
"&$ c #BABABA",
"*$ c #E7E7EE",
"=$ c #DADBEC",
"-$ c #C2C3E0",
";$ c #B5B7DB",
">$ c #B2B3D9",
",$ c #D3D1E4",
"'$ c #CA979F",
")$ c #DFC8C8",
"!$ c #D2A0A0",
"~$ c #FADEDE",
"{$ c #F08787",
"]$ c #DCCFCF",
"^$ c #CDCDD8",
"/$ c #D9DAEC",
"($ c #D4D5E9",
"_$ c #E3E4F0",
":$ c #9F9F9F",
"<$ c #898AA8",
"[$ c #ADAFD4",
"}$ c #BEBFDE",
"|$ c #D3D3E8",
"1$ c #E2BCBC",
"2$ c #ECD6D6",
"3$ c #D19494",
"4$ c #F49B9B",
"5$ c #FCF6F6",
"6$ c #B9B9CD",
"7$ c #E2E2E4",
"8$ c #C9CAE4",
"9$ c #ACAED6",
"0$ c #A9A9A9",
"a$ c #7A7A7A",
"b$ c #747474",
"c$ c #8A8A8A",
"d$ c #F8CDCD",
"e$ c #F28484",
"f$ c #BDBEDE",
"g$ c #C9CBE4",
"h$ c #DFDFEE",
"i$ c #AFAFAF",
"j$ c #D4BABA",
"k$ c #BDABAB",
"l$ c #D4D4D4",
"m$ c #898989",
"n$ c #DEDCDC",
"o$ c #D0A6A6",
"p$ c #D19393",
"q$ c #F4E9E9",
"r$ c #E1D6D6",
"s$ c #F18C8C",
"t$ c #F6ADAD",
"u$ c #ABADD3",
"v$ c #DADADD",
"w$ c #E7C9C9",
"x$ c #D4B9B9",
"y$ c #8B8B8B",
"z$ c #979797",
"A$ c #DBB3B3",
"B$ c #E2D7D7",
"C$ c #D7A2A2",
"D$ c #EDD8D8",
"E$ c #BDBDBD",
"F$ c #F6B4B4",
"G$ c #E37B7B",
"H$ c #F7E7E7",
"I$ c #A7A9D3",
"J$ c #E8E8F2",
"K$ c #B1B2D6",
"L$ c #D7D7DA",
"M$ c #BABCD4",
"N$ c #EAD0D0",
"O$ c #E4C5C5",
"P$ c #734F4F",
"Q$ c #989898",
"R$ c #F38484",
"S$ c #F8C6C6",
"T$ c #B2B3CE",
"U$ c #AFB0C6",
"V$ c #D6D7EA",
"W$ c #E3C0C0",
"X$ c #F3E6E6",
"Y$ c #DAAAAA",
"Z$ c #ACACAC",
"`$ c #CDB5B5",
" % c #CCB6B6",
".% c #7B7B7B",
"+% c #F49797",
"@% c #F59D9D",
"#% c #A9ABCD",
"$% c #B3B5DA",
"%% c #8D8D8C",
"&% c #C18F8F",
"*% c #E6DCDC",
"=% c #D59C9C",
"-% c #848484",
";% c #DEA4A4",
">% c #F28585",
",% c #FAE4E4",
"'% c #A7A9D4",
")% c #E0E0E1",
"!% c #B0B1C7",
"~% c #AFB1D8",
"{% c #F3E5E5",
"]% c #DEB3B3",
"^% c #D29696",
"/% c #C3BABA",
"(% c #CF9191",
"_% c #F9DFDF",
":% c #8B5050",
"<% c #EEB5B5",
"[% c #E4E4E6",
"}% c #A9ABD0",
"|% c #C7C8E1",
"1% c #E4DFDF",
"2% c #835757",
"3% c #8A8787",
"4% c #9B9B9B",
"5% c #797979",
"6% c #DBD9D9",
"7% c #DFB6B6",
"8% c #D57F7F",
"9% c #A2A1A1",
"0% c #9EA0CA",
"a% c #DEDEEA",
"b% c #D7D8EB",
"c% c #F6ECEC",
"d% c #D49A9A",
"e% c #FAF7F7",
"f% c #FAF8F8",
"g% c #CC8B8B",
"h% c #DED5D5",
"i% c #F3E2E2",
"j% c #E3E3EC",
"k% c #A5A7D3",
"l% c #DEDEE4",
"m% c #DDDEED",
"n% c #F7F0F0",
"o% c #DAA8A8",
"p% c #E6E2E2",
"q% c #CC9494",
"r% c #F5F4F4",
"s% c #EEDFDF",
"t% c #E4BDBD",
"u% c #A05959",
"v% c #D2A5A5",
"w% c #BBBCCD",
"x% c #A0A2C9",
"y% c #BBBDDD",
"z% c #ADAFC6",
"A% c #D4C2C2",
"B% c #C38E8E",
"C% c #D4BDBD",
"D% c #E67F7F",
"E% c #F5ABAB",
"F% c #F9F6F6",
"G% c #D6D6D7",
"H% c #ACADC5",
"I% c #D4D4D8",
"J% c #BCBEDB",
"K% c #D5D5D8",
"L% c #D8A3A3",
"M% c #D29595",
"N% c #E6C8C8",
"O% c #7D7D7D",
"P% c #A6A5A5",
"Q% c #EC9A9A",
"R% c #F29393",
"S% c #DBD0D0",
"T% c #B9BADC",
"U% c #EEDBDB",
"V% c #E3BEBE",
"W% c #FCF9F9",
"X% c #F3ABAB",
"Y% c #C36F6F",
"Z% c #928E8E",
"`% c #CFCFCF",
" & c #DCDCE0",
".& c #B5B6C9",
"+& c #E6E6ED",
"@& c #F9F3F3",
"#& c #E8CDCD",
"$& c #F7C1C1",
"%& c #F8D0D0",
"&& c #8D8D8D",
"*& c #C3C3C3",
"=& c #A1A2BD",
"-& c #BBBCCC",
";& c #D4D5DA",
">& c #A3A4B8",
",& c #D59E9E",
"'& c #D8D4D4",
")& c #D49B9B",
"!& c #F9D3D3",
"~& c #F7BDBD",
"{& c #999999",
"]& c #9C9C9C",
"^& c #B0B0B0",
"/& c #C5C5C6",
"(& c #8081A5",
"_& c #C4C4C5",
":& c #8A8BAA",
"<& c #9B9CB2",
"[& c #B4B4BC",
"}& c #CEA5A5",
"|& c #EDD9D9",
"1& c #DECECE",
"2& c #C98C8C",
"3& c #DDC2C2",
"4& c #F18888",
"5& c #F6ABAB",
"6& c #F1E0E0",
"7& c #D9A6A6",
"8& c #B09D9D",
"9& c #ADADAE",
"0& c #7C7EA1",
"a& c #C2C2C4",
"b& c #B5B5B8",
"c& c #8A8CA8",
"d& c #9C9DB2",
"e& c #B6B6BF",
"f& c #BEB2B2",
"g& c #AC8686",
"h& c #A06969",
"i& c #9D6464",
"j& c #9A8989",
"k& c #F5EAEA",
"l& c #D09090",
"m& c #DCDADA",
"n& c #FAE8E8",
"o& c #F39090",
"p& c #F49F9F",
"q& c #DFD7D7",
"r& c #B1B1B1",
"s& c #C0C1D1",
"t& c #C4C5D6",
"u& c #C4AFC3",
"v& c #CC9DA5",
"w& c #D39999",
"x& c #DCAEAE",
"y& c #EDEAEA",
"z& c #DFB5B5",
"A& c #F8F1F1",
"B& c #CE8C8C",
"C& c #FBF1F1",
"D& c #F49595",
"E& c #F49696",
"F& c #FBEEEE",
"G& c #DBB1B1",
"H& c #C08484",
"I& c #CA9D9D",
"J& c #C0C1D6",
"K& c #C6C8E3",
"L& c #D8D8D9",
"M& c #D6A0A0",
"N& c #B795AB",
"O& c #E4D9E2",
"P& c #F7EFEF",
"Q& c #DED7D7",
"R& c #F59F9F",
"S& c #F38E8E",
"T& c #D6BCBC",
"U& c #C18787",
"V& c #CD9696",
"W& c #D1BFBF",
"X& c #969696",
"Y& c #DCDCE8",
"Z& c #ADAED3",
"`& c #E6E4E4",
" * c #E1CACA",
".* c #DAA9A9",
"+* c #D9A7A7",
"@* c #D69E9E",
"#* c #D09292",
"$* c #F3E7E7",
"%* c #F4A7A7",
"&* c #E47C7C",
"** c #FAE0E0",
"=* c #F5EBEB",
"-* c #868686",
";* c #9D9EC9",
">* c #EAEAEB",
",* c #E1BCBC",
"'* c #C08A95",
")* c #BF8690",
"!* c #CDAAAA",
"~* c #EBECF3",
"{* c #F0DEDE",
"]* c #E4A0A0",
"^* c #F6D3D3",
"/* c #808081",
"(* c #A2A4CF",
"_* c #E3E3E8",
":* c #EDECEC",
"<* c #E8CCCC",
"[* c #DDAFAF",
"}* c #ADACD2",
"|* c #C4C5DC",
"1* c #D0D0D4",
"2* c #CB9696",
"3* c #E4CCCC",
"4* c #F7BABA",
"5* c #F38787",
"6* c #E6BBBB",
"7* c #E5C5C5",
"8* c #ECD4D4",
"9* c #AEB0D6",
"0* c #878893",
"a* c #D9A8A8",
"b* c #C18888",
"c* c #D09C9C",
"d* c #E7CACA",
"e* c #F7F1F1",
"f* c #F7F7F9",
"g* c #ADAEC8",
"h* c #F4F5F8",
"i* c #E5C7C7",
"j* c #F8C4C4",
"k* c #F8C5C5",
"l* c #DDBFBF",
"m* c #C48B8B",
"n* c #E9CDCD",
"o* c #6F6F6F",
"p* c #D2CBDE",
"q* c #916060",
"r* c #B98080",
"s* c #E5C3C3",
"t* c #DFB7B7",
"u* c #F38686",
"v* c #F7BBBB",
"w* c #ECD5D5",
"x* c #CBAEAE",
"y* c #DEDBDB",
"z* c #907F7F",
"A* c #BB828F",
"B* c #BD848F",
"C* c #E3DADA",
"D* c #ADAFD7",
"E* c #D7A3A3",
"F* c #E9C6C6",
"G* c #F6B2B2",
"H* c #E1BBBB",
"I* c #858383",
"J* c #D3BFBF",
"K* c #E0B7B7",
"L* c #CB9191",
"M* c #C59090",
"N* c #956C6C",
"O* c #DCD9E8",
"P* c #B9BBDC",
"Q* c #E1BABA",
"R* c #F9DBDB",
"S* c #F28989",
"T* c #E19595",
"U* c #FBF7F7",
"V* c #D49C9C",
"W* c #E4D3D3",
"X* c #D4B2B2",
"Y* c #985F5F",
"Z* c #CF9898",
"`* c #DAB4B4",
" = c #DDCCCC",
".= c #DEDEE7",
"+= c #808080",
"@= c #BEBFDF",
"#= c #EDD7D7",
"$= c #FAE1E1",
"%= c #F38D8D",
"&= c #F4A1A1",
"*= c #E9CACA",
"== c #C28A8A",
"-= c #D19797",
";= c #ECEBEB",
">= c #DDD4D4",
",= c #C79F9F",
"'= c #ACADB2",
")= c #8C8EB9",
"!= c #838383",
"~= c #EEEFEF",
"{= c #DDB1B1",
"]= c #FAE6E6",
"^= c #E88181",
"/= c #D59595",
"(= c #EEEAEA",
"_= c #F2E3E3",
":= c #E6C6C6",
"<= c #D09797",
"[= c #C68D8D",
"}= c #D0A0A0",
"|= c #D1AEAE",
"1= c #B5B5BA",
"2= c #C5C6D4",
"3= c #C5C7E1",
"4= c #A8AACE",
"5= c #C09191",
"6= c #A95252",
"7= c #CE8080",
"8= c #F08B8B",
"9= c #D75252",
"0= c #D18989",
"a= c #E8CBCB",
"b= c #C18B8B",
"c= c #EAD1D1",
"d= c #E4E5ED",
"e= c #D3D3D5",
"f= c #BDBDCB",
"g= c #D1B9B9",
"h= c #921919",
"i= c #8A1717",
"j= c #AE2121",
"k= c #B33F3F",
"l= c #C67979",
"m= c #DDB2B2",
"n= c #F6F5F5",
"o= c #DBDBDC",
"p= c #B8B9D7",
"q= c #CBACAC",
"r= c #991919",
"s= c #8E1717",
"t= c #AD5A5A",
"u= c #B6B8D8",
"v= c #818181",
"w= c #B4B5D0",
"x= c #CFD0DD",
"y= c #D9D9DF",
"z= c #BDBFDE",
"A= c #BA8585",
"B= c #B47676",
"C= c #C57878",
"D= c #C3C4DF",
"E= c #BDBFD6",
"F= c #858696",
"G= c #D09191",
"H= c #E8CACA",
"I= c #E3C1C1",
"J= c #C69C9C",
"K= c #E2CACA",
"L= c #CFD0E7",
"M= c #C5C6E2",
"N= c #C3C4D0",
"O= c #C6C7E0",
"P= c #F7F5F5",
"Q= c #CFBDBD",
"R= c #EED9D9",
"S= c #FAF6F6",
"T= c #B6B6B6",
"U= c #D29797",
"V= c #E2BEBE",
"W= c #CB9F9F",
"X= c #CEA1A1",
"Y= c #E0E1EF",
"Z= c #D3D3D7",
"`= c #AEB0D5",
" - c #EEECEC",
".- c #EBD4D4",
"+- c #DBCBCB",
"@- c #C0C1E0",
"#- c #D1D2DC",
"$- c #F5ECEC",
"%- c #CDBBBB",
"&- c #D59F9F",
"*- c #CE9595",
"=- c #705151",
"-- c #C4AAAA",
";- c #EFE2E2",
">- c #A9ABD4",
",- c #EFDCDC",
"'- c #F0E7E7",
")- c #C4A7A7",
"!- c #CA9398",
"~- c #90729D",
"{- c #DAAFB1",
"]- c #CB9797",
"^- c #D5D5D9",
"/- c #D4CBCB",
"(- c #B4B4B4",
"_- c #C6AAAA",
":- c #A0A2CD",
"<- c #D6BBBB",
"[- c #C99696",
"}- c #D29898",
"|- c #827070",
"1- c #D0C1C1",
"2- c #D4C0C0",
"3- c #F6F0F0",
"4- c #DDB6B6",
"5- c #EFE0E0",
"6- c #C5A4A4",
"7- c #B2B3D8",
"8- c #E6E6F2",
"9- c #D19FA3",
"0- c #9D7FA4",
"a- c #E7C8C8",
"b- c #D8D9DA",
"c- c #B2B4D8",
"d- c #C39B9B",
"e- c #EDDDDD",
"f- c #EACFCF",
"g- c #CD9595",
"h- c #C4A8A8",
"i- c #D39B9B",
"j- c #F2E5E5",
"k- c #F5F2F2",
"l- c #AAAAAB",
"m- c #A5A5AB",
"n- c #D9A9A9",
"o- c #AF9D9D",
"p- c #E9CECE",
"q- c #D09999",
"r- c #D2BFBF",
"s- c #E1B9B9",
"t- c #C2A7A7",
"u- c #865C5C",
"v- c #C5C7E2",
"w- c #CCCEE5",
"x- c #F5F3F3",
"y- c #B28EA6",
"z- c #A9819D",
"A- c #E3E3F0",
"B- c #F6EDEE",
"C- c #E6D5D5",
"D- c #C19D9D",
"E- c #C9A6A6",
"F- c #AFB0BF",
"G- c #A6A7CA",
"H- c #D0D0D7",
"I- c #CF9090",
"J- c #F3E8E8",
"K- c #6E6E7A",
"L- c #E6C5C5",
"M- c #F2F2F5",
"N- c #D7CFCF",
"O- c #707176",
"P- c #9091BA",
"Q- c #CD8E8E",
"R- c #E8D4D4",
"S- c #C4C5E2",
"T- c #AD8E8E",
"U- c #7D7E8D",
"V- c #E1DFDF",
"W- c #D8ACAC",
"X- c #C58989",
"Y- c #EAD7D7",
"Z- c #727272",
"`- c #E0E0EC",
" ; c #E3E3E5",
".; c #D29A9A",
"+; c #BEB4B4",
"@; c #A1A2B4",
"#; c #D8D1D1",
"$; c #AB9999",
" . + @ # $ % & * * & % $ # @ + . ",
" = - ; > , ' ) ! ~ { ] ^ / ( ( / ^ ] { ~ ! ) ' , > ; - = ",
" _ : < [ } | 1 ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( 1 | } [ < : _ ",
" 2 * 3 4 5 ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( 5 4 3 * 2 ",
" 6 7 8 9 0 ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( 0 9 8 7 6 ",
" a b c d ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( d c b a ",
" e f g h ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( h g f e ",
" i j k ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( k j i ",
" l m n ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( n m l ",
" o p q ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( q p o ",
" r s t ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( t s r ",
" u v w ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( w v u ",
" e x y ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( y x e ",
" b z ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( z b ",
" A B C ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( C B A ",
" D E y ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( y E D ",
" F G ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( G F ",
" H ) ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ) H ",
" I J ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( K L M ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( J I ",
" I N ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( O P Q / ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( N I ",
" R S ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( y C T U V W X Y ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( S R ",
" F ) ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( h Z ~ ` .M K C ..+.@.#.$.%.&.( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ) F ",
" *.=.( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( / Z -.` .` ~ Z h ( y ;.C >.,.'.U M ).!.~.{.( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( =.*. ",
" ].^.( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( y | 1 ( ( ( ( ( ( ( 0 d /.T . .T ~ (.h ( ( ( ( ( _. .^ :.<.[.}.d _.| K |.1.2.3.( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ^.]. ",
" B y ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( 4.5.6.K _.7.` . .` /.5 t h ( ( ( ( ( ( ( ( ( ] U d ( 8.9.y 0.4.y ;.( a.(.( b.c.d.e.( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( y B ",
" b C ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( h f.g.h.i.j.k.l.( ( ( ( ( ( ( ( ( ( ( ( ( ( h m.| / ( n.o.p.~ q.7.0 r.(.h U t ( ( s.t.u.v.( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( C b ",
" w.z ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( x.y.g.w z.A.B.t.C.c.D.E.( ( ( ( ( ( ( ( { F.{ ( ( G.H.I.( a.J._.(./ .( / K.1 ( ( ( L.M.N.( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( z w. ",
" u O.( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( r.P.Q.R.S._.;.] ( ( b.T.U.t.t.B.N.V.h 1 T m.( ( ( ( W.X.( 1 .Y.C K ( ` 1 ( ^ F./ ( ( ( ( Z.%.`.( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( O.u ",
" v y ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( +.+++` a.@+` 1 7.| 1 ( ( ( ( ( #+$+%+&+*+=+-+;+E.( >+,+( ( '+M )+5 d ( +~ ( ( ] ;.h ( ( ( ( !+~+2.{+( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( y v ",
" ]+w ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( / F.^+,+` { /+(+_.( ] a.-.( ( ( ( ( t ;.'+( !+_+:+U.<+[+d.}+|+a.z z 1+2+( ( ;.( ( ( { T ( ( ( ( ( ( E.3+4+|.( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( w ]+ ",
" o s ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ` ] 5+6+` ( a.7+` d ( ( 8+U K ( ( r.` 1 ( ( ( ( ( 9+0+a+b+c+d+e+f+g+h+i+j+( -.K ( ( ( 5 m.( ( ( ( ( ( ( L.k+T.( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( s o ",
" p t ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( l+-.( m+( ` ( m.n+o+ .(.( ( h ~ K.w K ( ( ( ( ( ( ( p+q+( ( ( 2+8+R.!+r+s+t+C.u+v+w+Z.x+h '+-.( ( ( ( ( ( ( y+N.2.z+( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( t p ",
" A+9 ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( t a.( B+C+( ` ( ^ T D+d F.y ( ^ ` /.T M / ( ( ( ( ( E+F+( ( ( ( ./ J.( 0 /.( ( ( G+H+I+u.J+C.K+L+M+N+v.( ( ( ( ( e.O+P+Q+( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( 9 A+ ",
" m h ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( h F.1 ( R+S+( ` ( ( a.l+T+1 F.r.a.y ( ( Z ;.C ( ( ( U+V+( ( ( ( h .C W+( y M ( ( ( Z /.( ( ( ( ( X+Y+Z+3+C.`+ @.@+@@@( #@$@%@&@*@8+( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( h m ",
" i n ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( 7. +( ( m+( ( T h ( l+5 o+L K.=@( ( ( ( ( ( 5 U +-@0+9+( ( ( ( d l+;@z ( 1 7.( ( ( ( a.( ( ( ( ( ( ;.] ( ( ( |.>@A.,@C.C.O+'@)@!@~@( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( n i ",
" f ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( l+_.( ( I.9.( ( | / ( h K.U @+^ 1+7.( ( ( ( ( ( h {@]@^@( ( ( ( ( .h /@~ ( h T ( ( ( ( -.K ( ( ( ( ( / F.^ ( ( ( ( ( b+(@_@:@<@[@}@|@( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( f ",
" e k ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( Z .( ( ( 1@2@( ( | 1 / T 3@0 k 4@( '+-.( ( ( ( ( ( 5@6@` m.h ( ( h .( 7@t ( ( ` ( ( ( ( h .( ( ( ( ( ( ^ F./ 3.8@t.t.,@A.9@0@a@b@c@d@( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( k e ",
" j ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ^ F.h ( ( ( ++G.( ( 7.M ;.t ] /.( T+l+( M 8+( ( ( ( e@f@( ( +U l+( 1+C ( D+( ( ( ` ( ( ( ( ( T ^ ( ( ( g@h@i@j@k@_@{.l@( ( m@n@o@$@2.$@,@( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( j ",
" a 6.( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( h F.y ( ( ( -@p@( h C L 8+( ( ( ;.( 8+Y.( ( .Z ( ( 6+H.h ( ( ( ( 2+;.K.1 ( J.( ( ( ` ( ( ( ( ( q@r@u.t.t.s@t@E.( { T ( ( u@v@w@x@y@Z.}+O+3+z@( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( 6.a ",
" A@h ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( a.Z ( ( ( ( B@8.d U d m.t ( ( ( _. +( (+` ( / F.^ C@D@E@( ( ( ( ( ( / F@` (.7@( ( ( ` G@L.H@t.t.B.I@|+( ( ( ( ( ( ( l+J@K@L@M@B.2.N@3+#+O+O@,@( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( h A@ ",
" 6 (+( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( | 1+( ( ( ( ( P@U '+( ( /.t ( ( ( / .( y 7+( ( ^ F.Q@2@( ( ( ( ( ( ( { -.y f.R@S@%+T@U@T@~+V@( ( ( '+1+( ( ( ( ( ( ( W@X@Y@3+Z@!.`@( #( O+( .#g@( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (+6 ",
" 7 d ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( m.5 ( ( ( ( (.+#@#h ( ( ( r.0 ( ( ( ( ./ ( ##$#( ( %#( ( ( ( ( ( ( b.*#=#T@-#;#>#,#|.` ( ( ( ( ( ( / .( ( ( ( ( '#)#!#~#{#]#S@^#( N@_@( O+( g@ @( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( d 7 ",
" /#( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( r.C ( ( ( ] a./.(#e@( ( ( ( ~ Z ( ( ( ( K -.( h _#/ 8.:#8+M |.3.}+U.C.t.c.<#[#!+}#^ h '+;.K.( ( ( ( ( ( ( ` 1 ( ( ( |#1#2#;+3#e.4#5#6#( 7#8#( O+( ( @9#( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( /# ",
" 2 9 ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( _.-.( ( y .7.1 ( ++h ( ( ( ( -.(.( ( ( ( ( ;.( ( L 0#a#b#O+c#d#e##@E.( ( Z r.( ( J.( ( ( / f#T / ( ( ( ( ( ] /.( g#L@h#i#j#k#h ( l#m#/ ( n#y+( d.6#( s.B.( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( 9 2 ",
" * 0 ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( -._.( y T T ^ ( ( -@p@( ( ( ( ( C { ( ( b.o#p#q#r#C.s#t#u#b.y+( 7.1+( ( ( ( T 1 ( / Y.( ( ( ( ` 0 ;._.h ( ( ( ( a.v#w#u@h i@}+( ( !.M+] a.6#J+( ( s@e.( ( J+e.( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( 0 * ",
" 8 ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( '+~ 1 7.` t ( ( ( ( x#e@( ( b+y#`@z#A#C.`+B#C#L.D#E#( F#G#H#( ( ( ( a.] ( ( ( a.( ( 1+I#( ( ( ( ` ( ( 8+U 1+( ( J#K#L#G.v.:@M#( ( N#d.( ( 8+O#I+( ( P#Q#( ( [#R#( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( 8 ",
" _ 4 ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( C m.M .0 ( ( ( y+j+S#T#U#`+`+^#-+V#W#d ( ( ( ( ( ( a.X#Y#( }#C ( ( ( / F.1 ( Z r.( ( z Z#( ( ( ( ` ( ( ( h _.`# $.$+$` E.@$#$( ( @@@$|.( ( ( $$).( ( A.%$( ( ( 2.6#( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( 4 _ ",
" : l+( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( K &$q Z#;.*$=$-$;$`+`+>$4+,$'$( ( ( ( ( ( 8+l+( ( ( ( ( ( )$!$( ( ] q.( ( ( ( y F.h 7.y ( ( )+1+( ( ( ( ` ( ( ( ( ~${$]$7./ ^$@$E.( ( ( t.[#( ( ( l@n#` Z ( /$($( ( ( _$%+( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( l+: ",
" < ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( k :$)+<$[$}$|$N+b+( ( ( ( 1$2$( ( ( ( ( ( K 2+( ( ( ( ( B+3$a.( ( ( ##Z#( ( ( ( (.` a.( ( ( J.( ( ( ( ( ` h ( '#)#4$5$( ] 6$i.7$( ( ( 8$`@( ( ( ( [#w+/ F.1 S@p#( ( ( ( 9$y+( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( < ",
" [ ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( 7./+0$a$b$c$k M 8+1 ( ( ( m+G.( ( ( ( ( ( +'+( ( ( ( a+0+a+T ^ ( ( h _#y ( ( ( ( -.K.( ( ( J.( ( ( ( ( | / d$e$2#( ( l@P#H@5 3@{ ( S@^#( ( ( ( ( f$|+( t ;.{+w+( ( ( ( g$h$( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( [ ",
" = i$( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( j$k$l$` 6.Y.m$J T .` n$o$/ ( ( ( ( ( ( (.-.( ( ( G.p$q$( ] /.( ( ( U W+( ( ( ( 7.7.l+( +' ( ( ( ( ( r$s$t$G.( ( |.t.T.( ( /.a.a.u$!+( ( ( ( ( 2.( ( ( 1+v$B#( ( ( ( v.t.( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( i$= ",
" - | ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( w$x$_.T +U '+q y$z$U A$B$T .` m.1+1 ( Z ~ ( ( ( C$D$( ( ( a.( ( ( ( T+l+( ( ( a.( T +f#E$( ( ( G.F$G$H$( ( ( j+I$J$( ( ( 1 ` K$L$M / ( ( ( E.B.( ( ( ( ~ M$( ( ( ( ( O+v.( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( | - ",
" * 1 ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( N$O$` 2+_.( -.a.t K 5.P$Q$ .h ( t 2+| .K.=@1+1 :.Y#( ( ( ( _. +( ( ( +y$( ( Z r.( h U I#'+( ( W@R$S$/.0 ( ( {.$@E.( ( ( ( ( T$($( (.U 2+( ( :+#@( ( ( ( ( U$] ( ( ( ( ($V$( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( 1 * ",
" > ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( D$W$ .h m.8+( 1 T m.X$Y$K Z$c$P 0 ( ( ( 0 | 2+`$ % .7.1+/ ( 1 T ( ( ( ( 5.n ( | ^ ( ( 1 .%1 5$+%@%'#( r.] ( h@.#!+( ( ( ( ( _$#%l+( ( ( l+U +C.!+( ( ( ( ( n#K.h ( ( ( b+$%( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( > ",
" %%( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( 2@B@8+2+( a.0 ( ( (.&%*%( ( ( | R.}# .( 0 /.q+=%( ( ^ l+T . .F@5 y ( ( h -%1 a.( ( ( ( c$;%>%,%( ( ( _.Z Z+H@( ( ( ( ( ( b.'%h a.( ( ( ( h )%!%y ( ( ( ( ( O+0 a.( ( ( ( ~%( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( %% ",
" ' ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( {%]%( a.( h F.1 ( G.^%-.a.t ( ( ( +S.y$Q$/%(%p.( ( ( ( ( ( ( 5 ;.M . .| E$:$~ ( ( ( _%:%<%.+( ( ( ( [%}%D.( ( ( ( ( ( y+:@s.( | ^ ( ( ( ( h$|%` /.h ( ( ( >$( l+_.( ( ( 4+s.( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ' ",
". ) ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( q$R+( | ^ ( t U h X.W$( 1 T m.h ( ( ( ( 1%2%3%4%~ ( ( ( ( ( ( h a.( ( ( 1 K 5%n .6%7%8%9%( C -.( ( E.0%a%( ( ( ( ( ( ( 7#b%( ( (.r.( ( ( ( c.e.( +U l+( ( >$( ( M K ( ( %$N.( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ) . ",
"+ ! ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( c%f@( Z r.( ( { | d%e%( ( ( +U d ( ( f%g%h%( d (+y$W+2+( ( ( ( | y ( ( ( h 3@J.F$v@i%f.Q . .;@/.j%k%l%K ( ( ( ( ( ( m%f$( ( ( ( a.( ( ( ( 2.( ( ( ( 2+U (.O+( ( h U ^ ( v. @( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ! + ",
"@ ~ ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( n%o%( ( a.( ( ( p%q%( ( ( ( ( ( -.a.r%^%s%M ( ( ( ( ~ I#y$S y ( t M ( ( ( 1+t%u%v%( ( W+2+( ( 1 w%x%G+k =@7.'+Z / ( j+3#y+( ( ( ( m.] ( ( s.y%( ( ( ( ( / M z%y ( ( ^ U h ( t.( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ~ @ ",
"# { ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( n.5+( ( r.Z ( ( 1@A%K ( ( ( ( ( ( ^ B%C%y 7.( ( ( ( ( ( / L R.7@M a.( ( u@D%E%F%_#h ( 0.^ ( ( N.R#G%1 5 8+^ { _.| a.H%I%_.{ 1 ( ( y 7.( ( u.N@( ( ( ( ( ( ( J%K%r.h ( { 7.( J+!+( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( { # ",
"$ ] ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( a+L%( ( ^ | ( ( M%( ;.t ( ( ( ( ( ,+N% +K.;.( ( ( ( ( ( ( ( ( { W O%P%Q%R%S%( ( g J ( D+( ( t+A.( y F.5 d ( ( ( ( T%+@h Z C | ` .` F@l+] 2.( ( ( ( ( ( ( ( f$j+{ U 5 ( _.5 N.%$( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ] $ ",
"% ^ ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( e%p+( ( ( a.( U%7%( / F./ ( ( ( V%B@( ( ^ n a.t ( ( ( ( ( ( ( ( W%X%Y%Z%_#q 1 ( ( 7+T J.!+J+t@( ( ( +`%5 ( ( ( }+8$( ( ( ( ( ( ( h r.r. &.& . .| ~ 1+y ( ( e#Q#( ( '+;.Z .+&_@( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ^ % ",
"& / ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( 9+p@( ( ( C 8+V+@&( ( 0 ;.( ( #&Y$( ( ( 1 7.1 ` /.h ( ( ( ( G.$&w#%& ./ F.N &&7@;.*#9 =&o#( ( ( ( ( r.| ( ( J$J+( ( ( ( ( ( ( ( ( 1 T N.;+( ( / ] 2+m.` .-&;&'+(.1 / M .! >&m.( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( / & ",
"* ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( p.,&( ( ( h '&)&( ( ( ( 1+M D$,&( ( ( ( 1 | ( ( +U d ( ( !&w#~&G.( 8+_.T ( ( +Q {&5.]&^&Z#Z#Z#Z#Z#Z#J =.N /&(&_&Z#Z#Z#Z#Z#Z#Z#Z#Z#Z#Z$:&Z#Z#Z#Z#Z#Z#Z#Z#Z#<&[&J ^&0$P P /@I#W+5./ ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( * ",
"* ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( h V+( ( ( ( }&|&( ( ( ( ( 1&2&G.( ( ( ( / | ( ( ( ( -.3&4&5&G.( ( ( h $#] ( ( 6&7&8&/+c$i$Z#Z#Z#Z#Z#Z#J 9 9&0&a&Z#Z#Z#Z#Z#Z#Z#Z#Z#Z#Z#b&c&Z#Z#Z#Z#Z#Z#Z#Z#Z#d&e&Z#Z#f&g&h&i&j&4%i$/ ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( * ",
"& / ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( h V+( ( ( ( 2&-.( ( ( ( k&l&m&{ ( ( ( ( / | ( ( ( n&o&p&q&M / ( ( ( ( L s%:#m+]%6+[.r&r&&&;@( ( ( ( ( 1+l+R#s&^ ( ( ( ( ( ( ( ( ( ( ( }+t&( ( ( ( ( ( ( ( a+u&v&w&d%x&8.y&F.L q m.( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( / & ",
"% ^ ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( p.,&( ( ( U%z&a.( ( ( A&B&a+h U y ( ( ( 1 | ( C&D&E&F&( ( (.U l+( -@G&H&I&I.( ( / -%7.R.h W 5.( ( ( ( 8+J&K&y U h ( ( ( ( ( ( ( ( ( ( t.L&( ( ( G.I.W$=%w&M&N&O&( ( h | /.-.2+` ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ^ % ",
"$ ] ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( 9+p@( ( ( ++f%7.t ( F%0+P&( ( 1 K./ ( ( 1 Q&R&S&n&( ( ( ( ( G.T&U&V&W&1 a.( ( ( r&3@( J.( ( N X&/ ( ( Y&Z&( ( (.` ( ( ( ( ( ( ( ( ( |.C.`& *.*)&)&+*2$9+( ( %+#$( { F.Z t . +-.( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ] $ ",
"# { ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( e%p+( ( n.@*( 0 m.9+#*$*( ( ( ( ] a.( '#%*&***( ( ( ( ( =*Y$^%Y#F%T 3@1 r.(.( (.c$( ( X&t ( ( K.-*Z 9#;*>*( ( ( l+~ ( ( ( ( ( h X$,*'*)*Q@!*6+h ( ( ( ( ( ( P#~*7.m.h ( ;.1 ~ Z ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( { # ",
"@ ~ ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( -@:#( ( ,+6&( ( ;.w&{*( ( ( ( ( ( y&]*v@^*7.( ( ( F%V%^%9.$*( ( ( C -.a.r.T ( 0.C ( ( 0$r.( ( ( C /*(*_*d ( ( ( ( m.:*n.<*9.d%)&[*8.}*!+( a.( ( ( ( ( ( ( ( |*1*(.( ( _.d ( ` h ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ~ @ ",
"+ ! ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( A&7&( G.M%( ( ( 2*3*( ( ( ( ( ( 4*5*6*2+^ 7.p.7*++V+8*G.( ( ( ( ( a.h ( d F@`%=.( ( ( `%S ( ( ( ( 9*0**&8+( e%X.a*)&b*c*d*e*( ( ( f*J+( ( -.{ ( ( ( ( ( h 7.g*h*( ( t .( ( .( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ! + ",
". ) ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( I.Y$( >+E+( ( f@i*` ( ( ( G.j*w#k*( ( m&l*m*w&n*p.( ( ( ( ( ( ( t 7.( ( ( C o*F.y ( ( 1+I#( ( ( _@p*<*q*r*)&p@s*I.G./ K.1 ( ( ( ( g$(@( ( / ` ( ( ( ( +F. +$%!+( ( U / ( ( ` ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ) . ",
" ' ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( k&x&( ++f%( t*x#( .h ( d$u*v*i#G.w*)&)&x*y*( ( ( ( ( ( ( ( ( ( | y ( ( ( q Z$y ` m./ a+z*1$F#A*B*+*w$C*P%(+h ( ( ( ( y U h ( ( ( D*( ( ( ( .h ( h M M h ( O+( ( ~ 8+( ( ^ 7.( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ' ",
" %%( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( {%5@6+E*( Y#]%( ( l+F*u*G*i#f%7%M%H*e%( 0 L / ( ( ( ( ( ( ( ( h a.( ( ( 0 I*J*K*V+L*m*M*N*U%O*c.( ( ( '+{ F@}.^ ( ( ( ( { | ( ( z+P*( ( ( ( _. + +F. +( ( ( O+( ] T ( ( ( d 5 ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( %% ",
" > ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( q+Q*9.=*n*.*( ( R*S*T*U*<*V*w&8.( ( ( ( t a.a.( ( ( ( ( ( ( F%W*X*+*V+)&Y*Z*`* =p.( ( l+g..=9$y+( ( ( -.(.( m.+=d ( ( ( ( C -.( @=[#( ( ( ( y 3@M h ( ( ( ( O+( F./ ( ( ( 7.^ ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( > ",
" * 1 ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( w*W$m+#=p@G.$=%=&=*===-=<.e%( ( ( ( ( ( 0 /.;=>=#=Q*+*V*)&)&p+,=8*n%9+/.{&( h a.( ( ( ( '=)=X+y ( ( ( _.Z ( ( +!=;.( ( ( ( M ~=:@( ( ( ( { F.l$( ( ( ( ( ( O+m.{ ( ( ( ( .( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( 1 * ",
" - | ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( <*3${=^%]=.$^=/=w&Y#(=_.( ( h e%_=:=f@)&<=[=,&}=|=q+n%( ( ( t M ( ( ( 7+0 ( ( T ^ ( ( v.{#1=y ` m./ ( r.] ( ( ( 1 0.[.( ( ( ( 2=3=( ( h | m.h r.Z ( ( ( ( ( 4=7.( ( ( ( h ` ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( | - ",
" = i$( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( h 5=6=7=8=9=0=5@e*{%a=R+b=V*)&=%M&1@c==*( ] ~ ( ( | { ( ( ( ( 7.t ( ( g q ( ( ( Z r.( y+%.d=X&( ( (.;.'+/.t ( ( ( ( ( Q o+( ( ( `+e=/ 1+U Z ( ( y 7.( ( ( ( / f=h ( ( ( ( { '+( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( i$= ",
" [ ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( g=h=i=j=k=l=d%)&,&m=<*B+y*n=( ( ( ( ( ( ( Z _.( ( h U y ( ( h a.( ( t _#h ( ( ( ( a.y+O+_$( J.( ( ( ( d L 5 ( ( ( ( ( ( L }.t v.t.(.;@r.h ( ( ( ( a.( ( ( ( o=p=( ( ( ( ( | ^ ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( [ ",
" < ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( q=r=s=t=#*B@$*p.( ( ( ( 0 M ( ( ( ( ( ( ( (.-.( ( ( 1 K./ ( 2+d ( ( :$` ( ( ( ( ( M u=Z.( ( J.( ( ( ( ( 7./.a.0 ( ( ( ( ( m.v=w=x=;.C M ( ( ( ( ( M 0 ( ( 5 y=z=( ( ( ( ( a.( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( < ",
" : l+( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( n=A=B=C=V+2$x&)&d%5+w*p.( a.( ( ( ( ( ( ( { C ( ( ( ( ] a.( a.( ( -.7@( ( ( ( ( ( D=E=( ( ( W -.( ( ( ( T / 1 | T 1 ( ( ( ( 8+F=z ( ( _.2+( ( ( ( t M ( ^ ;.8#.@( ( ( ( K '+( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( l+: ",
" _ 4 ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( d%c=G=H=( ( n%I=V*w&J=K==*( ( ( ( ( 1+l+( ( ( ( ( 1+;.m.( h -*0 ( ( ( ( ( L=M=a.( ( ( n E$( ( ( ( ` ( ( ( t a.r.h h /.N=O=}#O ( ( T +( ( ( ( a.h U ^ =$h@( ( ( ( a.h ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( 4 _ ",
" 8 ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( e%D@F%,*++P&( ( ( ( P=Q=Y$d%d%x&R=S=d 5 ( ( ( ( ( ( w ~ ( ;@T=( ( ( ( ( Z.y%( r.(.( ( Z Q$( ( ( ( ` ( ( ( ( ( { k n { O+#+h P ^&( h U y ( ( ( 7.T 1+( A.%$( ( ( ] M ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( 8 ",
" * 0 ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( U+,&( 6+U=V=( ( ( ( .h ( ( $*1$p@W=X=Y#n%G.( ( / .7.d _#h ( ( ( ( Y=T@( ( ^ | ( ( h D+( ( ( ( ` ( ( ( ( t a._.l+Z=`=( ( ( &${&h ^ F.h ( ( '+K.( ( w+|+( ( ( a./ ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( 0 * ",
" 2 9 ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( W$x#( ( N%#*B+( ( 2+d ( ( ( ( ( C -.-5+)&)&Y$+-y&( ]&z ( ( ( ( N#D*h ( ( ( a.( ( ( J.( ( ( ( ` ( ( / M ` 1 ( ( @-#-a.0 ( ( w -%{ ] .( y ;.a.( ( T%h*( ( { r.( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( 9 2 ",
" /#( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( V+^+( ( -@,&{=p./ .( ( ( ( ( -. +( ( ( h $-%-&-*-=---;-e%( 3.>-|.( ( ( ( -.{ ( ( 7@t ( ( ( ` ( '+;.Z ( ( ( ( 9$( 1 | | ^ ( d !=;.5 /.F.1 | 1 ( .#!+( ( U h ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( /# ",
" 7 d ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( 9+0+F%( ( ( w*o.,-` / ( ( ( ( ~ Z ( ( ( ( +~ ( =.m&'-)-,&!-~-{-8.S=( ( ( / ` ( ( r&a.( ( ( l$U d ( ( ( ( ( V$M+( ( ( 0 ./.h ^ X&q n ~ ( K '+( O+( ( -.d ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( d 7 ",
" 6 (+( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( X$w&( ( ( ( 9+Y$]--.( ( ( ( r.0 ( ( ( ( ./ 8+D+( ( (.^-@$E._=1$M&)&V*C$Y#/-h ( ` ^&( (.;.`%( ( ( ( ( ( ( 9$y+( ( ( ( ( +U C ( (-4%U ] h .( O+( 1 ;.( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (+6 ",
" A@h ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( w$7%( ( ( ( ( S+_-<*( ( ( /.t ( ( ( 1 ` ( Y.d ( ( v.:-y=( ( ( ( ( G.-@8*<-[-)&}-|-1-2-3-` ( ( ( ( ( ( V._@( ( ( ( ( ( ( ( 5 k ;.a.v=L 1 ` h O+( .y ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( h A@ ",
" a 6.( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( a*#=( ( ( ( ( T 4-++6+( m.y ( ( ( /.Z T =.( ( |.%.N@~ 2+( ( ( ( ( ( ( / ` t .I#5-1$5+6-)&)&9.F+R=n%7-E.( ( ( ( ( ( ( ( K | ~ a.-.O%&$5 l+O+8+_.( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( 6.a ",
" j ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( G.G=6+( ( ( ( ] m.P&>.7%M ^ ( ( h a.( -*0 ( y+2.8-( ( T { ( ( ( ( ( ( y L T ^ D+( ( ( ` ( ( A&8.V=9-0-)&)&V*Y$a-{%h ( (.a.( ( 1 7.;._###b-c-U ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( j ",
" e k ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( E@0+f%( ( ( ( a.( ( c=d-e-( ( 8+C q 6.( ( T@Y=( ( ( ( U 0 ( ( ( y T T C l+( {&Z ( ( ` ( ( ( ( ( _@V.( ( G.6+f-m==%g-h-i-E*{=#&j-k-a..%l-m- .( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( k e ",
" f ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( U+d%G.( ( ( /.Z ( ( T n-p+-@a. +q.h ( T%/$( ( ( ( ( / F.1 t T T y ( h .( Q 7.( ( ` ( ( ( ( h 9$( ( ( ( ( ( ( t F./ G.-@X$H=5@M&)&o-}#!=J ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( f ",
" i n ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( p-f@( ( ( y | ( ( T h $*q-r-Y.2+( 1.h@( ( ( ( ( ( ( { Z#T y ( ( ( ( .h n E$( h T ( ( ( ( L=Z.( ( ( ( ( ( y K.1 ( ( ( ( 1 C . .9 S.^&L ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( n i ",
" m h ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( s-V%( ( ( a.( ( ` ( ( 7.t-u-,-v-w-( ( ( ( ( ( 0 .| 1+` ( ( ( ( ( K '+1+I#( 1 7.( ( ( ( 9$y+( ( ( ( ( y K.1 ( ( { 7.a.T 1+( -./.M 7.( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( h m ",
" A+9 ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( C+a=( ( '+1+( ` ( h ;.7+x-y-z-6+( ( ( ( ] .7.1 ( ( 5 /.( ( ( ( ( a.( J.( y m.( ( ( A-%+( ( ( ( ( y K.(.~ . .'+^ ( ( ( /.-.( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( 9 A+ ",
" p t ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( G.M=( / ` ( ` ( '+##&$`@w+B-V+C+e%Z a.M 1 ( ( ( ( ( ~ 2+( ( ( ( T 1 J.( 0 r.( ( ( n#v.( ( ( ^ '+L U /.Z ( ( ( ( ( h | l+( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( t p ",
" o s ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( p.^%2@( .h ` ( ;.-%T.P*( ( ( C-D-E-1 ( ( ( ( ( ( ( ( | K ( ( ( +_.o+'+Z _.( ( s.c.t -.` .;.f#1 ( ( ( ( ( ( ( h ;.K ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( s o ",
" ]+w ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( p.#*S+8+2+` (.Q$F-3+( ( K a.r./ c=G=:=G.( ( ( ( ( ( h ;.0 ( ( ( a.`%S { ~ 8+M G-H-M +h 0 F./ ( ( ( ( ( ( ( y F.] ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( w ]+ ",
" v y ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( e%I-J-a.` K.K- #!+8+;._./ ( ( ( G.L-#*c=( ( ( ( ( ( / K.y y 8+`%k -*n+K.l+M-n#( ( ( ] F./ ( ( ( ( ( ( ( K U 1 ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( y v ",
" u O.( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( a+0+N-k O-P-l+U '+h ( ( ( ( ( ( ( p.Q*Q-R-2+m.` ` .U ;@M l+d /.D+2+1+( S-A-( ( Z U / ( ( ( ( ( ( ( m.M h ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( O.u ",
" w.z ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( -@T-^&U-G%'+t +d _.M | ` ` .` ` ` V-W-X-Y-( ( ( ( (. .( ( a.J.-.(.( M.( ( +;.h ( ( ( ( ( ( (.F.K ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( z w. ",
" b C ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( h T=Z-S.=@T /.-.d (.y 1 h ( ( ( ( ( ( ( e%R+m+6&( ( ( d /.( M J.T 0 ($`@( K .h ( ( ( ( ( ] .m.h ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( C b ",
" B y ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( $#r&F@/.a.| (.( ( ( ( ( ( ( ( ( ( ( ( ( ( a+f@U=X$( ( _.2+0 H#/+y M.( 8+T ( ( ( ( ( K a.M ^ ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( y B ",
" ].^.( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( y ( ( ( ^ r.a.T 1+( ( ( ( ( ( ( ( ( ( ( ( ( a++*w&X$( | K L !=`-7#l+7.( ( ( t m.a.-.h ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ^.]. ",
" *.=.( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( / 2+ . .'+^ ( ( ( ( ( ( ( ( ( ( ( E@7&)&X$;.a.'.r# ;m.( y r.a.7.0 ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( =.*. ",
" F ) ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( h K 7. .` '+0 h ( ( ( ( ( ( ( ( e*5+.;+;T+@;| r.a.7.(.( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ) F ",
" R S ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( h { /.T ` ` ` ` ` ` T T T T #;$;}#4@` Z ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( S R ",
" I N ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( h h h h h h h $#S.(-h ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( N I ",
" I J ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ^ K.1+( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( J I ",
" H ) ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ) H ",
" F G ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( G F ",
" D E y ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( y E D ",
" A B C ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( C B A ",
" b z ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( z b ",
" e x y ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( y x e ",
" u v w ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( w v u ",
" r s t ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( t s r ",
" o p q ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( q p o ",
" l m n ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( n m l ",
" i j k ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( k j i ",
" e f g h ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( h g f e ",
" a b c d ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( d c b a ",
" 6 7 8 9 0 ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( 0 9 8 7 6 ",
" 2 * 3 4 5 ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( 5 4 3 * 2 ",
" _ : < [ } | 1 ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( 1 | } [ < : _ ",
" = - ; > , ' ) ! ~ { ] ^ / ( ( / ^ ] { ~ ! ) ' , > ; - = ",
" . + @ # $ % & * * & % $ # @ + . "};
ocamlgraph-2.0.0/editor/htree.ml 0000644 0001750 0000144 00000022004 13735627615 015136 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(*** Signatures ***)
module type TREE = sig
type t
type label
val children : t -> t list
val label : t -> label
end ;;
module type HTREE = sig
type t
type label
val children : t -> t list
val label : t -> label
type coord = float * float
type driver = {
rlimit : float ;
moveto : coord -> unit ;
lineto : coord -> unit ;
curveto : coord -> coord -> coord -> unit ;
draw_label : label -> coord -> float -> unit ;
init_edge_pass : unit -> unit ;
init_label_pass : unit -> unit ;
finalize : unit -> unit ;
}
val shrink_factor : coord -> float
val drag_origin : coord -> coord -> coord -> coord
val draw_linear_tree : driver -> t -> coord -> float -> unit
val draw_curved_tree : driver -> t -> coord -> float -> unit
end ;;
(*** Complex operators ***)
let ( ~-& ) (x, y) = (-.x, -.y) ;;
let ( ~& ) (x, y) = (x, -.y) ;;
let ( +& ) (x1, y1) (x2, y2) =
(x1 +. x2, y1 +. y2) ;;
let ( -& ) (x1, y1) (x2, y2) =
(x1 +. x2, y1 +. y2) ;;
let ( *& ) (x1, y1) (x2, y2) =
(x1*.x2 -. y1*.y2, x1*.y2 +. y1*.x2) ;;
let ( /& ) (x1, y1) (x2, y2) =
let n2 = x2*.x2 +. y2*.y2 in
((x1*.x2 +. y1*.y2)/.n2, (-.x1*.y2 +. y1*.x2)/.n2) ;;
let ( *.& ) f (x, y) =
(f*.x, f*.y) ;;
let norm_sqr (x, y) =
x*.x +. y*.y ;;
let norm (x, y) =
sqrt(x*.x +. y*.y) ;;
let normalize (x, y) =
let n = sqrt(x*.x +. y*.y) in
(x/.n, y/.n) ;;
let expi t =
(cos t, sin t) ;;
(*** Hyperbolic functions ***)
let th t =
let ept = exp t
and emt = exp (-.t) in
(ept -. emt)/.(ept +. emt) ;;
let ath x =
0.5*.log((1.0 +. x)/.(1.0 -. x)) ;;
let pi = 3.14159265358979323846 ;;
let pi_over_2 = pi/.2.0 ;;
let pi_over_4 = pi/.4.0 ;;
let one = (1.0, 0.0) ;;
let translate a z =
(a +& z)/&(one +& (~&a) *& z) ;;
let gamma a u t =
let utht = th t *.& u in
(a +& utht) /& (one +& (~&a) *& utht) ;;
let delta a u t =
let atht = th t *.& a
and utht = th t *.& u in
normalize ((u +& atht) /& (one +& (~&a) *& utht)) ;;
(*** The hyperbolic turtle ***)
type coord = float * float ;;
type turtle = {
pos : coord ; (* with |pos| < 1 *)
dir : coord (* with |dir| = 1 *)
} ;;
let make_turtle pos angle =
{ pos = pos ;
dir = expi angle } ;;
let advance turt step =
{ pos = gamma turt.pos turt.dir step ;
dir = delta turt.pos turt.dir step } ;;
let turn turtle u =
{ pos = turtle.pos ;
dir = turtle.dir *& u } ;;
let turn_left turtle angle =
turn turtle (expi angle) ;;
let turn_right turtle angle =
turn turtle (expi (-.angle)) ;;
(*** Tree-independent functions ***)
let shrink_factor (x, y) =
1.0 -. (x*.x +. y*.y)
(* solving a Cramer system *)
let cramer a1 a2 b1 b2 c1 c2 =
let cdet = a1*.b2 -. a2*.b1
and xdet = c1*.b2 -. c2*.b1
and ydet = a1*.c2 -. a2*.c1 in
(xdet/.cdet, ydet/.cdet) ;;
let drag_origin (x0, y0) (x1, y1) (x2, y2) =
let (x1, y1) = translate (-.x0, -.y0) (x1, y1) in
let x3 = x1*.x2 -. y1*.y2 in
let y3 = x1*.y2 +. y1*.x2 in
cramer (1.0 -. x3) (-.y3) (-.y3) (1.0 +. x3) (x2 -. x1) (y2 -. y1)
(* [step_from n] computes the best `distance' for solving the
dictator's problem in the complex hyperbolic plane for [n]
dictators. In a half-plane, we have to use the distance
given by [step_from (2*n)] or, better, the distance given
by [step_from (2*max(3 n))]. *)
let step_from n =
ath (tan (pi_over_4 -. pi/.float(2*n)))
(* [hspace_dist_sqr turtle] computes the square of the distance
between the origin and the half-space in front of [turtle]. *)
let hspace_dist_sqr turtle =
let (ax, ay) = turtle.pos
and (dx, dy) = turtle.dir in
if ax*.dx +. ay*.dy < 0.0 then 0.0 else
begin
let ux = dy and uy = -.dx in
let alpha = ax*.ax +. ay*.ay
and beta = 2.0*.(ax*.ux +. ay*.uy) in
if beta = 0.0 then
alpha
else
begin
let gamma = (1.0 +. alpha)/.beta in
let delta = gamma*.gamma -. 1.0 in
let sol =
if beta > 0.0
then -.gamma +. sqrt(delta)
else -.gamma -. sqrt(delta) in
let (zx, zy) = translate (ax, ay) (ux*.sol, uy*.sol) in
zx*.zx +. zy*.zy
end
end ;;
(*** The functor ***)
module Make(T : TREE) = struct
type t = T.t
type label = T.label
let children = T.children
let label = T.label
type coord = float * float
type driver = {
rlimit : float ;
moveto : coord -> unit ;
lineto : coord -> unit ;
curveto : coord -> coord -> coord -> unit ;
draw_label : label -> coord -> float -> unit ;
init_edge_pass : unit -> unit ;
init_label_pass : unit -> unit ;
finalize : unit -> unit ;
}
let shrink_factor = shrink_factor
let drag_origin = drag_origin
let draw_linear_edges drv tree turtle =
let rlimit_sqr = drv.rlimit*.drv.rlimit in
let rec do_tree tur t =
if hspace_dist_sqr tur <= rlimit_sqr then
begin
let list = children t in
let num = List.length list in
if num > 0 then
begin
let step = step_from (2*(max 3 num))
and angle = pi/.float(num) in
let tur' = turn_left tur (angle/.2.0 -. pi_over_2) in
do_list tur' step (expi angle) list
end
end
and do_list tur step u = function
| [] -> ()
| t :: rest ->
drv.moveto tur.pos ;
let tur' = advance tur step in
drv.lineto tur'.pos ;
do_tree tur' t ;
do_list (turn tur u) step u rest in
do_tree turtle tree
let draw_curved_edges drv tree turtle =
let rlimit_sqr = drv.rlimit*.drv.rlimit in
let rec do_tree tur t =
if hspace_dist_sqr tur <= rlimit_sqr then
begin
let list = children t in
let num = List.length list in
if num > 0 then
begin
let step = step_from (2*(max 3 num))
and angle = pi/.float(num) in
let tur' = turn_left tur (angle/.2.0 -. pi_over_2) in
do_list tur' step (expi angle) list
end
end
and do_list tur step u = function
| [] -> ()
| t :: rest ->
drv.moveto tur.pos ;
let tur' = advance tur step in
let (a0x, a0y) = tur.pos
and (u0x, u0y) = tur.dir
and (a3x, a3y) = tur'.pos
and (u3x, u3y) = tur'.dir in
let dx = a3x -. a0x
and dy = a3y -. a0y in
let k = sqrt(dx*.dx +. dy*.dy)/.3.0 in
let a1 = (a0x +. k*.u0x, a0y +. k*.u0y)
and a2 = (a3x -. k*.u3x, a3y -. k*.u3y) in
drv.moveto tur.pos ;
drv.curveto a1 a2 tur'.pos ;
do_tree tur' t ;
do_list (turn tur u) step u rest in
do_tree turtle tree
let draw_labels drv tree turtle =
let rlimit_sqr = drv.rlimit*.drv.rlimit in
let rec do_tree tur t =
if hspace_dist_sqr tur <= rlimit_sqr then
begin
drv.draw_label (label t) tur.pos (shrink_factor tur.pos) ;
let list = children t in
let num = List.length list in
if num > 0 then
begin
let step = step_from (2*(max 3 num))
and angle = pi/.float(num) in
let tur' = turn_left tur (angle/.2.0 -. pi_over_2) in
do_list tur' step (expi angle) list
end
end
and do_list tur step u = function
| [] -> ()
| t :: rest ->
let tur' = advance tur step in
do_tree tur' t ;
do_list (turn tur u) step u rest in
do_tree turtle tree
let draw_linear_tree drv tree start angle =
let turt = make_turtle start angle in
drv.init_edge_pass () ;
draw_linear_edges drv tree turt ;
drv.init_label_pass () ;
draw_labels drv tree turt ;
drv.finalize ()
let draw_curved_tree drv tree start angle =
let turt = make_turtle start angle in
drv.init_edge_pass () ;
draw_curved_edges drv tree turt ;
drv.init_label_pass () ;
draw_labels drv tree turt ;
drv.finalize ()
end
ocamlgraph-2.0.0/editor/dune 0000644 0001750 0000144 00000002401 13735627615 014352 0 ustar rt users (executable
(name ed_main)
(modules ed_main ed_display ed_graph ed_hyper ed_draw)
(libraries graph lablgtk2 lablgtk2.gnomecanvas))
(executable
(name editor)
(modules editor gtree htree)
(libraries graph lablgtk2 lablgtk2.gnomecanvas)
(flags -w -32))
(executable
(name graphEdGTK)
(modules graphEdGTK outils_tort outils_math)
(libraries graph lablgtk2 lablgtk2.gnomecanvas)
(flags -w -32))
;; FIXME: graphEd cannot be built because tmoveto / tlineto don't exist (anymore ?)
; (executable
; (name graphEd)
; (modules graphEd outils_math outils_tort)
; (libraries graph lablgtk2 lablgtk2.gnomecanvas))
;; This was commented in the old makefile that was here before :
; # tortuegpoint: tortue.ml
; # ocamlopt outils_math.ml
; # ocamlopt -o $@ graphics.cmxa outils_math.cmx $^
; # graphEd.opt : outils_math.ml outils_tort.ml graphEd.ml
; # ocamlopt -o $@ graphics.cmxa -I .. ../graph.cmxa $^
; # graphEdGTK : outils_math.ml outils_tort.ml graphEdGTK.ml
; # ocamlopt.opt -o $@ -I +lablgtk2 lablgtk.cmxa lablgnomecanvas.cmxa unix.cmxa -I .. ../graph.cmxa $^
; # graphEdGTK.byte : outils_math.ml outils_tort.ml graphEdGTK.ml
; # ocamlc.opt -g -o $@ -I +lablgtk2 lablgtk.cma lablgnomecanvas.cma unix.cma -I .. ../graph.cma $^
; # editor.opt:
; # make -C ..
ocamlgraph-2.0.0/editor/ed_hyper.ml 0000644 0001750 0000144 00000013176 13735627615 015640 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(* This code is from Alexandre Miquel's Htree
(http://www.pps.jussieu.fr/~miquel/soft.html) *)
(*** Complex numbers *)
let ( ~-& ) (x, y) = (-.x, -.y)
let ( ~& ) (x, y) = (x, -.y)
let ( +& ) (x1, y1) (x2, y2) =
(x1 +. x2, y1 +. y2)
let ( -& ) (x1, y1) (x2, y2) =
(x1 +. x2, y1 +. y2)
let ( *& ) (x1, y1) (x2, y2) =
(x1*.x2 -. y1*.y2, x1*.y2 +. y1*.x2)
let ( /& ) (x1, y1) (x2, y2) =
let n2 = x2*.x2 +. y2*.y2 in
((x1*.x2 +. y1*.y2)/.n2, (-.x1*.y2 +. y1*.x2)/.n2)
let ( *.& ) f (x, y) =
(f*.x, f*.y)
let norm_sqr (x, y) =
x*.x +. y*.y
let norm (x, y) =
sqrt(x*.x +. y*.y)
let normalize (x, y) =
let n = sqrt(x*.x +. y*.y) in
(x/.n, y/.n)
let expi t =
(cos t, sin t)
(*** Hyperbolic geometry ***)
let th t =
let ept = exp t
and emt = exp (-.t) in
(ept -. emt)/.(ept +. emt)
let ath x =
0.5*.log((1.0 +. x)/.(1.0 -. x))
let pi = 3.14159265358979323846
let pi_over_2 = pi/.2.0
let pi_over_4 = pi/.4.0
let one = (1.0, 0.0)
let translate a z =
(a +& z)/&(one +& (~&a) *& z)
let gamma a u t =
let utht = th t *.& u in
(a +& utht) /& (one +& (~&a) *& utht)
let delta a u t =
let atht = th t *.& a
and utht = th t *.& u in
(u +& atht) /& (one +& (~&a) *& utht)
(* solving a Cramer system *)
let cramer a1 a2 b1 b2 c1 c2 =
let cdet = a1*.b2 -. a2*.b1
and xdet = c1*.b2 -. c2*.b1
and ydet = a1*.c2 -. a2*.c1 in
(xdet/.cdet, ydet/.cdet) ;;
let drag_origin (x0, y0) (x1, y1) (x2, y2) =
let (x1, y1) = translate (-.x0, -.y0) (x1, y1) in
let x3 = x1*.x2 -. y1*.y2 in
let y3 = x1*.y2 +. y1*.x2 in
cramer (1.0 -. x3) (-.y3) (-.y3) (1.0 +. x3) (x2 -. x1) (y2 -. y1)
let shrink_factor (x, y) =
1.0 -. (x*.x +. y*.y)
(*** Hyperbolic turtle ***)
type coord = float * float
type turtle =
{
pos : coord ; (* with |pos| < 1 *)
dir : coord (* with |dir| = 1 *)
}
let make_turtle pos angle =
{
pos = pos ;
dir = expi angle
}
let make_turtle_dir pos dir =
{
pos = pos ;
dir = dir
}
let dist tdep tdest =
let a = tdep.pos in
let b = tdest.pos in
ath (norm ( (a -& b) /& (one -& (~&a) *& b)))
let dir_to tdep tdest t =
let a = tdep.pos in
let d = tdest.pos in
((d -& a) /& (th t *.&( one -& (~&a) *& d)))
(* return a turtle for a distance from original *)
let advance turtle step =
{ pos = gamma turtle.pos turtle.dir step ;
dir = delta turtle.pos turtle.dir step }
(* return a turtle for a distance d from original with steps *)
let advance_many turtle d steps =
let d = d /. (float steps) in
let rec adv t = function
| 0 -> t
| n -> adv (advance t d) (n-1)
in
adv turtle steps
(* return a list of turtle along distance d from original turtle with steps *)
let list_advance_many turtle d steps =
let d = d /. (float steps) in
let rec adv t = function
| 0 -> []
| n -> t :: adv (advance t d) (n-1)
in
adv turtle steps
let turn turtle u =
{ turtle with dir = turtle.dir *& u }
let turn_left turtle angle =
turn turtle (expi angle) (*** a comprendre pourquoi je dois inverser + et - de l'angle ***)
let turn_right turtle angle =
turn turtle (expi (-.angle)) (*** a comprendre pourquoi je dois inverser + et - de l'angle ***)
let dummy_turtle = { pos = (0., 0.); dir = (0., 0.) }
(* [step_from n] computes the best `distance' for solving the
dictator's problem in the complex hyperbolic plane for [n]
dictators. In a half-plane, we have to use the distance
given by [step_from (2*n)] or, better, the distance given
by [step_from (2*max(3 n))]. *)
let step_from n =
ath (tan (pi_over_4 -. pi/.float(2*n)))
(* [hspace_dist_sqr turtle] computes the square of the distance
between the origin and the half-space in front of [turtle]. *)
let hspace_dist_sqr turtle =
let (ax, ay) = turtle.pos
and (dx, dy) = turtle.dir in
if ax*.dx +. ay*.dy < 0.0
then begin
0.0
end else begin
let ux = dy and uy = -.dx in
let alpha = ax*.ax +. ay*.ay
and beta = 2.0*.(ax*.ux +. ay*.uy) in
if beta = 0.0 then
alpha
else
begin
let gamma = (1.0 +. alpha)/.beta in
let delta = gamma*.gamma -. 1.0 in
let sol =
if beta > 0.0
then -.gamma +. sqrt(delta)
else -.gamma -. sqrt(delta) in
let (zx, zy) = translate (ax, ay) (ux*.sol, uy*.sol) in
let res = zx*.zx +. zy*.zy in
res
end
end
(* Limit of visibility for nodes *)
let rlimit = 0.98
let rlimit_sqr = rlimit *. rlimit
ocamlgraph-2.0.0/editor/gtree.ml 0000644 0001750 0000144 00000021775 13735627615 015153 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(*
module T =
struct
type t = DirTree.t
type label = DirTree.t
let id = DirTree.id
let edges = Hashtbl.create 97
let children t =
let l = DirTree.children t in
List.iter (fun i -> Hashtbl.replace edges (DirTree.id t, DirTree.id i) ()) l;
l
let label x = x
let string_of_label x = DirTree.string_of_label (DirTree.label x)
let root = DirTree.from_dir "" Sys.argv.(1)
end
*)
let debug = ref false
type drag_box =
{
db_nom : string;
db_noeud : GnoCanvas.ellipse;
mutable db_x : float;
mutable db_y : float;
db_w : float;
db_h : float;
mutable db_viewable : bool;
}
let drag_boxes = Hashtbl.create 97
module T =
struct
open Graph.Pack.Graph
let g = parse_gml_file Sys.argv.(1)
exception Choose of V.t
let root =
try
iter_vertex (fun v -> raise (Choose v)) g;
Format.eprintf "empty graph@."; exit 0
with Choose v ->
v
type t = V.t
type label = V.t
module H = Hashtbl.Make(V)
let ids = H.create 97
let id =
let r = ref 0 in
fun v -> try H.find ids v with Not_found -> incr r; H.add ids v !r; !r
let edges = Hashtbl.create 97
let make_subgraph l =
let edge v w = mem_edge g v w || mem_edge g w v in
let gl = create () in
List.iter (fun v -> add_vertex gl v) l;
List.iter
(fun v -> List.iter (fun w -> if edge v w then add_edge gl v w) l)
l;
(* TODO: efficacite *)
gl
let order_children l =
let gl = make_subgraph l in
let scc = Components.scc_list gl in
let order_component c =
let gc = make_subgraph c in
let v = match c with
| v :: l ->
List.fold_left
(fun m v -> if out_degree gc v < out_degree gc m then v else m)
v l
| [] ->
assert false
in
let l = ref [] in
Dfs.prefix_component (fun w -> l := w :: !l) gc v;
!l
in
let scc = List.map order_component scc in
List.flatten scc
let children v =
let l = succ g v in
List.iter (fun i -> Hashtbl.replace edges (id v, id i) ()) l;
let l =
List.filter
(fun w ->
try not (Hashtbl.find drag_boxes (id w)).db_viewable
with Not_found -> true)
l
in
let l = order_children l in
if !debug then
(
Format.printf "children %d: " (V.label v);
List.iter (fun w -> Format.printf "%d " (V.label w)) l;
Format.printf "@.";
);
l
let label x = x
let string_of_label x = string_of_int (V.label x)
end
module HT = Htree.Make(T)
let step = ref 0
let lines = Hashtbl.create 97
let show_tree canvas t width height =
let rlimit = 0.98 in
let xzoom = float(width)/.2.0
and yzoom = float(height)/.2.0 in
let origin = ref (-0.5,0.0) in
let xy2gtk x y = float x -. 300., float(height)/.2. -. float y +. 50. in
let gtk2xy gx gy = truncate (gx +. 300.), truncate ((float height)/.2. +. 50. -. gy) in
let xy2c (x, y) =
let zx = (float(x) -. xzoom)/.xzoom
and zy = (float(y) -. yzoom)/.yzoom in
let zn = sqrt(zx*.zx +. zy*.zy) in
if zn > rlimit then
(rlimit*.zx/.zn, rlimit*.zy/.zn)
else
(zx, zy)
in
let draw_edges () =
let draw_edge (i,j) () =
try
let dbi = Hashtbl.find drag_boxes i in
let dbj = Hashtbl.find drag_boxes j in
let l =
try
Hashtbl.find lines (i,j);
(*
if !debug
then Format.printf "find edge %s ---- %s@." (dbi.db_nom)(dbj.db_nom)
else ();
*)
with Not_found->
try
Hashtbl.find lines (j,i);
(* if !debug
then Format.printf "find edge %s ---- %s@." (dbi.db_nom)(dbj.db_nom)
else ();
*)
with Not_found ->
let l = GnoCanvas.line canvas ~props:[ `FILL_COLOR "black" ;`WIDTH_PIXELS 1; `SMOOTH true] in
Hashtbl.add lines (i,j) l;
if !debug
then Format.printf "draw_edge %s ---- %s@." (dbi.db_nom)(dbj.db_nom)
else ();
l
in
let p = [| dbi.db_x; dbi.db_y; dbj.db_x; dbj.db_y |] in
l#set [`POINTS p];
l#lower_to_bottom ()
with Not_found ->
try
let l= Hashtbl.find lines (i,j) in
l#destroy();
Hashtbl.remove lines (i,j)
with Not_found ->
()
in
Hashtbl.iter draw_edge T.edges
in
let rec draw_label lab (zx,zy) facteur_reduction =
if !debug then
Format.printf "draw_label %d@." (T.id lab);
let x = truncate (zx*.xzoom +. xzoom)
and y = truncate (zy*.yzoom +. yzoom) in
let name = T.string_of_label lab in
let (w,h) = (40,15) in
let x0 = x - w/2
and y0 = y - h/2 in
let fx,fy = xy2gtk x0 y0 in
try
let db = Hashtbl.find drag_boxes (T.id lab) in
db.db_x <- fx;
db.db_y <- fy;
db.db_viewable <- true;
db.db_noeud#parent#set [ `X fx; `Y fy; ];
db.db_noeud#parent#move ~x:zx ~y:zy;
with Not_found ->
let noeud = GnoCanvas.group ~x:fx ~y:fy canvas in
let ellipse = GnoCanvas.ellipse
~props:[ `X1 ( float (-w/2)); `Y1 (float (-h/2)); `X2 (float (w/2)) ; `Y2 ( float (h/2)) ;
`FILL_COLOR "grey" ; `OUTLINE_COLOR "black" ; `WIDTH_PIXELS 0 ] noeud
in
let _ = GnoCanvas.text ~props:[`X 0.0; `Y 0.0 ; `TEXT name; `FILL_COLOR "blue"] noeud in
let sigs = noeud#connect in
let db = { db_nom = name; db_noeud = ellipse; db_x = fx; db_y = fy; db_w = float w; db_h = float h; db_viewable = true } in
let _ = sigs#event (drag_label db) in
Hashtbl.add drag_boxes (T.id lab) db;
and draw_drv =
{ HT.rlimit = rlimit ;
HT.moveto = (fun _ -> ());
HT.lineto = (fun _ -> ());
HT.curveto = (fun _ _ _ -> ());
HT.draw_label = draw_label ;
HT.init_edge_pass = (fun () -> ());
HT.init_label_pass = (fun () -> ());
HT.finalize = (fun () -> ())
}
and draw_linear_tree t c f =
(* mettre toutes les boites à faux *)
Hashtbl.iter (fun _ db -> db.db_viewable <- false) drag_boxes;
HT.draw_linear_tree draw_drv t c f;
(* détruire toutes les boites restées à faux et les aretes correspondantes *)
let l = Hashtbl.fold
(fun i db acc ->
if not db.db_viewable
then
begin
db.db_noeud#parent#destroy ();
db.db_noeud#destroy ();
i::acc
end
else acc)
drag_boxes []
in
List.iter (fun i -> Hashtbl.remove drag_boxes i) l;
draw_edges ()
and drag_label db ev =
let item = db.db_noeud in
begin match ev with
| `ENTER_NOTIFY _ ->
item#set [ `FILL_COLOR "steelblue" ]
| `LEAVE_NOTIFY ev ->
let state = GdkEvent.Crossing.state ev in
if not (Gdk.Convert.test_modifier `BUTTON1 state)
then item#set [ `FILL_COLOR "grey" ; ]
| `BUTTON_RELEASE ev ->
item#parent#ungrab (GdkEvent.Button.time ev)
| `MOTION_NOTIFY ev ->
incr step;
let state = GdkEvent.Motion.state ev in
if Gdk.Convert.test_modifier `BUTTON1 state && !step mod 10=0 then
begin
let curs = Gdk.Cursor.create `FLEUR in
item#parent#grab [`POINTER_MOTION; `BUTTON_RELEASE] curs
(GdkEvent.Button.time ev);
let z1 = xy2c (gtk2xy db.db_x db.db_y) in
let mx = GdkEvent.Motion.x ev in
let my = GdkEvent.Motion.y ev in
let z2 = xy2c (gtk2xy mx my) in
item#parent#move ~x:mx ~y:my;
item#parent#set [`X mx; `Y my]; (* inutil ? *)
db.db_x <- mx;
db.db_y <- my;
origin := HT.drag_origin !origin z1 z2;
draw_linear_tree t !origin 0.0;
end
| _ ->
()
end;
true
in
draw_linear_tree t !origin 0.0
ocamlgraph-2.0.0/editor/outils_math.ml 0000644 0001750 0000144 00000005365 13735627615 016372 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(*** Operateurs Complex ***)
let ( ~-& ) (x, y) = (-.x, -.y)
let ( ~& ) (x, y) = (x, -.y)
let ( +& ) (x1, y1) (x2, y2) =
(x1 +. x2, y1 +. y2)
let ( -& ) (x1, y1) (x2, y2) =
(x1 +. x2, y1 +. y2)
let ( *& ) (x1, y1) (x2, y2) =
(x1*.x2 -. y1*.y2, x1*.y2 +. y1*.x2)
let ( /& ) (x1, y1) (x2, y2) =
let n2 = x2*.x2 +. y2*.y2 in
((x1*.x2 +. y1*.y2)/.n2, (-.x1*.y2 +. y1*.x2)/.n2)
let ( *.& ) f (x, y) =
(f*.x, f*.y)
let norm_sqr (x, y) =
x*.x +. y*.y
let norm (x, y) =
sqrt(x*.x +. y*.y)
let normalize (x, y) =
let n = sqrt(x*.x +. y*.y) in
(x/.n, y/.n)
let expi t =
(cos t, sin t)
(*** Fonctions Hyperboliques ***)
let th t =
let ept = exp t
and emt = exp (-.t) in
(ept -. emt)/.(ept +. emt)
let ath x =
0.5*.log((1.0 +. x)/.(1.0 -. x))
let pi = 3.14159265358979323846
let pi_over_2 = pi/.2.0
let pi_over_4 = pi/.4.0
let one = (1.0, 0.0)
let translate a z =
(a +& z)/&(one +& (~&a) *& z)
let gamma a u t =
let utht = th t *.& u in
(a +& utht) /& (one +& (~&a) *& utht)
let delta a u t =
let atht = th t *.& a
and utht = th t *.& u in
normalize ((u +& atht) /& (one +& (~&a) *& utht))
(* solving a Cramer system *)
let cramer a1 a2 b1 b2 c1 c2 =
let cdet = a1*.b2 -. a2*.b1
and xdet = c1*.b2 -. c2*.b1
and ydet = a1*.c2 -. a2*.c1 in
(xdet/.cdet, ydet/.cdet) ;;
let drag_origin (x0, y0) (x1, y1) (x2, y2) =
let (x1, y1) = translate (-.x0, -.y0) (x1, y1) in
let x3 = x1*.x2 -. y1*.y2 in
let y3 = x1*.y2 +. y1*.x2 in
cramer (1.0 -. x3) (-.y3) (-.y3) (1.0 +. x3) (x2 -. x1) (y2 -. y1)
ocamlgraph-2.0.0/editor/editor.ml 0000644 0001750 0000144 00000005774 13735627615 015334 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
open Format
let _ = GMain.Main.init ()
let print _ () = ()
(* print_endline msg;
flush stdout*)
let create_menu label menubar =
let item = GMenu.menu_item ~label ~packing:menubar#append () in
GMenu.menu ~packing:item#set_submenu ()
let main () =
(* Initialisation du fichier de graph *)
if Sys.argv.(1) = "--help" then
begin
printf "usage: %s file.gml # browse graph of file.gml@." Sys.argv.(0) ;
printf "@." ;
exit 0
end ;
(*
if Array.length Sys.argv > 2 then
eprintf "%s: ignoring trailing arguments@." Sys.argv.(0) ;
*)
(* la Fenetre principale *)
let window =
GWindow.window ~border_width: 10 ~title:"Edit'OcamlGraph" () in
let _ =
window#connect#destroy~callback:GMain.Main.quit in
(* une Verticale Box pour contenir le menu de la fenetre principale *)
let v_box =
GPack.vbox ~homogeneous:false ~spacing:30 ~packing:window#add () in
(* la barre de Menu ajout�e dans la V_box *)
let menu_bar =
GMenu.menu_bar ~packing:v_box#pack () in
(* le menu file : la description puis l'ajout au menu_bar *)
let menu_files =
[
`I ("_New Graph", print "todo new graph");
`I ("_Open Graph", print "todo open graph");
`I ("_Save Graph", print "todo save graph");
`I ("Save Graph _As ...", print "todo save graph as...");
`S;
`I ("_Quit", GMain.Main.quit )
]
and menu =
create_menu "File" menu_bar in
GToolbox.build_menu menu ~entries:menu_files ;
(* la zone d'affichage du graph, le canvas *)
let canvas =
GnoCanvas.canvas ~aa:true ~width:800 ~height:600 ~packing:v_box#add ()
in
let root = canvas#root in
(* l'affichage de la fenetre principale *)
window#show ();
let _ = Gtree.show_tree root Gtree.T.root 640 480 in
GMain.Main.main ()
let _ = main ()
ocamlgraph-2.0.0/editor/graphEd.ml 0000644 0001750 0000144 00000015227 13735627615 015412 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
open Graph.Pack.Graph
open Outils_math
open Outils_tort
open Format
open Graphics
let graph = parse_gml_file Sys.argv.(1)
exception Choose of V.t
let grey = rgb 128 128 128
let root =
try
iter_vertex (fun v -> raise (Choose v)) graph;
Format.eprintf "empty graph@."; exit 0
with Choose v ->
v
(* [step_from n] computes the best `distance' for solving the
dictator's problem in the complex hyperbolic plane for [n]
dictators. In a half-plane, we have to use the distance
given by [step_from (2*n)] or, better, the distance given
by [step_from (2*max(3 n))]. *)
let step_from n =
ath (tan (pi_over_4 -. pi/.float(2*n)))
(* [hspace_dist_sqr turtle] computes the square of the distance
between the origin and the half-space in front of [turtle]. *)
let hspace_dist_sqr turtle =
let (ax, ay) = turtle.pos
and (dx, dy) = turtle.dir in
if ax*.dx +. ay*.dy < 0.0 then 0.0 else
begin
let ux = dy and uy = -.dx in
let alpha = ax*.ax +. ay*.ay
and beta = 2.0*.(ax*.ux +. ay*.uy) in
if beta = 0.0 then
alpha
else
begin
let gamma = (1.0 +. alpha)/.beta in
let delta = gamma*.gamma -. 1.0 in
let sol =
if beta > 0.0
then -.gamma +. sqrt(delta)
else -.gamma -. sqrt(delta) in
let (zx, zy) = translate (ax, ay) (ux*.sol, uy*.sol) in
zx*.zx +. zy*.zy
end
end ;;
let draw_label v =
draw_string (string_of_int (V.label v))
let edge v w = mem_edge graph v w || mem_edge graph w v
let make_subgraph l =
let gl = create () in
List.iter (fun v -> add_vertex gl v) l;
List.iter
(fun v -> List.iter (fun w -> if edge v w then add_edge gl v w) l)
l;
(* TODO: efficacite *)
gl
let order_children l =
let gl = make_subgraph l in
let scc = Components.scc_list gl in
let order_component c =
let gc = make_subgraph c in
let v = match c with
| v :: l ->
List.fold_left
(fun m v -> if out_degree gc v < out_degree gc m then v else m)
v l
| [] ->
assert false
in
let l = ref [] in
Dfs.prefix_component (fun w -> l := w :: !l) gc v;
!l
in
let scc = List.map order_component scc in
List.flatten scc
let rlimit = 0.90
let rlimit_sqr = rlimit *. rlimit
module Vset = Set.Make(V)
let vset_of_list = List.fold_left (fun s x -> Vset.add x s) Vset.empty
module H = Hashtbl.Make(V)
let pos = H.create 97
let rec draw_graph noeud tortue =
if hspace_dist_sqr tortue <= rlimit_sqr then
begin
H.add pos noeud (0,tortue);
tmoveto tortue;
draw_label noeud;
let l = succ graph noeud in
let l = List.filter (fun x -> not (H.mem pos x) ) l in
let l = order_children l in
let n = List.length l in
if n > 0 then
begin
let pas = step_from (max 3 n)
and angle = 2. *. pi /. (float n) in
let ll = draw_edges tortue pas angle l in
List.iter (fun (v,tv) -> H.add pos v (1,tv)) ll;
List.iter
(fun (w,tw) ->
let l = succ graph w in
let l = List.filter (fun x -> not (H.mem pos x)) l in
let n = List.length l in
if n > 0 then
begin
let pas = step_from (max 3 n)
and angle = pi /. (float n) in
let tw = turn_right tw ((pi -. angle) /. 2.) in
let l = draw_edges tw pas angle l in
List.iter (fun (v,tv) -> H.add pos v (2,tv)) l
end)
ll;
(* draw intern edges *)
set_color grey;
H.iter
(fun v (lv,tv) ->
List.iter
(fun w ->
try
let lw,tw = H.find pos w in
if abs (lw - lv) <> 1 then begin tmoveto tv; tlineto tw end
with Not_found ->
())
(succ graph v))
pos;
set_color black
end
end
and draw_edges t pas angle= function
| [] ->
[]
| v :: l ->
let tv = tdraw_edge t pas 10 in
if hspace_dist_sqr t <= rlimit_sqr
then (draw_label v; H.add pos v (1,t));
let t = turn_left t angle in
let list = (v,tv) :: draw_edges t pas angle l in
draw_graph v tv ;
list
let draw origine tortue =
H.clear pos;
draw_graph root tortue
let () = open_graph (sprintf " %dx%d" (truncate w) (truncate h))
let tortue =
let (x,y) = from_tortue !origine in
moveto x y;
make_turtle !origine 0.0
let old_xy = ref None
let flags = [Button_down; Button_up; Key_pressed; Mouse_motion]
let rec boucle tortue =
let st = wait_next_event flags in
if st.button then begin match !old_xy with
| None ->
clear_graph ();
draw origine tortue;
old_xy := Some(st.mouse_x, st.mouse_y);
boucle tortue
| Some(x,y) ->
let z1 = to_tortue(x,y)
and z2 = to_tortue (st.mouse_x, st.mouse_y) in
clear_graph ();
origine := drag_origin !origine z1 z2 ;
let tort = make_turtle_dir !origine tortue.dir in
old_xy := Some(st.mouse_x, st.mouse_y);
draw origine tortue;
boucle tort
end
else
begin
match !old_xy with
| None ->
draw origine tortue;
boucle tortue
| Some(x,y) ->
clear_graph ();
draw origine tortue;
old_xy := None;
boucle tortue
end
let () = boucle tortue
ocamlgraph-2.0.0/editor/ed_draw.ml 0000644 0001750 0000144 00000012363 13735627615 015443 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(* This file is a contribution of Benjamin Vadon *)
open Ed_hyper
open Ed_graph
let make_subgraph l =
let gl = G.create () in
List.iter (fun v -> G.add_vertex gl v) l;
List.iter
(fun v ->
List.iter (fun w ->
if edge v w
then G.add_edge gl v w)
l)
l;
(* TODO: efficacite *)
gl
let order_children l =
let gl = make_subgraph l in
let scc = Components.scc_list gl in
let order_component c =
let gc = make_subgraph c in
(* choose a vertex v of minimal out degree *)
let v = match c with
| v :: l ->
List.fold_left
(fun m v ->
if G.out_degree gc v < G.out_degree gc m
then v
else m)
v l
| [] ->
assert false
in
let l = ref [] in
Dfs.prefix_component (fun w -> l := w :: !l) gc v;
!l
in
let scc = List.map order_component scc in
List.flatten scc
(* Depth First Search drawing *)
let rec draw_dfs depth node turtle =
let lab = G.V.label node in
lab.turtle <- turtle;
lab.depth <- depth;
if hspace_dist_sqr turtle <= rlimit_sqr then begin
lab.visible <- Visible;
let l = G.succ !graph node in
let l = List.filter (fun x -> (G.V.label x).visible = Hidden) l in
List.iter (fun w -> (G.V.label w).visible <- BorderNode) l;
let l = order_children l in
let n = List.length l in
if n > 0 then begin
let distance = step_from (if depth = 0 then max 3 n else 2 * max 3 n)
and angle = (if depth = 0 then 2. else 1.) *. pi /. (float_of_int n) in
let turtle =
if depth = 0 then turtle else turn_right turtle ((pi -. angle) /. 2.)
in
let _ = draw_edges_dfs node (depth+1) turtle distance angle l in
()
end
end
and draw_edges_dfs node depth turtle distance angle = function
| [] ->
[]
| v :: l ->
let e = G.E.label (G.find_edge !graph node v) in
e.visited <- true;
e.edge_turtle <- turtle;
e.edge_distance <- distance;
let steps = 10 in
e.edge_steps <- steps;
let tv = advance_many turtle distance steps in
let turtle = turn_left turtle angle in
let l = (v,tv) :: draw_edges_dfs node depth turtle distance angle l in
draw_dfs depth v tv;
l
(* Breadth First Search drawing *)
let draw_bfs root turtle =
let q = Queue.create () in
let add v n t =
Queue.push v q;
let lab = G.V.label v in
lab.turtle <- t;
lab.depth <- n
in
add root 0 turtle;
while not (Queue.is_empty q) do
let v = Queue.pop q in
let lab = G.V.label v in
let depth = lab.depth in
let tv = lab.turtle in
let dist = hspace_dist_sqr tv in
(* Format.eprintf"le noeud : %s la val presente apres :%f \n@."lab.label dist;*)
if dist <= rlimit_sqr then begin
lab.visible <- Visible;
let l = try G.succ !graph v with Invalid_argument _ -> [] in
let l = List.filter (fun x -> (G.V.label x).visible = Hidden) l in
List.iter (fun w -> (G.V.label w).visible <- BorderNode) l;
let l = order_children l in
let n = List.length l in
if n > 0 then begin
let distance = step_from (if depth = 0 then max 3 n else 2 * max 3 n)
and angle = (if depth = 0 then 2. else 1.) *. pi /. (float_of_int n) in
let turtle =
ref (if depth = 0 then tv else turn_right tv ((pi -. angle) /. 2.))
in
List.iter
(fun w ->
let e = G.E.label (G.find_edge !graph v w) in
e.visited <- true;
e.edge_turtle <- !turtle;
e.edge_distance <- distance;
let steps = 10 in
e.edge_steps <- steps;
let tw = advance_many !turtle distance steps in
add w (depth + 1) tw;
turtle := turn_left !turtle angle)
l
end
end
done
(* Drawing graph function *)
let draw_graph root turtle =
G.iter_vertex (fun v -> let l = G.V.label v in l.visible <- Hidden) !graph;
G.iter_edges_e (fun e -> let l = G.E.label e in l.visited <- false) !graph;
(if !dfs then draw_dfs 0 else draw_bfs) root turtle
ocamlgraph-2.0.0/editor/ed_main.ml 0000644 0001750 0000144 00000077446 13735627615 015447 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(* This file is a contribution of Benjamin Vadon *)
open Format
open Ed_hyper
open Ed_graph
open Ed_display
let debug = ref false
let trace f x =
try f x with e -> eprintf "TRACE: %s@." (Printexc.to_string e); raise e
let _ = GMain.Main.init ()
(* Model for the treeview on the left *)
module Model = struct
open Gobject.Data
let cols = new GTree.column_list
let name = cols#add string
let vertex = cols#add caml
let model = GTree.tree_store cols
let rows = H.create 97
let find_row v =
try
H.find rows v
with Not_found ->
Format.eprintf "anomaly: no model row for %s@." (string_of_label v);
raise Not_found
let add_vertex v =
let row = model#append () in
model#set ~row ~column:name (string_of_label v);
model#set ~row ~column:vertex v;
H.add rows v row;
row
let add_edge_1 row_v w =
let row = model#append ~parent:row_v () in
model#set ~row ~column:name (string_of_label w);
model#set ~row ~column:vertex w
let add_edge v w =
let row_v = find_row v in
add_edge_1 row_v w;
if not G.is_directed then
let row_w = find_row w in
add_edge_1 row_w v
let find_children row_v w =
let nb_child = model#iter_n_children (Some row_v) in
let rec find n =
let child = model#iter_children ~nth:(n-1) (Some row_v) in
let child_vertex = model#get ~row:child ~column:vertex in
match n with
| 0 -> raise Not_found
| n ->
if (G.V.equal child_vertex w)
then child
else find (n-1)
in
find nb_child
let remove_edge_1 row_v w =
ignore (model#remove (find_children row_v w))
let remove_edge v w =
let row_v = find_row v in
remove_edge_1 row_v w;
if not G.is_directed then
let row_w = find_row w in
remove_edge_1 row_w v
let remove_vertex vertex =
G.iter_succ (fun w -> remove_edge w vertex) !graph vertex;
let row = find_row vertex in
model#remove row
let reset () =
H.clear rows;
model#clear ();
G.iter_vertex
(fun v ->
let row = add_vertex v in
G.iter_succ (add_edge_1 row) !graph v)
!graph
end
let () = Model.reset ()
let ed_name = "Ocamlgraph's Editor"
(* Main GTK window *)
let window = GWindow.window ~border_width: 10 ~position: `CENTER ()
(* usual function to change window title *)
let set_window_title () =
window#set_title
(match !graph_name with
| None -> ed_name
| Some name -> ed_name^" : "^(Filename.chop_extension (Filename.basename name)))
(* menu bar *)
let v_box = GPack.vbox ~homogeneous:false ~spacing:30 ~packing:window#add ()
let menu_bar_box = GPack.vbox ~packing:v_box#pack ()
(* treeview on the left, canvas on the right *)
let h_box = GPack.hbox ~homogeneous:false ~spacing:30 ~packing:v_box#add ()
let sw = GBin.scrolled_window ~shadow_type:`ETCHED_IN ~hpolicy:`NEVER
~vpolicy:`AUTOMATIC ~packing:h_box#add ()
let canvas =
GnoCanvas.canvas
~aa:!aa
~width:(truncate w)
~height:(truncate h)
~packing:h_box#add ()
(* unit circle as root of graph drawing *)
let canvas_root =
let circle_group = GnoCanvas.group ~x:300.0 ~y:300.0 canvas#root in
circle_group#lower_to_bottom ();
let w2 = 2. in
let circle = GnoCanvas.ellipse ~props:[ `X1 (-.w/.2. +.w2); `Y1 (-.h/.2. +.w2);
`X2 (w/.2. -.w2) ; `Y2 ( h/.2. -.w2) ;
`FILL_COLOR color_circle ; `OUTLINE_COLOR "black" ;
`WIDTH_PIXELS (truncate w2) ] circle_group
in
circle_group#lower_to_bottom ();
circle#show();
let graph_root = GnoCanvas.group ~x:(-.300.0) ~y:(-.300.0) circle_group in
graph_root#raise_to_top ();
set_window_title ();
graph_root
(* current root used for drawing *)
let root = ref (choose_root ())
let load_graph f =
Ed_graph.load_graph f;
Model.reset ();
set_window_title ();
root := choose_root ()
(* refresh rate *)
let refresh = ref 0
let do_refresh () =
!refresh mod !refresh_rate = 0
(* graph drawing *)
let draw tortue canvas =
match !root with
| None -> ()
| Some root ->
Ed_draw.draw_graph root tortue;
Ed_display.draw_graph root canvas;
if do_refresh () then
canvas_root#canvas#update_now ()
let refresh_draw () =
refresh := 0;
let tor = make_turtle !origine 0.0 in
draw tor canvas_root
let refresh_display () =
Ed_display.draw_graph !root canvas_root
let root_change vertex ()=
root := vertex;
origine := start_point;
let turtle = make_turtle_origine () in
draw turtle canvas_root
let node_selection ~(model : GTree.tree_store) path =
let row = model#get_iter path in
let vertex = model#get ~row ~column: Model.vertex in
root_change (Some vertex) ()
(* usual function ref, for vertex event *)
let set_vertex_event_fun = ref (fun _ -> ())
(* type to select nature of modification *)
type modification = Add | Remove
(* add a vertex with no successor *)
let add_node () =
let window = GWindow.window
~title: "Choose vertex label"
~width: 300
~height: 50
~position: `MOUSE
() in
let vbox = GPack.vbox
~packing: window#add () in
let entry = GEdit.entry
~max_length: 50
~packing: vbox#add () in
entry#set_text "Label";
entry#select_region
~start:0
~stop:entry#text_length;
(*two check buttons allowing to add node to selection list and to choose this node as root*)
let hbox = GPack.hbox
~packing: vbox#add () in
let is_in_selection = ref false in
let in_selection = GButton.check_button
~label: "Add to selection"
~active:!is_in_selection
~packing: hbox#add () in
ignore (in_selection#connect#toggled
~callback:(fun () ->is_in_selection := in_selection#active ));
let is_as_root = ref ((G.nb_vertex !graph)=0) in
let as_root = GButton.check_button
~label:"Choose as root"
~active:!is_as_root
~packing:hbox#add () in
ignore (as_root#connect#toggled
~callback:(fun () ->is_as_root := as_root#active ));
window#show ();
(*entry's callback*)
ignore( entry#connect#activate
~callback: (fun () ->
let text = entry#text in
window#destroy ();
(* new vertex *)
let vertex = G.V.create (make_node_info text) in
G.add_vertex !graph vertex ;
ignore (Model.add_vertex vertex);
Ed_display.add_node canvas_root vertex;
!set_vertex_event_fun vertex;
if !is_as_root then root_change (Some vertex) () ;
if !is_in_selection then update_vertex vertex Select;
let tor = make_turtle !origine 0.0 in
draw tor canvas_root))
(* add an edge between n1 and n2 , add link in column and re-draw *)
let add_edge n1 n2 ()=
if not (edge n1 n2)
then begin
G.add_edge_e !graph (G.E.create n1 (make_edge_info ()) n2);
Model.add_edge n1 n2;
let tor = make_turtle !origine 0.0 in
draw tor canvas_root;
end
let add_edge_no_refresh n1 n2 ()=
if not (edge n1 n2)
then begin
G.add_edge_e !graph (G.E.create n1 (make_edge_info ()) n2);
Model.add_edge n1 n2
end
(* remove an edge between n1 and n2 , add un-link in column and re-draw *)
let remove_edge n1 n2 ()=
if (edge n1 n2)
then begin
G.remove_edge !graph n1 n2;
Model.remove_edge n1 n2;
begin
try
let _,n = H2.find intern_edges (n1,n2) in
n#destroy ();
H2.remove intern_edges (n1,n2)
with Not_found -> ()
end;
begin
try
let _,n = H2.find intern_edges (n2,n1) in
n#destroy ();
H2.remove intern_edges (n2,n1)
with Not_found -> ()
end;
begin
try
let n = H2.find successor_edges (n1,n2) in
n#destroy ();
H2.remove successor_edges (n1,n2)
with Not_found -> ()
end;
begin
try
let n = H2.find successor_edges (n2,n1) in
n#destroy ();
H2.remove successor_edges (n2,n1)
with Not_found -> ()
end;
let tor = make_turtle !origine 0.0 in
draw tor canvas_root;
end
let remove_edge_no_refresh n1 n2 ()=
if (edge n1 n2)
then begin
G.remove_edge !graph n1 n2;
Model.remove_edge n1 n2
end
(* add successor node to selected node *)
let add_successor node () =
let window = GWindow.window
~title: "Choose label name"
~width: 300
~height: 50
~position: `MOUSE
() in
let vbox = GPack.vbox
~packing: window#add
() in
let entry = GEdit.entry
~max_length: 50
~packing: vbox#add
() in
entry#set_text "Label";
entry#select_region
~start:0
~stop:entry#text_length;
window#show ();
ignore (entry#connect#activate
~callback:(fun () ->
let text = entry#text in
window#destroy ();
(* new vertex *)
let vertex = G.V.create (make_node_info text) in
G.add_vertex !graph vertex ;
ignore (Model.add_vertex vertex);
Ed_display.add_node canvas_root vertex;
!set_vertex_event_fun vertex;
(* new edge *)
G.add_edge_e !graph (G.E.create node (make_edge_info()) vertex);
Model.add_edge node vertex;
(* redraw *)
let tor = make_turtle !origine 0.0 in
draw tor canvas_root
)
)
let remove_vertex vertex () =
G.iter_succ
(fun w ->
begin
try
let _,n = H2.find intern_edges (vertex,w) in
n#destroy ();
H2.remove intern_edges (vertex,w)
with Not_found -> ()
end;
begin
try
let _,n = H2.find intern_edges (w,vertex) in
n#destroy ();
H2.remove intern_edges (w,vertex)
with Not_found -> ()
end;
begin
try
let n = H2.find successor_edges (vertex,w) in
n#destroy ();
H2.remove successor_edges (vertex,w)
with Not_found -> ()
end;
begin
try
let n = H2.find successor_edges (w,vertex) in
n#destroy ();
H2.remove successor_edges (w,vertex)
with Not_found -> ()
end;
)
!graph vertex;
let (n,_,_) = H.find nodes vertex in
n#destroy ();
H.remove nodes vertex;
ignore (Model.remove_vertex vertex);
G.remove_vertex !graph vertex;
begin match !root with
| None -> ()
| Some root_v ->
if (G.V.equal root_v vertex)
then root := choose_root();
end;
refresh_draw ()
let sub_edge_to modif_type vertex list =
let ll = List.length list in
let nb_sub_menu = (ll - 1)/10 + 1 in
let nb_edge = ll / nb_sub_menu -1 in
let menu = new GMenu.factory (GMenu.menu()) in
let sub_menu =ref (new GMenu.factory (GMenu.menu())) in
let add_menu_edge vertex v2 =
if not (G.V.equal v2 vertex)
then begin
match modif_type with
| Add -> ignore((!sub_menu)#add_item (string_of_label v2)
~callback:( add_edge v2 vertex));
| Remove -> ignore((!sub_menu)#add_item (string_of_label v2)
~callback:(remove_edge v2 vertex));
end;
in
let rec make_sub_menu vertex list nb =
match list with
| [] -> ()
| v::list ->
match nb with
| 0 ->
begin
sub_menu :=new GMenu.factory (GMenu.menu()) ;
add_menu_edge vertex v;
let string = string_of_label v in
ignore (menu#add_item (String.sub string 0 (min (String.length string) 3)^"...")
~submenu: !sub_menu#menu);
make_sub_menu vertex list (nb+1);
end
| n when n= nb_edge->
begin
add_menu_edge vertex v;
make_sub_menu vertex list 0
end
| _ ->
begin
add_menu_edge vertex v;
make_sub_menu vertex list (nb+1)
end
in
if ll > 10
then begin
make_sub_menu vertex list 0;
menu
end
else begin
let rec make_sub_bis list =
match list with
| [] -> ();
| v::list ->add_menu_edge vertex v; make_sub_bis list
in
make_sub_bis list;
!sub_menu
end
let edge_to modif_type vertex list =
(* add an edge between current vertex and one of selected vertex*)
sub_edge_to modif_type vertex list
let all_edges (edge_menu :#GMenu.menu GMenu.factory) vertex list =
(*add all edges as possible from current vertex to selected vertices*)
begin
let add_all_edge vertex list () =
List.iter (fun v -> if not (G.V.equal v vertex)
then add_edge_no_refresh v vertex()
)
list ;
refresh := 0;
let tor = make_turtle !origine 0.0 in
draw tor canvas_root
in
ignore (edge_menu#add_item "Add all edges" ~callback:( add_all_edge vertex list))
end
let contextual_menu vertex ev =
let menu = new GMenu.factory (GMenu.menu ()) in
(* change root*)
ignore (menu#add_item "As root" ~callback:(root_change (Some vertex)));
(*vertex menu*)
let vertex_menu = new GMenu.factory (GMenu.menu ()) in
begin
(* successor *)
ignore (vertex_menu#add_item "Add successor" ~callback:(add_successor vertex));
ignore (vertex_menu#add_separator ());
(* remove vertex *)
ignore(vertex_menu#add_item "Remove vertex" ~callback:(remove_vertex vertex));
end;
ignore(menu#add_item "Vertex ops" ~submenu: vertex_menu#menu);
(*edge menu*)
begin
let add_list = selected_list (ADD_FROM vertex) in
let rem_list = selected_list (REMOVE_FROM vertex) in
let al =List.length add_list in
let rl =List.length rem_list in
let isel = is_selected vertex in
let menu_bool = ref false in
let edge_menu = new GMenu.factory (GMenu.menu ()) in
begin
(* add menu *)
if isel && al=2
|| not isel && al=1
then begin
ignore (edge_menu#add_item "Add edge with" ~submenu: (edge_to Add vertex add_list)#menu);
menu_bool := true;
end
else begin
if isel && al>2 ||
not isel && al>1
then begin
ignore (edge_menu#add_item "Add edge with" ~submenu: (edge_to Add vertex add_list)#menu);
all_edges edge_menu vertex add_list;
menu_bool := true;
end
end;
(* remove menu *)
if isel && rl>=2 ||
not isel && rl>=1
then begin
if !menu_bool then ignore (edge_menu#add_separator ());
ignore (edge_menu#add_item "Remove edge with" ~submenu: (edge_to Remove vertex rem_list)#menu);
menu_bool := true;
end;
if !menu_bool then ignore(menu#add_item "Edge ops" ~submenu: edge_menu#menu);
end;
end;
menu#menu#popup ~button:3 ~time:(GdkEvent.Button.time ev)
(* unit circle callback *)
let circle_event ev =
begin match ev with
| `BUTTON_PRESS ev ->
if (GdkEvent.Button.button ev) = 3
then
begin
let menu = new GMenu.factory (GMenu.menu ()) in
ignore (menu#add_item " Add node" ~callback:(add_node));
menu#menu#popup
~button:3
~time:(GdkEvent.Button.time ev)
end
| _ ->()
end;
true
(* event for each vertex of canvas *)
let vertex_event vertex item ellispe ev =
(* let vertex_info = G.V.label vertex in*)
begin match ev with
| `ENTER_NOTIFY _ ->
item#grab_focus ();
update_vertex vertex Focus;
refresh_display ()
| `LEAVE_NOTIFY ev ->
if not (Gdk.Convert.test_modifier `BUTTON1 (GdkEvent.Crossing.state ev))
then begin
update_vertex vertex Unfocus;
refresh_display ()
end
| `BUTTON_RELEASE ev ->
ellispe#parent#ungrab (GdkEvent.Button.time ev);
| `MOTION_NOTIFY ev ->
incr refresh;
let state = GdkEvent.Motion.state ev in
if Gdk.Convert.test_modifier `BUTTON1 state then
begin
let curs = Gdk.Cursor.create `FLEUR in
ellispe#parent#grab [`POINTER_MOTION; `BUTTON_RELEASE]
curs (GdkEvent.Button.time ev);
if do_refresh ()
then begin
let old_origin = !origine in
let turtle = motion_turtle ellispe ev in
if hspace_dist_sqr turtle <= rlimit_sqr then begin
draw turtle canvas_root
end else begin
origine := old_origin;
let turtle = { turtle with pos = old_origin } in
draw turtle canvas_root
end
end
end
| `BUTTON_PRESS ev ->
if (GdkEvent.Button.button ev) = 3
then
begin
contextual_menu vertex ev
end
| `TWO_BUTTON_PRESS ev->
if (GdkEvent.Button.button ev) = 1
then begin
if (Gdk.Convert.test_modifier `CONTROL (GdkEvent.Button.state ev))
then begin
if ( !nb_selected =0)
then begin
select_all ();
update_vertex vertex Focus
end
else begin
unselect_all ();
update_vertex vertex Focus
end
end
else begin
if (is_selected vertex)
then update_vertex vertex Unselect
else update_vertex vertex Select;
end;
refresh_draw ();
end;
| _ ->
()
end;
true
let set_vertex_event vertex =
let item,ell,_ = H.find nodes vertex in
ignore (item#connect#event ~callback:(vertex_event vertex item ell))
let () = set_vertex_event_fun := set_vertex_event
let set_canvas_event () =
(* circle event *)
ignore(canvas_root#parent#connect#event ~callback:(circle_event));
(* vertex event *)
G.iter_vertex set_vertex_event !graph
(* treeview *)
let add_columns ~(view : GTree.view) ~model =
let renderer = GTree.cell_renderer_text [`XALIGN 0.] in
let vc = GTree.view_column ~title:"Nodes" ~renderer:(renderer, ["text", Model.name]) ()
in
ignore (view#append_column vc);
vc#set_sizing `FIXED;
vc#set_fixed_width 100;
(* vc#set_resizable true;*)
vc#set_sizing `AUTOSIZE;
view#selection#connect#after#changed ~callback:
begin fun () ->
List.iter
(fun p -> node_selection ~model p)
view#selection#get_selected_rows;
end
let _ = window#connect#destroy~callback:GMain.Main.quit
let treeview = GTree.view ~model:Model.model ~packing:sw#add ()
let () = treeview#set_rules_hint true
let () = treeview#selection#set_mode `MULTIPLE
let _ = add_columns ~view:treeview ~model:Model.model
(* reset *)
let reset_table_and_canvas () =
let l = canvas_root#get_items in
List.iter (fun v -> trace v#destroy ()) l;
H2.clear intern_edges;
H2.clear successor_edges;
reset_display canvas_root;
origine := start_point;
nb_selected:=0
(* menu action functions *)
(* choose a file to load or save to *)
let ask_for_file (mode: [< `OPEN | `SAVE]) =
let default_file d = function
| None -> d
| Some v -> v
in
let all_files () =
let f = GFile.filter ~name:"All" () in
f#add_pattern "*" ;
f
in
let graph_filter () =
GFile.filter
~name:"Fichier de graphes"
~patterns:[ "*.dot"; "*.gml" ] ()
in
let dialog =
begin match mode with
| `OPEN ->
let dialog =
GWindow.file_chooser_dialog
~action: `OPEN
~title:"Open graph file"
~parent: window () in
dialog#add_button_stock `CANCEL `CANCEL ;
dialog#add_select_button_stock `OPEN `OPEN;
dialog
| `SAVE ->
let dialog =
GWindow.file_chooser_dialog
~action: `SAVE
~title: "Save graph as..."
~parent: window
() in
dialog#set_current_name "my_graph.dot";
dialog#add_button_stock `CANCEL `CANCEL ;
dialog#add_select_button_stock `SAVE `SAVE;
dialog
end;
in
dialog#add_filter (graph_filter ()) ;
dialog#add_filter (all_files ()) ;
let f = match dialog#run () with
| `OPEN -> default_file "" dialog#filename
| `SAVE -> default_file "my_graph.dot" dialog#filename
| `DELETE_EVENT | `CANCEL -> ""
in
dialog#destroy ();
f
(* menu action new graph *)
let new_graph () =
let alert_window = GWindow.message_dialog
~message:("Are you sure you want to start"
^" a new graph and discard all"
^" unsaved changes to :\n\n"
^"\t"
^(match !graph_name with
| None -> "unamed"
| Some name -> name)
^" ")
~use_markup:true
~title:"New graph ?"
~message_type:`QUESTION
~buttons:GWindow.Buttons.yes_no
~parent:window
~resizable:false
~position:`CENTER_ON_PARENT
()
in
begin
match alert_window#run () with
| `YES ->
begin
graph := G.create ();
Model.reset();
reset_table_and_canvas ();
graph_name := None;
set_window_title ()
end
| `DELETE_EVENT | `NO -> ()
end;
alert_window#destroy ()
(* menu action open graph *)
let open_graph () =
let file = ask_for_file `OPEN in
if file <> ""
then
begin
load_graph file;
reset_table_and_canvas ();
let turtle = make_turtle_origine () in
draw turtle canvas_root;
set_canvas_event ()
end
(* menu action save graph as *)
let save_graph_as () =
let file = ask_for_file `SAVE in
if file <> ""
then begin
save_graph file;
set_window_title ()
end
(* menu action save graph *)
let save_graph () =
match !graph_name with
| None -> ()
| Some name ->
begin
save_graph name;
set_window_title ()
end
(* menu action quit *)
let quit () =
let alert_window = GWindow.message_dialog
~message:("Are you sure you want to quit"
^" and discard all"
^" unsaved changes to :\n\n"
^"\t"
^(match !graph_name with
| None -> "unamed"
| Some name -> name)
^" ")
~use_markup:true
~title:"Quit ?"
~message_type:`QUESTION
~buttons:GWindow.Buttons.yes_no
~parent:window
~resizable:false
~position:`CENTER_ON_PARENT
()
in
begin
match alert_window#run () with
| `YES -> window#destroy ()
| `DELETE_EVENT | `NO -> ()
end
(* menu action about *)
let about () =
let dialog = GWindow.about_dialog
~authors:["Ocamlgraph :";
" Sylvain Conchon";
" Jean-Christophe Filliatre";
" Julien Signoles";
"";
ed_name^" :";
" Vadon Benjamin"]
~comments:" Ocamlgraph: a generic graph library for OCaml"
~copyright:"Copyright (C) 2004-2007
Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles"
~license:" 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, 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."
~logo:(GdkPixbuf.from_file"ed_icon.xpm" )
~name:ed_name
~version:"0.99"
~website:"http://ocamlgraph.lri.fr/"
~parent:window
~title:"About"
~resizable:false
~position:`CENTER_ON_PARENT
()
in
try ignore( dialog#run ())
with Not_found -> dialog#destroy ()
let handbook_text (view:GText.view) =
let buffer = view#buffer in
(* text's tags *)
ignore (buffer#create_tag ~name:"annotation" [`LEFT_MARGIN 10; `RIGHT_MARGIN 10; `SIZE (7*Pango.scale)]);
ignore (buffer#create_tag ~name:"center" [`JUSTIFICATION `CENTER]);
ignore (buffer#create_tag ~name:"heading" [`UNDERLINE `SINGLE; `WEIGHT `BOLD; `SIZE (14*Pango.scale)]);
ignore (buffer#create_tag ~name:"italic" [`LEFT_MARGIN 10; `RIGHT_MARGIN 10; `STYLE `ITALIC]);
ignore (buffer#create_tag ~name:"item" [`LEFT_MARGIN 20; `RIGHT_MARGIN 10]);
ignore (buffer#create_tag ~name:"subsection" [`LEFT_MARGIN 10; `RIGHT_MARGIN 10]);
ignore (buffer#create_tag ~name:"title" [`WEIGHT `BOLD; `SIZE (17*Pango.scale);`JUSTIFICATION `CENTER]);
ignore (buffer#create_tag ~name:"word_wrap" [`WRAP_MODE `WORD; `EDITABLE false]);
let iter = buffer#get_iter_at_char 0 in
(* title *)
buffer#insert ~iter ~tag_names:["title"] (ed_name^" Handbook\n");
(* editor's icon *)
let image_anchor = buffer#create_child_anchor iter in
let image = GMisc.image
~pixbuf:(GdkPixbuf.from_file_at_size "ed_icon.xpm" ~width:70 ~height:70)
() in
view#add_child_at_anchor image#coerce image_anchor;
buffer#insert ~iter "\n\n\n";
let start,stop = buffer#bounds in
buffer#apply_tag_by_name "center" ~start ~stop ;
(* buffer's text *)
buffer#insert ~iter ~tag_names:["heading"] "First words\n";
buffer#insert ~iter ~tag_names:["subsection"]
("\tFirst of all, you have to know this is an experimental application. "
^"If you find a bug, please report it to the developers. "
^"This application has only basic functionalities on graphs, so if you want a new functionality, send it too.\n");
buffer#insert ~iter ~tag_names:["subsection"]
(ed_name^" represents a graph in hyperbolic geometry, and specifically in Poincaré's disk representation.\n\n"
^ed_name^" is organized in four parts :\n");
buffer#insert ~iter ~tag_names:["item"] "- a menu bar\n";
buffer#insert ~iter ~tag_names:["item"] "- a vertex list, on the left side\n";
buffer#insert ~iter ~tag_names:["item"] "- the Poincaré's disk\n";
buffer#insert ~iter ~tag_names:["item"] "- and an associated contextual menu\n\n";
buffer#insert ~iter ~tag_names:["heading"] "Menu bar\n";
buffer#insert ~iter ~tag_names:["subsection"]
"\t It provides standard functionalities. You can create a new graph, open and save graphs from/to the Gml and Dot formats.\n";
buffer#insert ~iter ~tag_names:["italic"]
"Don't forget to save your changes before create or load a new graph.\n\n";
buffer#insert ~iter ~tag_names:["heading"] "Vertex list\n";
buffer#insert ~iter ~tag_names:["subsection"]
"\t You can change the root the of graph diagram by clicking on a vertex name. If you expand one, you can see its descendants.\n\n";
buffer#insert ~iter ~tag_names:["heading"] "Poincaré's disk\n";
buffer#insert ~iter ~tag_names:["subsection"]
("\t The graph is displayed in a disk. You can drag vertex to move the whole graph around.");
buffer#insert ~iter ~tag_names:["annotation"] "[1]\n";
buffer#insert ~iter ~tag_names:["subsection"]
("By double-clicking on a node, you add/remove it to the current selection.\nWith a +double-click you select all nodes, or unselect all (if one or more node is already selected)"
^"\n\n");
buffer#insert ~iter ~tag_names:["heading"] "Contextual menu\n";
buffer#insert ~iter ~tag_names:["subsection"]
("\t This is the main way (and the only for the moment) to edit a graph. There are two different menus, but the distinction is transparent for the user.\n"
^"The first is only composed by an 'adding node' menu, and appears when you click anywhere in the background of the disk.\n"
^"The second menu appears when you click on a vertex."
^" You can change root of the graph diagram, add a child node or remove the focused vertex."
^" The remainder of the menu depends on which nodes are selected. You can add or remove an edge with one of them selected, or with all."
^"\n\n");
buffer#insert ~iter ~tag_names:["annotation"] "[1] :";
buffer#insert ~iter ~tag_names:["subsection"] " a bug still remains, you can't drag root to much on the right-side, but on the left-side it is infinite";
let start,stop = buffer#bounds in
buffer#apply_tag_by_name "word_wrap" ~start ~stop ;
()
(* menu action handbook *)
let handbook () =
let dialog = GWindow.dialog
~width:450
~height:450
~title:"Handbook"
() in
let view = GText.view () in
let sw = GBin.scrolled_window ~packing:dialog#vbox#add ()
in
sw#add view#coerce;
handbook_text view;
dialog#add_button_stock `CLOSE `CLOSE;
match dialog#run () with
| `CLOSE | `DELETE_EVENT -> dialog#destroy ()
(* menu bar, based on ui_manager *)
let ui_info = "\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
"
(* choose right menu action *)
let activ_action ac =
let name = ac#name in
match name with
| "New graph" -> new_graph ()
| "Open graph"-> open_graph ()
| "Save graph" -> save_graph ()
| "Save graph as..." -> save_graph_as ()
| "Quit" -> quit ()
| "About" -> about ()
| "Handbook" -> handbook ()
| _ -> Format.eprintf "%s menu is not yet implemented @." name
let setup_ui window =
let add_action = GAction.add_action in
let actions = GAction.action_group ~name:"Actions" () in
GAction.add_actions actions
[ add_action "FileMenu" ~label:"_File" ;
add_action "HelpMenu" ~label:"_Help" ;
add_action "New graph" ~stock:`NEW ~tooltip:"Create a new graph"
~callback:activ_action ;
add_action "Open graph" ~stock:`OPEN ~tooltip:"Open a graph file"
~callback:activ_action ;
add_action "Save graph" ~stock:`SAVE ~tooltip:"Save current graph"
~callback:activ_action ;
add_action "Save graph as..." ~stock:`SAVE_AS ~accel:"S"
~tooltip:"Save current graph to specified file"
~callback:activ_action ;
add_action "Quit" ~stock:`QUIT ~tooltip:"Quit"
~callback:activ_action ;
add_action "About" ~label:"_About" ~tooltip:"Who build this"
~callback:activ_action;
add_action "Handbook" ~label:"_Handbook" ~accel:"H" ~tooltip:"How to.."
~callback:activ_action;
] ;
let ui_m = GAction.ui_manager () in
ui_m#insert_action_group actions 0 ;
window#add_accel_group ui_m#get_accel_group ;
ignore (ui_m#add_ui_from_string ui_info) ;
menu_bar_box#pack (ui_m#get_widget "/MenuBar")
let () =
reset_table_and_canvas ();
draw (make_turtle_origine ()) canvas_root;
set_canvas_event ();
canvas#set_scroll_region ~x1:0. ~y1:0. ~x2:w ~y2:h ;
setup_ui window;
ignore (window#show ());
GMain.Main.main ()
ocamlgraph-2.0.0/editor/htree.mli 0000644 0001750 0000144 00000004036 13735627615 015314 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
module type TREE = sig
type t
type label
val children : t -> t list
val label : t -> label
end ;;
module type HTREE = sig
type t
type label
val children : t -> t list
val label : t -> label
type coord = float * float
type driver = {
rlimit : float ;
moveto : coord -> unit ;
lineto : coord -> unit ;
curveto : coord -> coord -> coord -> unit ;
draw_label : label -> coord -> float -> unit ;
init_edge_pass : unit -> unit ;
init_label_pass : unit -> unit ;
finalize : unit -> unit ;
}
val shrink_factor : coord -> float
val drag_origin : coord -> coord -> coord -> coord
val draw_linear_tree : driver -> t -> coord -> float -> unit
val draw_curved_tree : driver -> t -> coord -> float -> unit
end ;;
module Make(T : TREE) :
HTREE with type t = T.t and type label = T.label ;;
ocamlgraph-2.0.0/editor/ed_display.ml 0000644 0001750 0000144 00000031447 13735627615 016157 0 ustar rt users (**************************************************************************)
(* *)
(* 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. *)
(* *)
(**************************************************************************)
(* This file is a contribution of Benjamin Vadon *)
open Ed_hyper
open Ed_graph
let debug = ref false
(* Original window size *)
let (w,h)= (600.,600.)
(* light mode
(* differents definitions *)
let color_circle = "grey99"
let color_intern_edge = "grey69"
let color_successor_edge = "black" (*"grey38"*)
let color_vertex = "grey75"
let color_selected_intern_edge = "#9f1a1a" (* "#74885e"*)
let color_selected_successor_edge = "#9f1a1a"
let color_selected_vertex = "#9f1a1a"
let color_focused_intern_edge = "#4d51a9"
let color_focused_successor_edge = "#4d51a9"
let color_focused_vertex = "#4d51a9"
let color_selected_focused_intern_edge = "LightCoral"
let color_selected_focused_vertex ="LightCoral"
let color_selected_focused_successor_edge = "LightCoral"
let color_text = "black"
let width_successor_edge = 2
let width_intern_edge = 2
let point_size_text = 12.*)
(* dark mode
(* differents definitions *)
let color_circle = "grey99"
let color_intern_edge = "black"
let color_successor_edge ="black"
let color_vertex = "grey58"
let color_selected_intern_edge = "OrangeRed4"
let color_selected_successor_edge = "OrangeRed4"
let color_selected_vertex = "OrangeRed4"
let color_focused_intern_edge = "blue"
let color_focused_successor_edge = "blue"
let color_focused_vertex = "blue"
let color_selected_focused_intern_edge = "dark magenta"
let color_selected_focused_vertex ="dark magenta"
let color_selected_focused_successor_edge = "dark magenta"
let color_text = "white"
let width_successor_edge = 2
let width_intern_edge = 2
let point_size_text = 12.
*)
(* guizmode *)
(* differents definitions *)
let color_circle = "grey99"
let color_intern_edge = "grey69"
let color_successor_edge = "black" (*"grey38"*)
let color_vertex = "grey75"
let color_selected_intern_edge = "#9f1a1a" (* "#74885e"*)
let color_selected_successor_edge = "#9f1a1a"
let color_selected_vertex = "#9f1a1a"
let color_focused_intern_edge = "#4d51a9"
let color_focused_successor_edge = "#4d51a9"
let color_focused_vertex = "#4d51a9"
let color_selected_focused_intern_edge = "#e80000"
let color_selected_focused_vertex ="#e80000"
let color_selected_focused_successor_edge = "#e80000"
let color_text = "black"
let width_successor_edge = 2
let width_intern_edge = 2
let point_size_text = 12.
(* two tables for two types of edge :
successor_edges = edges with successor of root
intern_edges = edges between successors of root *)
let successor_edges = H2.create 97
let intern_edges = H2.create 97
(* table of all nodes *)
let nodes = H.create 97
(* GTK to hyperbolic coordinates *)
let to_turtle(x,y)=
let zx,zy as r = ((float x*.(2./.w) -. 1.),(1. -. float y *.(2./.h))) in
let zn = sqrt(zx*.zx +. zy*.zy) in
if zn > rlimit then
(rlimit*.zx/.zn, rlimit*.zy/.zn)
else
r
(* Hyperbolic to GTK coordinates *)
let from_turtle (x,y) =
let xzoom = (w/.2.)
and yzoom = (h/.2.) in
(truncate (x*.xzoom +. xzoom), truncate(yzoom -. y*.yzoom))
(* the middle of the screen used when init a graoh drawing *)
let start_point = to_turtle (truncate(w/.2.), truncate(h/.2.))
(* origine is a reference to the start point drawing for the graph in GTK coordinates *)
let origine = ref start_point
(* Current point in Hyperbolic view with an initialization in center of hyperbolic circle *)
let current_point = ref (0,0)
(* Change hyperbolic current point *)
let moveto_gtk x y = current_point := (x,y)
(* Change hyperbolic current point with turtle coordinates *)
let tmoveto_gtk turtle =
let (x,y)= from_turtle turtle.pos in
moveto_gtk x y
(* Create a turtle with origine's coordinates *)
let make_turtle_origine () =
let (x,y) = let (x,y) = !origine in (truncate x, truncate y) in
moveto_gtk x y;
make_turtle !origine 0.0
(* Append turtle coordinates to line, set current point and return the "new" line *)
let tlineto_gtk turtle line =
tmoveto_gtk turtle;
let (x,y) = !current_point in
List.append line [(float x); (float y) ]
(* Set line points for a distance with a number of steps,
set current point to last line's point, by side-effect of tlineto_gtk,
and return the final turtle *)
let set_successor_edge turtle distance steps line =
let d = distance /. (float steps) in
let rec list_points turtle liste = function
| 0 -> (turtle,liste)
| n ->let turt = advance turtle d in
list_points turt (tlineto_gtk turt liste) (n-1)
in
let start =
let (x,y) = from_turtle turtle.pos in [(float x); (float y)] in
let _,lpoints = list_points turtle start steps in
let points = Array.of_list lpoints in
line#set [`POINTS points]
type polaire = { radius : float; angle : float}
type cartesien = { x : float; y: float}
let pol_to_cart p =
{
x = p.radius *. (cos p.angle);
y = p.radius *. (sin p.angle)
}
let cart_to_pol p =
let radius = sqrt((p.x *. p.x) +.(p.y *. p.y)) in
{
radius = radius;
angle = 2. *. ath ((p.y /. radius) /. (1. +. p.x /. radius))
}
(* Set Bpath between turtles tv and tw where line is a gtk widget *)
let set_intern_edge tv tw bpath line =
let (x,y) = let (x ,y ) = from_turtle tv.pos in ((float_of_int x),(float_of_int y)) in
let (x',y') = let (x',y') = from_turtle tw.pos in ((float_of_int x'),(float_of_int y')) in
let rate = 1.95 in
GnomeCanvas.PathDef.reset bpath;
GnomeCanvas.PathDef.moveto bpath x y ;
GnomeCanvas.PathDef.curveto bpath ((x+. x')/.rate) ((y +. y')/.rate)
((x +.x')/.rate) ((y +. y')/.rate)
x' y';
line#set [`BPATH bpath]
(* Set ellipse coordinate to turtle's and set current point too *)
let tdraw_string_gtk v turtle =
let node,ellipse,texte = H.find nodes v in
tmoveto_gtk turtle;
let factor = (shrink_factor ((G.V.label v).turtle.pos)) in
let factor = if factor < 0.5 then 0.5 else factor in
let w = factor*. point_size_text in
texte#set [`SIZE_POINTS w ];
let w = texte#text_width in
let h = texte#text_height in
ellipse#set [ `X1 (-.( w+.8.)/.2.); `X2 ((w+.8.)/.2.);
`Y1 (-.( h+.6.)/.2.); `Y2 ((h+.6.)/.2.)];
let (x,y) = !current_point in
node#move ~x:(float x) ~y:(float y);
node#set [`X (float x); `Y (float y)];
node
let add_node canvas v =
let s = string_of_label v in
let node_group = GnoCanvas.group ~x:0.0 ~y:0.0 canvas in
let ellipse = GnoCanvas.ellipse
~props:[ `FILL_COLOR color_vertex ; `OUTLINE_COLOR "black" ;
`WIDTH_PIXELS 0 ] node_group
in
let texte = GnoCanvas.text ~props:[`X 0.0; `Y 0.0 ; `TEXT s;
`FILL_COLOR color_text] node_group
in
node_group#hide();
H.add nodes v (node_group,ellipse,texte)
let init_nodes canvas =
H.clear nodes;
G.iter_vertex (add_node canvas) !graph
(* change color for a vertex *)
let color_change_vertex item color n =
item#set [ `FILL_COLOR color ; `WIDTH_PIXELS n ]
(* change color for a successor edge *)
let color_change_intern_edge (line:GnoCanvas.bpath) color =
line#set [`OUTLINE_COLOR color]
(* change color for an intern edge *)
let color_change_successor_edge (line:GnoCanvas.line) color =
line#set [`FILL_COLOR color]
(* draws but don't show intern edges, and return a couple bpath (gtk_object), and line (gtw_widget)*)
let draw_intern_edge vw edge tv tw canvas =
let bpath,line =
try
let _,_ as pl = H2.find intern_edges vw in
pl
with Not_found ->
let bpath = GnomeCanvas.PathDef.new_path () in
let line = GnoCanvas.bpath canvas
~props:[ `BPATH bpath ; `WIDTH_PIXELS width_intern_edge ]
in
line#lower_to_bottom ();
H2.add intern_edges vw (bpath,line);
let v,w = vw in
if (is_selected w) || (is_selected v)
then edge.edge_mode <- Selected;
bpath,line
in
set_intern_edge tv tw bpath line;
bpath,line
let draw_successor_edge vw edge canvas =
let line =
try
H2.find successor_edges vw
with Not_found ->
let line = GnoCanvas.line canvas ~props:[ `FILL_COLOR color_successor_edge ;
`WIDTH_PIXELS width_successor_edge; `SMOOTH true]
in
line#lower_to_bottom ();
H2.add successor_edges vw line;
let v,w = vw in
if (is_selected w) || (is_selected v)
then edge.edge_mode <- Selected;
line
in
set_successor_edge edge.edge_turtle edge.edge_distance edge.edge_steps line;
line
(* set origine to new mouse position and return associated turtle *)
let motion_turtle item ev =
let bounds = item#parent#get_bounds in
let z1 = to_turtle(truncate((bounds.(0)+. bounds.(2))/.2.),
truncate((bounds.(1)+. bounds.(3))/.2.)) in
let z2 = to_turtle (truncate (GdkEvent.Motion.x ev),
truncate (GdkEvent.Motion.y ev)) in
let (x,y) = drag_origin !origine z1 z2 in
origine := (x,y);
make_turtle !origine 0.0
let hide_intern_edge vw =
try let _,line = H2.find intern_edges vw in line#hide () with Not_found -> ()
let hide_succesor_edge vw =
try let line = H2.find successor_edges vw in line#hide () with Not_found -> ()
(* graph drawing *)
let draw_graph _root canvas =
(* vertexes *)
G.iter_vertex
(fun v ->
let ( l : node_info) = G.V.label v in
if l.visible = Visible then
begin
let node = tdraw_string_gtk v l.turtle in
node#raise_to_top();
node#show();
let _,item,_=H.find nodes v in
match l.vertex_mode with
| Normal -> color_change_vertex item color_vertex 0;
| Selected -> color_change_vertex item color_selected_vertex 0;
| Focused -> color_change_vertex item color_focused_vertex 3;
| Selected_Focused -> color_change_vertex item color_selected_focused_vertex 3;
end
else
let node,_,_= H.find nodes v in
node#hide()
)
!graph;
(* edges *)
G.iter_edges_e
(fun e ->
let edge = G.E.label e in
let v = G.E.src e in
let w = G.E.dst e in
let vw = (v,w) in
if edge.visited
then
(* successor edge *)
begin
let line = draw_successor_edge vw edge canvas
in
begin
match edge.edge_mode with
| Normal -> color_change_successor_edge line color_successor_edge;
| Selected -> color_change_successor_edge line color_selected_successor_edge;
| Focused -> color_change_successor_edge line color_focused_successor_edge;
| Selected_Focused -> color_change_successor_edge line color_selected_focused_successor_edge;
end;
line#show ();
hide_intern_edge vw
end
else
(* intern edges *)
begin
hide_succesor_edge vw;
let labv = G.V.label v in
let labw = G.V.label w in
let turv = labv.turtle in
let turw = labw.turtle in
if labv.visible = Visible
&& labw.visible = Visible
&& v!=w
then begin
let _,line = draw_intern_edge vw edge turv turw canvas in
begin
match edge.edge_mode with
| Normal -> color_change_intern_edge line color_intern_edge;
| Selected -> color_change_intern_edge line color_selected_intern_edge;
| Focused -> color_change_intern_edge line color_focused_intern_edge;
| Selected_Focused -> color_change_intern_edge line color_selected_focused_intern_edge;
end;
line#show()
end else
hide_intern_edge vw
end)
!graph
let reset_display canvas =
init_nodes canvas
ocamlgraph-2.0.0/.ocp-indent 0000644 0001750 0000144 00000000007 13735627615 014247 0 ustar rt users normal
ocamlgraph-2.0.0/Makefile 0000644 0001750 0000144 00000000122 13735627615 013644 0 ustar rt users
all:
dune build
test:
dune runtest
doc:
dune build @doc
clean:
dune clean
ocamlgraph-2.0.0/view_graph/ 0000755 0001750 0000144 00000000000 13735627615 014344 5 ustar rt users ocamlgraph-2.0.0/view_graph/viewGraph.ml 0000644 0001750 0000144 00000000166 13735627615 016635 0 ustar rt users module ViewGraph = ViewGraph_core
module ViewGraph_select = ViewGraph_select
module ViewGraph_utils = ViewGraph_utils ocamlgraph-2.0.0/view_graph/viewGraph_test.ml 0000644 0001750 0000144 00000015242 13735627615 017675 0 ustar rt users (**************************************************************************)
(* *)
(* ViewGraph: a library to interact with graphs in ocaml and lablgtk2 *)
(* *)
(* Copyright (C) 2008 - Anne Pacalet *)
(* *)
(* 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, 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. *)
(* *)
(**************************************************************************)
(** This is only a test file to show how to use
* [ViewGraph] and [ViewGraph_select].
* Just compile and test... (click on the Help button to know how to use it).
*)
(* Nice tutorial at :
* http://plus.kaist.ac.kr/~shoh/ocaml/lablgtk2/lablgtk2-tutorial/book1.html
* See also examples in :
* /usr/share/doc/lablgtk-2.6.0/examples/canvas/
*)
(** To test to callbacks : only print messages *)
module CbTest = struct
(** need nothing for this test, but usually contains at least the graph... *)
type t_env = unit
let button_one_press_on_graph _env =
Format.printf "[CbTest] button_one_press_on_graph @."
let button_two_press_on_graph _env =
Format.printf "[CbTest] button_two_press_on_graph @."
let button_three_press_on_graph _env =
Format.printf "[CbTest] button_three_press_on_graph @."
let button_one_press_on_node _env n =
Format.printf "[CbTest] button_one_press_on_node %s@."
(ViewGraph.get_id n)
let button_two_press_on_node _env n =
Format.printf "[CbTest] button_two_press_on_node %s@."
(ViewGraph.get_id n)
let button_three_press_on_node _env n =
Format.printf "[CbTest] button_three_press_on_node %s@."
(ViewGraph.get_id n)
let enter_node _env n =
Format.printf "[CbTest] enter_node %s@." (ViewGraph.get_id n)
let leave_node _env n =
Format.printf "[CbTest] leave_node %s@." (ViewGraph.get_id n)
end
module V = ViewGraph_select.VG (CbTest)
let open_file select_init_env file =
try
let env = () in
let _graph = V.open_dot_file env select_init_env file in
()
with ViewGraph.DotError cmd ->
GToolbox.message_box "Error"
(Printf.sprintf
"%s failed\nDidn't succed to build graph for %s\nSorry !" cmd file)
let open_cb select_init_env () =
match GToolbox.select_file ~title:"Select a dot file" () with
| None -> ()
| Some filename -> open_file select_init_env filename
let help_act_cb _ac = ViewGraph_select.show_help ()
let error_act_cb ac =
GToolbox.message_box "Error"
(Printf.sprintf "Action '%s' activated : no callback ?\n" ac#name)
let quit_cb () = GMain.Main.quit ()
let quit_act_cb _a = quit_cb ()
let menu_desc = "\
\
\
\
\
\
\
\
\
\
\
"
let create_menu () =
let ui_m = GAction.ui_manager () in
let actions = GAction.action_group ~name:"Actions" () in
GAction.add_actions actions [
GAction.add_action "FileMenu" ~label:"File" ;
GAction.add_action "Open" ~label:"Open" ~accel:"o"
(* callback connected later *);
GAction.add_action "Quit" ~label:"Quit" ~accel:"q" ~callback:quit_act_cb;
GAction.add_action "HelpMenu" ~label:"Help" ;
GAction.add_action "Help" ~label:"Help" ~accel:"h" ~callback:help_act_cb;
];
ui_m#insert_action_group actions 0 ;
let _ = ui_m#add_ui_from_string menu_desc in
let help_item = ui_m#get_widget "/MenuBar/HelpMenu" in
let help_item = GtkMenu.MenuItem.cast help_item#as_widget in
GtkMenu.MenuItem.set_right_justified help_item true ;
ui_m
(*
let create_menu2 packing open_cb =
let file_item = GMenu.menu_item ~label:"File" ~packing () in
let file_menu = GMenu.menu () in
let item = GMenu.menu_item ~label:"Open" ~packing:file_menu#append () in
let _ = item#connect#activate ~callback:open_cb in
let item = GMenu.menu_item ~label:"Quit" ~packing:file_menu#append () in
let _ = item#connect#activate ~callback:GMain.Main.quit in
let _ = file_item#set_submenu file_menu in
let help_item = GMenu.menu_item ~label:"Help"
~right_justified:true ~packing () in
let help_menu = GMenu.menu () in
let item = GMenu.menu_item ~label:"Help about ViewGraph"
~packing:help_menu#append () in
let _ = item#connect#activate ~callback:ViewGraph_select.show_help in
let _ = help_item#set_submenu help_menu in
()
*)
let create_gui () =
let window = GWindow.window ~title:"ViewGraph"
~allow_shrink:true ~allow_grow:true () in
let vbox = GPack.vbox ~border_width:4 ~spacing:4 ~packing:window#add () in
let ui_m = create_menu () in
window#add_accel_group ui_m#get_accel_group ;
vbox#pack ~expand:false (ui_m#get_widget "/MenuBar") ;
let frame = GBin.frame ~label:"How to use this :" ~packing:vbox#pack () in
let _ = GMisc.label ~text:"\n Open the Help window to know more...\n"
~packing:frame#add () in
let pack = vbox#pack ~expand:true ~fill:true in
let canvas = ViewGraph_utils.create_scrolled_canvas pack in
let hbox = GPack.hbox ~spacing:4 ~packing:vbox#pack () in
let select_init_env =
ViewGraph_select.init ViewGraph_select.default_options
canvas (hbox#pack ~expand:true ~fill:true) in
let actions = match ui_m#get_action_groups with
| a::[] -> a | _ -> assert false
in
let open_action = actions#get_action "Open" in
let _ = open_action#connect#activate ~callback:(open_cb select_init_env) in
let _ = window#connect#destroy ~callback:quit_cb in
let _ = window#show () in
(canvas, select_init_env)
let main () =
let _ = GMain.Main.init () in
let canvas, select_init_env = create_gui () in
if Array.length Sys.argv = 2 then
open_file select_init_env Sys.argv.(1);
GMain.Main.main ()
let _ = Printexc.print main ()
ocamlgraph-2.0.0/view_graph/viewGraph_select.mli 0000644 0001750 0000144 00000004553 13735627615 020351 0 ustar rt users (**************************************************************************)
(* *)
(* ViewGraph: a library to interact with graphs in ocaml and lablgtk2 *)
(* *)
(* Copyright (C) 2008 - Anne Pacalet *)
(* *)
(* 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, 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. *)
(* *)
(**************************************************************************)
(** This module can be used to add some selection feature to {!ViewGraph}.
* See {!ViewGraph_test} to see how to use it.
* *)
(** object returned by [init] and used by [open_dot_file] *)
type t_env
type t_options = {
sel_1_color : string; (** color of the selected node (default "red") *)
sel_2_color : string; (** color of the selected neighbour (default "green") *)
center_node_when_selected :bool;
(** automatically center a node when it is selected (default true) *)
}
(** some default values for the options.
* It is a good idea to use it and overwrite the one that have to be changed,
* just in case some more options appear *)
val default_options : t_options
(** should be called only once because it creates widgets.
* The packing function is the place to put the messages about selection.
*)
val init : t_options -> GnoCanvas.canvas -> (GObj.widget -> unit) -> t_env
(** functor to instanciate with your callbacks *)
module VG (UserCb : ViewGraph_core.SigCb) : sig
val open_dot_file : UserCb.t_env -> t_env ->
?dot_cmd:string -> string -> ViewGraph_core.t_graph
end
(** Popup a message window with some help. *)
val show_help : unit -> unit
ocamlgraph-2.0.0/view_graph/README 0000644 0001750 0000144 00000000730 13735627615 015224 0 ustar rt users ======================================================
ViewGraph is now deprecated. Prefer to use dgraph now.
======================================================
ViewGraph is a small ocaml library that helps to view a graph from a dot file
in a Lablgtk canvas, and interact with it.
To have more information :
make doc
and browse the documentation starting from doc/index.html
You can also compile the test file, and try to use it :
make; ./viewgraph file.dot
ocamlgraph-2.0.0/view_graph/viewGraph_utils.mli 0000644 0001750 0000144 00000002636 13735627615 020232 0 ustar rt users (**************************************************************************)
(* *)
(* ViewGraph: a library to interact with graphs in ocaml and lablgtk2 *)
(* *)
(* Copyright (C) 2008 - Anne Pacalet *)
(* *)
(* 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, 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. *)
(* *)
(**************************************************************************)
(** This file provide useful function to build windows to put the graph *)
val create_scrolled_canvas : (GObj.widget -> unit) -> GnoCanvas.canvas
val create_graph_win : string -> ViewGraph_select.t_env
ocamlgraph-2.0.0/view_graph/viewGraph_select.ml 0000644 0001750 0000144 00000031123 13735627615 020171 0 ustar rt users (**************************************************************************)
(* *)
(* ViewGraph: a library to interact with graphs in ocaml and lablgtk2 *)
(* *)
(* Copyright (C) 2008 - Anne Pacalet *)
(* *)
(* 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, 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. *)
(* *)
(**************************************************************************)
(** This module can be used to add some selection feature to [ViewGraph].
* see [show_help] for more details. *)
(** To manage the lists of neighbours of the selected node.
* The type [t] is made of a boolean [b] and 3 lists [(l1, l2, l3)].
* [b] tells is [l1] is a list of predecessors (vs. successors).
* [l3] has the same 'kind' than [l1], and [l2] the other.
* [l1] cannot be empty, except if the 3 lists are empty.
* The first node of [l1] is the currently selected neighbour.
* When we go to the next one, [n] is removed and appended to [l3] tail.
* If [l1] is then empty, [l2] becomes the first list, and [b] is changed. *)
module CircLists = struct
type t_elem = ViewGraph_core.t_node
type t_lists = t_elem list * t_elem list * t_elem list
type t = bool * t_lists
let mk (l1, l2) = match l1, l2 with
| [], [] -> true, ([], [], [])
| [], l2 -> false, (l2, [], [])
| l1, l2 -> true, (l1, l2, [])
let current_node lists = match lists with
| _, ( [] , _, _) -> None
| b, (n::_, _, _) -> Some (b, n)
let go_next lists =
let lists = match lists with
| _, ([], [], []) -> lists
| _, ([], _, _) ->
assert false (* l1 cannot be empty, except if every lists are *)
| b, (n::[], [], l3) -> b, (l3 @ [n], [], [])
| b, (n::[], l2, l3) -> not b, (l2, l3 @ [n], [])
| b, (n::l1, l2, l3) -> b, (l1, l2, l3 @ [n])
in lists
let goto_n ((_, (l1, l2, l3)) as lists) n =
let max = List.length l1 + List.length l2 + List.length l3 in
let rec find nb_iter lists =
match current_node lists with
| None -> raise Not_found
| Some (_, cur_n) ->
if cur_n = n then lists
else if nb_iter >= 0 then
find (nb_iter - 1) (go_next lists)
else raise Not_found
in find max lists
end
type t_options = {
sel_1_color : string;
sel_2_color : string;
center_node_when_selected :bool;
}
let default_options = {
sel_1_color = "red";
sel_2_color = "green";
center_node_when_selected = true;
}
(** Some widgets, useful for the selection. *)
type t_widgets = {
canvas : GnoCanvas.canvas;
sel_1_txt : GMisc.label;
sel_edge_txt : GMisc.label;
sel_2_txt : GMisc.label;
}
type t_state = {
w : t_widgets;
opt : t_options;
mutable graph : ViewGraph_core.t_graph option ;
mutable ppu : float ;
mutable selected : ViewGraph_core.t_node option ;
mutable neighbours : CircLists.t option;
mutable gui_sel : (ViewGraph_core.t_gtk_obj option) array;
}
type t_env = t_state
(* horrible zoom : probably to be changed ! *)
let change_zoom state delta =
state.ppu <- state.ppu +. delta;
state.w.canvas#set_pixels_per_unit state.ppu
let center_selected_node state =
match state.selected with
| None -> ()
| Some n -> match ViewGraph_core.get_coord n with
| None -> ()
| Some ((x1, y1), (x2, y2)) ->
let canvas = state.w.canvas in
let x = x1 +. (x2 -. x1) /. 2. in
let y = y1 +. (y2 -. y1) /. 2. in
(* Format.printf "want to see = %f x %f@." x y; *)
let w = canvas#hadjustment#page_size in
let h = canvas#vadjustment#page_size in
(* Format.printf "page_size = %f x %f@." w h; *)
let sx = x -. (w /. 2.) in
let sy = y -. (h /. 2.) in
(* Format.printf "scroll to = %f x %f (world) @." sx sy; *)
let sx, sy = canvas#w2c ~wx:sx ~wy:sy in
(* this is to handle zoom factor *)
(* Format.printf "scroll to = %d x %d (canvas) @." sx sy; *)
canvas#scroll_to ~x:sx ~y:sy
let key_press state ev =
let canvas = state.w.canvas in
let (x, y) = canvas#get_scroll_offsets in
match GdkEvent.Key.keyval ev with
| k when k = GdkKeysyms._Up -> canvas#scroll_to ~x ~y:(y-20) ; true
| k when k = GdkKeysyms._Down -> canvas#scroll_to ~x ~y:(y+20) ; true
| k when k = GdkKeysyms._Left -> canvas#scroll_to ~x:(x-10) ~y ; true
| k when k = GdkKeysyms._Right -> canvas#scroll_to ~x:(x+10) ~y ; true
| k when k = GdkKeysyms._Page_Down -> change_zoom state 0.1; true
| k when k = GdkKeysyms._Page_Up -> change_zoom state (-0.1); true
| k when k = GdkKeysyms._Home -> center_selected_node state; true
| _ -> false
let init options (canvas : GnoCanvas.canvas) pack_txt =
let _ = GMisc.label ~text:"Selected : " ~packing:pack_txt () in
let sel_1_txt = GMisc.label ~packing:pack_txt () in
let sel_edge_txt = GMisc.label ~packing:pack_txt () in
let sel_2_txt = GMisc.label ~packing:pack_txt () in
let w = { canvas = canvas;
sel_1_txt = sel_1_txt; sel_edge_txt = sel_edge_txt;
sel_2_txt = sel_2_txt } in
let state =
{ w = w; opt = options; gui_sel = [| None; None |] ;
graph = None ; ppu = 1.; selected = None; neighbours = None } in
let _ = canvas#event#connect#after#key_press ~callback:(key_press state) in
state
let sel_1_bitmap () = Gdk.Bitmap.create_from_data ~width:2 ~height:2 "\002\001"
let sel_2_bitmap () = Gdk.Bitmap.create_from_data ~width:2 ~height:2 "\002\001"
(* we have to put some color on item in order to be able to get their events,
* so let's cheat and add a bitmap with 0 every where... *)
let no_bitmap () = Gdk.Bitmap.create_from_data ~width:1 ~height:1 "\000"
let move_selection state n_opt1 n_opt2 =
let set_props o col bitmap = match o with None -> ()
| Some o -> o#set [ `FILL_COLOR col ; `FILL_STIPPLE bitmap]
in
let n_obj n_opt = match n_opt with
| None -> None
| Some n -> ViewGraph_core.get_obj n
in
let obj1 = n_obj n_opt1 in
let obj2 = n_obj n_opt2 in
let reset_old i = set_props state.gui_sel.(i) "black" (no_bitmap()) in
reset_old 0; reset_old 1;
state.gui_sel.(0) <- obj1; state.gui_sel.(1) <- obj2;
set_props obj1 state.opt.sel_1_color (sel_1_bitmap()) ;
set_props obj2 state.opt.sel_2_color (sel_2_bitmap())
let show_selection state =
let n_opt, txt1, txt2, txt3 = match state.selected with
| None -> None, "(none)", "", ""
| Some n ->
let txt1 = ViewGraph_core.get_id n in
let n_opt, txt2, txt3 = match state.neighbours with
| None -> None, "", ""
| Some info ->
match CircLists.current_node info with
| None -> None, " --- ", "(none)"
| Some (pred_first, n) ->
let txt2 = if pred_first then " <-- " else " --> " in
Some n, txt2, ViewGraph_core.get_id n
in n_opt, txt1, txt2, txt3
in
state.w.sel_1_txt#set_text txt1;
state.w.sel_edge_txt#set_text txt2;
state.w.sel_2_txt#set_text txt3;
move_selection state state.selected n_opt;
if state.opt.center_node_when_selected then
center_selected_node state
let select_node state n_opt =
state.selected <- n_opt;
state.neighbours <- None;
show_selection state
let select_neighbour state =
match state.graph with None -> ()
| Some graph ->
match state.selected with None -> ()
| Some n ->
let new_info =
match state.neighbours with
| None ->
let neighbours = ViewGraph_core.get_neighbours graph n in
CircLists.mk neighbours
| Some info -> CircLists.go_next info
in
state.neighbours <- Some (new_info);
show_selection state
let goto_neighbour state =
match state.graph with None -> ()
| Some graph ->
match state.neighbours with
| None -> ()
| Some info -> match CircLists.current_node info with
| None -> ()
| Some (_, n) ->
match state.selected with
| None ->
(* neighbours without selected node ? Impossible... *)
assert false
| Some old_n ->
state.selected <- Some n;
let neighbours = ViewGraph_core.get_neighbours graph n in
let neighbours = CircLists.mk neighbours in
let neighbours = CircLists.goto_n neighbours old_n in
state.neighbours <- Some neighbours;
show_selection state
let clear_state state =
state.graph <- None;
state.ppu <- 1.;
state.selected <- None;
state.neighbours <- None;
state.gui_sel <- [| None; None |];
show_selection state
module SelectCb (UserCb : ViewGraph_core.SigCb) = struct
type t_env = UserCb.t_env * t_state
let button_one_press_on_graph (u_env, state) =
select_node state None;
UserCb.button_one_press_on_graph (u_env)
let button_two_press_on_graph (u_env, state) =
select_neighbour state;
UserCb.button_two_press_on_graph (u_env)
let button_three_press_on_graph (u_env, state) =
goto_neighbour state;
UserCb.button_three_press_on_graph (u_env)
let button_one_press_on_node (u_env, state) n =
select_node state (Some n);
UserCb.button_one_press_on_node (u_env) n
let button_two_press_on_node ((u_env, _state) as env) n =
button_two_press_on_graph env;
UserCb.button_two_press_on_node (u_env) n
let button_three_press_on_node ((u_env, _state) as env) n =
button_three_press_on_graph env;
UserCb.button_three_press_on_node (u_env) n
let enter_node (u_env, _state) n =
begin match ViewGraph_core.get_obj n with None -> assert false
| Some n_item -> n_item#set [`OUTLINE_COLOR "red"]
end;
UserCb.enter_node (u_env) n
let leave_node (u_env, _state) n =
begin match ViewGraph_core.get_obj n with None -> assert false
| Some n_item -> n_item#set [`NO_OUTLINE_COLOR]
end;
UserCb.leave_node (u_env) n
end
module VG (UserCb : ViewGraph_core.SigCb) = struct
module Cb = SelectCb (UserCb)
module V = ViewGraph_core.M (Cb)
let open_dot_file u_env state ?(dot_cmd="dot") file =
let canvas = state.w.canvas in
(match state.graph with None -> () | Some g -> V.clear canvas g);
let _ = clear_state state in
let env = (u_env, state) in
let graph = V.open_dot_file env canvas ~dot_cmd file in
state.graph <- Some graph;
graph
end
let show_help () =
GToolbox.message_box ~title:"Help"
"Selection :\n
- use the mouse button-1 to select a node : \
it should turn red and (optionally) be centered.
- when a node is selected, button-2 selects one of its neighbour : \
it should turn green.
- using button-2 again selects the next neighbour, and so on.
- when a neighbour is selected, button-3 makes it the selected node,
and the previously selected node become the selected neighbour,
so pressing the button-3 again brings back to it.
- button-1 outside a node deselect everything.
Have a look at the bottom line to see the selection.
Moving arround :\n
- the scrollbars, as well as the arrows, can be used to move in the window.
- the Page-Up and Page-Down keys can be used to zoom \
(ugly zoom at the moment !).
- the Home key centers the selected node in the window.
"
ocamlgraph-2.0.0/view_graph/viewGraph_core.ml 0000644 0001750 0000144 00000026460 13735627615 017652 0 ustar rt users (**************************************************************************)
(* *)
(* ViewGraph: a library to interact with graphs in ocaml and lablgtk2 *)
(* *)
(* Copyright (C) 2008 - Anne Pacalet *)
(* *)
(* 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, 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. *)
(* *)
(**************************************************************************)
(** ViewGraph : a library to view .dot graphs and interact with the GUI.
*)
(** This is Ocamlgraph library : see http://ocamlgraph.lri.fr/doc/ *)
open Graph
exception DotError of string
type t_point = float * float
type t_coord = t_point * t_point
type t_shape = Srect | Sellipse (* TODO : add some more ! *)
type t_gtk_obj = GnomeCanvas.re_p GnoCanvas.item
module Node = struct
type t = string * (t_shape * t_coord * t_gtk_obj) option
let id n = fst n
let coord n = match snd n with None -> None
| Some (_, c, _) -> Some c
let item n = match snd n with None -> None
| Some (_, _, r) -> Some r
end
module G = Imperative.Digraph.Abstract(Node)
module B = Builder.I(G)
type t_graph = B.G.t * GnoCanvas.pixbuf
type t_node = B.G.V.t
let get_graph g = fst g
let get_pixbuf g = snd g
let get_node_info n = B.G.V.label n
let get_coord n = Node.coord (get_node_info n)
let get_id n = Node.id (get_node_info n)
let get_obj n = Node.item (get_node_info n)
(** find the attributes [pos], [width] and [height] in the attribute list *)
let get_info attr_list_list =
let get (shp, p,w,h) (attr, val_opt) = match attr, val_opt with
| (Dot_ast.Ident "shape"), Some (Dot_ast.String s) ->
(* Format.printf "found pos = %s@." s; *)
(Some s), p, w, h
| (Dot_ast.Ident "pos"), Some (Dot_ast.String s) ->
(* Format.printf "found pos = %s@." s; *)
shp, (Some s), w, h
| (Dot_ast.Ident "width"), Some (Dot_ast.String s) ->
(* Format.printf "found width = %s@." s; *)
shp, p, (Some s), h
| (Dot_ast.Ident "height"), Some (Dot_ast.String s) ->
(* Format.printf "found height = %s@." s; *)
shp, p, w, (Some s)
| (Dot_ast.Ident _), Some (Dot_ast.String _) ->
(* Format.printf "found %s = %s -> ignored@." id s; *)
(shp, p, w, h)
| _ -> (shp, p,w,h)
in
let get acc attr_list =
(* Format.printf "%d attr in attr_list@." (List.length attr_list); *)
List.fold_left get acc attr_list in
(*Format.printf "%d lists in attr_list_list@." (List.length attr_list_list); *)
List.fold_left get (None, None, None, None) attr_list_list
(** Translate the information given by dot
* into the coordinate of a rectangle in the png image.
* see http://www.graphviz.org/mywiki/FaqCoordTransformation
* to understand the [pad] and [factor] variables.
* @param pos position of the center of the node, in points.
* @param w width of the node, in inch.
* @param h height of the node, in inch.
*)
let compute_coord pos w h =
let dot_ppi = 72. (* number of pixels per inch on a display device *) in
let dot_png_ppi = 96. (* number of pixels per inch on a display device *) in
try
let w = float_of_string w in
let h = float_of_string h in
let x,y = Scanf.sscanf pos "%d,%d" (fun x y -> (x,y)) in
let pad = 4 in
let x = float_of_int (x + pad) in
let y = float_of_int (y + pad) in
let dx = w *. dot_ppi /. 2. in
let dy = h *. dot_ppi /. 2. in
let x1 = x -. dx in
let y1 = y -. dy in
let x2 = x +. dx in
let y2 = y +. dy in
let factor = dot_png_ppi /. dot_ppi in
let x1 = x1 *. factor in
let y1 = y1 *. factor in
let x2 = x2 *. factor in
let y2 = y2 *. factor in
(* Format.printf "compute_coord -> x1=%f y1=%f x2=%f y2=%f@."
x1 y1 x2 y2; *)
Some ((x1,y1),(x2,y2))
with e ->
let s = Printexc.to_string e in
Format.printf "compute_coord failled : %s@." s;
None
module DotParser (C : sig val mk_node : t_shape -> t_coord -> t_gtk_obj end) =
Dot.Parse
(B)
(struct
let node (id,_) attr_list =
let name = match id with
| Dot_ast.Ident s
| Dot_ast.Number s
| Dot_ast.String s
| Dot_ast.Html s -> s
in
let info = match get_info attr_list with
| shp, Some pos, Some w, Some h ->
let shp = match shp with
| Some "ellipse" -> Sellipse
| Some "box" -> Srect
| Some _ -> Srect
| None -> Sellipse (* default shape *)
in
begin match compute_coord pos w h with
| None -> None
| Some coord ->
let n_obj = C.mk_node shp coord in
Some (shp, coord, n_obj)
end
| _ -> Format.printf "info KO for %s@." name; None
in (name, info)
let edge _ = ()
end)
(** Call [dot] to build the graph image in a [png] file *)
let png_graph_image dot_cmd dot_file png_file =
let cmd = Printf.sprintf "%s -T png %s > %s" dot_cmd dot_file png_file in
match Sys.command cmd with
| 0 -> png_file
| _ -> raise (DotError cmd)
(** Call 'dot' on the [dot_file] to get a file with position information,
* and also to have a [png] image of the graph.
* Then parse the annotated file to get the graph with the nodes coordinates.
* @return the graph and the pgn filename.
* *)
let build_graph dot_cmd dot_file annot_dot_file mk_node_item =
let cmd = Printf.sprintf "%s -y %s > %s " dot_cmd dot_file annot_dot_file in
match Sys.command cmd with
| 0 ->
let module Parser =
DotParser (struct let mk_node = mk_node_item end) in
let graph = Parser.parse annot_dot_file in
graph
| _ -> raise (DotError cmd)
(** @return 2 lists : the predecessors and successors of the node*)
let get_neighbours graph n =
let graph = get_graph graph in
let preds = B.G.pred graph n in
let succs = B.G.succ graph n in
(preds, succs)
(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
module type SigCb = sig
type t_env
val button_one_press_on_graph : t_env -> unit
val button_two_press_on_graph : t_env -> unit
val button_three_press_on_graph : t_env -> unit
val button_one_press_on_node : t_env -> t_node -> unit
val button_two_press_on_node : t_env -> t_node -> unit
val button_three_press_on_node : t_env -> t_node -> unit
val enter_node : t_env -> t_node -> unit
val leave_node : t_env -> t_node -> unit
end
module EmptyCb = struct
type t_env = unit
let button_one_press_on_graph _env = ()
let button_two_press_on_graph _env = ()
let button_three_press_on_graph _env = ()
let button_one_press_on_node _env _n = ()
let button_two_press_on_node _env _n = ()
let button_three_press_on_node _env _n = ()
let enter_node _env _n = ()
let leave_node _env _n = ()
end
module M (Cb : SigCb) = struct
let mk_node_item canvas shp ((x1,y1),(x2,y2)) =
(* we have to put some color on item in order to be able to get their events,
* so let's cheat and add a bitmap with 0 every where... *)
let no_color = [
`FILL_COLOR "black" ;
`FILL_STIPPLE (Gdk.Bitmap.create_from_data ~width:1 ~height:1 "\000")
] in
let props = [ `X1 x1; `Y1 y1; `X2 x2; `Y2 y2] @ no_color in
let n_obj = match shp with
| Srect -> GnoCanvas.rect canvas#root ~props
| Sellipse -> GnoCanvas.ellipse canvas#root ~props
in n_obj
let graph_event env ev =
begin match ev with
| `BUTTON_PRESS ev ->
begin
(* let state = GdkEvent.Button.state ev in *)
match GdkEvent.Button.button ev with
(* | 1 when Gdk.Convert.test_modifier `SHIFT state ->
| 1 when Gdk.Convert.test_modifier `CONTROL state ->
let (x, y) =
canvas#w2c_d (GdkEvent.Button.x ev) (GdkEvent.Button.y ev) in
*)
| 1 -> Cb.button_one_press_on_graph env
| 2 -> Cb.button_two_press_on_graph env
| 3 -> Cb.button_three_press_on_graph env
| _ -> ()
end
| _ -> ()
end ; false
let node_event env node ev =
begin match ev with
| `ENTER_NOTIFY _ -> Cb.enter_node env node
| `LEAVE_NOTIFY _ -> Cb.leave_node env node
| `BUTTON_PRESS ev ->
begin match GdkEvent.Button.button ev with
| 1 -> Cb.button_one_press_on_node env node
| 2 -> Cb.button_two_press_on_node env node
| 3 -> Cb.button_three_press_on_node env node
| _ -> ()
end
| _ -> ()
end ;
false
(** for each node that has an item, connect the events *)
let add_node_items env graph =
let do_it n =
match get_obj n with
| None -> ()
| Some n_rect -> ignore (n_rect#connect#event ~callback:(node_event env n))
in B.G.iter_vertex do_it graph
let remove_node_items graph =
let do_it n =
match get_obj n with
| None -> ()
| Some n_rect -> n_rect#destroy ()
in B.G.iter_vertex do_it graph
let install_image (canvas :GnoCanvas.canvas) png_file =
let im = GdkPixbuf.from_file png_file in
(*let im = GdkPixbuf.add_alpha ~transparent:(0xff, 0xff, 0xff) im in*)
let w = GdkPixbuf.get_width im in
let h = GdkPixbuf.get_height im in
(* Format.printf "GnoCanvas.pixbuf size = %dx%d@." w h; *)
let _ = canvas#set_scroll_region ~x1:0. ~y1:0. ~x2:(float w) ~y2:(float h) in
let px = GnoCanvas.pixbuf ~x:0. ~y:0. ~pixbuf:im canvas#root in
px
let open_dot_file env (canvas :GnoCanvas.canvas) ?(dot_cmd="dot") dot_file =
let basename = try Filename.chop_extension dot_file
with Invalid_argument _ -> dot_file in
let png_file = Printf.sprintf "%s.png" basename in
let annot_dot_file = Printf.sprintf "%s_annot" dot_file in
let graph =
build_graph dot_cmd dot_file annot_dot_file (mk_node_item canvas) in
(* TODO : it would be better not to recompute the layout,
* ie. use annot_dot_file instead of dot_file,
* but it seems that it doesn't work properly...
* It is ok for 'simple' graphs like unix.dot,
* but not on crazy.dot for instance. What goes wrong ?
* Anyway, it would be better to build GTK objects instead of a png image !
* *)
let png_file = png_graph_image dot_cmd dot_file png_file in
let pixbuf = install_image canvas png_file in
let _ = pixbuf#connect#event ~callback:(graph_event env) in
let _ = add_node_items env graph in
let _ = pixbuf#lower_to_bottom () in
(graph, pixbuf)
let clear _canvas graph =
(* TODO : remove pixbuf from _canvas ? *)
let pixbuf = get_pixbuf graph in pixbuf#destroy ();
let graph = get_graph graph in remove_node_items graph
end
ocamlgraph-2.0.0/view_graph/doc/ 0000755 0001750 0000144 00000000000 13735627615 015111 5 ustar rt users ocamlgraph-2.0.0/view_graph/doc/style.css 0000644 0001750 0000144 00000003501 13735627615 016762 0 ustar rt users .typetable {
border-style : hidden
}
.indextable {
border-style : hidden
}
.paramstable {
border-style : hidden ;
padding: 5pt 5pt
}
body {
background-color : white
font-family: Lucida,Times,serif;
margin-left: 2em;
margin-right: 1em;
}
td.typefieldcomment {
background-color : white
font-size: smaller ;
}
pre {
margin-bottom: 2px;
}
pre, code {
font-family: terminal,"courier new",monospace;
font-size: 10pt;
}
div.sig_block {
margin-left: 2em
}
.keyword {
font-weight : bold ;
color : fuchsia;
}
.keywordsign {
color : #C04600
}
.superscript {
font-size : 4
}
.subscript {
font-size : 4
}
.comment {
color : Green
}
.constructor {
color : Blue
}
.type {
color : #5C6585
}
.string {
color : Maroon
}
.warning {
color : Red ;
font-weight : bold
}
.info {
margin-left : 3em;
margin-right : 3em
}
.param_info {
margin-top: 4px;
margin-left : 3em;
margin-right : 3em
}
.code {
color : #465F91 ;
}
a .code {
color : #416DFF;
}
a:link {
color : #416DFF;
text-decoration : none;
}
a:visited {
color : #416DFF;
text-decoration : none;
}
a:hover {
color : fuchsia;
text-decoration : none;
background-color: #CCE8FE;
}
a:active {
color : fuchsia;
text-decoration : underline;
}
h1 {
font-size : 30 ;
text-align: center;
}
h2 {
background-color: #1E90FF ;
font-size : 25 ;
border: 1px solid #000000;
margin-top: 2ex;
margin-bottom: 1ex;
margin-left: -1ex;
margin-right: -1ex;
text-align: center;
padding: 2px;
}
h3 {
background-color: #00CFFF ;
font-size : 18 ;
border: 1px solid #000000;
margin-top: 5px;
margin-bottom: 2px;
margin-left: 0;
margin-right: 0;
text-align: center;
padding: 2px;
}
h4 {
font-size : 18 ;
margin-top: 1ex;
margin-bottom: 1ex;
}
ul {
margin:0;
list-style-type: square;
}
ul ul {
list-style-type: disc;
}
ocamlgraph-2.0.0/view_graph/doc/intro.txt 0000644 0001750 0000144 00000005153 13735627615 017011 0 ustar rt users {1 ViewGraph}
{2 Presentation}
ViewGraph is a small {{:http://caml.inria.fr/ocaml/}ocaml} library
that helps to view a graph from a dot file
in a Lablgtk canvas, and interact with it.
It reads dot files and uses the dot tool for the layout of the nodes.
You can have a look to {{:http://www.graphviz.org/}Graphviz}
to know more about the dot tool and file format.
It also uses the {{:http://caml.inria.fr/ocaml/}ocaml}
graph library {{:http://ocamlgraph.lri.fr/}ocamlgraph}.
It is composed of the {{:index_modules.html}modules}:
- {!module:ViewGraph} : which is the main part and that can be used alone
to parse a file, generate an image of the graph
and add some user defined callbacks to interact with it,
- {!module:ViewGraph_select} : which can be used to add selection features
in addition to user callbacks,
- {!module:ViewGraph_test} : which is not really part of the library
but that creates a small gui to show how to use the 2 other modules.
To know more about it, the best thing to do is to compile
and test :
- [make]
- [./viewgraph file.dot]
If you don't have any dot file, you can for instance use some examples from
{{:http://www.graphviz.org/Gallery.php}graphviz gallery}
but please remove the size attibutes (they are not handdled yet : see below)
Notice also that if you are already using
{{:http://ocamlgraph.lri.fr/}ocamlgraph} to build some graphs,
it is quite easy to generate dot files by using
{{:http://ocamlgraph.lri.fr/doc/Graphviz.html}Graph.Graphviz.Dot}.
{2 Some more things TODO}
- some of the dot format attributes are not handled
(size and ratio for instance)
- the zoom feature is very ugly at the moment !
- as we call 'dot' once for the image and another time for annotations,
the layout is computed twice. That can be a problem for big graphs.
- instead of using PNG images from dot, we could generate the GTK objects,
and the zoom problem would be solved. This requires a lot of work,
but we hope to do it soon !
- add something to find a node by its name
- ... and more...
{2 More links}
- GTK :
{ul {- all the {{:http://library.gnome.org/devel/gtk/stable/}widgets}
Reference Manual}
{- the
{{:http://library.gnome.org/devel/libgnomecanvas/stable/}GnomeCanvas}
Library Reference Manual}
}
- Lablgtk :
{ul{- ocamldoc
{{:http://plus.kaist.ac.kr/~shoh/ocaml/lablgtk2/lablgtk-2.4.0/doc/html/index.html}
reference} with links on GTK reference,}
{- an excellent
{{:http://plus.kaist.ac.kr/~shoh/english/ocaml/lablgtk2/lablgtk2-tutorial/index.html}tutorial} fo those (like me) who don't know GTK.}
}
- Author : {{:http://www-sop.inria.fr/everest/personnel/Anne.Pacalet/}Anne
Pacalet}
ocamlgraph-2.0.0/view_graph/dune 0000644 0001750 0000144 00000000370 13735627615 015222 0 ustar rt users (library
(name viewGraph)
(wrapped false)
(modules :standard \ viewGraph_test)
(libraries ocamlgraph lablgtk2 lablgtk2.gnomecanvas))
(executable
(name viewGraph_test)
(modules viewGraph_test)
(libraries viewGraph)
(flags -open ViewGraph))
ocamlgraph-2.0.0/view_graph/viewGraph_utils.ml 0000644 0001750 0000144 00000005666 13735627615 020067 0 ustar rt users (**************************************************************************)
(* *)
(* ViewGraph: a library to interact with graphs in ocaml and lablgtk2 *)
(* *)
(* Copyright (C) 2008 - Anne Pacalet *)
(* *)
(* 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, 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. *)
(* *)
(**************************************************************************)
(** This file provide useful function to build windows to put the graph *)
let create_scrolled_canvas packing =
let frame = GBin.frame ~shadow_type:`IN () in
let canvas =
let aa = false (* anti-aliasing *) in
GnoCanvas.canvas ~aa ~width:600 ~height:400 ~packing:frame#add ()
in
let _ = canvas#set_center_scroll_region true in
(* if the graph is too big, show its center *)
let table = GPack.table ~packing
~rows:2 ~columns:2 ~row_spacings:4 ~col_spacings:4 () in
let _ = table#attach ~left:0 ~right:1 ~top:0 ~bottom:1
~expand:`BOTH ~fill:`BOTH ~shrink:`BOTH ~xpadding:0 ~ypadding:0
frame#coerce in
let w = GRange.scrollbar `HORIZONTAL ~adjustment:canvas#hadjustment () in
let _ = table#attach ~left:0 ~right:1 ~top:1 ~bottom:2
~expand:`X ~fill:`BOTH ~shrink:`X ~xpadding:0 ~ypadding:0
w#coerce in
let w = GRange.scrollbar `VERTICAL ~adjustment:canvas#vadjustment () in
let _ = table#attach ~left:1 ~right:2 ~top:0 ~bottom:1
~expand:`Y ~fill:`BOTH ~shrink:`Y ~xpadding:0 ~ypadding:0
w#coerce in
canvas
let create_graph_win title =
let window = GWindow.window ~title
~allow_shrink:true ~allow_grow:true () in
let vbox = GPack.vbox ~border_width:4 ~spacing:4 ~packing:window#add () in
let help_but = GButton.button ~label:"Help"
~packing:(vbox#pack ~expand:false ~fill:true) () in
let _ = help_but#connect#clicked ~callback:ViewGraph_select.show_help in
let canvas = create_scrolled_canvas (vbox#pack ~expand:true ~fill:true) in
let hbox = GPack.hbox ~spacing:4 ~packing:vbox#pack () in
let select_init_env =
ViewGraph_select.init ViewGraph_select.default_options
canvas (hbox#pack ~expand:true ~fill:true) in
window#show ();
select_init_env
ocamlgraph-2.0.0/view_graph/viewGraph_core.mli 0000644 0001750 0000144 00000006014 13735627615 020014 0 ustar rt users (**************************************************************************)
(* *)
(* ViewGraph: a library to interact with graphs in ocaml and lablgtk2 *)
(* *)
(* Copyright (C) 2008 - Anne Pacalet *)
(* *)
(* 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, 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. *)
(* *)
(**************************************************************************)
(** ViewGraph : a library to view .dot graphs and interact with the GUI.
* To use it you have :
* - first to define callbacks (see {!modtype:ViewGraph.SigCb})
* - then instanciate the module {!module:ViewGraph.M} with your callbacks,
* - then use {!ViewGraph.M.open_dot_file}
* - don't forget to call {!ViewGraph.M.clear} when changing the file.
*)
(** raised when the call to a dot command fails.
* The string gives the command that failed *)
exception DotError of string
type t_point = float * float
type t_coord = t_point * t_point
type t_graph
type t_node
type t_gtk_obj = GnomeCanvas.re_p GnoCanvas.item
(*val get_canvas : t_graph -> GnoCanvas.canvas *)
val get_id : t_node -> string
val get_coord : t_node -> t_coord option
val get_obj : t_node -> t_gtk_obj option
(** @return 2 lists : the predecessors and successors of the node*)
val get_neighbours : t_graph -> t_node -> t_node list * t_node list
module type SigCb = sig
type t_env
val button_one_press_on_graph : t_env -> unit
val button_two_press_on_graph : t_env -> unit
val button_three_press_on_graph : t_env -> unit
val button_one_press_on_node : t_env -> t_node -> unit
val button_two_press_on_node : t_env -> t_node -> unit
val button_three_press_on_node : t_env -> t_node -> unit
val enter_node : t_env -> t_node -> unit
val leave_node : t_env -> t_node -> unit
end
(** usefull when we don't want to have callbacks on the nodes *)
module EmptyCb : SigCb with type t_env=unit
module M (Cb : SigCb) : sig
(** Open the dot file in the canvas.
* @raise Error if either the image or the graph fail to build *)
val open_dot_file : Cb.t_env -> GnoCanvas.canvas ->
?dot_cmd:string -> string -> t_graph
(** it is very important to not using the graph anymore after calling [clear] *)
val clear : GnoCanvas.canvas -> t_graph -> unit
end
ocamlgraph-2.0.0/ocamlgraph_gtk.opam 0000644 0001750 0000144 00000001521 13735627615 016050 0 ustar rt users opam-version: "2.0"
synopsis: "Displaying graphs using OCamlGraph and GTK"
description: "Displaying graphs using OCamlGraph and GTK"
maintainer: ["filliatr@lri.fr"]
authors: ["Sylvain Conchon" "Jean-Christophe Filliâtre" "Julien Signoles"]
license: "LGPL-2.1-only"
tags: [
"graph"
"library"
"algorithms"
"directed graph"
"vertice"
"edge"
"persistent"
"imperative"
]
homepage: "https://github.com/backtracking/ocamlgraph/"
bug-reports: "https://github.com/backtracking/ocamlgraph/issues/new"
depends: [
"ocaml"
"stdlib-shims"
"lablgtk"
"conf-gnomecanvas"
"ocamlgraph"
"dune" {>= "2.0"}
]
build: [
["dune" "subst"] {pinned}
[
"dune"
"build"
"-p"
name
"-j"
jobs
"@install"
"@runtest" {with-test}
"@doc" {with-doc}
]
]
dev-repo: "git+https://github.com/backtracking/ocamlgraph.git"
ocamlgraph-2.0.0/README.md 0000644 0001750 0000144 00000003342 13735627615 013472 0 ustar rt users # OCamlgraph
OCamlgraph is a graph library for Ocaml. Its contribution is three-fold:
1. It provides an easy-to-use graph implementation together with several
operations and algorithms over graphs, in Graph.Pack.Digraph.
It is a reasonably efficient imperative data structure for directed graphs
with vertices and edges labeled with integers.
Have a look at this module first in order to get an overview of what
this library provides. See also `demo.ml`.
2. Then OCamlgraph provides several other graph implementations for those
not satisfied with the one above. Some are persistent (immutable) and other
imperative (mutable). Some are directed and other are not.
Some have labels for vertices, or labels for edges, or both.
Some have abstract types for vertices. etc.
See interface Sig for the graph signatures and modules Persistent and
Imperative for the implementations.
These implementations are written as functors: you give the types of
vertices labels, edge labels, etc. and you get the data structure as a
result.
3. Finally, OCamlgraph provides several classic operations and algorithms
over graphs. They are also written as functors i.e. independently of the
data structure for graphs. One consequence is that you can define your own
data structure for graphs and yet re-use all the algorithms from this
library -- you only need to provide a few operations such as iterating over
all vertices, over the successors of a vertex, etc.
## Documentation
https://backtracking.github.io/ocamlgraph/
## Examples
You'll find examples of OCamlgraph use in subdirectory examples/
(demo.ml, demo_planar.ml, color.ml, etc.).
## Bug reports
https://github.com/backtracking/ocamlgraph/issues
ocamlgraph-2.0.0/FAQ 0000644 0001750 0000144 00000010077 13735627615 012550 0 ustar rt users ==========================
FREQUENTLY ASKED QUESTIONS
==========================
==========
Q: Is it possible to update imperative graph during traversal
done by |fold_vertex| or |iter_vertex|?
A: Imperative graphs being implemented with hash tables, the answer is no.
Workarounds include
- storing update information on the side, then apply it in a second step;
- mutate a second graph instead.
Regarding the latter, it is worth pointing out OCamlgraph also
provides immutable graphs that could make it more efficient (free
``copy'' and possible sharing between the two graphs, at the extra
cost of logarithmic operations instead of constant-time
operations).
==========
==========
Q: I need to store some information into vertices and/or edges
I need several kind of labels on the edges
-----
A: Use one of the functor implementation provided in Persistent or Imperative.
If for instance you want mutable directed graphs with colored vertices,
you may do
type color = Red | Green | Blue | Yellow
module G = Imperative.Digraph.Abstract(struct type t = color end)
(to be able to change the color you would use `type t = color ref' instead)
==========
==========
Q: How to choose between concrete and abstract vertices for my graph
implementation?
-----
A: If you fall into one of the following cases, use abstract vertices:
- you cannot provide efficient comparison/hash functions for vertices; or
- you wish to get two different vertices with the same label.
In other cases, it is certainly easier to use concrete vertices.
==========
==========
Q: Is it possible to serialize graphs?
-----
A: Graphs are serializable data structures: just call [Pervasives.output_value]
on your graph (for example).
But abstract graphs use integer tags to identify vertices;
this tag is made from the global reference [Blocks.cpt_vertex].
There are two related issues.
1) If there are abstract vertices in RAM while unmarshalling some others,
you have to be sure that RAM vertices do not share tags with unmarshalled
ones (except if you really want that).
2) If you need to create new vertices after unserialising an abstract graph,
you have to:
- serialize [!Blocks.cpt_vertex];
- call function [Blocks.after_unserialization] after your unserialisation
process.
There is no issue with concrete graph: it may be easier to use them if
unmarshalling is required.
==========
==========
Q: I need Foobar-Tarjan algorithm and it is not provided
-----
A: Please contribute by sending us the code :-) See next question.
==========
==========
Q: How can I contribute to this library?
-----
A: You can contribute either with a graph data structure or with an algorithm
over graphs. For the former, please follow the signatures given in module
Sig. For the latter, write your algorithm as a functor, following examples
in modules Path, Flow, Components, etc.
==========
==========
Q: Your implementation of algorithm AAA could be greatly improved provided
you add this and this into the graph data structure
-----
A: Of course yes. But the idea behind ocamlgraph is to be as generic as
possible (any algorithm should be useable on any implementation).
When the graph data structure provides additional capabilities
(such as marking, etc.) it is possible to provide a more efficient
implementation into some specialized functor. See module Traverse for
instance (where DFS and cycle detection are optimized for imperative
graphs equipped with marks)
==========
==========
Q: I have a graph implementation with polymorphic types for vertices or edges
and thus I can't apply the algorithms functors
-----
A: Here we bump into Ocaml's type system limitations: the number of type
parameters must be know when the functor is written and the simplest
choice for us was to assume no type parameter at all. (This is exactly the
same for functors Set.Make or Map.Make from Ocaml standard library.)
As a (bad) workaround, you can copy the functor body and substitute your
own functions for the functor arguments.
==========
ocamlgraph-2.0.0/.gitignore 0000644 0001750 0000144 00000000120 13735627615 014172 0 ustar rt users .merlin
/META
/www/index.en.html
/www/index.fr.html
/www/version.prehtml
_build
ocamlgraph-2.0.0/tests/ 0000755 0001750 0000144 00000000000 13735627615 013353 5 ustar rt users ocamlgraph-2.0.0/tests/dot.expected 0000644 0001750 0000144 00000000734 13735627615 015670 0 ustar rt users ========= BEGIN output graph =========
digraph G {
"task_menu";
"task_ingredients";
"task_invitation";
"task_cook";
"task_table";
"task_eat";
"task_menu" -> "task_ingredients" [label=, ];
"task_ingredients" -> "task_cook" [label=, ];
"task_invitation" -> "task_cook" [label=, ];
"task_cook" -> "task_eat" [label=, ];
"task_table" -> "task_eat" [label=, ];
}========= END output graph ========= ocamlgraph-2.0.0/tests/test_wto.expected 0000644 0001750 0000144 00000000044 13735627615 016744 0 ustar rt users (1 4 1' 4' ) 2' 3' 2 3 (6 5' 6' 5 ) ocamlgraph-2.0.0/tests/test_chaotic.ml 0000644 0001750 0000144 00000011671 13735627615 016364 0 ustar rt users open Graph
(*
Analysis with ChaoticIteration of the following program :
X:=0;
while X<40 do
X:=X+1
done
The analyses uses the interval abstract domain, with widening, and
the widening delay given as a parameter in the commande line (0 if
no parameter is given).
Executing this program should print:
W = WTO, delay=40:
1 -> [-∞; +∞]
2 -> [0; +∞]
3 -> [0; 39]
4 -> [40; +∞]
W = {3}, delay=39:
1 -> [-∞; +∞]
2 -> [0; +∞]
3 -> [0; +∞]
4 -> [40; +∞]
W = WTO, delay=41:
1 -> [-∞; +∞]
2 -> [0; 40]
3 -> [0; 39]
4 -> [40; 40]
*)
(* Trivial language, only one variable *)
module Operator = struct
type expr =
| Var
| Int of int
| Sum of expr * expr
type test =
| Le
| Ge
type t =
| Affect of expr
| Test of test * int
let compare = compare
let default = Affect Var
end
open Operator
(* Basic interval domain *)
module Interval = struct
type num =
| MinusInfinity
| Int of int
| PlusInfinity
let print_num = function
| MinusInfinity -> print_string "-∞"
| Int n -> print_int n
| PlusInfinity -> print_string "+∞"
let ( <% ) n1 n2 = match n1, n2 with
| MinusInfinity, MinusInfinity
| PlusInfinity, PlusInfinity -> failwith "<%"
| MinusInfinity, _ -> true
| _, PlusInfinity -> true
| Int a, Int b -> a < b
| _, _ -> false
let ( >=% ) n1 n2 =
not (n1 <% n2)
let ( <=% ) n1 n2 =
n1 <% n2 || n1 = n2
let ( >% ) n1 n2 =
n1 >=% n2 && n1 <> n2
let min_ n1 n2 =
if n1 <=% n2 then n1 else n2
let max_ n1 n2 =
if n1 >=% n2 then n1 else n2
type t =
| Bottom
| Bounded of num * num
let top =
Bounded (MinusInfinity, PlusInfinity)
let equal = ( = )
let print = function
| Bottom -> print_string "⊥"
| Bounded (a, b) ->
(* Printf is for the weak *)
print_string "[";
print_num a;
print_string "; ";
print_num b;
print_string "]"
let join i1 i2 = match i1, i2 with
| Bottom, _ -> i2
| _, Bottom -> i1
| Bounded (a, b), Bounded (c, d) -> Bounded (min_ a c, max_ b d)
let singleton n =
Bounded (Int n, Int n)
let ( +% ) x y = match x, y with
| MinusInfinity, PlusInfinity
| PlusInfinity, MinusInfinity -> failwith "+%"
| MinusInfinity, _
| _, MinusInfinity -> MinusInfinity
| PlusInfinity, _
| _, PlusInfinity -> PlusInfinity
| Int a, Int b -> Int (a + b)
let rec abstr_expr interval = function
| Var -> interval
| Int n -> singleton n
| Sum (e1, e2) ->
match abstr_expr interval e1, abstr_expr interval e2 with
| Bottom, _ -> Bottom
| _, Bottom -> Bottom
| Bounded (a, b), Bounded (c, d) -> Bounded (a +% c, b +% d)
let abstr_test interval test c = match interval with
| Bottom -> Bottom
| Bounded (a, b) ->
match test with
| Le -> if a >% c then Bottom else Bounded (a, min_ b c)
| Ge -> if b <% c then Bottom else Bounded (max_ a c, b)
let analyze (_, op, _) interval = match op with
| Affect e -> abstr_expr interval e
| Test (test, n) -> abstr_test interval test (Int n)
let widening i1 i2 = match i1, i2 with
| Bottom, _ -> i2
| Bounded _, Bottom -> failwith "widening"
| Bounded (a, b), Bounded (c, d) ->
Bounded (
(if a <=% c then a else MinusInfinity),
(if b >=% d then b else PlusInfinity)
)
end
module Int = struct
type t = int
let compare = compare
let hash = Hashtbl.hash
let equal = ( = )
end
module Data = struct
include Interval
type edge = int * Operator.t * int
end
module G = Persistent.Digraph.ConcreteLabeled (Int) (Operator)
module Wto = WeakTopological.Make (G)
module Chaotic = ChaoticIteration.Make (G) (Data)
let edges = [
1, 2, Affect (Int 0);
2, 3, Test (Le, 39);
3, 2, Affect (Sum (Var, Int 1));
2, 4, Test (Ge, 40);
]
let g =
List.fold_left
(fun acc (v, w, op) -> G.add_edge_e acc (G.E.create v op w))
G.empty edges
let strategy = Wto.recursive_scc g 1
let print_vertex_data vertex interval =
print_int vertex;
print_string " -> ";
Interval.print interval;
print_newline ()
let init v =
if v = 1 then Interval.top else Interval.Bottom
let widening_delay1 = 40
let widening_set1 = ChaoticIteration.FromWto
let widening_delay2 = 39
let widening_set2 = ChaoticIteration.Predicate (( = ) 3)
let widening_delay3 = 41
let widening_set3 = ChaoticIteration.FromWto
let result1 = Chaotic.recurse g strategy init widening_set1 widening_delay1
let result2 = Chaotic.recurse g strategy init widening_set2 widening_delay2
let result3 = Chaotic.recurse g strategy init widening_set3 widening_delay3
let () =
print_endline "W = WTO, delay=40:";
Chaotic.M.iter print_vertex_data result1;
print_newline ();
print_endline "W = {3}, delay=39:";
Chaotic.M.iter print_vertex_data result2;
print_newline ();
print_endline "W = WTO, delay=41:";
Chaotic.M.iter print_vertex_data result3;
print_newline ();
ocamlgraph-2.0.0/tests/nonneg.ml 0000644 0001750 0000144 00000004740 13735627615 015176 0 ustar rt users
(* Test file for module [Nonnegative] *)
open Printf
open Graph
open Pack.NonnegDigraph
open Nonnegative
let test () =
let v = Array.init 10 V.create in
let g = create () in
let test result op =
begin
try
op g;
with
| Assert_failure _ -> print_string "bug bug bug?"; assert false
| exc ->
let exc_name = Printexc.to_string exc in
if exc_name = "Nonnegative.Imperative(G)(W).Negative_cycle(_)" then
assert (not result)
else begin
print_endline exc_name;
Printexc.print_backtrace stdout;
assert false
end
end;
flush_all ();
display_with_gv g
in
let add s t g = add_edge g v.(s) v.(t) in
let add_e s w t g = add_edge_e g (E.create v.(s) w v.(t)) in
let rem s t g = remove_edge g v.(s) v.(t) in
let rem_v s g = remove_vertex g v.(s) in
let rem_e s w t g = remove_edge_e g (E.create v.(s) w v.(t)) in
test true (add 0 1);
test true (rem 0 1);
clear g;
test true (add_e 0 1 1);
test true (add_e 0 1 1);
test true (rem 0 1);
clear g;
test true (add 0 1);
test true (add_e 0 1 1);
test true (rem 0 1);
test true (rem_v 0 );
test true (rem_v 1 );
clear g;
test true (add_e 2 1 3);
test true (add_e 3 2 4);
test true (add_e 0 (-1) 2);
test true (add_e 3 1 4);
test false (add_e 4 (-4) 2);
test false (add_e 4 (-3) 2);
test true (add_e 4 (-2) 2);
test true (add_e 1 3 2);
test true (add_e 5 (-2) 4);
test false (add 2 5);
test true (add_e 2 4 5);
test true (rem 2 3);
test true (rem_v 2 );
clear g;
test false (add_e 1 (-1) 1);
test true (add 1 1);
test true (add_e 1 1 1);
test true (add_e 1 1 2);
test false (add_e 2 (-2) 1);
test true (rem_v 1 );
clear g;
test true (add 1 2);
test true (add_e 2 1 3);
test true (add_e 3 2 4);
test true (add_e 4 3 1);
test true (add 5 6);
test true (add_e 6 1 7);
test true (add_e 7 2 8);
test true (add_e 8 3 5);
test true (add_e 1 (-3) 5);
test false (add_e 8 (-4) 4);
test true (add_e 8 (-3) 4);
test true (rem 1 5);
assert false; (* FIXME: Bug in choosing new source *)
clear g;
printf "All test succeeded.\n";
()
let _ = test ()
ocamlgraph-2.0.0/tests/dot.ml 0000644 0001750 0000144 00000004053 13735627615 014475 0 ustar rt users (**************************************************************************)
(* *)
(* Ocamlgraph: a generic graph library for OCaml *)
(* Copyright (C) 2004-2007 *)
(* 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, 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. *)
(* *)
(**************************************************************************)
(* $Id:$ *)
open Graph
module G = Imperative.Digraph.Abstract(String)
module B = Builder.I(G)
module DotInput =
Dot.Parse
(B)
(struct
let node (id,_) _ = match id with
| Dot_ast.Ident s
| Dot_ast.Number s
| Dot_ast.String s
| Dot_ast.Html s -> s
let edge _ = ()
end)
module Display = struct
include G
let vertex_name v = "\"" ^ String.escaped (V.label v) ^ "\""
let graph_attributes _ = []
let default_vertex_attributes _ = []
let vertex_attributes _ = []
let default_edge_attributes _ = []
let edge_attributes _ = [ `HtmlLabel "f$oo" ]
let get_subgraph _ = None
end
module DotOutput = Graphviz.Dot(Display)
let g = DotInput.parse Sys.argv.(1)
let () =
Printf.printf "========= BEGIN output graph =========\n";
DotOutput.output_graph stdout g;
Printf.printf "========= END output graph =========" ocamlgraph-2.0.0/tests/bench.ml 0000644 0001750 0000144 00000005766 13735627615 015002 0 ustar rt users (**************************************************************************)
(* *)
(* Ocamlgraph: a generic graph library for OCaml *)
(* Copyright (C) 2004-2007 *)
(* 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, 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. *)
(* *)
(**************************************************************************)
open Format
(* bench program for Ocamlgraph *)
module Time = struct
open Unix
let utime f x =
let u = (times()).tms_utime in
let y = f x in
let ut = (times()).tms_utime -. u in
(y,ut)
let print f x =
let (y,ut) = utime f x in
printf "user time: %2.2f@." ut;
y
end
open Graph
module Bench
(G : Sig.G with type V.label = int)
(B : Builder.S with module G = G) =
struct
module R = Rand.Make(B)
(*1. Parcours *)
module Dfs = Traverse.Dfs(G)
(* d�tection de cycle *)
let has_cycle v e =
let g = R.graph ~v ~e () in
let b,t = Time.utime Dfs.has_cycle g in
printf "v = %d e = %d cycle = %b time = %2.2f@." v e b t;
b
let bench1 () =
(* on augmente E jusqu'� trouver un cycle *)
let v = 20000 in
let e = ref 1 in
while not (has_cycle v !e) do e := 2 * !e done
let () =
Printf.printf "======== BEGIN bench1 =========\n";
bench1();
Printf.printf "======== END bench1 =========\n\n"
(* r�sultats :
le temps d'une recherche de cycle n�gative ne d�pend pas de
E et est d'environ 1s pour 10^6 noeuds *)
(* 2. composantes fortement connexes *)
module C = Components.Make(G)
let bench2 () =
for i = 1 to 100 do
let v = i * i in
let d = Random.float 1.0 in
let e = truncate (let x = d *. (float v -. 1.0) in x *. x) in
let g = R.graph ~v ~e () in
let _,t = Time.utime C.scc g in
printf "i = %d v = %d e = %d d = %1.2f time = %2.2f@." i v e d t
done
(* r�sultats : voir results.bench2.txt *)
let () =
Printf.printf "======== BEGIN bench2 =========\n";
bench2();
Printf.printf "======== END bench2 =========\n\n"
end
module B1 = Bench(Pack.Digraph)(Builder.I(Pack.Digraph))
(*
Local Variables:
compile-command: "make -C .. bench"
End:
*)
ocamlgraph-2.0.0/tests/strat.expected 0000644 0001750 0000144 00000000355 13735627615 016236 0 ustar rt users
For 15 matches, is there a winning strategy for the first player ?
true --- (15, 13) (14, 13) (12, 9) (11, 9) (10, 9) (8, 5) (7, 5) (6, 5) (4, 1) (3, 1) (2, 1)
For 13 matches, is there a winning strategy for the first player ?
false
ocamlgraph-2.0.0/tests/test_fixpoint.ml 0000644 0001750 0000144 00000002165 13735627615 016610 0 ustar rt users
(* Test file for Fixpoint *)
let id x = x
module IntOrdered = struct
type t = int
let compare: int -> int -> int = compare
let hash: int -> int = id
let equal: int -> int -> bool = (=)
end
module IntSet = Set.Make(IntOrdered)
module G = Graph.Persistent.Digraph.Concrete(IntOrdered)
module Divisors = Graph.Classic.P(G)
module Analysis = struct
type data = IntSet.t
type edge = G.edge
type vertex = G.vertex
type g = G.t
let direction = Graph.Fixpoint.Backward
let join = IntSet.union
let equal = IntSet.equal
let analyze (_: edge): data -> data = id
end
module Fixpoint = Graph.Fixpoint.Make(G)(Analysis)
let pp_int_set pp set =
let first = ref true in
Format.fprintf pp "@[";
IntSet.iter (fun x ->
if !first then
first := false
else
Format.fprintf pp ",@ ";
Format.pp_print_int pp x)
set;
Format.fprintf pp "@]"
let () =
let n = 15 in
let labels = Fixpoint.analyze IntSet.singleton (Divisors.divisors n) in
Format.open_vbox 0;
for i = 2 to n do
Format.printf "Labels for %d: %a@," i pp_int_set (labels i)
done;
Format.close_box ();
Format.print_flush ()
ocamlgraph-2.0.0/tests/check.ml 0000644 0001750 0000144 00000052620 13735627615 014767 0 ustar rt users (**************************************************************************)
(* *)
(* Ocamlgraph: a generic graph library for OCaml *)
(* Copyright (C) 2004-2007 *)
(* 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, 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. *)
(* *)
(**************************************************************************)
open Graph
module Int = struct
type t = int
let compare = compare
let hash = Hashtbl.hash
let equal = (=)
let default = 0
end
(* pair with equality which ignores the second component *)
module Pair = struct
type t = int * int
let compare (x, _) (y, _) = Int.compare x y
let hash (x, _) = Int.hash x
let equal (x, _) (y, _) = x = y
let default = 0, 0
end
module W(E:sig type t type label val label: t -> label end) = struct
type edge = E.t
type t = int
let weight = E.label
let zero = 0
let add = (+)
let compare = compare
end
(********************************************)
(* Generic functions *)
(********************************************)
module Generic = struct
(* Generic tests for imperative graphs *)
module Make
(G : Sig.I with type V.label = int)
(V : sig val v: int val e: int end) =
struct
module O = Oper.I(G)
let test_mirror g =
if G.is_directed then begin (* TODO: remove *)
let g' = O.mirror g in
assert (G.nb_vertex g = G.nb_vertex g');
G.iter_edges (fun v1 v2 -> assert (G.mem_edge g' v2 v1)) g;
G.iter_edges (fun v1 v2 -> assert (G.mem_edge g v2 v1)) g';
()
end
let g = G.create ()
let () =
let v1 = G.V.create 1 in
let v2 = G.V.create 2 in
let v3 = G.V.create 3 in
test_mirror g;
G.add_edge g v1 v2;
G.add_edge g v1 v3;
G.add_edge g v2 v1;
G.add_edge g v2 v2;
G.add_edge g v2 v2;
test_mirror g;
assert (G.nb_vertex g = V.v && G.nb_edges g = V.e);
G.remove_vertex g v1;
assert (G.nb_vertex g = 2 && G.nb_edges g = 1);
G.remove_vertex g v2;
assert (G.nb_vertex g = 1 && G.nb_edges g = 0);
test_mirror g;
G.clear g;
assert (G.nb_vertex g = 0 && G.nb_edges g = 0)
end
let () =
let module A = Make
(Imperative.Digraph.ConcreteLabeled(Int)(Int))
(struct let v = 3 let e = 4 end)
in
let module A = Make
(Imperative.Graph.ConcreteLabeled(Int)(Int))
(struct let v = 3 let e = 3 end)
in
let module A = Make
(Imperative.Digraph.AbstractLabeled(Int)(Int))
(struct let v = 3 let e = 4 end)
in
let module A = Make
(Imperative.Graph.AbstractLabeled(Int)(Int))
(struct let v = 3 let e = 3 end)
in
let module A = Make
(Imperative.Digraph.Concrete(Int))
(struct let v = 3 let e = 4 end)
in
let module A = Make
(Imperative.Graph.Concrete(Int))
(struct let v = 3 let e = 3 end)
in
let module A = Make
(Imperative.Digraph.Abstract(Int))
(struct let v = 3 let e = 4 end)
in
let module A = Make
(Imperative.Graph.Abstract(Int))
(struct let v = 3 let e = 3 end)
in
let module A = Make
(Imperative.Digraph.ConcreteBidirectional(Int))
(struct let v = 3 let e = 4 end)
in
let module A = Make
(Imperative.Digraph.ConcreteBidirectionalLabeled(Int)(Int))
(struct let v = 3 let e = 4 end)
in
()
(* Generic tests for persistent graphs *)
module MakeP
(G : Sig.P with type V.label = int)
(V : sig val v: int val e: int end) =
struct
module O = Oper.P(G)
let test_mirror g =
let g' = O.mirror g in
assert (G.nb_vertex g = G.nb_vertex g')
let () =
let g = G.empty in
let v1 = G.V.create 1 in
let v2 = G.V.create 2 in
let v3 = G.V.create 3 in
test_mirror g;
let g = G.add_edge g v1 v2 in
let g = G.add_edge g v1 v3 in
let g = G.add_edge g v2 v1 in
let g = G.add_edge g v2 v2 in
let g = G.add_edge g v2 v2 in
test_mirror g;
assert (G.nb_vertex g = V.v && G.nb_edges g = V.e);
let g = G.remove_vertex g v1 in
assert (G.nb_vertex g = 2 && G.nb_edges g = 1);
let g = G.remove_vertex g v2 in
assert (G.nb_vertex g = 1 && G.nb_edges g = 0);
test_mirror g
end
let () =
let module A = MakeP
(Persistent.Digraph.ConcreteLabeled(Int)(Int))
(struct let v = 3 let e = 4 end)
in
let module A = MakeP
(Persistent.Graph.ConcreteLabeled(Int)(Int))
(struct let v = 3 let e = 3 end)
in
let module A = MakeP
(Persistent.Digraph.AbstractLabeled(Int)(Int))
(struct let v = 3 let e = 4 end)
in
let module A = MakeP
(Persistent.Graph.AbstractLabeled(Int)(Int))
(struct let v = 3 let e = 3 end)
in
let module A = MakeP
(Persistent.Digraph.Concrete(Int))
(struct let v = 3 let e = 4 end)
in
let module A = MakeP
(Persistent.Graph.Concrete(Int))
(struct let v = 3 let e = 3 end)
in
let module A = MakeP
(Persistent.Digraph.Abstract(Int))
(struct let v = 3 let e = 4 end)
in
let module A = MakeP
(Persistent.Graph.Abstract(Int))
(struct let v = 3 let e = 3 end)
in
let module A = MakeP
(Persistent.Digraph.ConcreteBidirectional(Int))
(struct let v = 3 let e = 4 end)
in
let module A = MakeP
(Persistent.Digraph.ConcreteBidirectionalLabeled(Int)(Int))
(struct let v = 3 let e = 4 end)
in
()
(* Generic tests for imperative concrete graphs with custom equality *)
module Make_pair
(G : Sig.I with type V.label = int * int)
(V : sig val v: int val e: int end) =
struct
module O = Oper.I(G)
let test_mirror g =
if G.is_directed then begin (* TODO: remove *)
let g' = O.mirror g in
assert (G.nb_vertex g = G.nb_vertex g');
G.iter_edges (fun v1 v2 -> assert (G.mem_edge g' v2 v1)) g;
G.iter_edges (fun v1 v2 -> assert (G.mem_edge g v2 v1)) g';
()
end
let g = G.create ()
let () =
let v1 = G.V.create (1, 0) in
let v2 = G.V.create (2, 0) in
let v3 = G.V.create (2, 1) in
test_mirror g;
G.add_edge g v1 v2;
G.add_edge g v2 v1;
G.add_edge g v1 v3;
G.iter_vertex (fun v -> assert (snd (G.V.label v) = 0)) g;
test_mirror g;
assert (G.nb_vertex g = V.v && G.nb_edges g = V.e);
G.remove_vertex g v3;
assert (G.nb_vertex g = 1 && G.nb_edges g = 0);
test_mirror g;
G.clear g;
assert (G.nb_vertex g = 0 && G.nb_edges g = 0)
end
let () =
let module A = Make_pair
(Imperative.Digraph.ConcreteLabeled(Pair)(Pair))
(struct let v = 2 let e = 2 end)
in
let module A = Make_pair
(Imperative.Graph.ConcreteLabeled(Pair)(Pair))
(struct let v = 2 let e = 1 end)
in
let module A = Make_pair
(Imperative.Digraph.Concrete(Pair))
(struct let v = 2 let e = 2 end)
in
let module A = Make_pair
(Imperative.Graph.Concrete(Pair))
(struct let v = 2 let e = 1 end)
in
let module A = Make_pair
(Imperative.Digraph.ConcreteBidirectional(Pair))
(struct let v = 2 let e = 2 end)
in
let module A = Make_pair
(Imperative.Digraph.ConcreteBidirectionalLabeled(Pair)(Pair))
(struct let v = 2 let e = 2 end)
in
()
(* find_edge *)
module Make2
(G : Sig.I
with type V.t = int and type E.label = int and type E.t = int * int * int)
=
struct
let g = G.create ()
let test_exn v1 v2 =
assert (G.find_all_edges g v1 v2 = []);
try
let _ = G.find_edge g v1 v2 in
assert false
with Not_found ->
()
let () =
let e1 = 1, 0, 2 in
let e2 = 1, 1, 3 in
let e2' = 1, 2, 3 in
let e3 = 2, 2, 1 in
G.add_edge_e g e1;
G.add_edge_e g e2;
G.add_edge_e g e2';
G.add_edge_e g e3;
G.add_edge_e g e3;
assert (G.find_edge g 1 2 = e1);
assert (List.length (G.find_all_edges g 1 3) = 2);
test_exn 2 3;
test_exn 2 4;
test_exn 5 2;
G.remove_vertex g 2;
assert (G.nb_vertex g = 2 && G.nb_edges g = 2)
end
let () =
let module D = Make2(Imperative.Digraph.ConcreteLabeled(Int)(Int)) in
D.test_exn 3 1;
let module G = Imperative.Graph.ConcreteLabeled(Int)(Int) in
let module G2 = Make2(G) in
assert (G.find_edge G2.g 3 1 = (3, 1, 1))
end
(********************************************)
(* Dijkstra *)
(********************************************)
module Dijkstra = struct
module TestDijkstra
(G: Sig.G with type V.label = int and type E.label = int)
(B: Builder.S with module G = G) =
struct
let g = B.empty ()
let v1 = G.V.create 1
let g = B.add_vertex g v1
let v2 = G.V.create 2
let g = B.add_vertex g v2
let v3 = G.V.create 3
let g = B.add_vertex g v3
let v4 = G.V.create 4
let g = B.add_vertex g v4
let v5 = G.V.create 5
let g = B.add_vertex g v5
let g = B.add_edge_e g (G.E.create v1 10 v2)
let g = B.add_edge_e g (G.E.create v2 50 v3)
let g = B.add_edge_e g (G.E.create v1 30 v4)
let g = B.add_edge_e g (G.E.create v1 100 v5)
let g = B.add_edge_e g (G.E.create v3 10 v5)
let g = B.add_edge_e g (G.E.create v4 20 v3)
let g = B.add_edge_e g (G.E.create v4 60 v5)
module Dij = Path.Dijkstra(G)(W(G.E))
module Dfs = Traverse.Dfs(G)
let test g i j w l =
let p,w' = Dij.shortest_path g i j in
assert (w' = w && List.length p = l)
let test_not_found g i j =
try let _ = Dij.shortest_path g i j in assert false with Not_found -> ()
let () = test g v1 v5 60 3
let () = test g v1 v1 0 0
let () = if G.is_directed then test_not_found g v5 v1
let () = assert (not (Dfs.has_cycle g))
let gc = B.add_edge_e g (G.E.create v5 10 v1)
let v6 = G.V.create 6
let gc = B.add_vertex gc v6
let () = if G.is_directed then test gc v1 v5 60 3
let () = test gc v5 v1 10 1
let () = test_not_found gc v1 v6
let () = assert (Dfs.has_cycle gc)
end
(* Dijkstra on Persistent Directed Labeled Graphs *)
module G = Persistent.Digraph.ConcreteLabeled(Int)(Int)
module Test1 = TestDijkstra(G)(Builder.P(G))
(* Dijkstra on Persistent Directed Abstract Labeled Graphs *)
module G2 = Persistent.Digraph.AbstractLabeled(Int)(Int)
module Test2 = TestDijkstra(G2)(Builder.P(G2))
(* Dijkstra on Imperative Hashed Directed Labeled Graphs *)
module G3 = Imperative.Digraph.ConcreteLabeled(Int)(Int)
module Test3 = TestDijkstra(G3)(Builder.I(G3))
end
(********************************************)
(* Traversal *)
(********************************************)
module Traversal = struct
module G = Imperative.Digraph.AbstractLabeled(Int)(Int)
module Dfs = Traverse.Dfs(G)
module Mark = Traverse.Mark(G)
let g = G.create ()
let newv g = let v = G.V.create 0 in G.add_vertex g v; v
let v1 = newv g
let v2 = newv g
let v3 = newv g
let v4 = newv g
let v5 = newv g
let add_edge g v1 l v2 = G.add_edge_e g (G.E.create v1 l v2)
let () =
add_edge g v1 10 v2;
add_edge g v2 50 v3;
add_edge g v1 30 v4;
add_edge g v1 100 v5;
add_edge g v3 10 v5;
add_edge g v4 20 v3;
add_edge g v4 60 v5
let () = assert (not (Mark.has_cycle g) && not (Dfs.has_cycle g))
let v6 = newv g
let () = assert (not (Mark.has_cycle g) && not (Dfs.has_cycle g))
let () = add_edge g v5 10 v1
let () = assert (Mark.has_cycle g && Dfs.has_cycle g)
(* debug dfs / Cormen p 479 *)
let g = G.create ()
let newv i = let v = G.V.create i in G.add_vertex g v; v
let u = newv 1
let v = newv 2
let w = newv 3
let x = newv 4
let y = newv 5
let z = newv 6
let edge a b = add_edge g a 0 b
let () =
edge u v; edge u x;
edge v y;
edge w y; edge w z;
edge x v;
edge y x;
edge z z
open Format
let pre v = printf "pre %d@." (G.V.label v)
let post v = printf "post %d@." (G.V.label v)
(*
let () = printf "iter:@."; Dfs.iter_component ~pre ~post g w
let () = printf "prefix:@."; Dfs.prefix_component pre g w
let () =
printf "step:@.";
let rec visit it =
let v = Dfs.get it in
printf "visit %d@." (G.V.label v);
visit (Dfs.step it)
in
try visit (Dfs.start g) with Exit -> ()
*)
end
(********************************************)
(* Ford-Fulkerson and Goldberg *)
(********************************************)
module FF_Goldberg = struct
module G = Persistent.Digraph.ConcreteLabeled(Int)(Int)
let add_edge g v1 l v2 = G.add_edge_e g (G.E.create v1 l v2)
let g = G.empty
let g = add_edge g 1 16 2
let g = add_edge g 1 13 3
let g = add_edge g 2 10 3
let g = add_edge g 3 4 2
let g = add_edge g 2 12 4
let g = add_edge g 4 9 3
let g = add_edge g 3 14 5
let g = add_edge g 5 7 4
let g = add_edge g 4 20 6
let g = add_edge g 5 4 6
module F = struct
type label = int
type t = int
let max_capacity x = x
let min_capacity _ = 0
let flow _ = 0
let add = (+)
let sub = (-)
let compare = compare
let zero = 0
end
module FF = Flow.Ford_Fulkerson(G)(F)
module Gold = Flow.Goldberg_Tarjan(G)(F)
let () =
assert (snd (FF.maxflow g 1 6) = 23);
assert (snd (Gold.maxflow g 1 6) = 23);
assert (snd (FF.maxflow g 1 1) = 0);
assert (snd (Gold.maxflow g 1 1) = 0)
module G2 =
Persistent.Digraph.ConcreteLabeled
(Int)
(struct include Util.OTProduct(Int)(Int) let default = 0, 0 end)
let add_edge g v1 l v2 = G2.add_edge_e g (G2.E.create v1 l v2)
let g = G2.empty
let g = add_edge g 1 (1, 1) 2
let g = add_edge g 1 (3, 0) 3
let g = add_edge g 2 (1, 1) 3
let g = add_edge g 3 (1, 0) 2
let g = add_edge g 2 (3, 0) 4
let g = add_edge g 3 (1, 1) 4
module F2 = struct
type label = int * int
type t = int
let max_capacity = fst
let min_capacity _ = 0
let flow = snd
let add = (+)
let sub = (-)
let compare = compare
let zero = 0
end
module FF2 = Flow.Ford_Fulkerson(G2)(F2)
module Gold2 = Flow.Goldberg_Tarjan(G2)(F2)
let () =
assert (snd (FF2.maxflow g 1 4) = 2); (* growth of the flow *)
assert (snd (Gold2.maxflow g 1 4) = 3) (* max flow *)
end
(********************************************)
(* Neighbourhood *)
(********************************************)
module Neighbourhood = struct
module G = Graph.Imperative.Graph.Concrete(Int)
open G
let g = create ()
let add = add_edge g
let () =
add 1 2;
add 1 3;
add 1 4;
add 2 5;
add 3 5;
add 4 5;
add 5 6
module N = Oper.Neighbourhood(G)
module V = N.Vertex_Set
let s2 = V.add 1 (V.singleton 5)
let () = assert (V.equal (N.set_from_vertex g 2) s2)
let s25 = V.add 1 (V.add 3 (V.add 4 (V.singleton 6)))
let () = assert (V.equal (N.set_from_vertices g [ 2; 5 ]) s25)
end
(********************************************)
(* Minimal seperators *)
(********************************************)
module Minsep = struct
module P = struct
module G = Graph.Persistent.Graph.Concrete(Int)
open G
let g = empty
let g = add_edge g 1 2
let g = add_edge g 1 3
let g = add_edge g 1 4
let g = add_edge g 2 5
let g = add_edge g 3 5
let g = add_edge g 4 5
let g = add_edge g 5 6
module M = Minsep.P(G)
module S = M.Vertex_Set
module VS = M.VSetset
let s5 = S.singleton 5
let s15 = S.add 1 s5
let s234 = S.add 2 (S.add 3 (S.singleton 4))
let bigs = VS.add s5 (VS.add s15 (VS.singleton s234))
let () = assert (VS.equal (M.set_of_allminsep g) bigs)
end
module I = struct
module G = Graph.Imperative.Graph.Abstract(struct type t = unit end)
open G
let g = create ()
let v1 = V.create ()
let v2 = V.create ()
let v3 = V.create ()
let v4 = V.create ()
let v5 = V.create ()
let v6 = V.create ()
let add = add_edge g
let () =
add v1 v2;
add v1 v3;
add v1 v4;
add v2 v5;
add v3 v5;
add v4 v5;
add v5 v6
module M = Minsep.I(G)
module S = M.Vertex_Set
module VS = M.VSetset
let s5 = S.singleton v5
let s15 = S.add v1 s5
let s234 = S.add v2 (S.add v3 (S.singleton v4))
let bigs = VS.add s5 (VS.add s15 (VS.singleton s234))
let () =
let _ = G.copy g in
assert (VS.equal (M.set_of_allminsep g) bigs)
end
end
(********************************************)
(* Checking signature *)
(********************************************)
(* check that signature [Sig_pack.S] (which is manually expanded) does not
forget anything *)
module type RightSigPack = sig
include Sig.IM with type V.label = int and type E.label = int
val find_vertex : t -> int -> V.t
include Oper.S with type g = t
module Dfs : sig
val iter : ?pre:(V.t -> unit) ->
?post:(V.t -> unit) -> t -> unit
val prefix : (V.t -> unit) -> t -> unit
val postfix : (V.t -> unit) -> t -> unit
val iter_component :
?pre:(V.t -> unit) ->
?post:(V.t -> unit) -> t -> V.t -> unit
val prefix_component : (V.t -> unit) -> t -> V.t -> unit
val postfix_component : (V.t -> unit) -> t -> V.t -> unit
val has_cycle : t -> bool
end
module Bfs : sig
val iter : (V.t -> unit) -> t -> unit
val iter_component : (V.t -> unit) -> t -> V.t -> unit
end
module Marking : sig
val dfs : t -> unit
val has_cycle : t -> bool
end
module Classic : sig
val divisors : int -> t
val de_bruijn : int -> t
val vertex_only : int -> t
val full : ?self:bool -> int -> t
end
module Rand : sig
val graph : ?loops:bool -> v:int -> e:int -> unit -> t
val labeled :
(V.t -> V.t -> E.label) ->
?loops:bool -> v:int -> e:int -> unit -> t
end
module Components : sig
val scc : t -> int*(V.t -> int)
val scc_array : t -> V.t list array
val scc_list : t -> V.t list list
end
val shortest_path : t -> V.t -> V.t -> E.t list * int
val ford_fulkerson : t -> V.t -> V.t -> (E.t -> int) * int
val goldberg_tarjan : t -> V.t -> V.t -> (E.t -> int) * int
val dot_output : t -> string -> unit
end
module TestSigPack : RightSigPack = struct
include Pack.Digraph
type g = t
end
module Test_clique = struct
(* Test file for Brom-Kerbosch *)
open Graph
module G = Persistent.Graph.Concrete (struct
type t = int
let compare = compare
let hash = Hashtbl.hash
let equal = (=)
end)
module BK = Clique.Bron_Kerbosch(G)
let () =
let vertices = [1;2;3;4;5;6;7] in
let edges = [(1,2);(1,5);(2,5);(2,3);(4,5);(3,4);(4,6)] in
let g = List.fold_left (fun graph v -> G.add_vertex graph v) G.empty vertices in
let g = List.fold_left (fun graph (v1, v2) -> G.add_edge graph v1 v2) g edges in
let cliques = BK.maximalcliques g in
(* The cliques of this graph should be: [2, 3], [3, 4], [1, 2, 5], [4, 5], [4, 6], [7] *)
assert (List.length cliques == 6);
assert (List.exists (fun cl -> List.length cl == 2 && List.mem 2 cl && List.mem 3 cl) cliques);
assert (List.exists (fun cl -> List.length cl == 2 && List.mem 3 cl && List.mem 4 cl) cliques);
assert (List.exists (fun cl -> List.length cl == 3 && List.mem 1 cl && List.mem 2 cl && List.mem 5 cl) cliques);
assert (List.exists (fun cl -> List.length cl == 2 && List.mem 4 cl && List.mem 5 cl) cliques);
assert (List.exists (fun cl -> List.length cl == 2 && List.mem 4 cl && List.mem 6 cl) cliques);
assert (List.exists (fun cl -> List.length cl == 1 && List.mem 7 cl) cliques)
end
module Test_reduction = struct
open Graph
module G = Imperative.Digraph.Concrete(struct
type t = int
let compare = compare
let hash = Hashtbl.hash
let equal = (=) end)
open G
module R = Rand.I(G)
module O = Oper.I(G)
let check_included g1 g2 =
iter_vertex (fun v -> assert (mem_vertex g2 v)) g1;
iter_edges (fun u v -> assert (mem_edge g1 u v)) g1
let check_same_graph g1 g2 =
check_included g1 g2;
check_included g2 g1
let test v e =
let g = R.graph ~loops:true ~v ~e () in
let t = O.transitive_closure g in
check_included g t;
let r = O.transitive_reduction g in
check_included r g;
check_same_graph (O.transitive_closure r) t
let () =
for v = 1 to 10 do
for e = 0 to v * (v-1) / 2 do
test v e
done
done
(* issue #91 *)
let () =
let g = create () in
for v = 1 to 5 do add_vertex g v done;
add_edge g 1 2; add_edge g 2 3; add_edge g 3 4; add_edge g 4 5;
add_edge g 2 5;
let r = O.transitive_reduction g in
check_included r g;
assert (nb_edges r = 4);
assert (not (mem_edge r 2 5));
()
end
let () = Format.printf "check: all tests succeeded@."
(*
Local Variables:
compile-command: "make -C .. check"
End:
*)
ocamlgraph-2.0.0/tests/basic.ml 0000644 0001750 0000144 00000004620 13735627615 014770 0 ustar rt users (**************************************************************************)
(* *)
(* Ocamlgraph: a generic graph library for OCaml *)
(* Copyright (C) 2004-2007 *)
(* 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, 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. *)
(* *)
(**************************************************************************)
open Format
open Graph
module Int = struct
type t = int
let compare = compare
let hash = Hashtbl.hash
let equal = (=)
let default = 0
end
module G = Persistent.Digraph.ConcreteLabeled(Int)(Int)
let g = G.empty
let g = G.add_vertex g 1
let g = G.add_edge_e g (G.E.create 1 10 2)
let g = G.add_edge_e g (G.E.create 2 50 3)
let g = G.add_edge_e g (G.E.create 1 30 4)
let g = G.add_edge_e g (G.E.create 1 100 5)
let g = G.add_edge_e g (G.E.create 3 10 5)
let g = G.add_edge_e g (G.E.create 4 20 3)
let g = G.add_edge_e g (G.E.create 4 60 5)
let g = G.remove_vertex g 4
let gc = G.add_edge_e g (G.E.create 5 10 1)
let gc = G.add_vertex gc 6
module W = struct
type edge = G.E.t
type t = int
let weight e = G.E.label e
let zero = 0
let add = (+)
let sub = (-)
let compare = compare
end
module Dij = Path.Dijkstra(G)(W)
let p,w = Dij.shortest_path gc 1 5
open G.E
let () = List.iter (fun e -> printf "[%d -> %d]" (src e) (dst e)) p; printf "@."
module Comp = Components.Make(G)
let g = G.add_edge g 3 2
let n, f = Comp.scc g
let () = G.iter_edges (fun u v -> printf "%d -> %d@." u v) g
let () = printf "%d components@." n
let () = G.iter_vertex (fun v -> printf " %d -> %d@." v (f v)) g
ocamlgraph-2.0.0/tests/strat.ml 0000644 0001750 0000144 00000010130 13735627615 015035 0 ustar rt users (**************************************************************************)
(* *)
(* Ocamlgraph: a generic graph library for OCaml *)
(* Copyright (C) 2004-2007 *)
(* 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, 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. *)
(* *)
(**************************************************************************)
(* $Id:$ *)
open Graph
module V = struct
type t = bool * int
let compare = compare
let hash = Hashtbl.hash
let equal = (=)
end
module G = Persistent.Digraph.Concrete(V)
module P = struct
type vertex = V.t
type t = vertex * (vertex list) * (vertex -> bool)
let get_initial (i, _, _) = i
let is_final (_, f, _) v = List.mem v f
let turn (_, _, f) v = f v
end
module S = struct
type vertex = V.t
type t = vertex -> vertex
let empty =
fun _ -> raise (Invalid_argument "Strategy definition")
let next f v = f v
let add s v v' =
fun e -> if V.equal e v then v' else next s e
end
module A = Strat.Algo(G)(P)(S);;
(* Match game : n matches in line, two players. Each player takes
one, two or three matches in order. The player who takes the
last match loses. *)
(* States are given by the remaining number of matches
and the player whose turn it is to play.
Edges are the possible moves. *)
let rec trans_aux g (j, n) =
if n = 0 then g
else
if n = 1 then
let g = G.add_edge g (j, n) (not j, n - 1) in
(if j then trans_aux g (not j, n) else trans_aux g (not j, n - 1))
else
if n = 2 then
let g = G.add_edge g (j, n) (not j, n - 1) in
let g = G.add_edge g (j, n) (not j, n - 2) in
(if j then trans_aux g (not j, n) else trans_aux g (not j, n - 1))
else
let g = G.add_edge g (j, n) (not j, n - 1) in
let g = G.add_edge g (j, n) (not j, n - 2) in
let g = G.add_edge g (j, n) (not j, n - 3) in
(if j then trans_aux g (not j, n) else trans_aux g (not j, n - 1));;
let trans n = trans_aux G.empty (true, n);;
let p n = ((true, n), [(true, 0)], fun (b, _) -> b);;
(* ex n = ((true, _), _) if there is a winning strategy for the
first player to play. In this case, it provides
a strategy. *)
let ex n =
let t = trans n in
(A.strategyA t (p n), t);;
let n1 = 15;;
let n2 = 13;;
let ex1 = ex n1;;
let ex2 = ex n2;;
(* Printing on the standard out channel ;
simply uncomment to see the results. *)
let couple_of_strat g s =
let f v l =
try
let v' = S.next s v in (v, v') :: l
with Invalid_argument _ -> l
in
G.fold_vertex f g [];;
let string_of_couple ((_, i1), (_, i2)) =
"(" ^ (string_of_int i1) ^ ", " ^ (string_of_int i2) ^ ") ";;
let rec string_of_couple_list l = match l with
[] -> ""
| e :: l' -> (string_of_couple e) ^ (string_of_couple_list l');;
print_newline();;
print_string ("For " ^ (string_of_int n1) ^ " matches, is there a winning strategy for the first player ?");;
print_newline();;
print_string (string_of_bool (fst (fst ex1)));;
print_string " --- ";;
print_string (string_of_couple_list (couple_of_strat (snd ex1) (snd (fst ex1))));;
print_newline();; print_newline();;
print_string ("For " ^ (string_of_int n2) ^ " matches, is there a winning strategy for the first player ?");;
print_newline();;
print_string (string_of_bool (fst (fst ex2)));;
print_newline();; print_newline();;
ocamlgraph-2.0.0/tests/test_bf.expected 0000644 0001750 0000144 00000001116 13735627615 016523 0 ustar rt users Running test with name: cycle_1
1 --(1)--> 2
2 --(1)--> 0
0 --(-3)--> 1
Running test with name: cycle_2
1 --(1)--> 2
2 --(1)--> 0
0 --(-10)--> 1
Running test with name: cycle_3
0 --(-10)--> 1
1 --(1)--> 3
3 --(1)--> 4
4 --(1)--> 0
Running test with name: cycle_4
0 --(-10)--> 1
1 --(1)--> 3
3 --(1)--> 4
4 --(1)--> 0
Running test with name: cycle_5
0 --(-10)--> 1
1 --(1)--> 2
2 --(1)--> 0
Running test with name: cycle_6
0 --(-10)--> 1
1 --(1)--> 2
2 --(1)--> 0
Running test with name: nocycle_1
No cycle found
Running test with name: nocycle_2
No cycle found
All tests succeeded.
ocamlgraph-2.0.0/tests/test_chaotic.expected 0000644 0001750 0000144 00000000364 13735627615 017552 0 ustar rt users W = WTO, delay=40:
1 -> [-∞; +∞]
2 -> [0; +∞]
3 -> [0; 39]
4 -> [40; +∞]
W = {3}, delay=39:
1 -> [-∞; +∞]
2 -> [0; +∞]
3 -> [0; +∞]
4 -> [40; +∞]
W = WTO, delay=41:
1 -> [-∞; +∞]
2 -> [0; 40]
3 -> [0; 39]
4 -> [40; 40]
ocamlgraph-2.0.0/tests/test_johnson.expected 0000644 0001750 0000144 00000000514 13735627615 017613 0 ustar rt users [2 -> 5 : -1]
[5 -> 1 : 8]
[2 -> 4 : 1]
[2 -> 1 : 3]
[3 -> 2 : 4]
[3 -> 5 : 3]
[5 -> 2 : 5]
[1 -> 1 : 0]
[2 -> 3 : -4]
[1 -> 4 : 2]
[5 -> 5 : 0]
[4 -> 4 : 0]
[5 -> 3 : 1]
[1 -> 5 : -4]
[4 -> 5 : -2]
[1 -> 2 : 1]
[2 -> 2 : 0]
[4 -> 3 : -5]
[3 -> 1 : 7]
[3 -> 4 : 5]
[4 -> 2 : -1]
[4 -> 1 : 2]
[1 -> 3 : -3]
[5 -> 4 : 6]
[3 -> 3 : 0]
ocamlgraph-2.0.0/tests/dot.dot 0000644 0001750 0000144 00000003406 13735627615 014654 0 ustar rt users digraph D {
node [shape=plaintext fontname="Sans serif" fontsize="8"];
task_menu [ label=<
>];
task_ingredients [ label=<
Task 2
Buy ingredients
done
>];
task_invitation [ label=<
Task 4
Send invitation
done
>];
task_cook [ label=<
>];
task_table[ label=<
>];
task_eat[ label=<
>];
task_menu -> task_ingredients;
task_ingredients -> task_cook;
task_invitation -> task_cook;
task_table -> task_eat;
task_cook -> task_eat;
} ocamlgraph-2.0.0/tests/dune 0000644 0001750 0000144 00000006057 13735627615 014241 0 ustar rt users (test
(name check)
(libraries graph)
(modules check))
(test
(name test_topsort)
(libraries graph)
(modules test_topsort))
;; Rules for the Bellman-Ford tests
(rule
(with-stdout-to
test_bf.output
(run ./test_bf.exe)))
(rule
(alias runtest)
(action
(progn
(diff test_bf.expected test_bf.output)
(echo "test_bf: all tests succeeded.\n"))))
(executable
(name test_bf)
(modules test_bf)
(libraries graph))
;; Rules for the chaotic tests
(rule
(with-stdout-to
test_chaotic.output
(run ./test_chaotic.exe)))
(rule
(alias runtest)
(action
(progn
(diff test_chaotic.expected test_chaotic.output)
(echo "test_chaotic: all tests succeeded.\n"))))
(executable
(name test_chaotic)
(modules test_chaotic)
(libraries graph))
;; Rules for the strat test
(rule
(with-stdout-to
strat.output
(run ./strat.exe)))
(rule
(alias runtest)
(action
(progn
(diff strat.expected strat.output)
(echo "strat: all tests succeeded.\n"))))
(executable
(name strat)
(modules strat)
(libraries graph))
;; Rules for the fixpoint test
(rule
(with-stdout-to
test_fixpoint.output
(run ./test_fixpoint.exe)))
(rule
(alias runtest)
(action
(progn
(diff test_fixpoint.expected test_fixpoint.output)
(echo "test_fixpoint: all tests succeeded.\n"))))
(executable
(name test_fixpoint)
(modules test_fixpoint)
(libraries graph))
;; Rules for the Johnson test
(rule
(with-stdout-to
test_johnson.output
(run ./test_johnson.exe)))
(rule
(alias runtest)
(action
(progn
(diff test_johnson.expected test_johnson.output)
(echo "test_johnson: all tests succeeded.\n"))))
(executable
(name test_johnson)
(modules test_johnson)
(libraries graph))
;; Rules for the weak topological test
(rule
(with-stdout-to
test_wto.output
(run ./test_wto.exe)))
(rule
(alias runtest)
(action
(progn
(diff test_wto.expected test_wto.output)
(echo "test_wto: all tests succeeded.\n"))))
(executable
(name test_wto)
(modules test_wto)
(libraries graph))
;; Rules for the basic test
(rule
(with-stdout-to
basic.output
(run ./basic.exe)))
(rule
(alias runtest)
(action
(progn
(diff basic.expected basic.output)
(echo "basic: all tests succeeded.\n"))))
(executable
(name basic)
(modules basic)
(libraries graph))
;; Rules for the test_components test
(rule
(with-stdout-to
test_components.output
(run ./test_components.exe)))
(rule
(alias runtest)
(action
(progn
(diff test_components.expected test_components.output)
(echo "test_components: all tests succeeded.\n"))))
(executable
(name test_components)
(modules test_components)
(libraries graph))
;; rules for the dot test
(rule
(deps dot.dot)
(action
(with-stdout-to
dot.output
(run ./dot.exe %{deps}))))
(rule
(alias runtest)
(action
(progn
(diff dot.expected dot.output)
(echo "dot: all tests succeeded.\n"))))
(executable
(name dot)
(modules dot)
(libraries graph))
;; rules for the running the benchmark
(rule
(alias bench)
(action
(run ./bench.exe)))
(executable
(name bench)
(modules bench)
(libraries graph unix))
ocamlgraph-2.0.0/tests/test_bf.ml 0000644 0001750 0000144 00000003044 13735627615 015334 0 ustar rt users
(* Test file for Bellman-Ford *)
open Printf
open Graph
open Pack.Digraph
(* TODO: This could be done a tiny bit better,
no need for printing, this could use alcotest or equivalent *)
let test ~name has_cycle spec =
printf "Running test with name: %s\n" name;
let v = Array.init 5 V.create in
let g = create () in
let () = Array.iter (add_vertex g) v in
let build (s,w,t) = add_edge_e g (E.create v.(s) w v.(t)) in
List.iter build spec;
begin try
let cycle = bellman_ford g v.(1) in
let print_edge e =
printf "%d --(%d)--> %d\n" (V.label (E.src e)) (E.label e) (V.label (E.dst e))
in
List.iter print_edge cycle;
assert has_cycle
with Not_found ->
printf "No cycle found\n";
assert (not has_cycle)
end;
print_newline ();
flush stdout
let () =
test ~name:"cycle_1" true [ 0, (-3), 1; 1, 1, 2; 2, 1, 0; 1, 1, 3; 3, 1, 4; 4, 1, 0 ];
test ~name:"cycle_2" true [ 0, (-10), 1; 1, 1, 2; 2, 1, 0; 1, 1, 3; 3, 1, 4; 4, 1, 0 ];
test ~name:"cycle_3" true [ 0, (-10), 1; 2, 1, 0; 1, 1, 3; 3, 1, 4; 4, 1, 0 ];
test ~name:"cycle_4" true [ 0, (-10), 1; 1, 1, 2; 1, 1, 3; 3, 1, 4; 4, 1, 0 ];
test ~name:"cycle_5" true [ 0, (-10), 1; 1, 1, 2; 2, 1, 0; 3, 1, 4; 4, 1, 0 ];
test ~name:"cycle_6" true [ 0, (-10), 1; 1, 1, 2; 2, 1, 0; 1, 1, 3; 4, 1, 0 ];
test ~name:"nocycle_1" false [ 1, 1, 2; 2, 1, 0; 1, 1, 3; 3, 1, 4; 4, 1, 0 ];
test ~name:"nocycle_2" false [ 0, (-10), 1; 1, 1, 2; 1, 1, 3; 3, 1, 4; ];
printf "All tests succeeded.\n"
ocamlgraph-2.0.0/tests/test_wto.ml 0000644 0001750 0000144 00000002304 13735627615 015554 0 ustar rt users open Graph
(*
The non-reducible example from Bourdoncle paper
Reference is in WeakTopological source
*)
(* Execution should print something like (i and i' can be switched) :
(1 4 1' 4') 2' 3' 2 3 (6 5' 6' 5) *)
module Vertex = struct
type t = string
let compare = Stdlib.compare
let hash = Hashtbl.hash
let equal = ( = )
end
module G = Persistent.Digraph.Concrete (Vertex)
module Wto = WeakTopological.Make (G)
let rec print_element = function
| WeakTopological.Vertex v -> print_string v
| WeakTopological.Component (head, components) ->
(* Printf is for the weak *)
print_string "(";
print_string head;
print_string " ";
print_components components;
print_string ")"
and print_components components =
WeakTopological.fold_left
(fun () elem -> print_element elem; print_string " ")
()
components
let edges = [
"1", "4";
"1", "2";
"2", "3";
"3", "6";
"4", "1'";
"5", "6";
"6", "5'";
"1'", "2'";
"1'", "4'";
"2'", "3'";
"3'", "6'";
"4'", "1";
"5'", "6'";
"6'", "5";
]
let g =
List.fold_left
(fun acc (v, w) -> G.add_edge acc v w)
G.empty edges
let result = Wto.recursive_scc g "1"
let () =
print_components result
ocamlgraph-2.0.0/tests/test_johnson.ml 0000644 0001750 0000144 00000001643 13735627615 016426 0 ustar rt users
(* Test file for Johnson *)
open Graph
module Int = struct
type t = int
let compare = compare
let hash = Hashtbl.hash
let equal = (=)
let default = 0
end
module G = Imperative.Digraph.ConcreteLabeled(Int)(Int)
module W = struct
type edge = G.E.t
type t = int
let weight e = G.E.label e
let zero = 0
let add = (+)
let sub = (-)
let compare = compare
end
module J = Path.Johnson(G)(W)
let g = G.create ()
let () =
G.add_edge_e g (G.E.create 1 3 2);
G.add_edge_e g (G.E.create 1 (-4) 5);
G.add_edge_e g (G.E.create 1 8 3);
G.add_edge_e g (G.E.create 2 7 5);
G.add_edge_e g (G.E.create 2 1 4);
G.add_edge_e g (G.E.create 3 4 2);
G.add_edge_e g (G.E.create 4 (-5) 3);
G.add_edge_e g (G.E.create 4 2 1);
G.add_edge_e g (G.E.create 5 6 4)
let () = let test = J.all_pairs_shortest_paths g in
J.HVV.iter (fun (v, u) d -> Printf.printf "[%d -> %d : %d]\n" v u d) test
ocamlgraph-2.0.0/tests/test_topsort.ml 0000644 0001750 0000144 00000004637 13735627615 016470 0 ustar rt users
(* Test file for topological sort *)
open Format
open Graph
open Pack.Digraph
let test ?(check=true) iter n edges =
let v = Array.init n V.create in
let g = create () in
let () = Array.iter (add_vertex g) v in
let build (s,t) = add_edge g v.(s) v.(t) in
List.iter build edges;
(* run top sort *)
let num = Array.make n 0 in
let i = ref 0 in
iter (fun v -> incr i; num.(V.label v) <- !i) g;
let r = Array.init n (fun i -> i) in
Array.sort (fun i j -> num.(i) - num.(j)) r;
(* if check then for v = 0 to n-1 do printf "%d " r.(v) done; printf "@."; *)
(* check *)
let path = PathCheck.check_path (PathCheck.create g) in
let check_edge (x,y) =
let vx = v.(x) and vy = v.(y) in
(* printf "x=%d y=%d num(x)=%d num(y)=%d@." x y num.(x) num.(y);
* printf "x-->y=%b y-->x=%b@." (path vx vy) (path vy vx); *)
assert (num.(x) > 0 && num.(y) > 0);
assert (num.(x) >= num.(y) || path vx vy || not (path vy vx)) in
if check then
for x = 0 to n-1 do for y = 0 to n-1 do check_edge (x,y) done done;
(* display_with_gv g; *)
()
let tests iter =
let test = test iter in
test 3 [0,1; 1,2];
test 3 [];
(* 1-cycle *)
test 1 [0,0];
(* 2-cycle *)
test 2 [0,1; 1,0];
(* 2-cycle with out edge *)
test 3 [0,1; 1,0; 1,2];
test 3 [2,0; 0,2; 0,1];
test 3 [1,2; 2,1; 2,0];
(* 2 loops *)
test 5 [1,2; 2,1; 2,0; 3,4; 4,3];
(* 2-cycle with in edge *)
test 3 [1,2; 2,1; 0,2];
test 3 [1,2; 2,1; 0,1];
(* 2 cycles connected *)
test 4 [0,1; 1,0; 2,3; 3,2; 2,1];
test 4 [0,1; 1,0; 2,3; 3,2; 1,2];
test 4 [0,1; 1,0; 2,3; 3,2; 1,2; 2,1];
(* 3-cycle with in and out edges *)
test 5 [0,1; 1,2; 2,0; 3,0; 2,4];
(* 3 cycles in a row *)
test 7 [0,1; 1,0; 1,2; 2,3; 3,2; 3,4; 4,5; 5,6; 6,4];
(* 3 cycles with 2 cycles in a cycle *)
test 7 [0,1; 1,0; 1,2; 2,3; 3,2; 3,4; 4,5; 5,6; 6,4; 5,2];
printf "test topsort: all tests succeeded.@."
let () = tests Topological.iter
(* let () = tests Topological.iter_stable *)
let rec pow a = function
| 0 -> 1
| 1 -> a
| n ->
let b = pow a (n / 2) in
b * b * (if n mod 2 = 0 then 1 else a)
let () =
for n_iter = 0 to 5 do
let n = pow 10 n_iter in
let el = ref [] in
(* linear graph *)
(* for i = 0 to n-2 do el := (i,i+1) :: !el done; *)
(* for i = 0 to n-2 do el := (i+1,i) :: !el done; *)
el := [n-1,0]; for i = 0 to n-2 do el := (i,i+1) :: !el done;
test ~check:false Topological.iter n !el
done
ocamlgraph-2.0.0/tests/test_components.expected 0000644 0001750 0000144 00000000123 13735627615 020316 0 ustar rt users 7 components
0 -> 0
1 -> 1
2 -> 1
3 -> 2
4 -> 3
5 -> 3
6 -> 4
7 -> 5
8 -> 6
9 -> 0
ocamlgraph-2.0.0/tests/test_fixpoint.expected 0000644 0001750 0000144 00000000446 13735627615 020001 0 ustar rt users Labels for 2: 2, 4, 6, 8, 10, 12, 14
Labels for 3: 3, 6, 9, 12, 15
Labels for 4: 4, 8, 12
Labels for 5: 5, 10, 15
Labels for 6: 6, 12
Labels for 7: 7, 14
Labels for 8: 8
Labels for 9: 9
Labels for 10: 10
Labels for 11: 11
Labels for 12: 12
Labels for 13: 13
Labels for 14: 14
Labels for 15: 15
ocamlgraph-2.0.0/tests/test_components.ml 0000644 0001750 0000144 00000003057 13735627615 017136 0 ustar rt users (**************************************************************************)
(* *)
(* Ocamlgraph: a generic graph library for OCaml *)
(* Copyright (C) 2004-2007 *)
(* 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, 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. *)
(* *)
(**************************************************************************)
open Format
open Graph
module C = Components.Undirected(Pack.Graph)
open Pack.Graph
let () =
let g = Rand.graph ~v:10 ~e:3 () in
let n, f = C.components g in
printf "%d components@." n;
iter_vertex (fun v -> printf "%d -> %d@." (V.label v) (f v)) g
(*
Local Variables:
compile-command: "ocaml -I .. graph.cma test_components.ml"
End:
*)
ocamlgraph-2.0.0/tests/testgraphml.ml 0000644 0001750 0000144 00000003401 13735627615 016235 0 ustar rt users (******************************************************************************)
(* *)
(* Copyright (C) 2012 Pietro Abate *)
(* *)
(* This library is free software: you can redistribute it and/or modify *)
(* it under the terms of the GNU Lesser General Public License as *)
(* published by the Free Software Foundation, either version 3 of the *)
(* License, or (at your option) any later version. A special linking *)
(* exception to the GNU Lesser General Public License applies to this *)
(* library, see the COPYING file for more information. *)
(* *)
(******************************************************************************)
module V = struct
type t = int
let compare = compare
let hash i = i
let equal = (=)
end
module G = Graph.Imperative.Digraph.ConcreteBidirectional(V)
module Gr = struct
include G
let vertex_properties = ["id1","string",None; "id2","string",Some "2"]
let edge_properties = ["ed", "string",Some "3"]
let map_edge e = ["ed", string_of_int (E.dst e)]
let map_vertex v = [ "id1", string_of_int v ; "id2", string_of_int v]
let vertex_uid = G.V.hash
let edge_uid e =
Hashtbl.hash (vertex_uid (G.E.src e), G.E.label e, vertex_uid (G.E.dst e))
end
module GraphPrinter = Graph.Graphml.Print(G)(Gr)
let print g = GraphPrinter.print Format.std_formatter g
let () =
let g = G.create () in
G.add_vertex g 1;
G.add_vertex g 2;
G.add_vertex g 3;
G.add_edge g 1 2;
G.add_edge g 1 3;
print g;;
ocamlgraph-2.0.0/tests/basic.expected 0000644 0001750 0000144 00000000155 13735627615 016160 0 ustar rt users [1 -> 2][2 -> 3][3 -> 5]
1 -> 2
1 -> 5
2 -> 3
3 -> 2
3 -> 5
3 components
1 -> 2
2 -> 1
3 -> 1
5 -> 0
ocamlgraph-2.0.0/LICENSE 0000644 0001750 0000144 00000065616 13735627615 013234 0 ustar rt users The Library is distributed under the terms of the GNU Library General
Public License version 2.1 (included below).
As a special exception to the GNU Library General Public License, you
may link, statically or dynamically, a "work that uses the Library"
with a publicly distributed version of the Library to produce an
executable file containing portions of the Library, and distribute
that executable file under terms of your choice, without any of the
additional requirements listed in clause 6 of the GNU Library General
Public License. By "a publicly distributed version of the Library", we
mean either the unmodified Library as distributed, or a
modified version of the Library that is distributed under the
conditions defined in clause 3 of the GNU Library General Public
License. This exception does not however invalidate any other reasons
why the executable file might be covered by the GNU Library General
Public License.
======================================================================
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations
below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it
becomes a de-facto standard. To achieve this, non-free programs must
be allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control
compilation and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at least
three years, to give the same user the materials specified in
Subsection 6a, above, for a charge no more than the cost of
performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply, and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License
may add an explicit geographical distribution limitation excluding those
countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms
of the ordinary General Public License).
To apply these terms, attach the following notices to the library.
It is safest to attach them to the start of each source file to most
effectively convey the exclusion of warranty; and each file should
have at least the "copyright" line and a pointer to where the full
notice is found.
Copyright (C)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or
your school, if any, to sign a "copyright disclaimer" for the library,
if necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James
Random Hacker.
, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!
ocamlgraph-2.0.0/INSTALL.md 0000644 0001750 0000144 00000001020 13735627615 013632 0 ustar rt users
The simplest way to install OCamlGraph is via opam.
If instead you choose to compile OCamlGraph from sources,
the simplest way is to use `dune`.
Otherwise, you can still use the old way:
- Configure with
```
autoconf
./configure
```
- Compile with
```
make
```
- Install (as root if needed) with
```
make install
```
To install somewhere else, with a different path prefix, use instead
```
make DESTDIR=/another/place install
```
findlib users may also do
```
make install-findlib
```
ocamlgraph-2.0.0/dune-project 0000644 0001750 0000144 00000000104 13735627615 014526 0 ustar rt users (lang dune 2.0)
(name ocamlgraph)
(formatting (enabled_for dune))
ocamlgraph-2.0.0/ocamlgraph.opam 0000644 0001750 0000144 00000001446 13735627615 015211 0 ustar rt users opam-version: "2.0"
synopsis: "A generic graph library for OCaml"
description: "Provides both graph data structures and graph algorithms"
maintainer: ["filliatr@lri.fr"]
authors: ["Sylvain Conchon" "Jean-Christophe Filliâtre" "Julien Signoles"]
license: "LGPL-2.1-only"
tags: [
"graph"
"library"
"algorithms"
"directed graph"
"vertice"
"edge"
"persistent"
"imperative"
]
homepage: "https://github.com/backtracking/ocamlgraph/"
bug-reports: "https://github.com/backtracking/ocamlgraph/issues/new"
depends: [
"ocaml"
"stdlib-shims"
"dune" {>= "2.0"}
]
build: [
["dune" "subst"] {pinned}
[
"dune"
"build"
"-p"
name
"-j"
jobs
"@install"
"@runtest" {with-test}
"@doc" {with-doc}
]
]
dev-repo: "git+https://github.com/backtracking/ocamlgraph.git"
ocamlgraph-2.0.0/.merlin 0000644 0001750 0000144 00000000140 13735627615 013473 0 ustar rt users S src
S lib
S dgraph
B src
B lib
B dgraph
B .
PKG lablgtk2
FLG -w +a -w -4 -w -44 -w -48 -w -29
ocamlgraph-2.0.0/examples/ 0000755 0001750 0000144 00000000000 13735627615 014027 5 ustar rt users ocamlgraph-2.0.0/examples/sudoku.ml 0000644 0001750 0000144 00000006174 13735627615 015703 0 ustar rt users (**************************************************************************)
(* *)
(* Ocamlgraph: a generic graph library for OCaml *)
(* Copyright (C) 2004-2007 *)
(* 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, 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. *)
(* *)
(**************************************************************************)
(* Ocamlgraph demo program: solving the Sudoku puzzle using graph coloring *)
open Format
open Graph
(* We use undirected graphs with nodes containing a pair of integers
(the cell coordinates in 0..8 x 0..8).
The integer marks of the nodes will store the colors. *)
module G = Imperative.Graph.Abstract(struct type t = int * int end)
(* The Sudoku grid = a graph with 9x9 nodes *)
let g = G.create ()
(* We create the 9x9 nodes, add them to the graph and keep them in a matrix
for later access *)
let nodes =
let new_node i j = let v = G.V.create (i, j) in G.add_vertex g v; v in
Array.init 9 (fun i -> Array.init 9 (new_node i))
let node i j = nodes.(i).(j) (* shortcut for easier access *)
(* We add the edges:
two nodes are connected whenever they can't have the same value,
i.e. they belong to the same line, the same column or the same 3x3 group *)
let () =
for i = 0 to 8 do for j = 0 to 8 do
for k = 0 to 8 do
if k <> i then G.add_edge g (node i j) (node k j);
if k <> j then G.add_edge g (node i j) (node i k);
done;
let gi = 3 * (i / 3) and gj = 3 * (j / 3) in
for di = 0 to 2 do for dj = 0 to 2 do
let i' = gi + di and j' = gj + dj in
if i' <> i || j' <> j then G.add_edge g (node i j) (node i' j')
done done
done done
(* Displaying the current state of the graph *)
let display () =
for i = 0 to 8 do
for j = 0 to 8 do printf "%d" (G.Mark.get (node i j)) done;
printf "\n";
done;
printf "@?"
(* We read the initial constraints from standard input and we display g *)
let () =
for i = 0 to 8 do
let s = read_line () in
for j = 0 to 8 do match s.[j] with
| '1'..'9' as ch -> G.Mark.set (node i j) (Char.code ch - Char.code '0')
| _ -> ()
done
done;
display ();
printf "---------@."
(* We solve the Sudoku by 9-coloring the graph g and we display the solution *)
module C = Coloring.Mark(G)
let () =
C.coloring g 9; display ()
ocamlgraph-2.0.0/examples/demo.ml 0000644 0001750 0000144 00000021171 13735627615 015307 0 ustar rt users (**************************************************************************)
(* *)
(* Ocamlgraph: a generic graph library for OCaml *)
(* Copyright (C) 2004-2007 *)
(* 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, 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. *)
(* *)
(**************************************************************************)
open Format
open Graph
let v_ = ref 30
let prob_ = ref 0.5
let seed_ = ref None
let interactive_ = ref false
type algo = TransitiveClosure | TransitiveReduction | Prim | Kruskal |
Dijkstra | Bfs | Dfs
let algo = ref None
let arg_spec =
["-v", Arg.Int (fun i -> v_ := i),
" number of vertices";
"--prob", Arg.Float (fun f -> prob_ := f),
" probability to discrad an edge";
"--seed", Arg.Int (fun n -> seed_ := Some n),
" random seed";
"--transitive-closure", Arg.Unit (fun () -> algo := Some TransitiveClosure),
" display transitive closure in blue";
"--transitive-reduction", Arg.Unit (fun () ->
algo := Some TransitiveReduction),
" display useless edges in blue";
"--prim", Arg.Unit (fun () -> algo := Some Prim),
" Prim's algorithm";
"--kruskal", Arg.Unit (fun () -> algo := Some Kruskal),
" Kruskal's algorithm";
"--dijkstra", Arg.Unit (fun () -> algo := Some Dijkstra),
" Dijkstra's algorithm";
"--dfs", Arg.Unit (fun () -> algo := Some Dfs),
" Depth-First Search's algorithm";
"--bfs", Arg.Unit (fun () -> algo := Some Bfs),
" Breadth-First Search's algorithm";
"-i", Arg.Set interactive_, " run algorithms interactively";
]
let () = Arg.parse arg_spec (fun _ -> ()) "usage: color "
let v = !v_
let prob = !prob_
let interactive = !interactive_
let seed = match !seed_ with
| None -> Random.self_init (); Random.int (1 lsl 29)
| Some s -> s
let () = printf "seed = %d@." seed; Random.init seed
let () = if interactive then
printf "interactive mode (press any key to step in algorithm, q to quit)@."
module G = struct
module IntInt = struct
type t = int * int
let compare = Stdlib.compare
let equal = (=)
let hash = Hashtbl.hash
end
module Int = struct
type t = int
let compare = Stdlib.compare
let hash = Hashtbl.hash
let equal = (=)
let default = 0
end
include Imperative.Digraph.ConcreteLabeled(IntInt)(Int)
end
(* a random graph with n vertices *)
module R = Rand.Planar.I(G)
let g = R.graph ~xrange:(20,780) ~yrange:(20,580)~prob v
module Draw = struct
open Graphics
let () = open_graph " 800x600"
let vertex_radius = 5
let round f = truncate (f +. 0.5)
let pi = 4.0 *. atan 1.0
let draw_arrow ?(color=black) ?(width=1) (xu,yu) (xv,yv) =
set_color color;
set_line_width width;
let dx = float (xv - xu) in
let dy = float (yv - yu) in
let alpha = atan2 dy dx in
let r = sqrt (dx *. dx +. dy *. dy) in
let ra = float vertex_radius *. 1.5 in
let d = float vertex_radius +. 3. in
let xs, ys = float xu +. d *. dx /. r, float yu +. d *. dy /. r in
let xd, yd = float xv -. d *. dx /. r, float yv -. d *. dy /. r in
let coords theta =
round (xd +. ra *. cos (pi +. alpha +. theta)),
round (yd +. ra *. sin (pi +. alpha +. theta))
in
moveto (round xs) (round ys);
lineto (round xd) (round yd);
let x1,y1 = coords (pi /. 6.) in
moveto (round xd) (round yd); lineto x1 y1;
let x2,y2 = coords (-. pi /. 6.) in
moveto (round xd) (round yd); lineto x2 y2
let draw_edge ?color ?width v1 v2 =
draw_arrow ?color ?width (G.V.label v1) (G.V.label v2)
let draw_vertex ?(color=red) ?(width=1) v =
let (x,y) = G.V.label v in
set_line_width width;
set_color color;
draw_circle x y vertex_radius
let color_vertex v color =
let x,y = G.V.label v in
set_color color;
fill_circle x y vertex_radius
let draw_graph ?color ?width g =
clear_graph ();
G.iter_vertex draw_vertex g;
G.iter_edges (draw_edge ?color ?width) g
let draw_edges ?(color=blue) ?(width=2) el =
List.iter
(fun e ->
draw_edge ~color ~width (G.E.src e) (G.E.dst e);
draw_vertex ~color ~width (G.E.src e);
draw_vertex ~color ~width (G.E.dst e)
) el
let pause () =
let st = wait_next_event [Key_pressed] in
if st.key = 'q' then begin close_graph (); exit 0 end
let draw_iteration ?(interactive=false) f g =
f (fun v -> color_vertex v Graphics.red; if interactive then pause ()) g
end
module W = struct
type edge = G.E.t
type t = int
let weight = G.E.label
let zero = 0
let add = (+)
let sub = (-)
let compare = compare
end
module PathWeight = struct
type edge = G.E.t
type t = int
let weight x = G.E.label x
let zero = 0
let add = (+)
let sub = (-)
let compare = compare
end
module Selection = struct
type selection =
| No
| One of G.V.t
| Two of G.V.t * G.V.t
let selection = ref No
let draw_selection () = match !selection with
| No -> ()
| One v1 -> Draw.color_vertex v1 Graphics.blue
| Two (v1, v2) -> Draw.color_vertex v1 Graphics.blue;
Draw.color_vertex v2 Graphics.green
let distance (x1,y1) (x2,y2) =
let dx = float (x1 - x2) in
let dy = float (y1 - y2) in
Draw.round (sqrt (dx *. dx +. dy *. dy))
let select g =
let select_vertex v = match !selection with
| No -> selection := One v
| One v1 -> selection := Two (v1, v)
| Two (_, v2) -> selection := Two (v2, v)
in
let p = Graphics.mouse_pos () in
try
G.iter_vertex
(fun v ->
if distance p (G.V.label v) <= Draw.vertex_radius then begin
select_vertex v; Draw.draw_graph g; draw_selection (); raise Exit
end)
g
with Exit -> ()
let select2 g =
printf "please select two vertices...@.";
printf "press r to run...@.";
printf "press q to quit...@.";
let continue = ref true in
while !continue do
let st = Graphics.wait_next_event [ Graphics.Key_pressed;
Graphics.Button_down ] in
if st.Graphics.keypressed then match st.Graphics.key with
| 'r' ->
begin match !selection with
| Two (_,_) -> continue := false
| _ -> printf "please select two vertices...@."
end
| 'q' -> raise Exit
| _ -> ()
else if st.Graphics.button then
select g
done;
match !selection with
| Two (v1,v2) -> (v1,v2)
| _ -> assert false
end
let () = Draw.draw_graph g
let () = match !algo with
| Some Dijkstra -> ()
| _ -> ignore (Graphics.wait_next_event [Graphics.Key_pressed ])
let () = match !algo with
| Some TransitiveClosure ->
let module O = Oper.I(G) in
let tg = O.transitive_closure g in
G.iter_edges
(fun v1 v2 ->
if not (G.mem_edge g v1 v2) then
Draw.draw_edge ~color:Graphics.blue v1 v2) tg
| Some TransitiveReduction ->
Draw.draw_graph ~color:Graphics.blue g;
let module O = Oper.I(G) in
let tr = O.transitive_reduction g in
G.iter_edges Draw.draw_edge tr;
ignore (Graphics.wait_next_event [Graphics.Key_pressed ]);
Draw.draw_graph tr
| Some Prim ->
let module P = Prim.Make(G)(W) in
let el = P.spanningtree g in
Draw.draw_edges el
| Some Kruskal ->
let module P = Kruskal.Make(G)(W) in
let el = P.spanningtree g in
Draw.draw_edges el
| Some Dijkstra ->
let module Dij = Path.Dijkstra(G)(PathWeight) in
let rec recherche () =
let (v1, v2) = Selection.select2 g in
begin
try
let (p, _) = Dij.shortest_path g v1 v2 in
Draw.draw_edges ~color:Graphics.red p
with Not_found ->
printf "no path found...@.";
recherche ()
end
in
recherche ()
| Some Dfs ->
let module Dfs = Traverse.Dfs(G) in
Draw.draw_iteration ~interactive Dfs.prefix g
| Some Bfs ->
let module Bfs = Traverse.Bfs(G) in
Draw.draw_iteration ~interactive Bfs.iter g
| None -> ()
let () =
ignore (Graphics.wait_next_event [Graphics.Key_pressed ]);
Graphics.close_graph ()
ocamlgraph-2.0.0/examples/demo_prim.ml 0000644 0001750 0000144 00000007533 13735627615 016344 0 ustar rt users (**************************************************************************)
(* *)
(* Ocamlgraph: a generic graph library for OCaml *)
(* Copyright (C) 2004-2007 *)
(* 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, 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. *)
(* *)
(**************************************************************************)
(* Demo of Prim's algorithm *)
open Graph
(* command line *)
let n_ = ref 30
let prob_ = ref 0.5
let seed_ = ref None
let arg_spec =
["-v", Arg.Int (fun i -> n_ := i),
" number of vertices";
"-prob", Arg.Float (fun f -> prob_ := f),
" probability to discrad an edge";
"-seed", Arg.Int (fun n -> seed_ := Some n),
" random seed"
]
let () = Arg.parse arg_spec (fun _ -> ()) "usage: color "
let n = !n_
let prob = !prob_
let seed = match !seed_ with
| None -> Random.self_init (); Random.int (1 lsl 29)
| Some s -> s
let () = Format.printf "seed = %d@." seed; Random.init seed
(* undirected graphs with integer coordinates and integer labels on edges *)
module IntInt = struct
type t = int * int
let compare = compare
let hash = Hashtbl.hash
let equal = (=)
let default = (0, 0)
end
module Int = struct
type t = int
let compare = compare
let hash = Hashtbl.hash
let equal = (=)
let default = 0
end
module G = Imperative.Graph.ConcreteLabeled(IntInt)(Int)
(* a random graph with n vertices *)
module R = Rand.Planar.I(G)
let g0 = R.graph ~xrange:(20,780) ~yrange:(20,580) ~prob n
(* drawing *)
let round f = truncate (f +. 0.5)
let pi = 4.0 *. atan 1.0
open Graphics
let () = open_graph " 800x600"
let vertex_radius = 5
let draw_edge ?(color=black) v1 v2 =
let (xu,yu) = G.V.label v1 in
let (xv,yv) = G.V.label v2 in
set_color color;
let dx = float (xv - xu) in
let dy = float (yv - yu) in
let r = sqrt (dx *. dx +. dy *. dy) in
let d = float vertex_radius +. 3. in
let xs, ys = float xu +. d *. dx /. r, float yu +. d *. dy /. r in
let xd, yd = float xv -. d *. dx /. r, float yv -. d *. dy /. r in
moveto (round xs) (round ys);
lineto (round xd) (round yd)
let draw_vertex ?(color=red) v =
let (x,y) = G.V.label v in
set_color color;
draw_circle x y vertex_radius
let color_vertex v color =
let x,y = G.V.label v in
set_color color;
fill_circle x y vertex_radius
let draw_graph () =
clear_graph ();
set_color red;
set_line_width 1;
G.iter_vertex draw_vertex g0;
G.iter_edges draw_edge g0
module W = struct
type edge = G.E.t
type label = G.E.label
type t = int
let weight (_, x, _: edge) : t = x
let zero = 0
let add = (+)
let compare = compare
end
module P = Prim.Make(G)(W)
let () =
draw_graph ();
ignore (Graphics.wait_next_event [ Key_pressed ]);
let el = P.spanningtree g0 in
set_line_width 2;
List.iter
(fun e ->
draw_edge ~color:blue (G.E.src e) (G.E.dst e);
draw_vertex ~color:blue (G.E.src e);
draw_vertex ~color:blue (G.E.dst e)
) el;
ignore (Graphics.wait_next_event [ Key_pressed ]);
close_graph ()
ocamlgraph-2.0.0/examples/compare_prim_kruskal.ml 0000644 0001750 0000144 00000006656 13735627615 020607 0 ustar rt users (**************************************************************************)
(* *)
(* Ocamlgraph: a generic graph library for OCaml *)
(* Copyright (C) 2004-2007 *)
(* 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, 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. *)
(* *)
(**************************************************************************)
(* Kruskal and Prim tests *)
open Printf
open Graph
(* command line *)
let v_ = ref 30
let e_ = ref 50
let seed_ = ref None
let debug_ = ref false
let arg_spec =
["-v", Arg.Int (fun i -> v_ := i),
" number of vertices";
"-e", Arg.Int (fun i -> e_ := i),
" number of edges";
"-seed", Arg.Int (fun n -> seed_ := Some n),
" random seed";
"--debug", Arg.Set debug_, "set the debug flag";
]
let () = Arg.parse arg_spec (fun _ -> ()) "usage: color "
let v = !v_
let e = !e_
let debug = !debug_
let seed = match !seed_ with
| None -> Random.self_init (); Random.int (1 lsl 29)
| Some s -> s
let () = Format.printf "seed = %d@." seed; Random.init seed
(* undirected graphs with integer coordinates and integer labels on edges *)
module Int = struct
type t = int
let compare = compare
let hash = Hashtbl.hash
let equal = (=)
let default = 0
end
module G = Imperative.Graph.AbstractLabeled(Int)(Int)
module R = Rand.I(G)
module W = struct
type label = G.E.label
type edge = G.E.t
type t = int
let weight x = G.E.label x
let zero = 0
let add = (+)
let compare = compare
end
module Time = struct
open Unix
let utime f x =
let u = (times()).tms_utime in
let y = f x in
let ut = (times()).tms_utime -. u in
y, ut
(* runs f 5 times, removes minimum and maximum timings, and
returns the mean of the remaining three timings *)
let time5 f x =
let t = Array.init 5 (fun _ -> snd (utime f x)) in
if debug then Array.iter (fun x -> Printf.printf "%2.2f\n" x) t;
Array.sort Stdlib.compare t;
(t.(1) +. t.(2) +. t.(3)) /. 3.
let print f x =
let (y,ut) = utime f x in
printf "user time: %2.2f@." ut;
y
end
module P1 = Kruskal.Make(G)(W)
module P2 = Prim.Make(G)(W)
let testp g =Time.time5 P1.spanningtree g
let testk g = Time.time5 P2.spanningtree g
let test nb_v nb_e =
Printf.printf "Execution time v=%d - e=%d\n" nb_v nb_e;
let g = R.graph ~v:nb_v ~e:nb_e () in
let resp = testp g in
Printf.printf "PRIM : %2.2fs\n" resp;
let resk = testk g in
Printf.printf "KRUSKAL : %2.2fs\n%!" resk
let () = test v e ocamlgraph-2.0.0/examples/demo_planar.ml 0000644 0001750 0000144 00000025410 13735627615 016644 0 ustar rt users (**************************************************************************)
(* *)
(* Ocamlgraph: a generic graph library for OCaml *)
(* Copyright (C) 2004-2007 *)
(* 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, 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. *)
(* *)
(**************************************************************************)
open Printf
open Graph
module U = Unix
let utime f x =
let u = (U.times()).U.tms_utime in
let y = f x in
let ut = (U.times()).U.tms_utime -. u in
(y,ut)
let print_utime f x =
let (y,ut) = utime f x in
Printf.printf "user time: %2.2f\n" ut; flush Stdlib.stdout;
y
let () =
printf "planar graphs demo
use mouse to select two vertices (blue = source, green = destination)
keys are
- `r' generates a new random graph
- `d' runs DFS
- `b' runs BFS
- `p' runs Dijkstra's shortest path
- `c' runs SCC
- `j' runs Johnson shortest path
- `q' to quit
";
flush stdout
(* directed graphs with integer coordinates and integer labels on edges *)
module IntInt = struct
type t = int * int
end
module Int = struct
type t = int
let compare = compare
let hash = Hashtbl.hash
let equal = (=)
let default = 0
end
module G = Imperative.Digraph.AbstractLabeled(IntInt)(Int)
open G
let n_ = ref 30
let prob_ = ref 0.5
let () =
Arg.parse
["-v", Arg.Int (fun i -> n_ := i),
" number of vertices";
"-prob", Arg.Float (fun f -> prob_ := f),
" probability to discrad an edge";
]
(fun _ -> ())
"usage: demo_planar "
let n = !n_
let prob = !prob_
let round f = truncate (f +. 0.5)
let pi = 4.0 *. atan 1.0
module Point = struct
type point = V.t
let ccw v1 v2 v3 =
Delaunay.IntPoints.ccw (V.label v1) (V.label v2) (V.label v3)
let in_circle v1 v2 v3 v4 =
Delaunay.IntPoints.in_circle
(V.label v1) (V.label v2) (V.label v3) (V.label v4)
let distance v1 v2 =
let x1,y1 = V.label v1 in
let x2,y2 = V.label v2 in
let sqr x = let x = float x in x *. x in
truncate (sqrt (sqr (x1 - x2) +. sqr (y1 - y2)))
end
module Triangulation = Delaunay.Make(Point)
let read_graph f =
let c = open_in f in
let l = ref [] in
try
while true do
let s = input_line c in
let x,y = Scanf.sscanf s "%d %f %f" (fun _ x y -> x,y) in
printf "x=%f y=%f\n" x y;
l := (x,y) :: !l
done;
assert false
with End_of_file ->
close_in c;
let rec min_list cmp = function
| [] -> assert false
| [x] -> x
| x :: l -> let m = min_list cmp l in if cmp x m then x else m
in
let xmin,_ = min_list (fun (x,_) (x',_) -> x < x') !l in
let xmax,_ = min_list (fun (x,_) (x',_) -> x > x') !l in
let _,ymin = min_list (fun (_,y) (_,y') -> y < y') !l in
let _,ymax = min_list (fun (_,y) (_,y') -> y > y') !l in
let calibrate (x,y) =
round (20. +. 760. *. (x -. xmin) /. (xmax -. xmin)),
round (20. +. 560. *. (y -. ymin) /. (ymax -. ymin))
in
let vertices =
Array.map (fun xy -> V.create (calibrate xy)) (Array.of_list !l)
in
let t = Triangulation.triangulate vertices in
let g = create () in
Array.iter (G.add_vertex g) vertices;
let add_edge v1 v2 =
let e = E.create v1 (Point.distance v1 v2) v2 in G.add_edge_e g e
in
Triangulation.iter (fun v1 v2 -> add_edge v1 v2; add_edge v2 v1) t;
g
(* a random digraph with n vertices *)
let () = Random.self_init ()
module R = Rand.Planar.I(G)
let new_graph () = R.graph ~xrange:(20,780) ~yrange:(20,580) ~prob n
let g = ref (new_graph ())
let () = printf "nb edges : %d\n" (G.nb_edges !g); flush stdout
let dump_graph () =
G.iter_edges (fun v1 v2 ->
let x1, y1 = G.V.label v1 in
let x2, y2 = G.V.label v2 in
Format.printf "%d,%d,%d,%d@\n" x1 y1 x2 y2) !g;
Format.printf "@?"
(* let () = g := read_graph "tmp/carron.txt" *)
open Graphics
let () = open_graph " 800x600"
let vertex_radius = 5
let draw_arrow ?(color=black) ?(width=1) (xu,yu) (xv,yv) =
set_color color;
set_line_width width;
let dx = float (xv - xu) in
let dy = float (yv - yu) in
let alpha = atan2 dy dx in
let r = sqrt (dx *. dx +. dy *. dy) in
let ra = float vertex_radius *. 1.5 in
let d = float vertex_radius +. 3. in
let xs, ys = float xu +. d *. dx /. r, float yu +. d *. dy /. r in
let xd, yd = float xv -. d *. dx /. r, float yv -. d *. dy /. r in
let coords theta =
round (xd +. ra *. cos (pi +. alpha +. theta)),
round (yd +. ra *. sin (pi +. alpha +. theta))
in
moveto (round xs) (round ys);
lineto (round xd) (round yd);
let x1,y1 = coords (pi /. 6.) in
moveto (round xd) (round yd); lineto x1 y1;
let x2,y2 = coords (-. pi /. 6.) in
moveto (round xd) (round yd); lineto x2 y2
let color_vertex v color =
let x,y = G.V.label v in
set_color color;
fill_circle x y vertex_radius
type selection =
| No
| One of G.V.t
| Two of G.V.t * G.V.t
let selection = ref No
let draw_selection () = match !selection with
| No -> ()
| One v1 -> color_vertex v1 blue
| Two (v1, v2) -> color_vertex v1 blue; color_vertex v2 green
let draw_graph () =
clear_graph ();
set_color red;
set_line_width 1;
G.iter_vertex
(fun v ->
let (x,y) = G.V.label v in
draw_circle x y vertex_radius)
!g;
set_color black;
G.iter_edges
(fun v1 v2 -> draw_arrow (G.V.label v1) (G.V.label v2))
!g;
draw_selection ()
let distance (x1,y1) (x2,y2) =
let dx = float (x1 - x2) in
let dy = float (y1 - y2) in
round (sqrt (dx *. dx +. dy *. dy))
let select () =
let select_vertex v = match !selection with
| No -> selection := One v
| One v1 -> selection := Two (v1, v)
| Two (_, v2) -> selection := Two (v2, v)
in
let p = mouse_pos () in
try
G.iter_vertex
(fun v ->
if distance p (G.V.label v) <= vertex_radius then begin
select_vertex v; draw_graph (); raise Exit
end)
!g
with Exit ->
()
module W = struct
type edge = G.E.t
type t = int
let weight x = G.E.label x
let zero = 0
let add = (+)
let sub = (-)
let compare = compare
end
module Dij = Path.Dijkstra(G)(W)
let dijkstra () = match !selection with
| Two (v1, v2) ->
printf "running Dijkstra... "; flush stdout;
let t_ = ref 0.0 in
begin try
let (p,l),t = utime (Dij.shortest_path !g v1) v2 in
t_ := t;
printf "path of length %d (%d nodes) (%2.2f s)\n" l (List.length p) t;
flush stdout;
List.iter
(fun e ->
let v1 = G.E.src e in
let v2 = G.E.dst e in
draw_arrow ~color:red ~width:3 (G.V.label v1) (G.V.label v2))
p;
ignore (Graphics.wait_next_event [ Key_pressed; Button_down ]);
draw_graph ()
with Not_found ->
printf "no path (%2.2f s)\n" !t_; flush stdout
end
| _ ->
()
module J = Path.Johnson(G)(W)
let johnson () =
match !selection with
| Two (v1, v2) ->
printf "running Johnson... "; flush stdout;
let t_ = ref 0.0 in
begin try
let paths, t = utime (J.all_pairs_shortest_paths) !g in
t_ := t;
printf "path of length %d (%2.2f s)\n" (J.HVV.find paths (v1, v2)) t;
flush stdout
with Not_found ->
printf "no path (%2.2f s)\n" !t_; flush stdout
end
| _ -> ()
let draw_iteration f =
let pause () = for _ = 1 to 10000000 do () done in
f (fun v -> color_vertex v red; pause ()) !g;
ignore (Graphics.wait_next_event [ Key_pressed; Button_down ]);
draw_graph ()
module Dfs = Traverse.Dfs(G)
let dfs () = draw_iteration Dfs.prefix
module Bfs = Traverse.Bfs(G)
let bfs () = draw_iteration Bfs.iter
let golden_ratio = 0.618033988749895
let hsv_to_rgb h s v =
let c = v *. s in
let h = int_of_float h in
let hh = (h mod 360)/60 in
let hhf = (mod_float (float_of_int h) 360.) /. 60. in
let x = c *. (1. -. (abs_float (mod_float hhf 2. -. 1.))) in
let m = v -. c in
let cc = int_of_float ((c +. m) *. 255.) in
let xx = int_of_float ((x +. m) *. 255.) in
let mm = int_of_float (m *. 255.) in
match hh with
| 0 -> cc, xx, mm
| 1 -> xx, cc, mm
| 2 -> mm, cc, xx
| 3 -> mm, xx, cc
| 4 -> xx, mm, cc
| 5 -> cc, mm, xx
| _ -> mm, mm, mm
module Scc = Components.Make(G)
let scc () =
printf "running scc ... "; flush stdout;
let (n_scc, map_scc) = Scc.scc !g in
printf "number of components: %d\n" n_scc; flush stdout;
let colors = Hashtbl.create n_scc in
let inc = golden_ratio *. 360. in
Random.self_init ();
let h = ref (Random.float 360.) in
G.iter_vertex (
fun v -> try let color = Hashtbl.find colors (map_scc v) in
color_vertex v color
with Not_found ->
let color = hsv_to_rgb !h 0.7 0.95 in
h := !h +. inc;
let rgb (r, g, b) = rgb r g b in
let c = rgb color in
Hashtbl.add colors (map_scc v) c;
color_vertex v c) !g
(* brute-force coloring *)
let four_colors () =
(* vertices still to be colored are queued in [q] *)
let q = Queue.create () in
let rec loop () =
if not (Queue.is_empty q) then begin
let v = Queue.pop q in
assert (Mark.get v == 0);
try_color v 1 ||
try_color v 2 ||
try_color v 3 ||
try_color v 4 ||
(Mark.set v 0; Queue.add v q; false)
end else
true
and try_color v c =
(try
G.iter_succ (fun w -> if Mark.get w == c then raise Exit) !g v; true
with Exit ->
false) &&
(Mark.set v c; loop ())
in
G.iter_vertex (fun v -> Queue.add v q) !g;
Mark.clear !g;
assert (loop ());
let color = [| black; red; green; blue; yellow |] in
G.iter_vertex (fun v -> color_vertex v (color.(Mark.get v))) !g;
ignore (Graphics.wait_next_event [ Key_pressed; Button_down ])
let () =
try
let () = draw_graph () in
while true do
let st = Graphics.wait_next_event [ Key_pressed; Button_down ] in
if st.keypressed then match st.key with
| 'q' -> raise Exit
| 'r' -> g := new_graph (); selection := No; draw_graph ()
| 'p' -> dijkstra ()
| 'd' -> dfs ()
| 'b' -> bfs ()
| 'x' -> dump_graph ()
| 'c' -> scc ()
| 'j' -> johnson ()
(* | 'c' -> four_colors () *)
| _ -> ()
else if st.button then
select ()
done
with Exit ->
close_graph ()
ocamlgraph-2.0.0/examples/dune 0000644 0001750 0000144 00000000366 13735627615 014712 0 ustar rt users (executables
(names color compare_prim_kruskal demo_planar demo_prim demo sudoku)
(libraries graph unix graphics threads))
(alias
(name runtest)
(deps color.exe compare_prim_kruskal.exe demo_planar.exe demo_prim.exe
demo.exe sudoku.exe))
ocamlgraph-2.0.0/examples/color.ml 0000644 0001750 0000144 00000017073 13735627615 015507 0 ustar rt users (**************************************************************************)
(* *)
(* Ocamlgraph: a generic graph library for OCaml *)
(* Copyright (C) 2004-2007 *)
(* 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, 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. *)
(* *)
(**************************************************************************)
(* 4-coloring planar graphs *)
open Printf
open Graph
(* command line *)
let n_ = ref 30
let prob_ = ref 0.5
let seed_ = ref None
let arg_spec =
["-v", Arg.Int (fun i -> n_ := i),
" number of vertices";
"-prob", Arg.Float (fun f -> prob_ := f),
" probability to discrad an edge";
"-seed", Arg.Int (fun n -> seed_ := Some n),
" random seed"
]
let () = Arg.parse arg_spec (fun _ -> ()) "usage: color "
let n = !n_
let prob = !prob_
let seed = match !seed_ with
| None -> Random.self_init (); Random.int (1 lsl 29)
| Some s -> s
let () = Format.printf "seed = %d@." seed; Random.init seed
(* undirected graphs with integer coordinates and integer labels on edges *)
module IntInt = struct
type t = int * int
end
module Int = struct
type t = int
let compare = compare
let hash = Hashtbl.hash
let equal = (=)
let default = 0
end
module G = Imperative.Graph.AbstractLabeled(IntInt)(Int)
open G
(* a random graph with n vertices *)
module R = Rand.Planar.I(G)
let g0 = R.graph ~xrange:(20,780) ~yrange:(20,580) ~prob n
(* drawing *)
let round f = truncate (f +. 0.5)
let pi = 4.0 *. atan 1.0
open Graphics
let () = open_graph " 800x600"
let vertex_radius = 5
let draw_edge v1 v2 =
let (xu,yu) = G.V.label v1 in
let (xv,yv) = G.V.label v2 in
set_color black;
let dx = float (xv - xu) in
let dy = float (yv - yu) in
let r = sqrt (dx *. dx +. dy *. dy) in
let d = float vertex_radius +. 3. in
let xs, ys = float xu +. d *. dx /. r, float yu +. d *. dy /. r in
let xd, yd = float xv -. d *. dx /. r, float yv -. d *. dy /. r in
moveto (round xs) (round ys);
lineto (round xd) (round yd)
let draw_vertex v =
let (x,y) = G.V.label v in
set_color red;
draw_circle x y vertex_radius
let color_vertex v color =
let x,y = G.V.label v in
set_color color;
fill_circle x y vertex_radius
let draw_graph () =
clear_graph ();
set_color red;
set_line_width 1;
G.iter_vertex draw_vertex g0;
G.iter_edges draw_edge g0
module Dfs = Traverse.Dfs(G)
module Bfs = Traverse.Bfs(G)
let test_bfs () =
let rec loop i =
let v = Bfs.get i in
color_vertex v red;
ignore (Graphics.wait_next_event [ Key_pressed ]);
loop (Bfs.step i)
in
try loop (Bfs.start g0) with Exit -> ()
let test_dfs () =
let rec loop i =
let v = Dfs.get i in
color_vertex v red;
ignore (Graphics.wait_next_event [ Key_pressed ]);
loop (Dfs.step i)
in
try loop (Dfs.start g0) with Exit -> ()
let cols = [| white; red; green; blue; yellow; black |]
exception NoColor
(* Algo I. Brute force. *)
module C = Coloring.Mark(G)
let coloring_a _ =
Mark.clear g0;
C.coloring g0 4;
iter_vertex (fun v -> color_vertex v cols.(Mark.get v)) g0
(* Algo II.
we use marks to color; bits are used as follows:
0: set if node is discarded at step 1
1-4: available colors
5-7: the color (0 = not colored, else color in 1..4
*)
let print_8_bits x =
for i = 7 downto 0 do
if (x lsr i) land 1 = 1 then printf "1" else printf "0"
done
let dump () =
let dump_mark v = printf "["; print_8_bits (Mark.get v); printf "]" in
iter_vertex dump_mark g0;
printf "\n"; flush stdout
let mask_color = [| 0; 0b11101; 0b11011; 0b10111; 0b01111 |]
let coloring_b () =
(* initially all 4 colors available and every vertex to be colored *)
iter_vertex (fun v -> Mark.set v 0b11110) g0;
(* first step: we eliminate vertices with less than 4 successors *)
let stack = Stack.create () in
let finish = ref false in
let round = ref 1 in
let nb_to_color = ref n in
while not !finish do
let c = ref 0 in
finish := true;
let erase v =
incr c; finish := false; Mark.set v 0b11111; Stack.push v stack
in
G.iter_vertex
(fun v -> if Mark.get v = 0 && out_degree g0 v < 4 then erase v)
g0;
printf "round %d: removed %d vertices\n" !round !c;
incr round;
nb_to_color := !nb_to_color - !c
done;
flush stdout;
(* second step: we 4-color the remaining of the graph *)
(* [try_color v i] tries to assigne color [i] to vertex [v] *)
let try_color v i =
assert (1 <= i && i <= 4);
let m = Mark.get v in
assert (m lsr 5 = 0);
if (m lsr i) land 1 = 0 then raise NoColor; (* color [i] not available *)
let remove_color w =
(* make color [i] unavailable for [w] *)
let m = Mark.get w in
if m lsr 5 > 0 then
assert (m lsr 5 <> i) (* [w] already colored *)
else begin
let m' = m land mask_color.(i) in
if m' = 0 then raise NoColor; (* no more color available for [w] *)
Mark.set w m'
end
in
iter_succ remove_color g0 v;
Mark.set v (m lor (i lsl 5))
in
let uncolor v =
let m = Mark.get v in
let c = m lsr 5 in
assert (0 <= c && c <= 4);
if c > 0 then begin
Mark.set v (m land 0b11111);
let update w =
(* give back color [c] to [w] only when no more succ. has color [c] *)
try
iter_succ (fun u -> if Mark.get u lsr 5 = c then raise Exit) g0 w;
Mark.set w ((Mark.get w) lor (1 lsl c))
with Exit ->
()
in
iter_succ update g0 v
end
in
if !nb_to_color > 0 then begin
let rec iterate iter =
let v = Bfs.get iter in
if Mark.get v land 1 = 1 then
(* no need to color this vertex *)
iterate (Bfs.step iter)
else begin
for i = 1 to 4 do
try try_color v i; iterate (Bfs.step iter); assert false
with NoColor -> uncolor v
done;
raise NoColor
end
in
try iterate (Bfs.start g0) with Exit -> ()
end;
(* third step: we color the eliminated vertices, in reverse order *)
Stack.iter
(fun v ->
assert (Mark.get v land 1 = 1);
try
for i = 1 to 4 do
try try_color v i; raise Exit with NoColor -> uncolor v
done;
assert false (* we must succeed *)
with Exit -> ())
stack;
(* finally we display the coloring *)
iter_vertex
(fun v ->
let c = (Mark.get v) lsr 5 in
assert (1 <= c && c <= 4);
color_vertex v cols.(c))
g0
open Unix
let utime f x =
let u = (times()).tms_utime in
let y = f x in
let ut = (times()).tms_utime -. u in
(y,ut)
let print_utime f x =
let (y,ut) = utime f x in
Format.printf "user time: %2.2f@." ut;
y
let () =
draw_graph ();
(* test_bfs (); *)
(* test_dfs (); *)
print_utime coloring_a 4;
(*ignore (Graphics.wait_next_event [ Key_pressed ]);*)
(*draw_graph ();*)
print_utime coloring_b ();
ignore (Graphics.wait_next_event [ Key_pressed ]);
close_graph ()
ocamlgraph-2.0.0/COPYING 0000644 0001750 0000144 00000001141 13735627615 013241 0 ustar rt users Ocamlgraph: a generic graph library for ocaml
Copyright (C) 2004-2010
Sylvain Conchon, Jean-Christophe Filliâtre and Julien Signoles
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License version 2.1, as published by the Free Software Foundation.
This library 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.
See the GNU Library General Public License version 2.1 for more details
(enclosed in the file LICENSE).
ocamlgraph-2.0.0/CREDITS 0000644 0001750 0000144 00000000234 13735627615 013230 0 ustar rt users
Contributors, in alphabetic order
Sylvain Conchon
Jean-Christophe Filliâtre
François Pottier
Julien Signoles
Vincent Simonet
Matthieu Sozeau