Skip to main content

CorefGraph

Struct CorefGraph 

Source
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 connected

Implementations§

Source§

impl CorefGraph

Source

pub fn new(num_mentions: usize) -> Self

Create an empty coreference graph with the given number of mentions.

Source

pub fn num_mentions(&self) -> usize

Get the number of mentions (nodes) in the graph.

Source

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.

Source

pub fn remove_edge(&mut self, i: usize, j: usize)

Remove a coreference edge between two mentions.

Source

pub fn has_edge(&self, i: usize, j: usize) -> bool

Check if two mentions are directly linked.

Source

pub fn neighbors(&self, i: usize) -> Vec<usize>

Get all neighbors (directly linked mentions) of a mention.

Source

pub fn shared_neighbors(&self, i: usize, j: usize) -> usize

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.

Source

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.

Source

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.

Source

pub fn edge_count(&self) -> usize

Get the number of edges in the graph.

Source

pub fn is_empty(&self) -> bool

Check if graph is empty (no edges).

Source

pub fn seed_cooccurrence_edges<F>( &mut self, mention_positions: &[usize], window_size: usize, scorer: Option<F>, )
where F: Fn(usize, usize) -> bool,

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 edges
  • E_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

Source§

fn clone(&self) -> CorefGraph

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for CorefGraph

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl PartialEq for CorefGraph

Source§

fn eq(&self, other: &CorefGraph) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Eq for CorefGraph

Source§

impl StructuralPartialEq for CorefGraph

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more