Skip to content

glazing.wordnet.relations

Lexical relation utilities.

relations

WordNet relation traversal functionality.

This module provides relation traversal capabilities for WordNet, including hypernym/hyponym chains, meronym/holonym navigation, entailment and causation relations, and similarity measure calculations.

CLASS DESCRIPTION
WordNetRelationTraverser

Traverser for WordNet semantic and lexical relations.

Classes

WordNetRelationTraverser(synsets: dict[SynsetOffset, Synset])

Traverser for WordNet semantic and lexical relations.

Provides methods for navigating WordNet's relation graph, including hypernym/hyponym traversal, meronym/holonym relations, and calculating semantic similarity measures.

PARAMETER DESCRIPTION
synsets

Mapping from synset offset to synset object.

TYPE: dict[SynsetOffset, Synset]

ATTRIBUTE DESCRIPTION
_synsets

Internal synset storage.

TYPE: dict[SynsetOffset, Synset]

METHOD DESCRIPTION
get_hypernyms

Get hypernyms (is-a relations) of a synset.

get_hyponyms

Get hyponyms (inverse of hypernym) of a synset.

get_hypernym_paths

Get all paths to root hypernyms.

get_common_hypernyms

Find common hypernyms of two synsets.

get_meronyms

Get meronyms (part-of relations) of a synset.

get_holonyms

Get holonyms (has-part relations) of a synset.

get_entailments

Get entailments (verb relations) of a synset.

get_causes

Get causes (verb relations) of a synset.

get_similar_to

Get similar adjectives for an adjective synset.

get_also_see

Get also-see relations for a synset.

get_antonyms

Get antonyms for a synset or specific lemma.

get_derivations

Get derivationally related forms.

calculate_path_similarity

Calculate path-based similarity between synsets.

calculate_depth

Calculate depth of synset in hypernym hierarchy.

Examples:

>>> traverser = WordNetRelationTraverser(synsets)
>>> hypernyms = traverser.get_hypernyms(dog_synset)
>>> paths = traverser.get_hypernym_paths(dog_synset, max_depth=5)
>>> similarity = traverser.calculate_path_similarity(dog_synset, cat_synset)

Initialize relation traverser with synset data.

Source code in src/glazing/wordnet/relations.py
def __init__(self, synsets: dict[SynsetOffset, Synset]) -> None:
    """Initialize relation traverser with synset data."""
    self._synsets = synsets
Functions
calculate_depth(synset: Synset) -> int

Calculate depth of synset in hypernym hierarchy.

PARAMETER DESCRIPTION
synset

Synset to calculate depth for.

TYPE: Synset

RETURNS DESCRIPTION
int

Maximum depth from root (0 for root synsets).

Source code in src/glazing/wordnet/relations.py
def calculate_depth(self, synset: Synset) -> int:
    """Calculate depth of synset in hypernym hierarchy.

    Parameters
    ----------
    synset : Synset
        Synset to calculate depth for.

    Returns
    -------
    int
        Maximum depth from root (0 for root synsets).
    """
    paths = self.get_hypernym_paths(synset)
    if not paths:
        return 0

    return max(len(path) - 1 for path in paths)
calculate_path_similarity(synset1: Synset, synset2: Synset) -> float

Calculate path-based similarity between synsets.

PARAMETER DESCRIPTION
synset1

First synset.

TYPE: Synset

synset2

Second synset.

TYPE: Synset

RETURNS DESCRIPTION
float

Similarity score between 0 and 1. Returns 0 if synsets are not connected.

Source code in src/glazing/wordnet/relations.py
def calculate_path_similarity(self, synset1: Synset, synset2: Synset) -> float:
    """Calculate path-based similarity between synsets.

    Parameters
    ----------
    synset1 : Synset
        First synset.
    synset2 : Synset
        Second synset.

    Returns
    -------
    float
        Similarity score between 0 and 1.
        Returns 0 if synsets are not connected.
    """
    # Must be same POS
    if synset1.ss_type != synset2.ss_type:
        return 0.0

    # Same synset has similarity 1
    if synset1.offset == synset2.offset:
        return 1.0

    # Find shortest path through common hypernyms
    common = self.get_common_hypernyms(synset1, synset2)
    if not common:
        return 0.0

    # Calculate shortest path
    min_distance = float("inf")

    for common_synset in common:
        # Distance from synset1 to common
        dist1 = self._calculate_min_distance(synset1, common_synset)
        # Distance from synset2 to common
        dist2 = self._calculate_min_distance(synset2, common_synset)

        if dist1 >= 0 and dist2 >= 0:
            total_dist = dist1 + dist2
            min_distance = min(min_distance, total_dist)

    if min_distance == float("inf"):
        return 0.0

    # Convert distance to similarity (1 / (distance + 1))
    return 1.0 / (min_distance + 1.0)
get_all_relations(synset: Synset) -> dict[str, list[Synset]]

Get all relations for a synset.

PARAMETER DESCRIPTION
synset

Synset to get relations for.

TYPE: Synset

RETURNS DESCRIPTION
dict[str, list[Synset]]

Dictionary mapping relation names to related synsets.

Source code in src/glazing/wordnet/relations.py
def get_all_relations(self, synset: Synset) -> dict[str, list[Synset]]:
    """Get all relations for a synset.

    Parameters
    ----------
    synset : Synset
        Synset to get relations for.

    Returns
    -------
    dict[str, list[Synset]]
        Dictionary mapping relation names to related synsets.
    """
    relations: dict[str, list[Synset]] = {}

    # Add general hierarchical relations
    self._add_hierarchical_relations(synset, relations)

    # Add part-whole relations
    self._add_meronymy_relations(synset, relations)

    # Add POS-specific relations
    self._add_pos_specific_relations(synset, relations)

    # Add general relations
    self._add_general_relations(synset, relations)

    return relations
get_also_see(synset: Synset) -> list[Synset]

Get also-see relations for a synset.

PARAMETER DESCRIPTION
synset

Synset to get also-see relations for.

TYPE: Synset

RETURNS DESCRIPTION
list[Synset]

Related synsets.

Source code in src/glazing/wordnet/relations.py
def get_also_see(self, synset: Synset) -> list[Synset]:
    """Get also-see relations for a synset.

    Parameters
    ----------
    synset : Synset
        Synset to get also-see relations for.

    Returns
    -------
    list[Synset]
        Related synsets.
    """
    also_see = []

    for pointer in synset.pointers:
        if pointer.symbol == "^" and pointer.is_semantic():
            related = self._synsets.get(pointer.offset)
            if related:
                also_see.append(related)

    return also_see
get_antonyms(synset: Synset, lemma: str | None = None) -> list[tuple[Synset, str]]

Get antonyms for a synset or specific lemma.

PARAMETER DESCRIPTION
synset

Synset to get antonyms for.

TYPE: Synset

lemma

Specific lemma to get antonyms for.

TYPE: str | None DEFAULT: None

RETURNS DESCRIPTION
list[tuple[Synset, str]]

List of (antonym synset, antonym lemma) pairs.

Source code in src/glazing/wordnet/relations.py
def get_antonyms(self, synset: Synset, lemma: str | None = None) -> list[tuple[Synset, str]]:
    """Get antonyms for a synset or specific lemma.

    Parameters
    ----------
    synset : Synset
        Synset to get antonyms for.
    lemma : str | None
        Specific lemma to get antonyms for.

    Returns
    -------
    list[tuple[Synset, str]]
        List of (antonym synset, antonym lemma) pairs.
    """
    antonyms = []

    for pointer in synset.pointers:
        if pointer.symbol == "!":
            antonym_pairs = self._extract_antonym_pairs(synset, pointer, lemma)
            antonyms.extend(antonym_pairs)

    return antonyms
get_causes(synset: Synset) -> list[Synset]

Get causes (verb relations) of a synset.

PARAMETER DESCRIPTION
synset

Verb synset to get causes for.

TYPE: Synset

RETURNS DESCRIPTION
list[Synset]

Caused synsets.

Source code in src/glazing/wordnet/relations.py
def get_causes(self, synset: Synset) -> list[Synset]:
    """Get causes (verb relations) of a synset.

    Parameters
    ----------
    synset : Synset
        Verb synset to get causes for.

    Returns
    -------
    list[Synset]
        Caused synsets.
    """
    causes: list[Synset] = []

    if synset.ss_type != "v":
        return causes

    for pointer in synset.pointers:
        if pointer.symbol == ">" and pointer.is_semantic():
            cause = self._synsets.get(pointer.offset)
            if cause:
                causes.append(cause)

    return causes
get_common_hypernyms(synset1: Synset, synset2: Synset) -> list[Synset]

Find common hypernyms of two synsets.

PARAMETER DESCRIPTION
synset1

First synset.

TYPE: Synset

synset2

Second synset.

TYPE: Synset

RETURNS DESCRIPTION
list[Synset]

Common hypernym synsets.

Source code in src/glazing/wordnet/relations.py
def get_common_hypernyms(self, synset1: Synset, synset2: Synset) -> list[Synset]:
    """Find common hypernyms of two synsets.

    Parameters
    ----------
    synset1 : Synset
        First synset.
    synset2 : Synset
        Second synset.

    Returns
    -------
    list[Synset]
        Common hypernym synsets.
    """
    hypernyms1 = self.get_hypernyms(synset1, direct_only=False)
    hypernyms1_offsets = {h.offset for h in hypernyms1}
    hypernyms1_offsets.add(synset1.offset)  # Include the synset itself

    hypernyms2 = self.get_hypernyms(synset2, direct_only=False)
    hypernyms2_offsets = {h.offset for h in hypernyms2}
    hypernyms2_offsets.add(synset2.offset)  # Include the synset itself

    common_offsets = hypernyms1_offsets & hypernyms2_offsets
    common = [self._synsets[offset] for offset in common_offsets if offset in self._synsets]
    return sorted(common, key=lambda s: s.offset)
get_derivations(synset: Synset, lemma: str | None = None) -> list[tuple[Synset, str]]

Get derivationally related forms.

PARAMETER DESCRIPTION
synset

Synset to get derivations for.

TYPE: Synset

lemma

Specific lemma to get derivations for.

TYPE: str | None DEFAULT: None

RETURNS DESCRIPTION
list[tuple[Synset, str]]

List of (related synset, related lemma) pairs.

Source code in src/glazing/wordnet/relations.py
def get_derivations(self, synset: Synset, lemma: str | None = None) -> list[tuple[Synset, str]]:
    """Get derivationally related forms.

    Parameters
    ----------
    synset : Synset
        Synset to get derivations for.
    lemma : str | None
        Specific lemma to get derivations for.

    Returns
    -------
    list[tuple[Synset, str]]
        List of (related synset, related lemma) pairs.
    """
    derivations = []

    for pointer in synset.pointers:
        if pointer.symbol == "+":
            derivation_pairs = self._extract_derivation_pairs(synset, pointer, lemma)
            derivations.extend(derivation_pairs)

    return derivations
get_entailments(synset: Synset) -> list[Synset]

Get entailments (verb relations) of a synset.

PARAMETER DESCRIPTION
synset

Verb synset to get entailments for.

TYPE: Synset

RETURNS DESCRIPTION
list[Synset]

Entailed synsets.

Source code in src/glazing/wordnet/relations.py
def get_entailments(self, synset: Synset) -> list[Synset]:
    """Get entailments (verb relations) of a synset.

    Parameters
    ----------
    synset : Synset
        Verb synset to get entailments for.

    Returns
    -------
    list[Synset]
        Entailed synsets.
    """
    entailments: list[Synset] = []

    if synset.ss_type != "v":
        return entailments

    for pointer in synset.pointers:
        if pointer.symbol == "*" and pointer.is_semantic():
            entailment = self._synsets.get(pointer.offset)
            if entailment:
                entailments.append(entailment)

    return entailments
get_holonyms(synset: Synset, holonym_type: str | None = None) -> list[Synset]

Get holonyms (has-part relations) of a synset.

PARAMETER DESCRIPTION
synset

Synset to get holonyms for.

TYPE: Synset

holonym_type

Type of holonym: "member", "substance", "part", or None for all.

TYPE: str | None DEFAULT: None

RETURNS DESCRIPTION
list[Synset]

Holonym synsets.

Source code in src/glazing/wordnet/relations.py
def get_holonyms(self, synset: Synset, holonym_type: str | None = None) -> list[Synset]:
    """Get holonyms (has-part relations) of a synset.

    Parameters
    ----------
    synset : Synset
        Synset to get holonyms for.
    holonym_type : str | None
        Type of holonym: "member", "substance", "part", or None for all.

    Returns
    -------
    list[Synset]
        Holonym synsets.
    """
    holonyms = []

    # Map holonym types to pointer symbols
    symbol_map = {"member": "#m", "substance": "#s", "part": "#p"}

    symbols = [symbol_map.get(holonym_type, "")] if holonym_type else ["#m", "#s", "#p"]

    for pointer in synset.pointers:
        if pointer.symbol in symbols and pointer.is_semantic():
            holonym = self._synsets.get(pointer.offset)
            if holonym:
                holonyms.append(holonym)

    return holonyms
get_hypernym_paths(synset: Synset, max_depth: int = 10) -> list[list[Synset]]

Get all paths to root hypernyms.

PARAMETER DESCRIPTION
synset

Starting synset.

TYPE: Synset

max_depth

Maximum depth to traverse.

TYPE: int DEFAULT: 10

RETURNS DESCRIPTION
list[list[Synset]]

List of paths, each path is a list of synsets from start to root.

Source code in src/glazing/wordnet/relations.py
def get_hypernym_paths(self, synset: Synset, max_depth: int = 10) -> list[list[Synset]]:
    """Get all paths to root hypernyms.

    Parameters
    ----------
    synset : Synset
        Starting synset.
    max_depth : int
        Maximum depth to traverse.

    Returns
    -------
    list[list[Synset]]
        List of paths, each path is a list of synsets from start to root.
    """
    paths = []

    def traverse(current: Synset, path: list[Synset], depth: int) -> None:
        """Recursively traverse hypernym paths."""
        if depth >= max_depth:
            paths.append(path)
            return

        hypernyms = self.get_hypernyms(current, direct_only=True)
        if not hypernyms:
            # Reached a root
            paths.append(path)
        else:
            for hypernym in hypernyms:
                # Avoid cycles
                if hypernym.offset not in {s.offset for s in path}:
                    traverse(hypernym, [*path, hypernym], depth + 1)

    traverse(synset, [synset], 0)
    return paths
get_hypernyms(synset: Synset, direct_only: bool = True) -> list[Synset]

Get hypernyms (is-a relations) of a synset.

PARAMETER DESCRIPTION
synset

Synset to get hypernyms for.

TYPE: Synset

direct_only

If True, return only direct hypernyms. If False, return all hypernyms up to root.

TYPE: bool DEFAULT: True

RETURNS DESCRIPTION
list[Synset]

Hypernym synsets.

Source code in src/glazing/wordnet/relations.py
def get_hypernyms(self, synset: Synset, direct_only: bool = True) -> list[Synset]:
    """Get hypernyms (is-a relations) of a synset.

    Parameters
    ----------
    synset : Synset
        Synset to get hypernyms for.
    direct_only : bool
        If True, return only direct hypernyms.
        If False, return all hypernyms up to root.

    Returns
    -------
    list[Synset]
        Hypernym synsets.
    """
    if direct_only:
        hypernyms = []
        for pointer in synset.pointers:
            if pointer.symbol == "@" and pointer.is_semantic():
                hypernym = self._synsets.get(pointer.offset)
                if hypernym:
                    hypernyms.append(hypernym)
        return hypernyms
    # Get all hypernyms recursively
    all_hypernym_offsets = set()
    queue = deque([synset])
    visited = {synset.offset}

    while queue:
        current = queue.popleft()
        for pointer in current.pointers:
            if (
                pointer.symbol == "@"
                and pointer.is_semantic()
                and pointer.offset not in visited
                and (hypernym := self._synsets.get(pointer.offset))
            ):
                all_hypernym_offsets.add(hypernym.offset)
                queue.append(hypernym)
                visited.add(pointer.offset)

    hypernyms = [self._synsets[offset] for offset in all_hypernym_offsets]
    return sorted(hypernyms, key=lambda s: s.offset)
get_hyponyms(synset: Synset, direct_only: bool = True) -> list[Synset]

Get hyponyms (inverse of hypernym) of a synset.

PARAMETER DESCRIPTION
synset

Synset to get hyponyms for.

TYPE: Synset

direct_only

If True, return only direct hyponyms. If False, return all hyponyms recursively.

TYPE: bool DEFAULT: True

RETURNS DESCRIPTION
list[Synset]

Hyponym synsets.

Source code in src/glazing/wordnet/relations.py
def get_hyponyms(self, synset: Synset, direct_only: bool = True) -> list[Synset]:
    """Get hyponyms (inverse of hypernym) of a synset.

    Parameters
    ----------
    synset : Synset
        Synset to get hyponyms for.
    direct_only : bool
        If True, return only direct hyponyms.
        If False, return all hyponyms recursively.

    Returns
    -------
    list[Synset]
        Hyponym synsets.
    """
    if direct_only:
        hyponyms = []
        for pointer in synset.pointers:
            if pointer.symbol == "~" and pointer.is_semantic():
                hyponym = self._synsets.get(pointer.offset)
                if hyponym:
                    hyponyms.append(hyponym)
        return hyponyms
    # Get all hyponyms recursively
    all_hyponym_offsets = set()
    queue = deque([synset])
    visited = {synset.offset}

    while queue:
        current = queue.popleft()
        for pointer in current.pointers:
            if (
                pointer.symbol == "~"
                and pointer.is_semantic()
                and pointer.offset not in visited
                and (hyponym := self._synsets.get(pointer.offset))
            ):
                all_hyponym_offsets.add(hyponym.offset)
                queue.append(hyponym)
                visited.add(pointer.offset)

    hyponyms = [self._synsets[offset] for offset in all_hyponym_offsets]
    return sorted(hyponyms, key=lambda s: s.offset)
get_meronyms(synset: Synset, meronym_type: str | None = None) -> list[Synset]

Get meronyms (part-of relations) of a synset.

PARAMETER DESCRIPTION
synset

Synset to get meronyms for.

TYPE: Synset

meronym_type

Type of meronym: "member", "substance", "part", or None for all.

TYPE: str | None DEFAULT: None

RETURNS DESCRIPTION
list[Synset]

Meronym synsets.

Source code in src/glazing/wordnet/relations.py
def get_meronyms(self, synset: Synset, meronym_type: str | None = None) -> list[Synset]:
    """Get meronyms (part-of relations) of a synset.

    Parameters
    ----------
    synset : Synset
        Synset to get meronyms for.
    meronym_type : str | None
        Type of meronym: "member", "substance", "part", or None for all.

    Returns
    -------
    list[Synset]
        Meronym synsets.
    """
    meronyms = []

    # Map meronym types to pointer symbols
    symbol_map = {"member": "%m", "substance": "%s", "part": "%p"}

    symbols = [symbol_map.get(meronym_type, "")] if meronym_type else ["%m", "%s", "%p"]

    for pointer in synset.pointers:
        if pointer.symbol in symbols and pointer.is_semantic():
            meronym = self._synsets.get(pointer.offset)
            if meronym:
                meronyms.append(meronym)

    return meronyms
get_similar_to(synset: Synset) -> list[Synset]

Get similar adjectives for an adjective synset.

PARAMETER DESCRIPTION
synset

Adjective synset.

TYPE: Synset

RETURNS DESCRIPTION
list[Synset]

Similar adjective synsets.

Source code in src/glazing/wordnet/relations.py
def get_similar_to(self, synset: Synset) -> list[Synset]:
    """Get similar adjectives for an adjective synset.

    Parameters
    ----------
    synset : Synset
        Adjective synset.

    Returns
    -------
    list[Synset]
        Similar adjective synsets.
    """
    similar: list[Synset] = []

    if synset.ss_type not in ["a", "s"]:
        return similar

    for pointer in synset.pointers:
        if pointer.symbol == "&" and pointer.is_semantic():
            sim = self._synsets.get(pointer.offset)
            if sim:
                similar.append(sim)

    return similar
get_verb_groups(synset: Synset) -> list[Synset]

Get verb group members for a verb synset.

PARAMETER DESCRIPTION
synset

Verb synset.

TYPE: Synset

RETURNS DESCRIPTION
list[Synset]

Related verb synsets in the same group.

Source code in src/glazing/wordnet/relations.py
def get_verb_groups(self, synset: Synset) -> list[Synset]:
    """Get verb group members for a verb synset.

    Parameters
    ----------
    synset : Synset
        Verb synset.

    Returns
    -------
    list[Synset]
        Related verb synsets in the same group.
    """
    groups: list[Synset] = []

    if synset.ss_type != "v":
        return groups

    for pointer in synset.pointers:
        if pointer.symbol == "$" and pointer.is_semantic():
            group = self._synsets.get(pointer.offset)
            if group:
                groups.append(group)

    return groups