This module is provides a representation for categories from Category Theory.
Instances of this class represent objects in some category.
Instances of this class represent arrows or morphisms between objects in some category.
Instances of this class are intended to represent categories.
a class of objects
where is an arrow with source
and target
,
in which case we define
and
a composition operation between arrows
an ‘identity’ arrow for each object
And it must satisfy the following:
for every pair of arrows
and
, if the target of
is the source of
, then their composition, written
, exists, and is an arrow whose source is the source of
and whose target is the target of
. In short:
if
and
then
for each object
, the identity arrow
is the identity with respect to composition. This is,
- for any arrow
,
- for any arrow
,
Composition is associative: for any arrows
,
,
![]()
Instances of the Category class are intended to implement these categories, where objects are any Python objects and arrows are instances of the Arrow class (or any subclass).
This class is intended to be subclassed. In particular, a subclass should implement the composition and identity methods. Then to obtain the composition, a user calls the composite() method and to obtaind the identity, the user calls the ident() method of this class.
The composite() method is normally called via the
Arrow.__mul__() method so if and
then we can obtain
by calling:
g * f
instead of:
cat.composite(f,g)
The constructor creates a category whose objects and arrows belong to the given classes.
Parameters: |
---|
Returns the arrow g * f. Note that this intends to be f first, then g: f: A -> B and g: B -> C, then g * f == f >> g : A -> C
Note: it does not apply the composition, just computes and returns the composite arrow.
Instances of this subclass of Category make the assumption that the sets of objects and arrows are finite.
Compute the closure: generates all compositions and identities.
TODO: check whether this indeed computes the closure: add_edge adds new edges to self.arrows, but does this guarantee that all newly added edges will be traversed? If not, we may replace it with something like this:
arrow_list = list(self.arrows) new_arrows = [] for f in arrow_list:
- for g in f.target.outgoing:
- new_arrow = self.compose(f, g) new_arrows.append(new_arrow) arrow_list.append(new_arrow)