passagemath-objects 10.6.41__cp314-cp314t-macosx_13_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of passagemath-objects might be problematic. Click here for more details.
- passagemath_objects/.dylibs/libgmp.10.dylib +0 -0
- passagemath_objects/__init__.py +3 -0
- passagemath_objects-10.6.41.dist-info/METADATA +115 -0
- passagemath_objects-10.6.41.dist-info/RECORD +280 -0
- passagemath_objects-10.6.41.dist-info/WHEEL +6 -0
- passagemath_objects-10.6.41.dist-info/top_level.txt +3 -0
- sage/all__sagemath_objects.py +37 -0
- sage/arith/all__sagemath_objects.py +5 -0
- sage/arith/long.pxd +411 -0
- sage/arith/numerical_approx.cpython-314t-darwin.so +0 -0
- sage/arith/numerical_approx.pxd +35 -0
- sage/arith/numerical_approx.pyx +75 -0
- sage/arith/power.cpython-314t-darwin.so +0 -0
- sage/arith/power.pxd +31 -0
- sage/arith/power.pyx +127 -0
- sage/categories/action.cpython-314t-darwin.so +0 -0
- sage/categories/action.pxd +29 -0
- sage/categories/action.pyx +641 -0
- sage/categories/algebra_functor.py +745 -0
- sage/categories/all__sagemath_objects.py +33 -0
- sage/categories/basic.py +62 -0
- sage/categories/cartesian_product.py +295 -0
- sage/categories/category.py +3401 -0
- sage/categories/category_cy_helper.cpython-314t-darwin.so +0 -0
- sage/categories/category_cy_helper.pxd +8 -0
- sage/categories/category_cy_helper.pyx +322 -0
- sage/categories/category_singleton.cpython-314t-darwin.so +0 -0
- sage/categories/category_singleton.pxd +3 -0
- sage/categories/category_singleton.pyx +342 -0
- sage/categories/category_types.py +637 -0
- sage/categories/category_with_axiom.py +2876 -0
- sage/categories/covariant_functorial_construction.py +703 -0
- sage/categories/facade_sets.py +228 -0
- sage/categories/functor.cpython-314t-darwin.so +0 -0
- sage/categories/functor.pxd +7 -0
- sage/categories/functor.pyx +691 -0
- sage/categories/homset.py +1338 -0
- sage/categories/homsets.py +364 -0
- sage/categories/isomorphic_objects.py +73 -0
- sage/categories/map.cpython-314t-darwin.so +0 -0
- sage/categories/map.pxd +34 -0
- sage/categories/map.pyx +2112 -0
- sage/categories/morphism.cpython-314t-darwin.so +0 -0
- sage/categories/morphism.pxd +14 -0
- sage/categories/morphism.pyx +895 -0
- sage/categories/objects.py +167 -0
- sage/categories/primer.py +1696 -0
- sage/categories/pushout.py +4834 -0
- sage/categories/quotients.py +64 -0
- sage/categories/realizations.py +200 -0
- sage/categories/sets_cat.py +3228 -0
- sage/categories/sets_with_partial_maps.py +52 -0
- sage/categories/subobjects.py +64 -0
- sage/categories/subquotients.py +21 -0
- sage/categories/with_realizations.py +311 -0
- sage/cpython/__init__.py +19 -0
- sage/cpython/_py2_random.py +619 -0
- sage/cpython/all.py +3 -0
- sage/cpython/atexit.cpython-314t-darwin.so +0 -0
- sage/cpython/atexit.pyx +269 -0
- sage/cpython/builtin_types.cpython-314t-darwin.so +0 -0
- sage/cpython/builtin_types.pyx +7 -0
- sage/cpython/cython_metaclass.cpython-314t-darwin.so +0 -0
- sage/cpython/cython_metaclass.h +117 -0
- sage/cpython/cython_metaclass.pxd +3 -0
- sage/cpython/cython_metaclass.pyx +130 -0
- sage/cpython/debug.cpython-314t-darwin.so +0 -0
- sage/cpython/debug.pyx +302 -0
- sage/cpython/dict_del_by_value.cpython-314t-darwin.so +0 -0
- sage/cpython/dict_del_by_value.pxd +9 -0
- sage/cpython/dict_del_by_value.pyx +191 -0
- sage/cpython/dict_internal.h +245 -0
- sage/cpython/getattr.cpython-314t-darwin.so +0 -0
- sage/cpython/getattr.pxd +9 -0
- sage/cpython/getattr.pyx +439 -0
- sage/cpython/pycore_long.h +97 -0
- sage/cpython/pycore_long.pxd +10 -0
- sage/cpython/python_debug.h +44 -0
- sage/cpython/python_debug.pxd +47 -0
- sage/cpython/pyx_visit.h +13 -0
- sage/cpython/string.cpython-314t-darwin.so +0 -0
- sage/cpython/string.pxd +76 -0
- sage/cpython/string.pyx +34 -0
- sage/cpython/string_impl.h +60 -0
- sage/cpython/type.cpython-314t-darwin.so +0 -0
- sage/cpython/type.pxd +2 -0
- sage/cpython/type.pyx +40 -0
- sage/cpython/wrapperdescr.pxd +67 -0
- sage/ext/all__sagemath_objects.py +3 -0
- sage/ext/ccobject.h +64 -0
- sage/ext/cplusplus.pxd +17 -0
- sage/ext/mod_int.h +30 -0
- sage/ext/mod_int.pxd +24 -0
- sage/ext/stdsage.pxd +39 -0
- sage/groups/all__sagemath_objects.py +1 -0
- sage/groups/group.cpython-314t-darwin.so +0 -0
- sage/groups/group.pxd +14 -0
- sage/groups/group.pyx +322 -0
- sage/groups/old.cpython-314t-darwin.so +0 -0
- sage/groups/old.pxd +14 -0
- sage/groups/old.pyx +219 -0
- sage/libs/all__sagemath_objects.py +3 -0
- sage/libs/gmp/__init__.py +1 -0
- sage/libs/gmp/all.pxd +6 -0
- sage/libs/gmp/binop.pxd +23 -0
- sage/libs/gmp/misc.pxd +8 -0
- sage/libs/gmp/mpf.pxd +88 -0
- sage/libs/gmp/mpn.pxd +57 -0
- sage/libs/gmp/mpq.pxd +57 -0
- sage/libs/gmp/mpz.pxd +202 -0
- sage/libs/gmp/pylong.cpython-314t-darwin.so +0 -0
- sage/libs/gmp/pylong.pxd +12 -0
- sage/libs/gmp/pylong.pyx +150 -0
- sage/libs/gmp/random.pxd +25 -0
- sage/libs/gmp/randomize.pxd +59 -0
- sage/libs/gmp/types.pxd +53 -0
- sage/libs/gmpxx.pxd +19 -0
- sage/misc/abstract_method.py +276 -0
- sage/misc/all__sagemath_objects.py +43 -0
- sage/misc/bindable_class.py +253 -0
- sage/misc/c3_controlled.cpython-314t-darwin.so +0 -0
- sage/misc/c3_controlled.pxd +2 -0
- sage/misc/c3_controlled.pyx +1402 -0
- sage/misc/cachefunc.cpython-314t-darwin.so +0 -0
- sage/misc/cachefunc.pxd +43 -0
- sage/misc/cachefunc.pyx +3781 -0
- sage/misc/call.py +188 -0
- sage/misc/classcall_metaclass.cpython-314t-darwin.so +0 -0
- sage/misc/classcall_metaclass.pxd +14 -0
- sage/misc/classcall_metaclass.pyx +599 -0
- sage/misc/constant_function.cpython-314t-darwin.so +0 -0
- sage/misc/constant_function.pyx +130 -0
- sage/misc/decorators.py +747 -0
- sage/misc/fast_methods.cpython-314t-darwin.so +0 -0
- sage/misc/fast_methods.pxd +20 -0
- sage/misc/fast_methods.pyx +351 -0
- sage/misc/flatten.py +90 -0
- sage/misc/fpickle.cpython-314t-darwin.so +0 -0
- sage/misc/fpickle.pyx +177 -0
- sage/misc/function_mangling.cpython-314t-darwin.so +0 -0
- sage/misc/function_mangling.pxd +11 -0
- sage/misc/function_mangling.pyx +308 -0
- sage/misc/inherit_comparison.cpython-314t-darwin.so +0 -0
- sage/misc/inherit_comparison.pxd +5 -0
- sage/misc/inherit_comparison.pyx +105 -0
- sage/misc/instancedoc.cpython-314t-darwin.so +0 -0
- sage/misc/instancedoc.pyx +331 -0
- sage/misc/lazy_attribute.cpython-314t-darwin.so +0 -0
- sage/misc/lazy_attribute.pyx +607 -0
- sage/misc/lazy_format.py +135 -0
- sage/misc/lazy_import.cpython-314t-darwin.so +0 -0
- sage/misc/lazy_import.pyx +1299 -0
- sage/misc/lazy_import_cache.py +36 -0
- sage/misc/lazy_list.cpython-314t-darwin.so +0 -0
- sage/misc/lazy_list.pxd +19 -0
- sage/misc/lazy_list.pyx +1187 -0
- sage/misc/lazy_string.cpython-314t-darwin.so +0 -0
- sage/misc/lazy_string.pxd +7 -0
- sage/misc/lazy_string.pyx +546 -0
- sage/misc/misc.py +1066 -0
- sage/misc/misc_c.cpython-314t-darwin.so +0 -0
- sage/misc/misc_c.pxd +3 -0
- sage/misc/misc_c.pyx +766 -0
- sage/misc/namespace_package.py +37 -0
- sage/misc/nested_class.cpython-314t-darwin.so +0 -0
- sage/misc/nested_class.pxd +3 -0
- sage/misc/nested_class.pyx +394 -0
- sage/misc/persist.cpython-314t-darwin.so +0 -0
- sage/misc/persist.pyx +1251 -0
- sage/misc/prandom.py +418 -0
- sage/misc/randstate.cpython-314t-darwin.so +0 -0
- sage/misc/randstate.pxd +30 -0
- sage/misc/randstate.pyx +1059 -0
- sage/misc/repr.py +203 -0
- sage/misc/reset.cpython-314t-darwin.so +0 -0
- sage/misc/reset.pyx +196 -0
- sage/misc/sage_ostools.cpython-314t-darwin.so +0 -0
- sage/misc/sage_ostools.pyx +323 -0
- sage/misc/sage_timeit.py +276 -0
- sage/misc/sage_timeit_class.cpython-314t-darwin.so +0 -0
- sage/misc/sage_timeit_class.pyx +120 -0
- sage/misc/sage_unittest.py +637 -0
- sage/misc/sageinspect.py +2768 -0
- sage/misc/session.cpython-314t-darwin.so +0 -0
- sage/misc/session.pyx +392 -0
- sage/misc/superseded.py +557 -0
- sage/misc/test_nested_class.py +228 -0
- sage/misc/timing.py +264 -0
- sage/misc/unknown.py +222 -0
- sage/misc/verbose.py +253 -0
- sage/misc/weak_dict.cpython-314t-darwin.so +0 -0
- sage/misc/weak_dict.pxd +15 -0
- sage/misc/weak_dict.pyx +1231 -0
- sage/modules/all__sagemath_objects.py +1 -0
- sage/modules/module.cpython-314t-darwin.so +0 -0
- sage/modules/module.pxd +5 -0
- sage/modules/module.pyx +329 -0
- sage/rings/all__sagemath_objects.py +3 -0
- sage/rings/integer_fake.h +22 -0
- sage/rings/integer_fake.pxd +55 -0
- sage/sets/all__sagemath_objects.py +3 -0
- sage/sets/pythonclass.cpython-314t-darwin.so +0 -0
- sage/sets/pythonclass.pxd +9 -0
- sage/sets/pythonclass.pyx +247 -0
- sage/structure/__init__.py +4 -0
- sage/structure/all.py +30 -0
- sage/structure/category_object.cpython-314t-darwin.so +0 -0
- sage/structure/category_object.pxd +28 -0
- sage/structure/category_object.pyx +1087 -0
- sage/structure/coerce.cpython-314t-darwin.so +0 -0
- sage/structure/coerce.pxd +44 -0
- sage/structure/coerce.pyx +2107 -0
- sage/structure/coerce_actions.cpython-314t-darwin.so +0 -0
- sage/structure/coerce_actions.pxd +27 -0
- sage/structure/coerce_actions.pyx +988 -0
- sage/structure/coerce_dict.cpython-314t-darwin.so +0 -0
- sage/structure/coerce_dict.pxd +51 -0
- sage/structure/coerce_dict.pyx +1557 -0
- sage/structure/coerce_exceptions.py +23 -0
- sage/structure/coerce_maps.cpython-314t-darwin.so +0 -0
- sage/structure/coerce_maps.pxd +28 -0
- sage/structure/coerce_maps.pyx +718 -0
- sage/structure/debug_options.cpython-314t-darwin.so +0 -0
- sage/structure/debug_options.pxd +6 -0
- sage/structure/debug_options.pyx +54 -0
- sage/structure/dynamic_class.py +541 -0
- sage/structure/element.cpython-314t-darwin.so +0 -0
- sage/structure/element.pxd +272 -0
- sage/structure/element.pyx +4772 -0
- sage/structure/element_wrapper.cpython-314t-darwin.so +0 -0
- sage/structure/element_wrapper.pxd +12 -0
- sage/structure/element_wrapper.pyx +582 -0
- sage/structure/factorization.py +1422 -0
- sage/structure/factorization_integer.py +105 -0
- sage/structure/factory.cpython-314t-darwin.so +0 -0
- sage/structure/factory.pyx +786 -0
- sage/structure/formal_sum.py +489 -0
- sage/structure/gens_py.py +73 -0
- sage/structure/global_options.py +1743 -0
- sage/structure/indexed_generators.py +863 -0
- sage/structure/list_clone.cpython-314t-darwin.so +0 -0
- sage/structure/list_clone.pxd +65 -0
- sage/structure/list_clone.pyx +1867 -0
- sage/structure/list_clone_demo.cpython-314t-darwin.so +0 -0
- sage/structure/list_clone_demo.pyx +248 -0
- sage/structure/list_clone_timings.py +179 -0
- sage/structure/list_clone_timings_cy.cpython-314t-darwin.so +0 -0
- sage/structure/list_clone_timings_cy.pyx +86 -0
- sage/structure/mutability.cpython-314t-darwin.so +0 -0
- sage/structure/mutability.pxd +21 -0
- sage/structure/mutability.pyx +348 -0
- sage/structure/nonexact.py +69 -0
- sage/structure/parent.cpython-314t-darwin.so +0 -0
- sage/structure/parent.pxd +112 -0
- sage/structure/parent.pyx +3093 -0
- sage/structure/parent_base.cpython-314t-darwin.so +0 -0
- sage/structure/parent_base.pxd +13 -0
- sage/structure/parent_base.pyx +44 -0
- sage/structure/parent_gens.cpython-314t-darwin.so +0 -0
- sage/structure/parent_gens.pxd +22 -0
- sage/structure/parent_gens.pyx +377 -0
- sage/structure/parent_old.cpython-314t-darwin.so +0 -0
- sage/structure/parent_old.pxd +25 -0
- sage/structure/parent_old.pyx +294 -0
- sage/structure/proof/__init__.py +1 -0
- sage/structure/proof/all.py +243 -0
- sage/structure/proof/proof.py +300 -0
- sage/structure/richcmp.cpython-314t-darwin.so +0 -0
- sage/structure/richcmp.pxd +213 -0
- sage/structure/richcmp.pyx +495 -0
- sage/structure/sage_object.cpython-314t-darwin.so +0 -0
- sage/structure/sage_object.pxd +3 -0
- sage/structure/sage_object.pyx +988 -0
- sage/structure/sage_object_test.py +19 -0
- sage/structure/sequence.py +937 -0
- sage/structure/set_factories.py +1178 -0
- sage/structure/set_factories_example.py +527 -0
- sage/structure/support_view.py +179 -0
- sage/structure/test_factory.py +56 -0
- sage/structure/unique_representation.py +1359 -0
|
@@ -0,0 +1,691 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-objects
|
|
2
|
+
"""
|
|
3
|
+
Functors
|
|
4
|
+
|
|
5
|
+
AUTHORS:
|
|
6
|
+
|
|
7
|
+
- David Kohel and William Stein
|
|
8
|
+
|
|
9
|
+
- David Joyner (2005-12-17): examples
|
|
10
|
+
|
|
11
|
+
- Robert Bradshaw (2007-06-23): Pyrexify
|
|
12
|
+
|
|
13
|
+
- Simon King (2010-04-30): more examples, several bug fixes,
|
|
14
|
+
re-implementation of the default call method,
|
|
15
|
+
making functors applicable to morphisms (not only to objects)
|
|
16
|
+
|
|
17
|
+
- Simon King (2010-12): Pickling of functors without losing domain and codomain
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
# ****************************************************************************
|
|
21
|
+
# Copyright (C) 2005 David Kohel <kohel@maths.usyd.edu> and
|
|
22
|
+
# William Stein <wstein@math.ucsd.edu>
|
|
23
|
+
#
|
|
24
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
25
|
+
#
|
|
26
|
+
# This code is distributed in the hope that it will be useful,
|
|
27
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty
|
|
28
|
+
# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
29
|
+
#
|
|
30
|
+
# See the GNU General Public License for more details; the full text
|
|
31
|
+
# is available at:
|
|
32
|
+
#
|
|
33
|
+
# https://www.gnu.org/licenses/
|
|
34
|
+
# ****************************************************************************
|
|
35
|
+
|
|
36
|
+
from sage.categories import category
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _Functor_unpickle(Cl, D, domain, codomain):
|
|
40
|
+
"""
|
|
41
|
+
Generic unpickling function for functors.
|
|
42
|
+
|
|
43
|
+
AUTHOR:
|
|
44
|
+
|
|
45
|
+
- Simon King (2010-12): :issue:`10460`
|
|
46
|
+
|
|
47
|
+
EXAMPLES::
|
|
48
|
+
|
|
49
|
+
sage: R.<x,y> = InfinitePolynomialRing(QQ)
|
|
50
|
+
sage: F = R.construction()[0]
|
|
51
|
+
sage: F == loads(dumps(F))
|
|
52
|
+
True
|
|
53
|
+
sage: F.domain(), loads(dumps(F)).domain()
|
|
54
|
+
(Category of rings, Category of rings)
|
|
55
|
+
"""
|
|
56
|
+
F = Functor.__new__(Cl)
|
|
57
|
+
Functor.__init__(F, domain, codomain)
|
|
58
|
+
for s, v in D:
|
|
59
|
+
setattr(F, s, v)
|
|
60
|
+
return F
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
cdef class Functor(SageObject):
|
|
64
|
+
"""
|
|
65
|
+
A class for functors between two categories.
|
|
66
|
+
|
|
67
|
+
NOTE:
|
|
68
|
+
|
|
69
|
+
- In the first place, a functor is given by its domain and codomain,
|
|
70
|
+
which are both categories.
|
|
71
|
+
- When defining a sub-class, the user should not implement a call method.
|
|
72
|
+
Instead, one should implement three methods, which are composed in the
|
|
73
|
+
default call method:
|
|
74
|
+
|
|
75
|
+
- ``_coerce_into_domain(self, x)`` -- return an object of ``self``'s
|
|
76
|
+
domain, corresponding to ``x``, or raise a :exc:`TypeError`.
|
|
77
|
+
- Default: Raise :exc:`TypeError` if ``x`` is not in ``self``'s domain.
|
|
78
|
+
|
|
79
|
+
- ``_apply_functor(self, x)`` -- apply ``self`` to an object ``x`` of
|
|
80
|
+
``self``'s domain.
|
|
81
|
+
- Default: Conversion into ``self``'s codomain.
|
|
82
|
+
|
|
83
|
+
- ``_apply_functor_to_morphism(self, f)`` -- apply ``self`` to a morphism
|
|
84
|
+
``f`` in ``self``'s domain.
|
|
85
|
+
- Default: Return ``self(f.domain()).hom(f,self(f.codomain()))``.
|
|
86
|
+
|
|
87
|
+
EXAMPLES::
|
|
88
|
+
|
|
89
|
+
sage: rings = Rings()
|
|
90
|
+
sage: abgrps = CommutativeAdditiveGroups()
|
|
91
|
+
sage: F = ForgetfulFunctor(rings, abgrps)
|
|
92
|
+
sage: F.domain()
|
|
93
|
+
Category of rings
|
|
94
|
+
sage: F.codomain()
|
|
95
|
+
Category of commutative additive groups
|
|
96
|
+
sage: from sage.categories.functor import Functor
|
|
97
|
+
sage: isinstance(F, Functor)
|
|
98
|
+
True
|
|
99
|
+
sage: I = IdentityFunctor(abgrps)
|
|
100
|
+
sage: I
|
|
101
|
+
The identity functor on Category of commutative additive groups
|
|
102
|
+
sage: I.domain()
|
|
103
|
+
Category of commutative additive groups
|
|
104
|
+
sage: isinstance(I, Functor)
|
|
105
|
+
True
|
|
106
|
+
|
|
107
|
+
Note that by default, an instance of the class Functor is coercion
|
|
108
|
+
from the domain into the codomain. The above subclasses overloaded
|
|
109
|
+
this behaviour. Here we illustrate the default::
|
|
110
|
+
|
|
111
|
+
sage: from sage.categories.functor import Functor
|
|
112
|
+
sage: F = Functor(Rings(), Fields())
|
|
113
|
+
sage: F
|
|
114
|
+
Functor from Category of rings to Category of fields
|
|
115
|
+
sage: F(ZZ)
|
|
116
|
+
Rational Field
|
|
117
|
+
sage: F(GF(2))
|
|
118
|
+
Finite Field of size 2
|
|
119
|
+
|
|
120
|
+
Functors are not only about the objects of a category, but also about
|
|
121
|
+
their morphisms. We illustrate it, again, with the coercion functor
|
|
122
|
+
from rings to fields.
|
|
123
|
+
|
|
124
|
+
::
|
|
125
|
+
|
|
126
|
+
sage: R1.<x> = ZZ[]
|
|
127
|
+
sage: R2.<a,b> = QQ[]
|
|
128
|
+
sage: f = R1.hom([a + b], R2)
|
|
129
|
+
sage: f
|
|
130
|
+
Ring morphism:
|
|
131
|
+
From: Univariate Polynomial Ring in x over Integer Ring
|
|
132
|
+
To: Multivariate Polynomial Ring in a, b over Rational Field
|
|
133
|
+
Defn: x |--> a + b
|
|
134
|
+
sage: F(f) # needs sage.libs.singular
|
|
135
|
+
Ring morphism:
|
|
136
|
+
From: Fraction Field of Univariate Polynomial Ring in x over Integer Ring
|
|
137
|
+
To: Fraction Field of Multivariate Polynomial Ring in a, b over Rational Field
|
|
138
|
+
Defn: x |--> a + b
|
|
139
|
+
sage: F(f)(1/x) # needs sage.libs.singular
|
|
140
|
+
1/(a + b)
|
|
141
|
+
|
|
142
|
+
We can also apply a polynomial ring construction functor to our homomorphism. The
|
|
143
|
+
result is a homomorphism that is defined on the base ring::
|
|
144
|
+
|
|
145
|
+
sage: F = QQ['t'].construction()[0]
|
|
146
|
+
sage: F
|
|
147
|
+
Poly[t]
|
|
148
|
+
sage: F(f)
|
|
149
|
+
Ring morphism:
|
|
150
|
+
From: Univariate Polynomial Ring in t
|
|
151
|
+
over Univariate Polynomial Ring in x over Integer Ring
|
|
152
|
+
To: Univariate Polynomial Ring in t
|
|
153
|
+
over Multivariate Polynomial Ring in a, b over Rational Field
|
|
154
|
+
Defn: Induced from base ring by
|
|
155
|
+
Ring morphism:
|
|
156
|
+
From: Univariate Polynomial Ring in x over Integer Ring
|
|
157
|
+
To: Multivariate Polynomial Ring in a, b over Rational Field
|
|
158
|
+
Defn: x |--> a + b
|
|
159
|
+
sage: p = R1['t']('(-x^2 + x)*t^2 + (x^2 - x)*t - 4*x^2 - x + 1')
|
|
160
|
+
sage: F(f)(p)
|
|
161
|
+
(-a^2 - 2*a*b - b^2 + a + b)*t^2 + (a^2 + 2*a*b + b^2 - a - b)*t
|
|
162
|
+
- 4*a^2 - 8*a*b - 4*b^2 - a - b + 1
|
|
163
|
+
"""
|
|
164
|
+
def __init__(self, domain, codomain):
|
|
165
|
+
"""
|
|
166
|
+
TESTS::
|
|
167
|
+
|
|
168
|
+
sage: from sage.categories.functor import Functor
|
|
169
|
+
sage: F = Functor(Rings(), Fields())
|
|
170
|
+
sage: F
|
|
171
|
+
Functor from Category of rings to Category of fields
|
|
172
|
+
sage: F(ZZ)
|
|
173
|
+
Rational Field
|
|
174
|
+
sage: F(GF(2))
|
|
175
|
+
Finite Field of size 2
|
|
176
|
+
"""
|
|
177
|
+
if not isinstance(domain, category.Category):
|
|
178
|
+
raise TypeError("domain (=%s) must be a category" % domain)
|
|
179
|
+
if not isinstance(codomain, category.Category):
|
|
180
|
+
raise TypeError("codomain (=%s) must be a category" % codomain)
|
|
181
|
+
self.__domain = domain
|
|
182
|
+
self.__codomain = codomain
|
|
183
|
+
|
|
184
|
+
def __hash__(self):
|
|
185
|
+
r"""
|
|
186
|
+
TESTS::
|
|
187
|
+
|
|
188
|
+
sage: from sage.categories.functor import Functor
|
|
189
|
+
sage: F = Functor(Rings(), Fields())
|
|
190
|
+
sage: hash(F) # random
|
|
191
|
+
42
|
|
192
|
+
"""
|
|
193
|
+
return hash(self.__domain) ^ hash(self.__codomain)
|
|
194
|
+
|
|
195
|
+
def __reduce__(self):
|
|
196
|
+
"""
|
|
197
|
+
Generic pickling of functors.
|
|
198
|
+
|
|
199
|
+
AUTHOR:
|
|
200
|
+
|
|
201
|
+
- Simon King (2010-12): :issue:`10460`
|
|
202
|
+
|
|
203
|
+
TESTS::
|
|
204
|
+
|
|
205
|
+
sage: from sage.categories.pushout import CompositeConstructionFunctor
|
|
206
|
+
sage: F = CompositeConstructionFunctor(QQ.construction()[0],ZZ['x'].construction()[0],QQ.construction()[0],ZZ['y'].construction()[0])
|
|
207
|
+
sage: F == loads(dumps(F))
|
|
208
|
+
True
|
|
209
|
+
sage: F.codomain()
|
|
210
|
+
Category of rings
|
|
211
|
+
"""
|
|
212
|
+
return (_Functor_unpickle,
|
|
213
|
+
(self.__class__, list(self.__dict__.items()),
|
|
214
|
+
self.__domain, self.__codomain))
|
|
215
|
+
|
|
216
|
+
def _apply_functor(self, x):
|
|
217
|
+
"""
|
|
218
|
+
Apply the functor to an object of ``self``'s domain.
|
|
219
|
+
|
|
220
|
+
NOTE:
|
|
221
|
+
|
|
222
|
+
Each subclass of :class:`Functor` should overload this method. By default,
|
|
223
|
+
this method coerces into the codomain, without checking whether the
|
|
224
|
+
argument belongs to the domain.
|
|
225
|
+
|
|
226
|
+
TESTS::
|
|
227
|
+
|
|
228
|
+
sage: from sage.categories.functor import Functor
|
|
229
|
+
sage: F = Functor(FiniteFields(), Fields())
|
|
230
|
+
sage: F._apply_functor(ZZ)
|
|
231
|
+
Rational Field
|
|
232
|
+
"""
|
|
233
|
+
return self.__codomain(x)
|
|
234
|
+
|
|
235
|
+
def _apply_functor_to_morphism(self, f):
|
|
236
|
+
"""
|
|
237
|
+
Apply the functor to a morphism between two objects of ``self``'s domain.
|
|
238
|
+
|
|
239
|
+
NOTE:
|
|
240
|
+
|
|
241
|
+
Each subclass of :class:`Functor` should overload this method. By
|
|
242
|
+
default, this method coerces into the codomain, without checking
|
|
243
|
+
whether the argument belongs to the domain.
|
|
244
|
+
|
|
245
|
+
TESTS::
|
|
246
|
+
|
|
247
|
+
sage: # needs sage.rings.finite_rings
|
|
248
|
+
sage: from sage.categories.functor import Functor
|
|
249
|
+
sage: F = Functor(Rings(), Fields())
|
|
250
|
+
sage: k.<a> = GF(25)
|
|
251
|
+
sage: f = k.hom([-a - 4])
|
|
252
|
+
sage: R.<t> = k[]
|
|
253
|
+
sage: fR = R.hom(f, R)
|
|
254
|
+
sage: fF = F(fR) # indirect doctest
|
|
255
|
+
sage: fF
|
|
256
|
+
Ring endomorphism of Fraction Field of
|
|
257
|
+
Univariate Polynomial Ring in t over Finite Field in a of size 5^2
|
|
258
|
+
Defn: Induced from base ring by
|
|
259
|
+
Ring endomorphism of Univariate Polynomial Ring in t
|
|
260
|
+
over Finite Field in a of size 5^2
|
|
261
|
+
Defn: Induced from base ring by
|
|
262
|
+
Ring endomorphism of Finite Field in a of size 5^2
|
|
263
|
+
Defn: a |--> 4*a + 1
|
|
264
|
+
sage: fF((a^2+a)*t^2/(a*t - a^2))
|
|
265
|
+
((4*a + 2)*t^2)/(t + a + 4)
|
|
266
|
+
"""
|
|
267
|
+
try:
|
|
268
|
+
return self(f.domain()).hom(f, self(f.codomain()))
|
|
269
|
+
except Exception:
|
|
270
|
+
raise TypeError(f'unable to transform {f} into a morphism in {self.codomain()}')
|
|
271
|
+
|
|
272
|
+
def _coerce_into_domain(self, x):
|
|
273
|
+
"""
|
|
274
|
+
Interpret the argument as an object of ``self``'s domain.
|
|
275
|
+
|
|
276
|
+
NOTE:
|
|
277
|
+
|
|
278
|
+
A subclass of :class:`Functor` may overload this method. It should
|
|
279
|
+
return an object of ``self``'s domain, and should raise a
|
|
280
|
+
:exc:`TypeError` if this is impossible.
|
|
281
|
+
|
|
282
|
+
By default, the argument will not be changed, but a
|
|
283
|
+
:exc:`TypeError` will be raised if the argument does not
|
|
284
|
+
belong to the domain.
|
|
285
|
+
|
|
286
|
+
TESTS::
|
|
287
|
+
|
|
288
|
+
sage: from sage.categories.functor import Functor
|
|
289
|
+
sage: F = Functor(Fields(),Fields())
|
|
290
|
+
sage: F(QQ)
|
|
291
|
+
Rational Field
|
|
292
|
+
sage: F(ZZ) # indirect doctest
|
|
293
|
+
Traceback (most recent call last):
|
|
294
|
+
...
|
|
295
|
+
TypeError: x (=Integer Ring) is not in Category of fields
|
|
296
|
+
"""
|
|
297
|
+
if x not in self.__domain:
|
|
298
|
+
raise TypeError("x (=%s) is not in %s" % (x, self.__domain))
|
|
299
|
+
return x
|
|
300
|
+
|
|
301
|
+
def _repr_(self):
|
|
302
|
+
"""
|
|
303
|
+
TESTS::
|
|
304
|
+
|
|
305
|
+
sage: from sage.categories.functor import Functor
|
|
306
|
+
sage: F = Functor(Rings(),Fields())
|
|
307
|
+
sage: F #indirect doctest
|
|
308
|
+
Functor from Category of rings to Category of fields
|
|
309
|
+
|
|
310
|
+
A functor can be renamed if its type is a Python class
|
|
311
|
+
(see :issue:`16156`)::
|
|
312
|
+
|
|
313
|
+
sage: I = IdentityFunctor(Rings()); I
|
|
314
|
+
The identity functor on Category of rings
|
|
315
|
+
sage: I.rename('Id'); I
|
|
316
|
+
Id
|
|
317
|
+
"""
|
|
318
|
+
return "Functor from %s to %s" % (self.__domain, self.__codomain)
|
|
319
|
+
|
|
320
|
+
def __call__(self, x):
|
|
321
|
+
"""
|
|
322
|
+
NOTE:
|
|
323
|
+
|
|
324
|
+
Implement _coerce_into_domain, _apply_functor and
|
|
325
|
+
_apply_functor_to_morphism when subclassing Functor.
|
|
326
|
+
|
|
327
|
+
TESTS:
|
|
328
|
+
|
|
329
|
+
The default::
|
|
330
|
+
|
|
331
|
+
sage: from sage.categories.functor import Functor
|
|
332
|
+
sage: F = Functor(Rings(),Fields())
|
|
333
|
+
sage: F
|
|
334
|
+
Functor from Category of rings to Category of fields
|
|
335
|
+
sage: F(ZZ)
|
|
336
|
+
Rational Field
|
|
337
|
+
sage: F(GF(2))
|
|
338
|
+
Finite Field of size 2
|
|
339
|
+
|
|
340
|
+
Two subclasses::
|
|
341
|
+
|
|
342
|
+
sage: F1 = ForgetfulFunctor(FiniteFields(), Fields())
|
|
343
|
+
sage: F1(GF(5)) # indirect doctest
|
|
344
|
+
Finite Field of size 5
|
|
345
|
+
sage: F1(ZZ)
|
|
346
|
+
Traceback (most recent call last):
|
|
347
|
+
...
|
|
348
|
+
TypeError: x (=Integer Ring) is not in Category of finite enumerated fields
|
|
349
|
+
sage: F2 = IdentityFunctor(Fields())
|
|
350
|
+
sage: F2(RR) is RR #indirect doctest
|
|
351
|
+
True
|
|
352
|
+
sage: F2(ZZ['x','y'])
|
|
353
|
+
Traceback (most recent call last):
|
|
354
|
+
...
|
|
355
|
+
TypeError: x (=Multivariate Polynomial Ring in x, y over Integer Ring)
|
|
356
|
+
is not in Category of fields
|
|
357
|
+
|
|
358
|
+
The last example shows that it is tested whether the result of
|
|
359
|
+
applying the functor lies in the functor's codomain. Note that
|
|
360
|
+
the matrix functor used to be defined similar to this example,
|
|
361
|
+
which was fixed in :issue:`8807`::
|
|
362
|
+
|
|
363
|
+
sage: class IllFunctor(Functor):
|
|
364
|
+
....: def __init__(self, m, n):
|
|
365
|
+
....: self._m = m
|
|
366
|
+
....: self._n = n
|
|
367
|
+
....: Functor.__init__(self, Rings(), Rings())
|
|
368
|
+
....: def _apply_functor(self, R):
|
|
369
|
+
....: return MatrixSpace(R, self._m, self._n)
|
|
370
|
+
sage: F = IllFunctor(2, 2)
|
|
371
|
+
sage: F(QQ) # needs sage.modules
|
|
372
|
+
Full MatrixSpace of 2 by 2 dense matrices over Rational Field
|
|
373
|
+
sage: F = IllFunctor(2, 3)
|
|
374
|
+
sage: F(QQ) # needs sage.modules
|
|
375
|
+
Traceback (most recent call last):
|
|
376
|
+
...
|
|
377
|
+
TypeError: Functor from Category of rings to Category of rings
|
|
378
|
+
is ill-defined, since it sends x (=Rational Field) to something
|
|
379
|
+
that is not in Category of rings.
|
|
380
|
+
"""
|
|
381
|
+
from sage.categories.morphism import Morphism
|
|
382
|
+
if isinstance(x, Morphism):
|
|
383
|
+
return self._apply_functor_to_morphism(x)
|
|
384
|
+
y = self._apply_functor(self._coerce_into_domain(x))
|
|
385
|
+
if not ((y in self.__codomain) or (y in self.__codomain.Homsets())):
|
|
386
|
+
raise TypeError("%s is ill-defined, since it sends x (=%s) to something that is not in %s." % (repr(self), x, self.__codomain))
|
|
387
|
+
return y
|
|
388
|
+
|
|
389
|
+
def domain(self):
|
|
390
|
+
"""
|
|
391
|
+
The domain of ``self``.
|
|
392
|
+
|
|
393
|
+
EXAMPLES::
|
|
394
|
+
|
|
395
|
+
sage: F = ForgetfulFunctor(FiniteFields(), Fields())
|
|
396
|
+
sage: F.domain()
|
|
397
|
+
Category of finite enumerated fields
|
|
398
|
+
"""
|
|
399
|
+
return self.__domain
|
|
400
|
+
|
|
401
|
+
def codomain(self):
|
|
402
|
+
"""
|
|
403
|
+
The codomain of ``self``.
|
|
404
|
+
|
|
405
|
+
EXAMPLES::
|
|
406
|
+
|
|
407
|
+
sage: F = ForgetfulFunctor(FiniteFields(), Fields())
|
|
408
|
+
sage: F.codomain()
|
|
409
|
+
Category of fields
|
|
410
|
+
"""
|
|
411
|
+
return self.__codomain
|
|
412
|
+
|
|
413
|
+
|
|
414
|
+
def is_Functor(x):
|
|
415
|
+
"""
|
|
416
|
+
Test whether the argument is a functor.
|
|
417
|
+
|
|
418
|
+
This function is deprecated.
|
|
419
|
+
|
|
420
|
+
EXAMPLES::
|
|
421
|
+
|
|
422
|
+
sage: from sage.categories.functor import is_Functor
|
|
423
|
+
sage: F1 = QQ.construction()[0]
|
|
424
|
+
sage: F1
|
|
425
|
+
FractionField
|
|
426
|
+
sage: is_Functor(F1)
|
|
427
|
+
doctest:warning...
|
|
428
|
+
DeprecationWarning: The function is_Functor is deprecated;
|
|
429
|
+
use 'isinstance(..., Functor)' instead.
|
|
430
|
+
See https://github.com/sagemath/sage/issues/38184 for details.
|
|
431
|
+
True
|
|
432
|
+
sage: is_Functor(FractionField)
|
|
433
|
+
False
|
|
434
|
+
sage: F2 = ForgetfulFunctor(Fields(), Rings())
|
|
435
|
+
sage: F2
|
|
436
|
+
The forgetful functor from Category of fields to Category of rings
|
|
437
|
+
sage: is_Functor(F2)
|
|
438
|
+
True
|
|
439
|
+
"""
|
|
440
|
+
from sage.misc.superseded import deprecation
|
|
441
|
+
deprecation(38184,
|
|
442
|
+
"The function is_Functor is deprecated; "
|
|
443
|
+
"use 'isinstance(..., Functor)' instead.")
|
|
444
|
+
return isinstance(x, Functor)
|
|
445
|
+
|
|
446
|
+
|
|
447
|
+
###########################################
|
|
448
|
+
# The natural functors in Sage
|
|
449
|
+
###########################################
|
|
450
|
+
|
|
451
|
+
class ForgetfulFunctor_generic(Functor):
|
|
452
|
+
"""
|
|
453
|
+
The forgetful functor, i.e., embedding of a subcategory.
|
|
454
|
+
|
|
455
|
+
NOTE:
|
|
456
|
+
|
|
457
|
+
Forgetful functors should be created using :func:`ForgetfulFunctor`,
|
|
458
|
+
since the init method of this class does not check whether the
|
|
459
|
+
domain is a subcategory of the codomain.
|
|
460
|
+
|
|
461
|
+
EXAMPLES::
|
|
462
|
+
|
|
463
|
+
sage: F = ForgetfulFunctor(FiniteFields(), Fields()) # indirect doctest
|
|
464
|
+
sage: F
|
|
465
|
+
The forgetful functor
|
|
466
|
+
from Category of finite enumerated fields
|
|
467
|
+
to Category of fields
|
|
468
|
+
sage: F(GF(3))
|
|
469
|
+
Finite Field of size 3
|
|
470
|
+
"""
|
|
471
|
+
def __reduce__(self):
|
|
472
|
+
"""
|
|
473
|
+
EXAMPLES::
|
|
474
|
+
|
|
475
|
+
sage: F = ForgetfulFunctor(Groups(), Sets())
|
|
476
|
+
sage: loads(F.dumps()) == F
|
|
477
|
+
True
|
|
478
|
+
"""
|
|
479
|
+
return ForgetfulFunctor, (self.domain(), self.codomain())
|
|
480
|
+
|
|
481
|
+
def _repr_(self):
|
|
482
|
+
"""
|
|
483
|
+
TESTS::
|
|
484
|
+
|
|
485
|
+
sage: F = ForgetfulFunctor(FiniteFields(), Fields())
|
|
486
|
+
sage: F # indirect doctest
|
|
487
|
+
The forgetful functor from Category of finite enumerated fields
|
|
488
|
+
to Category of fields
|
|
489
|
+
"""
|
|
490
|
+
return "The forgetful functor from %s to %s" % (self.domain(),
|
|
491
|
+
self.codomain())
|
|
492
|
+
|
|
493
|
+
def __eq__(self, other):
|
|
494
|
+
"""
|
|
495
|
+
NOTE:
|
|
496
|
+
|
|
497
|
+
It is tested whether the second argument belongs to the class
|
|
498
|
+
of forgetful functors and has the same domain and codomain as
|
|
499
|
+
``self``. If the second argument is a functor of a different class
|
|
500
|
+
but happens to be a forgetful functor, both arguments will
|
|
501
|
+
still be considered as being *different*.
|
|
502
|
+
|
|
503
|
+
TESTS::
|
|
504
|
+
|
|
505
|
+
sage: F1 = ForgetfulFunctor(FiniteFields(), Fields())
|
|
506
|
+
|
|
507
|
+
This is to test against a bug occurring in a previous version
|
|
508
|
+
(see :issue:`8800`)::
|
|
509
|
+
|
|
510
|
+
sage: F1 == QQ #indirect doctest
|
|
511
|
+
False
|
|
512
|
+
|
|
513
|
+
We now compare with the fraction field functor, that has a
|
|
514
|
+
different domain::
|
|
515
|
+
|
|
516
|
+
sage: F2 = QQ.construction()[0]
|
|
517
|
+
sage: F1 == F2 #indirect doctest
|
|
518
|
+
False
|
|
519
|
+
"""
|
|
520
|
+
from sage.categories.pushout import IdentityConstructionFunctor
|
|
521
|
+
if not isinstance(other, (self.__class__, IdentityConstructionFunctor)):
|
|
522
|
+
return False
|
|
523
|
+
return (self.domain() == other.domain() and
|
|
524
|
+
self.codomain() == other.codomain())
|
|
525
|
+
|
|
526
|
+
def __ne__(self, other):
|
|
527
|
+
"""
|
|
528
|
+
Return whether ``self`` is not equal to ``other``.
|
|
529
|
+
|
|
530
|
+
EXAMPLES::
|
|
531
|
+
|
|
532
|
+
sage: F1 = ForgetfulFunctor(FiniteFields(), Fields())
|
|
533
|
+
sage: F1 != F1
|
|
534
|
+
False
|
|
535
|
+
sage: F1 != QQ
|
|
536
|
+
True
|
|
537
|
+
"""
|
|
538
|
+
return not self == other
|
|
539
|
+
|
|
540
|
+
|
|
541
|
+
class IdentityFunctor_generic(ForgetfulFunctor_generic):
|
|
542
|
+
"""
|
|
543
|
+
Generic identity functor on any category.
|
|
544
|
+
|
|
545
|
+
NOTE:
|
|
546
|
+
|
|
547
|
+
This usually is created using :func:`IdentityFunctor`.
|
|
548
|
+
|
|
549
|
+
EXAMPLES::
|
|
550
|
+
|
|
551
|
+
sage: F = IdentityFunctor(Fields()) #indirect doctest
|
|
552
|
+
sage: F
|
|
553
|
+
The identity functor on Category of fields
|
|
554
|
+
sage: F(RR) is RR
|
|
555
|
+
True
|
|
556
|
+
sage: F(ZZ)
|
|
557
|
+
Traceback (most recent call last):
|
|
558
|
+
...
|
|
559
|
+
TypeError: x (=Integer Ring) is not in Category of fields
|
|
560
|
+
|
|
561
|
+
TESTS::
|
|
562
|
+
|
|
563
|
+
sage: R = IdentityFunctor(Rings())
|
|
564
|
+
sage: P, _ = QQ['t'].construction()
|
|
565
|
+
sage: R == P
|
|
566
|
+
False
|
|
567
|
+
sage: P == R
|
|
568
|
+
False
|
|
569
|
+
sage: R == QQ
|
|
570
|
+
False
|
|
571
|
+
"""
|
|
572
|
+
def __init__(self, C):
|
|
573
|
+
"""
|
|
574
|
+
TESTS::
|
|
575
|
+
|
|
576
|
+
sage: from sage.categories.functor import IdentityFunctor_generic
|
|
577
|
+
sage: F = IdentityFunctor_generic(Groups())
|
|
578
|
+
sage: F == IdentityFunctor(Groups())
|
|
579
|
+
True
|
|
580
|
+
sage: F
|
|
581
|
+
The identity functor on Category of groups
|
|
582
|
+
"""
|
|
583
|
+
ForgetfulFunctor_generic.__init__(self, C, C)
|
|
584
|
+
|
|
585
|
+
def __reduce__(self):
|
|
586
|
+
"""
|
|
587
|
+
EXAMPLES::
|
|
588
|
+
|
|
589
|
+
sage: F = IdentityFunctor(Groups())
|
|
590
|
+
sage: loads(F.dumps()) == F
|
|
591
|
+
True
|
|
592
|
+
"""
|
|
593
|
+
return IdentityFunctor, (self.domain(), )
|
|
594
|
+
|
|
595
|
+
def _repr_(self):
|
|
596
|
+
"""
|
|
597
|
+
TESTS::
|
|
598
|
+
|
|
599
|
+
sage: fields = Fields()
|
|
600
|
+
sage: F = IdentityFunctor(fields)
|
|
601
|
+
sage: F #indirect doctest
|
|
602
|
+
The identity functor on Category of fields
|
|
603
|
+
"""
|
|
604
|
+
return "The identity functor on %s" % (self.domain())
|
|
605
|
+
|
|
606
|
+
def _apply_functor(self, x):
|
|
607
|
+
"""
|
|
608
|
+
Apply the functor to an object of ``self``'s domain.
|
|
609
|
+
|
|
610
|
+
TESTS::
|
|
611
|
+
|
|
612
|
+
sage: fields = Fields()
|
|
613
|
+
sage: F = IdentityFunctor(fields)
|
|
614
|
+
sage: F._apply_functor(QQ)
|
|
615
|
+
Rational Field
|
|
616
|
+
|
|
617
|
+
It is not tested here whether the argument belongs to the domain
|
|
618
|
+
(this test is done in the default method ``_coerce_into_domain``)::
|
|
619
|
+
|
|
620
|
+
sage: F._apply_functor(ZZ)
|
|
621
|
+
Integer Ring
|
|
622
|
+
"""
|
|
623
|
+
return x
|
|
624
|
+
|
|
625
|
+
|
|
626
|
+
def IdentityFunctor(C):
|
|
627
|
+
"""
|
|
628
|
+
Construct the identity functor of the given category.
|
|
629
|
+
|
|
630
|
+
INPUT:
|
|
631
|
+
|
|
632
|
+
- ``C`` -- a category
|
|
633
|
+
|
|
634
|
+
OUTPUT: the identity functor in ``C``
|
|
635
|
+
|
|
636
|
+
EXAMPLES::
|
|
637
|
+
|
|
638
|
+
sage: rings = Rings()
|
|
639
|
+
sage: F = IdentityFunctor(rings)
|
|
640
|
+
sage: F(ZZ['x','y']) is ZZ['x','y']
|
|
641
|
+
True
|
|
642
|
+
"""
|
|
643
|
+
return IdentityFunctor_generic(C)
|
|
644
|
+
|
|
645
|
+
|
|
646
|
+
def ForgetfulFunctor(domain, codomain):
|
|
647
|
+
"""
|
|
648
|
+
Construct the forgetful function from one category to another.
|
|
649
|
+
|
|
650
|
+
INPUT:
|
|
651
|
+
|
|
652
|
+
- ``C``, ``D`` -- two categories
|
|
653
|
+
|
|
654
|
+
OUTPUT:
|
|
655
|
+
|
|
656
|
+
A functor that returns the corresponding object of ``D`` for
|
|
657
|
+
any element of ``C``, by forgetting the extra structure.
|
|
658
|
+
|
|
659
|
+
ASSUMPTION:
|
|
660
|
+
|
|
661
|
+
The category ``C`` must be a sub-category of ``D``.
|
|
662
|
+
|
|
663
|
+
EXAMPLES::
|
|
664
|
+
|
|
665
|
+
sage: rings = Rings()
|
|
666
|
+
sage: abgrps = CommutativeAdditiveGroups()
|
|
667
|
+
sage: F = ForgetfulFunctor(rings, abgrps)
|
|
668
|
+
sage: F
|
|
669
|
+
The forgetful functor
|
|
670
|
+
from Category of rings
|
|
671
|
+
to Category of commutative additive groups
|
|
672
|
+
|
|
673
|
+
It would be a mistake to call it in opposite order::
|
|
674
|
+
|
|
675
|
+
sage: F = ForgetfulFunctor(abgrps, rings)
|
|
676
|
+
Traceback (most recent call last):
|
|
677
|
+
...
|
|
678
|
+
ValueError: Forgetful functor not supported for domain
|
|
679
|
+
Category of commutative additive groups
|
|
680
|
+
|
|
681
|
+
If both categories are equal, the forgetful functor is the same as the
|
|
682
|
+
identity functor::
|
|
683
|
+
|
|
684
|
+
sage: ForgetfulFunctor(abgrps, abgrps) == IdentityFunctor(abgrps)
|
|
685
|
+
True
|
|
686
|
+
"""
|
|
687
|
+
if domain == codomain:
|
|
688
|
+
return IdentityFunctor(domain)
|
|
689
|
+
if not domain.is_subcategory(codomain):
|
|
690
|
+
raise ValueError("Forgetful functor not supported for domain %s" % domain)
|
|
691
|
+
return ForgetfulFunctor_generic(domain, codomain)
|