### Navigation

- index
- modules |
- next |
- previous |
- Category Theory »

# Categories

AUTHORS:

- David Kohel, William Stein and Nicolas M. Thiery

Every Sage object lies in a category. Categories in Sage are modeled on the mathematical idea of category, and are distinct from Python classes, which are a programming construct.

In most cases, typing `x.category()` returns the category to which `x` belongs. If `C` is a category and `x` is any object, `C(x)` tries to make an object in `C` from `x`. Checking if `x` belongs to `C` is done as usually by `x in C`.

See `Category` and `sage.categories.primer` for more details.

EXAMPLES:

We create a couple of categories:

    sage: Sets()
    Category of sets
    sage: GSets(AbelianGroup([2,4,9]))
    Category of G-sets for Multiplicative Abelian group isomorphic to C2 x C4 x C9
    sage: Semigroups()
    Category of semigroups
    sage: VectorSpaces(FiniteField(11))
    Category of vector spaces over Finite Field of size 11
    sage: Ideals(IntegerRing())
    Category of ring ideals in Integer Ring

Let’s request the category of some objects:

    sage: V = VectorSpace(RationalField(), 3)
    sage: V.category()
    Category of vector spaces over Rational Field
    sage: G = SymmetricGroup(9)
    sage: G.category()
    Join of Category of finite permutation groups and Category of finite weyl groups
    sage: P = PerfectMatchings(3)
    sage: P.category()
    Category of finite enumerated sets

Let’s check some memberships:

    sage: V in VectorSpaces(QQ)
    True
    sage: V in VectorSpaces(FiniteField(11))
    False
    sage: G in Monoids()
    True
    sage: P in Rings()
    False

For parametrized categories one can use the following shorthand:

    sage: V in VectorSpaces
    True
    sage: G in VectorSpaces
    False

A parent `P` is in a category `C` if `P.category()` is a subcategory of `C`.

Note

Any object of a category should be an instance of `CategoryObject`.

For backward compatibilty this is not yet enforced:

    sage: class A:
    ....:   def category(self):
    ....:       return Fields()
    sage: A() in Rings()
    True

By default, the category of an element \(x\) of a parent \(P\) is the category of all objects of \(P\) (this is dubious an may be deprecated):

    sage: V = VectorSpace(RationalField(), 3)
    sage: v = V.gen(1)
    sage: v.category()
    Category of elements of Vector space of dimension 3 over Rational Field

class `sage.categories.category.``Category`(s=None)

  Bases: `sage.structure.unique_representation.UniqueRepresentation`, `sage.structure.sage_object.SageObject`

  The base class for modeling mathematical categories, like for example:

  - `Groups()`: the category of groups
  - `EuclideanDomains()`: the category of euclidean rings
  - `VectorSpaces(QQ)`: the category of vector spaces over the field of rationals

  See `sage.categories.primer` for an introduction to categories in Sage, their relevance, purpose, and usage. The documentation below will focus on their implementation.

  Technically, a category is an instance of the class `Category` or some of its subclasses. Some categories, like `VectorSpaces`, are parametrized: `VectorSpaces(QQ)` is one of many instances of the class `VectorSpaces`. On the other hand, `EuclideanDomains()` is the single instance of the class `EuclideanDomains`.

  Recall that an algebraic structure (say, the ring \(\QQ[x]\)) is modelled in Sage by an object which is called a parent. This object belongs to certain categories (here `EuclideanDomains()` and `Algebras()`). The elements of the ring are themselves objects.

  The class of a category (say `EuclideanDomains`) can define simultaneously:

  - Operations on the category itself (what is its super categories? its category of morphisms? its dual category?).
  - Generic operations on parents in this category, like the ring \(\QQ[x]\).
  - Generic operations on elements of such parents (e. g., the Euclidean algorithm for computing gcds).
  - Generic operations on morphisms of this category.

  This is achieved as follows:

      sage: from sage.categories.all import Category
      sage: class EuclideanDomains(Category):
      ....:     # operations on the category itself
      ....:     def super_categories(self):
      ....:         [Rings()]
      ....:
      ....:     def dummy(self): # TODO: find some good examples
      ....:          pass
      ....:
      ....:     class ParentMethods: # holds the generic operations on parents
      ....:          # TODO: find a good example of an operation
      ....:          pass
      ....:
      ....:     class ElementMethods:# holds the generic operations on elements
      ....:          def gcd(x,y):
      ....:              # Euclid algorithms
      ....:              pass
      ....:
      ....:     class MorphismMethods: # holds the generic operations on morphisms
      ....:          # TODO: find a good example of an operation
      ....:          pass
      ....:

  Note that the nested class `ParentMethods` is merely a container of operations, and does not inherit from anything. Instead, the hierarchy relation is defined once at the level of the categories, and the actual hierarchy of classes is built in parallel from all the `ParentMethods` nested classes, and stored in the attributes `parent_class`. Then, a parent in a category `C` receives the appropriate operations from all the super categories by usual class inheritance from `C.parent_class`.

  Similarly, two other hierarchies of classes, for elements and morphisms respectively, are built from all the `ElementMethods` and `MorphismMethods` nested classes.

  EXAMPLES:

  We define a hierarchy of four categories `As()`, `Bs()`, `Cs()`, `Ds()` with a diamond inheritance. Think for example:

  - `As()`: the category of sets
  - `Bs()`: the category of additive groups
  - `Cs()`: the category of multiplicative monoids
  - `Ds()`: the category of rings

      sage: from sage.categories.all import Category
      sage: from sage.misc.lazy_attribute import lazy_attribute
      sage: class As (Category):
      ....:     def super_categories(self):
      ....:         return []
      ....:
      ....:     class ParentMethods:
      ....:         def fA(self):
      ....:             return "A"
      ....:         f = fA

      sage: class Bs (Category):
      ....:     def super_categories(self):
      ....:         return [As()]
      ....:
      ....:     class ParentMethods:
      ....:         def fB(self):
      ....:             return "B"

      sage: class Cs (Category):
      ....:     def super_categories(self):
      ....:         return [As()]
      ....:
      ....:     class ParentMethods:
      ....:         def fC(self):
      ....:             return "C"
      ....:         f = fC

      sage: class Ds (Category):
      ....:     def super_categories(self):
      ....:         return [Bs(),Cs()]
      ....:
      ....:     class ParentMethods:
      ....:         def fD(self):
      ....:             return "D"

  Categories should always have unique representation; by trac ticket trac ticket #12215, this means that it will be kept in cache, but only if there is still some strong reference to it.

  We check this before proceeding:

      sage: import gc
      sage: idAs = id(As())
      sage: _ = gc.collect()
      sage: n == id(As())
      False
      sage: a = As()
      sage: id(As()) == id(As())
      True
      sage: As().parent_class == As().parent_class
      True

  We construct a parent in the category `Ds()` (that, is an instance of `Ds().parent_class`), and check that it has access to all the methods provided by all the categories, with the appropriate inheritance order:

      sage: D = Ds().parent_class()
      sage: [ D.fA(), D.fB(), D.fC(), D.fD() ]
      ['A', 'B', 'C', 'D']
      sage: D.f()
      'C'

      sage: C = Cs().parent_class()
      sage: [ C.fA(), C.fC() ]
      ['A', 'C']
      sage: C.f()
      'C'

  Here is the parallel hierarchy of classes which has been built automatically, together with the method resolution order (`.mro()`):

      sage: As().parent_class
      <class '__main__.As.parent_class'>
      sage: As().parent_class.__bases__
      (<type 'object'>,)
      sage: As().parent_class.mro()
      [<class '__main__.As.parent_class'>, <type 'object'>]

      sage: Bs().parent_class
      <class '__main__.Bs.parent_class'>
      sage: Bs().parent_class.__bases__
      (<class '__main__.As.parent_class'>,)
      sage: Bs().parent_class.mro()
      [<class '__main__.Bs.parent_class'>, <class '__main__.As.parent_class'>, <type 'object'>]

      sage: Cs().parent_class
      <class '__main__.Cs.parent_class'>
      sage: Cs().parent_class.__bases__
      (<class '__main__.As.parent_class'>,)
      sage: Cs().parent_class.__mro__
      (<class '__main__.Cs.parent_class'>, <class '__main__.As.parent_class'>, <type 'object'>)

      sage: Ds().parent_class
      <class '__main__.Ds.parent_class'>
      sage: Ds().parent_class.__bases__
      (<class '__main__.Cs.parent_class'>, <class '__main__.Bs.parent_class'>)
      sage: Ds().parent_class.mro()
      [<class '__main__.Ds.parent_class'>, <class '__main__.Cs.parent_class'>, <class '__main__.Bs.parent_class'>, <class '__main__.As.parent_class'>, <type 'object'>]

  Note that that two categories in the same class need not have the same `super_categories`. For example, `Algebras(QQ)` has `VectorSpaces(QQ)` as super category, whereas `Algebras(ZZ)` only has `Modules(ZZ)` as super category. In particular, the constructed parent class and element class will differ (inheriting, or not, methods specific for vector spaces):

      sage: Algebras(QQ).parent_class is Algebras(ZZ).parent_class
      False
      sage: issubclass(Algebras(QQ).parent_class, VectorSpaces(QQ).parent_class)
      True

  On the other hand, identical hierarchies of classes are, preferably, built only once (e.g. for categories over a base ring):

      sage: Algebras(GF(5)).parent_class is Algebras(GF(7)).parent_class
      True
      sage: Coalgebras(QQ).parent_class is Coalgebras(FractionField(QQ[x])).parent_class
      True

  We now construct a parent in the usual way:

      sage: class myparent(Parent):
      ....:     def __init__(self):
      ....:         Parent.__init__(self, category=Ds())
      ....:     def g(self):
      ....:         return "myparent"
      ....:     class Element:
      ....:         pass
      sage: D = myparent()
      sage: D.__class__
      <class '__main__.myparent_with_category'>
      sage: D.__class__.__bases__
      (<class '__main__.myparent'>, <class '__main__.Ds.parent_class'>)
      sage: D.__class__.mro()
      [<class '__main__.myparent_with_category'>,
      <class '__main__.myparent'>,
      <type 'sage.structure.parent.Parent'>,
      <type 'sage.structure.category_object.CategoryObject'>,
      <type 'sage.structure.sage_object.SageObject'>,
      <class '__main__.Ds.parent_class'>,
      <class '__main__.Cs.parent_class'>,
      <class '__main__.Bs.parent_class'>,
      <class '__main__.As.parent_class'>,
      <type 'object'>]
      sage: D.fA()
      'A'
      sage: D.fB()
      'B'
      sage: D.fC()
      'C'
      sage: D.fD()
      'D'
      sage: D.f()
      'C'
      sage: D.g()
      'myparent'

      sage: D.element_class
      <class '__main__.myparent_with_category.element_class'>
      sage: D.element_class.mro()
      [<class '__main__.myparent_with_category.element_class'>,
      <class __main__.Element at ...>,
      <class '__main__.Ds.element_class'>,
      <class '__main__.Cs.element_class'>,
      <class '__main__.Bs.element_class'>,
      <class '__main__.As.element_class'>,
      <type 'object'>]

  TESTS:

      sage: import __main__
      sage: __main__.myparent = myparent
      sage: __main__.As = As
      sage: __main__.Bs = Bs
      sage: __main__.Cs = Cs
      sage: __main__.Ds = Ds
      sage: loads(dumps(Ds)) is Ds
      True
      sage: loads(dumps(Ds())) is Ds()
      True
      sage: loads(dumps(Ds().element_class)) is Ds().element_class
      True

  `_super_categories`()

    The immediate super categories of this category.

    This lazy attribute caches the result of the mandatory method `super_categories()` for speed. It also does some mangling (flattening join categories, sorting, ...).

    Whenever speed matters, developers are advised to use this lazy attribute rather than calling `super_categories()`.

    Note

    This attribute is likely to eventually become a tuple. When this happens, we might as well use `Category._sort()`, if not `Category._sort_uniq()`.

    EXAMPLES:

        sage: Rings()._super_categories
        [Category of rngs, Category of semirings]

  `_super_categories_for_classes`()

    The super categories of this category used for building classes.

    This is a close variant of `_super_categories()` used for constructing the list of the bases for `parent_class()`, `element_class()`, and friends. The purpose is ensure that Python will find a proper Method Resolution Order for those classes. For background, see `sage.misc.c3_controlled`.

    See also

    `_cmp_key()`.

    Note

    This attribute is calculated as a by-product of computing `_all_super_categories()`.

    EXAMPLES:

        sage: Rings()._super_categories_for_classes
        [Category of rngs, Category of semirings]

  `_all_super_categories`()

    All the super categories of this category, including this category.

    Since trac ticket #11943, the order of super categories is determined by Python’s method resolution order C3 algorithm.

    See also

    `all_super_categories()`

    Note

    this attribute is likely to eventually become a tuple.

    Note

    this sets `_super_categories_for_classes()` as a side effect

    EXAMPLES:

        sage: C = Rings(); C
        Category of rings
        sage: C._all_super_categories
        [Category of rings, Category of rngs, Category of semirings, ...
         Category of monoids, ...
         Category of commutative additive groups, ...
         Category of sets, Category of sets with partial maps,
         Category of objects]

  `_all_super_categories_proper`()

    All the proper super categories of this category.

    Since trac ticket #11943, the order of super categories is determined by Python’s method resolution order C3 algorithm.

    See also

    `all_super_categories()`

    Note

    this attribute is likely to eventually become a tuple.

    EXAMPLES:

        sage: C = Rings(); C
        Category of rings
        sage: C._all_super_categories_proper
        [Category of rngs, Category of semirings, ...
         Category of monoids, ...
         Category of commutative additive groups, ...
         Category of sets, Category of sets with partial maps,
         Category of objects]

  `_set_of_super_categories`()

    The frozen set of all proper super categories of this category.

    Note

    this is used for speeding up category containment tests.

    See also

    `all_super_categories()`

    EXAMPLES:

        sage: Groups()._set_of_super_categories
        frozenset({Category of inverse unital magmas,
                   Category of unital magmas,
                   Category of magmas,
                   Category of monoids,
                   Category of objects,
                   Category of semigroups,
                   Category of sets with partial maps,
                   Category of sets})
        sage: sorted(Groups()._set_of_super_categories, key=str)
        [Category of inverse unital magmas, Category of magmas, Category of monoids,
         Category of objects, Category of semigroups, Category of sets,
         Category of sets with partial maps, Category of unital magmas]

    TESTS:

        sage: C = HopfAlgebrasWithBasis(GF(7))
        sage: C._set_of_super_categories == frozenset(C._all_super_categories_proper)
        True

  `_make_named_class`(name, method_provider, cache=False, picklable=True)

    Construction of the parent/element/... class of `self`.

    INPUT:

    - `name` – a string; the name of the class as an attribute of `self`. E.g. “parent_class”
    - `method_provider` – a string; the name of an attribute of `self` that provides methods for the new class (in addition to those coming from the super categories). E.g. “ParentMethods”
    - `cache` – a boolean or `ignore_reduction` (default: `False`) (passed down to dynamic_class; for internal use only)
    - `picklable` – a boolean (default: `True`)

    ASSUMPTION:

    It is assumed that this method is only called from a lazy attribute whose name coincides with the given `name`.

    OUTPUT:

    A dynamic class with bases given by the corresponding named classes of `self`‘s super_categories, and methods taken from the class `getattr(self,method_provider)`.

    Note

    - In this default implementation, the reduction data of the named class makes it depend on `self`. Since the result is going to be stored in a lazy attribute of `self` anyway, we may as well disable the caching in `dynamic_class` (hence the default value `cache=False`).
    - `CategoryWithParameters` overrides this method so that the same parent/element/... classes can be shared between closely related categories.
    - The bases of the named class may also contain the named classes of some indirect super categories, according to `_super_categories_for_classes()`. This is to guarantee that Python will build consistent method resolution orders. For background, see `sage.misc.c3_controlled`.

    See also

    `CategoryWithParameters._make_named_class()`

    EXAMPLES:

        sage: PC = Rings()._make_named_class("parent_class", "ParentMethods"); PC
        <class 'sage.categories.rings.Rings.parent_class'>
        sage: type(PC)
        <class 'sage.structure.dynamic_class.DynamicMetaclass'>
        sage: PC.__bases__
        (<class 'sage.categories.rngs.Rngs.parent_class'>,
         <class 'sage.categories.semirings.Semirings.parent_class'>)

    Note that, by default, the result is not cached:

        sage: PC is Rings()._make_named_class("parent_class", "ParentMethods")
        False

    Indeed this method is only meant to construct lazy attributes like `parent_class` which already handle this caching:

        sage: Rings().parent_class
        <class 'sage.categories.rings.Rings.parent_class'>

    Reduction for pickling also assumes the existence of this lazy attribute:

        sage: PC._reduction
        (<built-in function getattr>, (Category of rings, 'parent_class'))
        sage: loads(dumps(PC)) is Rings().parent_class
        True

    TESTS:

        sage: class A: pass
        sage: class BrokenCategory(Category):
        ....:     def super_categories(self): return []
        ....:     ParentMethods = 1
        ....:     class ElementMethods(A):
        ....:         pass
        ....:     class MorphismMethods(object):
        ....:         pass
        sage: C = BrokenCategory()
        sage: C._make_named_class("parent_class",   "ParentMethods")
        Traceback (most recent call last):
        ...
        AssertionError: BrokenCategory.ParentMethods should be a class
        sage: C._make_named_class("element_class",  "ElementMethods")
        doctest:...: UserWarning: BrokenCategory.ElementMethods should not have a super class
        <class '__main__.BrokenCategory.element_class'>
        sage: C._make_named_class("morphism_class", "MorphismMethods")
        <class '__main__.BrokenCategory.morphism_class'>

  `_repr_`()

    Return the print representation of this category.

    EXAMPLES:

        sage: Sets() # indirect doctest
        Category of sets

  `_repr_object_names`()

    Return the name of the objects of this category.

    EXAMPLES:

        sage: FiniteGroups()._repr_object_names()
        'finite groups'
        sage: AlgebrasWithBasis(QQ)._repr_object_names()
        'algebras with basis over Rational Field'

  `_test_category`(**options)

    Run generic tests on this category

    See also

    `TestSuite`.

    EXAMPLES:

        sage: Sets()._test_category()

    Let us now write a couple broken categories:

        sage: class MyObjects(Category):
        ....:      pass
        sage: MyObjects()._test_category()
        Traceback (most recent call last):
        ...
        NotImplementedError: <abstract method super_categories at ...>

        sage: class MyObjects(Category):
        ....:      def super_categories(self):
        ....:          return tuple()
        sage: MyObjects()._test_category()
        Traceback (most recent call last):
        ...
        AssertionError: Category of my objects.super_categories() should return a list

        sage: class MyObjects(Category):
        ....:      def super_categories(self):
        ....:          return []
        sage: MyObjects()._test_category()
        Traceback (most recent call last):
        ...
        AssertionError: Category of my objects is not a subcategory of Objects()

  `_with_axiom`(axiom)

    Return the subcategory of the objects of `self` satisfying the given `axiom`.

    INPUT:

    - `axiom` – a string, the name of an axiom

    EXAMPLES:

        sage: Sets()._with_axiom("Finite")
        Category of finite sets

        sage: type(Magmas().Finite().Commutative())
        <class 'sage.categories.category.JoinCategory_with_category'>
        sage: Magmas().Finite().Commutative().super_categories()
        [Category of commutative magmas, Category of finite sets]
        sage: Algebras(QQ).WithBasis().Commutative() is Algebras(QQ).Commutative().WithBasis()
        True

    When `axiom` is not defined for `self`, `self` is returned:

        sage: Sets()._with_axiom("Associative")
        Category of sets

    Warning

    This may be changed in the future to raising an error.

  `_with_axiom_as_tuple`(axiom)

    Return a tuple of categories whose join is `self._with_axiom()`.

    INPUT:

    - `axiom` – a string, the name of an axiom

    This is a lazy version of `_with_axiom()` which is used to avoid recursion loops during join calculations.

    Note

    The order in the result is irrelevant.

    EXAMPLES:

        sage: Sets()._with_axiom_as_tuple('Finite')
        (Category of finite sets,)
        sage: Magmas()._with_axiom_as_tuple('Finite')
        (Category of magmas, Category of finite sets)
        sage: Rings().Division()._with_axiom_as_tuple('Finite')
        (Category of division rings,
         Category of finite monoids,
         Category of commutative magmas)
        sage: HopfAlgebras(QQ)._with_axiom_as_tuple('FiniteDimensional')
        (Category of hopf algebras over Rational Field,
         Category of finite dimensional modules over Rational Field)

  `_without_axioms`(named=False)

    Return the category without the axioms that have been added to create it.

    INPUT:

    - `named` – a boolean (default: `False`)

    Todo

    Improve this explanation.

    If `named` is `True`, then this stops at the first category that has an explicit name of its own. See `category_with_axiom.CategoryWithAxiom._without_axioms()`

    EXAMPLES:

        sage: Sets()._without_axioms()
        Category of sets
        sage: Semigroups()._without_axioms()
        Category of magmas
        sage: Algebras(QQ).Commutative().WithBasis()._without_axioms()
        Category of magmatic algebras over Rational Field
        sage: Algebras(QQ).Commutative().WithBasis()._without_axioms(named=True)
        Category of algebras over Rational Field

  static `_sort`(categories)

    Return the categories after sorting them decreasingly according to their comparison key.

    See also

    `_cmp_key()`

    INPUT:

    - `categories` – a list (or iterable) of non-join categories

    OUTPUT:

    A sorted tuple of categories, possibly with repeats.

    Note

    The auxiliary function \(_flatten_categories\) used in the test below expects a second argument, which is a type such that instances of that type will be replaced by its super categories. Usually, this type is `JoinCategory`.

    EXAMPLES:

        sage: Category._sort([Sets(), Objects(), Coalgebras(QQ), Monoids(), Sets().Finite()])
        (Category of monoids,
         Category of coalgebras over Rational Field,
         Category of finite sets,
         Category of sets,
         Category of objects)
        sage: Category._sort([Sets().Finite(), Semigroups().Finite(), Sets().Facade(),Magmas().Commutative()])
        (Category of finite semigroups,
         Category of commutative magmas,
         Category of finite sets,
         Category of facade sets)
        sage: Category._sort(Category._flatten_categories([Sets().Finite(), Algebras(QQ).WithBasis(), Semigroups().Finite(), Sets().Facade(),Algebras(QQ).Commutative(), Algebras(QQ).Graded().WithBasis()], sage.categories.category.JoinCategory))
        (Category of algebras with basis over Rational Field,
         Category of algebras with basis over Rational Field,
         Category of graded algebras over Rational Field,
         Category of commutative algebras over Rational Field,
         Category of finite semigroups,
         Category of finite sets,
         Category of facade sets)

  `_sort_uniq`(categories)

    Return the categories after sorting them and removing redundant categories.

    Redundant categories include duplicates and categories which are super categories of other categories in the input.

    INPUT:

    - `categories` – a list (or iterable) of categories

    OUTPUT: a sorted tuple of mutually incomparable categories

    EXAMPLES:

        sage: Category._sort_uniq([Rings(), Monoids(), Coalgebras(QQ)])
        (Category of rings, Category of coalgebras over Rational Field)

    Note that, in the above example, `Monoids()` does not appear in the result because it is a super category of `Rings()`.

  static `__classcall__`(*args, **options)

    Input mangling for unique representation.

    Let `C = Cs(...)` be a category. Since trac ticket #12895, the class of `C` is a dynamic subclass `Cs_with_category` of `Cs` in order for `C` to inherit code from the `SubcategoryMethods` nested classes of its super categories.

    The purpose of this `__classcall__` method is to ensure that reconstructing `C` from its class with `Cs_with_category(...)` actually calls properly `Cs(...)` and gives back `C`.

    See also

    `subcategory_class()`

    EXAMPLES:

        sage: A = Algebras(QQ)
        sage: A.__class__
        <class 'sage.categories.algebras.Algebras_with_category'>
        sage: A is Algebras(QQ)
        True
        sage: A is A.__class__(QQ)
        True

  `__init__`(s=None)

    Initializes this category.

    EXAMPLES:

        sage: class SemiprimitiveRings(Category):
        ....:     def super_categories(self):
        ....:         return [Rings()]
        ....:
        ....:     class ParentMethods:
        ....:         def jacobson_radical(self):
        ....:             return self.ideal(0)
        ....:
        sage: C = SemiprimitiveRings()
        sage: C
        Category of semiprimitive rings
        sage: C.__class__
        <class '__main__.SemiprimitiveRings_with_category'>

    Note

    Specifying the name of this category by passing a string is deprecated. If the default name (built from the name of the class) is not adequate, please use `_repr_object_names()` to customize it.

  `Realizations`()

    Return the category of realizations of the parent `self` or of objects of the category `self`

    INPUT:

    - `self` – a parent or a concrete category

    Note

    this function is actually inserted as a method in the class `Category` (see `Realizations()`). It is defined here for code locality reasons.

    EXAMPLES:

    The category of realizations of some algebra:

        sage: Algebras(QQ).Realizations()
        Join of Category of algebras over Rational Field and Category of realizations of magmas

    The category of realizations of a given algebra:

        sage: A = Sets().WithRealizations().example(); A
        The subset algebra of {1, 2, 3} over Rational Field
        sage: A.Realizations()
        Category of realizations of The subset algebra of {1, 2, 3} over Rational Field

        sage: C = GradedHopfAlgebrasWithBasis(QQ).Realizations(); C
        Join of Category of graded hopf algebras with basis over Rational Field and Category of realizations of hopf algebras over Rational Field
        sage: C.super_categories()
        [Category of graded hopf algebras with basis over Rational Field, Category of realizations of hopf algebras over Rational Field]

        sage: TestSuite(C).run()

    See also

    - `Sets().WithRealizations`
    - `ClasscallMetaclass`

    Todo

    Add an optional argument to allow for:

        sage: Realizations(A, category = Blahs()) # todo: not implemented

  `WithRealizations`()

    Returns the category of parents in `self` endowed with multiple realizations

    INPUT:

    - `self` – a category

    See also

    - the documentation and code (`sage.categories.examples.with_realizations`) of `Sets().WithRealizations().example()` for more on how to use and implement a parent with several realizations.
    - `sage.categories.realizations`

    Note

    this function is actually inserted as a method in the class `Category` (see `WithRealizations()`). It is defined here for code locality reasons.

    EXAMPLES:

        sage: Sets().WithRealizations()
        Category of sets with realizations

    Parent with realizations

    Let us now explain the concept of realizations. A parent with realizations is a facade parent (see `Sets.Facade`) admitting multiple concrete realizations where its elements are represented. Consider for example an algebra \(A\) which admits several natural bases:

        sage: A = Sets().WithRealizations().example(); A
        The subset algebra of {1, 2, 3} over Rational Field

    For each such basis \(B\) one implements a parent \(P_B\) which realizes \(A\) with its elements represented by expanding them on the basis \(B\):

        sage: A.F()
        The subset algebra of {1, 2, 3} over Rational Field in the Fundamental basis
        sage: A.Out()
        The subset algebra of {1, 2, 3} over Rational Field in the Out basis
        sage: A.In()
        The subset algebra of {1, 2, 3} over Rational Field in the In basis

        sage: A.an_element()
        F[{}] + 2*F[{1}] + 3*F[{2}] + F[{1, 2}]

    If \(B\) and \(B'\) are two bases, then the change of basis from \(B\) to \(B'\) is implemented by a canonical coercion between \(P_B\) and \(P_{B'}\):

        sage: F = A.F(); In = A.In(); Out = A.Out()
        sage: i = In.an_element(); i
        In[{}] + 2*In[{1}] + 3*In[{2}] + In[{1, 2}]
        sage: F(i)
        7*F[{}] + 3*F[{1}] + 4*F[{2}] + F[{1, 2}]
        sage: F.coerce_map_from(Out)
        Generic morphism:
          From: The subset algebra of {1, 2, 3} over Rational Field in the Out basis
          To:   The subset algebra of {1, 2, 3} over Rational Field in the Fundamental basis

    allowing for mixed arithmetic:

        sage: (1 + Out.from_set(1)) * In.from_set(2,3)
        Out[{}] + 2*Out[{1}] + 2*Out[{2}] + 2*Out[{3}] + 2*Out[{1, 2}] + 2*Out[{1, 3}] + 4*Out[{2, 3}] + 4*Out[{1, 2, 3}]

    In our example, there are three realizations:

        sage: A.realizations()
        [The subset algebra of {1, 2, 3} over Rational Field in the Fundamental basis,
         The subset algebra of {1, 2, 3} over Rational Field in the In basis,
         The subset algebra of {1, 2, 3} over Rational Field in the Out basis]

    The set of all realizations of \(A\), together with the coercion morphisms is a category (whose class inherits from `Category_realization_of_parent`):

        sage: A.Realizations()
        Category of realizations of The subset algebra of {1, 2, 3} over Rational Field

    The various parent realizing \(A\) belong to this category:

        sage: A.F() in A.Realizations()
        True

    \(A\) itself is in the category of algebras with realizations:

        sage: A in Algebras(QQ).WithRealizations()
        True

    The (mostly technical) `WithRealizations` categories are the analogs of the `*WithSeveralBases` categories in MuPAD-Combinat. They provide support tools for handling the different realizations and the morphisms between them.

    Typically, `FiniteDimensionalVectorSpaces(QQ).WithRealizations()` will eventually be in charge, whenever a coercion \(\phi: A\mapsto B\) is registered, to register \(\phi^{-1}\) as coercion \(B \mapsto A\) if there is none defined yet. To achieve this, `FiniteDimensionalVectorSpaces` would provide a nested class `WithRealizations` implementing the appropriate logic.

    `WithRealizations` is a `regressive covariant functorial construction`. On our example, this simply means that \(A\) is automatically in the category of rings with realizations (covariance):

        sage: A in Rings().WithRealizations()
        True

    and in the category of algebras (regressiveness):

        sage: A in Algebras(QQ)
        True

    Note

    For `C` a category, `C.WithRealizations()` in fact calls `sage.categories.with_realizations.Realizations(C)`. The later is responsible for building the hierarchy of the categories with realizations in parallel to that of their base categories, optimizing away those categories that do not provide a `WithRealizations` nested class. See `sage.categories.covariant_functorial_construction` for the technical details.

    Note

    Design question: currently `WithRealizations` is a regressive construction. That is `self.WithRealizations()` is a subcategory of `self` by default:

        sage: Algebras(QQ).WithRealizations().super_categories()
        [Category of algebras over Rational Field,
         Category of monoids with realizations,
         Category of additive unital additive magmas with realizations]

    Is this always desirable? For example, `AlgebrasWithBasis(QQ).WithRealizations()` should certainly be a subcategory of `Algebras(QQ)`, but not of `AlgebrasWithBasis(QQ)`. This is because `AlgebrasWithBasis(QQ)` is specifying something about the concrete realization.

    TESTS:

        sage: Semigroups().WithRealizations()
        Join of Category of semigroups and Category of sets with realizations
        sage: C = GradedHopfAlgebrasWithBasis(QQ).WithRealizations(); C
        Category of graded hopf algebras with basis over Rational Field with realizations
        sage: C.super_categories()
        [Join of Category of hopf algebras over Rational Field
             and Category of graded algebras over Rational Field]
        sage: TestSuite(Semigroups().WithRealizations()).run()

  `additional_structure`()

    Return whether `self` defines additional structure.

    OUTPUT:

    - `self` if `self` defines additional structure and `None` otherwise. This default implementation returns `self`.

    A category \(C\) defines additional structure if \(C\)-morphisms shall preserve more structure (e.g. operations) than that specified by the super categories of \(C\). For example, the category of magmas defines additional structure, namely the operation \(*\) that shall be preserved by magma morphisms. On the other hand the category of rings does not define additional structure: a function between two rings that is both a unital magma morphism and a unital additive magma morphism is automatically a ring morphism.

    Formally speaking \(C\) defines additional structure, if \(C\) is not a full subcategory of the join of its super categories: the morphisms need to preserve more structure, and thus the homsets are smaller.

    By default, a category is considered as defining additional structure, unless it is a category with axiom.

    EXAMPLES:

    Here are some typical structure categories, with the additional structure they define:

        sage: Sets().additional_structure()
        Category of sets
        sage: Magmas().additional_structure()         # `*`
        Category of magmas
        sage: AdditiveMagmas().additional_structure() # `+`
        Category of additive magmas
        sage: LeftModules(ZZ).additional_structure()  # left multiplication by scalar
        Category of left modules over Integer Ring
        sage: Coalgebras(QQ).additional_structure()   # coproduct
        Category of coalgebras over Rational Field
        sage: CoxeterGroups().additional_structure()  # distinguished generators
        Category of coxeter groups
        sage: Crystals().additional_structure()       # crystal operators
        Category of crystals

    On the other hand, the category of semigroups is not a structure category, since its operation \(+\) is already defined by the category of magmas:

        sage: Semigroups().additional_structure()

    Most categories with axiom don’t define additional structure:

        sage: Sets().Finite().additional_structure()
        sage: Rings().Commutative().additional_structure()
        sage: Modules(QQ).FiniteDimensional().additional_structure()
        sage: from sage.categories.magmatic_algebras import MagmaticAlgebras
        sage: MagmaticAlgebras(QQ).Unital().additional_structure()

    As of Sage 6.4, the only exceptions are the category of unital magmas or the category of unital additive magmas (both define a unit which shall be preserved by morphisms):

        sage: Magmas().Unital().additional_structure()
        Category of unital magmas
        sage: AdditiveMagmas().AdditiveUnital().additional_structure()
        Category of additive unital additive magmas

    Similarly, functorial construction categories don’t define additional structure, unless the construction is actually defined by their base category. For example, the category of graded modules defines a grading which shall be preserved by morphisms:

        sage: Modules(ZZ).Graded().additional_structure()
        Category of graded modules over Integer Ring

    On the other hand, the category of graded algebras does not define additional structure; indeed an algebra morphism which is also a module morphism is a graded algebra morphism:

        sage: Algebras(ZZ).Graded().additional_structure()

    Similarly, morphisms are requested to preserve the structure given by the following constructions:

        sage: Sets().Quotients().additional_structure()
        Category of quotients of sets
        sage: Sets().CartesianProducts().additional_structure()
        Category of Cartesian products of sets
        sage: Modules(QQ).TensorProducts().additional_structure()

    This might change, as we are lacking enough data points to guarantee that this was the correct design decision.

    Note

    In some cases a category defines additional structure, where the structure can be useful to manipulate morphisms but where, in most use cases, we don’t want the morphisms to necessarily preserve it. For example, in the context of finite dimensional vector spaces, having a distinguished basis allows for representing morphisms by matrices; yet considering only morphisms that preserve that distinguished basis would be boring.

    In such cases, we might want to eventually have two categories, one where the additional structure is preserved, and one where it’s not necessarily preserved (we would need to find an idiom for this).

    At this point, a choice is to be made each time, according to the main use cases. Some of those choices are yet to be settled. For example, should by default:

    - an euclidean domain morphism preserve euclidean division?

          sage: EuclideanDomains().additional_structure()
          Category of euclidean domains

    - an enumerated set morphism preserve the distinguished enumeration?

          sage: EnumeratedSets().additional_structure()

    - a module with basis morphism preserve the distinguished basis?

          sage: Modules(QQ).WithBasis().additional_structure()

    See also

    This method together with the methods overloading it provide the basic data to determine, for a given category, the super categories that define some structure (see `structure()`), and to test whether a category is a full subcategory of some other category (see `is_full_subcategory()`).

    The support for modeling full subcategories has been introduced in trac ticket #16340.

  `all_super_categories`(proper=False)

    Returns the list of all super categories of this category.

    INPUT:

    > - `proper` – a boolean (default: `False`); whether to exclude this category.

    Since trac ticket #11943, the order of super categories is determined by Python’s method resolution order C3 algorithm.

    Note

    Whenever speed matters, the developers are advised to use instead the lazy attributes `_all_super_categories()`, `_all_super_categories_proper()`, or `_set_of_super_categories()`, as appropriate. Simply because lazy attributes are much faster than any method.

    EXAMPLES:

        sage: C = Rings(); C
        Category of rings
        sage: C.all_super_categories()
        [Category of rings, Category of rngs, Category of semirings, ...
         Category of monoids, ...
         Category of commutative additive groups, ...
         Category of sets, Category of sets with partial maps,
         Category of objects]

        sage: C.all_super_categories(proper = True)
        [Category of rngs, Category of semirings, ...
         Category of monoids, ...
         Category of commutative additive groups, ...
         Category of sets, Category of sets with partial maps,
         Category of objects]

        sage: Sets().all_super_categories()
        [Category of sets, Category of sets with partial maps, Category of objects]
        sage: Sets().all_super_categories(proper=True)
        [Category of sets with partial maps, Category of objects]
        sage: Sets().all_super_categories() is Sets()._all_super_categories
        True
        sage: Sets().all_super_categories(proper=True) is Sets()._all_super_categories_proper
        True

  classmethod `an_instance`()

    Return an instance of this class.

    EXAMPLES:

        sage: Rings.an_instance()
        Category of rings

    Parametrized categories should overload this default implementation to provide appropriate arguments:

        sage: Algebras.an_instance()
        Category of algebras over Rational Field
        sage: Bimodules.an_instance()
        Category of bimodules over Rational Field on the left and Real Field with 53 bits of precision on the right
        sage: AlgebraIdeals.an_instance()
        Category of algebra ideals in Univariate Polynomial Ring in x over Rational Field

  `axioms`()

    Return the axioms known to be satisfied by all the objects of `self`.

    Technically, this is the set of all the axioms `A` such that, if `Cs` is the category defining `A`, then `self` is a subcategory of `Cs().A()`. Any additional axiom `A` would yield a strict subcategory of `self`, at the very least `self & Cs().A()` where `Cs` is the category defining `A`.

    EXAMPLES:

        sage: Monoids().axioms()
        frozenset({'Associative', 'Unital'})
        sage: (EnumeratedSets().Infinite() & Sets().Facade()).axioms()
        frozenset({'Facade', 'Infinite'})

  `category`()

    Return the category of this category. So far, all categories are in the category of objects.

    EXAMPLES:

        sage: Sets().category()
        Category of objects
        sage: VectorSpaces(QQ).category()
        Category of objects

  `category_graph`()

    Returns the graph of all super categories of this category

    EXAMPLES:

        sage: C = Algebras(QQ)
        sage: G = C.category_graph()
        sage: G.is_directed_acyclic()
        True
        sage: G.girth()
        4

  `element_class`()

    A common super class for all elements of parents in this category (and its subcategories).

    This class contains the methods defined in the nested class `self.ElementMethods` (if it exists), and has as bases the element classes of the super categories of `self`.

    See also

    - `parent_class()`, `morphism_class()`
    - `Category` for details

    EXAMPLES:

        sage: C = Algebras(QQ).element_class; C
        <class 'sage.categories.algebras.Algebras.element_class'>
        sage: type(C)
        <class 'sage.structure.dynamic_class.DynamicMetaclass'>

    By trac ticket #11935, some categories share their element classes. For example, the element class of an algebra only depends on the category of the base. A typical example is the category of algebras over a field versus algebras over a non-field:

        sage: Algebras(GF(5)).element_class is Algebras(GF(3)).element_class
        True
        sage: Algebras(QQ).element_class is Algebras(ZZ).element_class
        False
        sage: Algebras(ZZ['t']).element_class is Algebras(ZZ['t','x']).element_class
        True

    See also

    `parent_class()`

  `example`(*args, **keywords)

    Returns an object in this category. Most of the time, this is a parent.

    This serves three purposes:

    - Give a typical example to better explain what the category is all about. (and by the way prove that the category is non empty :-) )
    - Provide a minimal template for implementing other objects in this category
    - Provide an object on which to test generic code implemented by the category

    For all those applications, the implementation of the object shall be kept to a strict minimum. The object is therefore not meant to be used for other applications; most of the time a full featured version is available elsewhere in Sage, and should be used insted.

    Technical note: by default `FooBar(...).example()` is constructed by looking up `sage.categories.examples.foo_bar.Example` and calling it as `Example()`. Extra positional or named parameters are also passed down. For a category over base ring, the base ring is further passed down as an optional argument.

    Categories are welcome to override this default implementation.

    EXAMPLES:

        sage: Semigroups().example()
        An example of a semigroup: the left zero semigroup

        sage: Monoids().Subquotients().example()
        NotImplemented

  `full_super_categories`()

    Return the immediate full super categories of `self`.

    See also

    - `super_categories()`
    - `is_full_subcategory()`

    Warning

    The current implementation selects the full subcategories among the immediate super categories of `self`. This assumes that, if \(C\subset B\subset A\) is a chain of categories and \(C\) is a full subcategory of \(A\), then \(C\) is a full subcategory of \(B\) and \(B\) is a full subcategory of \(A\).

    This assumption is guaranteed to hold with the current model and implementation of full subcategories in Sage. However, mathematically speaking, this is too restrictive. This indeed prevents the complete modelling of situations where any \(A\) morphism between elements of \(C\) automatically preserves the \(B\) structure. See below for an example.

    EXAMPLES:

    A semigroup morphism between two finite semigroups is a finite semigroup morphism:

        sage: Semigroups().Finite().full_super_categories()
        [Category of semigroups]

    On the other hand, a semigroup morphism between two monoids is not necessarily a monoid morphism (which must map the unit to the unit):

        sage: Monoids().super_categories()
        [Category of semigroups, Category of unital magmas]
        sage: Monoids().full_super_categories()
        [Category of unital magmas]

    Any semigroup morphism between two groups is automatically a monoid morphism (in a group the unit is the unique idempotent, so it has to be mapped to the unit). Yet, due to the limitation of the model advertised above, Sage currently can’t be taught that the category of groups is a full subcategory of the category of semigroups:

        sage: Groups().full_super_categories()     # todo: not implemented
        [Category of monoids, Category of semigroups, Category of inverse unital magmas]
        sage: Groups().full_super_categories()
        [Category of monoids, Category of inverse unital magmas]

  `is_abelian`()

    Returns whether this category is abelian.

    An abelian category is a category satisfying:

    - It has a zero object;
    - It has all pullbacks and pushouts;
    - All monomorphisms and epimorphisms are normal.

    Equivalently, one can define an increasing sequence of conditions:

    - A category is pre-additive if it is enriched over abelian groups (all homsets are abelian groups and composition is bilinear);
    - A pre-additive category is additive if every finite set of objects has a biproduct (we can form direct sums and direct products);
    - An additive category is pre-abelian if every morphism has both a kernel and a cokernel;
    - A pre-abelian category is abelian if every monomorphism is the kernel of some morphism and every epimorphism is the cokernel of some morphism.

    EXAMPLES:

        sage: Modules(ZZ).is_abelian()
        True
        sage: FreeModules(ZZ).is_abelian()
        False
        sage: FreeModules(QQ).is_abelian()
        True
        sage: CommutativeAdditiveGroups().is_abelian()
        True
        sage: Semigroups().is_abelian()
        Traceback (most recent call last):
        NotImplementedError: is_abelian

  `is_full_subcategory`(other)

    Return whether `self` is a full subcategory of `other`.

    A subcategory \(B\) of a category \(A\) is a full subcategory if any \(A\)-morphism between two objects of \(B\) is also a \(B\)-morphism (the reciprocal always holds: any \(B\)-morphism between two objects of \(B\) is an \(A\)-morphism).

    This is computed by testing whether `self` is a subcategory of `other` and whether they have the same structure, as determined by `structure()` from the result of `additional_structure()` on the super categories.

    Warning

    A positive answer is guaranteed to be mathematically correct. A negative answer may mean that Sage has not been taught enough information (or can not yet within the current model) to derive this information. See `full_super_categories()` for a discussion.

    See also

    - `is_subcategory()`
    - `full_super_categories()`

    EXAMPLES:

        sage: Magmas().Associative().is_full_subcategory(Magmas())
        True
        sage: Magmas().Unital().is_full_subcategory(Magmas())
        False
        sage: Rings().is_full_subcategory(Magmas().Unital() & AdditiveMagmas().AdditiveUnital())
        True

    Here are two typical examples of false negatives:

        sage: Groups().is_full_subcategory(Semigroups())
        False
        sage: Groups().is_full_subcategory(Semigroups()) # todo: not implemented
        True
        sage: Fields().is_full_subcategory(Rings())
        False
        sage: Fields().is_full_subcategory(Rings())      # todo: not implemented
        True

    Todo

    The latter is a consequence of `EuclideanDomains` currently being a structure category. Is this what we want?

        sage: EuclideanDomains().is_full_subcategory(Rings())
        False

  `is_subcategory`(c)

    Returns True if self is naturally embedded as a subcategory of c.

    EXAMPLES:

        sage: AbGrps = CommutativeAdditiveGroups()
        sage: Rings().is_subcategory(AbGrps)
        True
        sage: AbGrps.is_subcategory(Rings())
        False

    The `is_subcategory` function takes into account the base.

        sage: M3 = VectorSpaces(FiniteField(3))
        sage: M9 = VectorSpaces(FiniteField(9, 'a'))
        sage: M3.is_subcategory(M9)
        False

    Join categories are properly handled:

        sage: CatJ = Category.join((CommutativeAdditiveGroups(), Semigroups()))
        sage: Rings().is_subcategory(CatJ)
        True

        sage: V3 = VectorSpaces(FiniteField(3))
        sage: POSet = PartiallyOrderedSets()
        sage: PoV3 = Category.join((V3, POSet))
        sage: A3 = AlgebrasWithBasis(FiniteField(3))
        sage: PoA3 = Category.join((A3, POSet))
        sage: PoA3.is_subcategory(PoV3)
        True
        sage: PoV3.is_subcategory(PoV3)
        True
        sage: PoV3.is_subcategory(PoA3)
        False

  static `join`(categories, as_list=False, ignore_axioms=(), axioms=())

    Return the join of the input categories in the lattice of categories.

    At the level of objects and morphisms, this operation corresponds to intersection: the objects and morphisms of a join category are those that belong to all its super categories.

    INPUT:

    - `categories` – a list (or iterable) of categories
    - `as_list` – a boolean (default: `False`); whether the result should be returned as a list
    - `axioms` – a tuple of strings; the names of some supplementary axioms

    See also

    `__and__()` for a shortcut

    EXAMPLES:

        sage: J = Category.join((Groups(), CommutativeAdditiveMonoids())); J
        Join of Category of groups and Category of commutative additive monoids
        sage: J.super_categories()
        [Category of groups, Category of commutative additive monoids]
        sage: J.all_super_categories(proper=True)
        [Category of groups, ..., Category of magmas,
         Category of commutative additive monoids, ..., Category of additive magmas,
         Category of sets, ...]

    As a short hand, one can use:

        sage: Groups() & CommutativeAdditiveMonoids()
        Join of Category of groups and Category of commutative additive monoids

    This is a commutative and associative operation:

        sage: Groups() & Posets()
        Join of Category of groups and Category of posets
        sage: Posets() & Groups()
        Join of Category of groups and Category of posets

        sage: Groups() & (CommutativeAdditiveMonoids() & Posets())
        Join of Category of groups
            and Category of commutative additive monoids
            and Category of posets
        sage: (Groups() & CommutativeAdditiveMonoids()) & Posets()
        Join of Category of groups
            and Category of commutative additive monoids
            and Category of posets

    The join of a single category is the category itself:

        sage: Category.join([Monoids()])
        Category of monoids

    Similarly, the join of several mutually comparable categories is the smallest one:

        sage: Category.join((Sets(), Rings(), Monoids()))
        Category of rings

    In particular, the unit is the top category `Objects`:

        sage: Groups() & Objects()
        Category of groups

    If the optional parameter `as_list` is `True`, this returns the super categories of the join as a list, without constructing the join category itself:

        sage: Category.join((Groups(), CommutativeAdditiveMonoids()), as_list=True)
        [Category of groups, Category of commutative additive monoids]
        sage: Category.join((Sets(), Rings(), Monoids()), as_list=True)
        [Category of rings]
        sage: Category.join((Modules(ZZ), FiniteFields()), as_list=True)
        [Category of finite fields, Category of modules over Integer Ring]
        sage: Category.join([], as_list=True)
        []
        sage: Category.join([Groups()], as_list=True)
        [Category of groups]
        sage: Category.join([Groups() & Posets()], as_list=True)
        [Category of groups, Category of posets]

    Support for axiom categories (TODO: put here meaningfull examples):

        sage: Sets().Facade() & Sets().Infinite()
        Category of facade infinite sets
        sage: Magmas().Infinite() & Sets().Facade()
        Category of facade infinite magmas

        sage: FiniteSets() & Monoids()
        Category of finite monoids
        sage: Rings().Commutative() & Sets().Finite()
        Category of finite commutative rings

    Note that several of the above examples are actually join categories; they are just nicely displayed:

        sage: AlgebrasWithBasis(QQ) & FiniteSets().Algebras(QQ)
        Join of Category of finite dimensional algebras with basis over Rational Field
            and Category of finite set algebras over Rational Field

        sage: UniqueFactorizationDomains() & Algebras(QQ)
        Join of Category of unique factorization domains
            and Category of commutative algebras over Rational Field

    TESTS:

        sage: Magmas().Unital().Commutative().Finite() is Magmas().Finite().Commutative().Unital()
        True
        sage: from sage.categories.category_with_axiom import TestObjects
        sage: T = TestObjects()
        sage: TCF = T.Commutative().Facade(); TCF
        Category of facade commutative test objects
        sage: TCF is T.Facade().Commutative()
        True
        sage: TCF is (T.Facade() & T.Commutative())
        True
        sage: TCF.axioms()
        frozenset({'Commutative', 'Facade'})
        sage: type(TCF)
        <class 'sage.categories.category_with_axiom.TestObjects.Commutative.Facade_with_category'>

        sage: TCF = T.Commutative().FiniteDimensional()
        sage: TCF is T.FiniteDimensional().Commutative()
        True
        sage: TCF is T.Commutative() & T.FiniteDimensional()
        True
        sage: TCF is T.FiniteDimensional() & T.Commutative()
        True
        sage: type(TCF)
        <class 'sage.categories.category_with_axiom.TestObjects.Commutative.FiniteDimensional_with_category'>

        sage: TCU = T.Commutative().Unital()
        sage: TCU is T.Unital().Commutative()
        True
        sage: TCU is T.Commutative() & T.Unital()
        True
        sage: TCU is T.Unital() & T.Commutative()
        True

        sage: TUCF = T.Unital().Commutative().FiniteDimensional(); TUCF
        Category of finite dimensional commutative unital test objects
        sage: type(TUCF)
        <class 'sage.categories.category_with_axiom.TestObjects.FiniteDimensional.Unital.Commutative_with_category'>

        sage: TFFC = T.Facade().FiniteDimensional().Commutative(); TFFC
        Category of facade finite dimensional commutative test objects
        sage: type(TFFC)
        <class 'sage.categories.category.JoinCategory_with_category'>
        sage: TFFC.super_categories()
        [Category of facade commutative test objects,
         Category of finite dimensional commutative test objects]

  static `meet`(categories)

    Returns the meet of a list of categories

    INPUT:

    - `categories` - a non empty list (or iterable) of categories

    See also

    `__or__()` for a shortcut

    EXAMPLES:

        sage: Category.meet([Algebras(ZZ), Algebras(QQ), Groups()])
        Category of monoids

    That meet of an empty list should be a category which is a subcategory of all categories, which does not make practical sense:

        sage: Category.meet([])
        Traceback (most recent call last):
        ...
        ValueError: The meet of an empty list of categories is not implemented

  `morphism_class`()

    A common super class for all morphisms between parents in this category (and its subcategories).

    This class contains the methods defined in the nested class `self.MorphismMethods` (if it exists), and has as bases the morphims classes of the super categories of `self`.

    See also

    - `parent_class()`, `element_class()`
    - `Category` for details

    EXAMPLES:

        sage: C = Algebras(QQ).morphism_class; C
        <class 'sage.categories.algebras.Algebras.morphism_class'>
        sage: type(C)
        <class 'sage.structure.dynamic_class.DynamicMetaclass'>

  `or_subcategory`(category=None, join=False)

    Return `category` or `self` if `category` is `None`.

    INPUT:

    - `category` – a sub category of `self`, tuple/list thereof, or `None`
    - `join` – a boolean (default: `False`)

    OUTPUT:

    - a category

    EXAMPLES:

        sage: Monoids().or_subcategory(Groups())
        Category of groups
        sage: Monoids().or_subcategory(None)
        Category of monoids

    If category is a list/tuple, then a join category is returned:

        sage: Monoids().or_subcategory((CommutativeAdditiveMonoids(), Groups()))
        Join of Category of groups and Category of commutative additive monoids

    If `join` is `False`, an error if raised if category is not a subcategory of `self`:

        sage: Monoids().or_subcategory(EnumeratedSets())
        Traceback (most recent call last):
        ...
        AssertionError: Subcategory of `Category of enumerated sets` required; got `Category of monoids`

    Otherwise, the two categories are joined together:

        sage: Monoids().or_subcategory(EnumeratedSets(), join=True)
        Join of Category of monoids and Category of enumerated sets

  `parent_class`()

    A common super class for all parents in this category (and its subcategories).

    This class contains the methods defined in the nested class `self.ParentMethods` (if it exists), and has as bases the parent classes of the super categories of `self`.

    See also

    - `element_class()`, `morphism_class()`
    - `Category` for details

    EXAMPLES:

        sage: C = Algebras(QQ).parent_class; C
        <class 'sage.categories.algebras.Algebras.parent_class'>
        sage: type(C)
        <class 'sage.structure.dynamic_class.DynamicMetaclass'>

    By trac ticket #11935, some categories share their parent classes. For example, the parent class of an algebra only depends on the category of the base ring. A typical example is the category of algebras over a finite field versus algebras over a non-field:

        sage: Algebras(GF(7)).parent_class is Algebras(GF(5)).parent_class
        True
        sage: Algebras(QQ).parent_class is Algebras(ZZ).parent_class
        False
        sage: Algebras(ZZ['t']).parent_class is Algebras(ZZ['t','x']).parent_class
        True

    See `CategoryWithParameters` for an abstract base class for categories that depend on parameters, even though the parent and element classes only depend on the parent or element classes of its super categories. It is used in `Bimodules`, `Category_over_base` and `sage.categories.category.JoinCategory`.

  `required_methods`()

    Returns the methods that are required and optional for parents in this category and their elements.

    EXAMPLES:

        sage: Algebras(QQ).required_methods()
        {'element': {'optional': ['_add_', '_mul_'], 'required': ['__nonzero__']},
         'parent': {'optional': ['algebra_generators'], 'required': ['__contains__']}}

  `structure`()

    Return the structure `self` is endowed with.

    This method returns the structure that morphisms in this category shall be preserving. For example, it tells that a ring is a set endowed with a structure of both a unital magma and an additive unital magma which satisfies some further axioms. In other words, a ring morphism is a function that preserves the unital magma and additive unital magma structure.

    In practice, this returns the collection of all the super categories of `self` that define some additional structure, as a frozen set.

    EXAMPLES:

        sage: Objects().structure()
        frozenset()

        sage: def structure(C):
        ....:     return Category._sort(C.structure())

        sage: structure(Sets())
        (Category of sets, Category of sets with partial maps)
        sage: structure(Magmas())
        (Category of magmas, Category of sets, Category of sets with partial maps)

    In the following example, we only list the smallest structure categories to get a more readable output:

        sage: def structure(C):
        ....:     return Category._sort_uniq(C.structure())

        sage: structure(Magmas())
        (Category of magmas,)
        sage: structure(Rings())
        (Category of unital magmas, Category of additive unital additive magmas)
        sage: structure(Fields())
        (Category of euclidean domains,)
        sage: structure(Algebras(QQ))
        (Category of unital magmas,
         Category of right modules over Rational Field,
         Category of left modules over Rational Field)
        sage: structure(HopfAlgebras(QQ).Graded().WithBasis().Connected())
        (Category of hopf algebras over Rational Field,
         Category of graded modules over Rational Field)

    This method is used in `is_full_subcategory()` for deciding whether a category is a full subcategory of some other category, and for documentation purposes. It is computed recursively from the result of `additional_structure()` on the super categories of `self`.

  `subcategory_class`()

    A common superclass for all subcategories of this category (including this one).

    This class derives from `D.subcategory_class` for each super category \(D\) of `self`, and includes all the methods from the nested class `self.SubcategoryMethods`, if it exists.

    See also

    - trac ticket #12895
    - `parent_class()`
    - `element_class()`
    - `_make_named_class()`

    EXAMPLES:

        sage: cls = Rings().subcategory_class; cls
        <class 'sage.categories.rings.Rings.subcategory_class'>
        sage: type(cls)
        <class 'sage.structure.dynamic_class.DynamicMetaclass'>

    `Rings()` is an instance of this class, as well as all its subcategories:

        sage: isinstance(Rings(), cls)
        True
        sage: isinstance(AlgebrasWithBasis(QQ), cls)
        True

    TESTS:

        sage: cls = Algebras(QQ).subcategory_class; cls
        <class 'sage.categories.algebras.Algebras.subcategory_class'>
        sage: type(cls)
        <class 'sage.structure.dynamic_class.DynamicMetaclass'>

  `super_categories`()

    Return the immediate super categories of `self`.

    OUTPUT:

    - a duplicate-free list of categories.

    Every category should implement this method.

    EXAMPLES:

        sage: Groups().super_categories()
        [Category of monoids, Category of inverse unital magmas]
        sage: Objects().super_categories()
        []

    Note

    Since trac ticket #10963, the order of the categories in the result is irrelevant. For details, see On the order of super categories.

    Note

    Whenever speed matters, developers are advised to use the lazy attribute `_super_categories()` instead of calling this method.

class `sage.categories.category.``CategoryWithParameters`(s=None)

  Bases: `sage.categories.category.Category`

  A parametrized category whose parent/element classes depend only on its super categories.

  Many categories in Sage are parametrized, like `C = Algebras(K)` which takes a base ring as parameter. In many cases, however, the operations provided by `C` in the parent class and element class depend only on the super categories of `C`. For example, the vector space operations are provided if and only if `K` is a field, since `VectorSpaces(K)` is a super category of `C` only in that case. In such cases, and as an optimization (see trac ticket #11935), we want to use the same parent and element class for all fields. This is the purpose of this abstract class.

  Currently, `JoinCategory`, `Category_over_base` and `Bimodules` inherit from this class.

  EXAMPLES:

      sage: C1 = Algebras(GF(5))
      sage: C2 = Algebras(GF(3))
      sage: C3 = Algebras(ZZ)
      sage: from sage.categories.category import CategoryWithParameters
      sage: isinstance(C1, CategoryWithParameters)
      True
      sage: C1.parent_class is C2.parent_class
      True
      sage: C1.parent_class is C3.parent_class
      False

  `_make_named_class`(name, method_provider, cache=False, **options)

    Return the parent/element/... class of `self`.

    INPUT:

    - `name` – a string; the name of the class as an attribute of `self`
    - `method_provider` – a string; the name of an attribute of `self` that provides methods for the new class (in addition to what comes from the super categories)
    - `**options` – other named options to pass down to `Category._make_named_class()`.

    ASSUMPTION:

    It is assumed that this method is only called from a lazy attribute whose name coincides with the given `name`.

    OUTPUT:

    A dynamic class that has the corresponding named classes of the super categories of `self` as bases and contains the methods provided by `getattr(self, method_provider)`.

    Note

    This method overrides `Category._make_named_class()` so that the returned class only depends on the corresponding named classes of the super categories and on the provided methods. This allows for sharing the named classes across closely related categories providing the same code to their parents, elements and so on.

    EXAMPLES:

    The categories of bimodules over the fields `CC` or `RR` provide the same methods to their parents and elements:

        sage: Bimodules(ZZ,RR).parent_class is Bimodules(ZZ,RDF).parent_class #indirect doctest
        True
        sage: Bimodules(CC,ZZ).element_class is Bimodules(RR,ZZ).element_class
        True

    On the other hand, modules over a field have more methods than modules over a ring:

        sage: Modules(GF(3)).parent_class is Modules(ZZ).parent_class
        False
        sage: Modules(GF(3)).element_class is Modules(ZZ).element_class
        False

    For a more subtle example, one could possibly share the classes for `GF(3)` and `GF(2^3, 'x')`, but this is not currently the case:

        sage: Modules(GF(3)).parent_class is Modules(GF(2^3,'x')).parent_class
        False

    This is because those two fields do not have the exact same category:

        sage: GF(3).category()
        Join of Category of finite fields and Category of subquotients of monoids and Category of quotients of semigroups
        sage: GF(2^3,'x').category()
        Category of finite fields

    Similarly for `QQ` and `RR`:

        sage: QQ.category()
        Category of quotient fields
        sage: RR.category()
        Category of fields
        sage: Modules(QQ).parent_class is Modules(RR).parent_class
        False

    Some other cases where one could potentially share those classes:

        sage: Modules(GF(3),dispatch=False).parent_class  is Modules(ZZ).parent_class
        False
        sage: Modules(GF(3),dispatch=False).element_class is Modules(ZZ).element_class
        False

    TESTS:

        sage: PC = Algebras(QQ).parent_class; PC   # indirect doctest
        <class 'sage.categories.algebras.Algebras.parent_class'>
        sage: type(PC)
        <class 'sage.structure.dynamic_class.DynamicMetaclass'>
        sage: PC.__bases__
        (<class 'sage.categories.rings.Rings.parent_class'>,
         <class 'sage.categories.associative_algebras.AssociativeAlgebras.parent_class'>,
         <class 'sage.categories.unital_algebras.UnitalAlgebras.parent_class'>)
        sage: loads(dumps(PC)) is PC
        True

class `sage.categories.category.``JoinCategory`(super_categories, **kwds)

  Bases: `sage.categories.category.CategoryWithParameters`

  A class for joins of several categories. Do not use directly; see Category.join instead.

  EXAMPLES:

      sage: from sage.categories.category import JoinCategory
      sage: J = JoinCategory((Groups(), CommutativeAdditiveMonoids())); J
      Join of Category of groups and Category of commutative additive monoids
      sage: J.super_categories()
      [Category of groups, Category of commutative additive monoids]
      sage: J.all_super_categories(proper=True)
      [Category of groups, ..., Category of magmas,
       Category of commutative additive monoids, ..., Category of additive magmas,
       Category of sets, Category of sets with partial maps, Category of objects]

  By trac ticket #11935, join categories and categories over base rings inherit from `CategoryWithParameters`. This allows for sharing parent and element classes between similar categories. For example, since group algebras belong to a join category and since the underlying implementation is the same for all finite fields, we have:

      sage: G = SymmetricGroup(10)
      sage: A3 = G.algebra(GF(3))
      sage: A5 = G.algebra(GF(5))
      sage: type(A3.category())
      <class 'sage.categories.category.JoinCategory_with_category'>
      sage: type(A3) is type(A5)
      True

  `_repr_object_names`()

    Return the name of the objects of this category.

    See also

    `Category._repr_object_names()`, `_repr_()`, `_without_axioms()`

    EXAMPLES:

        sage: Groups().Finite().Commutative()._repr_(as_join=True)
        'Join of Category of finite groups and Category of commutative groups'
        sage: Groups().Finite().Commutative()._repr_object_names()
        'finite commutative groups'

    This uses `_without_axioms()` which may fail if this category is not obtained by adjoining axioms to some super categories:

        sage: Category.join((Groups(), CommutativeAdditiveMonoids()))._repr_object_names()
        Traceback (most recent call last):
        ...
        ValueError: This join category isn't built by adding axioms to a single category

  `_repr_`(as_join=False)

    Print representation.

    INPUT:

    - `as_join` – a boolean (default: False)

    EXAMPLES:

        sage: Category.join((Groups(), CommutativeAdditiveMonoids())) #indirect doctest
        Join of Category of groups and Category of commutative additive monoids

    By default, when a join category is built from category by adjoining axioms, a nice name is printed out:

        sage: Groups().Facade().Finite()
        Category of facade finite groups

    But this is in fact really a join category:

        sage: Groups().Facade().Finite()._repr_(as_join = True)
        'Join of Category of finite groups and Category of facade sets'

    The rationale is to make it more readable, and hide the technical details of how this category is constructed internally, especially since this construction is likely to change over time when new axiom categories are implemented.

    This join category may possibly be obtained by adding axioms to different categories; so the result is not guaranteed to be unique; when this is not the case the first found is used.

    See also

    `Category._repr_()`, `_repr_object_names()`

    TESTS:

        sage: Category.join((Sets().Facade(), Groups()))
        Category of facade groups

  `_without_axioms`(named=False)

    When adjoining axioms to a category, one often gets a join category; this method tries to recover the original category from this join category.

    INPUT:

    - `named` – a boolean (default: `False`)

    See `Category._without_axioms()` for the description of the `named` parameter.

    EXAMPLES:

        sage: C = Category.join([Monoids(), Posets()]).Finite()
        sage: C._repr_(as_join=True)
        'Join of Category of finite monoids and Category of finite posets'
        sage: C._without_axioms()
        Traceback (most recent call last):
        ...
        ValueError: This join category isn't built by adding axioms to a single category
        sage: C = Monoids().Infinite()
        sage: C._repr_(as_join=True)
        'Join of Category of monoids and Category of infinite sets'
        sage: C._without_axioms()
        Category of magmas
        sage: C._without_axioms(named=True)
        Category of monoids

    TESTS:

    `C` is in fact a join category:

        sage: from sage.categories.category import JoinCategory
        sage: isinstance(C, JoinCategory)
        True

  `additional_structure`()

    Return `None`.

    Indeed, a join category defines no additional structure.

    See also

    `Category.additional_structure()`

    EXAMPLES:

        sage: Modules(ZZ).additional_structure()

  `is_subcategory`(C)

    Check whether this join category is subcategory of another category `C`.

    EXAMPLES:

        sage: Category.join([Rings(),Modules(QQ)]).is_subcategory(Category.join([Rngs(),Bimodules(QQ,QQ)]))
        True

  `super_categories`()

    Returns the immediate super categories, as per `Category.super_categories()`.

    EXAMPLES:

        sage: from sage.categories.category import JoinCategory
        sage: JoinCategory((Semigroups(), FiniteEnumeratedSets())).super_categories()
        [Category of semigroups, Category of finite enumerated sets]

`sage.categories.category.``category_graph`(categories=None)

  Return the graph of the categories in Sage.

  INPUT:

  - `categories` – a list (or iterable) of categories

  If `categories` is specified, then the graph contains the mentioned categories together with all their super categories. Otherwise the graph contains (an instance of) each category in `sage.categories.all` (e.g. `Algebras(QQ)` for algebras).

  For readability, the names of the category are shortened.

  Todo

  Further remove the base ring (see also trac ticket #15801).

  EXAMPLES:

      sage: G = sage.categories.category.category_graph(categories = [Groups()])
      sage: G.vertices()
      ['groups', 'inverse unital magmas', 'magmas', 'monoids', 'objects',
       'semigroups', 'sets', 'sets with partial maps', 'unital magmas']
      sage: G.plot()
      Graphics object consisting of 20 graphics primitives

      sage: sage.categories.category.category_graph().plot()
      Graphics object consisting of 312 graphics primitives

`sage.categories.category.``category_sample`()

  Return a sample of categories.

  It is constructed by looking for all concrete category classes declared in `sage.categories.all`, calling `Category.an_instance()` on those and taking all their super categories.

  EXAMPLES:

      sage: from sage.categories.category import category_sample
      sage: sorted(category_sample(), key=str)
      [Category of G-sets for Symmetric group of order 8! as a permutation group,
       Category of Hecke modules over Rational Field,
       Category of additive magmas, ...,
       Category of fields, ...,
       Category of graded hopf algebras with basis over Rational Field, ...,
       Category of modular abelian varieties over Rational Field, ...,
       Category of simplicial complexes, ...,
       Category of vector spaces over Rational Field, ...,
       Category of weyl groups,...

`sage.categories.category.``is_Category`(x)

  Returns True if x is a category.

  EXAMPLES:

      sage: sage.categories.category.is_Category(CommutativeAdditiveSemigroups())
      True
      sage: sage.categories.category.is_Category(ZZ)
      False

### Navigation

- index
- modules |
- next |
- previous |
- Category Theory »