Skip to content

Profunctors

Profunctors (bimodules) in enriched categories.

profunctors

Profunctors (bimodules) for V-enriched categories.

A V-profunctor R: A ↛ B is a V-valued functor A^op ⊗ B → V, represented as a tensor of shape (A.shape, B.shape). Every morphism in a V-enriched category is canonically a profunctor.

Profunctor composition uses the coend formula:

(R ; S)(a, c) = ∫^b R(a, b) ⊗ S(b, c)

which is exactly V-enriched composition. This module makes the profunctor structure explicit and provides composition via the coend from ends_coends.py.

This module provides:

Profunctor — explicit profunctor with contravariant/covariant structure

Profunctor

Profunctor(contra: SetObject, co: SetObject, tensor: Tensor, algebra: Algebra | None = None)

A V-profunctor R: A ↛ B.

Wraps a tensor of shape (A.shape, B.shape) with explicit contravariant (A) and covariant (B) objects.

PARAMETER DESCRIPTION
contra

The contravariant (domain/source) object A.

TYPE: SetObject

co

The covariant (codomain/target) object B.

TYPE: SetObject

tensor

The profunctor's tensor of shape (A.shape, B.shape).

TYPE: Tensor

algebra

The enrichment algebra. Defaults to PRODUCT_FUZZY.

TYPE: Algebra or None DEFAULT: None

Source code in src/quivers/enriched/profunctors.py
def __init__(
    self,
    contra: SetObject,
    co: SetObject,
    tensor: torch.Tensor,
    algebra: Algebra | None = None,
) -> None:
    self._contra = contra
    self._co = co
    self._tensor = tensor
    self._algebra = algebra if algebra is not None else PRODUCT_FUZZY

    expected_shape = (*contra.shape, *co.shape)

    if tensor.shape != expected_shape:
        raise ValueError(
            f"tensor shape {tensor.shape} does not match expected "
            f"{expected_shape} from contra={contra!r}, co={co!r}"
        )

contra property

contra: SetObject

The contravariant (source) object.

co property

The covariant (target) object.

tensor property

tensor: Tensor

The profunctor tensor.

algebra property

algebra: Algebra

The enrichment algebra.

from_morphism classmethod

from_morphism(morph: Morphism) -> Profunctor

View a morphism as a profunctor (Yoneda embedding).

PARAMETER DESCRIPTION
morph

A morphism R: A → B.

TYPE: Morphism

RETURNS DESCRIPTION
Profunctor

The profunctor R: A ↛ B with the same tensor.

Source code in src/quivers/enriched/profunctors.py
@classmethod
def from_morphism(cls, morph: Morphism) -> Profunctor:
    """View a morphism as a profunctor (Yoneda embedding).

    Parameters
    ----------
    morph : Morphism
        A morphism R: A → B.

    Returns
    -------
    Profunctor
        The profunctor R: A ↛ B with the same tensor.
    """
    return cls(
        contra=morph.domain,
        co=morph.codomain,
        tensor=morph.tensor,
        algebra=morph.algebra,
    )

compose

compose(other: Profunctor) -> Profunctor

Profunctor composition via coend.

(R ; S)(a, c) = ∫^b R(a, b) ⊗ S(b, c)

This is equivalent to V-enriched composition via the algebra's compose method.

PARAMETER DESCRIPTION
other

Right profunctor S: B ↛ C.

TYPE: Profunctor

RETURNS DESCRIPTION
Profunctor

Composed profunctor R ; S: A ↛ C.

Source code in src/quivers/enriched/profunctors.py
def compose(self, other: Profunctor) -> Profunctor:
    """Profunctor composition via coend.

    (R ; S)(a, c) = ∫^b R(a, b) ⊗ S(b, c)

    This is equivalent to V-enriched composition via the
    algebra's compose method.

    Parameters
    ----------
    other : Profunctor
        Right profunctor S: B ↛ C.

    Returns
    -------
    Profunctor
        Composed profunctor R ; S: A ↛ C.
    """
    if self._co != other._contra:
        raise TypeError(
            f"cannot compose: R's covariant object {self._co!r} "
            f"!= S's contravariant object {other._contra!r}"
        )

    # use algebra.compose which is exactly the coend formula
    n_contract = self._co.ndim
    result_tensor = self._algebra.compose(self._tensor, other._tensor, n_contract)

    return Profunctor(
        contra=self._contra,
        co=other._co,
        tensor=result_tensor,
        algebra=self._algebra,
    )

to_morphism

to_morphism() -> ObservedMorphism

Convert back to a morphism (same tensor, different framing).

RETURNS DESCRIPTION
ObservedMorphism

A morphism with domain=contra, codomain=co.

Source code in src/quivers/enriched/profunctors.py
def to_morphism(self) -> ObservedMorphism:
    """Convert back to a morphism (same tensor, different framing).

    Returns
    -------
    ObservedMorphism
        A morphism with domain=contra, codomain=co.
    """
    return observed(
        self._contra,
        self._co,
        self._tensor,
        algebra=self._algebra,
    )