Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Toward singleton categories: subcategories of Modules #22962

Open
nthiery opened this issue May 9, 2017 · 4 comments
Open

Toward singleton categories: subcategories of Modules #22962

nthiery opened this issue May 9, 2017 · 4 comments

Comments

@nthiery
Copy link
Contributor

nthiery commented May 9, 2017

Categories over base ring like Algebras(QQ) have been a regular
source of issues. A series of tickets culminating in #15801 improved
quite some the situation. Yet #15475, #20896, #20469 show that this is
not the end.

In this ticket, we explore a plan first proposed at
#20896 comment:3.

Issue analysis

The issue in #20896 is that, by design, A3=Algebras(GF(3)) and
A5=Algebras(GF(5)) share the same element/parent/... classes.
However the MRO for such classes is built to be consistent with a
total order on categories, and that total order is built dynamically
using little context; so hard to keep consistent. Hence the order we
get for A3 and A5 need not be the same, and the MRO basically depends
on which one has been built first. If one builds alternatively larger
and larger hierarchies for GF(5) and GF(3) we are likely to hit an
inconsistency at some point.

Aim: toward singleton categories

This, together with other stuff I do (e.g. [1]) with colleagues from
other systems (GAP, MMT, ...), finished to convince me that most of
our categories should really be singleton categories, and not be
parametrized.

Let's see what this means for categories over a ring like
Algebras. I originally followed the tradition of Axiom and MuPAD by
having them be systematically parametrized by the base ring. However
the series of issues we faced and are still facing shows that this
does not scale.

Instead, to provide generic code, tests, ... we want a collection of
singleton categories like:

  • modules over rings
  • vector spaces (e.g. modules over fields)
  • polyonials over PIDs

After all, the code provided in e.g. ParentMethods will always be
the same, regardless of the parameters of the category (well, that's
not perfectly true; there are in Axiom and MuPAD idioms enabling the
conditional definition of methods depending on the base ring; we could
try to port those idioms over).

Of course, there can be cases, e.g. for typechecking, where it's handy
to model some finer category like Algebras(GF(3)). However such
categories should really be implemented as thin wrappers on top of the
previous ones.

We had already discussed approaches in this direction, in particular
with Simon. #15801 was a first step, but remaing issues show that this
is not enough.

Proposition of design

We keep our current Category_over_base_ring's (Modules,
Algebras, HopfAlgebras, ...). However they now are all singleton
categories, meant to be called as:

  • Modules() -> Modules over rings
  • Algebras() -> Algebras over rings

Whenever some of the above category needs to be refined depending on
the properties on the base ring, we define some appropriate axiom.
E.g. VectorSpaces() would be Modules().OverFields(). And we could
eventually have categories like Modules().OverPIDs(),
Polynomials().OverPIDs().

Now what happens if one calls Algebras(QQ)?

As a syntactical sugar, this returns the join Algebras() & Modules().Over(QQ).

Fine, now what's this latter gadget? It's merely a place holder with two roles:

  • Store the information that the base ring is QQ

  • Investigate, upon construction, the properties of the base ring and
    set axioms appropriately (e.g. in this case OverFields).

Implementation details

  • In effect, Modules().Over(QQ) is pretty similar to a category with
    axiom. First in terms of syntax; also the handling of pretty
    printing will be of the same nature (we want the join
    Algebras() & Modules().Over(QQ)
    to be printed as algebras over QQ).

  • However, at this stage, we can't implement it directly using axioms
    since those are not parametrized. One option would be to generalize
    our axiom infrastructure to support parameters; however it's far
    from clear that we actually want to have this feature, and how it
    should be implemented. So I am inclined to not overengineer for now.

  • Some care will be needed for subcategory and containment testing.

Pros, cons, points to be discussed

Pros:

  • Constructing Algebras(QQ) does not require constructing any of the
    super categories Modules(QQ) and such. Instead, this just requires
    Modules(), and the like which most likely have already been
    constructed.

  • There is no more need to fiddle with class creation as we used to
    do, and to have this special hack which causes Modules(QQ) to
    return VectorSpaces(QQ). This just uses the standard
    infrastructure for axioms, joins, etc.

  • It's more explicit about the level of generality of the
    code. Algebras().OverFields() provide codes valid for any algebra
    over a field.

  • This makes it easier for buiding static documentation: there is a
    canonical instance for Algebras() which Sphinx could inspect.

Cons:

  • The hierarchy of axioms OverFields, OverPIDs, ... will somewhat
    duplicate the existing hierarchy of axioms about rings. If we start
    having many of them, that could become cumbersome.

  • In a join like Algebras() & ModulesOver(QQ), there is little
    control about whether the parent class for the former or the latter
    comes first. But that's no different than what happens for other
    axioms.

  • C=Algebras().Over(QQ) should definitely be a full subcategory of
    Algebras(). But this means that Modules().Over(QQ) won't appear
    in C.structure(). The base field won't appear either in
    C.axioms(). Therefore C cannot be reconstructed from its
    structure and axioms as we are generally aiming for. Maybe this is
    really calling for Over(QQ) to be an axiom.

  • This should be relatively quick and straightforward to implement and
    fully backward compatible. And we have a lot of tests.

Points to be debated:

  • At some point, we will want to support semirings. Should we support
    them right away by having Modules() be the category of modules
    over a semiring? Same thing for Algebras(), ... It feels like
    overkill for now, but might be annoying to change later. Also where
    does the road end? We may want to support even weaker structures at
    some point.

  • What name for the axioms? OverField, or OverFields?

  • We want some syntax that, given e.g. QQ as input, returns
    Algebras().OverFields(). The typical use case is within the
    constructor of a parent that takes a base ring K as input, and
    wants to use the richest category possible based on the properties
    of K, but does not specifically care that K be stored in the
    category.

    Maybe something like Algebras().Over(QQ, store_base_ring=False).

    We want this syntax to be as simple as possible, to encourage using
    it whenever there is no specific reason to do otherwise.

[1] https://github.com/nthiery/sage-gap-semantic-interface

CC: @tscrim @simon-king-jena

Component: categories

Issue created by migration from https://trac.sagemath.org/ticket/22962

@nthiery nthiery added this to the sage-8.0 milestone May 9, 2017
@nthiery
Copy link
Contributor Author

nthiery commented May 9, 2017

comment:1

I am planning to work on this in the coming days.

@jdemeyer
Copy link

Replying to @nthiery:

  • What name for the axioms? OverField, or OverFields?

Why not Over(Fields())?

@nthiery
Copy link
Contributor Author

nthiery commented Jul 10, 2017

comment:3

Hi Jeroen,

Replying to @jdemeyer:

Replying to @nthiery:

  • What name for the axioms? OverField, or OverFields?

Why not Over(Fields())?

I would love it :-)

And we certainly could implement some idiom:

    sage: C = Algebras()
    sage: C.Over(Fields())

However, with the current axiom infrastructure, we still need a name for the actual class holding the code for the corresponding category. That name has to be a string.

    class Algebras:
        class OverFields(CategoryWithAxiom):
            class ParentMethods:
                ....

We could kind of hide this with some mangling (e.g. calling the class _OverFields and using #22965 to have the axiom be printed as Over(Fields())). However, at this stage, this feels like adding one layer of complexity. I'd rather keep things "simple".

@pjbruin
Copy link
Contributor

pjbruin commented Mar 20, 2020

comment:4

Hopefully this would also solve things like #29374.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants