#11935: Make parent/element classes independent of base rings
------------------------------------------------------------------+---------
Reporter: SimonKing |
Owner:
Type: enhancement |
Status: needs_work
Priority: major |
Milestone: sage-5.10
Component: categories |
Resolution:
Keywords: parent class, element class, category | Work
issues:
Report Upstream: N/A |
Reviewers: Nicolas Thiery, Travis Scrimshaw
Authors: Simon King | Merged
in:
Dependencies: #9138, #11900, #11943, #12875, #12876, #12877 |
Stopgaps:
------------------------------------------------------------------+---------
Comment (by SimonKing):
Earlier today, I wrote a long reply, but my laptop's battery seems to be
damaged, and without a warning the computer shut down and the whole text
was lost. Bad.
Replying to [comment:100 nthiery]:
> - This makes the model simpler to explain: C.element_class contains
> code provided by C and its upper categories. Nothing else. The
> hierarchy of classes for parents / elements is perfectly parallel to
> that of categories.
OK. But at some point, we want to mix the abstract class with a concrete
class. For example, if P is a parent, we have `P.element_class`, which
mixes an abstract class `P.category().element_class` with a concrete class
`P.Element`.
> The logic in Hom is such that every homset is anyway constructed as an
> instance of the concrete class Homset or some of its subclasses
> (RingHomset, ...).
Exactly.
So, in your approach, where would this mix happen? Of course, if a homset
H is initialised as an object of, say, `Rings().hom_category()`, and if
the base class of H is a python class, then of course the class of H is
changed into a sub-class of `Rings().hom_category().parent_class`.
But the first problem arises if the base class of H is an extension class.
Then, `H.__class__` can't be overridden, and thus inheritance from the
abstract class is by the custom `__getattr__` of Parent, which is slow
compared with proper inheritance.
The second problem is in `Hom(X,Y,category)`. First `X._Hom_(Y,category)`
is attempted, but if this doesn't return anything useful, the ''abstract''
class `C.hom_category().parent_class` is instantiated.
{{{
H = category.hom_category().parent_class(X, Y, category = category)
}}}
But an abstract class should not be instantiated! This is exactly why I
thought it would be better to mix the abstract and concrete classes by
providing `C.hom_category().ParentMethods` with bases.
And even worse things happen in
`sage.categories.rings.Rings.HomCategory.ParentMethods.__new__`, which is
a very ugly hack that should be avoided IMHO.
If you don't like bases, what do you think of the following alternative
model? I try to be as close to `P.element_class` (P being a parent) as
possible.
Let C be a category. On the one hand, it shall be provided with a concrete
class `C.Homset` defaulting to `sage.categories.homset.Homset`, which
could be overridden with a more concrete sub-class such as
`sage.rings.homset.RingHomset_generic`. This corresponds to `P.Element`.
As we have discussed already, if S is a subcategory of C, then we would
not want that `S.Homset` is obtained from `C.Homset`, unless S is a
''full'' subcategory. But fortunately, when we set `Rings().Homset =
RingHomset_generic`, then `Algebras().Homset` would still default to
`Homset`, not `RingHomset_generic`.
On the other hand, we get an abstract class
`C.hom_category().parent_class`. This corresponds to
`P.category().element_class`.
I suggest that the concrete and abstract classes be mixed in a lazy
attribute `C.homset_class`, in the same way as the concrete and abstract
classes are mixed in `P.element_class`.
If I am not mistaken, we discussed this in one of my visits to Orsay. If I
recall correctly, the only concern has been improper inheritance: When we
have a non-full subcategory S of C, then `S.homset_class` should not
inherit from `C.homset_class`.
But this, I think, is something that can be solved by making
`S.hom_category().super_categories()` return the right thing. Namely, the
concrete class `S.Homset` is not inherited from `C.Homset` anyway, and the
abstract class ``S.hom_category().parent_class` will be fine if and only
if `S.hom_category().super_categories()` returns the right thing.
Final remark: In `Hom(X,Y,category)`, it would still be possible for
`X._Hom_(Y,category)` to do something special. But I believe that with the
model I described it will be possible in most cases to rely on the generic
(purely categorical) construction of the homset.
So, question: Do you think that this model is the way to go? It keeps
abstract and concrete classes neatly apart, it will reduce the need to
have custom `X._Hom_(...)`, and we could get rid of the hack with
`__new__`.
If you agree, then I'd say we try to finalise the patch here in the way
you suggested, namely without allowing base classes. And in a second step
(I think I have opened an according ticket 2 or 3 years ago) we could
implement the model I sketched.
> Could you point me to the exact problem that arised when you worked on
it?
No. It has been a while ago, and I lost track, I am afraid.
--
Ticket URL: <http://trac.sagemath.org/sage_trac/ticket/11935#comment:104>
Sage <http://www.sagemath.org>
Sage: Creating a Viable Open Source Alternative to Magma, Maple, Mathematica,
and MATLAB
--
You received this message because you are subscribed to the Google Groups
"sage-trac" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/sage-trac?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.