Opened 11 months ago
Last modified 5 months ago
#31247 new defect
Forgetful Functor not working properly
Reported by: | gh-mjungmath | Owned by: | |
---|---|---|---|
Priority: | major | Milestone: | sage-9.5 |
Component: | categories | Keywords: | |
Cc: | tscrim, mkoeppe, gh-tobiasdiez, nthiery | Merged in: | |
Authors: | Reviewers: | ||
Report Upstream: | N/A | Work issues: | |
Branch: | Commit: | ||
Dependencies: | Stopgaps: |
Description
We have currently the following bug:
sage: from sage.categories.functor import ForgetfulFunctor sage: F = ForgetfulFunctor(Rings(), Sets()) sage: F(ZZ) Integer Ring
The result should rather be:
sage: Set(ZZ) Set of elements of Integer Ring
Change History (9)
comment:1 Changed 11 months ago by
comment:2 Changed 11 months ago by
One could try the following: overload _apply_functor
for forgetful functors and call _call_
directly. That would be a minimal solution, but I am not sure whether it is the most elegant.
comment:3 Changed 11 months ago by
- Cc nthiery added
comment:4 follow-up: ↓ 5 Changed 11 months ago by
I don't think this is a bug. The code is performing as it should because ZZ
is already in Sets()
. It doesn't need to create a new object, much less an instance of a different class. I think if you want to change your object, you should call the explicit constructor rather than relying on a functor. Moreover, if it is not going to be the current behavior, then I think you're asking for a solution to an impossible problem.
comment:5 in reply to: ↑ 4 Changed 11 months ago by
Replying to tscrim:
I don't think this is a bug. The code is performing as it should because
ZZ
is already inSets()
. It doesn't need to create a new object, much less an instance of a different class.
Then, the same would hold for manifolds in #31241. Differentiable manifolds are also in the category of topological manifolds (or at least should be). But we already agreed that it's a bug there. What is the difference then?
I think if you want to change your object, you should call the explicit constructor rather than relying on a functor. Moreover, if it is not going to be the current behavior, then I think you're asking for a solution to an impossible problem.
Well, the forgetful functor has the purpose to forget imposed structures, and see the object as an object in the super category only. This condition is currently not met:
sage: from sage.categories.functor import ForgetfulFunctor ....: F = ForgetfulFunctor(Rings(), Sets()) ....: F(ZZ).category() Join of Category of euclidean domains and Category of infinite enumerated sets and Category of metric spaces sage: F(ZZ)(1) + F(ZZ)(2) 3
Usual set operations are not even compatible:
sage: Set([1,2,3]).union(F(ZZ)) --------------------------------------------------------------------------- TypeError Traceback (most recent call last) ... TypeError: X (=Integer Ring) must be a Set
Of course, different structures need different implementations.
For manifolds, the current stage of behavior is rather bad. Differentiable manifolds can be seen as topological manifolds, however each differentiable manifold comes with a differentiable structure which Sage keeps implicitly track of. This must be dropped after the forgetful functor had been applied. But with the above behavior, this is not possible because the original instance would be returned.
comment:6 Changed 9 months ago by
- Milestone changed from sage-9.3 to sage-9.4
Sage development has entered the release candidate phase for 9.3. Setting a new milestone for this ticket based on a cursory review of ticket status, priority, and last modification date.
comment:7 Changed 5 months ago by
Another example:
sage: R.<x> = QQ[] sage: phi = R.hom([x^2]); phi Ring endomorphism of Univariate Polynomial Ring in x over Rational Field Defn: x |--> x^2 sage: phi.category_for() Join of Category of euclidean domains and Category of commutative algebras over (number fields and quotient fields and metric spaces) and Category of infinite sets sage: F = ForgetfulFunctor(Rings(), Sets()) sage: F(phi) Ring endomorphism of Univariate Polynomial Ring in x over Rational Field Defn: x |--> x^2
I hoped to compute the correct category of an image in #32121 (Replace MapCombinatorialClass
, add methods Map.image
, Map.pushforward
)...
comment:8 Changed 5 months ago by
This in and of itself is not a bug IMO as per comment:4. However, what is a bug IMO is that
sage: F(phi).parent() Set of Homomorphisms from Univariate Polynomial Ring in x over Rational Field to Univariate Polynomial Ring in x over Rational Field
which leads to this
sage: F(phi).category_for() Join of Category of euclidean domains and Category of commutative algebras over (number fields and quotient fields and metric spaces) and Category of infinite sets
For morphisms, where the category is part of the homset constructor, we can create the new homset parent and then convert the morphism into that parent. Mostly this just consists of rebuilding the same object but with a different parent. This is meaningful when we want to compose maps (as opposed to manipulating sets).
comment:9 Changed 5 months ago by
- Milestone changed from sage-9.4 to sage-9.5
Digging into the source code, the forgetful functor
F
calls the following code from its class parentFunctor
:Here,
__codomain
should be the destination category. However, the call function of a category is treated as some kind of coercion/conversion:as the following note in
sage/categories/sets_cat.py
indicates, too:Proper forgetful functors will eventually be implemented, with another syntax. It seems, this hasn't been done so far.