Algebras and Coalgebras

Monad algebras, comonad coalgebras, and their structural properties.

algebras

Algebras and coalgebras for monads and comonads.

An algebra (A, α) for a monad (T, η, μ) consists of an object A and a morphism α: T(A) → A satisfying:

α ∘ η_A = id_A           (unit law)
α ∘ μ_A = α ∘ T(α)       (associativity)

Dually, a coalgebra (A, γ) for a comonad (W, ε, δ) consists of an object A and a morphism γ: A → W(A) satisfying:

ε_A ∘ γ = id_A           (counit law)
δ_A ∘ γ = W(γ) ∘ γ       (coassociativity)

The Eilenberg-Moore category of a monad T has T-algebras as objects and algebra homomorphisms as morphisms. The comparison functor K: Kl(T) → EM(T) relates the Kleisli and Eilenberg-Moore categories.

This module provides:

Algebra (abstract)
├── FreeAlgebra            — free T-algebra μ_A: T(T(A)) → T(A)
└── ObservedAlgebra        — algebra from a concrete structure map

Coalgebra (abstract)
├── CofreeCoalgebra        — cofree W-coalgebra δ_A: W(A) → W(W(A))
└── ObservedCoalgebra      — coalgebra from a concrete structure map

EilenbergMooreCategory     — the category of algebras for a monad

Algebra

Algebra(monad: Monad, carrier: SetObject)

Bases: ABC

Abstract algebra for a monad.

An algebra (A, α) for monad T consists of a carrier object A and a structure map α: T(A) → A.

PARAMETER DESCRIPTION
monad

The monad T.

TYPE: Monad

carrier

The carrier object A.

TYPE: SetObject

Source code in src/quivers/monadic/algebras.py
58
59
60
def __init__(self, monad: Monad, carrier: SetObject) -> None:
    self._monad = monad
    self._carrier = carrier

monad property

monad: Monad

The monad T.

carrier property

carrier: SetObject

The carrier object A.

structure_map abstractmethod

structure_map() -> Morphism

The structure map α: T(A) → A.

RETURNS DESCRIPTION
Morphism

The algebra structure map.

Source code in src/quivers/monadic/algebras.py
72
73
74
75
76
77
78
79
80
81
@abstractmethod
def structure_map(self) -> Morphism:
    """The structure map α: T(A) → A.

    Returns
    -------
    Morphism
        The algebra structure map.
    """
    ...

verify_unit_law

verify_unit_law(atol: float = 1e-05) -> bool

Verify α ∘ η_A = id_A.

PARAMETER DESCRIPTION
atol

Absolute tolerance for comparison.

TYPE: float DEFAULT: 1e-05

RETURNS DESCRIPTION
bool

True if the unit law holds within tolerance.

Source code in src/quivers/monadic/algebras.py
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
def verify_unit_law(self, atol: float = 1e-5) -> bool:
    """Verify α ∘ η_A = id_A.

    Parameters
    ----------
    atol : float
        Absolute tolerance for comparison.

    Returns
    -------
    bool
        True if the unit law holds within tolerance.
    """
    alpha = self.structure_map()
    eta = self._monad.unit(self._carrier)
    result = (eta >> alpha).tensor
    expected = identity(self._carrier).tensor

    return torch.allclose(result, expected, atol=atol)

verify_associativity

verify_associativity(atol: float = 1e-05) -> bool

Verify α ∘ μ_A = α ∘ T(α).

PARAMETER DESCRIPTION
atol

Absolute tolerance for comparison.

TYPE: float DEFAULT: 1e-05

RETURNS DESCRIPTION
bool

True if associativity holds within tolerance.

Source code in src/quivers/monadic/algebras.py
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
def verify_associativity(self, atol: float = 1e-5) -> bool:
    """Verify α ∘ μ_A = α ∘ T(α).

    Parameters
    ----------
    atol : float
        Absolute tolerance for comparison.

    Returns
    -------
    bool
        True if associativity holds within tolerance.
    """
    alpha = self.structure_map()
    mu = self._monad.multiply(self._carrier)

    # left side: α ∘ μ_A
    left = (mu >> alpha).tensor

    # right side: α ∘ T(α)
    t_alpha = self._monad.endofunctor.map_morphism(alpha)
    right = (t_alpha >> alpha).tensor

    return torch.allclose(left, right, atol=atol)

FreeAlgebra

FreeAlgebra(monad: Monad, obj: SetObject)

Bases: Algebra

The free T-algebra on an object A.

The carrier is T(A) and the structure map is μ_A: T(T(A)) → T(A). This is the algebra that the comparison functor assigns to each object in the Kleisli category.

PARAMETER DESCRIPTION
monad

The monad T.

TYPE: Monad

obj

The base object A (the carrier will be T(A)).

TYPE: SetObject

Source code in src/quivers/monadic/algebras.py
147
148
149
150
def __init__(self, monad: Monad, obj: SetObject) -> None:
    carrier = monad.endofunctor.map_object(obj)
    super().__init__(monad, carrier)
    self._base = obj

base property

base: SetObject

The base object A (carrier is T(A)).

structure_map

structure_map() -> Morphism

μ_A: T(T(A)) → T(A).

Source code in src/quivers/monadic/algebras.py
157
158
159
def structure_map(self) -> Morphism:
    """μ_A: T(T(A)) → T(A)."""
    return self._monad.multiply(self._base)

ObservedAlgebra

ObservedAlgebra(monad: Monad, carrier: SetObject, structure_tensor: Tensor, quantale: Quantale | None = None)

Bases: Algebra

An algebra defined by an explicit structure map tensor.

PARAMETER DESCRIPTION
monad

The monad T.

TYPE: Monad

carrier

The carrier object A.

TYPE: SetObject

structure_tensor

The tensor for α: T(A) → A.

TYPE: Tensor

quantale

The enrichment algebra. Defaults to PRODUCT_FUZZY.

TYPE: Quantale or None DEFAULT: None

Source code in src/quivers/monadic/algebras.py
177
178
179
180
181
182
183
184
185
186
187
def __init__(
    self,
    monad: Monad,
    carrier: SetObject,
    structure_tensor: torch.Tensor,
    quantale: Quantale | None = None,
) -> None:
    super().__init__(monad, carrier)
    q = quantale if quantale is not None else PRODUCT_FUZZY
    ta = monad.endofunctor.map_object(carrier)
    self._morphism = observed(ta, carrier, structure_tensor, quantale=q)

structure_map

structure_map() -> Morphism

The stored structure map α: T(A) → A.

Source code in src/quivers/monadic/algebras.py
189
190
191
def structure_map(self) -> Morphism:
    """The stored structure map α: T(A) → A."""
    return self._morphism

Coalgebra

Coalgebra(comonad: object, carrier: SetObject)

Bases: ABC

Abstract coalgebra for a comonad.

A coalgebra (A, γ) for comonad W consists of a carrier object A and a structure map γ: A → W(A).

PARAMETER DESCRIPTION
comonad

The comonad W (a Comonad instance).

TYPE: object

carrier

The carrier object A.

TYPE: SetObject

Source code in src/quivers/monadic/algebras.py
208
209
210
def __init__(self, comonad: object, carrier: SetObject) -> None:
    self._comonad = comonad
    self._carrier = carrier

comonad property

comonad: object

The comonad W.

carrier property

carrier: SetObject

The carrier object A.

structure_map abstractmethod

structure_map() -> Morphism

The structure map γ: A → W(A).

RETURNS DESCRIPTION
Morphism

The coalgebra structure map.

Source code in src/quivers/monadic/algebras.py
222
223
224
225
226
227
228
229
230
231
@abstractmethod
def structure_map(self) -> Morphism:
    """The structure map γ: A → W(A).

    Returns
    -------
    Morphism
        The coalgebra structure map.
    """
    ...

verify_counit_law

verify_counit_law(atol: float = 1e-05) -> bool

Verify ε_A ∘ γ = id_A.

PARAMETER DESCRIPTION
atol

Absolute tolerance for comparison.

TYPE: float DEFAULT: 1e-05

RETURNS DESCRIPTION
bool

True if the counit law holds within tolerance.

Source code in src/quivers/monadic/algebras.py
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
def verify_counit_law(self, atol: float = 1e-5) -> bool:
    """Verify ε_A ∘ γ = id_A.

    Parameters
    ----------
    atol : float
        Absolute tolerance for comparison.

    Returns
    -------
    bool
        True if the counit law holds within tolerance.
    """

    gamma = self.structure_map()
    eps = self._comonad.counit(self._carrier)  # type: ignore[union-attr]
    result = (gamma >> eps).tensor
    expected = identity(self._carrier).tensor

    return torch.allclose(result, expected, atol=atol)

verify_coassociativity

verify_coassociativity(atol: float = 1e-05) -> bool

Verify δ_A ∘ γ = W(γ) ∘ γ.

PARAMETER DESCRIPTION
atol

Absolute tolerance for comparison.

TYPE: float DEFAULT: 1e-05

RETURNS DESCRIPTION
bool

True if coassociativity holds within tolerance.

Source code in src/quivers/monadic/algebras.py
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
def verify_coassociativity(self, atol: float = 1e-5) -> bool:
    """Verify δ_A ∘ γ = W(γ) ∘ γ.

    Parameters
    ----------
    atol : float
        Absolute tolerance for comparison.

    Returns
    -------
    bool
        True if coassociativity holds within tolerance.
    """

    gamma = self.structure_map()
    delta = self._comonad.comultiply(self._carrier)  # type: ignore[union-attr]

    # left side: δ_A ∘ γ
    left = (gamma >> delta).tensor

    # right side: W(γ) ∘ γ
    w_gamma = self._comonad.endofunctor.map_morphism(gamma)  # type: ignore[union-attr]
    right = (gamma >> w_gamma).tensor

    return torch.allclose(left, right, atol=atol)

CofreeCoalgebra

CofreeCoalgebra(comonad: object, obj: SetObject)

Bases: Coalgebra

The cofree W-coalgebra on an object A.

The carrier is W(A) and the structure map is δ_A: W(A) → W(W(A)).

PARAMETER DESCRIPTION
comonad

The comonad W.

TYPE: object

obj

The base object A (the carrier will be W(A)).

TYPE: SetObject

Source code in src/quivers/monadic/algebras.py
297
298
299
300
def __init__(self, comonad: object, obj: SetObject) -> None:
    carrier = comonad.endofunctor.map_object(obj)  # type: ignore[union-attr]
    super().__init__(comonad, carrier)
    self._base = obj

base property

base: SetObject

The base object A (carrier is W(A)).

structure_map

structure_map() -> Morphism

δ_A: W(A) → W(W(A)).

Source code in src/quivers/monadic/algebras.py
307
308
309
def structure_map(self) -> Morphism:
    """δ_A: W(A) → W(W(A))."""
    return self._comonad.comultiply(self._base)  # type: ignore[union-attr]

ObservedCoalgebra

ObservedCoalgebra(comonad: object, carrier: SetObject, structure_tensor: Tensor, quantale: Quantale | None = None)

Bases: Coalgebra

A coalgebra defined by an explicit structure map tensor.

PARAMETER DESCRIPTION
comonad

The comonad W.

TYPE: object

carrier

The carrier object A.

TYPE: SetObject

structure_tensor

The tensor for γ: A → W(A).

TYPE: Tensor

quantale

The enrichment algebra. Defaults to PRODUCT_FUZZY.

TYPE: Quantale or None DEFAULT: None

Source code in src/quivers/monadic/algebras.py
327
328
329
330
331
332
333
334
335
336
337
def __init__(
    self,
    comonad: object,
    carrier: SetObject,
    structure_tensor: torch.Tensor,
    quantale: Quantale | None = None,
) -> None:
    super().__init__(comonad, carrier)
    q = quantale if quantale is not None else PRODUCT_FUZZY
    wa = comonad.endofunctor.map_object(carrier)  # type: ignore[union-attr]
    self._morphism = observed(carrier, wa, structure_tensor, quantale=q)

structure_map

structure_map() -> Morphism

The stored structure map γ: A → W(A).

Source code in src/quivers/monadic/algebras.py
339
340
341
def structure_map(self) -> Morphism:
    """The stored structure map γ: A → W(A)."""
    return self._morphism

EilenbergMooreCategory

EilenbergMooreCategory(monad: Monad)

The Eilenberg-Moore category of a monad.

Objects are T-algebras. Morphisms (A, α) → (B, β) are base morphisms f: A → B satisfying β ∘ T(f) = f ∘ α, i.e., algebra homomorphisms.

PARAMETER DESCRIPTION
monad

The underlying monad T.

TYPE: Monad

Source code in src/quivers/monadic/algebras.py
357
358
def __init__(self, monad: Monad) -> None:
    self._monad = monad

monad property

monad: Monad

The underlying monad.

free_algebra

free_algebra(obj: SetObject) -> FreeAlgebra

Construct the free T-algebra on an object.

PARAMETER DESCRIPTION
obj

The base object A.

TYPE: SetObject

RETURNS DESCRIPTION
FreeAlgebra

The free algebra with carrier T(A).

Source code in src/quivers/monadic/algebras.py
365
366
367
368
369
370
371
372
373
374
375
376
377
378
def free_algebra(self, obj: SetObject) -> FreeAlgebra:
    """Construct the free T-algebra on an object.

    Parameters
    ----------
    obj : SetObject
        The base object A.

    Returns
    -------
    FreeAlgebra
        The free algebra with carrier T(A).
    """
    return FreeAlgebra(self._monad, obj)

is_homomorphism

is_homomorphism(f: Morphism, source_alg: Algebra, target_alg: Algebra, atol: float = 1e-05) -> bool

Check if f: A → B is an algebra homomorphism.

Verifies β ∘ T(f) = f ∘ α.

PARAMETER DESCRIPTION
f

A morphism A → B between the carriers.

TYPE: Morphism

source_alg

The source algebra (A, α).

TYPE: Algebra

target_alg

The target algebra (B, β).

TYPE: Algebra

atol

Absolute tolerance for comparison.

TYPE: float DEFAULT: 1e-05

RETURNS DESCRIPTION
bool

True if f is a homomorphism within tolerance.

Source code in src/quivers/monadic/algebras.py
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
def is_homomorphism(
    self,
    f: Morphism,
    source_alg: Algebra,
    target_alg: Algebra,
    atol: float = 1e-5,
) -> bool:
    """Check if f: A → B is an algebra homomorphism.

    Verifies β ∘ T(f) = f ∘ α.

    Parameters
    ----------
    f : Morphism
        A morphism A → B between the carriers.
    source_alg : Algebra
        The source algebra (A, α).
    target_alg : Algebra
        The target algebra (B, β).
    atol : float
        Absolute tolerance for comparison.

    Returns
    -------
    bool
        True if f is a homomorphism within tolerance.
    """
    alpha = source_alg.structure_map()
    beta = target_alg.structure_map()
    tf = self._monad.endofunctor.map_morphism(f)

    # left: β ∘ T(f)
    left = (tf >> beta).tensor

    # right: f ∘ α
    right = (alpha >> f).tensor

    return torch.allclose(left, right, atol=atol)