Sage: Ticket #22962: Toward singleton categories: subcategories of Modules
https://trac.sagemath.org/ticket/22962
<p>
Categories over base ring like <code>Algebras(QQ)</code> have been a regular
source of issues. A series of tickets culminating in <a class="closed ticket" href="https://trac.sagemath.org/ticket/15801" title="enhancement: Categories over a base ring category (closed: fixed)">#15801</a> improved
quite some the situation. Yet <a class="needs_work ticket" href="https://trac.sagemath.org/ticket/15475" title="defect: Reenable broken doctests in #15473 and #15476 when #10963 is merged (needs_work)">#15475</a>, <a class="closed ticket" href="https://trac.sagemath.org/ticket/20896" title="defect: calling GF(2)**2 breaks CyclicPermutationGroup(10).algebra(GF(5)) (closed: worksforme)">#20896</a>, <a class="closed ticket" href="https://trac.sagemath.org/ticket/20469" title="enhancement: Implement Ariki-Koike algebras (closed: fixed)">#20469</a> show that this is
not the end.
</p>
<p>
In this ticket, we explore a plan first proposed at
<a class="ext-link" href="https://trac.sagemath.org/ticket/20896#comment:3"><span class="icon"></span>https://trac.sagemath.org/ticket/20896#comment:3</a>.
</p>
<h2 id="Issueanalysis">Issue analysis</h2>
<p>
The issue in <a class="closed ticket" href="https://trac.sagemath.org/ticket/20896" title="defect: calling GF(2)**2 breaks CyclicPermutationGroup(10).algebra(GF(5)) (closed: worksforme)">#20896</a> is that, by design, <code>A3=Algebras(GF(3))</code> and
<code>A5=Algebras(GF(5))</code> 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 <code>A3</code> and <code>A5</code> 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 <code>GF(5)</code> and <code>GF(3)</code> we are likely to hit an
inconsistency at some point.
</p>
<h2 id="Aim:towardsingletoncategories">Aim: toward singleton categories</h2>
<p>
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.
</p>
<p>
Let's see what this means for categories over a ring like
<code>Algebras</code>. 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.
</p>
<p>
Instead, to provide generic code, tests, ... we want a collection of
singleton categories like:
</p>
<ul><li>modules over rings
</li><li>vector spaces (e.g. modules over fields)
</li><li>polyonials over PIDs
</li></ul><p>
After all, the code provided in e.g. <code>ParentMethods</code> 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).
</p>
<p>
Of course, there can be cases, e.g. for typechecking, where it's handy
to model some finer category like <code>Algebras(GF(3))</code>. However such
categories should really be implemented as thin wrappers on top of the
previous ones.
</p>
<p>
We had already discussed approaches in this direction, in particular
with Simon. <a class="closed ticket" href="https://trac.sagemath.org/ticket/15801" title="enhancement: Categories over a base ring category (closed: fixed)">#15801</a> was a first step, but remaing issues show that this
is not enough.
</p>
<h2 id="Propositionofdesign">Proposition of design</h2>
<p>
We keep our current <code>Category_over_base_ring</code>'s (<code>Modules</code>,
<code>Algebras</code>, <code>HopfAlgebras</code>, ...). However they now are all singleton
categories, meant to be called as:
</p>
<ul><li><code>Modules()</code> -> Modules over rings
</li><li><code>Algebras()</code> -> Algebras over rings
</li></ul><p>
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. <code>VectorSpaces()</code> would be <code>Modules().OverFields()</code>. And we could
eventually have categories like <code>Modules().OverPIDs()</code>,
<code>Polynomials().OverPIDs()</code>.
</p>
<p>
Now what happens if one calls <code>Algebras(QQ)</code>?
</p>
<p>
As a syntactical sugar, this returns the join <code>Algebras() & Modules().Over(QQ)</code>.
</p>
<p>
Fine, now what's this latter gadget? It's merely a place holder with two roles:
</p>
<ul><li>Store the information that the base ring is <code>QQ</code>
</li></ul><ul><li>Investigate, upon construction, the properties of the base ring and
set axioms appropriately (e.g. in this case <code>OverFields</code>).
</li></ul><h2 id="Implementationdetails">Implementation details</h2>
<ul><li>In effect, <code>Modules().Over(QQ)</code> 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
<code>Algebras() & Modules().Over(QQ)</code>
to be printed as <code>algebras over QQ</code>).
</li></ul><ul><li>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.
</li></ul><ul><li>Some care will be needed for subcategory and containment testing.
</li></ul><h2 id="Prosconspointstobediscussed">Pros, cons, points to be discussed</h2>
<p>
Pros:
</p>
<ul><li>Constructing <code>Algebras(QQ)</code> does not require constructing any of the
super categories <code>Modules(QQ)</code> and such. Instead, this just requires
<code>Modules()</code>, and the like which most likely have already been
constructed.
</li></ul><ul><li>There is no more need to fiddle with class creation as we used to
do, and to have this special hack which causes <code>Modules(QQ)</code> to
return <code>VectorSpaces(QQ)</code>. This just uses the standard
infrastructure for axioms, joins, etc.
</li></ul><ul><li>It's more explicit about the level of generality of the
code. <code>Algebras().OverFields()</code> provide codes valid for any algebra
over a field.
</li></ul><ul><li>This makes it easier for buiding static documentation: there is a
canonical instance for <code>Algebras()</code> which Sphinx could inspect.
</li></ul><p>
Cons:
</p>
<ul><li>The hierarchy of axioms <a class="missing wiki">OverFields?</a>, OverPIDs, ... will somewhat
duplicate the existing hierarchy of axioms about rings. If we start
having many of them, that could become cumbersome.
</li></ul><ul><li>In a join like <code>Algebras() & ModulesOver(QQ)</code>, 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.
</li></ul><ul><li><code>C=Algebras().Over(QQ)</code> should definitely be a full subcategory of
<code>Algebras()</code>. But this means that <code>Modules().Over(QQ)</code> won't appear
in <code>C.structure()</code>. The base field won't appear either in
<code>C.axioms()</code>. Therefore <code>C</code> cannot be reconstructed from its
structure and axioms as we are generally aiming for. Maybe this is
really calling for <code>Over(QQ)</code> to be an axiom.
</li></ul><ul><li>This should be relatively quick and straightforward to implement and
fully backward compatible. And we have a lot of tests.
</li></ul><p>
Points to be debated:
</p>
<ul><li>At some point, we will want to support semirings. Should we support
them right away by having <code>Modules()</code> be the category of modules
over a semiring? Same thing for <code>Algebras()</code>, ... 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.
</li></ul><ul><li>What name for the axioms? <code>OverField</code>, or <code>OverFields</code>?
</li></ul><ul><li>We want some syntax that, given e.g. <code>QQ</code> as input, returns
<code>Algebras().OverFields()</code>. The typical use case is within the
constructor of a parent that takes a base ring <code>K</code> as input, and
wants to use the richest category possible based on the properties
of <code>K</code>, but does not specifically care that <code>K</code> be stored in the
category.
</li></ul><blockquote>
<p>
Maybe something like <code>Algebras().Over(QQ, store_base_ring=False)</code>.
</p>
</blockquote>
<blockquote>
<p>
We want this syntax to be as simple as possible, to encourage using
it whenever there is no specific reason to do otherwise.
</p>
</blockquote>
<p>
[1] <a class="ext-link" href="https://github.com/nthiery/sage-gap-semantic-interface"><span class="icon"></span>https://github.com/nthiery/sage-gap-semantic-interface</a>
</p>
en-usSagehttps://trac.sagemath.org/chrome/site/logo_sagemath_trac.png
https://trac.sagemath.org/ticket/22962
Trac 1.1.6nthieryTue, 09 May 2017 00:54:09 GMT
https://trac.sagemath.org/ticket/22962#comment:1
https://trac.sagemath.org/ticket/22962#comment:1
<p>
I am planning to work on this in the coming days.
</p>
TicketjdemeyerMon, 10 Jul 2017 12:07:01 GMT
https://trac.sagemath.org/ticket/22962#comment:2
https://trac.sagemath.org/ticket/22962#comment:2
<p>
Replying to <a class="new ticket" href="https://trac.sagemath.org/ticket/22962" title="enhancement: Toward singleton categories: subcategories of Modules (new)">nthiery</a>:
</p>
<blockquote class="citation">
<ul><li>What name for the axioms? <code>OverField</code>, or <code>OverFields</code>?
</li></ul></blockquote>
<p>
Why not <code>Over(Fields())</code>?
</p>
TicketnthieryMon, 10 Jul 2017 14:16:58 GMT
https://trac.sagemath.org/ticket/22962#comment:3
https://trac.sagemath.org/ticket/22962#comment:3
<p>
Hi Jeroen,
</p>
<p>
Replying to <a class="ticket" href="https://trac.sagemath.org/ticket/22962#comment:2" title="Comment 2">jdemeyer</a>:
</p>
<blockquote class="citation">
<p>
Replying to <a class="new ticket" href="https://trac.sagemath.org/ticket/22962" title="enhancement: Toward singleton categories: subcategories of Modules (new)">nthiery</a>:
</p>
<blockquote class="citation">
<ul><li>What name for the axioms? <code>OverField</code>, or <code>OverFields</code>?
</li></ul></blockquote>
<p>
Why not <code>Over(Fields())</code>?
</p>
</blockquote>
<p>
I would love it :-)
</p>
<p>
And we certainly could implement some idiom:
</p>
<pre class="wiki"> sage: C = Algebras()
sage: C.Over(Fields())
</pre><p>
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.
</p>
<pre class="wiki"> class Algebras:
class OverFields(CategoryWithAxiom):
class ParentMethods:
....
</pre><p>
We could kind of hide this with some mangling (e.g. calling the class <code>_OverFields</code> and using <a class="needs_work ticket" href="https://trac.sagemath.org/ticket/22965" title="enhancement: Refactor axioms (needs_work)">#22965</a> to have the axiom be printed as <code>Over(Fields())</code>). However, at this stage, this feels like adding one layer of complexity. I'd rather keep things "simple".
</p>
TicketpbruinFri, 20 Mar 2020 07:40:12 GMT
https://trac.sagemath.org/ticket/22962#comment:4
https://trac.sagemath.org/ticket/22962#comment:4
<p>
Hopefully this would also solve things like <a class="new ticket" href="https://trac.sagemath.org/ticket/29374" title="defect: Modules(Algebras(Rings())) should be a subcategory of Modules(Rings()) (new)">#29374</a>.
</p>
Ticket