Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/structure/parent.pyx
8814 views
1
r"""
2
Base class for parent objects
3
4
CLASS HIERARCHY::
5
6
SageObject
7
CategoryObject
8
Parent
9
10
A simple example of registering coercions::
11
12
sage: class A_class(Parent):
13
....: def __init__(self, name):
14
....: Parent.__init__(self, name=name)
15
....: self._populate_coercion_lists_()
16
....: self.rename(name)
17
....: #
18
....: def category(self):
19
....: return Sets()
20
....: #
21
....: def _element_constructor_(self, i):
22
....: assert(isinstance(i, (int, Integer)))
23
....: return ElementWrapper(self, i)
24
....:
25
sage: A = A_class("A")
26
sage: B = A_class("B")
27
sage: C = A_class("C")
28
29
sage: def f(a):
30
....: return B(a.value+1)
31
....:
32
sage: class MyMorphism(Morphism):
33
....: def __init__(self, domain, codomain):
34
....: Morphism.__init__(self, Hom(domain, codomain))
35
....: #
36
....: def _call_(self, x):
37
....: return self.codomain()(x.value)
38
....:
39
sage: f = MyMorphism(A,B)
40
sage: f
41
Generic morphism:
42
From: A
43
To: B
44
sage: B.register_coercion(f)
45
sage: C.register_coercion(MyMorphism(B,C))
46
sage: A(A(1)) == A(1)
47
True
48
sage: B(A(1)) == B(1)
49
True
50
sage: C(A(1)) == C(1)
51
True
52
53
sage: A(B(1))
54
Traceback (most recent call last):
55
...
56
AssertionError
57
58
When implementing an element of a ring, one would typically provide the
59
element class with ``_rmul_`` and/or ``_lmul_`` methods for the action of a
60
base ring, and with ``_mul_`` for the ring multiplication. However, prior to
61
:trac:`14249`, it would have been necessary to additionally define a method
62
``_an_element_()`` for the parent. But now, the following example works::
63
64
sage: from sage.structure.element import RingElement
65
sage: class MyElement(RingElement):
66
....: def __init__(self, parent, x, y):
67
....: RingElement.__init__(self, parent)
68
....: def _mul_(self, other):
69
....: return self
70
....: def _rmul_(self, other):
71
....: return self
72
....: def _lmul_(self, other):
73
....: return self
74
sage: class MyParent(Parent):
75
....: Element = MyElement
76
77
Now, we define ::
78
79
sage: P = MyParent(base=ZZ, category=Rings())
80
sage: a = P(1,2)
81
sage: a*a is a
82
True
83
sage: a*2 is a
84
True
85
sage: 2*a is a
86
True
87
88
TESTS:
89
90
This came up in some subtle bug once::
91
92
sage: gp(2) + gap(3)
93
5
94
95
"""
96
97
cimport element
98
cimport sage.categories.morphism as morphism
99
cimport sage.categories.map as map
100
from sage.structure.debug_options import debug
101
from sage.structure.sage_object import SageObject
102
from sage.structure.misc import (dir_with_other_class, getattr_from_other_class,
103
is_extension_type)
104
from sage.misc.lazy_attribute import lazy_attribute
105
from sage.categories.sets_cat import Sets, EmptySetError
106
from copy import copy
107
from sage.misc.sage_itertools import unique_merge
108
from sage.misc.lazy_format import LazyFormat
109
110
# Create a dummy attribute error, using some kind of lazy error message,
111
# so that neither the error itself not the message need to be created
112
# repeatedly, which would cost time.
113
114
from sage.structure.misc cimport AttributeErrorMessage
115
cdef AttributeErrorMessage dummy_error_message = AttributeErrorMessage(None, '')
116
dummy_attribute_error = AttributeError(dummy_error_message)
117
118
# TODO: define this once?
119
120
cdef object elt_parent = None
121
122
cdef inline parent_c(x):
123
if PY_TYPE_CHECK(x, element.Element):
124
return (<element.Element>x)._parent
125
# elif hasattr(x, 'parent'):
126
# return x.parent()
127
# else:
128
# return <object>PY_TYPE(x)
129
else:
130
try:
131
return x.parent()
132
except AttributeError:
133
return <object>PY_TYPE(x)
134
135
cdef _record_exception():
136
from element import get_coercion_model
137
get_coercion_model()._record_exception()
138
139
cdef object _Integer
140
cdef bint is_Integer(x):
141
global _Integer
142
if _Integer is None:
143
from sage.rings.integer import Integer as _Integer
144
return PY_TYPE_CHECK_EXACT(x, _Integer) or PY_TYPE_CHECK_EXACT(x, int)
145
146
# for override testing
147
cdef extern from "descrobject.h":
148
ctypedef struct PyMethodDef:
149
void *ml_meth
150
ctypedef struct PyMethodDescrObject:
151
PyMethodDef *d_method
152
void* PyCFunction_GET_FUNCTION(object)
153
bint PyCFunction_Check(object)
154
155
cdef extern from *:
156
Py_ssize_t PyDict_Size(object)
157
Py_ssize_t PyTuple_GET_SIZE(object)
158
159
ctypedef class __builtin__.dict [object PyDictObject]:
160
cdef Py_ssize_t ma_fill
161
cdef Py_ssize_t ma_used
162
163
void* PyDict_GetItem(object, object)
164
165
cdef inline Py_ssize_t PyDict_GET_SIZE(o):
166
return (<dict>o).ma_used
167
168
###############################################################################
169
# Copyright (C) 2009 Robert Bradshaw <[email protected]>
170
# Copyright (C) 2008 Burcin Erocal <[email protected]>
171
# Copyright (C) 2008 Mike Hansen <[email protected]>
172
# Copyright (C) 2008 David Roe <[email protected]>
173
# Copyright (C) 2007 William Stein <[email protected]>
174
#
175
# Distributed under the terms of the GNU General Public License (GPL)
176
# The full text of the GPL is available at:
177
# http://www.gnu.org/licenses/
178
###############################################################################
179
180
import operator
181
import weakref
182
183
from category_object import CategoryObject
184
from generators import Generators
185
from coerce_exceptions import CoercionException
186
187
# TODO: Theses should probably go in the printer module (but lots of stuff imports them from parent)
188
from category_object import localvars
189
190
cdef object BuiltinMethodType = type(repr)
191
192
from cpython.object cimport *
193
from cpython.bool cimport *
194
include 'sage/ext/stdsage.pxi'
195
196
197
def is_Parent(x):
198
"""
199
Return True if x is a parent object, i.e., derives from
200
sage.structure.parent.Parent and False otherwise.
201
202
EXAMPLES::
203
204
sage: from sage.structure.parent import is_Parent
205
sage: is_Parent(2/3)
206
False
207
sage: is_Parent(ZZ)
208
True
209
sage: is_Parent(Primes())
210
True
211
"""
212
return PY_TYPE_CHECK(x, Parent)
213
214
cdef bint guess_pass_parent(parent, element_constructor):
215
if PY_TYPE_CHECK(element_constructor, types.MethodType):
216
return False
217
elif PY_TYPE_CHECK(element_constructor, BuiltinMethodType):
218
return element_constructor.__self__ is not parent
219
else:
220
return True
221
222
from sage.categories.category import Category
223
from sage.structure.dynamic_class import dynamic_class
224
Sets_parent_class = Sets().parent_class
225
226
cdef inline bint good_as_coerce_domain(S):
227
"""
228
Determine whether the input can be the domain of a map.
229
230
NOTE:
231
232
This is the same as being an object in a category, or
233
being a type. Namely, in Sage, we do consider coercion maps
234
from the type ``<int>`` to, say, `ZZ`.
235
236
TESTS:
237
238
If an instance `S` is not suitable as domain of a map, then
239
the non-existence of a coercion or conversion map from `S`
240
to some other parent is not cached, by :trac:`13378`::
241
242
sage: P.<x,y> = QQ[]
243
sage: P.is_coercion_cached(x)
244
False
245
sage: P.coerce_map_from(x)
246
sage: P.is_coercion_cached(x) # indirect doctest
247
False
248
249
"""
250
return isinstance(S,CategoryObject) or isinstance(S,type)
251
252
cdef inline bint good_as_convert_domain(S):
253
return isinstance(S,SageObject) or isinstance(S,type)
254
255
cdef class Parent(category_object.CategoryObject):
256
257
def __init__(self, base=None, *, category=None, element_constructor=None,
258
gens=None, names=None, normalize=True, facade=None, **kwds):
259
"""
260
Base class for all parents.
261
262
Parents are the Sage/mathematical analogues of container
263
objects in computer science.
264
265
INPUT:
266
267
- ``base`` -- An algebraic structure considered to be the
268
"base" of this parent (e.g. the base field for a vector
269
space).
270
271
- ``category`` -- a category or list/tuple of categories. The
272
category in which this parent lies (or list or tuple
273
thereof). Since categories support more general
274
super-categories, this should be the most specific category
275
possible. If category is a list or tuple, a JoinCategory is
276
created out of them. If category is not specified, the
277
category will be guessed (see
278
:class:`~sage.structure.category_object.CategoryObject`),
279
but won't be used to inherit parent's or element's code from
280
this category.
281
282
- ``element_constructor`` -- A class or function that creates
283
elements of this Parent given appropriate input (can also be
284
filled in later with :meth:`_populate_coercion_lists_`)
285
286
- ``gens`` -- Generators for this object (can also be filled in
287
later with :meth:`_populate_generators_`)
288
289
- ``names`` -- Names of generators.
290
291
- ``normalize`` -- Whether to standardize the names (remove
292
punctuation, etc)
293
294
- ``facade`` -- a parent, or tuple thereof, or ``True``
295
296
If ``facade`` is specified, then ``Sets().Facades()`` is added
297
to the categories of the parent. Furthermore, if ``facade`` is
298
not ``True``, the internal attribute ``_facade_for`` is set
299
accordingly for use by
300
:meth:`Sets.Facades.ParentMethods.facade_for`.
301
302
Internal invariants:
303
304
- ``self._element_init_pass_parent == guess_pass_parent(self,
305
self._element_constructor)`` Ensures that :meth:`__call__`
306
passes down the parent properly to
307
:meth:`_element_constructor`. See :trac:`5979`.
308
309
.. TODO::
310
311
Eventually, category should be
312
:class:`~sage.categories.sets_cat.Sets` by default.
313
314
.. automethod:: __call__
315
.. automethod:: _populate_coercion_lists_
316
.. automethod:: __mul__
317
.. automethod:: __contains__
318
.. automethod:: _coerce_map_from_
319
.. automethod:: _convert_map_from_
320
.. automethod:: _get_action_
321
.. automethod:: _an_element_
322
.. automethod:: _repr_option
323
.. automethod:: _init_category_
324
"""
325
# TODO: in the long run, we want to get rid of the element_constructor = argument
326
# (element_constructor would always be set by inheritance)
327
# Then, all the element_constructor logic should be moved to init_coerce.
328
CategoryObject.__init__(self, base = base)
329
if facade is not None and facade is not False:
330
if isinstance(facade, Parent):
331
facade = (facade,)
332
if facade is not True:
333
assert isinstance(facade, tuple)
334
self._facade_for = facade
335
if category is None:
336
category = Sets().Facades()
337
else:
338
if isinstance(category, (tuple,list)):
339
category = Category.join(tuple(category) + (Sets().Facades(),))
340
else:
341
category = Category.join((category,Sets().Facades()))
342
# Setting the categories is currently done in a separate
343
# method to let some subclasses (like ParentsWithBase)
344
# call it without calling the full constructor
345
self._init_category_(category)
346
347
if len(kwds) > 0:
348
if debug.bad_parent_warnings:
349
print "Illegal keywords for %s: %s" % (type(self), kwds)
350
# TODO: many classes don't call this at all, but __new__ crashes Sage
351
if debug.bad_parent_warnings:
352
if element_constructor is not None and not callable(element_constructor):
353
print "coerce BUG: Bad element_constructor provided", type(self), type(element_constructor), element_constructor
354
if gens is not None:
355
self._populate_generators_(gens, names, normalize)
356
elif names is not None:
357
self._assign_names(names, normalize)
358
if element_constructor is None:
359
self._set_element_constructor()
360
else:
361
self._element_constructor = element_constructor
362
self._element_init_pass_parent = guess_pass_parent(self, element_constructor)
363
self.init_coerce(False)
364
365
for cls in self.__class__.mro():
366
# this calls __init_extra__ if it is *defined* in cls (not in a super class)
367
if "__init_extra__" in cls.__dict__:
368
cls.__init_extra__(self)
369
370
def _init_category_(self, category):
371
"""
372
Initialize the category framework
373
374
Most parents initialize their category upon construction, and
375
this is the recommended behavior. For example, this happens
376
when the constructor calls :meth:`Parent.__init__` directly or
377
indirectly. However, some parents defer this for performance
378
reasons. For example,
379
:mod:`sage.matrix.matrix_space.MatrixSpace` does not.
380
381
EXAMPLES::
382
383
sage: P = Parent()
384
sage: P.category()
385
Category of sets
386
sage: class MyParent(Parent):
387
....: def __init__(self):
388
....: self._init_category_(Groups())
389
sage: MyParent().category()
390
Category of groups
391
"""
392
CategoryObject._init_category_(self, category)
393
394
# This substitutes the class of this parent to a subclass
395
# which also subclasses the parent_class of the category
396
397
if category is not None: #isinstance(self._category, Category) and not isinstance(self, Set_generic):
398
category = self._category # CategoryObject may have done some argument processing
399
# Some parent class may readily have their category classes attached
400
# TODO: assert that the category is consistent
401
if not issubclass(self.__class__, Sets_parent_class) and not is_extension_type(self.__class__):
402
#documentation transfer is handled by dynamic_class
403
self.__class__ = dynamic_class(
404
'{0}_with_category'.format(self.__class__.__name__),
405
(self.__class__, category.parent_class, ),
406
doccls=self.__class__)
407
408
def _refine_category_(self, category):
409
"""
410
Change the category of ``self`` into a subcategory.
411
412
INPUT:
413
414
- ``category`` -- a category or list or tuple thereof
415
416
The new category is obtained by adjoining ``category`` to the
417
current one.
418
419
.. NOTE::
420
421
The class of ``self`` might be replaced by a sub-class.
422
423
.. seealso::
424
425
:meth:`CategoryObject._refine_category`
426
427
EXAMPLES::
428
429
sage: P.<x,y> = QQ[]
430
sage: Q = P.quotient(x^2+2)
431
sage: Q.category()
432
Join of Category of commutative rings and Category of subquotients of monoids and Category of quotients of semigroups
433
sage: first_class = Q.__class__
434
sage: Q._refine_category_(Fields())
435
sage: Q.category()
436
Join of Category of fields and Category of subquotients of monoids and Category of quotients of semigroups
437
sage: first_class == Q.__class__
438
False
439
sage: TestSuite(Q).run()
440
441
442
TESTS:
443
444
Here is a test against :trac:`14471`. Refining the category will issue
445
a warning, if this change affects the hash value (note that this will
446
only be seen in doctest mode)::
447
448
sage: class MyParent(Parent):
449
....: def __hash__(self):
450
....: return hash(type(self)) # subtle mistake
451
sage: a = MyParent()
452
sage: h_a = hash(a)
453
sage: a._refine_category_(Algebras(QQ))
454
hash of <class '__main__.MyParent_with_category'> changed in
455
Parent._refine_category_ during initialisation
456
457
sage: b = MyParent(category=Rings())
458
sage: h_b = hash(b)
459
sage: h_a == h_b
460
False
461
sage: b._refine_category_(Algebras(QQ))
462
hash of <class '__main__.MyParent_with_category'> changed in
463
Parent._refine_category_ during refinement
464
sage: hash(a) == hash(b)
465
True
466
sage: hash(a) != h_a
467
True
468
469
"""
470
if debug.refine_category_hash_check:
471
# check that the hash stays the same after refinement
472
hash_old = hash(self)
473
if self._category is None:
474
self._init_category_(category)
475
if debug.refine_category_hash_check and hash_old != hash(self):
476
print 'hash of {0} changed in Parent._refine_category_ during initialisation' \
477
.format(str(self.__class__))
478
return
479
if category is self._category:
480
return
481
CategoryObject._refine_category_(self, category)
482
category = self._category
483
484
# This substitutes the class of this parent to a subclass
485
# which also subclasses the parent_class of the category.
486
# However, we only do so if we don't have an extension class.
487
if not is_extension_type(self.__class__):
488
# We tested in the very beginning that this parent
489
# had its category initialised. Hence, the class
490
# is already a dynamic class.
491
base = self.__class__.__base__
492
#documentation transfer is handled by dynamic_class
493
self.__class__ = dynamic_class("%s_with_category"%base.__name__,
494
(base, category.parent_class, ),
495
doccls=base)
496
# If the element class has already been assigned, it
497
# needs to be erased now.
498
try:
499
self.__dict__.__delitem__('element_class')
500
except (AttributeError, KeyError):
501
pass
502
if debug.refine_category_hash_check and hash_old != hash(self):
503
print 'hash of {0} changed in Parent._refine_category_ during refinement' \
504
.format(str(self.__class__))
505
506
def _unset_category(self):
507
"""
508
Remove the information on ``self``'s category.
509
510
NOTE:
511
512
This may change ``self``'s class!
513
514
EXAMPLES:
515
516
Let us create a parent in the category of rings::
517
518
sage: class MyParent(Parent):
519
....: def __init__(self):
520
....: Parent.__init__(self, category=Rings())
521
....:
522
sage: P = MyParent()
523
sage: P.category()
524
Category of rings
525
526
Of course, its category is initialised::
527
528
sage: P._is_category_initialized()
529
True
530
531
We may now refine the category to the category of fields.
532
Note that this changes the class::
533
534
sage: C = type(P)
535
sage: C == MyParent
536
False
537
sage: P._refine_category_(Fields())
538
sage: P.category()
539
Category of fields
540
sage: C == type(P)
541
False
542
543
Now we may have noticed that the category refinement was a
544
mistake. We do not need to worry, because we can undo category
545
initialisation totally::
546
547
sage: P._unset_category()
548
sage: P._is_category_initialized()
549
False
550
sage: type(P) == MyParent
551
True
552
553
Hence, we can now initialise the parent again in the original
554
category, i.e., the category of rings. We find that not only
555
the category, but also theclass of the parent is brought back
556
to what it was after the original category initialisation::
557
558
sage: P._init_category_(Rings())
559
sage: type(P) == C
560
True
561
562
"""
563
self._category = None
564
if not is_extension_type(self.__class__):
565
while issubclass(self.__class__, Sets_parent_class):
566
self.__class__ = self.__class__.__base__
567
568
# This probably should go into Sets().Parent
569
@lazy_attribute
570
def element_class(self):
571
"""
572
The (default) class for the elements of this parent
573
574
FIXME's and design issues:
575
576
- If self.Element is "trivial enough", should we optimize it away with:
577
self.element_class = dynamic_class("%s.element_class"%self.__class__.__name__, (category.element_class,), self.Element)
578
- This should lookup for Element classes in all super classes
579
"""
580
try: #if hasattr(self, 'Element'):
581
return self.__make_element_class__(self.Element, "%s.element_class"%self.__class__.__name__)
582
except AttributeError: #else:
583
return NotImplemented
584
585
586
def __make_element_class__(self, cls, name = None, inherit = None):
587
"""
588
A utility to construct classes for the elements of this
589
parent, with appropriate inheritance from the element class of
590
the category (only for pure python types so far).
591
"""
592
if name is None:
593
name = "%s_with_category"%cls.__name__
594
# By default, don't fiddle with extension types yet; inheritance from
595
# categories will probably be achieved in a different way
596
if inherit is None:
597
inherit = not is_extension_type(cls)
598
if inherit:
599
return dynamic_class(name, (cls, self.category().element_class))
600
else:
601
return cls
602
603
def _set_element_constructor(self):
604
"""
605
This function is used in translating from the old to the new coercion model.
606
607
It is called from sage.structure.parent_old.Parent.__init__
608
when an old style parent provides a _element_constructor_ method.
609
610
It just asserts that this _element_constructor_ is callable and
611
also sets self._element_init_pass_parent
612
613
EXAMPLES::
614
615
sage: k = GF(5); k._element_constructor # indirect doctest
616
<bound method FiniteField_prime_modn_with_category._element_constructor_ of Finite Field of size 5>
617
"""
618
try: #if hasattr(self, '_element_constructor_'):
619
_element_constructor_ = self._element_constructor_
620
except (AttributeError, TypeError):
621
# Remark: A TypeError can actually occur;
622
# it is a possible reason for "hasattr" to return False
623
return
624
assert callable(_element_constructor_)
625
self._element_constructor = _element_constructor_
626
self._element_init_pass_parent = guess_pass_parent(self, self._element_constructor)
627
628
def category(self):
629
"""
630
EXAMPLES::
631
632
sage: P = Parent()
633
sage: P.category()
634
Category of sets
635
sage: class MyParent(Parent):
636
....: def __init__(self): pass
637
sage: MyParent().category()
638
Category of sets
639
"""
640
if self._category is None:
641
# COERCE TODO: we shouldn't need this
642
self._category = Sets()
643
return self._category
644
645
def _test_category(self, **options):
646
"""
647
Run generic tests on the method :meth:`.category`.
648
649
See also: :class:`TestSuite`.
650
651
EXAMPLES::
652
653
sage: C = Sets().example()
654
sage: C._test_category()
655
656
Let us now write a parent with broken categories:
657
658
sage: class MyParent(Parent):
659
....: def __init__(self):
660
....: pass
661
sage: P = MyParent()
662
sage: P._test_category()
663
Traceback (most recent call last):
664
...
665
AssertionError: category of self improperly initialized
666
667
To fix this, :meth:`MyParent.__init__` should initialize the
668
category of ``self`` by calling :meth:`._init_category` or
669
``Parent.__init__(self, category = ...)``.
670
"""
671
tester = self._tester(**options)
672
SageObject._test_category(self, tester = tester)
673
category = self.category()
674
tester.assert_(category.is_subcategory(Sets()))
675
# Tests that self inherits methods from the categories
676
if not is_extension_type(self.__class__):
677
# For usual Python classes, that should be done with
678
# standard inheritance
679
tester.assertTrue(isinstance(self, category.parent_class),
680
LazyFormat("category of self improperly initialized")%self)
681
else:
682
# For extension types we just check that inheritance
683
# occurs on one specific method.
684
# _test_an_element from Sets().ParentMethods is a good
685
# candidate because it's unlikely to be overriden in self.
686
tester.assertTrue(hasattr(self, "_test_an_element"),
687
LazyFormat("category of self improperly initialized")%self)
688
689
def _test_eq(self, **options):
690
"""
691
Test that ``self`` is equal to ``self`` and different to ``None``.
692
693
See also: :class:`TestSuite`.
694
695
TESTS::
696
697
sage: O = Parent()
698
sage: O._test_eq()
699
700
Let us now write a broken class method::
701
702
sage: class CCls(Parent):
703
....: def __eq__(self, other):
704
....: return True
705
sage: CCls()._test_eq()
706
Traceback (most recent call last):
707
...
708
AssertionError: broken equality: <class '__main__.CCls'> == None
709
710
Let us now break inequality::
711
712
sage: class CCls(Parent):
713
....: def __ne__(self, other):
714
....: return True
715
sage: CCls()._test_eq()
716
Traceback (most recent call last):
717
...
718
AssertionError: broken non-equality: <class '__main__.CCls'> != itself
719
"""
720
tester = self._tester(**options)
721
722
# We don't use assertEqual / assertNonEqual in order to be
723
# 100% sure we indeed call the operators == and !=, whatever
724
# the version of Python is (see #11236)
725
tester.assertTrue(self == self,
726
LazyFormat("broken equality: %s == itself is False")%self)
727
tester.assertFalse(self == None,
728
LazyFormat("broken equality: %s == None")%self)
729
tester.assertFalse(self != self,
730
LazyFormat("broken non-equality: %s != itself")%self)
731
tester.assertTrue(self != None,
732
LazyFormat("broken non-equality: %s != None is False")%self)
733
734
cdef int init_coerce(self, bint warn=True) except -1:
735
if self._coerce_from_hash is None:
736
if warn:
737
print "init_coerce() for ", type(self)
738
raise ZeroDivisionError("hello")
739
self._initial_coerce_list = []
740
self._initial_action_list = []
741
self._initial_convert_list = []
742
self._coerce_from_list = []
743
self._coerce_from_hash = MonoDict(23)
744
self._action_list = []
745
self._action_hash = TripleDict(23)
746
self._convert_from_list = []
747
self._convert_from_hash = MonoDict(53)
748
self._embedding = None
749
750
def __getattr__(self, str name):
751
"""
752
Let cat be the category of ``self``. This method emulates
753
``self`` being an instance of both ``Parent`` and
754
``cat.parent_class``, in that order, for attribute lookup.
755
756
NOTE:
757
758
Attributes beginning with two underscores but not ending with
759
an unnderscore are considered private and are thus exempted
760
from the lookup in ``cat.parent_class``.
761
762
EXAMPLES:
763
764
We test that ZZ (an extension type) inherits the methods from
765
its categories, that is from ``EuclideanDomains().parent_class``::
766
767
sage: ZZ._test_associativity
768
<bound method EuclideanDomains.parent_class._test_associativity of Integer Ring>
769
sage: ZZ._test_associativity(verbose = True)
770
sage: TestSuite(ZZ).run(verbose = True)
771
running ._test_additive_associativity() . . . pass
772
running ._test_an_element() . . . pass
773
running ._test_associativity() . . . pass
774
running ._test_category() . . . pass
775
running ._test_characteristic() . . . pass
776
running ._test_distributivity() . . . pass
777
running ._test_elements() . . .
778
Running the test suite of self.an_element()
779
running ._test_category() . . . pass
780
running ._test_eq() . . . pass
781
running ._test_nonzero_equal() . . . pass
782
running ._test_not_implemented_methods() . . . pass
783
running ._test_pickling() . . . pass
784
pass
785
running ._test_elements_eq_reflexive() . . . pass
786
running ._test_elements_eq_symmetric() . . . pass
787
running ._test_elements_eq_transitive() . . . pass
788
running ._test_elements_neq() . . . pass
789
running ._test_eq() . . . pass
790
running ._test_not_implemented_methods() . . . pass
791
running ._test_one() . . . pass
792
running ._test_pickling() . . . pass
793
running ._test_prod() . . . pass
794
running ._test_some_elements() . . . pass
795
running ._test_zero() . . . pass
796
797
sage: Sets().example().sadfasdf
798
Traceback (most recent call last):
799
...
800
AttributeError: 'PrimeNumbers_with_category' object has no attribute 'sadfasdf'
801
802
TESTS:
803
804
We test that "private" attributes are not requested from the element class
805
of the category (:trac:`10467`)::
806
807
sage: P = Parent(QQ, category=CommutativeRings())
808
sage: P.category().parent_class.__foo = 'bar'
809
sage: P.__foo
810
Traceback (most recent call last):
811
...
812
AttributeError: 'sage.structure.parent.Parent' object has no attribute '__foo'
813
814
"""
815
if (name.startswith('__') and not name.endswith('_')) or self._category is None:
816
dummy_error_message.cls = type(self)
817
dummy_error_message.name = name
818
raise dummy_attribute_error
819
try:
820
return self.__cached_methods[name]
821
except KeyError:
822
attr = getattr_from_other_class(self, self._category.parent_class, name)
823
self.__cached_methods[name] = attr
824
return attr
825
except TypeError:
826
attr = getattr_from_other_class(self, self._category.parent_class, name)
827
self.__cached_methods = {name:attr}
828
return attr
829
830
def __dir__(self):
831
"""
832
Let cat be the category of ``self``. This method emulates
833
``self`` being an instance of both ``Parent`` and
834
``cat.parent_class``, in that order, for attribute directory.
835
836
EXAMPLES::
837
838
sage: for s in dir(ZZ):
839
....: if s[:6] == "_test_": print s
840
_test_additive_associativity
841
_test_an_element
842
_test_associativity
843
_test_category
844
_test_characteristic
845
_test_distributivity
846
_test_elements
847
_test_elements_eq_reflexive
848
_test_elements_eq_symmetric
849
_test_elements_eq_transitive
850
_test_elements_neq
851
_test_eq
852
_test_not_implemented_methods
853
_test_one
854
_test_pickling
855
_test_prod
856
_test_some_elements
857
_test_zero
858
sage: F = GF(9,'a')
859
sage: dir(F)
860
[..., '__class__', ..., '_test_pickling', ..., 'extension', ...]
861
862
"""
863
return dir_with_other_class(self, self.category().parent_class)
864
865
def _introspect_coerce(self):
866
"""
867
Used for debugging the coercion model.
868
869
EXAMPLES::
870
871
sage: sorted(QQ._introspect_coerce().items())
872
[('_action_hash', <sage.structure.coerce_dict.TripleDict object at ...>),
873
('_action_list', []),
874
('_coerce_from_hash', <sage.structure.coerce_dict.MonoDict object at ...>),
875
('_coerce_from_list', []),
876
('_convert_from_hash', <sage.structure.coerce_dict.MonoDict object at ...>),
877
('_convert_from_list', [...]),
878
('_element_init_pass_parent', False),
879
('_embedding', None),
880
('_initial_action_list', []),
881
('_initial_coerce_list', []),
882
('_initial_convert_list', [])]
883
"""
884
return {
885
'_coerce_from_list': self._coerce_from_list,
886
'_coerce_from_hash': self._coerce_from_hash,
887
'_action_list': self._action_list,
888
'_action_hash': self._action_hash,
889
'_convert_from_list': self._convert_from_list,
890
'_convert_from_hash': self._convert_from_hash,
891
'_embedding': self._embedding,
892
'_initial_coerce_list': self._initial_coerce_list,
893
'_initial_action_list': self._initial_action_list,
894
'_initial_convert_list': self._initial_convert_list,
895
'_element_init_pass_parent': self._element_init_pass_parent,
896
}
897
898
def __getstate__(self):
899
"""
900
Used for pickling.
901
902
TESTS::
903
904
sage: loads(dumps(RR['x'])) == RR['x']
905
True
906
"""
907
d = CategoryObject.__getstate__(self)
908
d['_embedding'] = self._embedding
909
d['_element_constructor'] = self._element_constructor
910
d['_convert_method_name'] = self._convert_method_name
911
d['_element_init_pass_parent'] = self._element_init_pass_parent
912
d['_initial_coerce_list'] = self._initial_coerce_list
913
d['_initial_action_list'] = self._initial_action_list
914
d['_initial_convert_list'] = self._initial_convert_list
915
return d
916
917
def __setstate__(self, d):
918
"""
919
Used for pickling.
920
921
TESTS::
922
923
sage: loads(dumps(CDF['x'])) == CDF['x']
924
True
925
"""
926
CategoryObject.__setstate__(self, d)
927
try:
928
version = d['_pickle_version']
929
except KeyError:
930
version = 0
931
if version == 1:
932
self.init_coerce(False) # Really, do we want to init this with the same initial data as before?
933
self._populate_coercion_lists_(coerce_list=d['_initial_coerce_list'] or [],
934
action_list=d['_initial_action_list'] or [],
935
convert_list=d['_initial_convert_list'] or [],
936
embedding=d['_embedding'],
937
convert_method_name=d['_convert_method_name'],
938
element_constructor = d['_element_constructor'],
939
init_no_parent=not d['_element_init_pass_parent'],
940
unpickling=True)
941
942
def _repr_option(self, key):
943
"""
944
Metadata about the :meth:`_repr_` output.
945
946
INPUT:
947
948
- ``key`` -- string. A key for different metadata informations
949
that can be inquired about.
950
951
Valid ``key`` arguments are:
952
953
- ``'ascii_art'``: The :meth:`_repr_` output is multi-line
954
ascii art and each line must be printed starting at the same
955
column, or the meaning is lost.
956
957
- ``'element_ascii_art'``: same but for the output of the
958
elements. Used in :mod:`sage.misc.displayhook`.
959
960
- ``'element_is_atomic'``: the elements print atomically, that
961
is, parenthesis are not required when *printing* out any of
962
`x - y`, `x + y`, `x^y` and `x/y`.
963
964
OUTPUT:
965
966
Boolean.
967
968
EXAMPLES::
969
970
sage: ZZ._repr_option('ascii_art')
971
False
972
sage: MatrixSpace(ZZ, 2)._repr_option('element_ascii_art')
973
True
974
"""
975
if not isinstance(key, basestring):
976
raise ValueError('key must be a string')
977
defaults = {
978
'ascii_art': False,
979
'element_ascii_art': False,
980
'element_is_atomic': False,
981
}
982
return defaults[key]
983
984
def is_atomic_repr(self):
985
"""
986
The old way to signal atomic string reps.
987
988
True if the elements have atomic string representations, in the
989
sense that if they print at s, then -s means the negative of s. For
990
example, integers are atomic but polynomials are not.
991
992
EXAMPLES::
993
994
sage: Parent().is_atomic_repr()
995
doctest:...: DeprecationWarning: Use _repr_option to return metadata about string rep
996
See http://trac.sagemath.org/14040 for details.
997
False
998
"""
999
from sage.misc.superseded import deprecation
1000
deprecation(14040, 'Use _repr_option to return metadata about string rep')
1001
return False
1002
1003
def __call__(self, x=0, *args, **kwds):
1004
"""
1005
This is the generic call method for all parents.
1006
1007
When called, it will find a map based on the Parent (or type) of x.
1008
If a coercion exists, it will always be chosen. This map will
1009
then be called (with the arguments and keywords if any).
1010
1011
By default this will dispatch as quickly as possible to
1012
:meth:`_element_constructor_` though faster pathways are
1013
possible if so desired.
1014
1015
TESTS:
1016
1017
We check that the invariant::
1018
1019
self._element_init_pass_parent == guess_pass_parent(self, self._element_constructor)
1020
1021
is preserved (see :trac:`5979`)::
1022
1023
sage: class MyParent(Parent):
1024
....: def _element_constructor_(self, x):
1025
....: print self, x
1026
....: return sage.structure.element.Element(parent = self)
1027
....: def _repr_(self):
1028
....: return "my_parent"
1029
....:
1030
sage: my_parent = MyParent()
1031
sage: x = my_parent("bla")
1032
my_parent bla
1033
sage: x.parent() # indirect doctest
1034
my_parent
1035
1036
sage: x = my_parent() # shouldn't this one raise an error?
1037
my_parent 0
1038
sage: x = my_parent(3) # todo: not implemented why does this one fail???
1039
my_parent 3
1040
1041
1042
"""
1043
if self._element_constructor is None:
1044
# Neither __init__ nor _populate_coercion_lists_ have been called...
1045
try:
1046
assert callable(self._element_constructor_)
1047
self._element_constructor = self._element_constructor_
1048
self._element_init_pass_parent = guess_pass_parent(self, self._element_constructor)
1049
except (AttributeError, AssertionError):
1050
raise NotImplementedError
1051
cdef Py_ssize_t i
1052
cdef R = parent_c(x)
1053
cdef bint no_extra_args = PyTuple_GET_SIZE(args) == 0 and PyDict_GET_SIZE(kwds) == 0
1054
if R is self and no_extra_args:
1055
return x
1056
1057
# Here we inline the first part of convert_map_from for speed.
1058
# (Yes, the virtual function overhead can matter.)
1059
if self._convert_from_hash is None: # this is because parent.__init__() does not always get called
1060
self.init_coerce()
1061
cdef map.Map mor
1062
try:
1063
mor = <map.Map> self._convert_from_hash.get(R)
1064
except KeyError:
1065
mor = <map.Map> self.convert_map_from(R)
1066
1067
if mor is not None:
1068
if no_extra_args:
1069
return mor._call_(x)
1070
else:
1071
return mor._call_with_args(x, args, kwds)
1072
1073
raise TypeError("No conversion defined from %s to %s"%(R, self))
1074
1075
def __mul__(self,x):
1076
"""
1077
This is a multiplication method that more or less directly
1078
calls another attribute ``_mul_`` (single underscore). This
1079
is because ``__mul__`` can not be implemented via inheritance
1080
from the parent methods of the category, but ``_mul_`` can
1081
be inherited. This is, e.g., used when creating twosided
1082
ideals of matrix algebras. See :trac:`7797`.
1083
1084
EXAMPLE::
1085
1086
sage: MS = MatrixSpace(QQ,2,2)
1087
1088
This matrix space is in fact an algebra, and in particular
1089
it is a ring, from the point of view of categories::
1090
1091
sage: MS.category()
1092
Category of algebras over Rational Field
1093
sage: MS in Rings()
1094
True
1095
1096
However, its class does not inherit from the base class
1097
``Ring``::
1098
1099
sage: isinstance(MS,Ring)
1100
False
1101
1102
Its ``_mul_`` method is inherited from the category, and
1103
can be used to create a left or right ideal::
1104
1105
sage: MS._mul_.__module__
1106
'sage.categories.rings'
1107
sage: MS*MS.1 # indirect doctest
1108
Left Ideal
1109
(
1110
[0 1]
1111
[0 0]
1112
)
1113
of Full MatrixSpace of 2 by 2 dense matrices over Rational Field
1114
sage: MS*[MS.1,2]
1115
Left Ideal
1116
(
1117
[0 1]
1118
[0 0],
1119
<BLANKLINE>
1120
[2 0]
1121
[0 2]
1122
)
1123
of Full MatrixSpace of 2 by 2 dense matrices over Rational Field
1124
sage: MS.1*MS
1125
Right Ideal
1126
(
1127
[0 1]
1128
[0 0]
1129
)
1130
of Full MatrixSpace of 2 by 2 dense matrices over Rational Field
1131
sage: [MS.1,2]*MS
1132
Right Ideal
1133
(
1134
[0 1]
1135
[0 0],
1136
<BLANKLINE>
1137
[2 0]
1138
[0 2]
1139
)
1140
of Full MatrixSpace of 2 by 2 dense matrices over Rational Field
1141
1142
"""
1143
# generic multiplication method. It defers to
1144
# _mul_, which may be defined via categories.
1145
_mul_ = None
1146
switch = False
1147
try:
1148
if isinstance(self,Parent):
1149
_mul_ = self._mul_
1150
except AttributeError:
1151
pass
1152
if _mul_ is None:
1153
try:
1154
if isinstance(x,Parent):
1155
_mul_ = x._mul_
1156
switch = True
1157
except AttributeError:
1158
pass
1159
if _mul_ is None:
1160
raise TypeError("For implementing multiplication, provide the method '_mul_' for %s resp. %s"%(self,x))
1161
if switch:
1162
return _mul_(self,switch_sides=True)
1163
return _mul_(x)
1164
1165
#############################################################################
1166
# Containment testing
1167
#############################################################################
1168
def __contains__(self, x):
1169
r"""
1170
True if there is an element of self that is equal to x under
1171
==, or if x is already an element of self. Also, True in other
1172
cases involving the Symbolic Ring, which is handled specially.
1173
1174
For many structures we test this by using :meth:`__call__` and
1175
then testing equality between x and the result.
1176
1177
The Symbolic Ring is treated differently because it is
1178
ultra-permissive about letting other rings coerce in, but
1179
ultra-strict about doing comparisons.
1180
1181
EXAMPLES::
1182
1183
sage: 2 in Integers(7)
1184
True
1185
sage: 2 in ZZ
1186
True
1187
sage: Integers(7)(3) in ZZ
1188
True
1189
sage: 3/1 in ZZ
1190
True
1191
sage: 5 in QQ
1192
True
1193
sage: I in RR
1194
False
1195
sage: SR(2) in ZZ
1196
True
1197
sage: RIF(1, 2) in RIF
1198
True
1199
sage: pi in RIF # there is no element of RIF equal to pi
1200
False
1201
sage: sqrt(2) in CC
1202
True
1203
sage: pi in RR
1204
True
1205
sage: pi in CC
1206
True
1207
sage: pi in RDF
1208
True
1209
sage: pi in CDF
1210
True
1211
1212
TESTS:
1213
1214
Check that :trac:`13824` is fixed::
1215
1216
sage: 4/3 in GF(3)
1217
False
1218
sage: 15/50 in GF(25, 'a')
1219
False
1220
sage: 7/4 in Integers(4)
1221
False
1222
sage: 15/36 in Integers(6)
1223
False
1224
"""
1225
P = parent_c(x)
1226
if P is self or P == self:
1227
return True
1228
try:
1229
x2 = self(x)
1230
EQ = (x2 == x)
1231
if EQ is True:
1232
return True
1233
elif EQ is False:
1234
return False
1235
elif EQ:
1236
return True
1237
else:
1238
from sage.symbolic.expression import is_Expression
1239
if is_Expression(EQ): # if comparing gives an Expression, then it must be an equation.
1240
# We return *true* here, even though the equation
1241
# EQ must have evaluated to False for us to get to
1242
# this point. The reason is because... in practice
1243
# SR is ultra-permissive about letting other rings
1244
# coerce in, but ultra-strict about doing
1245
# comparisons.
1246
return True
1247
return False
1248
except (TypeError, ValueError, ZeroDivisionError):
1249
return False
1250
1251
cpdef coerce(self, x):
1252
"""
1253
Return x as an element of self, if and only if there is a canonical
1254
coercion from the parent of x to self.
1255
1256
EXAMPLES::
1257
1258
sage: QQ.coerce(ZZ(2))
1259
2
1260
sage: ZZ.coerce(QQ(2))
1261
Traceback (most recent call last):
1262
...
1263
TypeError: no canonical coercion from Rational Field to Integer Ring
1264
1265
We make an exception for zero::
1266
1267
sage: V = GF(7)^7
1268
sage: V.coerce(0)
1269
(0, 0, 0, 0, 0, 0, 0)
1270
"""
1271
mor = self.coerce_map_from(parent_c(x))
1272
if mor is None:
1273
if is_Integer(x) and not x:
1274
try:
1275
return self(0)
1276
except Exception:
1277
_record_exception()
1278
raise TypeError("no canonical coercion from %s to %s" % (parent_c(x), self))
1279
else:
1280
return (<map.Map>mor)._call_(x)
1281
1282
def _list_from_iterator_cached(self):
1283
r"""
1284
Return a list of the elements of ``self``.
1285
1286
OUTPUT:
1287
1288
A list of all the elements produced by the iterator
1289
defined for the object. The result is cached. An
1290
infinite set may define an iterator, allowing one
1291
to search through the elements, but a request by
1292
this method for the entire list should fail.
1293
1294
NOTE:
1295
1296
Some objects ``X`` do not know if they are finite or not. If
1297
``X.is_finite()`` fails with a ``NotImplementedError``, then
1298
``X.list()`` will simply try. In that case, it may run without
1299
stopping.
1300
1301
However, if ``X`` knows that it is infinite, then running
1302
``X.list()`` will raise an appropriate error, while running
1303
``list(X)`` will run indefinitely. For many Sage objects
1304
``X``, using ``X.list()`` is preferable to using ``list(X)``.
1305
1306
Nevertheless, since the whole list of elements is created and
1307
cached by ``X.list()``, it may be better to do ``for x in
1308
X:``, not ``for x in X.list():``.
1309
1310
EXAMPLES::
1311
1312
sage: R = Integers(11)
1313
sage: R.list() # indirect doctest
1314
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
1315
1316
sage: ZZ.list()
1317
Traceback (most recent call last):
1318
...
1319
ValueError: since it is infinite, cannot list Integer Ring
1320
1321
This is the motivation for :trac:`10470` ::
1322
1323
sage: (QQ^2).list()
1324
Traceback (most recent call last):
1325
...
1326
ValueError: since it is infinite, cannot list Vector space of dimension 2 over Rational Field
1327
1328
TESTS:
1329
1330
The following tests the caching by adjusting the cached version::
1331
1332
sage: R = Integers(3)
1333
sage: R.list()
1334
[0, 1, 2]
1335
sage: R._list[0] = 'junk'
1336
sage: R.list()
1337
['junk', 1, 2]
1338
1339
Here we test that for an object that does not know whether it
1340
is finite or not. Calling ``X.list()`` simply tries to create
1341
the list (but here it fails, since the object is not
1342
iterable). This was fixed :trac:`11350` ::
1343
1344
sage: R.<t,p> = QQ[]
1345
sage: Q = R.quotient(t^2-t+1)
1346
sage: Q.is_finite()
1347
Traceback (most recent call last):
1348
...
1349
NotImplementedError
1350
sage: Q.list()
1351
Traceback (most recent call last):
1352
...
1353
NotImplementedError: object does not support iteration
1354
1355
Here is another example. We artificially create a version of
1356
the ring of integers that does not know whether it is finite
1357
or not::
1358
1359
sage: from sage.rings.integer_ring import IntegerRing_class
1360
sage: class MyIntegers_class(IntegerRing_class):
1361
....: def is_finite(self):
1362
....: raise NotImplementedError
1363
sage: MyIntegers = MyIntegers_class()
1364
sage: MyIntegers.is_finite()
1365
Traceback (most recent call last):
1366
...
1367
NotImplementedError
1368
1369
Asking for ``list(MyIntegers)`` below will never finish without
1370
pressing Ctrl-C. We let it run for 1 second and then interrupt::
1371
1372
sage: alarm(1.0); list(MyIntegers)
1373
Traceback (most recent call last):
1374
...
1375
AlarmInterrupt
1376
1377
"""
1378
try:
1379
if self._list is not None:
1380
return self._list
1381
except AttributeError:
1382
pass
1383
# if known to be infinite, give up
1384
# if unsure, proceed (which will hang for an infinite set)
1385
try:
1386
if not self.is_finite():
1387
raise ValueError('since it is infinite, cannot list %s' % self )
1388
except (AttributeError, NotImplementedError):
1389
pass
1390
the_list = list(self.__iter__())
1391
try:
1392
self._list = the_list
1393
except AttributeError:
1394
pass
1395
return the_list
1396
1397
def __nonzero__(self):
1398
"""
1399
By default, all Parents are treated as True when used in an if
1400
statement. Override this method if other behavior is desired
1401
(for example, for empty sets).
1402
1403
EXAMPLES::
1404
1405
sage: if ZZ: print "Yes"
1406
Yes
1407
"""
1408
return True
1409
1410
cpdef bint _richcmp_helper(left, right, int op) except -2:
1411
"""
1412
Compare left and right.
1413
1414
EXAMPLES::
1415
1416
sage: ZZ < QQ
1417
True
1418
"""
1419
cdef int r
1420
1421
if not PY_TYPE_CHECK(right, Parent) or not PY_TYPE_CHECK(left, Parent):
1422
# One is not a parent -- use arbitrary ordering
1423
if (<PyObject*>left) < (<PyObject*>right):
1424
r = -1
1425
elif (<PyObject*>left) > (<PyObject*>right):
1426
r = 1
1427
else:
1428
r = 0
1429
1430
else:
1431
# Both are parents -- but need *not* have the same type.
1432
if HAS_DICTIONARY(left):
1433
r = left.__cmp__(right)
1434
else:
1435
r = left._cmp_(right)
1436
1437
if op == 0: #<
1438
return r < 0
1439
elif op == 2: #==
1440
return r == 0
1441
elif op == 4: #>
1442
return r > 0
1443
elif op == 1: #<=
1444
return r <= 0
1445
elif op == 3: #!=
1446
return r != 0
1447
elif op == 5: #>=
1448
return r >= 0
1449
1450
# Should be moved and merged into the EnumeratedSets() category (#12955)
1451
def __len__(self):
1452
"""
1453
Returns the number of elements in self. This is the naive algorithm
1454
of listing self and counting the elements.
1455
1456
EXAMPLES::
1457
1458
sage: len(GF(5))
1459
5
1460
sage: len(MatrixSpace(GF(2), 3, 3))
1461
512
1462
"""
1463
return len(self.list())
1464
1465
# Should be moved and merged into the EnumeratedSets() category (#12955)
1466
def __getitem__(self, n):
1467
"""
1468
Returns the `n^{th}` item or slice `n` of self,
1469
by getting self as a list.
1470
1471
EXAMPLES::
1472
1473
sage: MatrixSpace(GF(3), 2, 2)[9]
1474
[0 2]
1475
[0 0]
1476
sage: MatrixSpace(GF(3), 2, 2)[0]
1477
[0 0]
1478
[0 0]
1479
sage: VectorSpace(GF(7), 3)[:10]
1480
[(0, 0, 0),
1481
(1, 0, 0),
1482
(2, 0, 0),
1483
(3, 0, 0),
1484
(4, 0, 0),
1485
(5, 0, 0),
1486
(6, 0, 0),
1487
(0, 1, 0),
1488
(1, 1, 0),
1489
(2, 1, 0)]
1490
1491
TESTS:
1492
1493
We test the workaround described in #12956 to let categories
1494
override this default implementation::
1495
1496
sage: class As(Category):
1497
....: def super_categories(self): return [Sets()]
1498
....: class ParentMethods:
1499
....: def __getitem__(self, n):
1500
....: return 'coucou'
1501
sage: class A(Parent):
1502
....: def __init__(self):
1503
....: Parent.__init__(self, category=As())
1504
sage: a = A()
1505
sage: a[1]
1506
'coucou'
1507
"""
1508
try:
1509
return super(Parent, self).__getitem__(n)
1510
except AttributeError:
1511
return self.list()[n]
1512
1513
1514
#################################################################################
1515
# Generators and Homomorphisms
1516
#################################################################################
1517
1518
def _is_valid_homomorphism_(self, codomain, im_gens):
1519
r"""
1520
Return True if ``im_gens`` defines a valid homomorphism
1521
from self to codomain; otherwise return False.
1522
1523
If determining whether or not a homomorphism is valid has not
1524
been implemented for this ring, then a NotImplementedError exception
1525
is raised.
1526
"""
1527
raise NotImplementedError("Verification of correctness of homomorphisms from %s not yet implemented."%self)
1528
1529
def Hom(self, codomain, category=None):
1530
r"""
1531
Return the homspace ``Hom(self, codomain, category)``.
1532
1533
INPUT:
1534
1535
- ``codomain`` -- a parent
1536
- ``category`` -- a category or ``None`` (default: ``None``)
1537
If ``None``, the meet of the category of ``self`` and
1538
``codomain`` is used.
1539
1540
OUTPUT:
1541
1542
The homspace of all homomorphisms from ``self`` to
1543
``codomain`` in the category ``category``.
1544
1545
.. SEEALSO:: :func:`~sage.categories.homset.Hom`
1546
1547
EXAMPLES::
1548
1549
sage: R.<x,y> = PolynomialRing(QQ, 2)
1550
sage: R.Hom(QQ)
1551
Set of Homomorphisms from Multivariate Polynomial Ring in x, y over Rational Field to Rational Field
1552
1553
Homspaces are defined for very general Sage objects, even elements of familiar rings::
1554
1555
sage: n = 5; Hom(n,7)
1556
Set of Morphisms from 5 to 7 in Category of elements of Integer Ring
1557
sage: z=(2/3); Hom(z,8/1)
1558
Set of Morphisms from 2/3 to 8 in Category of elements of Rational Field
1559
1560
This example illustrates the optional third argument::
1561
1562
sage: QQ.Hom(ZZ, Sets())
1563
Set of Morphisms from Rational Field to Integer Ring in Category of sets
1564
1565
A parent may specify how to construct certain homsets by
1566
implementing a method :meth:`_Hom_`(codomain, category).
1567
See :func:`~sage.categories.homset.Hom` for details.
1568
"""
1569
from sage.categories.homset import Hom
1570
return Hom(self, codomain, category)
1571
1572
def hom(self, im_gens, codomain=None, check=None):
1573
r"""
1574
Return the unique homomorphism from self to codomain that
1575
sends ``self.gens()`` to the entries of ``im_gens``.
1576
Raises a TypeError if there is no such homomorphism.
1577
1578
INPUT:
1579
1580
- ``im_gens`` -- the images in the codomain of the generators
1581
of this object under the homomorphism
1582
1583
- ``codomain`` -- the codomain of the homomorphism
1584
1585
- ``check`` -- whether to verify that the images of generators
1586
extend to define a map (using only canonical coercions).
1587
1588
OUTPUT:
1589
1590
A homomorphism self --> codomain
1591
1592
.. NOTE::
1593
1594
As a shortcut, one can also give an object X instead of
1595
``im_gens``, in which case return the (if it exists)
1596
natural map to X.
1597
1598
EXAMPLES:
1599
1600
Polynomial Ring: We first illustrate construction of a few
1601
homomorphisms involving a polynomial ring::
1602
1603
sage: R.<x> = PolynomialRing(ZZ)
1604
sage: f = R.hom([5], QQ)
1605
sage: f(x^2 - 19)
1606
6
1607
1608
sage: R.<x> = PolynomialRing(QQ)
1609
sage: f = R.hom([5], GF(7))
1610
Traceback (most recent call last):
1611
...
1612
TypeError: images do not define a valid homomorphism
1613
1614
sage: R.<x> = PolynomialRing(GF(7))
1615
sage: f = R.hom([3], GF(49,'a'))
1616
sage: f
1617
Ring morphism:
1618
From: Univariate Polynomial Ring in x over Finite Field of size 7
1619
To: Finite Field in a of size 7^2
1620
Defn: x |--> 3
1621
sage: f(x+6)
1622
2
1623
sage: f(x^2+1)
1624
3
1625
1626
Natural morphism::
1627
1628
sage: f = ZZ.hom(GF(5))
1629
sage: f(7)
1630
2
1631
sage: f
1632
Ring Coercion morphism:
1633
From: Integer Ring
1634
To: Finite Field of size 5
1635
1636
There might not be a natural morphism, in which case a
1637
``TypeError`` is raised::
1638
1639
sage: QQ.hom(ZZ)
1640
Traceback (most recent call last):
1641
...
1642
TypeError: Natural coercion morphism from Rational Field to Integer Ring not defined.
1643
"""
1644
if isinstance(im_gens, Parent):
1645
return self.Hom(im_gens).natural_map()
1646
from sage.structure.sequence import Sequence_generic, Sequence
1647
if codomain is None:
1648
im_gens = Sequence(im_gens)
1649
codomain = im_gens.universe()
1650
if isinstance(im_gens, (Sequence_generic, Generators)):
1651
im_gens = list(im_gens)
1652
if check is None:
1653
return self.Hom(codomain)(im_gens)
1654
else:
1655
return self.Hom(codomain)(im_gens, check=check)
1656
1657
#################################################################################
1658
# New Coercion support functionality
1659
#################################################################################
1660
1661
def _populate_coercion_lists_(self,
1662
coerce_list=[],
1663
action_list=[],
1664
convert_list=[],
1665
embedding=None,
1666
convert_method_name=None,
1667
element_constructor=None,
1668
init_no_parent=None,
1669
bint unpickling=False):
1670
"""
1671
This function allows one to specify coercions, actions, conversions
1672
and embeddings involving this parent.
1673
1674
IT SHOULD ONLY BE CALLED DURING THE __INIT__ method, often at the end.
1675
1676
INPUT:
1677
1678
- ``coerce_list`` -- a list of coercion Morphisms to self and
1679
parents with canonical coercions to self
1680
1681
- ``action_list`` -- a list of actions on and by self
1682
1683
- ``convert_list`` -- a list of conversion Maps to self and
1684
parents with conversions to self
1685
1686
- ``embedding`` -- a single Morphism from self
1687
1688
- ``convert_method_name`` -- a name to look for that other elements
1689
can implement to create elements of self (e.g. _integer_)
1690
1691
- ``element_constructor`` -- A callable object used by the
1692
__call__ method to construct new elements. Typically the
1693
element class or a bound method (defaults to
1694
self._element_constructor_).
1695
1696
- ``init_no_parent`` -- if True omit passing self in as the
1697
first argument of element_constructor for conversion. This
1698
is useful if parents are unique, or element_constructor is a
1699
bound method (this latter case can be detected
1700
automatically).
1701
"""
1702
self.init_coerce(False)
1703
1704
if element_constructor is None and not unpickling:
1705
try:
1706
element_constructor = self._element_constructor_
1707
except AttributeError:
1708
raise RuntimeError("element_constructor must be provided, either as an _element_constructor_ method or via the _populate_coercion_lists_ call")
1709
self._element_constructor = element_constructor
1710
self._element_init_pass_parent = guess_pass_parent(self, element_constructor)
1711
1712
if not PY_TYPE_CHECK(coerce_list, list):
1713
raise ValueError("%s_populate_coercion_lists_: coerce_list is type %s, must be list" % (type(coerce_list), type(self)))
1714
if not PY_TYPE_CHECK(action_list, list):
1715
raise ValueError("%s_populate_coercion_lists_: action_list is type %s, must be list" % (type(action_list), type(self)))
1716
if not PY_TYPE_CHECK(convert_list, list):
1717
raise ValueError("%s_populate_coercion_lists_: convert_list is type %s, must be list" % (type(convert_list), type(self)))
1718
1719
self._initial_coerce_list = copy(coerce_list)
1720
self._initial_action_list = copy(action_list)
1721
self._initial_convert_list = copy(convert_list)
1722
1723
self._convert_method_name = convert_method_name
1724
if init_no_parent is not None:
1725
self._element_init_pass_parent = not init_no_parent
1726
1727
for mor in coerce_list:
1728
self.register_coercion(mor)
1729
for action in action_list:
1730
self.register_action(action)
1731
for mor in convert_list:
1732
self.register_conversion(mor)
1733
if embedding is not None:
1734
self.register_embedding(embedding)
1735
1736
1737
def _unset_coercions_used(self):
1738
r"""
1739
Pretend that this parent has never been interrogated by the coercion
1740
model, so that it is possible to add coercions, conversions, and
1741
actions. Does not remove any existing embedding.
1742
1743
WARNING::
1744
1745
For internal use only!
1746
"""
1747
self._coercions_used = False
1748
import sage.structure.element
1749
sage.structure.element.get_coercion_model().reset_cache()
1750
1751
def _unset_embedding(self):
1752
r"""
1753
Pretend that this parent has never been interrogated by the
1754
coercion model, and remove any existing embedding.
1755
1756
WARNING::
1757
1758
This does *not* make it safe to add an entirely new embedding! It
1759
is possible that a `Parent` has cached information about the
1760
existing embedding; that cached information *is not* removed by
1761
this call.
1762
1763
For internal use only!
1764
"""
1765
self._embedding = None
1766
self._unset_coercions_used()
1767
1768
cpdef bint is_coercion_cached(self, domain):
1769
"""
1770
1771
"""
1772
return domain in self._coerce_from_hash
1773
1774
cpdef bint is_conversion_cached(self, domain):
1775
"""
1776
"""
1777
return domain in self._convert_from_hash
1778
1779
cpdef register_coercion(self, mor):
1780
r"""
1781
Update the coercion model to use `mor : P \to \text{self}` to coerce
1782
from a parent ``P`` into ``self``.
1783
1784
For safety, an error is raised if another coercion has already
1785
been registered or discovered between ``P`` and ``self``.
1786
1787
EXAMPLES::
1788
1789
sage: K.<a> = ZZ['a']
1790
sage: L.<b> = ZZ['b']
1791
sage: L_into_K = L.hom([-a]) # non-trivial automorphism
1792
sage: K.register_coercion(L_into_K)
1793
1794
sage: K(0) + b
1795
-a
1796
sage: a + b
1797
0
1798
sage: K(b) # check that convert calls coerce first; normally this is just a
1799
-a
1800
1801
sage: L(0) + a in K # this goes through the coercion mechanism of K
1802
True
1803
sage: L(a) in L # this still goes through the convert mechanism of L
1804
True
1805
1806
sage: K.register_coercion(L_into_K)
1807
Traceback (most recent call last):
1808
...
1809
AssertionError: coercion from Univariate Polynomial Ring in b over Integer Ring to Univariate Polynomial Ring in a over Integer Ring already registered or discovered
1810
"""
1811
if PY_TYPE_CHECK(mor, map.Map):
1812
if mor.codomain() is not self:
1813
raise ValueError("Map's codomain must be self (%s) is not (%s)" % (self, mor.codomain()))
1814
elif PY_TYPE_CHECK(mor, Parent) or PY_TYPE_CHECK(mor, type):
1815
mor = self._generic_convert_map(mor)
1816
else:
1817
raise TypeError("coercions must be parents or maps (got %s)" % type(mor))
1818
1819
assert not (self._coercions_used and mor.domain() in self._coerce_from_hash), "coercion from %s to %s already registered or discovered"%(mor.domain(), self)
1820
self._coerce_from_list.append(mor)
1821
self._coerce_from_hash.set(mor.domain(),mor)
1822
1823
cpdef register_action(self, action):
1824
r"""
1825
Update the coercion model to use ``action`` to act on self.
1826
1827
``action`` should be of type ``sage.categories.action.Action``.
1828
1829
EXAMPLES::
1830
1831
sage: import sage.categories.action
1832
sage: import operator
1833
1834
sage: class SymmetricGroupAction(sage.categories.action.Action):
1835
....: "Act on a multivariate polynomial ring by permuting the generators."
1836
....: def __init__(self, G, M, is_left=True):
1837
....: sage.categories.action.Action.__init__(self, G, M, is_left, operator.mul)
1838
....:
1839
....: def _call_(self, g, a):
1840
....: if not self.is_left():
1841
....: g, a = a, g
1842
....: D = {}
1843
....: for k, v in a.dict().items():
1844
....: nk = [0]*len(k)
1845
....: for i in range(len(k)):
1846
....: nk[g(i+1)-1] = k[i]
1847
....: D[tuple(nk)] = v
1848
....: return a.parent()(D)
1849
1850
sage: R.<x, y, z> = QQ['x, y, z']
1851
sage: G = SymmetricGroup(3)
1852
sage: act = SymmetricGroupAction(G, R)
1853
sage: t = x + 2*y + 3*z
1854
1855
sage: act(G((1, 2)), t)
1856
2*x + y + 3*z
1857
sage: act(G((2, 3)), t)
1858
x + 3*y + 2*z
1859
sage: act(G((1, 2, 3)), t)
1860
3*x + y + 2*z
1861
1862
This should fail, since we haven't registered the left
1863
action::
1864
1865
sage: G((1,2)) * t
1866
Traceback (most recent call last):
1867
...
1868
TypeError: ...
1869
1870
Now let's make it work::
1871
1872
sage: R._unset_coercions_used()
1873
sage: R.register_action(act)
1874
sage: G((1, 2)) * t
1875
2*x + y + 3*z
1876
"""
1877
assert not self._coercions_used, "coercions must all be registered up before use"
1878
from sage.categories.action import Action
1879
if isinstance(action, Action):
1880
if action.actor() is self:
1881
self._action_list.append(action)
1882
self._action_hash.set(action.domain(), action.operation(), action.is_left(), action)
1883
elif action.domain() is self:
1884
self._action_list.append(action)
1885
self._action_hash.set(action.actor(), action.operation(), not action.is_left(), action)
1886
else:
1887
raise ValueError("Action must involve self")
1888
else:
1889
raise TypeError("actions must be actions")
1890
1891
cpdef register_conversion(self, mor):
1892
r"""
1893
Update the coercion model to use `\text{mor} : P \to \text{self}` to convert
1894
from ``P`` into ``self``.
1895
1896
EXAMPLES::
1897
1898
sage: K.<a> = ZZ['a']
1899
sage: M.<c> = ZZ['c']
1900
sage: M_into_K = M.hom([a]) # trivial automorphism
1901
sage: K._unset_coercions_used()
1902
sage: K.register_conversion(M_into_K)
1903
1904
sage: K(c)
1905
a
1906
sage: K(0) + c
1907
Traceback (most recent call last):
1908
...
1909
TypeError: ...
1910
"""
1911
assert not (self._coercions_used and mor.domain() in self._convert_from_hash), "conversion from %s to %s already registered or discovered"%(mor.domain(), self)
1912
if isinstance(mor, map.Map):
1913
if mor.codomain() is not self:
1914
raise ValueError("Map's codomain must be self")
1915
self._convert_from_list.append(mor)
1916
self._convert_from_hash.set(mor.domain(),mor)
1917
elif PY_TYPE_CHECK(mor, Parent) or PY_TYPE_CHECK(mor, type):
1918
t = mor
1919
mor = self._generic_convert_map(mor)
1920
self._convert_from_list.append(mor)
1921
self._convert_from_hash.set(t, mor)
1922
self._convert_from_hash.set(mor.domain(), mor)
1923
else:
1924
raise TypeError("conversions must be parents or maps")
1925
1926
cpdef register_embedding(self, embedding):
1927
r"""
1928
Add embedding to coercion model.
1929
1930
This method updates the coercion model to use
1931
`\text{embedding} : \text{self} \to P` to embed ``self`` into
1932
the parent ``P``.
1933
1934
There can only be one embedding registered; it can only be registered
1935
once; and it must be registered before using this parent in the
1936
coercion model.
1937
1938
EXAMPLES::
1939
1940
sage: S3 = AlternatingGroup(3)
1941
sage: G = SL(3, QQ)
1942
sage: p = S3[2]; p.matrix()
1943
[0 0 1]
1944
[1 0 0]
1945
[0 1 0]
1946
1947
By default, one can't mix matrices and permutations::
1948
1949
sage: G(p)
1950
Traceback (most recent call last):
1951
...
1952
TypeError: entries must be coercible to a list or integer
1953
sage: G(1) * p
1954
Traceback (most recent call last):
1955
...
1956
TypeError: ...
1957
sage: phi = S3.hom(lambda p: G(p.matrix()), codomain = G)
1958
sage: phi(p)
1959
[0 0 1]
1960
[1 0 0]
1961
[0 1 0]
1962
sage: S3._unset_coercions_used()
1963
sage: S3.register_embedding(phi)
1964
sage: S3.coerce_embedding()
1965
Generic morphism:
1966
From: Alternating group of order 3!/2 as a permutation group
1967
To: Special Linear Group of degree 3 over Rational Field
1968
sage: S3.coerce_embedding()(p)
1969
[0 0 1]
1970
[1 0 0]
1971
[0 1 0]
1972
1973
This does not work since matrix groups are still old-style
1974
parents (see :trac:`14014`)::
1975
1976
sage: G(p) # todo: not implemented
1977
sage: G(1) * p # todo: not implemented
1978
1979
Some more advanced examples::
1980
1981
sage: x = QQ['x'].0
1982
sage: t = abs(ZZ.random_element(10^6))
1983
sage: K = NumberField(x^2 + 2*3*7*11, "a"+str(t))
1984
sage: a = K.gen()
1985
sage: K_into_MS = K.hom([a.matrix()])
1986
sage: K._unset_coercions_used()
1987
sage: K.register_embedding(K_into_MS)
1988
1989
sage: L = NumberField(x^2 + 2*3*7*11*19*31, "b"+str(abs(ZZ.random_element(10^6))))
1990
sage: b = L.gen()
1991
sage: L_into_MS = L.hom([b.matrix()])
1992
sage: L._unset_coercions_used()
1993
sage: L.register_embedding(L_into_MS)
1994
1995
sage: K.coerce_embedding()(a)
1996
[ 0 1]
1997
[-462 0]
1998
sage: L.coerce_embedding()(b)
1999
[ 0 1]
2000
[-272118 0]
2001
2002
sage: a.matrix() * b
2003
[-272118 0]
2004
[ 0 -462]
2005
sage: a * b.matrix()
2006
[-272118 0]
2007
[ 0 -462]
2008
"""
2009
assert not self._coercions_used, "coercions must all be registered up before use"
2010
assert self._embedding is None, "only one embedding allowed"
2011
2012
if isinstance(embedding, map.Map):
2013
if embedding.domain() is not self:
2014
raise ValueError("embedding's domain must be self")
2015
self._embedding = embedding
2016
elif isinstance(embedding, Parent):
2017
self._embedding = embedding._generic_convert_map(self)
2018
elif embedding is not None:
2019
raise TypeError("embedding must be a parent or map")
2020
2021
def coerce_embedding(self):
2022
"""
2023
Returns the embedding of self into some other parent, if such a parent
2024
exists.
2025
2026
This does not mean that there are no coercion maps from self into other
2027
fields, this is simply a specific morphism specified out of self and
2028
usually denotes a special relationship (e.g. sub-objects, choice of
2029
completion, etc.)
2030
2031
EXAMPLES::
2032
2033
sage: K.<a>=NumberField(x^3+x^2+1,embedding=1)
2034
sage: K.coerce_embedding()
2035
Generic morphism:
2036
From: Number Field in a with defining polynomial x^3 + x^2 + 1
2037
To: Real Lazy Field
2038
Defn: a -> -1.465571231876768?
2039
sage: K.<a>=NumberField(x^3+x^2+1,embedding=CC.gen())
2040
sage: K.coerce_embedding()
2041
Generic morphism:
2042
From: Number Field in a with defining polynomial x^3 + x^2 + 1
2043
To: Complex Lazy Field
2044
Defn: a -> 0.2327856159383841? + 0.7925519925154479?*I
2045
"""
2046
return self._embedding
2047
2048
cpdef _generic_convert_map(self, S):
2049
r"""
2050
Returns the default conversion map based on the data provided to
2051
:meth:`_populate_coercion_lists_`.
2052
2053
This called when :meth:`_coerce_map_from_` returns ``True``.
2054
2055
If a ``convert_method_name`` is provided, it creates a
2056
``NamedConvertMap``, otherwise it creates a
2057
``DefaultConvertMap`` or ``DefaultConvertMap_unique``
2058
depending on whether or not init_no_parent is set.
2059
2060
EXAMPLES:
2061
"""
2062
import coerce_maps
2063
if self._convert_method_name is not None:
2064
# handle methods like _integer_
2065
if PY_TYPE_CHECK(S, type):
2066
element_constructor = S
2067
elif PY_TYPE_CHECK(S, Parent):
2068
element_constructor = (<Parent>S)._element_constructor
2069
if not PY_TYPE_CHECK(element_constructor, type):
2070
# if element_constructor is not an actual class, get the element class
2071
element_constructor = type(S.an_element())
2072
else:
2073
element_constructor = None
2074
if element_constructor is not None and hasattr(element_constructor, self._convert_method_name):
2075
return coerce_maps.NamedConvertMap(S, self, self._convert_method_name)
2076
2077
if self._element_init_pass_parent:
2078
return coerce_maps.DefaultConvertMap(S, self)
2079
else:
2080
return coerce_maps.DefaultConvertMap_unique(S, self)
2081
2082
def _coerce_map_via(self, v, S):
2083
"""
2084
This attempts to construct a morphism from S to self by passing through
2085
one of the items in v (tried in order).
2086
2087
S may appear in the list, in which case algorithm will never progress
2088
beyond that point.
2089
2090
This is similar in spirit to the old {{{_coerce_try}}}, and useful when
2091
defining _coerce_map_from_
2092
2093
INPUT:
2094
2095
- ``v`` - A list (iterator) of parents with coercions into self. There
2096
MUST be maps provided from each item in the list to self.
2097
2098
- ``S`` - the starting parent
2099
2100
EXAMPLES::
2101
2102
sage: CDF._coerce_map_via([ZZ, RR, CC], int)
2103
Composite map:
2104
From: Set of Python objects of type 'int'
2105
To: Complex Double Field
2106
Defn: Native morphism:
2107
From: Set of Python objects of type 'int'
2108
To: Integer Ring
2109
then
2110
Native morphism:
2111
From: Integer Ring
2112
To: Complex Double Field
2113
2114
sage: CDF._coerce_map_via([ZZ, RR, CC], QQ)
2115
Composite map:
2116
From: Rational Field
2117
To: Complex Double Field
2118
Defn: Generic map:
2119
From: Rational Field
2120
To: Real Field with 53 bits of precision
2121
then
2122
Native morphism:
2123
From: Real Field with 53 bits of precision
2124
To: Complex Double Field
2125
2126
sage: CDF._coerce_map_via([ZZ, RR, CC], CC)
2127
Generic map:
2128
From: Complex Field with 53 bits of precision
2129
To: Complex Double Field
2130
"""
2131
cdef Parent R
2132
for R in v:
2133
if R is None:
2134
continue
2135
if R is S:
2136
return self.coerce_map_from(R)
2137
connecting = R.coerce_map_from(S)
2138
if connecting is not None:
2139
return self.coerce_map_from(R) * connecting
2140
2141
cpdef bint has_coerce_map_from(self, S) except -2:
2142
"""
2143
Return True if there is a natural map from S to self.
2144
Otherwise, return False.
2145
2146
EXAMPLES::
2147
2148
sage: RDF.has_coerce_map_from(QQ)
2149
True
2150
sage: RDF.has_coerce_map_from(QQ['x'])
2151
False
2152
sage: RDF['x'].has_coerce_map_from(QQ['x'])
2153
True
2154
sage: RDF['x,y'].has_coerce_map_from(QQ['x'])
2155
True
2156
"""
2157
if S is self:
2158
return True
2159
elif S == self:
2160
if debug.unique_parent_warnings:
2161
print "Warning: non-unique parents %s"%(type(S))
2162
return True
2163
return self.coerce_map_from(S) is not None
2164
2165
cpdef _coerce_map_from_(self, S):
2166
"""
2167
Override this method to specify coercions beyond those specified
2168
in coerce_list.
2169
2170
If no such coercion exists, return None or False. Otherwise, it may
2171
return either an actual Map to use for the coercion, a callable
2172
(in which case it will be wrapped in a Map), or True (in which case
2173
a generic map will be provided).
2174
"""
2175
return None
2176
2177
cpdef coerce_map_from(self, S):
2178
"""
2179
This returns a Map object to coerce from S to self if one exists,
2180
or None if no such coercion exists.
2181
2182
EXAMPLES::
2183
2184
sage: ZZ.coerce_map_from(int)
2185
Native morphism:
2186
From: Set of Python objects of type 'int'
2187
To: Integer Ring
2188
sage: QQ.coerce_map_from(ZZ)
2189
Natural morphism:
2190
From: Integer Ring
2191
To: Rational Field
2192
2193
By :trac:`12313`, a special kind of weak key dictionary is used to
2194
store coercion and conversion maps, namely
2195
:class:`~sage.structure.coerce_dict.MonoDict`. In that way, a memory
2196
leak was fixed that would occur in the following test::
2197
2198
sage: import gc
2199
sage: _ = gc.collect()
2200
sage: K = GF(1<<55,'t')
2201
sage: for i in range(50):
2202
....: a = K.random_element()
2203
....: E = EllipticCurve(j=a)
2204
....: b = K.has_coerce_map_from(E)
2205
sage: _ = gc.collect()
2206
sage: len([x for x in gc.get_objects() if isinstance(x,type(E))])
2207
1
2208
2209
TESTS:
2210
2211
The following was fixed in :trac:`12969`::
2212
2213
sage: R = QQ['q,t'].fraction_field()
2214
sage: Sym = sage.combinat.sf.sf.SymmetricFunctions(R)
2215
sage: H = Sym.macdonald().H()
2216
sage: P = Sym.macdonald().P()
2217
sage: m = Sym.monomial()
2218
sage: Ht = Sym.macdonald().Ht()
2219
sage: phi = m.coerce_map_from(P)
2220
sage: Ht.coerce_map_from(P)
2221
Composite map:
2222
From: Symmetric Functions over Fraction Field of Multivariate Polynomial Ring in q, t over Rational Field in the Macdonald P basis
2223
To: Symmetric Functions over Fraction Field of Multivariate Polynomial Ring in q, t over Rational Field in the Macdonald Ht basis
2224
Defn: Composite map:
2225
From: Symmetric Functions over Fraction Field of Multivariate Polynomial Ring in q, t over Rational Field in the Macdonald P basis
2226
To: Symmetric Functions over Fraction Field of Multivariate Polynomial Ring in q, t over Rational Field in the Schur basis
2227
Defn: Generic morphism:
2228
From: Symmetric Functions over Fraction Field of Multivariate Polynomial Ring in q, t over Rational Field in the Macdonald P basis
2229
To: Symmetric Functions over Fraction Field of Multivariate Polynomial Ring in q, t over Rational Field in the Macdonald J basis
2230
then
2231
Generic morphism:
2232
From: Symmetric Functions over Fraction Field of Multivariate Polynomial Ring in q, t over Rational Field in the Macdonald J basis
2233
To: Symmetric Functions over Fraction Field of Multivariate Polynomial Ring in q, t over Rational Field in the Schur basis
2234
then
2235
Generic morphism:
2236
From: Symmetric Functions over Fraction Field of Multivariate Polynomial Ring in q, t over Rational Field in the Schur basis
2237
To: Symmetric Functions over Fraction Field of Multivariate Polynomial Ring in q, t over Rational Field in the Macdonald Ht basis
2238
2239
The following was fixed in :trac:`4740`::
2240
2241
sage: F = GF(13)
2242
sage: F.coerce_map_from(F) is F.coerce_map_from(F)
2243
True
2244
2245
"""
2246
if not good_as_coerce_domain(S):
2247
return None
2248
self._coercions_used = True
2249
cdef map.Map mor
2250
2251
if isinstance(S, Set_PythonType_class):
2252
return self.coerce_map_from(S._type)
2253
if self._coerce_from_hash is None: # this is because parent.__init__() does not always get called
2254
self.init_coerce(False)
2255
2256
try:
2257
return self._coerce_from_hash.get(S)
2258
except KeyError:
2259
pass
2260
2261
if S is self:
2262
from sage.categories.homset import Hom
2263
mor = Hom(self, self).identity()
2264
self._coerce_from_hash.set(S, mor)
2265
return mor
2266
2267
if S == self:
2268
# non-unique parents
2269
if debug.unique_parent_warnings:
2270
print "Warning: non-unique parents %s"%(type(S))
2271
mor = self._generic_convert_map(S)
2272
self._coerce_from_hash.set(S, mor)
2273
return mor
2274
2275
try:
2276
_register_pair(self, S, "coerce")
2277
mor = self.discover_coerce_map_from(S)
2278
#if mor is not None:
2279
# # Need to check that this morphism doesn't connect previously unconnected parts of the coercion diagram
2280
# if self._embedding is not None and not self._embedding.codomain().has_coerce_map_from(S):
2281
# # The following if statement may call this function with self and S. If so, we want to return None,
2282
# # so that it doesn't use this path for the existence of a coercion path.
2283
# # We disable this for now because it is too strict
2284
# pass
2285
# # print "embed problem: the following morphisms connect unconnected portions of the coercion graph\n%s\n%s"%(self._embedding, mor)
2286
# # mor = None
2287
if mor is not None:
2288
# NOTE: this line is what makes the coercion detection stateful
2289
# self._coerce_from_list.append(mor)
2290
pass
2291
# It may be that the only coercion from S to self is
2292
# via another parent X. But if the pair (S,X) is temporarily
2293
# disregarded (using _register_pair, to avoid infinite recursion)
2294
# then we are not allowed to cache the absence of a coercion
2295
# from S to self. See #12969
2296
if (mor is not None) or _may_cache_none(self, S, "coerce"):
2297
self._coerce_from_hash.set(S,mor)
2298
return mor
2299
except CoercionException, ex:
2300
_record_exception()
2301
return None
2302
finally:
2303
_unregister_pair(self, S, "coerce")
2304
2305
2306
cdef discover_coerce_map_from(self, S):
2307
"""
2308
Precedence for discovering a coercion S -> self goes as follows:
2309
2310
1. If S has an embedding into T, look for T -> self and return composition
2311
2312
2. If self._coerce_map_from_(S) is NOT exactly one of
2313
2314
- DefaultConvertMap
2315
- DefaultConvertMap_unique
2316
- NamedConvertMap
2317
2318
return this map
2319
2320
3. Traverse the coercion lists looking for another map
2321
returning the map from step (2) if none is found.
2322
2323
In the future, multiple paths may be discovered and compared.
2324
2325
TESTS:
2326
2327
Regression test for :trac:`12919` (probably not 100% robust)::
2328
2329
sage: class P(Parent):
2330
....: def __init__(self):
2331
....: Parent.__init__(self, category=Sets())
2332
....: Element=ElementWrapper
2333
sage: A = P(); a = A('a')
2334
sage: B = P(); b = B('b')
2335
sage: C = P(); c = C('c')
2336
sage: D = P(); d = D('d')
2337
sage: Hom(A, B)(lambda x: b).register_as_coercion()
2338
sage: Hom(B, A)(lambda x: a).register_as_coercion()
2339
sage: Hom(C, B)(lambda x: b).register_as_coercion()
2340
sage: Hom(D, C)(lambda x: c).register_as_coercion()
2341
sage: A(d)
2342
'a'
2343
2344
Another test::
2345
2346
sage: K = NumberField([x^2-2, x^2-3], 'a,b')
2347
sage: M = K.absolute_field('c')
2348
sage: M_to_K, K_to_M = M.structure()
2349
sage: M.register_coercion(K_to_M)
2350
sage: K.register_coercion(M_to_K)
2351
sage: phi = M.coerce_map_from(QQ)
2352
sage: p = QQ.random_element()
2353
sage: c = phi(p) - p; c
2354
0
2355
sage: c.parent() is M
2356
True
2357
sage: K.coerce_map_from(QQ)
2358
Conversion map:
2359
From: Rational Field
2360
To: Number Field in a with defining polynomial x^2 - 2 over its base field
2361
"""
2362
best_mor = None
2363
if PY_TYPE_CHECK(S, Parent) and (<Parent>S)._embedding is not None:
2364
if (<Parent>S)._embedding.codomain() is self:
2365
return (<Parent>S)._embedding
2366
connecting = self.coerce_map_from((<Parent>S)._embedding.codomain())
2367
if connecting is not None:
2368
return (<Parent>S)._embedding.post_compose(connecting)
2369
2370
cdef map.Map mor
2371
user_provided_mor = self._coerce_map_from_(S)
2372
2373
if user_provided_mor is False:
2374
user_provided_mor = None
2375
2376
elif user_provided_mor is not None:
2377
2378
from sage.categories.map import Map
2379
from coerce_maps import DefaultConvertMap, DefaultConvertMap_unique, NamedConvertMap, CallableConvertMap
2380
2381
if user_provided_mor is True:
2382
mor = self._generic_convert_map(S)
2383
elif PY_TYPE_CHECK(user_provided_mor, Map):
2384
mor = <map.Map>user_provided_mor
2385
elif callable(user_provided_mor):
2386
mor = CallableConvertMap(user_provided_mor)
2387
else:
2388
raise TypeError("_coerce_map_from_ must return None, a boolean, a callable, or an explicit Map (called on %s, got %s)" % (type(self), type(user_provided_mor)))
2389
2390
if (PY_TYPE_CHECK_EXACT(mor, DefaultConvertMap) or
2391
PY_TYPE_CHECK_EXACT(mor, DefaultConvertMap_unique) or
2392
PY_TYPE_CHECK_EXACT(mor, NamedConvertMap)) and not mor._force_use:
2393
# If there is something better in the list, try to return that instead
2394
# This is so, for example, _coerce_map_from_ can return True but still
2395
# take advantage of the _populate_coercion_lists_ data.
2396
best_mor = mor
2397
else:
2398
return mor
2399
2400
from sage.categories.homset import Hom
2401
2402
cdef int num_paths = 1 # this is the number of paths we find before settling on the best (the one with lowest coerce_cost).
2403
# setting this to 1 will make it return the first path found.
2404
cdef int mor_found = 0
2405
cdef Parent R
2406
# Recurse. Note that if S is the domain of one of the maps in self._coerce_from_list,
2407
# we will have stuck the map into _coerce_map_hash and thus returned it already.
2408
for mor in self._coerce_from_list:
2409
if mor._domain is self:
2410
continue
2411
if mor._domain is S:
2412
if best_mor is None or mor._coerce_cost < best_mor._coerce_cost:
2413
best_mor = mor
2414
mor_found += 1
2415
if mor_found >= num_paths:
2416
return best_mor
2417
else:
2418
connecting = None
2419
if EltPair(mor._domain, S, "coerce") not in _coerce_test_dict:
2420
connecting = mor._domain.coerce_map_from(S)
2421
if connecting is not None:
2422
mor = mor * connecting
2423
if best_mor is None or mor._coerce_cost < best_mor._coerce_cost:
2424
best_mor = mor
2425
mor_found += 1
2426
if mor_found >= num_paths:
2427
return best_mor
2428
2429
return best_mor
2430
2431
2432
cpdef convert_map_from(self, S):
2433
"""
2434
This function returns a Map from S to self, which may or may not
2435
succeed on all inputs. If a coercion map from S to self exists,
2436
then the it will be returned. If a coercion from self to S exists,
2437
then it will attempt to return a section of that map.
2438
2439
Under the new coercion model, this is the fastest way to convert
2440
elements of S to elements of self (short of manually constructing
2441
the elements) and is used by __call__.
2442
2443
EXAMPLES::
2444
2445
sage: m = ZZ.convert_map_from(QQ)
2446
sage: m(-35/7)
2447
-5
2448
sage: parent(m(-35/7))
2449
Integer Ring
2450
"""
2451
if not good_as_convert_domain(S):
2452
return None
2453
if self._convert_from_hash is None: # this is because parent.__init__() does not always get called
2454
self.init_coerce()
2455
try:
2456
return self._convert_from_hash.get(S)
2457
except KeyError:
2458
mor = self.discover_convert_map_from(S)
2459
self._convert_from_list.append(mor)
2460
self._convert_from_hash.set(S, mor)
2461
return mor
2462
2463
cdef discover_convert_map_from(self, S):
2464
2465
cdef map.Map mor = self.coerce_map_from(S)
2466
if mor is not None:
2467
return mor
2468
2469
if PY_TYPE_CHECK(S, Parent):
2470
mor = S.coerce_map_from(self)
2471
if mor is not None:
2472
mor = mor.section()
2473
if mor is not None:
2474
return mor
2475
2476
user_provided_mor = self._convert_map_from_(S)
2477
2478
if user_provided_mor is not None:
2479
if PY_TYPE_CHECK(user_provided_mor, map.Map):
2480
return user_provided_mor
2481
elif callable(user_provided_mor):
2482
from coerce_maps import CallableConvertMap
2483
return CallableConvertMap(user_provided_mor)
2484
else:
2485
raise TypeError("_convert_map_from_ must return a map or callable (called on %s, got %s)" % (type(self), type(user_provided_mor)))
2486
2487
if not PY_TYPE_CHECK(S, type) and not PY_TYPE_CHECK(S, Parent):
2488
# Sequences is used as a category and a "Parent"
2489
from sage.categories.category_types import Sequences
2490
from sage.structure.coerce_maps import ListMorphism
2491
if isinstance(S, Sequences):
2492
return ListMorphism(S, self.convert_map_from(list))
2493
2494
mor = self._generic_convert_map(S)
2495
return mor
2496
2497
cpdef _convert_map_from_(self, S):
2498
"""
2499
Override this method to provide additional conversions beyond those
2500
given in convert_list.
2501
2502
This function is called after coercions are attempted. If there is a
2503
coercion morphism in the opposite direction, one should consider
2504
adding a section method to that.
2505
2506
This MUST return a Map from S to self, or None. If None is returned
2507
then a generic map will be provided.
2508
"""
2509
return None
2510
2511
cpdef get_action(self, S, op=operator.mul, bint self_on_left=True, self_el=None, S_el=None):
2512
"""
2513
Returns an action of self on S or S on self.
2514
2515
To provide additional actions, override :meth:`_get_action_`.
2516
2517
TESTS::
2518
2519
sage: M = QQ['y']^3
2520
sage: M.get_action(ZZ['x']['y'])
2521
Right scalar multiplication by Univariate Polynomial Ring in y over Univariate Polynomial Ring in x over Integer Ring on Ambient free module of rank 3 over the principal ideal domain Univariate Polynomial Ring in y over Rational Field
2522
sage: M.get_action(ZZ['x']) # should be None
2523
"""
2524
try:
2525
if self._action_hash is None: # this is because parent.__init__() does not always get called
2526
self.init_coerce()
2527
return self._action_hash.get(S, op, self_on_left)
2528
except KeyError:
2529
pass
2530
2531
action = self._get_action_(S, op, self_on_left)
2532
if action is None:
2533
action = self.discover_action(S, op, self_on_left, self_el, S_el)
2534
2535
if action is not None:
2536
from sage.categories.action import Action
2537
if not isinstance(action, Action):
2538
raise TypeError("get_action_impl must return None or an Action")
2539
# We do NOT add to the list, as this would lead to errors as in
2540
# the example above.
2541
2542
self._action_hash.set(S, op, self_on_left, action)
2543
return action
2544
2545
2546
cdef discover_action(self, S, op, bint self_on_left, self_el=None, S_el=None):
2547
# G acts on S, G -> G', R -> S => G' acts on R (?)
2548
# NO! ZZ[x,y] acts on Matrices(ZZ[x]) but ZZ[y] does not.
2549
# What may be true is that if the action's destination is S, then this can be allowed.
2550
# Note: a is either None or a sample elements of self.
2551
# If needed, it will be passed to Left/RightModuleAction.
2552
from sage.categories.action import Action, PrecomposedAction
2553
from sage.categories.homset import Hom
2554
from coerce_actions import LeftModuleAction, RightModuleAction
2555
cdef Parent R
2556
for action in self._action_list:
2557
if PY_TYPE_CHECK(action, Action) and action.operation() is op:
2558
if self_on_left:
2559
if action.left_domain() is not self: continue
2560
R = action.right_domain()
2561
else:
2562
if action.right_domain() is not self: continue
2563
R = action.left_domain()
2564
elif op is operator.mul and isinstance(action, Parent):
2565
try:
2566
R = action
2567
_register_pair(self, R, "action") # to kill circular recursion
2568
if self_on_left:
2569
action = LeftModuleAction(R, self, a=S_el, g=self_el) # self is acted on from right
2570
else:
2571
action = RightModuleAction(R, self, a=S_el, g=self_el) # self is acted on from left
2572
## The following two lines are disabled to prevent the following from working:
2573
## sage: x, y = var('x,y')
2574
## sage: parent(ZZ[x][y](1)*vector(QQ[y],[1,2]))
2575
## sage: parent(ZZ[x](1)*vector(QQ[y],[1,2]))
2576
## We will hopefully come up with a way to reinsert them, because they increase the scope
2577
## of discovered actions.
2578
#i = self._action_list.index(R)
2579
#self._action_list[i] = action
2580
except CoercionException:
2581
_record_exception()
2582
continue
2583
finally:
2584
_unregister_pair(self, R, "action")
2585
else:
2586
continue # only try mul if not specified
2587
if R is S:
2588
return action
2589
else:
2590
connecting = R.coerce_map_from(S) # S -> R
2591
if connecting is not None:
2592
if self_on_left:
2593
return PrecomposedAction(action, None, connecting)
2594
else:
2595
return PrecomposedAction(action, connecting, None)
2596
2597
# We didn't find an action in the list, but maybe the elements
2598
# define special action methods
2599
if op is operator.mul:
2600
# TODO: if _xmul_/_x_action_ code does stuff like
2601
# if self == 0:
2602
# return self
2603
# then an_element() == 0 could be very bad.
2604
try:
2605
_register_pair(self, S, "action") # this is to avoid possible infinite loops
2606
2607
# detect actions defined by _rmul_, _lmul_, _act_on_, and _acted_upon_ methods
2608
from coerce_actions import detect_element_action
2609
action = detect_element_action(self, S, self_on_left, self_el, S_el)
2610
if action is not None:
2611
return action
2612
2613
try:
2614
# maybe there is a more clever way of detecting ZZ than importing here...
2615
from sage.rings.integer_ring import ZZ
2616
if S is ZZ and not self.has_coerce_map_from(ZZ):
2617
from sage.structure.coerce_actions import IntegerMulAction
2618
action = IntegerMulAction(S, self, not self_on_left, self_el)
2619
return action
2620
except (CoercionException, TypeError):
2621
_record_exception()
2622
2623
finally:
2624
_unregister_pair(self, S, "action")
2625
2626
2627
cpdef _get_action_(self, S, op, bint self_on_left):
2628
"""
2629
Override this method to provide an action of self on S or S on self
2630
beyond what was specified in action_list.
2631
2632
This must return an action which accepts an element of self and an
2633
element of S (in the order specified by self_on_left).
2634
"""
2635
return None
2636
2637
def construction(self):
2638
"""
2639
Returns a pair (functor, parent) such that functor(parent) return self.
2640
If this ring does not have a functorial construction, return None.
2641
2642
EXAMPLES::
2643
2644
sage: QQ.construction()
2645
(FractionField, Integer Ring)
2646
sage: f, R = QQ['x'].construction()
2647
sage: f
2648
Poly[x]
2649
sage: R
2650
Rational Field
2651
sage: f(R)
2652
Univariate Polynomial Ring in x over Rational Field
2653
"""
2654
return None
2655
2656
# TODO: remove once all parents in Sage will inherit properly from
2657
# Sets().ParentMethods.an_element
2658
cpdef an_element(self):
2659
r"""
2660
Returns a (preferably typical) element of this parent.
2661
2662
This is used both for illustration and testing purposes. If
2663
the set ``self`` is empty, :meth:`an_element` raises the
2664
exception :class:`EmptySetError`.
2665
2666
This calls :meth:`_an_element_` (which see), and caches the
2667
result. Parent are thus encouraged to override :meth:`_an_element_`.
2668
2669
EXAMPLES::
2670
2671
sage: CDF.an_element()
2672
1.0*I
2673
sage: ZZ[['t']].an_element()
2674
t
2675
2676
In case the set is empty, an :class:`EmptySetError` is raised::
2677
2678
sage: Set([]).an_element()
2679
Traceback (most recent call last):
2680
...
2681
EmptySetError
2682
"""
2683
if self.__an_element is None:
2684
self.__an_element = self._an_element_()
2685
return self.__an_element
2686
2687
def _an_element_(self):
2688
"""
2689
Returns an element of self. Want it in sufficient generality
2690
that poorly-written functions won't work when they're not
2691
supposed to. This is cached so doesn't have to be super fast.
2692
2693
EXAMPLES::
2694
2695
sage: QQ._an_element_()
2696
1/2
2697
sage: ZZ['x,y,z']._an_element_()
2698
x
2699
2700
TESTS:
2701
2702
Since ``Parent`` comes before the parent classes provided by
2703
categories in the hierarchy of classes, we make sure that this
2704
default implementation of :meth:`_an_element_` does not
2705
override some provided by the categories. Eventually, this
2706
default implementation should be moved into the categories to
2707
avoid this workaround::
2708
2709
sage: S = FiniteEnumeratedSet([1,2,3])
2710
sage: S.category()
2711
Category of facade finite enumerated sets
2712
sage: super(Parent, S)._an_element_
2713
Cached version of <function _an_element_from_iterator at ...>
2714
sage: S._an_element_()
2715
1
2716
sage: S = FiniteEnumeratedSet([])
2717
sage: S._an_element_()
2718
Traceback (most recent call last):
2719
...
2720
EmptySetError
2721
2722
"""
2723
try:
2724
return super(Parent, self)._an_element_()
2725
except EmptySetError:
2726
raise
2727
except Exception:
2728
_record_exception()
2729
pass
2730
2731
try:
2732
return self.gen(0)
2733
except Exception:
2734
_record_exception()
2735
pass
2736
2737
try:
2738
return self.gen()
2739
except Exception:
2740
_record_exception()
2741
pass
2742
2743
from sage.rings.infinity import infinity
2744
for x in ['_an_element_', 'pi', 1.2, 2, 1, 0, infinity]:
2745
# This weird looking list is to try to get an element
2746
# which doesn't coerce other places.
2747
try:
2748
return self(x)
2749
except (TypeError, NameError, NotImplementedError, AttributeError, ValueError):
2750
_record_exception()
2751
2752
raise NotImplementedError("please implement _an_element_ for %s" % self)
2753
2754
cpdef bint is_exact(self) except -2:
2755
"""
2756
Test whether the ring is exact.
2757
2758
.. NOTE::
2759
2760
This defaults to true, so even if it does return ``True``
2761
you have no guarantee (unless the ring has properly
2762
overloaded this).
2763
2764
OUTPUT:
2765
2766
Return True if elements of this ring are represented exactly, i.e.,
2767
there is no precision loss when doing arithmetic.
2768
2769
EXAMPLES::
2770
2771
sage: QQ.is_exact()
2772
True
2773
sage: ZZ.is_exact()
2774
True
2775
sage: Qp(7).is_exact()
2776
False
2777
sage: Zp(7, type='capped-abs').is_exact()
2778
False
2779
"""
2780
return True
2781
2782
# cpdef base_extend(self, other, category=None):
2783
# """
2784
# EXAMPLES:
2785
# sage: QQ.base_extend(GF(7))
2786
# Traceback (most recent call last):
2787
# ...
2788
# TypeError: base extension not defined for Rational Field
2789
# sage: ZZ.base_extend(GF(7))
2790
# Finite Field of size 7
2791
# """
2792
# # Use the coerce map if a base extend is not defined in the category.
2793
# # this is the default implementation.
2794
# try:
2795
# if category is None:
2796
# method = self._categories[0].get_object_method("base_extend") # , self._categories[1:])
2797
# else:
2798
# method = category.get_object_method("base_extend")
2799
# if method is not None:
2800
# return method(self)
2801
# elif other.has_coerce_map_from(self):
2802
# return other
2803
# else:
2804
# raise TypeError, "base extension not defined for %s" % self
2805
# except AttributeError:
2806
# raise TypeError, "base extension not defined for %s" % self
2807
2808
############################################################################
2809
# Set base class --
2810
############################################################################
2811
2812
2813
cdef class Set_generic(Parent): # Cannot use Parent because Element._parent is Parent
2814
"""
2815
Abstract base class for sets.
2816
2817
TESTS::
2818
2819
sage: Set(QQ).category()
2820
Category of sets
2821
2822
"""
2823
# def category(self):
2824
# # TODO: remove once all subclasses specify their category, or
2825
# # the constructor of Parent sets it to Sets() by default
2826
# """
2827
# The category that this set belongs to, which is the category
2828
# of all sets.
2829
2830
# EXAMPLES:
2831
# sage: Set(QQ).category()
2832
# Category of sets
2833
# """
2834
# from sage.categories.sets_cat import Sets
2835
# return Sets()
2836
2837
def object(self):
2838
return self
2839
2840
def __nonzero__(self):
2841
"""
2842
A set is considered True unless it is empty, in which case it is
2843
considered to be False.
2844
2845
EXAMPLES::
2846
2847
sage: bool(Set(QQ))
2848
True
2849
sage: bool(Set(GF(3)))
2850
True
2851
"""
2852
return not (self.is_finite() and len(self) == 0)
2853
2854
2855
import types
2856
cdef _type_set_cache = {}
2857
2858
cpdef Parent Set_PythonType(theType):
2859
"""
2860
Return the (unique) Parent that represents the set of Python objects
2861
of a specified type.
2862
2863
EXAMPLES::
2864
2865
sage: from sage.structure.parent import Set_PythonType
2866
sage: Set_PythonType(list)
2867
Set of Python objects of type 'list'
2868
sage: Set_PythonType(list) is Set_PythonType(list)
2869
True
2870
sage: S = Set_PythonType(tuple)
2871
sage: S([1,2,3])
2872
(1, 2, 3)
2873
2874
S is a parent which models the set of all lists:
2875
sage: S.category()
2876
Category of sets
2877
2878
EXAMPLES::
2879
2880
sage: R = sage.structure.parent.Set_PythonType(int)
2881
sage: S = sage.structure.parent.Set_PythonType(float)
2882
sage: Hom(R, S)
2883
Set of Morphisms from Set of Python objects of type 'int' to Set of Python objects of type 'float' in Category of sets
2884
2885
"""
2886
try:
2887
return _type_set_cache[theType]
2888
except KeyError:
2889
_type_set_cache[theType] = theSet = Set_PythonType_class(theType)
2890
return theSet
2891
2892
cdef class Set_PythonType_class(Set_generic):
2893
2894
cdef _type
2895
2896
def __init__(self, theType):
2897
"""
2898
EXAMPLES::
2899
2900
sage: S = sage.structure.parent.Set_PythonType(float)
2901
sage: S.category()
2902
Category of sets
2903
"""
2904
Set_generic.__init__(self, element_constructor=theType, category=Sets())
2905
self._type = theType
2906
2907
def __call__(self, x):
2908
"""
2909
This doesn't return Elements, but actual objects of the given type.
2910
2911
EXAMPLES::
2912
2913
sage: S = sage.structure.parent.Set_PythonType(float)
2914
sage: S(5)
2915
5.0
2916
sage: S(9/3)
2917
3.0
2918
sage: S(1/3)
2919
0.333333333333333...
2920
2921
"""
2922
if PY_TYPE_CHECK(x,self._type):
2923
return x
2924
return self._type(x)
2925
2926
def __hash__(self):
2927
"""
2928
TESTS::
2929
2930
sage: S = sage.structure.parent.Set_PythonType(int)
2931
sage: hash(S) == -hash(int)
2932
True
2933
"""
2934
return -hash(self._type)
2935
2936
cpdef int _cmp_(self, other) except -100:
2937
"""
2938
Two Python type sets are considered the same if they contain the same
2939
type.
2940
2941
EXAMPLES::
2942
2943
sage: S = sage.structure.parent.Set_PythonType(int)
2944
sage: S == S
2945
True
2946
sage: S == sage.structure.parent.Set_PythonType(float)
2947
False
2948
"""
2949
if self is other:
2950
return 0
2951
if isinstance(other, Set_PythonType_class):
2952
return cmp(self._type, other._type)
2953
else:
2954
return cmp(self._type, other)
2955
2956
def __contains__(self, x):
2957
"""
2958
Only things of the right type (or subtypes thereof) are considered to
2959
belong to the set.
2960
2961
EXAMPLES::
2962
2963
sage: S = sage.structure.parent.Set_PythonType(tuple)
2964
sage: (1,2,3) in S
2965
True
2966
sage: () in S
2967
True
2968
sage: [1,2] in S
2969
False
2970
"""
2971
return isinstance(x, self._type)
2972
2973
def _repr_(self):
2974
"""
2975
EXAMPLES::
2976
2977
sage: sage.structure.parent.Set_PythonType(tuple)
2978
Set of Python objects of type 'tuple'
2979
sage: sage.structure.parent.Set_PythonType(Integer)
2980
Set of Python objects of type 'sage.rings.integer.Integer'
2981
sage: sage.structure.parent.Set_PythonType(Parent)
2982
Set of Python objects of type 'sage.structure.parent.Parent'
2983
"""
2984
return "Set of Python objects of %s"%(str(self._type)[1:-1])
2985
2986
def object(self):
2987
"""
2988
EXAMPLES::
2989
2990
sage: S = sage.structure.parent.Set_PythonType(tuple)
2991
sage: S.object()
2992
<type 'tuple'>
2993
"""
2994
return self._type
2995
2996
def cardinality(self):
2997
"""
2998
EXAMPLES::
2999
3000
sage: S = sage.structure.parent.Set_PythonType(bool)
3001
sage: S.cardinality()
3002
2
3003
sage: S = sage.structure.parent.Set_PythonType(int)
3004
sage: S.cardinality()
3005
4294967296 # 32-bit
3006
18446744073709551616 # 64-bit
3007
sage: S = sage.structure.parent.Set_PythonType(float)
3008
sage: S.cardinality()
3009
18437736874454810627
3010
sage: S = sage.structure.parent.Set_PythonType(long)
3011
sage: S.cardinality()
3012
+Infinity
3013
"""
3014
from sage.rings.integer import Integer
3015
two = Integer(2)
3016
if self._type is bool:
3017
return two
3018
elif self._type is int:
3019
import sys
3020
return two*sys.maxint + 2
3021
elif self._type is float:
3022
return 2 * two**52 * (two**11 - 1) + 3 # all NaN's are the same from Python's point of view
3023
else:
3024
# probably
3025
import sage.rings.infinity
3026
return sage.rings.infinity.infinity
3027
3028
# These functions are to guarantee that user defined _lmul_, _rmul_,
3029
# _act_on_, _acted_upon_ do not in turn call __mul__ on their
3030
# arguments, leading to an infinite loop.
3031
3032
cdef dict _coerce_test_dict = {}
3033
3034
cdef class EltPair:
3035
cdef x, y, tag
3036
def __init__(self, x, y, tag):
3037
self.x = x
3038
self.y = y
3039
self.tag = tag
3040
3041
def __richcmp__(EltPair self, EltPair other, int op):
3042
cdef bint eq = self.x is other.x and self.y is other.y and self.tag is other.tag
3043
if op in [Py_EQ, Py_GE, Py_LE]:
3044
return eq
3045
else:
3046
return not eq
3047
3048
def __hash__(self):
3049
"""
3050
EXAMPLES::
3051
3052
sage: from sage.structure.parent import EltPair
3053
sage: a = EltPair(ZZ, QQ, "coerce")
3054
sage: hash(a) == hash((ZZ, QQ, "coerce"))
3055
True
3056
"""
3057
return hash((self.x, self.y, self.tag))
3058
3059
def short_repr(self):
3060
return self.tag, hex(<long><void*>self.x), hex(<long><void*>self.y)
3061
3062
def __repr__(self):
3063
return "%r: %r (%r), %r (%r)" % (self.tag, self.x, type(self.x), self.y, type(self.y))
3064
3065
cdef bint _may_cache_none(x, y, tag) except -1:
3066
# Are we allowed to cache the absence of a coercion
3067
# from y to x? We are only allowed, if y is *not*
3068
# part of any coerce path that is temporarily disregarded,
3069
# with the only exception of the path from y to x.
3070
# See #12969.
3071
cdef EltPair P
3072
for P in _coerce_test_dict.iterkeys():
3073
if (P.y is y) and (P.x is not x) and (P.tag is tag):
3074
return 0
3075
return 1
3076
3077
cdef bint _register_pair(x, y, tag) except -1:
3078
# Means: We will temporarily disregard coercions from
3079
# y to x when looking for a coercion path by depth first
3080
# search. This is to avoid infinite recursion.
3081
both = EltPair(x,y,tag)
3082
3083
if both in _coerce_test_dict:
3084
xp = type(x) if PY_TYPE_CHECK(x, Parent) else parent_c(x)
3085
yp = type(y) if PY_TYPE_CHECK(y, Parent) else parent_c(y)
3086
raise CoercionException("Infinite loop in action of %s (parent %s) and %s (parent %s)!" % (x, xp, y, yp))
3087
_coerce_test_dict[both] = True
3088
return 0
3089
3090
cdef bint _unregister_pair(x, y, tag) except -1:
3091
try:
3092
_coerce_test_dict.pop(EltPair(x,y,tag), None)
3093
except (ValueError, CoercionException):
3094
pass
3095
3096
empty_set = Set_generic()
3097
3098
def normalize_names(ngens, names):
3099
"""
3100
TESTS::
3101
3102
sage: sage.structure.parent.normalize_names(5, 'x')
3103
('x0', 'x1', 'x2', 'x3', 'x4')
3104
sage: sage.structure.parent.normalize_names(2, ['x','y'])
3105
('x', 'y')
3106
"""
3107
return empty_set.normalize_names(ngens, names)
3108
3109