Skip to content

Categories

Category types for categorial grammars: atomic, slash, product, unit, and modal categories, plus the finite CategorySystem used by chart parsers.

The category types form the free algebra generated by atoms and type constructors. CategorySystem.from_generators() enumerates this algebra to a specified depth, producing finite category inventories for CCG, Lambek, multimodal TLG, and custom rule systems.

categories

Category types for categorial grammars.

Provides the free algebra of grammatical categories generated by atoms and type constructors. This is the type system underlying chart parsers for CCG, the Lambek calculus, multimodal type-logical grammar, and any bespoke formalism assembled from biclosed monoidal primitives.

Atomic categories

AtomicCategory(name="S"): a basic category like S, NP, N, PP.

Slash categories (internal homs)

SlashCategory(result=R, argument=A, direction="/"): the right residual R/A SlashCategory(result=R, argument=A, direction="\"): the left residual R\A

Product categories (tensor product)

ProductCategory(left=L, right=R): the tensor L ⊗ R

Unit category (monoidal unit)

UnitCategory(): the monoidal unit I satisfying I ⊗ A ≅ A ≅ A ⊗ I.

Category systems

A CategorySystem manages a finite inventory of categories with integer indices, supporting lookup and enumeration.

Category didactic-model

Category()

Bases: TaggedUnion

Sum of grammatical category kinds.

Variants subclass this root and pin kind to a literal value; Category.model_validate dispatches on that discriminator.

AtomicCategory didactic-model

AtomicCategory(*, name: str, kind: Literal['atomic'] = 'atomic')

Bases: Category

An atomic (primitive) grammatical category.

SlashCategory didactic-model

SlashCategory(*, result: Category, argument: Category, direction: Literal['/', '\\'], kind: Literal['slash'] = 'slash')

Bases: Category

A complex category formed by a slash operator.

result/argument (forward): seeks argument on the right. result\argument (backward): seeks argument on the left.

These are the internal homs of a biclosed monoidal category: / is the right residual and \ is the left residual.

ProductCategory didactic-model

ProductCategory(*, left: Category, right: Category, kind: Literal['product'] = 'product')

Bases: Category

A product category (tensor product) for type-logical grammar.

Represents A ⊗ B in the Lambek calculus.

UnitCategory didactic-model

UnitCategory(*, kind: Literal['unit'] = 'unit')

Bases: Category

The monoidal unit category I.

Satisfies the unit laws: I ⊗ A ≅ A ≅ A ⊗ I.

ModalCategory didactic-model

ModalCategory(*, modality: str, inner: Category, kind: Literal['modal'] = 'modal')

Bases: Category

A modal category: a unary type constructor applied to a category.

Represents modalities like ◇A (diamond) and □A (box) used in multimodal type-logical grammar (Moortgat 1997). Arbitrary named modalities are supported.

CategorySystem

CategorySystem(categories: list[Category] | None = None)

A finite inventory of grammatical categories with integer indices.

Manages the mapping between Category objects and their integer indices, used by chart parsers.

PARAMETER DESCRIPTION
categories

The initial category inventory.

TYPE: list of Category DEFAULT: None

Source code in src/quivers/stochastic/categories.py
def __init__(self, categories: list[Category] | None = None) -> None:
    self._cats: list[Category] = []
    self._index: dict[Category, int] = {}
    if categories:
        for cat in categories:
            self.add(cat)

size property

size: int

Number of categories in the system.

from_atoms classmethod

from_atoms(names: list[str]) -> CategorySystem

Create a category system from atomic category names.

PARAMETER DESCRIPTION
names

The atomic category names, in index order.

TYPE: list of str

RETURNS DESCRIPTION
CategorySystem

A system holding one AtomicCategory per name.

Source code in src/quivers/stochastic/categories.py
@classmethod
def from_atoms(cls, names: list[str]) -> "CategorySystem":
    """Create a category system from atomic category names.

    Parameters
    ----------
    names : list of str
        The atomic category names, in index order.

    Returns
    -------
    CategorySystem
        A system holding one `AtomicCategory` per name.
    """
    cats: list[Category] = [AtomicCategory(name=name) for name in names]
    return cls(cats)

from_atoms_and_slash_depth classmethod

from_atoms_and_slash_depth(names: list[str], max_depth: int = 1) -> CategorySystem

Create a category system with atomic categories and all slash combinations up to a given depth.

Each round adds A/B and A\B for every pair of categories already in the system.

PARAMETER DESCRIPTION
names

The atomic category names.

TYPE: list of str

max_depth

The number of slash-closure rounds; below 1, only the atoms are returned.

TYPE: int DEFAULT: 1

RETURNS DESCRIPTION
CategorySystem

The closed category system.

Source code in src/quivers/stochastic/categories.py
@classmethod
def from_atoms_and_slash_depth(
    cls,
    names: list[str],
    max_depth: int = 1,
) -> "CategorySystem":
    """Create a category system with atomic categories and all
    slash combinations up to a given depth.

    Each round adds ``A/B`` and ``A\\B`` for every pair of
    categories already in the system.

    Parameters
    ----------
    names : list of str
        The atomic category names.
    max_depth : int
        The number of slash-closure rounds; below 1, only the
        atoms are returned.

    Returns
    -------
    CategorySystem
        The closed category system.
    """
    system = cls.from_atoms(names)
    if max_depth < 1:
        return system
    for _ in range(max_depth):
        current = list(system._cats)
        for result in current:
            for arg in current:
                system.add(
                    SlashCategory(result=result, argument=arg, direction="/")
                )
                system.add(
                    SlashCategory(result=result, argument=arg, direction="\\")
                )
    return system

from_generators classmethod

from_generators(atoms: list[str], constructors: list[str] | None = None, max_depth: int = 1) -> CategorySystem

Create a category system from atoms and type constructors.

Built-in constructor names:

  • "slash": generates all A/B and A\B
  • "product": generates all A⊗B
  • "unit": adds the monoidal unit I
  • "diamond": generates ◇A for all A
  • "box": generates □A for all A
PARAMETER DESCRIPTION
atoms

The atomic category names.

TYPE: list of str

constructors

The constructor names to close under, each one of BUILTIN_CONSTRUCTOR_NAMES; None means ["slash"].

TYPE: list of str or None DEFAULT: None

max_depth

The number of closure rounds.

TYPE: int DEFAULT: 1

RETURNS DESCRIPTION
CategorySystem

The atoms closed under the constructors.

RAISES DESCRIPTION
ValueError

If a constructor name is not a built-in constructor.

Source code in src/quivers/stochastic/categories.py
@classmethod
def from_generators(
    cls,
    atoms: list[str],
    constructors: list[str] | None = None,
    max_depth: int = 1,
) -> "CategorySystem":
    """Create a category system from atoms and type constructors.

    Built-in constructor names:

    - ``"slash"``: generates all A/B and A\\B
    - ``"product"``: generates all A⊗B
    - ``"unit"``: adds the monoidal unit I
    - ``"diamond"``: generates ◇A for all A
    - ``"box"``: generates □A for all A

    Parameters
    ----------
    atoms : list of str
        The atomic category names.
    constructors : list of str or None
        The constructor names to close under, each one of
        `BUILTIN_CONSTRUCTOR_NAMES`; ``None`` means ``["slash"]``.
    max_depth : int
        The number of closure rounds.

    Returns
    -------
    CategorySystem
        The atoms closed under the constructors.

    Raises
    ------
    ValueError
        If a constructor name is not a built-in constructor.
    """
    if constructors is None:
        constructors = ["slash"]

    fns = []
    for name in constructors:
        if name not in _BUILTIN_CONSTRUCTORS:
            raise ValueError(constructor_name_error(name))
        fns.append(_BUILTIN_CONSTRUCTORS[name])

    system = cls.from_atoms(atoms)
    for _ in range(max_depth):
        current = list(system._cats)
        for fn in fns:
            for cat in fn(current):
                system.add(cat)
    return system

add

add(cat: Category) -> int

Add a category to the system; return its index.

PARAMETER DESCRIPTION
cat

The category to add. A category already present keeps its index.

TYPE: Category

RETURNS DESCRIPTION
int

The category's index.

Source code in src/quivers/stochastic/categories.py
def add(self, cat: Category) -> int:
    """Add a category to the system; return its index.

    Parameters
    ----------
    cat : Category
        The category to add. A category already present keeps
        its index.

    Returns
    -------
    int
        The category's index.
    """
    if cat in self._index:
        return self._index[cat]
    idx = len(self._cats)
    self._cats.append(cat)
    self._index[cat] = idx
    return idx

add_slash

add_slash(result: Category, argument: Category, direction: Literal['/', '\\']) -> int

Add a slash category and return its index.

PARAMETER DESCRIPTION
result

The result category of the slash.

TYPE: Category

argument

The argument category of the slash.

TYPE: Category

direction

"/" for the right residual, "\" for the left.

TYPE: "/", "\" DEFAULT: "/"

RETURNS DESCRIPTION
int

The slash category's index.

Source code in src/quivers/stochastic/categories.py
def add_slash(
    self,
    result: Category,
    argument: Category,
    direction: Literal["/", "\\"],
) -> int:
    """Add a slash category and return its index.

    Parameters
    ----------
    result : Category
        The result category of the slash.
    argument : Category
        The argument category of the slash.
    direction : {"/", "\\"}
        ``"/"`` for the right residual, ``"\\"`` for the left.

    Returns
    -------
    int
        The slash category's index.
    """
    cat = SlashCategory(result=result, argument=argument, direction=direction)
    return self.add(cat)

index

index(cat: Category) -> int

Get the integer index of a category.

PARAMETER DESCRIPTION
cat

The category to look up.

TYPE: Category

RETURNS DESCRIPTION
int

The category's index.

RAISES DESCRIPTION
KeyError

If the category is not in the system.

Source code in src/quivers/stochastic/categories.py
def index(self, cat: Category) -> int:
    """Get the integer index of a category.

    Parameters
    ----------
    cat : Category
        The category to look up.

    Returns
    -------
    int
        The category's index.

    Raises
    ------
    KeyError
        If the category is not in the system.
    """
    if cat not in self._index:
        raise KeyError(f"category {cat!r} not in system")
    return self._index[cat]

constructor_name_error

constructor_name_error(name: str) -> str

Return the diagnostic for a residuated constructor name.

The message is shared by every validation site so a name is rejected in the same words whether it is caught when the universe is declared or when it is enumerated.

Source code in src/quivers/stochastic/categories.py
def constructor_name_error(name: str) -> str:
    """Return the diagnostic for a residuated constructor name.

    The message is shared by every validation site so a name is
    rejected in the same words whether it is caught when the
    universe is declared or when it is enumerated.
    """
    hint = _CONSTRUCTOR_HINTS.get(name)
    detail = f"; {hint}" if hint else ""
    return (
        f"unknown constructor {name!r}; available: "
        f"{sorted(BUILTIN_CONSTRUCTOR_NAMES)}{detail}"
    )

Constructor names

Stochastic morphisms: Markov kernels over finite sets.

This module provides the probabilistic layer for quivers, implementing the category FinStoch of finite sets and stochastic maps (Markov kernels). This is the Kleisli category of the Giry monad restricted to finite sets, where:

  • Objects are finite sets (same as the base category).
  • Morphisms A -> B are stochastic matrices: tensors of shape (|A|, |B|) whose rows sum to 1.
  • Composition is standard matrix multiplication.
  • Identity is the Kronecker delta.

The package also re-exports MarkovAlgebra and its singleton MARKOV from quivers.core.algebras, the algebra these morphisms compose under.

Submodules

morphisms : StochasticMorphism, CategoricalMorphism families : Discretized distribution families transforms : condition, mix, factor, normalize queries : prob, marginal_prob, expectation giry : GiryMonad, FinStoch categories : Category types including atoms, slashes, products, unit, modals semiring : Chart semiring abstractions (LogProb, Viterbi, Boolean, Counting) schema : Composable rule schemas (functors CategorySystem -> RuleSystem) rules : Rule systems and the CCG / Lambek presets span : Span-based CKY components (LexicalAxiom, BinarySpanDeduction, etc.) parsers, ccg, lambek : Chart parsers inside : The inside algorithm over a rule system agenda : The agenda-driven weighted-deduction engine effect_lifts : Effect-lifted rule schemas for deduction systems deduction : Abstract weighted deductive system framework and its operations stdlib : Pre-registered deduction systems

BUILTIN_CONSTRUCTOR_NAMES module-attribute

BUILTIN_CONSTRUCTOR_NAMES: frozenset[str] = frozenset(_BUILTIN_CONSTRUCTORS)

Every constructor name CategorySystem.from_generators accepts.

Callers that build a residuated universe (the DSL's FreeResiduated declaration, for instance) validate against this set before the universe is enumerated.