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