use trueno_graph::{
bfs, find_callers, find_patterns, louvain, pagerank, CsrGraph, NodeId, Pattern,
};
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("╔══════════════════════════════════════════════════════════════╗");
println!("║ trueno-graph Comprehensive Feature Demo ║");
println!("╚══════════════════════════════════════════════════════════════╝\n");
demo_phase1_and_phase2()?;
demo_phase4_community_detection()?;
demo_phase4_pattern_matching()?;
print_performance_summary();
print_gpu_info();
Ok(())
}
fn demo_phase1_and_phase2() -> Result<(), Box<dyn std::error::Error>> {
println!("📊 Phase 1+2: CSR Storage & CPU Algorithms");
println!("──────────────────────────────────────────────────────────────\n");
let graph = build_call_graph()?;
demo_bfs(&graph)?;
demo_find_callers(&graph)?;
demo_pagerank(&graph)?;
Ok(())
}
fn build_call_graph() -> Result<CsrGraph, Box<dyn std::error::Error>> {
let mut graph = CsrGraph::new();
graph.add_edge(NodeId(0), NodeId(1), 1.0)?; graph.add_edge(NodeId(0), NodeId(2), 1.0)?; graph.add_edge(NodeId(1), NodeId(3), 1.0)?; graph.add_edge(NodeId(1), NodeId(4), 1.0)?; graph.add_edge(NodeId(2), NodeId(4), 1.0)?;
graph.set_node_name(NodeId(0), "main".to_string());
graph.set_node_name(NodeId(1), "parse_args".to_string());
graph.set_node_name(NodeId(2), "process".to_string());
graph.set_node_name(NodeId(3), "validate".to_string());
graph.set_node_name(NodeId(4), "logger".to_string());
println!("✓ Built call graph with {} nodes and {} edges", graph.num_nodes(), graph.num_edges());
println!();
Ok(graph)
}
fn demo_bfs(graph: &CsrGraph) -> Result<(), Box<dyn std::error::Error>> {
println!("🔍 BFS Traversal from 'main':");
let reachable = bfs(graph, NodeId(0))?;
print!(" Reachable nodes: ");
for &node_id in &reachable {
if let Some(name) = graph.get_node_name(NodeId(node_id)) {
print!("{} ", name);
}
}
println!("\n");
Ok(())
}
fn demo_find_callers(graph: &CsrGraph) -> Result<(), Box<dyn std::error::Error>> {
println!("📞 Find Callers of 'logger':");
let callers = find_callers(graph, NodeId(4), 10)?;
print!(" Functions that call 'logger': ");
for &caller_id in &callers {
if let Some(name) = graph.get_node_name(NodeId(caller_id)) {
print!("{} ", name);
}
}
println!("\n");
Ok(())
}
fn demo_pagerank(graph: &CsrGraph) -> Result<(), Box<dyn std::error::Error>> {
println!("⭐ PageRank (Function Importance):");
let scores = pagerank(graph, 20, 1e-6)?;
for (node_id, &score) in scores.iter().enumerate() {
if let Some(name) = graph.get_node_name(NodeId(node_id as u32)) {
println!(" {}: {:.4}", name, score);
}
}
println!();
Ok(())
}
fn demo_phase4_community_detection() -> Result<(), Box<dyn std::error::Error>> {
println!("🧩 Phase 4: Advanced Algorithms");
println!("──────────────────────────────────────────────────────────────\n");
println!("Building graph with intentional module structure...");
let community_graph = build_community_graph()?;
println!("\n🔬 Louvain Community Detection:");
let louvain_result = louvain(&community_graph)?;
println!(" Found {} communities", louvain_result.num_communities);
println!(" Modularity score: {:.3}", louvain_result.modularity);
for (comm_id, community) in louvain_result.communities.iter().enumerate() {
println!(" Community {}: {} nodes", comm_id, community.len());
}
println!();
Ok(())
}
fn build_community_graph() -> Result<CsrGraph, Box<dyn std::error::Error>> {
let mut graph = CsrGraph::new();
graph.add_edge(NodeId(0), NodeId(1), 1.0)?; graph.add_edge(NodeId(1), NodeId(2), 1.0)?; graph.add_edge(NodeId(2), NodeId(0), 1.0)?;
graph.add_edge(NodeId(3), NodeId(4), 1.0)?; graph.add_edge(NodeId(4), NodeId(5), 1.0)?; graph.add_edge(NodeId(5), NodeId(3), 1.0)?;
graph.add_edge(NodeId(0), NodeId(3), 1.0)?;
Ok(graph)
}
fn demo_phase4_pattern_matching() -> Result<(), Box<dyn std::error::Error>> {
println!("🔍 Pattern Matching (Anti-Patterns):");
println!("──────────────────────────────────────────────────────────────\n");
let antipattern_graph = build_antipattern_graph()?;
demo_god_class_pattern(&antipattern_graph)?;
demo_circular_dependency_pattern(&antipattern_graph)?;
demo_dead_code_pattern(&antipattern_graph)?;
Ok(())
}
fn build_antipattern_graph() -> Result<CsrGraph, Box<dyn std::error::Error>> {
let mut graph = CsrGraph::new();
for i in 1..=12 {
graph.add_edge(NodeId(0), NodeId(i), 1.0)?;
}
graph.add_edge(NodeId(10), NodeId(11), 1.0)?;
graph.add_edge(NodeId(11), NodeId(12), 1.0)?;
graph.add_edge(NodeId(12), NodeId(10), 1.0)?;
graph.add_edge(NodeId(13), NodeId(14), 1.0)?;
Ok(graph)
}
fn demo_god_class_pattern(graph: &CsrGraph) -> Result<(), Box<dyn std::error::Error>> {
println!("🐘 God Class Pattern (high fan-out ≥10):");
let pattern = Pattern::god_class(10);
let matches = find_patterns(graph, &pattern)?;
println!(" Found {} god class instances", matches.len());
for m in &matches {
println!(" - {} (Severity: {:?})", m.pattern_name, m.severity);
}
println!();
Ok(())
}
fn demo_circular_dependency_pattern(graph: &CsrGraph) -> Result<(), Box<dyn std::error::Error>> {
println!("🔄 Circular Dependency Pattern (3-node cycles):");
let pattern = Pattern::circular_dependency(3);
let matches = find_patterns(graph, &pattern)?;
println!(" Found {} circular dependencies", matches.len());
for m in &matches {
println!(" - {} (Severity: {:?})", m.pattern_name, m.severity);
}
println!();
Ok(())
}
fn demo_dead_code_pattern(graph: &CsrGraph) -> Result<(), Box<dyn std::error::Error>> {
println!("💀 Dead Code Pattern (uncalled functions):");
let pattern = Pattern::dead_code();
let matches = find_patterns(graph, &pattern)?;
println!(" Found {} dead code instances", matches.len());
for m in &matches {
println!(" - Node {:?} (Severity: {:?})", m.node_mapping.get(&0), m.severity);
}
println!();
Ok(())
}
fn print_performance_summary() {
println!("📊 Performance Characteristics:");
println!("──────────────────────────────────────────────────────────────");
println!(" CSR Construction: O(E log V) - ~100μs for 1K nodes");
println!(" BFS Traversal: O(V + E) - ~40μs for 1K nodes (33× vs NetworkX)");
println!(" PageRank (20 iter): O(iterations × E) - ~500μs for 1K nodes");
println!(" Louvain: O(V × E) - ~14μs for 20 nodes, ~443μs for 125 nodes");
println!(" Pattern Matching: O(V) for God Class/Dead Code, O(V × E) for cycles");
println!();
println!("✅ All phases demonstrated successfully!");
}
fn print_gpu_info() {
#[cfg(feature = "gpu")]
{
println!("\n💡 GPU acceleration is available! Use:");
println!(" cargo run --example comprehensive_demo --features gpu");
}
#[cfg(not(feature = "gpu"))]
{
println!("\n💡 For GPU acceleration (10-250× speedup), rebuild with:");
println!(" cargo run --example comprehensive_demo --features gpu");
}
}