pub struct CorefGraph { /* private fields */ }Expand description
A coreference graph representing mention relationships.
This is the core data structure for iterative refinement. Nodes are mention indices, edges are coreference links. The graph is stored as an adjacency set for O(1) edge lookup during refinement.
§Invariants
- Graph is symmetric: if edge(i,j) exists, edge(j,i) exists
- No self-loops: edge(i,i) is always None
- Indices are valid mention indices: 0 <= i,j < num_mentions
§Example
use anno::backends::graph_coref::CorefGraph;
let mut graph = CorefGraph::new(3);
graph.add_edge(0, 1);
graph.add_edge(1, 2);
assert!(graph.has_edge(0, 1));
assert!(graph.transitively_connected(0, 2)); // via 0-1-2
let clusters = graph.extract_clusters();
assert_eq!(clusters.len(), 1); // All connectedImplementations§
Source§impl CorefGraph
impl CorefGraph
Sourcepub fn new(num_mentions: usize) -> Self
pub fn new(num_mentions: usize) -> Self
Create an empty coreference graph with the given number of mentions.
Sourcepub fn num_mentions(&self) -> usize
pub fn num_mentions(&self) -> usize
Get the number of mentions (nodes) in the graph.
Sourcepub fn add_edge(&mut self, i: usize, j: usize)
pub fn add_edge(&mut self, i: usize, j: usize)
Add a coreference edge between two mentions.
The edge is stored in canonical form (i < j) for consistency. Self-loops and out-of-bounds indices are silently ignored.
Sourcepub fn remove_edge(&mut self, i: usize, j: usize)
pub fn remove_edge(&mut self, i: usize, j: usize)
Remove a coreference edge between two mentions.
Sourcepub fn neighbors(&self, i: usize) -> Vec<usize>
pub fn neighbors(&self, i: usize) -> Vec<usize>
Get all neighbors (directly linked mentions) of a mention.
Count shared neighbors between two mentions.
This is the basis for the transitivity bonus: if mentions i and j share many neighbors in the current graph, they’re likely coreferent.
§G2GT Connection
In the full G2GT model, shared structure is captured via graph-conditioned attention. Here we approximate it by explicitly counting shared neighbors and adding a proportional bonus to the pairwise score.
Sourcepub fn transitively_connected(&self, i: usize, j: usize) -> bool
pub fn transitively_connected(&self, i: usize, j: usize) -> bool
Check if two mentions are transitively connected.
Uses BFS to find if there’s a path from i to j through coreference links. This is the closure property that ensures consistency: if A~B and B~C, then A and C are transitively connected even without a direct edge.
Sourcepub fn extract_clusters(&self) -> Vec<Vec<usize>>
pub fn extract_clusters(&self) -> Vec<Vec<usize>>
Extract connected components as clusters.
Each connected component in the graph becomes a coreference chain. Singleton mentions (no edges) are included as single-mention clusters.
Sourcepub fn edge_count(&self) -> usize
pub fn edge_count(&self) -> usize
Get the number of edges in the graph.
Sourcepub fn seed_cooccurrence_edges<F>(
&mut self,
mention_positions: &[usize],
window_size: usize,
scorer: Option<F>,
)
pub fn seed_cooccurrence_edges<F>( &mut self, mention_positions: &[usize], window_size: usize, scorer: Option<F>, )
Seed the graph with co-occurrence priors based on mention proximity.
This is inspired by SpanEIT (Hossain et al. 2025), which constructs a
semantic co-occurrence graph G_sem alongside the syntactic graph. The
insight: mentions that appear close together are more likely coreferent.
§Arguments
mention_positions- Position of each mention (e.g., character offset)window_size- Maximum distance for co-occurrence (e.g., 100 chars)scorer- Optional scoring function; if None, uses constant weight
§Example
use anno::backends::graph_coref::CorefGraph;
let mut graph = CorefGraph::new(3);
let positions = vec![0, 50, 200]; // Character offsets
// Seed edges for mentions within 100 chars of each other
// Type annotation needed when passing None for the scorer
graph.seed_cooccurrence_edges::<fn(usize, usize) -> bool>(&positions, 100, None);
assert!(graph.has_edge(0, 1)); // 50 < 100
assert!(!graph.has_edge(0, 2)); // 200 > 100§Research Background
SpanEIT constructs G = (V, E_syn ∪ E_sem) where:
E_syn= syntactic dependency edgesE_sem= co-occurrence edges (this method)
The combined graph is processed by GAT layers for context-aware embeddings. For anno’s heuristic approach, we add these edges as initial priors before iterative refinement.
Trait Implementations§
Source§impl Clone for CorefGraph
impl Clone for CorefGraph
Source§fn clone(&self) -> CorefGraph
fn clone(&self) -> CorefGraph
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for CorefGraph
impl Debug for CorefGraph
Source§impl PartialEq for CorefGraph
impl PartialEq for CorefGraph
impl Eq for CorefGraph
impl StructuralPartialEq for CorefGraph
Auto Trait Implementations§
impl Freeze for CorefGraph
impl RefUnwindSafe for CorefGraph
impl Send for CorefGraph
impl Sync for CorefGraph
impl Unpin for CorefGraph
impl UnsafeUnpin for CorefGraph
impl UnwindSafe for CorefGraph
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more