passagemath-objects 10.6.41__cp312-cp312-win_amd64.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.
- passagemath_objects/__init__.py +3 -0
- passagemath_objects-10.6.41.dist-info/DELVEWHEEL +2 -0
- passagemath_objects-10.6.41.dist-info/METADATA +115 -0
- passagemath_objects-10.6.41.dist-info/RECORD +281 -0
- passagemath_objects-10.6.41.dist-info/WHEEL +5 -0
- passagemath_objects-10.6.41.dist-info/top_level.txt +3 -0
- passagemath_objects.libs/libgmp-10-79b4110c7ea2b760f16cfef97e8a8a34.dll +0 -0
- sage/all__sagemath_objects.py +46 -0
- sage/arith/all__sagemath_objects.py +5 -0
- sage/arith/long.pxd +411 -0
- sage/arith/numerical_approx.cp312-win_amd64.pyd +0 -0
- sage/arith/numerical_approx.pxd +35 -0
- sage/arith/numerical_approx.pyx +75 -0
- sage/arith/power.cp312-win_amd64.pyd +0 -0
- sage/arith/power.pxd +31 -0
- sage/arith/power.pyx +127 -0
- sage/categories/action.cp312-win_amd64.pyd +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 +71 -0
- sage/categories/cartesian_product.py +295 -0
- sage/categories/category.py +3401 -0
- sage/categories/category_cy_helper.cp312-win_amd64.pyd +0 -0
- sage/categories/category_cy_helper.pxd +8 -0
- sage/categories/category_cy_helper.pyx +322 -0
- sage/categories/category_singleton.cp312-win_amd64.pyd +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 +2885 -0
- sage/categories/covariant_functorial_construction.py +703 -0
- sage/categories/facade_sets.py +228 -0
- sage/categories/functor.cp312-win_amd64.pyd +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.cp312-win_amd64.pyd +0 -0
- sage/categories/map.pxd +34 -0
- sage/categories/map.pyx +2112 -0
- sage/categories/morphism.cp312-win_amd64.pyd +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 +28 -0
- sage/cpython/_py2_random.py +619 -0
- sage/cpython/all.py +3 -0
- sage/cpython/atexit.cp312-win_amd64.pyd +0 -0
- sage/cpython/atexit.pyx +269 -0
- sage/cpython/builtin_types.cp312-win_amd64.pyd +0 -0
- sage/cpython/builtin_types.pyx +7 -0
- sage/cpython/cython_metaclass.cp312-win_amd64.pyd +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.cp312-win_amd64.pyd +0 -0
- sage/cpython/debug.pyx +302 -0
- sage/cpython/dict_del_by_value.cp312-win_amd64.pyd +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.cp312-win_amd64.pyd +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.cp312-win_amd64.pyd +0 -0
- sage/cpython/string.pxd +76 -0
- sage/cpython/string.pyx +34 -0
- sage/cpython/string_impl.h +60 -0
- sage/cpython/type.cp312-win_amd64.pyd +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.cp312-win_amd64.pyd +0 -0
- sage/groups/group.pxd +14 -0
- sage/groups/group.pyx +322 -0
- sage/groups/old.cp312-win_amd64.pyd +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.cp312-win_amd64.pyd +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.cp312-win_amd64.pyd +0 -0
- sage/misc/c3_controlled.pxd +2 -0
- sage/misc/c3_controlled.pyx +1402 -0
- sage/misc/cachefunc.cp312-win_amd64.pyd +0 -0
- sage/misc/cachefunc.pxd +43 -0
- sage/misc/cachefunc.pyx +3781 -0
- sage/misc/call.py +188 -0
- sage/misc/classcall_metaclass.cp312-win_amd64.pyd +0 -0
- sage/misc/classcall_metaclass.pxd +14 -0
- sage/misc/classcall_metaclass.pyx +599 -0
- sage/misc/constant_function.cp312-win_amd64.pyd +0 -0
- sage/misc/constant_function.pyx +130 -0
- sage/misc/decorators.py +747 -0
- sage/misc/fast_methods.cp312-win_amd64.pyd +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.cp312-win_amd64.pyd +0 -0
- sage/misc/fpickle.pyx +177 -0
- sage/misc/function_mangling.cp312-win_amd64.pyd +0 -0
- sage/misc/function_mangling.pxd +11 -0
- sage/misc/function_mangling.pyx +308 -0
- sage/misc/inherit_comparison.cp312-win_amd64.pyd +0 -0
- sage/misc/inherit_comparison.pxd +5 -0
- sage/misc/inherit_comparison.pyx +105 -0
- sage/misc/instancedoc.cp312-win_amd64.pyd +0 -0
- sage/misc/instancedoc.pyx +331 -0
- sage/misc/lazy_attribute.cp312-win_amd64.pyd +0 -0
- sage/misc/lazy_attribute.pyx +607 -0
- sage/misc/lazy_format.py +135 -0
- sage/misc/lazy_import.cp312-win_amd64.pyd +0 -0
- sage/misc/lazy_import.pyx +1299 -0
- sage/misc/lazy_import_cache.py +36 -0
- sage/misc/lazy_list.cp312-win_amd64.pyd +0 -0
- sage/misc/lazy_list.pxd +19 -0
- sage/misc/lazy_list.pyx +1187 -0
- sage/misc/lazy_string.cp312-win_amd64.pyd +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.cp312-win_amd64.pyd +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.cp312-win_amd64.pyd +0 -0
- sage/misc/nested_class.pxd +3 -0
- sage/misc/nested_class.pyx +394 -0
- sage/misc/persist.cp312-win_amd64.pyd +0 -0
- sage/misc/persist.pyx +1251 -0
- sage/misc/prandom.py +418 -0
- sage/misc/randstate.cp312-win_amd64.pyd +0 -0
- sage/misc/randstate.pxd +30 -0
- sage/misc/randstate.pyx +1059 -0
- sage/misc/repr.py +203 -0
- sage/misc/reset.cp312-win_amd64.pyd +0 -0
- sage/misc/reset.pyx +196 -0
- sage/misc/sage_ostools.cp312-win_amd64.pyd +0 -0
- sage/misc/sage_ostools.pyx +323 -0
- sage/misc/sage_timeit.py +276 -0
- sage/misc/sage_timeit_class.cp312-win_amd64.pyd +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.cp312-win_amd64.pyd +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.cp312-win_amd64.pyd +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.cp312-win_amd64.pyd +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.cp312-win_amd64.pyd +0 -0
- sage/sets/pythonclass.pxd +9 -0
- sage/sets/pythonclass.pyx +247 -0
- sage/structure/__init__.py +13 -0
- sage/structure/all.py +30 -0
- sage/structure/category_object.cp312-win_amd64.pyd +0 -0
- sage/structure/category_object.pxd +28 -0
- sage/structure/category_object.pyx +1087 -0
- sage/structure/coerce.cp312-win_amd64.pyd +0 -0
- sage/structure/coerce.pxd +44 -0
- sage/structure/coerce.pyx +2107 -0
- sage/structure/coerce_actions.cp312-win_amd64.pyd +0 -0
- sage/structure/coerce_actions.pxd +27 -0
- sage/structure/coerce_actions.pyx +988 -0
- sage/structure/coerce_dict.cp312-win_amd64.pyd +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.cp312-win_amd64.pyd +0 -0
- sage/structure/coerce_maps.pxd +28 -0
- sage/structure/coerce_maps.pyx +718 -0
- sage/structure/debug_options.cp312-win_amd64.pyd +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.cp312-win_amd64.pyd +0 -0
- sage/structure/element.pxd +272 -0
- sage/structure/element.pyx +4772 -0
- sage/structure/element_wrapper.cp312-win_amd64.pyd +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.cp312-win_amd64.pyd +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.cp312-win_amd64.pyd +0 -0
- sage/structure/list_clone.pxd +65 -0
- sage/structure/list_clone.pyx +1867 -0
- sage/structure/list_clone_demo.cp312-win_amd64.pyd +0 -0
- sage/structure/list_clone_demo.pyx +248 -0
- sage/structure/list_clone_timings.py +179 -0
- sage/structure/list_clone_timings_cy.cp312-win_amd64.pyd +0 -0
- sage/structure/list_clone_timings_cy.pyx +86 -0
- sage/structure/mutability.cp312-win_amd64.pyd +0 -0
- sage/structure/mutability.pxd +21 -0
- sage/structure/mutability.pyx +348 -0
- sage/structure/nonexact.py +69 -0
- sage/structure/parent.cp312-win_amd64.pyd +0 -0
- sage/structure/parent.pxd +112 -0
- sage/structure/parent.pyx +3093 -0
- sage/structure/parent_base.cp312-win_amd64.pyd +0 -0
- sage/structure/parent_base.pxd +13 -0
- sage/structure/parent_base.pyx +44 -0
- sage/structure/parent_gens.cp312-win_amd64.pyd +0 -0
- sage/structure/parent_gens.pxd +22 -0
- sage/structure/parent_gens.pyx +377 -0
- sage/structure/parent_old.cp312-win_amd64.pyd +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.cp312-win_amd64.pyd +0 -0
- sage/structure/richcmp.pxd +213 -0
- sage/structure/richcmp.pyx +495 -0
- sage/structure/sage_object.cp312-win_amd64.pyd +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
|
Binary file
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-objects
|
|
2
|
+
cpdef tuple _sort_uniq(categories)
|
|
3
|
+
cdef class AxiomContainer(dict):
|
|
4
|
+
pass
|
|
5
|
+
cpdef tuple canonicalize_axioms(AxiomContainer all_axioms, axioms)
|
|
6
|
+
from sage.misc.classcall_metaclass cimport ClasscallMetaclass
|
|
7
|
+
cpdef tuple _flatten_categories(categories, ClasscallMetaclass JoinCategory)
|
|
8
|
+
cpdef tuple join_as_tuple(tuple categories, tuple axioms, tuple ignore_axioms)
|
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-objects
|
|
2
|
+
"""
|
|
3
|
+
Fast functions for the category framework
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
AUTHOR:
|
|
7
|
+
|
|
8
|
+
- Simon King (initial version)
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
# ****************************************************************************
|
|
12
|
+
# Copyright (C) 2014 Simon King <simon.king@uni-jena.de>
|
|
13
|
+
#
|
|
14
|
+
# This program is free software: you can redistribute it and/or modify
|
|
15
|
+
# it under the terms of the GNU General Public License as published by
|
|
16
|
+
# the Free Software Foundation, either version 2 of the License, or
|
|
17
|
+
# (at your option) any later version.
|
|
18
|
+
# https://www.gnu.org/licenses/
|
|
19
|
+
# ****************************************************************************
|
|
20
|
+
|
|
21
|
+
#######################################
|
|
22
|
+
# Sorting
|
|
23
|
+
|
|
24
|
+
cpdef inline tuple category_sort_key(object category):
|
|
25
|
+
"""
|
|
26
|
+
Return ``category._cmp_key``.
|
|
27
|
+
|
|
28
|
+
This helper function is used for sorting lists of categories.
|
|
29
|
+
|
|
30
|
+
It is semantically equivalent to
|
|
31
|
+
:func:`operator.attrgetter` ``("_cmp_key")``, but currently faster.
|
|
32
|
+
|
|
33
|
+
EXAMPLES::
|
|
34
|
+
|
|
35
|
+
sage: from sage.categories.category_cy_helper import category_sort_key
|
|
36
|
+
sage: category_sort_key(Rings()) is Rings()._cmp_key
|
|
37
|
+
True
|
|
38
|
+
"""
|
|
39
|
+
return category._cmp_key
|
|
40
|
+
|
|
41
|
+
cpdef tuple _sort_uniq(categories):
|
|
42
|
+
"""
|
|
43
|
+
Return the categories after sorting them and removing redundant categories.
|
|
44
|
+
|
|
45
|
+
Redundant categories include duplicates and categories which
|
|
46
|
+
are super categories of other categories in the input.
|
|
47
|
+
|
|
48
|
+
INPUT:
|
|
49
|
+
|
|
50
|
+
- ``categories`` -- list (or iterable) of categories
|
|
51
|
+
|
|
52
|
+
OUTPUT: a sorted tuple of mutually incomparable categories
|
|
53
|
+
|
|
54
|
+
EXAMPLES::
|
|
55
|
+
|
|
56
|
+
sage: Category._sort_uniq([Rings(), Monoids(), Coalgebras(QQ)])
|
|
57
|
+
(Category of rings, Category of coalgebras over Rational Field)
|
|
58
|
+
|
|
59
|
+
Note that, in the above example, ``Monoids()`` does not appear
|
|
60
|
+
in the result because it is a super category of ``Rings()``.
|
|
61
|
+
"""
|
|
62
|
+
cdef tuple cats = tuple(sorted(categories, key=category_sort_key, reverse=True))
|
|
63
|
+
cdef list result = []
|
|
64
|
+
cdef bint append
|
|
65
|
+
for category in cats:
|
|
66
|
+
append = True
|
|
67
|
+
for cat in result:
|
|
68
|
+
if cat.is_subcategory(category):
|
|
69
|
+
append = False
|
|
70
|
+
break
|
|
71
|
+
if append:
|
|
72
|
+
result.append(category)
|
|
73
|
+
return tuple(result)
|
|
74
|
+
|
|
75
|
+
cpdef tuple _flatten_categories(categories, ClasscallMetaclass JoinCategory):
|
|
76
|
+
"""
|
|
77
|
+
Return the tuple of categories in ``categories``, while
|
|
78
|
+
flattening join categories.
|
|
79
|
+
|
|
80
|
+
INPUT:
|
|
81
|
+
|
|
82
|
+
- ``categories`` -- list (or iterable) of categories
|
|
83
|
+
|
|
84
|
+
- ``JoinCategory`` -- a type such that instances of that type will be
|
|
85
|
+
replaced by its super categories. Usually, this type is
|
|
86
|
+
:class:`JoinCategory`.
|
|
87
|
+
|
|
88
|
+
.. NOTE::
|
|
89
|
+
|
|
90
|
+
It is needed to provide :class:`~sage.categories.category.JoinCategory` as
|
|
91
|
+
an argument, since we need to prevent a circular import.
|
|
92
|
+
|
|
93
|
+
EXAMPLES::
|
|
94
|
+
|
|
95
|
+
sage: Category._flatten_categories([Algebras(QQ), Category.join([Monoids(), Coalgebras(QQ)]), Sets()], sage.categories.category.JoinCategory)
|
|
96
|
+
(Category of algebras over Rational Field, Category of monoids,
|
|
97
|
+
Category of coalgebras over Rational Field, Category of sets)
|
|
98
|
+
"""
|
|
99
|
+
# Invariant: the super categories of a JoinCategory are not JoinCategories themselves
|
|
100
|
+
cdef list out = []
|
|
101
|
+
for category in categories:
|
|
102
|
+
if isinstance(category, JoinCategory):
|
|
103
|
+
out.extend(category.super_categories())
|
|
104
|
+
else:
|
|
105
|
+
out.append(category)
|
|
106
|
+
return tuple(out)
|
|
107
|
+
|
|
108
|
+
#############################################
|
|
109
|
+
# Join
|
|
110
|
+
|
|
111
|
+
cdef bint is_supercategory_of_done(new_cat, dict done) noexcept:
|
|
112
|
+
# This is a helper function. It replaces the closure
|
|
113
|
+
# any(cat.is_subcategory(new_cat) for cat in done)
|
|
114
|
+
for cat in done:
|
|
115
|
+
if cat.is_subcategory(new_cat):
|
|
116
|
+
return True
|
|
117
|
+
return False
|
|
118
|
+
|
|
119
|
+
cpdef tuple join_as_tuple(tuple categories, tuple axioms, tuple ignore_axioms):
|
|
120
|
+
"""
|
|
121
|
+
Helper for :meth:`~sage.categories.category.Category.join`.
|
|
122
|
+
|
|
123
|
+
INPUT:
|
|
124
|
+
|
|
125
|
+
- ``categories`` -- tuple of categories to be joined
|
|
126
|
+
- ``axioms`` -- tuple of strings; the names of some
|
|
127
|
+
supplementary axioms
|
|
128
|
+
- ``ignore_axioms`` -- tuple of pairs ``(cat, axiom)``, such
|
|
129
|
+
that ``axiom`` will not be applied to ``cat``, should ``cat``
|
|
130
|
+
occur in the algorithm
|
|
131
|
+
|
|
132
|
+
EXAMPLES::
|
|
133
|
+
|
|
134
|
+
sage: from sage.categories.category_cy_helper import join_as_tuple
|
|
135
|
+
sage: T = (Coalgebras(QQ), Sets().Finite(), Algebras(ZZ), SimplicialComplexes())
|
|
136
|
+
sage: join_as_tuple(T,(),())
|
|
137
|
+
(Category of algebras over Integer Ring,
|
|
138
|
+
Category of finite monoids,
|
|
139
|
+
Category of finite additive groups,
|
|
140
|
+
Category of coalgebras over Rational Field,
|
|
141
|
+
Category of finite simplicial complexes)
|
|
142
|
+
sage: join_as_tuple(T,('WithBasis',),())
|
|
143
|
+
(Category of algebras with basis over Integer Ring,
|
|
144
|
+
Category of finite monoids,
|
|
145
|
+
Category of coalgebras with basis over Rational Field,
|
|
146
|
+
Category of finite additive groups,
|
|
147
|
+
Category of finite simplicial complexes)
|
|
148
|
+
sage: join_as_tuple(T,(),((Monoids(),'Finite'),))
|
|
149
|
+
(Category of algebras over Integer Ring,
|
|
150
|
+
Category of finite additive groups,
|
|
151
|
+
Category of coalgebras over Rational Field,
|
|
152
|
+
Category of finite simplicial complexes)
|
|
153
|
+
"""
|
|
154
|
+
cdef set axiomsS = set(axioms)
|
|
155
|
+
for category in categories:
|
|
156
|
+
axiomsS.update(category.axioms())
|
|
157
|
+
cdef dict done = dict()
|
|
158
|
+
cdef set todo = set()
|
|
159
|
+
cdef frozenset axs
|
|
160
|
+
for category in categories:
|
|
161
|
+
axs = category.axioms()
|
|
162
|
+
for (cat, axiom) in ignore_axioms:
|
|
163
|
+
if category.is_subcategory(cat):
|
|
164
|
+
axs = axs | {axiom}
|
|
165
|
+
done[category] = axs
|
|
166
|
+
for axiom in axiomsS.difference(axs):
|
|
167
|
+
todo.add((category, axiom))
|
|
168
|
+
|
|
169
|
+
# Invariants:
|
|
170
|
+
# - the current list of categories is stored in the keys of ``done``
|
|
171
|
+
# - todo contains the ``complement`` of done; i.e.
|
|
172
|
+
# for category in the keys of done,
|
|
173
|
+
# (category, axiom) is in todo iff axiom is not in done[category]
|
|
174
|
+
cdef list new_cats
|
|
175
|
+
cdef set new_axioms
|
|
176
|
+
while todo:
|
|
177
|
+
(category, axiom) = todo.pop()
|
|
178
|
+
# It's easier to remove categories from done than from todo
|
|
179
|
+
# So we check that ``category`` had not been removed
|
|
180
|
+
if category not in done:
|
|
181
|
+
continue
|
|
182
|
+
|
|
183
|
+
# Removes redundant categories
|
|
184
|
+
new_cats = [new_cat for new_cat in <tuple>(category._with_axiom_as_tuple(axiom))
|
|
185
|
+
if not is_supercategory_of_done(new_cat, done)]
|
|
186
|
+
for cat in list(done.keys()):
|
|
187
|
+
for new_cat in new_cats:
|
|
188
|
+
if new_cat.is_subcategory(cat):
|
|
189
|
+
del done[cat]
|
|
190
|
+
break
|
|
191
|
+
|
|
192
|
+
new_axioms = set()
|
|
193
|
+
for new_cat in new_cats:
|
|
194
|
+
for axiom in new_cat.axioms():
|
|
195
|
+
if axiom not in axiomsS:
|
|
196
|
+
new_axioms.add(axiom)
|
|
197
|
+
|
|
198
|
+
# Mark old categories with new axioms as todo
|
|
199
|
+
for category in done:
|
|
200
|
+
for axiom in new_axioms:
|
|
201
|
+
todo.add((category, axiom))
|
|
202
|
+
for new_cat in new_cats:
|
|
203
|
+
axs = new_cat.axioms()
|
|
204
|
+
for (cat, axiom) in ignore_axioms:
|
|
205
|
+
if new_cat.is_subcategory(cat):
|
|
206
|
+
axs = axs | {axiom}
|
|
207
|
+
done[new_cat] = axs
|
|
208
|
+
for axiom in axiomsS.difference(axs):
|
|
209
|
+
todo.add((new_cat, axiom))
|
|
210
|
+
|
|
211
|
+
return _sort_uniq(done)
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
#############################################
|
|
215
|
+
# Axiom related functions
|
|
216
|
+
|
|
217
|
+
cdef class AxiomContainer(dict):
|
|
218
|
+
"""
|
|
219
|
+
A fast container for axioms.
|
|
220
|
+
|
|
221
|
+
This is derived from :class:`dict`. A key is the name of an axiom. The
|
|
222
|
+
corresponding value is the "rank" of this axiom, that is used to order the
|
|
223
|
+
axioms in :func:`canonicalize_axioms`.
|
|
224
|
+
|
|
225
|
+
EXAMPLES::
|
|
226
|
+
|
|
227
|
+
sage: all_axioms = sage.categories.category_with_axiom.all_axioms
|
|
228
|
+
sage: isinstance(all_axioms, sage.categories.category_with_axiom.AxiomContainer)
|
|
229
|
+
True
|
|
230
|
+
"""
|
|
231
|
+
def add(self, axiom):
|
|
232
|
+
"""
|
|
233
|
+
Add a new axiom name, of the next rank.
|
|
234
|
+
|
|
235
|
+
EXAMPLES::
|
|
236
|
+
|
|
237
|
+
sage: all_axioms = sage.categories.category_with_axiom.all_axioms
|
|
238
|
+
sage: m = max(all_axioms.values())
|
|
239
|
+
sage: all_axioms.add('Awesome')
|
|
240
|
+
sage: all_axioms['Awesome'] == m + 1
|
|
241
|
+
True
|
|
242
|
+
|
|
243
|
+
To avoid side effects, we remove the added axiom::
|
|
244
|
+
|
|
245
|
+
sage: del all_axioms['Awesome']
|
|
246
|
+
"""
|
|
247
|
+
self[axiom] = len(self)
|
|
248
|
+
|
|
249
|
+
def __iadd__(self, L):
|
|
250
|
+
"""
|
|
251
|
+
Inline addition, which means to add a list of axioms to the container.
|
|
252
|
+
|
|
253
|
+
EXAMPLES::
|
|
254
|
+
|
|
255
|
+
sage: all_axioms = sage.categories.category_with_axiom.all_axioms
|
|
256
|
+
sage: m = max(all_axioms.values())
|
|
257
|
+
sage: all_axioms += ('Fancy', 'Awesome')
|
|
258
|
+
sage: all_axioms['Awesome'] == m + 2
|
|
259
|
+
True
|
|
260
|
+
|
|
261
|
+
To avoid side effects, we delete the axioms that we just added::
|
|
262
|
+
|
|
263
|
+
sage: del all_axioms['Awesome'], all_axioms['Fancy']
|
|
264
|
+
"""
|
|
265
|
+
for axiom in L:
|
|
266
|
+
self.add(axiom)
|
|
267
|
+
return self
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
cpdef inline get_axiom_index(AxiomContainer all_axioms, str axiom):
|
|
271
|
+
"""
|
|
272
|
+
Helper function: Return the rank of an axiom.
|
|
273
|
+
|
|
274
|
+
INPUT:
|
|
275
|
+
|
|
276
|
+
- ``all_axioms`` -- the axiom collection
|
|
277
|
+
- ``axiom`` -- string, name of an axiom
|
|
278
|
+
|
|
279
|
+
EXAMPLES::
|
|
280
|
+
|
|
281
|
+
sage: all_axioms = sage.categories.category_with_axiom.all_axioms
|
|
282
|
+
sage: from sage.categories.category_cy_helper import get_axiom_index
|
|
283
|
+
sage: get_axiom_index(all_axioms, 'AdditiveCommutative') == all_axioms['AdditiveCommutative']
|
|
284
|
+
True
|
|
285
|
+
"""
|
|
286
|
+
return (<dict>all_axioms)[axiom]
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
cpdef tuple canonicalize_axioms(AxiomContainer all_axioms, axioms):
|
|
290
|
+
r"""
|
|
291
|
+
Canonicalize a set of axioms.
|
|
292
|
+
|
|
293
|
+
INPUT:
|
|
294
|
+
|
|
295
|
+
- ``all_axioms`` -- all available axioms
|
|
296
|
+
|
|
297
|
+
- ``axioms`` -- set (or iterable) of axioms
|
|
298
|
+
|
|
299
|
+
.. NOTE::
|
|
300
|
+
|
|
301
|
+
:class:`AxiomContainer` provides a fast container for axioms, and the
|
|
302
|
+
collection of axioms is stored in
|
|
303
|
+
:mod:`sage.categories.category_with_axiom`. In order to avoid circular
|
|
304
|
+
imports, we expect that the collection of all axioms is provided as an
|
|
305
|
+
argument to this auxiliary function.
|
|
306
|
+
|
|
307
|
+
OUTPUT:
|
|
308
|
+
|
|
309
|
+
A set of axioms as a tuple sorted according to the order of the
|
|
310
|
+
tuple ``all_axioms`` in :mod:`sage.categories.category_with_axiom`.
|
|
311
|
+
|
|
312
|
+
EXAMPLES::
|
|
313
|
+
|
|
314
|
+
sage: from sage.categories.category_with_axiom import canonicalize_axioms, all_axioms
|
|
315
|
+
sage: canonicalize_axioms(all_axioms, ["Commutative", "Connected", "WithBasis", "Finite"])
|
|
316
|
+
('Finite', 'Connected', 'WithBasis', 'Commutative')
|
|
317
|
+
sage: canonicalize_axioms(all_axioms, ["Commutative", "Connected", "Commutative", "WithBasis", "Finite"])
|
|
318
|
+
('Finite', 'Connected', 'WithBasis', 'Commutative')
|
|
319
|
+
"""
|
|
320
|
+
cdef list L = list(set(axioms))
|
|
321
|
+
L.sort(key=(all_axioms).__getitem__)
|
|
322
|
+
return tuple(L)
|
|
Binary file
|
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-objects
|
|
2
|
+
r"""
|
|
3
|
+
Singleton categories
|
|
4
|
+
"""
|
|
5
|
+
# ****************************************************************************
|
|
6
|
+
# Copyright (C) 2011 Simon King <simon.king@uni-jena.de>
|
|
7
|
+
# Nicolas M. Thiery <nthiery at users.sf.net>
|
|
8
|
+
#
|
|
9
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
10
|
+
# https://www.gnu.org/licenses/
|
|
11
|
+
# *****************************************************************************
|
|
12
|
+
from cpython.type cimport PyType_IsSubtype
|
|
13
|
+
|
|
14
|
+
from sage.misc.constant_function import ConstantFunction
|
|
15
|
+
from sage.misc.lazy_attribute import lazy_class_attribute
|
|
16
|
+
from sage.categories.category import Category
|
|
17
|
+
from sage.structure.category_object cimport CategoryObject
|
|
18
|
+
from sage.structure.dynamic_class import DynamicMetaclass
|
|
19
|
+
|
|
20
|
+
# This helper class is used to implement Category_singleton.__contains__
|
|
21
|
+
# In particular, the docstring is what appears upon C.__contains__?
|
|
22
|
+
# for C a singleton category like Fields().
|
|
23
|
+
|
|
24
|
+
cdef class Category_contains_method_by_parent_class:
|
|
25
|
+
"""
|
|
26
|
+
Return whether ``x`` is an object in this category.
|
|
27
|
+
|
|
28
|
+
More specifically, returns ``True`` if and only if ``x`` has a
|
|
29
|
+
category which is a subcategory of this one.
|
|
30
|
+
|
|
31
|
+
EXAMPLES::
|
|
32
|
+
|
|
33
|
+
sage: ZZ in Sets()
|
|
34
|
+
True
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
def __init__(self, category):
|
|
38
|
+
"""
|
|
39
|
+
TESTS::
|
|
40
|
+
|
|
41
|
+
sage: from sage.categories.category_singleton import Category_contains_method_by_parent_class
|
|
42
|
+
sage: Category_contains_method_by_parent_class(Rings())
|
|
43
|
+
<sage.categories.category_singleton.Category_contains_method_by_parent_class object at ...
|
|
44
|
+
"""
|
|
45
|
+
self._parent_class_of_category = <type> category.parent_class
|
|
46
|
+
|
|
47
|
+
def __call__(self, x):
|
|
48
|
+
"""
|
|
49
|
+
EXAMPLES::
|
|
50
|
+
|
|
51
|
+
sage: from sage.categories.category_singleton import Category_contains_method_by_parent_class
|
|
52
|
+
sage: in_Fields = Category_contains_method_by_parent_class(Fields())
|
|
53
|
+
sage: in_Fields(QQ)
|
|
54
|
+
True
|
|
55
|
+
sage: in_Fields(ZZ)
|
|
56
|
+
False
|
|
57
|
+
sage: in_Fields(1) # Not a CategoryObject
|
|
58
|
+
False
|
|
59
|
+
sage: in_Fields(int(1)) # Not a SageObject
|
|
60
|
+
False
|
|
61
|
+
|
|
62
|
+
TESTS:
|
|
63
|
+
|
|
64
|
+
The following used to segfault in a preliminary version of the
|
|
65
|
+
code::
|
|
66
|
+
|
|
67
|
+
sage: None in Rings()
|
|
68
|
+
False
|
|
69
|
+
"""
|
|
70
|
+
if x is None:
|
|
71
|
+
return False
|
|
72
|
+
cdef CategoryObject y
|
|
73
|
+
try:
|
|
74
|
+
y = x
|
|
75
|
+
return PyType_IsSubtype(<type>((y._category or y.category()).parent_class), self._parent_class_of_category)
|
|
76
|
+
except AttributeError:
|
|
77
|
+
return False
|
|
78
|
+
except TypeError: # this is for objects that are not CategoryObjects
|
|
79
|
+
try:
|
|
80
|
+
return PyType_IsSubtype(<type>(x.category().parent_class), self._parent_class_of_category)
|
|
81
|
+
except AttributeError:
|
|
82
|
+
return False
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
class Category_singleton(Category):
|
|
86
|
+
"""
|
|
87
|
+
A base class for implementing singleton category.
|
|
88
|
+
|
|
89
|
+
A *singleton* category is a category whose class takes no
|
|
90
|
+
parameters like ``Fields()`` or ``Rings()``. See also the
|
|
91
|
+
:wikipedia:`Singleton design pattern <Singleton_pattern>`.
|
|
92
|
+
|
|
93
|
+
This is a subclass of :class:`Category`, with a couple
|
|
94
|
+
optimizations for singleton categories.
|
|
95
|
+
|
|
96
|
+
The main purpose is to make the idioms::
|
|
97
|
+
|
|
98
|
+
sage: QQ in Fields()
|
|
99
|
+
True
|
|
100
|
+
sage: ZZ in Fields()
|
|
101
|
+
False
|
|
102
|
+
|
|
103
|
+
as fast as possible, and in particular competitive to calling a
|
|
104
|
+
constant Python method, in order to foster its systematic use
|
|
105
|
+
throughout the Sage library. Such tests are time critical, in
|
|
106
|
+
particular when creating a lot of polynomial rings over small
|
|
107
|
+
fields like in the elliptic curve code.
|
|
108
|
+
|
|
109
|
+
EXAMPLES::
|
|
110
|
+
|
|
111
|
+
sage: from sage.categories.category_singleton import Category_singleton
|
|
112
|
+
sage: class MyRings(Category):
|
|
113
|
+
....: def super_categories(self): return Rings().super_categories()
|
|
114
|
+
sage: class MyRingsSingleton(Category_singleton):
|
|
115
|
+
....: def super_categories(self): return Rings().super_categories()
|
|
116
|
+
|
|
117
|
+
We create three rings. One of them is contained in the usual category of
|
|
118
|
+
rings, one in the category of "my rings" and the third in the category of
|
|
119
|
+
"my rings singleton"::
|
|
120
|
+
|
|
121
|
+
sage: R = QQ['x,y']
|
|
122
|
+
sage: R1 = Parent(category = MyRings())
|
|
123
|
+
sage: R2 = Parent(category = MyRingsSingleton())
|
|
124
|
+
sage: R in MyRings()
|
|
125
|
+
False
|
|
126
|
+
sage: R1 in MyRings()
|
|
127
|
+
True
|
|
128
|
+
sage: R1 in MyRingsSingleton()
|
|
129
|
+
False
|
|
130
|
+
sage: R2 in MyRings()
|
|
131
|
+
False
|
|
132
|
+
sage: R2 in MyRingsSingleton()
|
|
133
|
+
True
|
|
134
|
+
|
|
135
|
+
One sees that containment tests for the singleton class is a lot faster
|
|
136
|
+
than for a usual class::
|
|
137
|
+
|
|
138
|
+
sage: # not tested
|
|
139
|
+
sage: timeit("R in MyRings()", number=10000)
|
|
140
|
+
10000 loops, best of 3: 7.12 µs per loop
|
|
141
|
+
sage: timeit("R1 in MyRings()", number=10000)
|
|
142
|
+
10000 loops, best of 3: 6.98 µs per loop
|
|
143
|
+
sage: timeit("R in MyRingsSingleton()", number=10000)
|
|
144
|
+
10000 loops, best of 3: 3.08 µs per loop
|
|
145
|
+
sage: timeit("R2 in MyRingsSingleton()", number=10000)
|
|
146
|
+
10000 loops, best of 3: 2.99 µs per loop
|
|
147
|
+
|
|
148
|
+
So this is an improvement, but not yet competitive with a pure
|
|
149
|
+
Cython method::
|
|
150
|
+
|
|
151
|
+
sage: timeit("R.is_ring()", number=10000) # not tested
|
|
152
|
+
10000 loops, best of 3: 383 ns per loop
|
|
153
|
+
|
|
154
|
+
However, it is competitive with a Python method. Actually it is faster,
|
|
155
|
+
if one stores the category in a variable::
|
|
156
|
+
|
|
157
|
+
sage: _Rings = Rings()
|
|
158
|
+
sage: R3 = Parent(category = _Rings)
|
|
159
|
+
sage: R3.is_ring.__module__
|
|
160
|
+
'sage.categories.rings'
|
|
161
|
+
sage: timeit("R3.is_ring()", number=10000) # not tested
|
|
162
|
+
10000 loops, best of 3: 2.64 µs per loop
|
|
163
|
+
sage: timeit("R3 in Rings()", number=10000) # not tested
|
|
164
|
+
10000 loops, best of 3: 3.01 µs per loop
|
|
165
|
+
sage: timeit("R3 in _Rings", number=10000) # not tested
|
|
166
|
+
10000 loops, best of 3: 652 ns per loop
|
|
167
|
+
|
|
168
|
+
This might not be easy to further optimize, since the time is
|
|
169
|
+
consumed in many different spots::
|
|
170
|
+
|
|
171
|
+
sage: timeit("MyRingsSingleton.__classcall__()", number=10000)# not tested
|
|
172
|
+
10000 loops, best of 3: 306 ns per loop
|
|
173
|
+
|
|
174
|
+
sage: X = MyRingsSingleton()
|
|
175
|
+
sage: timeit("R in X ", number=10000) # not tested
|
|
176
|
+
10000 loops, best of 3: 699 ns per loop
|
|
177
|
+
|
|
178
|
+
sage: c = MyRingsSingleton().__contains__
|
|
179
|
+
sage: timeit("c(R)", number = 10000) # not tested
|
|
180
|
+
10000 loops, best of 3: 661 ns per loop
|
|
181
|
+
|
|
182
|
+
.. WARNING::
|
|
183
|
+
|
|
184
|
+
A singleton concrete class `A` should not have a subclass `B`
|
|
185
|
+
(necessarily concrete). Otherwise, creating an instance `a` of
|
|
186
|
+
`A` and an instance `b` of `B` would break the singleton
|
|
187
|
+
principle: `A` would have two instances `a` and `b`.
|
|
188
|
+
|
|
189
|
+
With the current implementation only direct subclasses of
|
|
190
|
+
:class:`Category_singleton` are supported::
|
|
191
|
+
|
|
192
|
+
sage: class MyRingsSingleton(Category_singleton):
|
|
193
|
+
....: def super_categories(self): return Rings().super_categories()
|
|
194
|
+
sage: class Disaster(MyRingsSingleton): pass
|
|
195
|
+
sage: Disaster()
|
|
196
|
+
Traceback (most recent call last):
|
|
197
|
+
...
|
|
198
|
+
AssertionError: <class '__main__.Disaster'> is not a direct subclass of <class 'sage.categories.category_singleton.Category_singleton'>
|
|
199
|
+
|
|
200
|
+
However, it is acceptable for a direct subclass `R` of
|
|
201
|
+
:class:`Category_singleton` to create its unique instance as
|
|
202
|
+
an instance of a subclass of itself (in which case, its the
|
|
203
|
+
subclass of `R` which is concrete, not `R` itself). This is
|
|
204
|
+
used for example to plug in extra category code via a dynamic
|
|
205
|
+
subclass::
|
|
206
|
+
|
|
207
|
+
sage: from sage.categories.category_singleton import Category_singleton
|
|
208
|
+
sage: class R(Category_singleton):
|
|
209
|
+
....: def super_categories(self): return [Sets()]
|
|
210
|
+
sage: R()
|
|
211
|
+
Category of r
|
|
212
|
+
sage: R().__class__
|
|
213
|
+
<class '__main__.R_with_category'>
|
|
214
|
+
sage: R().__class__.mro()
|
|
215
|
+
[<class '__main__.R_with_category'>,
|
|
216
|
+
<class '__main__.R'>,
|
|
217
|
+
<class 'sage.categories.category_singleton.Category_singleton'>,
|
|
218
|
+
<class 'sage.categories.category.Category'>,
|
|
219
|
+
<class 'sage.structure.unique_representation.UniqueRepresentation'>,
|
|
220
|
+
<class 'sage.misc.fast_methods.WithEqualityById'>,
|
|
221
|
+
<class 'sage.structure.unique_representation.CachedRepresentation'>,
|
|
222
|
+
<class 'sage.structure.unique_representation.WithPicklingByInitArgs'>,
|
|
223
|
+
<class 'sage.structure.sage_object.SageObject'>,
|
|
224
|
+
<class '__main__.R.subcategory_class'>,
|
|
225
|
+
<class 'sage.categories.sets_cat.Sets.subcategory_class'>,
|
|
226
|
+
<class 'sage.categories.sets_with_partial_maps.SetsWithPartialMaps.subcategory_class'>,
|
|
227
|
+
<class 'sage.categories.objects.Objects.subcategory_class'>,
|
|
228
|
+
<class 'object'>]
|
|
229
|
+
sage: R() is R()
|
|
230
|
+
True
|
|
231
|
+
sage: R() is R().__class__()
|
|
232
|
+
True
|
|
233
|
+
|
|
234
|
+
In that case, ``R`` is an abstract class and has a single
|
|
235
|
+
concrete subclass, so this does not break the Singleton design
|
|
236
|
+
pattern.
|
|
237
|
+
|
|
238
|
+
.. SEEALSO:: :meth:`Category.__classcall__`, :meth:`Category.__init__`
|
|
239
|
+
|
|
240
|
+
TESTS::
|
|
241
|
+
|
|
242
|
+
sage: import __main__
|
|
243
|
+
sage: __main__.MyRings = MyRings
|
|
244
|
+
sage: __main__.MyRingsSingleton = MyRingsSingleton
|
|
245
|
+
sage: TestSuite(MyRingsSingleton()).run(skip=["_test_category"])
|
|
246
|
+
|
|
247
|
+
.. NOTE::
|
|
248
|
+
|
|
249
|
+
The ``_test_category`` test is failing because
|
|
250
|
+
``MyRingsSingleton()`` is not a subcategory of the join of its
|
|
251
|
+
super categories::
|
|
252
|
+
|
|
253
|
+
sage: C = MyRingsSingleton()
|
|
254
|
+
sage: C.super_categories()
|
|
255
|
+
[Category of rngs, Category of semirings]
|
|
256
|
+
sage: Rngs() & Semirings()
|
|
257
|
+
Category of rings
|
|
258
|
+
sage: C.is_subcategory(Rings())
|
|
259
|
+
False
|
|
260
|
+
|
|
261
|
+
Oh well; it's not really relevant for those tests.
|
|
262
|
+
"""
|
|
263
|
+
|
|
264
|
+
# That is just an optimized constant cached_method
|
|
265
|
+
@staticmethod
|
|
266
|
+
def __classcall__(object cls, *args):
|
|
267
|
+
"""
|
|
268
|
+
Return ``cls()`` and cache the result in ``cls``.
|
|
269
|
+
|
|
270
|
+
INPUT:
|
|
271
|
+
|
|
272
|
+
- ``*args`` -- some constant arguments
|
|
273
|
+
|
|
274
|
+
Most of the time, ``args`` is meant to be empty. However some
|
|
275
|
+
singleton categories, in particular axiom categories of
|
|
276
|
+
singleton categories, may require a constant argument.
|
|
277
|
+
``*args`` is passed down to :meth:`__init__`, and ignored upon
|
|
278
|
+
later calls.
|
|
279
|
+
|
|
280
|
+
.. SEEALSO:: :class:`sage.categories.category_with_axiomCategoryWithAxiom_singleton`
|
|
281
|
+
|
|
282
|
+
TESTS::
|
|
283
|
+
|
|
284
|
+
sage: from sage.categories.category_singleton import Category_singleton
|
|
285
|
+
sage: class MyRingsSingleton(Category_singleton):
|
|
286
|
+
....: def super_categories(self): return Rings().super_categories()
|
|
287
|
+
sage: MyRingsSingleton()
|
|
288
|
+
Category of my rings singleton
|
|
289
|
+
|
|
290
|
+
Instantiating :class:`Category_singleton` triggers an assertion error::
|
|
291
|
+
|
|
292
|
+
sage: Category_singleton()
|
|
293
|
+
Traceback (most recent call last):
|
|
294
|
+
...
|
|
295
|
+
AssertionError: <class 'sage.categories.category_singleton.Category_singleton'> is not a direct subclass of
|
|
296
|
+
<class 'sage.categories.category_singleton.Category_singleton'>
|
|
297
|
+
|
|
298
|
+
Instantiating a subclass of a subclass of :class:`Category_singleton`
|
|
299
|
+
also triggers an assertion error::
|
|
300
|
+
|
|
301
|
+
sage: class MyStuff(Category_singleton):
|
|
302
|
+
....: def super_categories(self): return [Sets()]
|
|
303
|
+
sage: class MySubStuff(MyStuff): pass
|
|
304
|
+
sage: MySubStuff()
|
|
305
|
+
Traceback (most recent call last):
|
|
306
|
+
...
|
|
307
|
+
AssertionError: <class '__main__.MySubStuff'> is not a direct subclass of <class 'sage.categories.category_singleton.Category_singleton'>
|
|
308
|
+
|
|
309
|
+
even if ``MyStuff`` has already been instantiated::
|
|
310
|
+
|
|
311
|
+
sage: MyStuff()
|
|
312
|
+
Category of my stuff
|
|
313
|
+
sage: MySubStuff()
|
|
314
|
+
Traceback (most recent call last):
|
|
315
|
+
...
|
|
316
|
+
AssertionError: <class '__main__.MySubStuff'> is not a direct subclass of <class 'sage.categories.category_singleton.Category_singleton'>
|
|
317
|
+
"""
|
|
318
|
+
if isinstance(cls, DynamicMetaclass): # cls is something like Rings_with_category
|
|
319
|
+
cls = cls.__base__
|
|
320
|
+
# TODO: find a better way to check that cls is an abstract class
|
|
321
|
+
from sage.categories.category_with_axiom import CategoryWithAxiom_singleton
|
|
322
|
+
assert (cls.__mro__[1] is Category_singleton or cls.__mro__[1] is CategoryWithAxiom_singleton), \
|
|
323
|
+
"{} is not a direct subclass of {}".format(cls, Category_singleton)
|
|
324
|
+
obj = super().__classcall__(cls, *args)
|
|
325
|
+
cls._set_classcall(ConstantFunction(obj))
|
|
326
|
+
obj.__class__._set_classcall(ConstantFunction(obj))
|
|
327
|
+
return obj
|
|
328
|
+
|
|
329
|
+
@lazy_class_attribute
|
|
330
|
+
def __contains__(cls):
|
|
331
|
+
"""
|
|
332
|
+
TESTS::
|
|
333
|
+
|
|
334
|
+
sage: from sage.categories.category_singleton import Category_singleton
|
|
335
|
+
sage: class MyRingsSingleton(Category_singleton):
|
|
336
|
+
....: def super_categories(self): return Rings().super_categories()
|
|
337
|
+
sage: ZZ in MyRingsSingleton()
|
|
338
|
+
False
|
|
339
|
+
sage: Parent(category=MyRingsSingleton()) in MyRingsSingleton()
|
|
340
|
+
True
|
|
341
|
+
"""
|
|
342
|
+
return Category_contains_method_by_parent_class(cls())
|