use oxirs_graphrag::community_detector::{CommunityDetector, CommunityGraph};
use oxirs_graphrag::path_finder::{KnowledgeEdge, PathFinder, PathFinderConfig};
use oxirs_graphrag::triple_extractor::{ExtractionConfig, TripleExtractor};
fn main() {
let sentences = [
"Alice is a data scientist.",
"Alice works at ACME.",
"Bob works at ACME.",
"Carol is part of the AI team.",
"Dave is a software engineer.",
"Dave works at ACME.",
"ACME has a research division.",
"The research division is located in Berlin.",
];
let extractor = TripleExtractor::with_defaults(ExtractionConfig::default());
let mut extracted: Vec<(String, String, String)> = Vec::new();
println!("=== Step 1: Extracted triples from corpus ===");
for sentence in &sentences {
for triple in extractor.extract(sentence) {
println!(
" ({}, {}, {}) [conf={:.2}]",
triple.subject, triple.predicate, triple.object, triple.confidence
);
extracted.push((triple.subject, triple.predicate, triple.object));
}
}
println!("Total triples extracted: {}\n", extracted.len());
let mut cg = CommunityGraph::new();
for (id, label) in [
(1u64, "Alice"),
(2, "Bob"),
(3, "Carol"),
(4, "Dave"),
(5, "ACME"),
(6, "AI-Team"),
(7, "Research"),
(8, "Berlin"),
] {
cg.add_node(id, label);
}
for (a, b, w) in [
(1u64, 5u64, 1.5), (2, 5, 1.5), (4, 5, 1.0), (3, 6, 1.0), (4, 6, 0.5), (5, 7, 1.0), (7, 8, 1.0), (1, 2, 0.5), ] {
cg.add_edge(a, b, w);
}
let detector = CommunityDetector::new(2, 50);
let result = detector.detect(&mut cg);
println!("=== Step 2: Community detection ===");
println!(
"Modularity: {:.4} | Iterations: {}",
result.modularity, result.iterations
);
for community in &result.communities {
let members: Vec<String> = community
.members
.iter()
.filter_map(|id| cg.nodes.get(id).map(|n| n.label.clone()))
.collect();
println!(
" Community {:>2}: {} member(s) — [{}]",
community.id,
community.size(),
members.join(", ")
);
}
println!();
let edges = vec![
KnowledgeEdge::new("Alice", "works_at", "ACME"),
KnowledgeEdge::new("Bob", "works_at", "ACME"),
KnowledgeEdge::new("Carol", "member_of", "AI-Team"),
KnowledgeEdge::new("Dave", "works_at", "ACME"),
KnowledgeEdge::new("ACME", "has", "Research"),
KnowledgeEdge::new("Research", "located_in", "Berlin"),
KnowledgeEdge::new("AI-Team", "part_of", "ACME"),
];
let config = PathFinderConfig {
max_depth: 4,
max_paths: 10,
..Default::default()
};
let finder = PathFinder::new(edges, config);
let source = "Alice";
let target = "Berlin";
let paths = finder.bfs_paths(source, target, 4);
println!(
"=== Step 3: Top-{} paths: {} → {} ===",
paths.len(),
source,
target
);
if paths.is_empty() {
println!(" (no path found within 4 hops)");
} else {
for (rank, path) in paths.iter().enumerate() {
println!(
" #{}: {} [score={:.2}]",
rank + 1,
path.narrative(),
path.score
);
}
}
println!("\n=== Summary ===");
println!(" Triples extracted: {}", extracted.len());
println!(" Communities found: {}", result.communities.len());
println!(" Paths {source}→{target}: {}", paths.len());
println!("\nKGQA basic example completed successfully.");
}