Opened 5 years ago

Closed 17 months ago

#20896 closed defect (worksforme)

calling GF(2)**2 breaks CyclicPermutationGroup(10).algebra(GF(5))

Reported by: dimpase Owned by:
Priority: major Milestone: sage-duplicate/invalid/wontfix
Component: categories Keywords:
Cc: klee, nthiery Merged in:
Authors: Reviewers:
Report Upstream: N/A Work issues:
Branch: Commit:
Dependencies: Stopgaps:

Status badges

Description (last modified by dimpase)

As reported on sage-devel this is fine:

sage: CyclicPermutationGroup(10).algebra(GF(5))
Group algebra of Cyclic group of order 10 as a permutation group over Finite Field of size 5
sage: GF(2)^2
Vector space of dimension 2 over Finite Field of size 2

now, start a new Sage session:

sage: GF(2)^2
Vector space of dimension 2 over Finite Field of size 2
sage: CyclicPermutationGroup(10).algebra(GF(5))
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
[...]
TypeError: Cannot create a consistent method resolution
order (MRO) for bases FiniteSets.subcategory_class, VectorSpaces.WithBasis.subcategory_class, FiniteDimensionalModulesWithBasis.subcategory_class

Change History (8)

comment:1 Changed 5 years ago by dimpase

  • Cc nthiery added
  • Description modified (diff)

Creatures from Sage Import Hell staring at you here...

comment:2 Changed 5 years ago by tscrim

See also #20460 and #15475.

comment:3 Changed 5 years ago by nthiery

Issue analysis

Scratching this itch and similar ones we have been getting, I have been pondering these last days about the handling of "over base ring" categories in Sage.

The issue 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 were idioms for this in Axiom and MuPAD which we could try to port 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

Last edited 5 years ago by nthiery (previous) (diff)

comment:4 Changed 5 years ago by tscrim

Something I've come across is that I have wanted to check category containment of objects (along with axioms), but with not necessarily knowing what the object's base ring is (or if it even has one), I couldn't get this to work easily. In particular, the category containment checking had trouble differentiating between when something was in Algebras(Rings()) and Algebras(ZZ)` IIRC. So I'm +1 for moving completely to singleton categories.

comment:5 Changed 17 months ago by pbruin

This seems to work fine in SageMath 9.1.beta8:

sage: GF(2)^2
Vector space of dimension 2 over Finite Field of size 2
sage: CyclicPermutationGroup(10).algebra(GF(5))
Algebra of Cyclic group of order 10 as a permutation group over Finite Field of size 5

comment:6 Changed 17 months ago by dimpase

  • Milestone changed from sage-7.3 to sage-duplicate/invalid/wontfix
  • Status changed from new to needs_review

time heals many things :-)

comment:7 Changed 17 months ago by klee

  • Status changed from needs_review to positive_review

comment:8 Changed 17 months ago by chapoton

  • Resolution set to worksforme
  • Status changed from positive_review to closed
Note: See TracTickets for help on using tickets.