1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
//! Generic directed graph infrastructure for program analysis.
//!
//! This module provides a reusable directed graph implementation designed for
//! program analysis tasks such as control flow graphs, call graphs, and dependency
//! analysis. The implementation prioritizes correctness, clear semantics, and
//! efficient algorithms over raw performance.
//!
//! # Architecture
//!
//! The graph module is organized into several components:
//!
//! - **Core Types**: [`NodeId`], [`EdgeId`], and [`DirectedGraph`] provide the fundamental
//! building blocks for graph representation
//! - **Algorithms**: Standard graph algorithms for traversal, dominator computation,
//! topological sorting, and cycle detection
//! - **Traits**: Abstraction traits enabling algorithms to work with different graph types
//!
//! # Design Principles
//!
//! ## Strongly-Typed Identifiers
//!
//! Node and edge identifiers use newtype wrappers to prevent accidental mixing of
//! indices and provide type safety at compile time.
//!
//! ## Immutable After Construction
//!
//! Graphs are designed to be built incrementally during construction, then treated
//! as immutable for analysis. This enables safe concurrent access without locks.
//!
//! ## Thread Safety
//!
//! All graph types are [`Send`] and [`Sync`] when their node and edge data types are,
//! enabling safe concurrent analysis across multiple threads.
//!
//! # Key Components
//!
//! - [`NodeId`] - Strongly-typed node identifier
//! - [`EdgeId`] - Strongly-typed edge identifier
//! - [`DirectedGraph`] - Core directed graph implementation with adjacency lists
//! - [`algorithms`] - Graph algorithms (traversal, dominators, SCC, etc.)
//!
//! # Usage Examples
//!
//! ## Creating a Simple Graph
//!
//! ```rust,ignore
//! use dotscope::graph::{DirectedGraph, NodeId};
//!
//! // Create a diamond-shaped graph: A -> B, A -> C, B -> D, C -> D
//! let mut graph: DirectedGraph<&str, &str> = DirectedGraph::new();
//!
//! let a = graph.add_node("A");
//! let b = graph.add_node("B");
//! let c = graph.add_node("C");
//! let d = graph.add_node("D");
//!
//! graph.add_edge(a, b, "A->B");
//! graph.add_edge(a, c, "A->C");
//! graph.add_edge(b, d, "B->D");
//! graph.add_edge(c, d, "C->D");
//!
//! assert_eq!(graph.node_count(), 4);
//! assert_eq!(graph.edge_count(), 4);
//! ```
//!
//! ## Traversing a Graph
//!
//! ```rust,ignore
//! use dotscope::graph::{DirectedGraph, NodeId, algorithms};
//!
//! let mut graph: DirectedGraph<&str, ()> = DirectedGraph::new();
//! let a = graph.add_node("A");
//! let b = graph.add_node("B");
//! let c = graph.add_node("C");
//! graph.add_edge(a, b, ());
//! graph.add_edge(b, c, ());
//!
//! // Depth-first traversal
//! let dfs_order: Vec<NodeId> = algorithms::dfs(&graph, a).collect();
//! assert_eq!(dfs_order.len(), 3);
//! ```
//!
//! ## Computing Dominators
//!
//! ```rust,ignore
//! use dotscope::graph::{DirectedGraph, NodeId, algorithms};
//!
//! let mut graph: DirectedGraph<&str, ()> = DirectedGraph::new();
//! let entry = graph.add_node("entry");
//! let a = graph.add_node("A");
//! let b = graph.add_node("B");
//! let exit = graph.add_node("exit");
//!
//! graph.add_edge(entry, a, ());
//! graph.add_edge(entry, b, ());
//! graph.add_edge(a, exit, ());
//! graph.add_edge(b, exit, ());
//!
//! let dominators = algorithms::compute_dominators(&graph, entry);
//! assert!(dominators.dominates(entry, exit)); // entry dominates exit
//! ```
//!
//! # Thread Safety
//!
//! All types in this module implement [`Send`] and [`Sync`] when their generic
//! parameters do, enabling safe concurrent access for analysis operations.
// Re-export core types at module level
pub use DirectedGraph;
pub use EdgeId;
pub use IndexedGraph;
pub use NodeId;
pub use ;