Morphisms¶
Base morphism classes, composition operations, and shared morphism utilities.
morphisms
¶
Morphism hierarchy: V-enriched relations between finite sets.
A morphism from domain D to codomain C is represented as a tensor of shape (D.shape, C.shape) with entries in the lattice L of an algebra. Composition uses the algebra's operations (join over tensor product).
The hierarchy:
Morphism (abstract)
├── ObservedMorphism — fixed tensor (not learned)
├── LatentMorphism — nn.Parameter with sigmoid constraint
├── ComposedMorphism — f >> g (V-enriched composition)
├── ProductMorphism — f @ g (tensor / parallel product)
├── MarginalizedMorphism — contract codomain dims via join
├── FunctorMorphism — lazy image of a morphism under a functor
└── RepeatMorphism — runtime-variable iterated composition (T^n)
PyTorch boundary¶
The categorical hierarchy is intentionally not a subclass of
torch.nn.Module: a Morphism is a categorical object and a
Module is a PyTorch parameter container. When a Morphism needs to
be bound into a parameter-tracking context (a MonadicProgram,
a FanMorphism, a parametric-program parameter slot), the
adapter as_torch_module produces a backend-agnostic
nn.Module wrapping the morphism's parameters. Every
binding site funnels through this adapter so the categorical /
PyTorch boundary stays explicit and a JAX or numpy backend can
replace as_torch_module without touching the morphism
hierarchy itself.
Morphism
¶
Bases: ABC
Abstract base for morphisms between finite sets.
Subclasses must implement tensor (returns the materialized
tensor with values in the algebra's lattice) and module
(returns the nn.Module tree for parameter collection).
| PARAMETER | DESCRIPTION |
|---|---|
domain
|
Source object.
TYPE:
|
codomain
|
Target object.
TYPE:
|
algebra
|
The enrichment algebra. Defaults to PRODUCT_FUZZY.
TYPE:
|
Source code in src/quivers/core/morphisms.py
tensor
abstractmethod
property
¶
tensor: Tensor
Materialize the morphism as a tensor with values in L.
dagger
property
¶
Transpose / dagger of self : A → B, producing a
morphism B → A whose tensor has the domain and codomain
axes swapped.
The compact-closed structure of V-Cat means every object is
self-dual (A^* = A), so the dagger is well-defined for
every algebra. The semantic interpretation depends on the
algebra: ProductFuzzyAlgebra gives the tensor transpose, Markov
the Bayes-uniform-prior inversion, Viterbi the max-plus
reversal, Boolean the relational converse.
Categorically:
f^† = (ε_B ⊗ id_A) ∘ (id_B ⊗ f^* ⊗ id_A) ∘ (id_B ⊗ η_A)
— but for finite-set objects the unit / counit collapse to
the diagonal / co-diagonal, and the dagger reduces to a
tensor transpose along the domain/codomain axes.
| RETURNS | DESCRIPTION |
|---|---|
ObservedMorphism
|
Morphism |
__rshift__
¶
__rshift__(other: Morphism) -> ComposedMorphism
V-enriched composition: self >> other.
Composes self: A -> B with other: B -> C to yield a morphism A -> C, contracting over B using the algebra.
| PARAMETER | DESCRIPTION |
|---|---|
other
|
Right morphism whose domain must match self's codomain.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
ComposedMorphism
|
The composed morphism. |
Source code in src/quivers/core/morphisms.py
__matmul__
¶
__matmul__(other: Morphism) -> ProductMorphism
Tensor (parallel) product: self @ other.
Given self: A -> B and other: C -> D, produces a morphism A×C -> B×D whose tensor is the outer product via the algebra's tensor_op.
| PARAMETER | DESCRIPTION |
|---|---|
other
|
Right morphism.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
ProductMorphism
|
The product morphism. |
Source code in src/quivers/core/morphisms.py
change_base
¶
Transport this morphism along a change-of-base functor.
phi may be either a
quivers.core.algebra_morphisms.AlgebraHomomorphism
(pointwise: the action factors entry-by-entry through
phi.apply) or a
quivers.core.morphism_transformations.MorphismTransformation
(shape-aware: the action consumes the whole tensor plus
the morphism for axis resolution).
The result is a TransformedMorphism whose
tensor is recomputed on each access by applying
phi to the source's current tensor. The source's
learnable parameters are exposed through .module() so
torch.nn.Module.parameters walks reach them, and
each backward through a fresh .tensor access rebuilds
a graph rooted at those parameters; multi-step optimisation
through change-of-base is supported.
| PARAMETER | DESCRIPTION |
|---|---|
phi
|
The change-of-base functor. Its |
| RETURNS | DESCRIPTION |
|---|---|
TransformedMorphism
|
A morphism over |
Source code in src/quivers/core/morphisms.py
refactor
¶
Switch between flat and product views of this morphism.
Given a morphism f : A -> B whose tensor storage has
total numel matching the requested domain / codomain
objects, return an equivalent morphism f' : A' -> B'
whose tensor is the same data reshaped to the new factored
layout. A' and B' must be isomorphic to A and
B as objects — same cardinality, possibly different
product structure.
Categorically this is the action of an object iso
B ≅ B' on the morphism's tensor. Semantically it is
a no-op; presentation only.
| PARAMETER | DESCRIPTION |
|---|---|
domain
|
New domain. Must have
TYPE:
|
codomain
|
New codomain. Same numel constraint.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
ObservedMorphism
|
The reshape of |
Source code in src/quivers/core/morphisms.py
marginalize
¶
marginalize(*sets: SetObject) -> MarginalizedMorphism
Marginalize (join-reduce) over codomain components.
The codomain must be a ProductSet containing the sets to marginalize over. The result has a codomain with those components removed. Uses the algebra's join operation.
| PARAMETER | DESCRIPTION |
|---|---|
*sets
|
Codomain components to marginalize over.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
MarginalizedMorphism
|
The marginalized morphism. |
Source code in src/quivers/core/morphisms.py
trace
¶
trace(obj: SetObject) -> 'TransformedMorphism'
Trace of self : X ⊗ A → A ⊗ Y along obj = A,
producing a morphism X → Y.
Concretely the trace contracts the A axis on the domain
side with the A axis on the codomain side via the algebra's
tensor_op and then joins (self._algebra.join) over
the contracted axis. This is the categorical trace
tr_A(f) : X → Y = (ε_A ⊗ id_Y) ∘ (id_A ⊗ f) ∘ (η_A ⊗ id_X).
The morphism's domain must be a product set whose first
component is obj; the codomain must be a product set
whose first component is obj. If this is not the case
a TypeError is raised — the user should call
ProductSet.swap style helpers (not yet exposed) to
reorder axes before tracing.
| PARAMETER | DESCRIPTION |
|---|---|
obj
|
The object to contract over. Must appear at the start of both the domain and codomain product sets.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
ObservedMorphism
|
Morphism |
Source code in src/quivers/core/morphisms.py
370 371 372 373 374 375 376 377 378 379 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 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 | |
TransformedMorphism
¶
TransformedMorphism(source: 'Morphism', transform, domain: SetObject, codomain: SetObject, algebra: Algebra | None = None)
Bases: Morphism
A morphism whose tensor is a transformation of a source
morphism's tensor, recomputed on each tensor access.
The source morphism is registered as a submodule so
self.module().parameters() includes the source's learnable
parameters; the transform is applied lazily, so each backward
through a fresh .tensor access gets its own autograd graph
and multi-step optimisation propagates gradients correctly.
| PARAMETER | DESCRIPTION |
|---|---|
source
|
Underlying morphism whose tensor feeds the transform.
TYPE:
|
transform
|
Pure function applied to |
domain
|
Target domain (may differ from
TYPE:
|
codomain
|
Target codomain.
TYPE:
|
algebra
|
Target algebra. Defaults to the source's algebra.
TYPE:
|
Source code in src/quivers/core/morphisms.py
ObservedMorphism
¶
ObservedMorphism(domain: SetObject, codomain: SetObject, data: Tensor, algebra: Algebra | None = None)
Bases: Morphism
A morphism with a fixed (non-learnable) tensor.
| PARAMETER | DESCRIPTION |
|---|---|
domain
|
Source object.
TYPE:
|
codomain
|
Target object.
TYPE:
|
data
|
Fixed tensor of shape (domain.shape, codomain.shape).
TYPE:
|
algebra
|
The enrichment algebra. Defaults to PRODUCT_FUZZY.
TYPE:
|
Source code in src/quivers/core/morphisms.py
LatentMorphism
¶
LatentMorphism(domain: SetObject, codomain: SetObject, init_scale: float = 0.5, algebra: Algebra | None = None)
Bases: Morphism
A learnable morphism backed by an nn.Parameter.
Stores unconstrained real-valued parameters and applies sigmoid to produce [0,1]-valued fuzzy relation entries.
| PARAMETER | DESCRIPTION |
|---|---|
domain
|
Source object.
TYPE:
|
codomain
|
Target object.
TYPE:
|
init_scale
|
Standard deviation of the normal initialization for the unconstrained parameters. Default 0.5 (sigmoid maps this to roughly uniform over [0.3, 0.7]).
TYPE:
|
algebra
|
The enrichment algebra. Defaults to PRODUCT_FUZZY.
TYPE:
|
Source code in src/quivers/core/morphisms.py
ComposedMorphism
¶
Bases: Morphism
V-enriched composition of two morphisms.
Given left: A -> B and right: B -> C, produces A -> C by contracting over B using the algebra's compose method.
| PARAMETER | DESCRIPTION |
|---|---|
left
|
Left morphism (applied first).
TYPE:
|
right
|
Right morphism (applied second).
TYPE:
|
Source code in src/quivers/core/morphisms.py
ProductMorphism
¶
Bases: Morphism
Tensor (parallel) product of two morphisms.
Given left: A -> B and right: C -> D, produces A×C -> B×D. The tensor is the outer product of the two component tensors via the algebra's tensor_op.
| PARAMETER | DESCRIPTION |
|---|---|
left
|
Left morphism.
TYPE:
|
right
|
Right morphism.
TYPE:
|
Source code in src/quivers/core/morphisms.py
MarginalizedMorphism
¶
Bases: Morphism
Morphism with codomain dimensions marginalized via the algebra's join.
Given an inner morphism A -> B × C and a set B to marginalize, produces A -> C by join-reduction over B's dimensions.
| PARAMETER | DESCRIPTION |
|---|---|
inner
|
The morphism to marginalize.
TYPE:
|
sets_to_marginalize
|
Codomain components to marginalize over.
TYPE:
|
Source code in src/quivers/core/morphisms.py
FunctorMorphism
¶
Bases: Morphism
Lazy image of a morphism under a functor.
Recomputes the tensor on each access from the inner morphism, preserving gradient flow through the functor's map_tensor method. No additional parameters beyond those of the inner morphism.
| PARAMETER | DESCRIPTION |
|---|---|
functor
|
The functor that produced this morphism.
TYPE:
|
inner
|
The original morphism being mapped.
TYPE:
|
domain
|
The image of the inner morphism's domain under the functor.
TYPE:
|
codomain
|
The image of the inner morphism's codomain under the functor.
TYPE:
|
Source code in src/quivers/core/morphisms.py
RepeatMorphism
¶
RepeatMorphism(inner: Morphism, n: int = 1)
Bases: Morphism
Runtime-variable iterated composition (matrix power).
Wraps an endomorphism f : X -> X and computes f^n at runtime, where n can be changed between calls. Uses repeated squaring for O(log n) algebra compositions.
For an endomorphism T : S -> S under an algebra, T^n is the
n-fold Kleisli composition. Under the product_fuzzy algebra
with stochastic matrices, this is standard matrix power.
| PARAMETER | DESCRIPTION |
|---|---|
inner
|
An endomorphism (domain must equal codomain).
TYPE:
|
n
|
Initial number of repetitions (default 1). Can be changed
later via the
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
TypeError
|
If the inner morphism is not an endomorphism. |
ValueError
|
If n < 1. |
Examples:
>>> T = morphism(S, S)
>>> rep = RepeatMorphism(T, n=5)
>>> rep.tensor # computes T^5
>>> rep.n_steps = 10
>>> rep.tensor # now computes T^10
Source code in src/quivers/core/morphisms.py
CurriedMorphism
¶
CurriedMorphism(inner: Morphism, direction: str = 'right')
Bases: Morphism
Residuation-witness curried morphism.
For an inner morphism f : X * Y -> Z whose codomain Z lives
in a residuated universe (a FreeResiduated), produces the
morphism corresponding to the relevant residuation isomorphism:
direction='right'realises the right-residuationX * Y -> Z ≅ X -> Z/Y(counit of the right-residual adjunction),direction='left'realises the left-residuationX * Y -> Z ≅ Y -> X\Z.
The underlying tensor data is reinterpreted, not recomputed: the same V-relation is presented under a different domain/codomain factoring in the residuated universe.
| PARAMETER | DESCRIPTION |
|---|---|
inner
|
The base morphism. Must have a domain that factors as a
non-trivial product (
TYPE:
|
direction
|
Which residuation to apply.
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
TypeError
|
If |
Source code in src/quivers/core/morphisms.py
morphism
¶
morphism(domain: SetObject, codomain: SetObject, init_scale: float = 0.5, algebra: Algebra | None = None) -> LatentMorphism
Create a latent (learnable) morphism.
| PARAMETER | DESCRIPTION |
|---|---|
domain
|
Source object.
TYPE:
|
codomain
|
Target object.
TYPE:
|
init_scale
|
Initialization scale for unconstrained parameters.
TYPE:
|
algebra
|
The enrichment algebra. Defaults to PRODUCT_FUZZY.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
LatentMorphism
|
A learnable morphism. |
Source code in src/quivers/core/morphisms.py
observed
¶
observed(domain: SetObject, codomain: SetObject, data: Tensor, algebra: Algebra | None = None) -> ObservedMorphism
Create an observed (fixed) morphism.
| PARAMETER | DESCRIPTION |
|---|---|
domain
|
Source object.
TYPE:
|
codomain
|
Target object.
TYPE:
|
data
|
Fixed tensor.
TYPE:
|
algebra
|
The enrichment algebra. Defaults to PRODUCT_FUZZY.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
ObservedMorphism
|
A fixed morphism. |
Source code in src/quivers/core/morphisms.py
identity
¶
identity(obj: SetObject, algebra: Algebra | None = None) -> ObservedMorphism
Create the identity morphism on an object.
Returns an observed morphism obj -> obj whose tensor is the identity: unit on the diagonal, zero elsewhere.
| PARAMETER | DESCRIPTION |
|---|---|
obj
|
The object to create an identity for.
TYPE:
|
algebra
|
The enrichment algebra. Defaults to PRODUCT_FUZZY.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
ObservedMorphism
|
The identity morphism. |
Source code in src/quivers/core/morphisms.py
as_torch_module
¶
as_torch_module(m: object) -> Module
Coerce a Morphism into an nn.Module for parameter
tracking at a binding site.
The adapter draws the line between the categorical morphism
hierarchy (backend-agnostic; lives in quivers.core) and
PyTorch's parameter-container infrastructure. Every site that
needs to register a morphism's parameters with a parent
nn.Module (the MonadicProgram step list, the
submodule list of a FanMorphism / StackMorphism
composite, a parametric-program parameter slot bound to a
morphism) calls this function once and stores the result.
| PARAMETER | DESCRIPTION |
|---|---|
m
|
The morphism (or other object) to wrap. Accepted forms:
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Module
|
A module whose parameters / buffers are exactly the
morphism's, suitable for |
| RAISES | DESCRIPTION |
|---|---|
TypeError
|
|
Source code in src/quivers/core/morphisms.py
1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 | |
extract_morphism
¶
Recover the Morphism previously bound through
as_torch_module.
Returns the categorical morphism stored on the wrapper, or
None if the module was registered directly (i.e. was
already an nn.Module subclass) and thus has no
separate categorical object attached.
| PARAMETER | DESCRIPTION |
|---|---|
module
|
A module bound into a parameter-tracking context.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Morphism or None
|
The wrapped morphism, or |
Source code in src/quivers/core/morphisms.py
cup
¶
cup(obj: SetObject, algebra: Algebra | None = None) -> ObservedMorphism
The compact-closed unit η_A : I → A ⊗ A.
For finite-set objects with their natural product, η_A is
the diagonal: every entry (a, a) carries the algebra's
monoidal unit and the off-diagonal entries carry the join unit
(zero). The Kronecker-like tensor produced is the identity
morphism's tensor reshaped from (*A.shape, *A.shape) to
(1, *A.shape, *A.shape) so that the leading axis is the
singleton input I.
Categorically the cup and the trivial-domain identity satisfy
ε ∘ (id ⊗ η) = id; the snake equation that makes V-Cat
compact-closed.
| PARAMETER | DESCRIPTION |
|---|---|
obj
|
The object whose dual is being introduced. Every algebra ships an identity tensor; this morphism reshapes it as a Kleisli arrow from the singleton domain.
TYPE:
|
algebra
|
Override the default (ProductFuzzyAlgebra) algebra.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
ObservedMorphism
|
Morphism |
Source code in src/quivers/core/morphisms.py
cap
¶
cap(obj: SetObject, algebra: Algebra | None = None) -> ObservedMorphism
The compact-closed counit ε_A : A ⊗ A → I.
The dual of cup. The tensor is the diagonal flattened
into (*A.shape, *A.shape, 1) so the trailing axis is the
unit codomain I.
| PARAMETER | DESCRIPTION |
|---|---|
obj
|
The object
TYPE:
|
algebra
|
Override the default (ProductFuzzyAlgebra) algebra.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
ObservedMorphism
|
Morphism |