Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/GAP/pkg/cap/gap/   (Algebra von RWTH Aachen Version 4.15.1©)  Datei vom 22.8.2025 mit Größe 117 kB image not shown  

Quelle  UniversalObjects.gd   Sprache: unbekannt

 
# SPDX-License-Identifier: GPL-2.0-or-later
# CAP: Categories, Algorithms, Programming
#
# Declarations
#
#! @Chapter Universal Objects

####################################
##
#! @Section Kernel
##
####################################

#! For a given morphism $\alpha: A \rightarrow B$, a kernel of $\alpha$ consists of three parts:
#! * an object $K$, 
#! * a morphism $\iota: K \rightarrow A$ such that $\alpha \circ \iota \sim_{K,B} 0$,
#! * a dependent function $u$ mapping each morphism $\tau: T \rightarrow A$ satisfying $\alpha \circ \tau \sim_{T,B} 0$ to a morphism $u(\tau): T \rightarrow K$ such that $\iota \circ u( \tau ) \sim_{T,A} \tau$. 
#! The triple $( K, \iota, u )$ is called a <Emph>kernel</Emph> of $\alpha$ if the morphisms $u( \tau )$ are uniquely determined up to
#! congruence of morphisms.
#! We denote the object $K$ of such a triple by $\mathrm{KernelObject}(\alpha)$.
#! We say that the morphism $u(\tau)$ is induced by the
#! <Emph>universal property of the kernel</Emph>.
#! $\\ $
#! $\mathrm{KernelObject}$ is a functorial operation. This means:
#! for $\mu: A \rightarrow A'$, $\nu: B \rightarrow B'$,
#! $\alpha: A \rightarrow B$, $\alpha': A' \rightarrow B'$ such that $\nu \circ \alpha \sim_{A,B'} \alpha' \circ \mu$,
#! we obtain a morphism $\mathrm{KernelObject}( \alpha ) \rightarrow \mathrm{KernelObject}( \alpha' )$.

#! @BeginLatexOnly
#! \begin{center}
#! \begin{tikzpicture}
#! \def\w{2}
#! \node (K) at (-\w,0) {$K$};
#! \node (T) at (-\w,\w) {$T$};
#! \node (A) at (0,0) {$A$};
#! \node (B) at (\w,0) {$B$};
#! \draw[-latex] (A) to node[pos=0.45, above] {$\alpha$} (B);
#! \draw[-latex] (K) to node[pos=0.45, above] {$\iota$} (A);
#! \draw[-latex] (T) to node[pos=0.45, above right] {$\tau$} (A);
#! \draw[dashed, -latex] (T) to node[pos=0.45, left] {$\exists ! u( \tau )$} (K);
#! \draw[-latex, dotted] (T) to [out = 0, in = 90] node[pos=0.45, above right] {$\alpha \circ \tau \sim_{T,B} 0$} (B);
#! \draw[-latex, dotted] (K) to [out = -45, in = -135] node[pos=0.45, below] {$\alpha \circ \iota \sim_{K,B} 0$} (B);
#! \end{tikzpicture}
#! \end{center}
#! @EndLatexOnly


## Main Operations and Attributes
#! @Description
#! The argument is a morphism $\alpha$.
#! The output is the kernel $K$ of $\alpha$.
#! @Returns an object
#! @Arguments alpha
DeclareAttribute( "KernelObject",
                  IsCapCategoryMorphism );

#! @Description
#! The argument is a morphism $\alpha: A \rightarrow B$.
#! The output is the kernel embedding $\iota: \mathrm{KernelObject}(\alpha) \rightarrow A$.
#! @Returns a morphism in $\mathrm{Hom}(\mathrm{KernelObject}(\alpha),A)$
#! @Arguments alpha
DeclareAttribute( "KernelEmbedding",
                  IsCapCategoryMorphism );

#! @Description
#! The arguments are a morphism $\alpha: A \rightarrow B$
#! and an object $K = \mathrm{KernelObject}(\alpha)$.
#! The output is the kernel embedding $\iota: K \rightarrow A$.
#! @Returns a morphism in $\mathrm{Hom}(K,A)$
#! @Arguments alpha, K
DeclareOperation( "KernelEmbeddingWithGivenKernelObject",
                  [ IsCapCategoryMorphism, IsCapCategoryObject ] );

#! @Description
#! The argument is a morphism $\alpha: A \rightarrow B$.
#! The output is the zero morphism $0: \mathrm{KernelObject}(\alpha) \rightarrow B$.
#! @Returns the zero morphism in $\mathrm{Hom}( \mathrm{KernelObject}(\alpha), B )$
#! @Arguments alpha
DeclareOperation( "MorphismFromKernelObjectToSink",
                  [ IsCapCategoryMorphism ] );

#! @Description
#! The arguments are a morphism $\alpha: A \rightarrow B$
#! and an object $K = \mathrm{KernelObject}(\alpha)$.
#! The output is the zero morphism $0: K \rightarrow B$.
#! @Returns the zero morphism in $\mathrm{Hom}( K, B )$
#! @Arguments alpha, K
DeclareOperation( "MorphismFromKernelObjectToSinkWithGivenKernelObject",
                  [ IsCapCategoryMorphism, IsCapCategoryObject ] );

#! @Description
#! The arguments are a morphism $\alpha: A \rightarrow B$, a test object $T$,
#! and a test morphism $\tau: T \rightarrow A$ satisfying $\alpha \circ \tau \sim_{T,B} 0$.
#! For convenience, the test object <A>T</A> can be omitted and is automatically derived from <A>tau</A> in that case.
#! The output is the morphism $u(\tau): T \rightarrow \mathrm{KernelObject}(\alpha)$
#! given by the universal property of the kernel.
#! @Returns a morphism in $\mathrm{Hom}(T,\mathrm{KernelObject}(\alpha))$
#! @Arguments alpha, T, tau
DeclareOperation( "KernelLift",
                  [ IsCapCategoryMorphism, IsCapCategoryObject, IsCapCategoryMorphism ] );

#! @Description
#! The arguments are a morphism $\alpha: A \rightarrow B$, a test object $T$,
#! a test morphism $\tau: T \rightarrow A$ satisfying $\alpha \circ \tau \sim_{T,B} 0$,
#! and an object $K = \mathrm{KernelObject}(\alpha)$.
#! For convenience, the test object <A>T</A> can be omitted and is automatically derived from <A>tau</A> in that case.
#! The output is the morphism $u(\tau): T \rightarrow K$
#! given by the universal property of the kernel.
#! @Returns a morphism in $\mathrm{Hom}(T,K)$
#! @Arguments alpha, T, tau, K
DeclareOperation( "KernelLiftWithGivenKernelObject",
                  [ IsCapCategoryMorphism, IsCapCategoryObject, IsCapCategoryMorphism, IsCapCategoryObject ] );

#! @Description
#! The argument is a list $L = [ \alpha: A \rightarrow B, [ \mu: A \rightarrow A', \nu: B \rightarrow B' ], \alpha': A' \rightarrow B' ]$ of morphisms.
#! The output is the morphism
#! $\mathrm{KernelObject}( \alpha ) \rightarrow \mathrm{KernelObject}( \alpha' )$
#! given by the functoriality of the kernel.
#! @Returns a morphism in $\mathrm{Hom}( \mathrm{KernelObject}( \alpha ), \mathrm{KernelObject}( \alpha' ) )$
#! @Arguments L
DeclareOperation( "KernelObjectFunctorial",
                  [ IsList ] );

#! @Description
#! The arguments are three morphisms
#! $\alpha: A \rightarrow B$, $\mu: A \rightarrow A'$, $\alpha': A' \rightarrow B'$.
#! The output is the morphism
#! $\mathrm{KernelObject}( \alpha ) \rightarrow \mathrm{KernelObject}( \alpha' )$
#! given by the functoriality of the kernel.
#! @Returns a morphism in $\mathrm{Hom}( \mathrm{KernelObject}( \alpha ), \mathrm{KernelObject}( \alpha' ) )$
#! @Arguments alpha, mu, alpha_prime
DeclareOperation( "KernelObjectFunctorial",
                  [ IsCapCategoryMorphism, IsCapCategoryMorphism, IsCapCategoryMorphism ] );

#! @Description
#! The arguments are an object $s = \mathrm{KernelObject}( \alpha )$,
#! three morphisms
#! $\alpha: A \rightarrow B$, $\mu: A \rightarrow A'$, $\alpha': A' \rightarrow B'$,
#! and an object $r = \mathrm{KernelObject}( \alpha' )$.
#! The output is the morphism
#! $\mathrm{KernelObject}( \alpha ) \rightarrow \mathrm{KernelObject}( \alpha' )$
#! given by the functoriality of the kernel.
#! @Returns a morphism in $\mathrm{Hom}( s, r )$
#! @Arguments s, alpha, mu, alpha_prime, r
DeclareOperation( "KernelObjectFunctorialWithGivenKernelObjects",
                  [ IsCapCategoryObject, IsCapCategoryMorphism, IsCapCategoryMorphism, 
                    IsCapCategoryMorphism, IsCapCategoryObject ] );

#! @Description
#! The arguments are an object $s = \mathrm{KernelObject}( \alpha )$,
#! four morphisms
#! $\alpha: A \rightarrow B$, $\mu: A \rightarrow A'$, $\nu: B \rightarrow B'$, $\alpha': A' \rightarrow B'$,
#! and an object $r = \mathrm{KernelObject}( \alpha' )$.
#! The output is the morphism
#! $\mathrm{KernelObject}( \alpha ) \rightarrow \mathrm{KernelObject}( \alpha' )$
#! given by the functoriality of the kernel.
#! @Returns a morphism in $\mathrm{Hom}( s, r )$
#! @Arguments s, alpha, mu, nu, alpha_prime, r
DeclareOperation( "KernelObjectFunctorialWithGivenKernelObjects",
                  [ IsCapCategoryObject, IsCapCategoryMorphism, IsCapCategoryMorphism,
                    IsCapCategoryMorphism, IsCapCategoryMorphism, IsCapCategoryObject ] );


#! @Chapter Universal Objects

####################################
##
#!  @Section Cokernel
##
####################################

#! For a given morphism $\alpha: A \rightarrow B$, a cokernel of $\alpha$ consists of three parts:
#! * an object $K$,
#! * a morphism $\epsilon: B \rightarrow K$ such that $\epsilon \circ \alpha \sim_{A,K} 0$,
#! * a dependent function $u$ mapping each $\tau: B \rightarrow T$ satisfying $\tau \circ \alpha \sim_{A, T} 0$ to a morphism $u(\tau):K \rightarrow T$ such that $u(\tau) \circ \epsilon \sim_{B,T} \tau$.
#! The triple $( K, \epsilon, u )$ is called a <Emph>cokernel</Emph> of $\alpha$ if the morphisms $u( \tau )$ are uniquely determined up to
#! congruence of morphisms.
#! We denote the object $K$ of such a triple by $\mathrm{CokernelObject}(\alpha)$.
#! We say that the morphism $u(\tau)$ is induced by the
#! <Emph>universal property of the cokernel</Emph>.
#! $\\ $
#! $\mathrm{CokernelObject}$ is a functorial operation. This means:
#! for $\mu: A \rightarrow A'$, $\nu: B \rightarrow B'$,
#! $\alpha: A \rightarrow B$, $\alpha': A' \rightarrow B'$ such that $\nu \circ \alpha \sim_{A,B'} \alpha' \circ \mu$,
#! we obtain a morphism $\mathrm{CokernelObject}( \alpha ) \rightarrow \mathrm{CokernelObject}( \alpha' )$.

#! @BeginLatexOnly
#! \begin{center}
#! \begin{tikzpicture}
#! \def\w{2}
#! \node (A) at (0,0) {$A$};
#! \node (B) at (\w,0) {$B$};
#! \node (K) at (2*\w,0) {$K$};
#! \node (T) at (2*\w,\w) {$T$};
#! \draw[-latex] (A) to node[pos=0.45, above] {$\alpha$} (B);
#! \draw[-latex] (B) to node[pos=0.45, above] {$\epsilon$} (K);
#! \draw[-latex] (B) to node[pos=0.45, above left] {$\tau$} (T);
#! \draw[dashed, -latex] (K) to node[pos=0.45, right] {$\exists ! u( \tau )$} (T);
#! \draw[-latex, dotted] (A) to [out = 90, in = 180] node[pos=0.45, above left] {$\tau \circ \alpha \sim_{A, T} 0$} (T);
#! \draw[-latex, dotted] (A) to [out = -45, in = -135] node[pos=0.45, below] {$\epsilon \circ \alpha \sim_{A,K} 0$} (K);
#! \end{tikzpicture}
#! \end{center}
#! @EndLatexOnly


## Main Operations and Attributes
#! @Description
#! The argument is a morphism $\alpha: A \rightarrow B$.
#! The output is the cokernel $K$ of $\alpha$.
#! @Returns an object
#! @Arguments alpha
DeclareAttribute( "CokernelObject",
                  IsCapCategoryMorphism );

#! @Description
#! The argument is a morphism $\alpha: A \rightarrow B$.
#! The output is the cokernel projection $\epsilon: B \rightarrow \mathrm{CokernelObject}( \alpha )$.
#! @Returns a morphism in $\mathrm{Hom}(B, \mathrm{CokernelObject}( \alpha ))$
#! @Arguments alpha
DeclareAttribute( "CokernelProjection",
                  IsCapCategoryMorphism );

#! @Description
#! The arguments are a morphism $\alpha: A \rightarrow B$
#! and an object $K = \mathrm{CokernelObject}(\alpha)$.
#! The output is the cokernel projection $\epsilon: B \rightarrow \mathrm{CokernelObject}( \alpha )$.
#! @Returns a morphism in $\mathrm{Hom}(B, K)$
#! @Arguments alpha, K
DeclareOperation( "CokernelProjectionWithGivenCokernelObject",
                  [ IsCapCategoryMorphism, IsCapCategoryObject ] );

#! @Description
#! The argument is a morphism $\alpha: A \rightarrow B$.
#! The output is the zero morphism $0: A \rightarrow \mathrm{CokernelObject}(\alpha)$.
#! @Returns the zero morphism in $\mathrm{Hom}( A, \mathrm{CokernelObject}( \alpha ) )$.
#! @Arguments alpha
DeclareOperation( "MorphismFromSourceToCokernelObject",
                  [ IsCapCategoryMorphism ] );

#! @Description
#! The argument is a morphism $\alpha: A \rightarrow B$
#! and an object $K = \mathrm{CokernelObject}(\alpha)$.
#! The output is the zero morphism $0: A \rightarrow K$.
#! @Returns the zero morphism in $\mathrm{Hom}( A, K )$.
#! @Arguments alpha, K
DeclareOperation( "MorphismFromSourceToCokernelObjectWithGivenCokernelObject",
                  [ IsCapCategoryMorphism, IsCapCategoryObject ] );

#! @Description
#! The arguments are a morphism $\alpha: A \rightarrow B$, a test object $T$,
#! and a test morphism $\tau: B \rightarrow T$ satisfying $\tau \circ \alpha \sim_{A, T} 0$.
#! For convenience, the test object <A>T</A> can be omitted and is automatically derived from <A>tau</A> in that case.
#! The output is the morphism $u(\tau): \mathrm{CokernelObject}(\alpha) \rightarrow T$
#! given by the universal property of the cokernel.
#! @Returns a morphism in $\mathrm{Hom}(\mathrm{CokernelObject}(\alpha),T)$
#! @Arguments alpha, T, tau
DeclareOperation( "CokernelColift",
                  [ IsCapCategoryMorphism, IsCapCategoryObject, IsCapCategoryMorphism ] );

#! @Description
#! The arguments are a morphism $\alpha: A \rightarrow B$, a test object $T$,
#! a test morphism $\tau: B \rightarrow T$ satisfying $\tau \circ \alpha \sim_{A, T} 0$,
#! and an object $K = \mathrm{CokernelObject}(\alpha)$.
#! For convenience, the test object <A>T</A> can be omitted and is automatically derived from <A>tau</A> in that case.
#! The output is the morphism $u(\tau): K \rightarrow T$
#! given by the universal property of the cokernel.
#! @Returns a morphism in $\mathrm{Hom}(K,T)$
#! @Arguments alpha, T, tau, K
DeclareOperation( "CokernelColiftWithGivenCokernelObject",
                  [ IsCapCategoryMorphism, IsCapCategoryObject, IsCapCategoryMorphism, IsCapCategoryObject ] );

#! @Description
#! The argument is a list $L = [ \alpha: A \rightarrow B, [ \mu:A \rightarrow A', \nu: B \rightarrow B' ], \alpha': A' \rightarrow B' ]$.
#! The output is the morphism
#! $\mathrm{CokernelObject}( \alpha ) \rightarrow \mathrm{CokernelObject}( \alpha' )$
#! given by the functoriality of the cokernel.
#! @Returns a morphism in $\mathrm{Hom}(\mathrm{CokernelObject}( \alpha ), \mathrm{CokernelObject}( \alpha' ))$
#! @Arguments L
DeclareOperation( "CokernelObjectFunctorial",
                  [ IsList ] );

#! @Description
#! The arguments are three morphisms
#! $\alpha: A \rightarrow B, \nu: B \rightarrow B', \alpha': A' \rightarrow B'$.
#! The output is the morphism
#! $\mathrm{CokernelObject}( \alpha ) \rightarrow \mathrm{CokernelObject}( \alpha' )$
#! given by the functoriality of the cokernel.
#! @Returns a morphism in $\mathrm{Hom}(\mathrm{CokernelObject}( \alpha ), \mathrm{CokernelObject}( \alpha' ))$
#! @Arguments alpha, nu, alpha_prime
DeclareOperation( "CokernelObjectFunctorial",
                  [ IsCapCategoryMorphism, IsCapCategoryMorphism, IsCapCategoryMorphism ] );

#! @Description
#! The arguments are an object $s = \mathrm{CokernelObject}( \alpha )$,
#! three morphisms
#! $\alpha: A \rightarrow B, \nu: B \rightarrow B', \alpha': A' \rightarrow B'$,
#! and an object $r = \mathrm{CokernelObject}( \alpha' )$.
#! The output is the morphism
#! $\mathrm{CokernelObject}( \alpha ) \rightarrow \mathrm{CokernelObject}( \alpha' )$
#! given by the functoriality of the cokernel.
#! @Returns a morphism in $\mathrm{Hom}(s, r)$
#! @Arguments s, alpha, nu, alpha_prime, r
DeclareOperation( "CokernelObjectFunctorialWithGivenCokernelObjects",
                  [ IsCapCategoryObject, IsCapCategoryMorphism, IsCapCategoryMorphism, 
                    IsCapCategoryMorphism, IsCapCategoryObject ] );

#! @Description
#! The arguments are an object $s = \mathrm{CokernelObject}( \alpha )$,
#! four morphisms
#! $\alpha: A \rightarrow B, \mu: A \rightarrow A', \nu: B \rightarrow B', \alpha': A' \rightarrow B'$,
#! and an object $r = \mathrm{CokernelObject}( \alpha' )$.
#! The output is the morphism
#! $\mathrm{CokernelObject}( \alpha ) \rightarrow \mathrm{CokernelObject}( \alpha' )$
#! given by the functoriality of the cokernel.
#! @Returns a morphism in $\mathrm{Hom}(s, r)$
#! @Arguments s, alpha, mu, nu, alpha_prime, r
DeclareOperation( "CokernelObjectFunctorialWithGivenCokernelObjects",
                  [ IsCapCategoryObject, IsCapCategoryMorphism, IsCapCategoryMorphism,
                    IsCapCategoryMorphism, IsCapCategoryMorphism, IsCapCategoryObject ] );


#! @Chapter Universal Objects

####################################
##
#! @Section Zero Object
##
####################################

#! A zero object consists of three parts:
#! * an object $Z$,
#! * a function $u_{\mathrm{in}}$ mapping each object $A$ to a morphism $u_{\mathrm{in}}(A): A \rightarrow Z$,
#! * a function $u_{\mathrm{out}}$ mapping each object $A$ to a morphism $u_{\mathrm{out}}(A): Z \rightarrow A$.
#! The triple $(Z, u_{\mathrm{in}}, u_{\mathrm{out}})$ is called a <Emph>zero object</Emph> if the morphisms 
#! $u_{\mathrm{in}}(A)$, $u_{\mathrm{out}}(A)$ are uniquely determined up to congruence of morphisms.
#! We denote the object $Z$ of such a triple by $\mathrm{ZeroObject}$.
#! We say that the morphisms $u_{\mathrm{in}}(A)$ and $u_{\mathrm{out}}(A)$ are induced by the
#! <Emph>universal property of the zero object</Emph>.
## Main Operations and Attributes

#! @Description
#! The argument is a category $C$.
#! The output is a zero object $Z$ of $C$.
#! @Returns an object
#! @Arguments C
DeclareAttribute( "ZeroObject",
                  IsCapCategory );

#! @Description
#! This is a convenience method.
#! The argument is a cell $c$.
#! The output is a zero object $Z$ of the
#! category $C$ for which $c \in C$.
#! @Returns an object
#! @Arguments c
DeclareAttribute( "ZeroObject",
                  IsCapCategoryCell );

#! @Description
#! The argument is an object $A$.
#! The output is the universal morphism $u_{\mathrm{out}}: \mathrm{ZeroObject} \rightarrow A$.
#! @Returns a morphism in $\mathrm{Hom}(\mathrm{ZeroObject}, A)$
#! @Arguments A
DeclareAttribute( "UniversalMorphismFromZeroObject",
                  IsCapCategoryObject );

#! @Description
#! The arguments are an object $A$,
#! and a zero object $Z = \mathrm{ZeroObject}$.
#! The output is the universal morphism $u_{\mathrm{out}}: Z \rightarrow A$.
#! @Returns a morphism in $\mathrm{Hom}(Z, A)$
#! @Arguments A, Z
DeclareOperation( "UniversalMorphismFromZeroObjectWithGivenZeroObject",
                  [ IsCapCategoryObject, IsCapCategoryObject ] );

#! @Description
#! The argument is an object $A$.
#! The output is the universal morphism $u_{\mathrm{in}}: A \rightarrow \mathrm{ZeroObject}$.
#! @Returns a morphism in $\mathrm{Hom}(A, \mathrm{ZeroObject})$
#! @Arguments A
DeclareAttribute( "UniversalMorphismIntoZeroObject",
                  IsCapCategoryObject );

#! @Description
#! The arguments are an object $A$,
#! and a zero object $Z = \mathrm{ZeroObject}$.
#! The output is the universal morphism $u_{\mathrm{in}}: A \rightarrow Z$.
#! @Returns a morphism in $\mathrm{Hom}(A, Z)$
#! @Arguments A, Z
DeclareOperation( "UniversalMorphismIntoZeroObjectWithGivenZeroObject",
                  [ IsCapCategoryObject, IsCapCategoryObject ] );

#! @Description
#! This is a synonym for `UniversalMorphismFromZeroObject`.
#! @Returns a morphism in $\mathrm{Hom}(\mathrm{ZeroObject}, A)$
#! @Arguments A
# DeclareAttribute( "MorphismFromZeroObject", IsCapCategoryObject );
# this comment stops AutoDoc from trying to parse the next line (which it can't at the moment)
DeclareSynonymAttr( "MorphismFromZeroObject",
                    UniversalMorphismFromZeroObject );

#! @Description
#! This is a synonym for `UniversalMorphismIntoZeroObject`.
#! @Returns a morphism in $\mathrm{Hom}(A, \mathrm{ZeroObject})$
#! @Arguments A
# DeclareAttribute( "MorphismIntoZeroObject", IsCapCategoryObject );
# this comment stops AutoDoc from trying to parse the next line (which it can't at the moment)
DeclareSynonymAttr( "MorphismIntoZeroObject",
                    UniversalMorphismIntoZeroObject );

#! @Description
#! The argument is a category $C$.
#! The output is the unique isomorphism $\mathrm{ZeroObject} \rightarrow \mathrm{InitialObject}$.
#! @Returns a morphism in $\mathrm{Hom}(\mathrm{ZeroObject}, \mathrm{InitialObject})$
#! @Arguments C
DeclareAttribute( "IsomorphismFromZeroObjectToInitialObject",
                  IsCapCategory );

#! @Description
#! The argument is a category $C$.
#! The output is the unique isomorphism $\mathrm{InitialObject} \rightarrow \mathrm{ZeroObject}$.
#! @Returns a morphism in $\mathrm{Hom}(\mathrm{InitialObject}, \mathrm{ZeroObject})$
#! @Arguments C
DeclareAttribute( "IsomorphismFromInitialObjectToZeroObject",
                  IsCapCategory );

#! @Description
#! The argument is a category $C$.
#! The output is the unique isomorphism $\mathrm{ZeroObject} \rightarrow \mathrm{TerminalObject}$.
#! @Returns a morphism in $\mathrm{Hom}(\mathrm{ZeroObject}, \mathrm{TerminalObject})$
#! @Arguments C
DeclareAttribute( "IsomorphismFromZeroObjectToTerminalObject",
                  IsCapCategory );

#! @Description
#! The argument is a category $C$.
#! The output is the unique isomorphism $\mathrm{TerminalObject} \rightarrow \mathrm{ZeroObject}$.
#! @Returns a morphism in $\mathrm{Hom}(\mathrm{TerminalObject}, \mathrm{ZeroObject})$
#! @Arguments C
DeclareAttribute( "IsomorphismFromTerminalObjectToZeroObject",
                  IsCapCategory );

#! @Description
#! The argument is a category $C$.
#! The output is the unique morphism $\mathrm{ZeroObject} \rightarrow \mathrm{ZeroObject}$.
#! @Returns a morphism in $\mathrm{Hom}(\mathrm{ZeroObject}, \mathrm{ZeroObject} )$
#! @Arguments C
DeclareAttribute( "ZeroObjectFunctorial",
                  IsCapCategory );

#! @Description
#! The argument is a category $C$ and a zero object $\mathrm{ZeroObject}(C)$ twice (for compatibility with other functorials).
#! The output is the unique morphism $zero_object1 \rightarrow zero_object2$.
#! @Returns a morphism in $\mathrm{Hom}(zero_object1, zero_object2)$
#! @Arguments C, zero_object1, zero_object2
DeclareOperation( "ZeroObjectFunctorialWithGivenZeroObjects",
                  [ IsCapCategoryObject, IsCapCategoryObject ] );

#! @Chapter Universal Objects

####################################
##
#! @Section Terminal Object
##
####################################

#! A terminal object consists of two parts:
#! * an object $T$,
#! * a function $u$ mapping each object $A$ to a morphism $u( A ): A \rightarrow T$.
#! The pair $( T, u )$ is called a <Emph>terminal object</Emph> if the morphisms $u( A )$ are uniquely determined up to
#! congruence of morphisms.
#! We denote the object $T$ of such a pair by $\mathrm{TerminalObject}$.
#! We say that the morphism $u( A )$ is induced by the
#! <Emph>universal property of the terminal object</Emph>.
#! $\\ $
#! $\mathrm{TerminalObject}$ is a functorial operation. This just means:
#! There exists a unique morphism $T \rightarrow T$.

## Main Operations and Attributes

#! @Description
#! The argument is a category $C$.
#! The output is a terminal object $T$ of $C$.
#! @Returns an object
#! @Arguments C
DeclareAttribute( "TerminalObject",
                  IsCapCategory );

#! @Description
#! This is a convenience method.
#! The argument is a cell $c$.
#! The output is a terminal object $T$ of the
#! category $C$ for which $c \in C$.
#! @Returns an object
#! @Arguments c
DeclareAttribute( "TerminalObject",
                  IsCapCategoryCell );


#! @Description
#! The argument is an object $A$.
#! The output is the universal morphism $u(A): A \rightarrow \mathrm{TerminalObject}$.
#! @Returns a morphism in $\mathrm{Hom}( A, \mathrm{TerminalObject} )$
#! @Arguments A
DeclareAttribute( "UniversalMorphismIntoTerminalObject",
                  IsCapCategoryObject );

#! @Description
#! The argument are an object $A$,
#! and an object $T = \mathrm{TerminalObject}$.
#! The output is the universal morphism $u(A): A \rightarrow T$.
#! @Returns a morphism in $\mathrm{Hom}( A, T )$
#! @Arguments A, T
DeclareOperation( "UniversalMorphismIntoTerminalObjectWithGivenTerminalObject",
                  [ IsCapCategoryObject, IsCapCategoryObject ] );

#! @Description
#! The argument is a category $C$.
#! The output is the unique morphism $\mathrm{TerminalObject} \rightarrow \mathrm{TerminalObject}$.
#! @Returns a morphism in $\mathrm{Hom}(\mathrm{TerminalObject}, \mathrm{TerminalObject} )$
#! @Arguments C
DeclareAttribute( "TerminalObjectFunctorial",
                  IsCapCategory );

#! @Description
#! The argument is a category $C$ and a terminal object $\mathrm{TerminalObject}(C)$ twice (for compatibility with other functorials).
#! The output is the unique morphism $terminal_object1 \rightarrow terminal_object2$.
#! @Returns a morphism in $\mathrm{Hom}(terminal_object1, terminal_object2)$
#! @Arguments C, terminal_object1, terminal_object2
DeclareOperation( "TerminalObjectFunctorialWithGivenTerminalObjects",
                  [ IsCapCategoryObject, IsCapCategoryObject ] );

#! @Chapter Universal Objects

####################################
##
#! @Section Initial Object
##
####################################

#! An initial object consists of two parts:
#! * an object $I$,
#! * a function $u$ mapping each object $A$ to a morphism $u( A ): I \rightarrow A$.
#! The pair $(I,u)$ is called a <Emph>initial object</Emph> if the morphisms $u(A)$ are uniquely determined up to
#! congruence of morphisms.
#! We denote the object $I$ of such a triple by $\mathrm{InitialObject}$.
#! We say that the morphism $u( A )$ is induced by the
#! <Emph>universal property of the initial object</Emph>.
#! $\\ $
#! $\mathrm{InitialObject}$ is a functorial operation. This just means:
#! There exists a unique morphisms $I \rightarrow I$.

## Main Operations and Attributes


#! @Description
#! The argument is a category $C$.
#! The output is an initial object $I$ of $C$.
#! @Returns an object
#! @Arguments C
DeclareAttribute( "InitialObject",
                  IsCapCategory );

#! @Description
#! This is a convenience method.
#! The argument is a cell $c$.
#! The output is an initial object $I$ of the category $C$
#! for which $c \in C$.
#! @Returns an object
#! @Arguments c
DeclareAttribute( "InitialObject",
                  IsCapCategoryCell );


#! @Description
#! The argument is an object $A$.
#! The output is the universal morphism $u(A): \mathrm{InitialObject} \rightarrow A$.
#! @Returns a morphism in $\mathrm{Hom}(\mathrm{InitialObject}, A)$.
#! @Arguments A
DeclareAttribute( "UniversalMorphismFromInitialObject",
                  IsCapCategoryObject );

#! @Description
#! The arguments are an object $A$,
#! and an object $I = \mathrm{InitialObject}$.
#! The output is the universal morphism $u(A): \mathrm{InitialObject} \rightarrow A$.
#! @Returns a morphism in $\mathrm{Hom}(I, A)$.
#! @Arguments A, I
DeclareOperation( "UniversalMorphismFromInitialObjectWithGivenInitialObject",
                  [ IsCapCategoryObject, IsCapCategoryObject ] );

#! @Description
#! The argument is a category $C$.
#! The output is the unique morphism $\mathrm{InitialObject} \rightarrow \mathrm{InitialObject}$.
#! @Returns a morphism in $\mathrm{Hom}( \mathrm{InitialObject}, \mathrm{InitialObject} )$
#! @Arguments C
DeclareAttribute( "InitialObjectFunctorial",
                  IsCapCategory );

#! @Description
#! The argument is a category $C$ and an initial object $\mathrm{InitialObject}(C)$ twice (for compatibility with other functorials).
#! The output is the unique morphism $initial_object1 \rightarrow initial_object2$.
#! @Returns a morphism in $\mathrm{Hom}(initial_object1, initial_object2)$
#! @Arguments C, initial_object1, initial_object2
DeclareOperation( "InitialObjectFunctorialWithGivenInitialObjects",
                  [ IsCapCategoryObject, IsCapCategoryObject ] );

#! @Chapter Universal Objects

####################################
##
#! @Section Direct Sum
##
####################################

#! For an integer $n \geq 1$ and a given list $D = (S_1, \dots, S_n)$ in an Ab-category, a direct sum consists of five parts:
#! * an object $S$,
#! * a list of morphisms $\pi = (\pi_i: S \rightarrow S_i)_{i = 1 \dots n}$,
#! * a list of morphisms $\iota = (\iota_i: S_i \rightarrow S)_{i = 1 \dots n}$,
#! * a dependent function $u_{\mathrm{in}}$ mapping every list $\tau = ( \tau_i: T \rightarrow S_i )_{i = 1 \dots n}$
#!  to a morphism $u_{\mathrm{in}}(\tau): T \rightarrow S$ such that
#!  $\pi_i \circ u_{\mathrm{in}}(\tau) \sim_{T,S_i} \tau_i$ for all $i = 1, \dots, n$.
#! * a dependent function $u_{\mathrm{out}}$ mapping every list $\tau = ( \tau_i: S_i \rightarrow T )_{i = 1 \dots n}$
#!  to a morphism $u_{\mathrm{out}}(\tau): S \rightarrow T$ such that
#!   $u_{\mathrm{out}}(\tau) \circ \iota_i \sim_{S_i, T} \tau_i$ for all $i = 1, \dots, n$,
#! such that
#! * $\sum_{i=1}^{n} \iota_i \circ \pi_i \sim_{S,S} \mathrm{id}_S$,
#! * $\pi_j \circ \iota_i \sim_{S_i, S_j} \delta_{i,j}$,
#! where $\delta_{i,j} \in \mathrm{Hom}( S_i, S_j )$ is the identity if $i=j$, and $0$ otherwise.
#! The $5$-tuple $(S, \pi, \iota, u_{\mathrm{in}}, u_{\mathrm{out}})$ is called a <Emph>direct sum</Emph> of $D$.
#! We denote the object $S$ of such a $5$-tuple by $\bigoplus_{i=1}^n S_i$.
#! We say that the morphisms $u_{\mathrm{in}}(\tau), u_{\mathrm{out}}(\tau)$ are induced by the
#! <Emph>universal property of the direct sum</Emph>.
#! $\\ $
#! $\mathrm{DirectSum}$ is a functorial operation. This means:
#! For $(\mu_i: S_i \rightarrow S'_i)_{i=1\dots n}$,
#! we obtain a morphism $\bigoplus_{i=1}^n S_i \rightarrow \bigoplus_{i=1}^n S_i'$.

#! @BeginLatexOnly
#! \begin{center}
#! \begin{tikzpicture}
#! \def\w{2}
#! \def\a{20}
#! \node (S) at (0,0) {$S$};
#! \node (S1) at (-\w,0) {$S_1$};
#! \node (S2) at (\w,0) {$S_2$};
#! \node (T) at (0,\w) {$T$};
#! \draw[-latex] (S) to [out = 180-\a, in = \a] node[pos=0.45, above] {$\pi_1$} (S1);
#! \draw[-latex] (S) to [out = \a, in = 180-\a] node[pos=0.45, above] {$\pi_2$} (S2);
#! \draw[-latex] (S1) to [out = -\a, in = -180+\a] node[pos=0.45, below] {$\iota_1$} (S);
#! \draw[-latex] (S2) to [out = -180+\a, in = -\a] node[pos=0.45, below] {$\iota_2$} (S);
#! \draw[-latex] (T) to [out = -180, in = 90] node[pos=0.45, above left] {$\tau_1$} (S1);
#! \draw[-latex] (T) to [out = 0, in = 90] node[pos=0.45, above right] {$\tau_2$} (S2);
#! \draw[dashed, -latex] (T) to node[pos=0.45, left] {$\exists u_{in} ( \tau )$} (S);
#! \end{tikzpicture}
#! \end{center}
#! @EndLatexOnly

#! @BeginLatexOnly
#! \begin{center}
#! \begin{tikzpicture}
#! \def\w{2}
#! \def\a{20}
#! \node (S) at (0,0) {$S$};
#! \node (S1) at (-\w,0) {$S_1$};
#! \node (S2) at (\w,0) {$S_2$};
#! \node (T) at (0,\w) {$T$};
#! \draw[-latex] (S) to [out = 180-\a, in = \a] node[pos=0.45, above] {$\pi_1$} (S1);
#! \draw[-latex] (S) to [out = \a, in = 180-\a] node[pos=0.45, above] {$\pi_2$} (S2);
#! \draw[-latex] (S1) to [out = -\a, in = -180+\a] node[pos=0.45, below] {$\iota_1$} (S);
#! \draw[-latex] (S2) to [out = -180+\a, in = -\a] node[pos=0.45, below] {$\iota_2$} (S);
#! \draw[-latex] (S1) to [out = 90, in = -180] node[pos=0.45, above left] {$\tau_1$} (T);
#! \draw[-latex] (S2) to [out = 90, in = 0] node[pos=0.45, above right] {$\tau_2$} (T);
#! \draw[dashed, -latex] (S) to node[pos=0.45, left] {$\exists u_{out} ( \tau )$} (T);
#! \end{tikzpicture}
#! \end{center}
#! @EndLatexOnly



## Main Operations and Attributes

#! @Description
#! This is a convenience method.
#! There are two different ways to use this method:
#! * The argument is a list of objects $D = (S_1, \dots, S_n)$.
#! * The arguments are objects $S_1, \dots, S_n$.
#! The output is the direct sum $\bigoplus_{i=1}^n S_i$.
#! @Returns an object
# DeclareGlobalFunction( "DirectSum" ); # already defined by GAP

#! @Description
#! The argument is a list of objects $D = (S_1, \dots, S_n)$.
#! The output is the direct sum $\bigoplus_{i=1}^n S_i$.
#! @Returns an object
#! @Arguments D
DeclareOperation( "DirectSumOp",
                           [ IsList ] );

# for compatibility with GAP's DirectSum function
DeclareOperation( "DirectSumOp",
                  [ IsList, IsCapCategoryObject ] );
DeclareOperation( "DirectSumOp",
                  [ IsList, IsCapCategory ] );

#! @Description
#! The arguments are a list of objects $D = (S_1, \dots, S_n)$
#! and an integer $k$.
#! The output is the $k$-th projection
#! $\pi_k: \bigoplus_{i=1}^n S_i \rightarrow S_k$.
#! @Returns a morphism in $\mathrm{Hom}( \bigoplus_{i=1}^n S_i, S_k )$
#! @Arguments D,k
DeclareOperation( "ProjectionInFactorOfDirectSum",
                  [ IsList, IsInt ] );

#! @Description
#! The arguments are a list of objects $D = (S_1, \dots, S_n)$,
#! an integer $k$,
#! and an object $S = \bigoplus_{i=1}^n S_i$.
#! The output is the $k$-th projection
#! $\pi_k: S \rightarrow S_k$.
#! @Returns a morphism in $\mathrm{Hom}( S, S_k )$
#! @Arguments D,k,S
DeclareOperation( "ProjectionInFactorOfDirectSumWithGivenDirectSum",
                  [ IsList, IsInt, IsCapCategoryObject ] );

#! @Description
#! The arguments are a list of objects $D = (S_1, \dots, S_n)$
#! and an integer $k$.
#! The output  is the $k$-th injection
#! $\iota_k: S_k \rightarrow \bigoplus_{i=1}^n S_i$.
#! @Returns a morphism in $\mathrm{Hom}( S_k, \bigoplus_{i=1}^n S_i )$
#! @Arguments D,k
DeclareOperation( "InjectionOfCofactorOfDirectSum",
                  [ IsList, IsInt ] );

#! @Description
#! The arguments are a list of objects $D = (S_1, \dots, S_n)$,
#! an integer $k$,
#! and an object $S = \bigoplus_{i=1}^n S_i$.
#! The output  is the $k$-th injection
#! $\iota_k: S_k \rightarrow S$.
#! @Returns a morphism in $\mathrm{Hom}( S_k, S )$
#! @Arguments D,k,S
DeclareOperation( "InjectionOfCofactorOfDirectSumWithGivenDirectSum",
                  [ IsList, IsInt, IsCapCategoryObject ] );

#! @Description
#! The arguments are a list of objects $D = (S_1, \dots, S_n)$, a test object $T$,
#! and a list of morphisms $\tau = ( \tau_i: T \rightarrow S_i )_{i = 1 \dots n}$.
#! For convenience, the diagram <A>D</A> and/or the test object <A>T</A> can be omitted
#! and are automatically derived from <A>tau</A> in that case.
#! The output is the morphism
#! $u_{\mathrm{in}}(\tau): T \rightarrow \bigoplus_{i=1}^n S_i$
#! given by the universal property of the direct sum.
#! @Returns a morphism in $\mathrm{Hom}(T, \bigoplus_{i=1}^n S_i)$
#! @Arguments D, T, tau
DeclareOperation( "UniversalMorphismIntoDirectSum",
                  [ IsList, IsCapCategoryObject, IsList ] );

DeclareOperation( "UniversalMorphismIntoDirectSum",
                  [ IsList ] );

#! @Description
#! The arguments are a list of objects $D = (S_1, \dots, S_n)$, a test object $T$,
#! a list of morphisms $\tau = ( \tau_i: T \rightarrow S_i )_{i = 1 \dots n}$,
#! and an object $S = \bigoplus_{i=1}^n S_i$.
#! For convenience, the test object <A>T</A> can be omitted and is automatically derived from <A>tau</A> in that case.
#! The output is the morphism
#! $u_{\mathrm{in}}(\tau): T \rightarrow S$
#! given by the universal property of the direct sum.
#! @Returns a morphism in $\mathrm{Hom}(T, S)$
#! @Arguments D, T, tau, S
DeclareOperation( "UniversalMorphismIntoDirectSumWithGivenDirectSum",
                  [ IsList, IsCapCategoryObject, IsList, IsCapCategoryObject ] );

#! @Description
#! The arguments are a list of objects $D = (S_1, \dots, S_n)$, a test object $T$,
#! and a list of morphisms $\tau = ( \tau_i: S_i \rightarrow T )_{i = 1 \dots n}$.
#! For convenience, the diagram <A>D</A> and/or the test object <A>T</A> can be omitted
#! and are automatically derived from <A>tau</A> in that case.
#! The output is the morphism
#! $u_{\mathrm{out}}(\tau): \bigoplus_{i=1}^n S_i \rightarrow T$
#! given by the universal property of the direct sum.
#! @Returns a morphism in $\mathrm{Hom}(\bigoplus_{i=1}^n S_i, T)$
#! @Arguments D, T, tau
DeclareOperation( "UniversalMorphismFromDirectSum",
                  [ IsList, IsCapCategoryObject, IsList ] );

DeclareOperation( "UniversalMorphismFromDirectSum",
                  [ IsList ] );

#! @Description
#! The arguments are a list of objects $D = (S_1, \dots, S_n)$, a test object $T$,
#! a list of morphisms $\tau = ( \tau_i: S_i \rightarrow T )_{i = 1 \dots n}$,
#! and an object $S = \bigoplus_{i=1}^n S_i$.
#! For convenience, the test object <A>T</A> can be omitted and is automatically derived from <A>tau</A> in that case.
#! The output is the morphism
#! $u_{\mathrm{out}}(\tau): S \rightarrow T$
#! given by the universal property of the direct sum.
#! @Returns a morphism in $\mathrm{Hom}(S, T)$
#! @Arguments D, T, tau, S
DeclareOperation( "UniversalMorphismFromDirectSumWithGivenDirectSum",
                  [ IsList, IsCapCategoryObject, IsList, IsCapCategoryObject ] );

#! @Description
#! The argument is a list of objects $D = (S_1, \dots, S_n)$.
#! The output is the canonical isomorphism
#! $\bigoplus_{i=1}^n S_i \rightarrow \prod_{i=1}^{n}S_i$.
#! @Returns a morphism in $\mathrm{Hom}( \bigoplus_{i=1}^n S_i, \prod_{i=1}^{n}S_i )$
#! @Arguments D
DeclareOperation( "IsomorphismFromDirectSumToDirectProduct",
                  [ IsList ] );

#! @Description
#! The argument is a list of objects $D = (S_1, \dots, S_n)$.
#! The output is the canonical isomorphism
#! $\prod_{i=1}^{n}S_i \rightarrow \bigoplus_{i=1}^n S_i$.
#! @Returns a morphism in $\mathrm{Hom}( \prod_{i=1}^{n}S_i, \bigoplus_{i=1}^n S_i )$
#! @Arguments D
DeclareOperation( "IsomorphismFromDirectProductToDirectSum",
                  [ IsList ] );

#! @Description
#! The argument is a list of objects $D = (S_1, \dots, S_n)$.
#! The output is the canonical isomorphism
#! $\bigoplus_{i=1}^n S_i \rightarrow \bigsqcup_{i=1}^{n}S_i$.
#! @Returns a morphism in $\mathrm{Hom}( \bigoplus_{i=1}^n S_i, \bigsqcup_{i=1}^{n}S_i )$
#! @Arguments D
DeclareOperation( "IsomorphismFromDirectSumToCoproduct",
                  [ IsList ] );

#! @Description
#! The argument is a list of objects $D = (S_1, \dots, S_n)$.
#! The output is the canonical isomorphism
#! $\bigsqcup_{i=1}^{n}S_i \rightarrow \bigoplus_{i=1}^n S_i$.
#! @Returns a morphism in $\mathrm{Hom}( \bigsqcup_{i=1}^{n}S_i, \bigoplus_{i=1}^n S_i )$
#! @Arguments D
DeclareOperation( "IsomorphismFromCoproductToDirectSum",
                  [ IsList ] );

#! @Description
#! The arguments are given as follows:
#! * <A>diagram_S</A> is a list of objects $(A_i)_{i = 1 \dots m}$,
#! * <A>diagram_T</A> is a list of objects $(B_j)_{j = 1 \dots n}$,
#! * <A>M</A> is a list of lists of morphisms $( ( \phi_{i,j}: A_i \rightarrow B_j )_{j = 1 \dots n} )_{i = 1 \dots m}$.
#! The output is the morphism
#! $\bigoplus_{i=1}^{m}A_i \rightarrow \bigoplus_{j=1}^n B_j$
#! defined by the matrix $M$.
#! @Returns a morphism in $\mathrm{Hom}(\bigoplus_{i=1}^{m}A_i, \bigoplus_{j=1}^n B_j)$
#! @Arguments diagram_S, M, diagram_T
DeclareOperation( "MorphismBetweenDirectSums",
                  [ IsList, IsList, IsList ] );

#! @Description
#! This is a convenience method.
#! The argument $M = ( ( \phi_{i,j}: A_i \rightarrow B_j )_{j = 1 \dots n} )_{i = 1 \dots m}$
#! is a (non-empty) list of (non-empty) lists of morphisms.
#! The output is the morphism
#! $\bigoplus_{i=1}^{m}A_i \rightarrow \bigoplus_{j=1}^n B_j$
#! defined by the matrix $M$.
#! @Returns a morphism in $\mathrm{Hom}(\bigoplus_{i=1}^{m}A_i, \bigoplus_{j=1}^n B_j)$
#! @Arguments M
DeclareOperation( "MorphismBetweenDirectSums",
                  [ IsList ] );

#! @Description
#! The arguments are given as follows:
#! * <A>diagram_S</A> is a list of objects $(A_i)_{i = 1 \dots m}$,
#! * <A>diagram_T</A> is a list of objects $(B_j)_{j = 1 \dots n}$,
#! * <A>S</A> is the direct sum $\bigoplus_{i=1}^{m}A_i$,
#! * <A>T</A> is the direct sum $\bigoplus_{j=1}^{n}B_j$,
#! * <A>M</A> is a list of lists of morphisms $( ( \phi_{i,j}: A_i \rightarrow B_j )_{j = 1 \dots n} )_{i = 1 \dots m}$.
#! The output is the morphism
#! $\bigoplus_{i=1}^{m}A_i \rightarrow \bigoplus_{j=1}^n B_j$
#! defined by the matrix $M$.
#! @Returns a morphism in $\mathrm{Hom}(\bigoplus_{i=1}^{m}A_i, \bigoplus_{j=1}^n B_j)$
#! @Arguments S, diagram_S, M, diagram_T, T
DeclareOperation( "MorphismBetweenDirectSumsWithGivenDirectSums",
                  [ IsCapCategoryObject, IsList, IsList, IsList, IsCapCategoryObject ] );

#! @Description
#! The arguments are a morphism $\alpha: A \rightarrow S$,
#! a list $D = (S_1, \dots, S_n)$ of objects with $S = \bigoplus_{j=1}^n S_j$,
#! and an integer $k$.
#! The output is the component morphism
#! $A \rightarrow S_k$.
#! @Returns a morphism in $\mathrm{Hom}(A, S_k)$
#! @Arguments alpha, D, k
DeclareOperation( "ComponentOfMorphismIntoDirectSum",
                  [ IsCapCategoryMorphism, IsList, IsInt ] );

#! @Description
#! The arguments are a morphism $\alpha: S \rightarrow A$,
#! a list $D = (S_1, \dots, S_n)$ of objects with $S = \bigoplus_{j=1}^n S_j$,
#! and an integer $k$.
#! The output is the component morphism
#! $S_k \rightarrow A$.
#! @Returns a morphism in $\mathrm{Hom}(S_k, A)$
#! @Arguments alpha, D, k
DeclareOperation( "ComponentOfMorphismFromDirectSum",
                  [ IsCapCategoryMorphism, IsList, IsInt ] );

#! @Description
#! The arguments are
#! a list of objects $(S_i)_{i = 1 \dots n}$,
#! a list of morphisms $L = ( \mu_1: S_1 \rightarrow S_1', \dots, \mu_n: S_n \rightarrow S_n' )$,
#! and a list of objects $(S_i')_{i = 1 \dots n}$.
#! For convenience, <A>source_diagram</A> and <A>range_diagram</A> can be omitted
#! and are automatically derived from <A>L</A> in that case.
#! The output is a morphism
#! $\bigoplus_{i=1}^n S_i \rightarrow \bigoplus_{i=1}^n S_i'$
#! given by the functoriality of the direct sum.
#! @Returns a morphism in $\mathrm{Hom}( \bigoplus_{i=1}^n S_i, \bigoplus_{i=1}^n S_i' )$
#! @Arguments source_diagram, L, range_diagram
DeclareOperation( "DirectSumFunctorial",
                  [ IsList, IsList, IsList ] );

#! @Description
#! The arguments are an object $d_1 = \bigoplus_{i=1}^n S_i$,
#! a list of objects $(S_i)_{i = 1 \dots n}$,
#! a list of morphisms $L = ( \mu_1: S_1 \rightarrow S_1', \dots, \mu_n: S_n \rightarrow S_n' )$,
#! a list of objects $(S_i')_{i = 1 \dots n}$,
#! and an object $d_2 = \bigoplus_{i=1}^n S_i'$.
#! For convenience, <A>source_diagram</A> and <A>range_diagram</A> can be omitted
#! and are automatically derived from <A>L</A> in that case.
#! The output is a morphism
#! $d_1 \rightarrow d_2$
#! given by the functoriality of the direct sum.
#! @Returns a morphism in $\mathrm{Hom}( d_1, d_2 )$
#! @Arguments d_1, source_diagram, L, range_diagram, d_2
DeclareOperation( "DirectSumFunctorialWithGivenDirectSums",
                  [ IsCapCategoryObject, IsList, IsList, IsList, IsCapCategoryObject ] );

#! @Chapter Universal Objects

####################################
##
#! @Section Coproduct
##
####################################

#! For an integer $n \geq 1$ and a given list of objects $D = ( I_1, \dots, I_n )$, a coproduct of $D$ consists of three parts:
#! * an object $I$,
#! * a list of morphisms $\iota = ( \iota_i: I_i \rightarrow I )_{i = 1 \dots n}$
#! * a dependent function $u$ mapping each list of morphisms $\tau = ( \tau_i: I_i \rightarrow T )$
#!  to a morphism $u( \tau ): I \rightarrow T$ such that $u( \tau ) \circ \iota_i \sim_{I_i, T} \tau_i$ for all $i = 1, \dots, n$.
#! The triple $( I, \iota, u )$ is called a <Emph>coproduct</Emph> of $D$ if the morphisms $u( \tau )$ are uniquely determined up to
#! congruence of morphisms.
#! We denote the object $I$ of such a triple by $\bigsqcup_{i=1}^n I_i$.
#! We say that the morphism $u( \tau )$ is induced by the
#! <Emph>universal property of the coproduct</Emph>.
#! $\\ $
#! $\mathrm{Coproduct}$ is a functorial operation. This means:
#! For $(\mu_i: I_i \rightarrow I'_i)_{i=1\dots n}$,
#! we obtain a morphism $\bigsqcup_{i=1}^n I_i \rightarrow \bigsqcup_{i=1}^n I_i'$.

#! @BeginLatexOnly
#! \begin{center}
#! \begin{tikzpicture}
#! \def\w{2}
#! \node (I) at (0,0) {$I$};
#! \node (I1) at (-\w,0) {$I_1$};
#! \node (I2) at (\w,0) {$I_2$};
#! \node (T) at (0,\w) {$T$};
#! \draw[-latex] (S1) to node[pos=0.45, below] {$\iota_1$} (S);
#! \draw[-latex] (S2) to node[pos=0.45, below] {$\iota_2$} (S);
#! \draw[-latex] (S1) to [out = 90, in = -180] node[pos=0.45, above left] {$\tau_1$} (T);
#! \draw[-latex] (S2) to [out = 90, in = 0] node[pos=0.45, above right] {$\tau_2$} (T);
#! \draw[dashed, -latex] (S) to node[pos=0.45, left] {$\exists ! u ( \tau )$} (T);
#! \end{tikzpicture}
#! \end{center}
#! @EndLatexOnly


## Main Operations and Attributes

#! @Description
#! The argument is a list of objects $D = ( I_1, \dots, I_n )$.
#! The output is the coproduct $\bigsqcup_{i=1}^n I_i$.
#! @Returns an object
#! @Arguments D
DeclareOperation( "Coproduct",
                  [ IsList ] );

#! @Description
#! This is a convenience method.
#! The arguments are two objects $I_1, I_2$.
#! The output is the coproduct $I_1 \bigsqcup I_2$.
#! @Returns an object
#! @Arguments I1, I2
DeclareOperation( "Coproduct",
                  [ IsCapCategoryObject, IsCapCategoryObject ] );

#! @Description
#! This is a convenience method.
#! The arguments are three objects $I_1, I_2, I_3$.
#! The output is the coproduct $I_1 \bigsqcup I_2 \bigsqcup I_3$.
#! @Returns an object
#! @Arguments I1, I2
DeclareOperation( "Coproduct",
                  [ IsCapCategoryObject, IsCapCategoryObject, IsCapCategoryObject ] );


#! @Description
#! The arguments are a list of objects $D = ( I_1, \dots, I_n )$
#! and an integer $k$.
#! The output is the $k$-th injection
#! $\iota_k: I_k \rightarrow \bigsqcup_{i=1}^n I_i$.
#! @Returns a morphism in $\mathrm{Hom}(I_k, \bigsqcup_{i=1}^n I_i)$
#! @Arguments D,k
DeclareOperation( "InjectionOfCofactorOfCoproduct",
                  [ IsList, IsInt ] );

#! @Description
#! The arguments are a list of objects $D = ( I_1, \dots, I_n )$,
#! an integer $k$,
#! and an object $I = \bigsqcup_{i=1}^n I_i$.
#! The output is the $k$-th injection
#! $\iota_k: I_k \rightarrow I$.
#! @Returns a morphism in $\mathrm{Hom}(I_k, I)$
#! @Arguments D,k,I
DeclareOperation( "InjectionOfCofactorOfCoproductWithGivenCoproduct",
                  [ IsList, IsInt, IsCapCategoryObject ] );

#! @Description
#! The arguments are a list of objects $D = ( I_1, \dots, I_n )$, a test object $T$,
#! and a list of morphisms $\tau = ( \tau_i: I_i \rightarrow T )$.
#! For convenience, the diagram <A>D</A> and/or the test object <A>T</A> can be omitted
#! and are automatically derived from <A>tau</A> in that case.
#! The output is the morphism
#! $u( \tau ): \bigsqcup_{i=1}^n I_i \rightarrow T$
#! given by the universal property of the coproduct.
#! @Returns a morphism in $\mathrm{Hom}(\bigsqcup_{i=1}^n I_i, T)$
#! @Arguments D, T, tau
DeclareOperation( "UniversalMorphismFromCoproduct",
                  [ IsList, IsCapCategoryObject, IsList ] );

DeclareOperation( "UniversalMorphismFromCoproduct",
                  [ IsList ] );

#! @Description
#! The arguments are a list of objects $D = ( I_1, \dots, I_n )$, a test object $T$,
#! a list of morphisms $\tau = ( \tau_i: I_i \rightarrow T )$,
#! and an object $I = \bigsqcup_{i=1}^n I_i$.
#! For convenience, the test object <A>T</A> can be omitted and is automatically derived from <A>tau</A> in that case.
#! The output is the morphism
#! $u( \tau ): I \rightarrow T$
#! given by the universal property of the coproduct.
#! @Returns a morphism in $\mathrm{Hom}(I, T)$
#! @Arguments D, T, tau, I
DeclareOperation( "UniversalMorphismFromCoproductWithGivenCoproduct",
                  [ IsList, IsCapCategoryObject, IsList, IsCapCategoryObject ] );

#! @Description
#! The arguments are
#! a list of objects $(I_i)_{i = 1 \dots n}$,
#! a list $L = ( \mu_1: I_1 \rightarrow I_1', \dots, \mu_n: I_n \rightarrow I_n' )$,
#! and a list of objects $(I_i')_{i = 1 \dots n}$.
#! For convenience, <A>source_diagram</A> and <A>range_diagram</A> can be omitted
#! and are automatically derived from <A>L</A> in that case.
#! The output is a morphism
#! $\bigsqcup_{i=1}^n I_i \rightarrow \bigsqcup_{i=1}^n I_i'$
#! given by the functoriality of the coproduct.
#! @Returns a morphism in $\mathrm{Hom}(\bigsqcup_{i=1}^n I_i, \bigsqcup_{i=1}^n I_i')$
#! @Arguments source_diagram, L, range_diagram
DeclareOperation( "CoproductFunctorial",
                  [ IsList, IsList, IsList ] );

#! @Description
#! The arguments are an object $s = \bigsqcup_{i=1}^n I_i$, 
#! a list of objects $(I_i)_{i = 1 \dots n}$,
#! a list $L = ( \mu_1: I_1 \rightarrow I_1', \dots, \mu_n: I_n \rightarrow I_n' )$,
#! a list of objects $(I_i')_{i = 1 \dots n}$,
#! and an object $r = \bigsqcup_{i=1}^n I_i'$.
#! For convenience, <A>source_diagram</A> and <A>range_diagram</A> can be omitted
#! and are automatically derived from <A>L</A> in that case.
#! The output is a morphism
#! $\bigsqcup_{i=1}^n I_i \rightarrow \bigsqcup_{i=1}^n I_i'$
#! given by the functoriality of the coproduct.
#! @Returns a morphism in $\mathrm{Hom}(s, r)$
#! @Arguments s, source_diagram, L, range_diagram, r
DeclareOperation( "CoproductFunctorialWithGivenCoproducts",
                  [ IsCapCategoryObject, IsList, IsList, IsList, IsCapCategoryObject ] );

#! @Description
#! The arguments are a morphism $\alpha: I \rightarrow A$,
#! a list $D = (I_1, \dots, I_n)$ of objects with $I = \bigsqcup_{j=1}^n I_j$,
#! and an integer $k$.
#! The output is the component morphism
#! $I_k \rightarrow A$.
#! @Returns a morphism in $\mathrm{Hom}(I_k, A)$
#! @Arguments alpha, D, k
DeclareOperation( "ComponentOfMorphismFromCoproduct",
                  [ IsCapCategoryMorphism, IsList, IsInt ] );

#! @Chapter Universal Objects

####################################
##
#! @Section Direct Product
##
####################################

#! For an integer $n \geq 1$ and a given list of objects $D = ( P_1, \dots, P_n )$, a direct product of $D$ consists of three parts:
#! * an object $P$,
#! * a list of morphisms $\pi = ( \pi_i: P \rightarrow P_i )_{i = 1 \dots n}$ 
#! * a dependent function $u$ mapping each list of morphisms $\tau = ( \tau_i: T \rightarrow P_i )_{i = 1, \dots, n}$ 
#!  to a morphism $u(\tau): T \rightarrow P$ such that $\pi_i \circ u( \tau ) \sim_{T,P_i} \tau_i$ for all $i = 1, \dots, n$.
#! The triple $( P, \pi, u )$ is called a <Emph>direct product</Emph> of $D$ if the morphisms $u( \tau )$ are uniquely determined up to
#! congruence of morphisms.
#! We denote the object $P$ of such a triple by $\prod_{i=1}^n P_i$.
#! We say that the morphism $u( \tau )$ is induced by the
#! <Emph>universal property of the direct product</Emph>.
#! $\\ $
#! $\mathrm{DirectProduct}$ is a functorial operation. This means:
#! For $(\mu_i: P_i \rightarrow P'_i)_{i=1\dots n}$,
#! we obtain a morphism $\prod_{i=1}^n P_i \rightarrow \prod_{i=1}^n P_i'$.

#! @BeginLatexOnly
#! \begin{center}
#! \begin{tikzpicture}
#! \def\w{2}
#! \node (P) at (0,0) {$P$};
#! \node (P1) at (-\w,0) {$P_1$};
#! \node (P2) at (\w,0) {$P_2$};
#! \node (T) at (0,\w) {$T$};
#! \draw[-latex] (P) to node[pos=0.45, above] {$\pi_1$} (P1);
#! \draw[-latex] (P) to node[pos=0.45, above] {$\pi_2$} (P2);
#! \draw[-latex] (T) to [out = -180, in = 90] node[pos=0.45, above left] {$\tau_1$} (P1);
#! \draw[-latex] (T) to [out = 0, in = 90] node[pos=0.45, above right] {$\tau_2$} (P2);
#! \draw[dashed, -latex] (T) to node[pos=0.45, left] {$\exists ! u ( \tau )$} (P);
#! \end{tikzpicture}
#! \end{center}
#! @EndLatexOnly


## Main Operations and Attributes

#! @Description
#! This is a convenience method.
#! There are two different ways to use this method:
#! * The argument is a list of objects $D = ( P_1, \dots, P_n )$.
#! * The arguments are objects $P_1, \dots, P_n$.
#! The output is the direct product $\prod_{i=1}^n P_i$.
#! @Returns an object
# DeclareGlobalFunction( "DirectProduct" ); # already defined by GAP

#! @Description
#! The argument is a list of objects $D = ( P_1, \dots, P_n )$.
#! The output is the direct product $\prod_{i=1}^n P_i$.
#! @Returns an object
#! @Arguments D
DeclareOperation( "DirectProductOp",
                           [ IsList ] );

# for compatibility with GAP's DirectProduct function
DeclareOperation( "DirectProductOp",
                  [ IsList, IsCapCategoryObject ] );
DeclareOperation( "DirectProductOp",
                  [ IsList, IsCapCategory ] );

#! @Description
#! The arguments are a list of objects $D = ( P_1, \dots, P_n )$
#! and an integer $k$.
#! The output is the $k$-th projection
#! $\pi_k: \prod_{i=1}^n P_i \rightarrow P_k$.
#! @Returns a morphism in $\mathrm{Hom}(\prod_{i=1}^n P_i, P_k)$
#! @Arguments D,k
DeclareOperation( "ProjectionInFactorOfDirectProduct",
                  [ IsList, IsInt ] );

#! @Description
#! The arguments are a list of objects $D = ( P_1, \dots, P_n )$,
#! an integer $k$,
#! and an object $P = \prod_{i=1}^n P_i$.
#! The output is the $k$-th projection
#! $\pi_k: P \rightarrow P_k$.
#! @Returns a morphism in $\mathrm{Hom}(P, P_k)$
#! @Arguments D,k,P
DeclareOperation( "ProjectionInFactorOfDirectProductWithGivenDirectProduct",
                  [ IsList, IsInt, IsCapCategoryObject ] );

#! @Description
#! The arguments are a list of objects $D = ( P_1, \dots, P_n )$, a test object $T$,
#! and a list of morphisms $\tau = ( \tau_i: T \rightarrow P_i )_{i = 1, \dots, n}$.
#! For convenience, the diagram <A>D</A> and/or the test object <A>T</A> can be omitted
#! and are automatically derived from <A>tau</A> in that case.
#! The output is the morphism
#! $u(\tau): T \rightarrow \prod_{i=1}^n P_i$
#! given by the universal property of the direct product.
#! @Returns a morphism in $\mathrm{Hom}(T, \prod_{i=1}^n P_i)$
#! @Arguments D, T, tau
DeclareOperation( "UniversalMorphismIntoDirectProduct",
                  [ IsList, IsCapCategoryObject, IsList ] );

DeclareOperation( "UniversalMorphismIntoDirectProduct",
                  [ IsList ] );

#! @Description
#! The arguments are a list of objects $D = ( P_1, \dots, P_n )$, a test object $T$,
#! a list of morphisms $\tau = ( \tau_i: T \rightarrow P_i )_{i = 1, \dots, n}$,
#! and an object $P = \prod_{i=1}^n P_i$.
#! For convenience, the test object <A>T</A> can be omitted and is automatically derived from <A>tau</A> in that case.
#! The output is the morphism
#! $u(\tau): T \rightarrow \prod_{i=1}^n P_i$
#! given by the universal property of the direct product.
#! @Returns a morphism in $\mathrm{Hom}(T, \prod_{i=1}^n P_i)$
#! @Arguments D, T, tau, P
DeclareOperation( "UniversalMorphismIntoDirectProductWithGivenDirectProduct",
                  [ IsList, IsCapCategoryObject, IsList, IsCapCategoryObject ] );

#! @Description
#! The arguments are
#! a list of objects $(P_i)_{i = 1 \dots n}$,
#! a list of morphisms $L = (\mu_i: P_i \rightarrow P'_i)_{i=1\dots n}$,
#! and a list of objects $(P_i')_{i = 1 \dots n}$.
#! For convenience, <A>source_diagram</A> and <A>range_diagram</A> can be omitted
#! and are automatically derived from <A>L</A> in that case.
#! The output is a morphism
#! $\prod_{i=1}^n P_i \rightarrow \prod_{i=1}^n P_i'$
#! given by the functoriality of the direct product.
#! @Returns a morphism in $\mathrm{Hom}( \prod_{i=1}^n P_i, \prod_{i=1}^n P_i' )$
#! @Arguments source_diagram, L, range_diagram
DeclareOperation( "DirectProductFunctorial",
                  [ IsList, IsList, IsList ] );

#! @Description
#! The arguments are an object $s = \prod_{i=1}^n P_i$,
#! a list of objects $(P_i)_{i = 1 \dots n}$,
#! a list of morphisms $L = (\mu_i: P_i \rightarrow P'_i)_{i=1\dots n}$,
#! a list of objects $(P_i')_{i = 1 \dots n}$,
#! and an object $r = \prod_{i=1}^n P_i'$.
#! For convenience, <A>source_diagram</A> and <A>range_diagram</A> can be omitted
#! and are automatically derived from <A>L</A> in that case.
#! The output is a morphism
#! $\prod_{i=1}^n P_i \rightarrow \prod_{i=1}^n P_i'$
#! given by the functoriality of the direct product.
#! @Returns a morphism in $\mathrm{Hom}( s, r )$
#! @Arguments s, source_diagram, L, range_diagram r
DeclareOperation( "DirectProductFunctorialWithGivenDirectProducts",
                  [ IsCapCategoryObject, IsList, IsList, IsList, IsCapCategoryObject ] );

#! @Description
#! The arguments are a morphism $\alpha: A \rightarrow P$,
#! a list $D = (P_1, \dots, P_n)$ of objects with $P = \prod_{j=1}^n P_j$,
#! and an integer $k$.
#! The output is the component morphism
#! $A \rightarrow P_k$.
#! @Returns a morphism in $\mathrm{Hom}(A, P_k)$
#! @Arguments alpha, D, k
DeclareOperation( "ComponentOfMorphismIntoDirectProduct",
                  [ IsCapCategoryMorphism, IsList, IsInt ] );

#! @Chapter Universal Objects

####################################
##
#! @Section Equalizer
##
####################################

#! For an integer $n \geq 1$ and a given list of morphisms $D = ( \beta_i: A \rightarrow B )_{i = 1 \dots n}$,
#! an equalizer of $D$ consists of three parts:
#! * an object $E$,
#! * a morphism $\iota: E \rightarrow A $ such that
#!  $\beta_i \circ \iota  \sim_{E, B} \beta_j \circ \iota$ for all pairs $i,j$.
#! * a dependent function $u$ mapping each morphism
#!  $\tau = ( \tau: T \rightarrow A )$ such that
#!  $\beta_i \circ \tau  \sim_{T, B} \beta_j \circ \tau$ for all pairs $i,j$
#!  to a morphism $u( \tau ): T \rightarrow E$ such that
#!  $\iota \circ u( \tau ) \sim_{T, A} \tau$.
#! The triple $( E, \iota, u )$ is called an <Emph>equalizer</Emph> of $D$ if the morphisms $u( \tau )$ are uniquely determined up to
#! congruence of morphisms.
#! We denote the object $E$ of such a triple by $\mathrm{Equalizer}(D)$.
#! We say that the morphism $u( \tau )$ is induced by the
#! <Emph>universal property of the equalizer</Emph>.
#! $\\ $
#! $\mathrm{Equalizer}$ is a functorial operation. This means:
#! For a second diagram $D' = (\beta_i': A' \rightarrow B')_{i = 1 \dots n}$ and a natural morphism
#! between equalizer diagrams (i.e., a collection of morphisms
#! $\mu: A \rightarrow A'$ and $\beta: B \rightarrow B'$
#! such that $\beta_i' \circ \mu \sim_{A,B'} \beta \circ \beta_i$ for $i = 1, \dots, n$)
#! we obtain a morphism $\mathrm{Equalizer}( D ) \rightarrow \mathrm{Equalizer}( D' )$.

#! @BeginLatexOnly
#! \begin{center}
#! \begin{tikzpicture}
#! \def\w{2}
#! \node (E) at (-\w,0) {$E$};
#! \node (T) at (-\w,\w) {$T$};
#! \node (A) at (0,0) {$A$};
#! \node (B) at (\w,0) {$B$};
#! \draw[-latex] (A) to [out = 20, in = 180-20] node[pos=0.45, above] {$\beta_1$} (B);
#! \draw[-latex] (A) to [out = -20, in = -180+20] node[pos=0.45, below] {$\beta_2$} (B);
#! \draw[-latex] (E) to node[pos=0.45, above] {$\iota$} (A);
#! \draw[-latex] (T) to node[pos=0.45, above right] {$\tau$} (A);
#! \draw[dashed, -latex] (T) to node[pos=0.45, left] {$\exists ! u( \tau )$} (E);
#! \draw[-latex, dotted] (T) to [out = 0, in = 90] node[pos=0.45, above right] {$\beta_2 \circ \tau \sim_{T,B} \beta_1 \circ \tau$} (B);
#! \draw[-latex, dotted] (E) to [out = -45, in = -135] node[pos=0.45, below] {$\beta_2 \circ \iota \sim_{E,B} \beta_1 \circ \iota$} (B);
#! \end{tikzpicture}
#! \end{center}
#! @EndLatexOnly


## Main Operations and Attributes

#! @Description
#! This is a convenience method.
#! There are three different ways to use this method:
#! * The arguments are an object $A$ and a list of morphisms $D = ( \beta_i: A \rightarrow B )_{i = 1 \dots n}$.
#! * The argument is a list of morphisms $D = ( \beta_i: A \rightarrow B )_{i = 1 \dots n}$.
#! * The arguments are morphisms $\beta_1: A \rightarrow B, \dots, \beta_n: A \rightarrow B$.
#! The output is the equalizer $\mathrm{Equalizer}(D)$.
#! @Returns an object
DeclareGlobalFunction( "Equalizer" );

#! @Description
#! The arguments are an object $A$ and list of morphisms $D = ( \beta_i: A \rightarrow B )_{i = 1 \dots n}$.
#! For convenience, the object $A$ can be omitted and is automatically derived from $D$ in that case.
#! The output is the equalizer $\mathrm{Equalizer}(D)$.
#! @Returns an object
#! @Arguments A, D
DeclareOperation( "EqualizerOp",
                  [ IsCapCategoryObject, IsList ] );

#! @Description
#! The arguments are an object $A$ and a list of morphisms $D = ( \beta_i: A \rightarrow B )_{i = 1 \dots n}$.
#! For convenience, the object $A$ can be omitted and is automatically derived from $D$ in that case.
#! The output is the equalizer embedding
#! $\iota: \mathrm{Equalizer}(D) \rightarrow A$.
#! @Returns a morphism in $\mathrm{Hom}( \mathrm{Equalizer}(D), A )$
#! @Arguments A, D
DeclareOperation( "EmbeddingOfEqualizer",
                  [ IsCapCategoryObject, IsList ] );

#! @Description
#! The arguments are an object $A$, a list of morphisms $D = ( \beta_i: A \rightarrow B )_{i = 1 \dots n}$,
#! and an object $E = \mathrm{Equalizer}(D)$.
#! For convenience, the object $A$ can be omitted and is automatically derived from $D$ in that case.
#! The output is the equalizer embedding
#! $\iota: E \rightarrow A$.
#! @Returns a morphism in $\mathrm{Hom}( E, A )$
#! @Arguments A, D, E
DeclareOperation( "EmbeddingOfEqualizerWithGivenEqualizer",
                  [ IsCapCategoryObject, IsList, IsCapCategoryObject ] );

#! @Description
#! The arguments are an object $A$ and a list of morphisms $D = ( \beta_i: A \rightarrow B )_{i = 1 \dots n}$.
#! For convenience, the object $A$ can be omitted and is automatically derived from $D$ in that case.
#! The output is the composition $\mu: \mathrm{Equalizer}(D) \rightarrow B$
#! of the embedding $\iota: \mathrm{Equalizer}(D) \rightarrow A$ and $\beta_1$.
#! @Returns a morphism in $\mathrm{Hom}( \mathrm{Equalizer}(D), B )$
#! @Arguments A, D
DeclareOperation( "MorphismFromEqualizerToSink",
                  [ IsCapCategoryObject, IsList ] );

#! @Description
#! The arguments are an object $A$, a list of morphisms $D = ( \beta_i: A \rightarrow B )_{i = 1 \dots n}$
#! and an object $E = \mathrm{Equalizer}(D)$.
#! For convenience, the object $A$ can be omitted and is automatically derived from $D$ in that case.
#! The output is the composition $\mu: E \rightarrow B$
#! of the embedding $\iota: E \rightarrow A$ and $\beta_1$.
#! @Returns a morphism in $\mathrm{Hom}( E, B )$
#! @Arguments A, D, E
DeclareOperation( "MorphismFromEqualizerToSinkWithGivenEqualizer",
                  [ IsCapCategoryObject, IsList, IsCapCategoryObject ] );

#! @Description
#! The arguments are an object $A$, a list of morphisms $D = ( \beta_i: A \rightarrow B )_{i = 1 \dots n}$, a test object $T$,
#! and a morphism $ \tau: T \rightarrow A $
#! such that $\beta_i \circ \tau  \sim_{T, B} \beta_j \circ \tau$ for all pairs $i,j$.
#! For convenience, the object $A$ can be omitted and is automatically derived from $D$ in that case.
#! For convenience, the test object <A>T</A> can be omitted and is automatically derived from <A>tau</A> in that case.
#! The output is the morphism
#! $u( \tau ): T \rightarrow \mathrm{Equalizer}(D)$
#! given by the universal property of the equalizer.
#! @Returns a morphism in $\mathrm{Hom}( T, \mathrm{Equalizer}(D) )$
#! @Arguments A, D, T, tau
DeclareOperation( "UniversalMorphismIntoEqualizer",
                  [ IsCapCategoryObject, IsList, IsCapCategoryObject, IsCapCategoryMorphism ] );

#! @Description
#! The arguments are an object $A$, a list of morphisms $D = ( \beta_i: A \rightarrow B )_{i = 1 \dots n}$, a test object $T$,
#! a morphism $\tau: T \rightarrow A )$
#! such that $\beta_i \circ \tau  \sim_{T, B} \beta_j \circ \tau$ for all pairs $i,j$,
#! and an object $E = \mathrm{Equalizer}(D)$.
#! For convenience, the object $A$ can be omitted and is automatically derived from $D$ in that case.
#! For convenience, the test object <A>T</A> can be omitted and is automatically derived from <A>tau</A> in that case.
#! The output is the morphism
#! $u( \tau ): T \rightarrow E$
#! given by the universal property of the equalizer.
#! @Returns a morphism in $\mathrm{Hom}( T, E )$
#! @Arguments A, D, T, tau, E
DeclareOperation( "UniversalMorphismIntoEqualizerWithGivenEqualizer",
                  [ IsCapCategoryObject, IsList, IsCapCategoryObject, IsCapCategoryMorphism, IsCapCategoryObject ] );

#! @Description
#! The arguments are a list of morphisms
#! $L_s = (\beta_i: A \rightarrow B)_{i = 1 \dots n}$,
#! a morphism
#! $\mu: A \rightarrow A'$,
#! and a list of morphisms
#! $L_r = (\beta_i': A' \rightarrow B')_{i = 1 \dots n}$
#! such that there exists a morphism $\beta: B \rightarrow B'$
#! such that $\beta_i' \circ \mu \sim_{A,B'} \beta \circ \beta_i$ for $i = 1, \dots, n$.
#! The output is the morphism
#! $\mathrm{Equalizer}( ( \beta_i )_{i=1 \dots n} ) \rightarrow \mathrm{Equalizer}( ( \beta_i' )_{i=1 \dots n} )$
#! given by the functorality of the equalizer.
#! @Returns a morphism in $\mathrm{Hom}(\mathrm{Equalizer}( ( \beta_i )_{i=1 \dots n} ), \mathrm{Equalizer}( ( \beta_i' )_{i=1 \dots n} ))$
#! @Arguments Ls, mu, Lr
DeclareOperation( "EqualizerFunctorial",
                  [ IsList, IsCapCategoryMorphism, IsList ] );

#! @Description
#! The arguments are an object $s = \mathrm{Equalizer}( ( \beta_i )_{i=1 \dots n} )$,
#! a list of morphisms
#! $L_s = (\beta_i: A \rightarrow B)_{i = 1 \dots n}$,
#! a morphism
#! $\mu: A \rightarrow A'$,
#! and a list of morphisms
#! $L_r = (\beta_i': A' \rightarrow B')_{i = 1 \dots n}$
#! such that there exists a morphism $\beta: B \rightarrow B'$
#! such that $\beta_i' \circ \mu \sim_{A,B'} \beta \circ \beta_i$ for $i = 1, \dots, n$,
#! and an object $r = \mathrm{Equalizer}( ( \beta_i' )_{i=1 \dots n} )$.
#! The output is the morphism
#! $s \rightarrow r$
#! given by the functorality of the equalizer.
#! @Returns a morphism in $\mathrm{Hom}(s, r)$
#! @Arguments s, Ls, mu, Lr, r
DeclareOperation( "EqualizerFunctorialWithGivenEqualizers",
                  [ IsCapCategoryObject, IsList, IsCapCategoryMorphism, IsList, IsCapCategoryObject ] );

#! @Description
#! The arguments are an object A and a list of morphisms $D = ( \beta_i: A \rightarrow B )_{i = 1 \dots n}$.
#! The output is a morphism
#! $A \rightarrow \prod_{i=1}^{n-1} B$
#! such that its kernel equalizes the $\beta_i$.
#! @Returns a morphism in $\mathrm{Hom}( A, \prod_{i=1}^{n-1} B )$
#! @Arguments A, D
DeclareOperation( "JointPairwiseDifferencesOfMorphismsIntoDirectProduct",
                  [ IsCapCategoryObject, IsList ] );

#! @Description
--> --------------------

--> maximum size reached

--> --------------------

[ Dauer der Verarbeitung: 0.17 Sekunden  (vorverarbeitet)  ]