Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/symbolic/ring.pyx
4096 views
1
"""
2
The symbolic ring
3
"""
4
###############################################################################
5
# Sage: Open Source Mathematical Software
6
# Copyright (C) 2008 William Stein <[email protected]>
7
# Copyright (C) 2008 Burcin Erocal <[email protected]>
8
# Distributed under the terms of the GNU General Public License (GPL),
9
# version 2 or any later version. The full text of the GPL is available at:
10
# http://www.gnu.org/licenses/
11
###############################################################################
12
13
include "../ext/stdsage.pxi"
14
include "../ext/cdefs.pxi"
15
16
#################################################################
17
# Initialize the library
18
#################################################################
19
20
#initialize_ginac()
21
22
from sage.libs.ginac cimport *
23
24
from sage.rings.integer cimport Integer
25
from sage.rings.real_mpfr import RealNumber
26
27
from sage.symbolic.expression cimport Expression, new_Expression_from_GEx, new_Expression_from_pyobject
28
from sage.symbolic.expression import is_Expression
29
30
from sage.misc.latex import latex_variable_name
31
from sage.structure.element cimport RingElement, Element
32
from sage.structure.parent_base import ParentWithBase
33
from sage.rings.ring cimport CommutativeRing
34
from sage.categories.morphism cimport Morphism
35
36
from sage.rings.all import RR, CC
37
38
pynac_symbol_registry = {}
39
40
cdef class SymbolicRing(CommutativeRing):
41
"""
42
Symbolic Ring, parent object for all symbolic expressions.
43
"""
44
def __init__(self):
45
"""
46
Initialize the Symbolic Ring.
47
48
EXAMPLES::
49
50
sage: sage.symbolic.ring.SymbolicRing()
51
Symbolic Ring
52
"""
53
CommutativeRing.__init__(self, self)
54
self._populate_coercion_lists_(convert_method_name='_symbolic_')
55
56
def __reduce__(self):
57
"""
58
EXAMPLES::
59
60
sage: loads(dumps(SR)) == SR # indirect doctest
61
True
62
"""
63
return the_SymbolicRing, tuple([])
64
65
def __hash__(self):
66
"""
67
EXAMPLES::
68
69
sage: hash(SR) #random
70
139682705593888
71
"""
72
return hash(SymbolicRing)
73
74
def _repr_(self):
75
"""
76
Return a string representation of self.
77
78
EXAMPLES::
79
80
sage: repr(SR)
81
'Symbolic Ring'
82
"""
83
return "Symbolic Ring"
84
85
def _latex_(self):
86
"""
87
Return latex representation of the symbolic ring.
88
89
EXAMPLES::
90
91
sage: latex(SR)
92
\text{SR}
93
sage: M = MatrixSpace(SR, 2); latex(M)
94
\mathrm{Mat}_{2\times 2}(\text{SR})
95
"""
96
return r'\text{SR}'
97
98
cpdef _coerce_map_from_(self, R):
99
"""
100
EXAMPLES::
101
102
sage: SR.coerce(int(2))
103
2
104
sage: SR.coerce(-infinity)
105
-Infinity
106
sage: SR.has_coerce_map_from(ZZ['t'])
107
True
108
sage: SR.has_coerce_map_from(ZZ['t,u,v'])
109
True
110
sage: SR.has_coerce_map_from(Frac(ZZ['t,u,v']))
111
True
112
sage: SR.has_coerce_map_from(GF(5)['t'])
113
True
114
sage: SR.has_coerce_map_from(SR['t'])
115
False
116
sage: SR.has_coerce_map_from(Integers(8))
117
True
118
sage: SR.has_coerce_map_from(GF(9, 'a'))
119
True
120
121
TESTS:
122
123
Check if arithmetic with bools work #9560::
124
125
sage: SR.has_coerce_map_from(bool)
126
True
127
sage: SR(5)*True; True*SR(5)
128
5
129
5
130
sage: SR(5)+True; True+SR(5)
131
6
132
6
133
sage: SR(5)-True
134
4
135
"""
136
if isinstance(R, type):
137
if R in [int, float, long, complex, bool]:
138
return True
139
140
if 'numpy' in R.__module__:
141
import numpy
142
basic_types = [numpy.float, numpy.float32, numpy.float64,
143
numpy.complex, numpy.complex64, numpy.complex128]
144
if hasattr(numpy, 'float128'):
145
basic_types += [numpy.float128, numpy.complex256]
146
if R in basic_types:
147
return NumpyToSRMorphism(R, self)
148
149
if 'sympy' in R.__module__:
150
from sympy.core.basic import Basic
151
if issubclass(R, Basic):
152
return UnderscoreSageMorphism(R, self)
153
154
return False
155
else:
156
from sage.rings.real_mpfr import mpfr_prec_min
157
158
from sage.rings.all import ( ComplexField,
159
is_PolynomialRing, is_MPolynomialRing,
160
is_FractionField, RLF, CLF, AA, QQbar, InfinityRing,
161
is_RealIntervalField, is_ComplexIntervalField,
162
is_IntegerModRing, is_FiniteField)
163
164
from sage.interfaces.maxima import Maxima
165
from sage.libs.pari.gen import PariInstance
166
167
if ComplexField(mpfr_prec_min()).has_coerce_map_from(R):
168
# Anything with a coercion into any precision of CC
169
170
# In order to have coercion from SR to AA or QQbar,
171
# we disable coercion in the reverse direction.
172
# This makes the following work:
173
# sage: QQbar(sqrt(2)) + sqrt(3)
174
# 3.146264369941973?
175
return R not in (RLF, CLF, AA, QQbar)
176
elif is_PolynomialRing(R) or is_MPolynomialRing(R) or is_FractionField(R):
177
base = R.base_ring()
178
return base is not self and self.has_coerce_map_from(base)
179
elif (R is InfinityRing
180
or is_RealIntervalField(R) or is_ComplexIntervalField(R)
181
or is_IntegerModRing(R) or is_FiniteField(R)):
182
return True
183
elif isinstance(R, (Maxima, PariInstance)):
184
return False
185
186
def _element_constructor_(self, x):
187
"""
188
Coerce `x` into the symbolic expression ring SR.
189
190
EXAMPLES::
191
192
sage: a = SR(-3/4); a
193
-3/4
194
sage: type(a)
195
<type 'sage.symbolic.expression.Expression'>
196
sage: a.parent()
197
Symbolic Ring
198
sage: K.<a> = QuadraticField(-3)
199
sage: a + sin(x)
200
I*sqrt(3) + sin(x)
201
sage: x=var('x'); y0,y1=PolynomialRing(ZZ,2,'y').gens()
202
sage: x+y0/y1
203
x + y0/y1
204
sage: x.subs(x=y0/y1)
205
y0/y1
206
sage: x + long(1)
207
x + 1L
208
209
If `a` is already in the symbolic expression ring, coercing returns
210
`a` itself (not a copy)::
211
212
sage: a = SR(-3/4); a
213
-3/4
214
sage: SR(a) is a
215
True
216
217
A Python complex number::
218
219
sage: SR(complex(2,-3))
220
(2-3j)
221
222
TESTS::
223
224
sage: SR._coerce_(int(5))
225
5
226
sage: SR._coerce_(5)
227
5
228
sage: SR._coerce_(float(5))
229
5.0
230
sage: SR._coerce_(5.0)
231
5.00000000000000
232
233
An interval arithmetic number::
234
235
sage: SR._coerce_(RIF(pi))
236
3.141592653589794?
237
238
A number modulo 7::
239
240
sage: a = SR(Mod(3,7)); a
241
3
242
sage: a^2
243
2
244
245
sage: si = SR.coerce(I)
246
sage: si^2
247
-1
248
sage: bool(si == CC.0)
249
True
250
251
"""
252
cdef GEx exp
253
254
if is_Expression(x):
255
if (<Expression>x)._parent is self:
256
return x
257
else:
258
return new_Expression_from_GEx(self, (<Expression>x)._gobj)
259
elif hasattr(x, '_symbolic_'):
260
return x._symbolic_(self)
261
elif isinstance(x, str):
262
try:
263
from sage.calculus.calculus import symbolic_expression_from_string
264
return self(symbolic_expression_from_string(x))
265
except SyntaxError, err:
266
msg, s, pos = err.args
267
raise TypeError, "%s: %s !!! %s" % (msg, s[:pos], s[pos:])
268
269
from sage.rings.infinity import (infinity, minus_infinity,
270
unsigned_infinity)
271
272
if isinstance(x, (Integer, RealNumber, float, long, complex)):
273
GEx_construct_pyobject(exp, x)
274
elif isinstance(x, int):
275
GEx_construct_long(&exp, x)
276
elif x is infinity:
277
return new_Expression_from_GEx(self, g_Infinity)
278
elif x is minus_infinity:
279
return new_Expression_from_GEx(self, g_mInfinity)
280
elif x is unsigned_infinity:
281
return new_Expression_from_GEx(self, g_UnsignedInfinity)
282
elif isinstance(x, RingElement):
283
GEx_construct_pyobject(exp, x)
284
else:
285
raise TypeError
286
287
return new_Expression_from_GEx(self, exp)
288
289
def _force_pyobject(self, x):
290
"""
291
Wrap the given Python object in a symbolic expression even if it
292
cannot be coerced to the Symbolic Ring.
293
294
EXAMPLES::
295
296
sage: t = SR._force_pyobject([3,4,5]); t
297
[3, 4, 5]
298
sage: type(t)
299
<type 'sage.symbolic.expression.Expression'>
300
"""
301
cdef GEx exp
302
GEx_construct_pyobject(exp, x)
303
return new_Expression_from_GEx(self, exp)
304
305
def wild(self, unsigned int n=0):
306
"""
307
Return the n-th wild-card for pattern matching and substitution.
308
309
INPUT:
310
311
- ``n`` - a nonnegative integer
312
313
OUTPUT:
314
315
- `n^{th}` wildcard expression
316
317
EXAMPLES::
318
319
sage: x,y = var('x,y')
320
sage: w0 = SR.wild(0); w1 = SR.wild(1)
321
sage: pattern = sin(x)*w0*w1^2; pattern
322
$0*$1^2*sin(x)
323
sage: f = atan(sin(x)*3*x^2); f
324
arctan(3*x^2*sin(x))
325
sage: f.has(pattern)
326
True
327
sage: f.subs(pattern == x^2)
328
arctan(x^2)
329
"""
330
return new_Expression_from_GEx(self, g_wild(n))
331
332
def __cmp__(self, other):
333
"""
334
Compare two symbolic expression rings. They are equal if and only
335
if they have the same type. Otherwise their types are compared.
336
337
EXAMPLES::
338
339
sage: from sage.symbolic.ring import SymbolicRing
340
sage: cmp(SR, RR) #random
341
1
342
sage: cmp(RR, SymbolicRing()) #random
343
-1
344
sage: cmp(SR, SymbolicRing())
345
0
346
"""
347
return cmp(type(self), type(other))
348
349
def __contains__(self, x):
350
r"""
351
True if there is an element of the symbolic ring that is equal to x
352
under ``==``.
353
354
EXAMPLES:
355
356
The symbolic variable x is in the symbolic ring.::
357
358
sage: x.parent()
359
Symbolic Ring
360
sage: x in SR
361
True
362
363
2 is also in the symbolic ring since it is equal to something in
364
SR, even though 2's parent is not SR.
365
366
::
367
368
sage: 2 in SR
369
True
370
sage: parent(2)
371
Integer Ring
372
sage: 1/3 in SR
373
True
374
"""
375
try:
376
x2 = self(x)
377
return bool(x2 == x)
378
except TypeError:
379
return False
380
381
def characteristic(self):
382
"""
383
Return the characteristic of the symbolic ring, which is 0.
384
385
OUTPUT:
386
387
- a Sage integer
388
389
EXAMPLES::
390
391
sage: c = SR.characteristic(); c
392
0
393
sage: type(c)
394
<type 'sage.rings.integer.Integer'>
395
"""
396
return Integer(0)
397
398
def _an_element_(self):
399
"""
400
Return an element of the symbolic ring, which is used by the
401
coercion model.
402
403
EXAMPLES::
404
405
sage: SR._an_element_()
406
some_variable
407
"""
408
return self.var('some_variable')
409
410
def is_field(self, proof = True):
411
"""
412
Returns True, since the symbolic expression ring is (for the most
413
part) a field.
414
415
EXAMPLES::
416
417
sage: SR.is_field()
418
True
419
"""
420
return True
421
422
cpdef bint is_exact(self) except -2:
423
"""
424
Return False, because there are approximate elements in the
425
symbolic ring.
426
427
EXAMPLES::
428
429
sage: SR.is_exact()
430
False
431
432
Here is an inexact element.
433
434
::
435
436
sage: SR(1.9393)
437
1.93930000000000
438
"""
439
return False
440
441
def pi(self):
442
"""
443
EXAMPLES::
444
445
sage: SR.pi() is pi
446
True
447
"""
448
from sage.symbolic.constants import pi
449
return self(pi)
450
451
cpdef symbol(self, name=None, latex_name=None, domain=None):
452
"""
453
EXAMPLES::
454
455
sage: t0 = SR.symbol("t0")
456
sage: t0.conjugate()
457
conjugate(t0)
458
459
sage: t1 = SR.symbol("t1", domain='real')
460
sage: t1.conjugate()
461
t1
462
463
sage: t0.abs()
464
abs(t0)
465
466
sage: t0_2 = SR.symbol("t0", domain='positive')
467
sage: t0_2.abs()
468
t0
469
sage: bool(t0_2 == t0)
470
True
471
sage: t0.conjugate()
472
t0
473
474
sage: SR.symbol() # temporary variable
475
symbol...
476
"""
477
cdef GSymbol symb
478
cdef Expression e
479
480
# check if there is already a symbol with same name
481
e = pynac_symbol_registry.get(name)
482
483
# fast path to get an already existing variable
484
if e is not None:
485
if domain is None:
486
if latex_name is None:
487
return e
488
489
# get symbol
490
symb = ex_to_symbol(e._gobj)
491
if latex_name is not None:
492
symb.set_texname(latex_name)
493
if domain is not None:
494
symb.set_domain(sage_domain_to_ginac(domain))
495
GEx_construct_symbol(&e._gobj, symb)
496
497
return e
498
499
else: # initialize a new symbol
500
# Construct expression
501
e = <Expression>PY_NEW(Expression)
502
e._parent = SR
503
504
if name is None: # Check if we need a temporary anonymous new symbol
505
symb = ginac_new_symbol()
506
if domain is not None:
507
symb.set_domain(sage_domain_to_ginac(domain))
508
else:
509
if latex_name is None:
510
latex_name = latex_variable_name(name)
511
if domain is not None:
512
domain = sage_domain_to_ginac(domain)
513
else:
514
domain = domain_complex
515
symb = ginac_symbol(name, latex_name, domain)
516
pynac_symbol_registry[name] = e
517
518
GEx_construct_symbol(&e._gobj, symb)
519
return e
520
521
cpdef var(self, name, latex_name=None, domain=None):
522
"""
523
Return the symbolic variable defined by x as an element of the
524
symbolic ring.
525
526
EXAMPLES::
527
528
sage: zz = SR.var('zz'); zz
529
zz
530
sage: type(zz)
531
<type 'sage.symbolic.expression.Expression'>
532
sage: t = SR.var('theta2'); t
533
theta2
534
535
TESTS::
536
537
sage: var(' x y z ')
538
(x, y, z)
539
sage: var(' x , y , z ')
540
(x, y, z)
541
sage: var(' ')
542
Traceback (most recent call last):
543
...
544
ValueError: You need to specify the name of the new variable.
545
546
var(['x', 'y ', ' z '])
547
(x, y, z)
548
var(['x,y'])
549
Traceback (most recent call last):
550
...
551
ValueError: The name "x,y" is not a valid Python identifier.
552
"""
553
if is_Expression(name):
554
return name
555
if not isinstance(name, (basestring,list,tuple)):
556
name = repr(name)
557
558
if isinstance(name, (list,tuple)):
559
names_list = [s.strip() for s in name]
560
elif ',' in name:
561
names_list = [s.strip() for s in name.split(',' )]
562
elif ' ' in name:
563
names_list = [s.strip() for s in name.split()]
564
else:
565
names_list = [name]
566
567
for s in names_list:
568
if not isidentifier(s):
569
raise ValueError('The name "'+s+'" is not a valid Python identifier.')
570
571
if len(names_list) == 0:
572
raise ValueError('You need to specify the name of the new variable.')
573
if len(names_list) == 1:
574
return self.symbol(name, latex_name=latex_name, domain=domain)
575
if len(names_list) > 1:
576
if latex_name:
577
raise ValueError, "cannot specify latex_name for multiple symbol names"
578
return tuple([self.symbol(s, domain=domain) for s in names_list])
579
580
def _repr_element_(self, Expression x):
581
"""
582
Returns the string representation of the element x. This is
583
used so that subclasses of the SymbolicRing (such the a
584
CallableSymbolicExpressionRing) can provide their own
585
implementations of how to print Expressions.
586
587
EXAMPLES::
588
589
sage: SR._repr_element_(x+2)
590
'x + 2'
591
"""
592
return GEx_to_str(&x._gobj)
593
594
def _latex_element_(self, Expression x):
595
"""
596
Returns the standard LaTeX version of the expression *x*.
597
598
EXAMPLES::
599
600
sage: latex(sin(x+2))
601
\sin\left(x + 2\right)
602
sage: latex(var('theta') + 2)
603
\theta + 2
604
"""
605
return GEx_to_str_latex(&x._gobj)
606
607
def _call_element_(self, _the_element, *args, **kwds):
608
"""
609
EXAMPLES::
610
611
sage: x,y=var('x,y')
612
sage: f = x+y
613
sage: f.variables()
614
(x, y)
615
sage: f()
616
x + y
617
sage: f(3)
618
doctest:...: DeprecationWarning: Substitution using function-call syntax and unnamed arguments is deprecated and will be removed from a future release of Sage; you can use named arguments instead, like EXPR(x=..., y=...)
619
y + 3
620
sage: f(x=3)
621
y + 3
622
sage: f(3,4)
623
7
624
sage: f(x=3,y=4)
625
7
626
sage: f(2,3,4)
627
Traceback (most recent call last):
628
...
629
ValueError: the number of arguments must be less than or equal to 2
630
sage: f(x=2,y=3,z=4)
631
5
632
633
::
634
635
sage: f({x:3})
636
y + 3
637
sage: f({x:3,y:4})
638
7
639
sage: f(x=3)
640
y + 3
641
sage: f(x=3,y=4)
642
7
643
644
::
645
646
sage: a = (2^(8/9))
647
sage: a(4)
648
Traceback (most recent call last):
649
...
650
ValueError: the number of arguments must be less than or equal to 0
651
652
653
Note that you make get unexpected results when calling
654
symbolic expressions and not explicitly giving the variables::
655
656
sage: f = function('Gamma', var('z'), var('w')); f
657
Gamma(z, w)
658
sage: f(2)
659
Gamma(z, 2)
660
sage: f(2,5)
661
Gamma(5, 2)
662
663
Thus, it is better to be explicit::
664
665
sage: f(z=2)
666
Gamma(2, w)
667
"""
668
if len(args) == 0:
669
d = None
670
elif len(args) == 1 and isinstance(args[0], dict):
671
d = args[0]
672
else:
673
from sage.misc.misc import deprecation
674
vars = _the_element.operands()
675
deprecation("Substitution using function-call syntax and unnamed arguments is deprecated and will be removed from a future release of Sage; you can use named arguments instead, like EXPR(x=..., y=...)")
676
d = {}
677
678
vars = _the_element.variables()
679
for i, arg in enumerate(args):
680
try:
681
d[ vars[i] ] = arg
682
except IndexError:
683
raise ValueError, "the number of arguments must be less than or equal to %s"%len(vars)
684
685
return _the_element.subs(d, **kwds)
686
687
SR = SymbolicRing()
688
689
cdef unsigned sage_domain_to_ginac(object domain) except +:
690
# convert the domain argument to something easy to parse
691
if domain is RR or domain is 'real':
692
return domain_real
693
elif domain is 'positive':
694
return domain_positive
695
elif domain is CC or domain is 'complex':
696
return domain_complex
697
else:
698
raise ValueError, "domain must be one of 'complex', 'real' or 'positive'"
699
700
cdef class NumpyToSRMorphism(Morphism):
701
def __init__(self, numpy_type, R):
702
"""
703
A Morphism which constructs Expressions from NumPy floats and
704
complexes by converting them to elements of either RDF or CDF.
705
706
EXAMPLES::
707
708
sage: import numpy
709
sage: from sage.symbolic.ring import NumpyToSRMorphism
710
sage: f = NumpyToSRMorphism(numpy.float64, SR)
711
sage: f(numpy.float64('2.0'))
712
2.0
713
sage: _.parent()
714
Symbolic Ring
715
"""
716
import sage.categories.homset
717
from sage.structure.parent import Set_PythonType
718
Morphism.__init__(self, sage.categories.homset.Hom(Set_PythonType(numpy_type), R))
719
720
cpdef Element _call_(self, a):
721
"""
722
EXAMPLES:
723
724
This should be called when coercing or converting a NumPy
725
float or complex to the Symbolic Ring::
726
727
sage: import numpy
728
sage: SR(numpy.float64('2.0')).pyobject().parent()
729
Real Double Field
730
"""
731
from sage.rings.all import RDF, CDF
732
numpy_type = self._domain.object()
733
if 'complex' in numpy_type.__name__:
734
res = CDF(a)
735
else:
736
res = RDF(a)
737
738
return new_Expression_from_pyobject(self._codomain, res)
739
740
cdef class UnderscoreSageMorphism(Morphism):
741
def __init__(self, t, R):
742
"""
743
A Morphism which constructs Expressions from an arbitrary Python
744
object by calling the :meth:`_sage_` method on the object.
745
746
EXAMPLES::
747
748
sage: import sympy
749
sage: from sage.symbolic.ring import UnderscoreSageMorphism
750
sage: b = sympy.var('b')
751
sage: f = UnderscoreSageMorphism(type(b), SR)
752
sage: f(b)
753
b
754
sage: _.parent()
755
Symbolic Ring
756
"""
757
import sage.categories.homset
758
from sage.structure.parent import Set_PythonType
759
Morphism.__init__(self, sage.categories.homset.Hom(Set_PythonType(t), R))
760
761
cpdef Element _call_(self, a):
762
"""
763
EXAMPLES:
764
765
This should be called when coercing or converting a SymPy
766
object to the Symbolic Ring::
767
768
sage: import sympy
769
sage: b = sympy.var('b')
770
sage: bool(SR(b) == SR(b._sage_()))
771
True
772
"""
773
return self._codomain(a._sage_())
774
775
776
def the_SymbolicRing():
777
"""
778
Return the unique symbolic ring object.
779
780
(This is mainly used for unpickling.)
781
782
EXAMPLES::
783
784
sage: sage.symbolic.ring.the_SymbolicRing()
785
Symbolic Ring
786
sage: sage.symbolic.ring.the_SymbolicRing() is sage.symbolic.ring.the_SymbolicRing()
787
True
788
sage: sage.symbolic.ring.the_SymbolicRing() is SR
789
True
790
"""
791
return SR
792
793
def is_SymbolicExpressionRing(R):
794
"""
795
Returns True if *R* is the symbolic expression ring.
796
797
EXAMPLES::
798
799
sage: from sage.symbolic.ring import is_SymbolicExpressionRing
800
sage: is_SymbolicExpressionRing(ZZ)
801
False
802
sage: is_SymbolicExpressionRing(SR)
803
True
804
"""
805
return R is SR
806
807
def var(name, **kwds):
808
"""
809
EXAMPLES::
810
811
sage: from sage.symbolic.ring import var
812
sage: var("x y z")
813
(x, y, z)
814
sage: var("x,y,z")
815
(x, y, z)
816
sage: var("x , y , z")
817
(x, y, z)
818
sage: var("z")
819
z
820
821
TESTS:
822
823
These examples test that variables can only be made from
824
valid identifiers. See Trac 7496 (and 9724) for details::
825
826
sage: var(' ')
827
Traceback (most recent call last):
828
...
829
ValueError: You need to specify the name of the new variable.
830
sage: var('3')
831
Traceback (most recent call last):
832
...
833
ValueError: The name "3" is not a valid Python identifier.
834
"""
835
return SR.var(name, **kwds)
836
837
def is_SymbolicVariable(x):
838
"""
839
Returns True if x is a variable.
840
841
EXAMPLES::
842
843
sage: from sage.symbolic.ring import is_SymbolicVariable
844
sage: is_SymbolicVariable(x)
845
True
846
sage: is_SymbolicVariable(x+2)
847
False
848
849
TESTS::
850
851
sage: ZZ[x]
852
Univariate Polynomial Ring in x over Integer Ring
853
"""
854
return is_Expression(x) and is_a_symbol((<Expression>x)._gobj)
855
856
def isidentifier(x):
857
"""
858
Return whether ``x`` is a valid identifier.
859
860
When we switch to Python 3 this function can be replaced by the
861
official Python function of the same name.
862
863
INPUT:
864
865
- ``x`` -- a string.
866
867
OUTPUT:
868
869
Boolean. Whether the string ``x`` can be used as a variable name.
870
871
EXAMPLES::
872
873
sage: from sage.symbolic.ring import isidentifier
874
sage: isidentifier('x')
875
True
876
sage: isidentifier(' x') # can't start with space
877
False
878
sage: isidentifier('ceci_n_est_pas_une_pipe')
879
True
880
sage: isidentifier('1 + x')
881
False
882
sage: isidentifier('2good')
883
False
884
sage: isidentifier('good2')
885
True
886
sage: isidentifier('lambda s:s+1')
887
False
888
"""
889
import parser
890
try:
891
code = parser.expr(x).compile()
892
except (MemoryError, OverflowError, SyntaxError, SystemError, parser.ParserError), msg:
893
return False
894
return len(code.co_names)==1 and code.co_names[0]==x
895
896
897
898