#10668 closed defect (fixed)
Refactor category support for morphisms (Hom is not a functorial construction!)
Reported by:  nthiery  Owned by:  nthiery 

Priority:  major  Milestone:  sage6.4 
Component:  categories  Keywords:  
Cc:  sagecombinat, SimonKing  Merged in:  
Authors:  Nicolas M. Thiéry  Reviewers:  Simon King 
Report Upstream:  N/A  Work issues:  
Branch:  a937938 (Commits)  Commit:  
Dependencies:  #16340  Stopgaps: 
Description (last modified by )
Before this ticket, Hom was implemented as a covariant functorial construction:
sage: Rings().hom_category() Category of hom sets in Category of rings sage: Rings().hom_category().super_categories() [Category of hom sets in Category of sets]
The intention was to model the fact that a morphism in a category is also a morphism in any super category, via the forgetful functor. With the example above, if A and B are rings, then a ring morphism phi: A>B is also a set morphism. However, at the level of parents, and as noted in the documentation of sage.category.HomCategory?, this is mathematically plain wrong: if A and B are rings, then Hom(A,B) in the category of rings does not coincide with Hom(A,B) in the category of sets.
I, Nicolas, take full blame for this misfeature; it was just the shortest route to implement some urgently needed features about morphisms, and still get that huge chunk of category code done.
Status of the current reimplementation:
 Add support for a MorphismsMethods? subclass, similar to ElementMethods? and ParentMethods?. If Cat is a category, then Cat.MorphismMethods? will provide generic methods for morphisms in Cat and in any subcategory. This can be achieved by:
 Building of a hierarchy of abstract classes Cat.morphism_class, similar to Cat.element_class and Cat.parent_class (10 lines of code; see Category.element_class).
 Having morphisms in Cat inherit from
Cat.morphism_class
; this is implemented by overridingParent.morphism_class
. An alternative would have been to overrideCategory.element_class
inHomsetsCategory.element_class
.
 Rename both HomCategory? and hom_category to Homsets, for consistency with the other constructions like CartesianProducts?, ...
 Fix HomCategory?: for Cat a category, the purpose of Cat.hom_category() shall be to provide mathematical information about its homsets (e.g. that a homset in the category of vector spaces is also a vector space). It is only a subcategory of the homsets of the full super categories of Cat (a homset in the category of finite groups is also a homset in the category of groups).
 Remove HomCategory? from the global namespace.
Potential further desirable features for a later ticket:
 If CatA is a subcategory of CatB, add automatic coercion (or just conversion?) from Hom(A,B, CatA) to Hom(A, B, CatB), modeling the appropriate forgetful functor. There are too many such coercions for them to be registered explicitly. So this probably needs to be implemented through a specific CatB._has_coerce_map_from(A) for homsets.
 Extend/use sage.categories.pushout to handle mixed morphism arithmetic (e.g. having the sum of an algebra morphism and a coalgebra morphism return a vector space morphism).
Attachments (1)
Change History (68)
comment:1 in reply to: ↑ description ; followup: ↓ 2 Changed 7 years ago by
comment:2 in reply to: ↑ 1 ; followup: ↓ 3 Changed 7 years ago by
 Description modified (diff)
Replying to SimonKing:
Replying to nthiery:
The intention was to model the fact that a morphism in a category is also a morphism in any super category, via the forgetful functor. With the example above, if A and B are rings, then a ring morphism phi: A>B is also a set morphism. However, at the level of parents, and as noted in the documentation of sage.category.HomCategory?, this is mathematically plain wrong: if A and B are rings, then Hom(A,B) in the category of rings does not coincide with Hom(A,B) in the category of sets.
I don't see why this should be wrong: Any ring homomorphism is a set homomorphism. Hence,
Hom_Rings()(A,B)
is a subset ofHom_Sets()(A,B)
 nobody claims that they coincide.
Very short answer for now: here the question is whether Hom_Rings()(A,B) is an object of Hom_Sets(). It's not. The point of VectorSpaces?().HomCategory?() is to encode mathematical information about the homsets, like the fact that Hom(A,B) is itself a vector space. We don't want this information to be applied to a homset of a subcategory (a homset in Algebras() being certainly not a vector space).
comment:3 in reply to: ↑ 2 Changed 7 years ago by
Replying to nthiery:
Very short answer for now: here the question is whether Hom_Rings()(A,B) is an object of Hom_Sets(). It's not. The point of VectorSpaces?().HomCategory?() is to encode mathematical information about the homsets, like the fact that Hom(A,B) is itself a vector space. We don't want this information to be applied to a homset of a subcategory (a homset in Algebras() being certainly not a vector space).
Right.
Nevertheless, I believe that an attribute like C.hom_structure
would be a convenient way to declare that the homsets of C
all have a particular structure (like Rings()
or VectorSpaces(C.base_ring())
) and that therefore C.hom_category()
is a subcategory of C.hom_structure
.
So, for now, the only detail that I have to withdraw from my proposal is that C.hom_structure
will not be influenced by X.hom_structure
for a supercategory X
of C
.
comment:4 followup: ↓ 5 Changed 7 years ago by
 Description modified (diff)
comment:5 in reply to: ↑ 4 Changed 7 years ago by
Replying to nthiery:
More later when I'll have recharged my battery ...
comment:6 in reply to: ↑ description ; followup: ↓ 7 Changed 7 years ago by
Replying to nthiery:
 Add support for a MorphismsMethods? subclass, similar to ElementMethods? and ParentMethods?. If Cat is a category, then Cat.MorphismMethods? will provide generic methods for morphisms in Cat and in any subcategory.
Not in a subcategory! Namely, if Cat
is the category of Fvectorspaces, then Cat.MorphismMethods
would include addition and skalar multiplication. But for a subcategory of Cat
, such as Falgebras, we don't want that, as you had pointed out.
This can be achieved by:
 Building of a hierarchy of abstract classes Cat.morphism_class, similar to Cat.element_class and Cat.parent_class (10 lines of code; see Category.element_class).
I don't see such hierarchy.
 Having morphisms in Cat inherit from Cat.morphism_class.
I really think the Cat.hom_structure
formalism that I suggested would be easier.
Any category would provide its own homstructure (and there would be no inheritance for subcategories), of course Objects()
being the default homstructure.
Then, homsets in Cat
would inherit from Cat.hom_structure.parent_class
, whereas morphisms in Cat
would inherit from Cat.hom_structure.element_class
.
In particular, there is no need to provide Cat.HomMethods
or Cat.MorphismMethods
. In fact, they are redundant: If you simply state that Cat.hom_structure
is VectorSpaces(QQ)
, then the morphisms already have the element methods of vector spaces, whereas in your approach you needed to restate (copyandpaste) them as Cat.MorphismMethods
.
comment:7 in reply to: ↑ 6 ; followup: ↓ 8 Changed 7 years ago by
Replying to SimonKing:
Not in a subcategory! Namely, if
Cat
is the category of Fvectorspaces, thenCat.MorphismMethods
would include addition and skalar multiplication. But for a subcategory ofCat
, such as Falgebras, we don't want that, as you had pointed out.
Of course addition should not be put in MorphismMethods?. On the other hand, there are a lot of generic operations on morphisms that pass down to subcategories, like inverting a morphism (say in the category of finite sets) or computing the matrix/the rank/the det/you_name_it of a morphism of finite dimensional vector space. It is essential to pass those generic methods down to subcategories.
That is not a vague though that popped up when I created this ticket, but a concrete feature that we have been longing for years and we could not implement in MuPAD (MuPAD categories did not handle morphisms) despite our many use cases.
I really think the
Cat.hom_structure
formalism that I suggested would be easier.
And I think mine is no more complicated, while being more consistent with the rest of the framework :)
It seems like most of the discussion comes from confusion and vagueness (and I take my share of the blame for that). So let's both write a little prototype to have a concrete ground to discuss on. We don't have to include the coercion / push_out part in this prototype since we agree on it. I can try to implement mine sometime next week.
In particular, there is no need to provide
Cat.HomMethods
orCat.MorphismMethods
. In fact, they are redundant: If you simply state thatCat.hom_structure
isVectorSpaces(QQ)
, then the morphisms already have the element methods of vector spaces, whereas in your approach you needed to restate (copyandpaste) them asCat.MorphismMethods
.
Cat.HomCategory?() will still use the standard super_categories() approach to state that it is a subcategory of VectorSpaces?(), and its elements will inherit from VectorSpaces?().element_class.
Cheers,
Nicolas
PS: by the way, I am wondering if we should be using Cat.objects() or Cat.Objects() (given that we already have Cat.Quotients(), Cat.Subobjects(), Cat.CartesianProducts?(), ...). Here, I am thinking about using the occasion to replace Cat.hom_category() by Cat.Homsets().
comment:8 in reply to: ↑ 7 ; followup: ↓ 9 Changed 7 years ago by
Replying to nthiery:
Replying to SimonKing:
Not in a subcategory! Namely, if
Cat
is the category of Fvectorspaces, thenCat.MorphismMethods
would include addition and skalar multiplication. But for a subcategory ofCat
, such as Falgebras, we don't want that, as you had pointed out.Of course addition should not be put in MorphismMethods?. On the other hand, there are a lot of generic operations on morphisms that pass down to subcategories, like inverting a morphism (say in the category of finite sets) or computing the matrix/the rank/the det/you_name_it of a morphism of finite dimensional vector space. It is essential to pass those generic methods down to subcategories.
I see. Yes, for those kind of methods, your approach makes very much sense.
But what would actually prevent us from doing both? Our two approaches are good for different things, and they are orthogonal to each other. If I understand correctly, you suggest that there should be Cat.morphism_class
from which morphisms inherit, analogous to Cat.element_class
, thereby getting "hereditary" (to subcategories) methods. I suggest that Cat
should have an attribute that allows Cat.hom_category()
to assign the correct category to the homset category (hence, Cat.hom_category().is_subcategory(Cat.hom_structure)
), so that homomorphism would inherit from Cat.hom_structure.element_class
(by the existing framework  hence, my suggestion is indeed very consistent with with the existing framework :).
Is there any reason to not have a double inheritance from Cat.morphism_class
and Cat.hom_structure.element_class
(Cat.hom_structure
being a category)?
So let's both write a little prototype to have a concrete ground to discuss on. We don't have to include the coercion / push_out part in this prototype since we agree on it. I can try to implement mine sometime next week.
OK.
Cat.HomCategory?() will still use the standard super_categories() approach to state that it is a subcategory of VectorSpaces?(), and its elements will inherit from VectorSpaces?().element_class.
OK, this is what I suggested above: One needs to introduce a standard mechanism to declare the category which Cat.hom_category()
is subcategory of.
comment:9 in reply to: ↑ 8 ; followup: ↓ 10 Changed 7 years ago by
But what would actually prevent us from doing both?
Ah, good, we now fund the point were we did not understand each other. The plan is definitely to do both! That is have inheritance from Cat.morphism_class and Cat.hom_category().element_class.
OK, this is what I suggested above: One needs to introduce a standard mechanism to declare the category which
Cat.hom_category()
is subcategory of.
And that's a second misunderstanding: this mechanism already exists, and I am not planning to remove it (though the syntax might change a tiny bit; we probably don't need the extra_super_categories thingy, and just use super_categories.
What do you think of using the occasion to rename Cat.hom_category() into Cat.Homsets(), for consistency with Cat.Quotients() and the like?
Cheers,
Nicolas
comment:10 in reply to: ↑ 9 Changed 7 years ago by
Replying to nthiery:
OK, this is what I suggested above: One needs to introduce a standard mechanism to declare the category which
Cat.hom_category()
is subcategory of.And that's a second misunderstanding: this mechanism already exists, and I am not planning to remove it (though the syntax might change a tiny bit; we probably don't need the extra_super_categories thingy, and just use super_categories.
What mechanism do you mean? I am of course aware of the extra_super_category
method  but sage.categories.category.HomCategory.extra_super_category()
returns []
, and sage.categories.category.HomCategory.super_categories()
returns stuff that we don't want (namely C.hom_category()
for all C
in self.base_category.super_categories()
).
Of course, it would suffice to make VectorSpaces(QQ).hom_category().extra_super_categories()
return [VectorSpaces(QQ)]
. But this would currently require to introduce a custom HomCategory
class for VectorSpaces
that overrides the method of the HomCategory
base class. This is not nice and should be simplified.
What I plan is: Remove inheritance of the homcategories of the supercategories of the basecategory from sage.categories.category.HomCategory.super_categories()
; it should basically return self.extra_super_categories()+[Sets()]
. Moreover, define sage.categories.category.HomCategory.extra_super_categories()
like this:
def extra_super_categories(self): try: return [self.base_category.hom_structure] except AttributeError: return []
Then, in the initmethod of the category of vector spaces, one would simply add the line
self.hom_structure = self
Similarly (I hope that I am not confusing things now), one would add the line
self.hom_structure = LeftModules(self.base_ring())
to the init method of right modules; and self.hom_structure = RightModules(self.base_ring())
for left modules, and so on. That seems easier than defining a whole class HomCategory
for LeftModules
.
What do you think of using the occasion to rename Cat.hom_category() into Cat.Homsets(), for consistency with Cat.Quotients() and the like?
Personally, I don't like uppercase method names, and I remember that it is officially recommended to avoid capital letters in Python method or function or module names, whereas upper case is recommended to use for classes (but I do not remember where I was reading that recommendation).
Best regards,
Simon
comment:11 followup: ↓ 12 Changed 7 years ago by
A technical question:
For things to work, it is needed that Fields().hom_category().parent_class
inherits from Rings().hom_category().parent_class
.
I thought that the inheritance would be provided by the category framework, if we have Fields().hom_category().is_subcategory(Rings().hom_category())
(which, I guess, is mathematically correct). Unfortunately, even though I arranged things so that indeed Fields().hom_category().is_subcategory(Rings().hom_category())
, I still get no inheritance of the parent classes.
So, how can one inherit the parent class of a supercategory?
comment:12 in reply to: ↑ 11 Changed 7 years ago by
Replying to SimonKing:
A technical question:
For things to work, it is needed that
Fields().hom_category().parent_class
inherits fromRings().hom_category().parent_class
.
Sorry for asking: It seems to work. I misinterpreted an error message.
comment:13 followup: ↓ 14 Changed 7 years ago by
I wonder whether it wouldn't be better to build upon #10667. There, amongst other things, I try to separate CategoryObject
from SageObject
and remove some inappropriate category stuff from elements and morphisms. I think that this part of #10667 could help me to implement my approach.
I suggest that I prepare my patch on top of #10667; you can of course do differently with the implementation of your approach.
comment:14 in reply to: ↑ 13 Changed 7 years ago by
Replying to SimonKing:
I wonder whether it wouldn't be better to build upon #10667. There, amongst other things, I try to separate
CategoryObject
fromSageObject
and remove some inappropriate category stuff from elements and morphisms. I think that this part of #10667 could help me to implement my approach.I suggest that I prepare my patch on top of #10667; you can of course do differently with the implementation of your approach.
Sure, please take the easiest route for you! #10667 is already large enough, and I see the point of not introducing yet another dependency :)
Cheers,
comment:15 Changed 7 years ago by
I just uploaded a preliminary patch, implementing my approach. The patch isn't finished (lacking doc tests), but is ready for discussion. It depends on #10667 (though it might apply with some noise without #10667  test, if you like).
Features:
Structure of hom sets
As I announced, I introduced an attribute for categories C
that determines a category which C.hom_category()
is subcategory of. I call this attribute C.hom_structure
:
# This was already fixed by #10667 sage: LeftModules(ZZ).hom_category() Category of hom sets in Category of left modules over Integer Ring sage: type(LeftModules(ZZ).hom_category()) <class 'sage.categories.sets_cat.Sets.HomCategory'> # This is new: sage: LeftModules(ZZ).hom_category().is_subcategory(RightModules(ZZ)) True sage: issubclass(LeftModules(ZZ).hom_category().parent_class, RightModules(ZZ).parent_class) True # Reason for it working: sage: LeftModules(ZZ).hom_structure Category of right modules over Integer Ring
The attribute C.hom_structure
is used in sage.categories.HomCategory.extra_super_categories()
.
Hierarchy of homcategories
Recall that currently, the hierarchy of homcategories goes parallel with the hierarchy of their base categories, which is wrong.
However, if C1
is a full subcategory of C2
then (and only then) we should indeed have C1.hom_category().is_subcategory(C2.hom_category())
. Similar to the method C.super_categories()
, I introduce an attribute C.full_subcategory_of
, that provides a list of immediate super categories in which C
is full.
With that, I have:
sage: IntegralDomains().full_subcategory_of [Category of commutative rings, Category of domains] sage: Domains().full_subcategory_of [Category of rings] sage: IntegralDomains().hom_category().is_subcategory(CommutativeRings().hom_category()) True sage: IntegralDomains().hom_category().is_subcategory(Rings().hom_category()) True
and, in particular
sage: issubclass(IntegralDomains().hom_category().parent_class, Rings().hom_category().parent_class) True
Selfcriticism
It is not very pythonic to do those things with an attribute  usually, methods are better. However, an attribute is easier to add, and it is faster to access.
I am not sure whether I got the "full subcategory" business right in all cases.
comment:16 followup: ↓ 17 Changed 7 years ago by
Hi Simon!
I finally got to work on this. See:
http://combinat.sagemath.org/patches/file/tip/categoryhom_methodsnt.patch
It's just a proof of concept. The core of the patch implementing the infrastructure is about 10 lines of code. The rest is (partially) adapting the category code to make use of that infrastructure. I haven't run all tests, and there are a couple things failing here and there, but it should be about correct. At least the tests of modules_with_basis basically pass :)
About attributes for specifying homset structures / full sub categories
I much prefer to use methods instead:
 This is consistent with what has been done so far (with the method super_categories, ...)
 It is easier for a subclass to override
 It's only a tiny bit more verbose, since anyway one should write a doctest for it, and since most categories do not have an init.
About full subcategories
I totally agree that we want this concept. I am not sure yet about the syntax though. In the draft, I have implemented a separate method "full_super_categories". However most of the time, this is quite redundant with the super_categories method. So I'd rather have instead the method super_categories include the information in its result. An option would be to use something like:
def super_categories(self):
return [ (Semigroups(), "full"), Monoids() ]
Then full_super_categories and all_super_categories, ... would extract the relevant information from the above.
We could be more fancy to avoid breaking backward compatibility:
def super_categories(self):
return annotated_list( [ (Semigroups(), "full"), Monoids() ])
where annotated_list would be a helper class whose instances would behave like usual lists, except that one could query annotations on their elements, as in:
"full" in l.annotations(Semigroups())
Things that still need discussion
 Do we want all morphisms, and in particular SetMorphism?'s to systematically inherit from categories (that wasn't the case yet)
 How should categories specify the class to use for their homsets? This currently is done in a couple spots by having C.HomCategory?.ParentMethods? inherit from some specific homset. But that's quite hugly (ParentMethods? is supposed to be an abstract class with just generic methods). Or maybe, that won't be needed anymore once things will be cleaned up: there will be a single concrete Homset class, and all the rest will be provided by the categories?
 Where should the constructors for the various types of morphisms be stored? In C.MorphismMethods?? In C.ParentMethods? (like is currently done with module_morphism)? Elsewhere?
 super_categories and friends should probably return tuples instead of lists. That's safer, especially since their results are cached.
 We probably want to move HomCategory? in its own file
 Do we want to keep C.hom_category() or use C.Homsets() instead, for consistency with C.CartesianProducts?() and such.
Cheers,
Nicolas
comment:17 in reply to: ↑ 16 Changed 6 years ago by
Replying to nthiery:
Some notes after face to face discussion with Simon:
 Do we want all morphisms, and in particular SetMorphism?'s to systematically inherit from categories (that wasn't the case yet)
Eventually yes.
 How should categories specify the class to use for their homsets? This currently is done in a couple spots by having C.HomCategory?.ParentMethods? inherit from some specific homset. But that's quite hugly (ParentMethods? is supposed to be an abstract class with just generic methods). Or maybe, that won't be needed anymore once things will be cleaned up: there will be a single concrete Homset class, and all the rest will be provided by the categories?
Each category should have a Homset
attribute specifying which
concrete class to use for its homset. The default value for that
attribute (implemented as a lazy attribute) is too pickup the first
non default Homset attribute in the list of full_super_categories(),
or sage.category.homset.Homset if there is none.
 Where should the constructors for the various types of morphisms be stored? In C.MorphismMethods?? In C.ParentMethods? (like is currently done with module_morphism)? Elsewhere?
For A
a parent, A.hom(on_basis = [data],...)
would call
A.morphism_on_basis(data,...)
. This morphism_on_basis
could
typically be implemented in A
, or in C.ParentMethods
for C
the
category of A
.
There are 56 explicit hom functions in Sage that would need to be generalized to accept this syntax, while keeping backward compatibility if no keyword is specified.
 super_categories and friends should probably return tuples instead of lists. That's safer, especially since their results are cached.
The new _super_categories
lazy attribute should be a tuple. In the
long run, all_super_categories and friends would best return tuples
for safety (especially since they are cached). Probably
super_categories as well. It would be good to allow soon
super_categories to return a tuple. However this might induce speed
regression in the C3 implementation.
 We probably want to move HomCategory? in its own file
+1
 Do we want to keep C.hom_category() or use C.Homsets() instead, for consistency with C.CartesianProducts?() and such.
That would make sense. Comments anyone?
Little inconvenient: possible confusion between C.Homset
(the
concrete class to be used for homsets in this category) and
C.Homsets()
(the category of homsets in this category).
Simon and Nicolas
comment:18 Changed 6 years ago by
Some food for thought (taken from Rings.HomCategory? before #12876):
When X is a quotient field, we can build a morphism from X to Y by specifying the images of the generators. This is not something about the category, because Y need not be a quotient field.
comment:19 Changed 4 years ago by
 Description modified (diff)
comment:20 Changed 4 years ago by
 Branch set to u/nthiery/categories/morphismmethods10668
comment:21 Changed 4 years ago by
 Commit set to ad87027e6ad2cabfc1bdaab2de061374403c9939
Branch pushed to git repo; I updated commit sha1. New commits:
e87c4dd  10668: specify that NN is commutative

5ea3234  10668: CategoryWithAxiom: simplified _without_axioms logic and improved repr

59fa15e  10668: Removed unused import

18b3483  10668: Implement EndSets; construct the abstract element class in the homset not the homset category

06db0c5  10668: Trivial comment addition in Sets.ElementMethods

4d4b599  10668: Fixed refinement of category to handle Parent._abstract_element_class

125aa8e  10668: Simplify the logic of endsets of modular abelian varieties using the new Endsets construction

fc5b0f1  10668: trivial doctest output updates w.r.t. the new printing of homsets

4b67d7c  10668: Explicitly document that Element.__getattr__ can also be useful when refining categories

ad87027  10668: Fixed doctest

comment:22 Changed 4 years ago by
 Description modified (diff)
 Status changed from new to needs_review
comment:23 Changed 4 years ago by
For the record: all long tests passed.
comment:24 Changed 4 years ago by
 Commit changed from ad87027e6ad2cabfc1bdaab2de061374403c9939 to 90510508e41a09d90758f7c2e48071bebc8185d7
Branch pushed to git repo; I updated commit sha1. New commits:
9051050  10668: fixed ReST typo

comment:25 Changed 4 years ago by
 Dependencies set to 16340
comment:26 Changed 4 years ago by
 Dependencies changed from 16340 to #16340
comment:27 Changed 4 years ago by
 Commit changed from 90510508e41a09d90758f7c2e48071bebc8185d7 to ac38edabd09cbe567e84866f269c6657f5c4fb02
Branch pushed to git repo; I updated commit sha1. New commits:
ac38eda  10668: trivial ReST fix

comment:28 Changed 4 years ago by
 Commit changed from ac38edabd09cbe567e84866f269c6657f5c4fb02 to 9de89090ec0c6072076caf5e248d4e6aa0613c7a
Branch pushed to git repo; I updated commit sha1. New commits:
eaa56bc  16340: super_structure_categories > all_structure_super_categories

afc9724  Merge branch 'develop' into categories/fullsubcategories16340

21bf60a  Merge branch 'categories/fullsubcategories16340' and '6.3beta5' into categories/morphismmethods10668

9de8909  10668: super_structure_categories > all_structure_super_categories

comment:29 Changed 4 years ago by
For the record: all long tests passed for me, and the pdf documentation compiles.
comment:30 Changed 4 years ago by
 Commit changed from 9de89090ec0c6072076caf5e248d4e6aa0613c7a to 56e982e555deaf63ca1b064ca2685493f44db2af
Branch pushed to git repo; I updated commit sha1. New commits:
93273a7  Merge branch 'u/nthiery/categories/fullsubcategories16340' of trac.sagemath.org:sage into public/categories/full_subcategories16340

edb29e6  Fixed trivial doctest failures.

99a8eb1  Merge branch 'public/categories/full_subcategories16340' of trac.sagemath.org:sage into categories/fullsubcategories16340

8bc456c  Merge branch 'master=6.3' into categories/fullsubcategories16340

56e982e  Merge branch 'categories/fullsubcategories16340' and 6.3 into categories/morphismmethods10668

comment:31 Changed 4 years ago by
 Commit changed from 56e982e555deaf63ca1b064ca2685493f44db2af to 016cd166f269f3cb21ef61a14a35f72d23d8f3a6
Branch pushed to git repo; I updated commit sha1. New commits:
016cd16  #16340: Revert ReST typo fix in ell_curve_isogeny.py to avoid conflict with other ticket handling it

comment:32 Changed 4 years ago by
 Commit changed from 016cd166f269f3cb21ef61a14a35f72d23d8f3a6 to d147678711fc32df88a24e8c4ba16ad414179fee
Branch pushed to git repo; I updated commit sha1. New commits:
d147678  Merge branch 'develop=6.4.beta0' into categories/morphismmethods10668

comment:33 Changed 4 years ago by
 Cc sagecombinat SimonKing added
comment:34 Changed 4 years ago by
 Commit changed from d147678711fc32df88a24e8c4ba16ad414179fee to 33463c4196d0906453cca976b94457b0fc353290
Branch pushed to git repo; I updated commit sha1. New commits:
33463c4  10668: rebase doctest upon the fact that Monoids.Commutative now exists

comment:35 Changed 4 years ago by
 Commit changed from 33463c4196d0906453cca976b94457b0fc353290 to 62a28dddc0d484aabcef16e914d873bbce6613ea
Branch pushed to git repo; I updated commit sha1. New commits:
dc0d1db  8678: removed explicit doctest:xxx: source line number from a doctest

8457690  8678: trivial doctest update after merge with develop

62a28dd  8678: rewrote a few tests introduced by #16296 so that they do not depend on the number of axioms defined in Sage

comment:36 Changed 4 years ago by
 Commit changed from 62a28dddc0d484aabcef16e914d873bbce6613ea to 2b3ee8104552292c87f0a19b6f787eb727210f96
Branch pushed to git repo; I updated commit sha1. New commits:
2b3ee81  Merge branch 'develop = 6.4 beta2' into categories/morphismmethods10668

comment:37 Changed 3 years ago by
Work plan: Review this after #16340.
comment:38 Changed 3 years ago by
Nicolas asked me to look at this here first, since he is now working on #16340.
comment:39 Changed 3 years ago by
 Commit changed from 2b3ee8104552292c87f0a19b6f787eb727210f96 to 54fe992bc3532106abcec15b1b32e514f8e7a459
Branch pushed to git repo; I updated commit sha1. Last 10 new commits:
1e4418f  Merge branch 'develop' into categories/fullsubcategories16340

e5f210c  Merge branch 'public/categories/full_subcategories16340' of trac.sagemath.org:sage into public/categories/full_subcategories16340

d4c7a88  Specified more categories as not being structure categories.

708cc41  Merge branch 'public/categories/full_subcategories16340' of trac.sagemath.org:sage into categories/fullsubcategories16340

29a6c67  16340: reverted change to CoxeterGroups.is_structure_category() + explanations in the doc

60aa128  16340: fixed typos

950b039  16340: Merge branch 'develop = 6.4 beta4' into categories/fullsubcategories16340

b14ca6c  16340: revert change, and add documentation thereabout: the category of permutation groups defines additional structure

43b25d4  16340: is_structure_category > additional_structure, all_super_structure_categories > structure, default for functorial construction categories

54fe992  10668: merged in latest 16340 (and develop=6.4 beta4)

comment:40 Changed 3 years ago by
 Commit changed from 54fe992bc3532106abcec15b1b32e514f8e7a459 to 9398475171db0afdfcedf3f8538eaaab058764a8
Branch pushed to git repo; I updated commit sha1. New commits:
9398475  10668: fixed the endset logic, and updated (all?) doctests accordingly

comment:41 Changed 3 years ago by
 Branch changed from u/nthiery/categories/morphismmethods10668 to public/categories/morphismmethods10668
comment:42 Changed 3 years ago by
 Commit changed from 9398475171db0afdfcedf3f8538eaaab058764a8 to 75615b5153afce1dc8a9e01d9db0ad4ccfe9de45
Branch pushed to git repo; I updated commit sha1. New commits:
75615b5  10668: trivial doctest updates

comment:43 Changed 3 years ago by
 Commit changed from 75615b5153afce1dc8a9e01d9db0ad4ccfe9de45 to d5d3a97fcfbf3d2316d8096681c39da2996b8096
Branch pushed to git repo; I updated commit sha1. New commits:
d5d3a97  10668: improved description of the HomsetsOf class

comment:44 Changed 3 years ago by
For the record: I opened #17150, to make the conversion/coercion/call mechanism of homsets closer to what we do for other parents.
comment:45 Changed 3 years ago by
 Commit changed from d5d3a97fcfbf3d2316d8096681c39da2996b8096 to 5416ba0a866806b9746fd0e46c3888f2c308e73a
Branch pushed to git repo; I updated commit sha1. New commits:
5416ba0  Add a note on the MRO used for Homset._abstract_element_class

comment:46 Changed 3 years ago by
TODO:
Add documentation to the category_of
method, which seems to return an instance of HomsetsOf
. It is absolutely unclear to me what it is supposed to be or to do.
comment:47 followup: ↓ 60 Changed 3 years ago by
I wonder about Homsets.Endset.super_categories
, which returns [Monoids()]
. Shouldn't this rather be extra super categories? If not, why not?
comment:48 followup: ↓ 51 Changed 3 years ago by
TODO:
We have
sage: Posets().Homsets().Endset().super_categories() [Category of homsets, Category of homsets of posets]
hence, in spite of Homsets.Endset.super_categories
, the fact that endsets are monoids is not mentioned.
comment:49 followup: ↓ 58 Changed 3 years ago by
Why am I logged out of trac after few seconds? This has happened at least 10 times this evening.
Anyway.
What is the point of Modules.EndCategory
? Shouldn't it be implemented as an axiom Endset
, by the framework provided in this ticket?
comment:50 followup: ↓ 52 Changed 3 years ago by
 Reviewers set to Simon King
 Status changed from needs_review to needs_work
The good news: All doctests pass. But I think it needs work, to address the concerns expressed in my previous comments.
comment:51 in reply to: ↑ 48 ; followup: ↓ 53 Changed 3 years ago by
Replying to SimonKing:
TODO:
We have
sage: Posets().Homsets().Endset().super_categories() [Category of homsets, Category of homsets of posets]hence, in spite of
Homsets.Endset.super_categories
, the fact that endsets are monoids is not mentioned.
Changing Homsets.Endset.super_categories
into extra_supercategories
does not help. Nicolas, do you know how to fix that?
comment:52 in reply to: ↑ 50 Changed 3 years ago by
Replying to SimonKing:
The good news: All doctests pass. But I think it needs work, to address the concerns expressed in my previous comments.
Oops, I made a wrong test. When using extra_supercategories, the following does give the correct result:
sage: Posets().Homsets().Endset().is_subcategory(Monoids()) True
comment:53 in reply to: ↑ 51 ; followup: ↓ 55 Changed 3 years ago by
Replying to SimonKing:
Replying to SimonKing:
We have
sage: Posets().Homsets().Endset().super_categories() [Category of homsets, Category of homsets of posets]hence, in spite of
Homsets.Endset.super_categories
, the fact that endsets are monoids is not mentioned.
The source of confusion is that the first entry above should have read as "Category of endsets". I just fixed that (a trivial thing in _repr_) and will push shortly.
Now I have::
sage: Posets().Endsets().super_categories() [Category of endsets, Category of homsets of posets]
An it's normal that monoids don't show up above because they are a super category of the category of endsets. Just as a double check:
sage: Posets().Endsets().is_subcategory(Monoids()) True sage: Posets().Homsets().Endset().is_subcategory(Monoids()) True
Cheers,
Nicolas
comment:54 Changed 3 years ago by
 Commit changed from 5416ba0a866806b9746fd0e46c3888f2c308e73a to 23639a9288bdca85482a93ed029b3d1390309141
Branch pushed to git repo; I updated commit sha1. New commits:
23639a9  Fix more typos

comment:55 in reply to: ↑ 53 Changed 3 years ago by
Replying to nthiery:
The source of confusion is that the first entry above should have read as "Category of endsets". I just fixed that (a trivial thing in _repr_) and will push shortly.
Good. Please also add a test to the super_categories method. I have just push some typo fixes.
comment:56 followup: ↓ 59 Changed 3 years ago by
Now I went through the whole diff. The only remaining issues are "Add documentation to the category_of method" and the _repr_
problem you are working at now.
So, time for me to call it a day :)
comment:57 Changed 3 years ago by
 Commit changed from 23639a9288bdca85482a93ed029b3d1390309141 to 877bfdb215628b19c44a66d14ceee54824beaf14
Branch pushed to git repo; I updated commit sha1. New commits:
02a6a8a  10668: fixed representation of the category of endsets

477d381  10668: Homsets.Endset.super_category > extra_super_category + documentation

877bfdb  10668: fix: Modules.EndCategory > Modules.Homsets.Endset + made it functional: endsets of modules are algebras

comment:58 in reply to: ↑ 49 Changed 3 years ago by
Replying to SimonKing:
What is the point of
Modules.EndCategory
? Shouldn't it be implemented as an axiomEndset
, by the framework provided in this ticket?
Good catch; that piece had not been refactored. Now it even works :)
comment:59 in reply to: ↑ 56 Changed 3 years ago by
Replying to SimonKing:
Now I went through the whole diff. The only remaining issues are "Add documentation to the category_of method" and the
_repr_
problem you are working at now.
The second piece is done now. I am about to work on the doc of category_of
.
So, time for me to call it a day :)
Yes indeed, thanks so much!
comment:60 in reply to: ↑ 47 Changed 3 years ago by
Replying to SimonKing:
I wonder about
Homsets.Endset.super_categories
, which returns[Monoids()]
. Shouldn't this rather be extra super categories? If not, why not?
Done.
comment:61 Changed 3 years ago by
 Commit changed from 877bfdb215628b19c44a66d14ceee54824beaf14 to f86824ea354a5260b2ee0b8f24f239c8b5178bdd
Branch pushed to git repo; I updated commit sha1. New commits:
f86824e  10668: documentation for HomsetsCategory.category_of + fixed typo in doctest nearby

comment:62 Changed 3 years ago by
 Milestone set to sage6.4
 Status changed from needs_work to needs_review
I believe all discussion points have been addressed. Hence back to needs review.
comment:63 Changed 3 years ago by
 Commit changed from f86824ea354a5260b2ee0b8f24f239c8b5178bdd to 787f461ff097e860f21ebf990f67e74185f84d53
Branch pushed to git repo; I updated commit sha1. New commits:
787f461  10668: proofreading of Homsets.category_of

comment:64 Changed 3 years ago by
 Commit changed from 787f461ff097e860f21ebf990f67e74185f84d53 to a9379383081f2ae7d42c0e17601c6e549269899c
Branch pushed to git repo; I updated commit sha1. New commits:
a937938  Fixing two typos

comment:65 Changed 3 years ago by
 Status changed from needs_review to positive_review
All tests pass and all issues have been addressed. Hence, it's a positive review, of course modulo #16340.
comment:66 Changed 3 years ago by
 Branch changed from public/categories/morphismmethods10668 to a9379383081f2ae7d42c0e17601c6e549269899c
 Resolution set to fixed
 Status changed from positive_review to closed
comment:67 Changed 3 years ago by
 Commit a9379383081f2ae7d42c0e17601c6e549269899c deleted
Thanks Simon :) And thanks for coming over; that was a productive trip!
Replying to nthiery:
I don't see why this should be wrong: Any ring homomorphism is a set homomorphism. Hence,
Hom_Rings()(A,B)
is a subset ofHom_Sets()(A,B)
 nobody claims that they coincide.You mean "Cat.HomMethods? will provide...", I guess.
The approach with
HomMethods
would provide methods defined for homsets, whereas the fact that a homset of vector spaces is a vector space has implications for the methods of elements of the homsets (i.e., for methods of morphisms).I don't know whether we need special methods for homset, but of course it would be nice to have homsets that are vector spaces.
What about the following approach:
sage.categories.category.HomCategory
. I suggest to provide it with an optional argumenthom_structure
. Define, for example,H = HomCategory(Algebras(QQ),hom_structure=VectorSpaces(QQ))
. Then,H
is the category of homsets in the category of algebras overQQ
, and each homset would automatically be a vector space overQQ
. Moreover,H
would be a subcategory ofVectorSpaces(QQ)
.C.hom_structure
, that defaults toC.HomStructure
if that exists, and otherwise returns the join ofS.hom_structure
for allS in C.super_categories()
. Then,C.hom_category()
defaults toHomCategory(C, hom_structure=C.hom_structure)
.HomStructure
(e.g., in the__init__
method ofVectorSpaces(R)
, we would defineself.HomStructure=self
, ensuring thatself.hom_structure
is the right thing). In order to avoid an infinite recursion of the lazy attribute, we also need to defineObjects().HomStructure=Objects()
.That would be a good candidate for your
HomMethods
, don't you think?I guess that would be an extension of the
sage.categories.pushout
formalism.Anyway, my suggestion is to start with the
hom_structure
approach, as it seems to be relatively straight forward to implement.