1"""str() printing tests."""
2
3import pytest
4
5from diofant import (CC, QQ, ZZ, Abs, Add, And, BlockMatrix, Catalan,
6                     Complement, Derivative, Dict, Dummy, E, Eq, Equivalent,
7                     EulerGamma, Expr, FiniteSet, Float, Function, GoldenRatio,
8                     I, Integer, Integral, Interval, Lambda, Limit, Matrix,
9                     MatrixSymbol, Mul, Ne, O, Poly, Pow, Rational, Rel,
10                     RootOf, RootSum, S, SparseMatrix, StrPrinter, Sum, Symbol,
11                     SymmetricDifference, Tuple, Wild, WildFunction, Xor,
12                     ZeroMatrix, cbrt, cos, exp, factor, factorial, factorial2,
13                     false, field, grlex, groebner, nan, oo, pi, ring, root,
14                     sin, sqrt, sstr, sstrrepr, subfactorial, summation,
15                     symbols, true, zeta, zoo)
16from diofant.abc import w, x, y, z
17from diofant.combinatorics import AbelianGroup, Cycle, Permutation
18from diofant.core.trace import Tr
19from diofant.diffgeom import Differential, LieDerivative, TensorProduct
20from diofant.diffgeom.rn import R2
21from diofant.geometry import Circle, Point
22from diofant.stats import Die, Exponential, Normal, pspace, where
23from diofant.tensor.array import ImmutableDenseNDimArray
24
25
26__all__ = ()
27
28d = Dummy('d')
29
30
31def test_printmethod():
32    class R(Abs):
33        def _diofantstr(self, printer):
34            return f'foo({printer._print(self.args[0])})'
35    assert sstr(R(x)) == 'foo(x)'
36
37    class R2(Abs):
38        def _diofantstr(self, printer):
39            return 'foo'
40    assert sstr(R2(x)) == 'foo'
41
42
43def test_Abs():
44    assert str(abs(x)) == 'Abs(x)'
45    assert str(abs(Rational(1, 6))) == '1/6'
46    assert str(abs(Rational(-1, 6))) == '1/6'
47
48
49def test_Add():
50    assert str(x + y) == 'x + y'
51    assert str(x + 1) == 'x + 1'
52    assert str(x + x**2) == 'x**2 + x'
53    assert str(5 + x + y + x*y + x**2 + y**2) == 'x**2 + x*y + x + y**2 + y + 5'
54    assert str(1 + x + x**2/2 + x**3/3) == 'x**3/3 + x**2/2 + x + 1'
55    assert str(2*x - 7*x**2 + 2 + 3*y) == '-7*x**2 + 2*x + 3*y + 2'
56    assert str(x - y) == 'x - y'
57    assert str(2 - x) == '-x + 2'
58    assert str(x - 2) == 'x - 2'
59    assert str(x - y - z - w) == '-w + x - y - z'
60    assert str(x - z*y**2*z*w) == '-w*y**2*z**2 + x'
61    assert str(x - 1*y*x*y) == '-x*y**2 + x'
62    assert str(sin(x).series(x, 0, 15)) == 'x - x**3/6 + x**5/120 - x**7/5040 + x**9/362880 - x**11/39916800 + x**13/6227020800 + O(x**15)'
63    assert str(Add(0, 0, evaluate=False)) == '0 + 0'
64    assert str(Add(And(x, y), z)) == 'z + (x & y)'
65
66
67def test_Catalan():
68    assert str(Catalan) == 'Catalan'
69
70
71def test_ComplexInfinity():
72    assert str(zoo) == 'zoo'
73
74
75def test_Derivative():
76    assert str(Derivative(x, y)) == 'Derivative(x, y)'
77    assert str(Derivative(x**2, x, evaluate=False)) == 'Derivative(x**2, x)'
78    assert str(Derivative(
79        x**2/y, x, y, evaluate=False)) == 'Derivative(x**2/y, x, y)'
80
81
82def test_dict():
83    assert sstr({1: 1 + x}) == '{1: x + 1}'
84    assert str({1: 1 + x}) == "{1: Add(Symbol('x'), Integer(1))}"
85    assert str({1: x**2, 2: y*x}) in ("{1: Pow(Symbol('x'), Integer(2)), 2: Mul(Symbol('x'), Symbol('y'))}", "{1: Mul(Symbol('x'), Symbol('y')), 2: Pow(Symbol('x'), Integer(2))}")
86    assert sstr({1: x**2, 2: y*x}) == '{1: x**2, 2: x*y}'
87
88
89def test_Dict():
90    assert str(Dict({1: 1 + x})) == sstr({1: 1 + x}) == '{1: x + 1}'
91    assert str(Dict({1: x**2, 2: y*x})) in (
92        '{1: x**2, 2: x*y}', '{2: x*y, 1: x**2}')
93    assert sstr(Dict({1: x**2, 2: y*x})) == '{1: x**2, 2: x*y}'
94
95
96def test_Dummy():
97    assert str(d) == '_d'
98    assert str(d + x) == 'x + _d'
99
100
101def test_EulerGamma():
102    assert str(EulerGamma) == 'EulerGamma'
103
104
105def test_Exp():
106    assert str(E) == 'E'
107
108
109def test_factorial():
110    n = Symbol('n', integer=True)
111    assert str(factorial(-2)) == 'zoo'
112    assert str(factorial(0)) == '1'
113    assert str(factorial(7)) == '5040'
114    assert str(factorial(n)) == 'factorial(n)'
115    assert str(factorial(2*n)) == 'factorial(2*n)'
116    assert str(factorial(factorial(n))) == 'factorial(factorial(n))'
117    assert str(factorial(factorial2(n))) == 'factorial(factorial2(n))'
118    assert str(factorial2(factorial(n))) == 'factorial2(factorial(n))'
119    assert str(factorial2(factorial2(n))) == 'factorial2(factorial2(n))'
120    assert str(subfactorial(3)) == '2'
121    assert str(subfactorial(n)) == 'subfactorial(n)'
122    assert str(subfactorial(2*n)) == 'subfactorial(2*n)'
123
124
125def test_Function():
126    f = Function('f')
127    fx = f(x)
128    w = WildFunction('w')
129    assert str(f) == 'f'
130    assert str(fx) == 'f(x)'
131    assert str(w) == 'w_'
132
133
134def test_Geometry():
135    assert sstr(Point(0, 0)) == 'Point(0, 0)'
136    assert sstr(Circle(Point(0, 0), 3)) == 'Circle(Point(0, 0), 3)'
137
138
139def test_GoldenRatio():
140    assert str(GoldenRatio) == 'GoldenRatio'
141
142
143def test_ImaginaryUnit():
144    assert str(I) == 'I'
145
146
147def test_Infinity():
148    assert str(oo) == 'oo'
149    assert str(oo*I) == 'oo*I'
150
151
152def test_Integer():
153    assert str(Integer(-1)) == '-1'
154    assert str(Integer(1)) == '1'
155    assert str(Integer(-3)) == '-3'
156    assert str(Integer(0)) == '0'
157    assert str(Integer(25)) == '25'
158
159
160def test_Integral():
161    assert str(Integral(sin(x), y)) == 'Integral(sin(x), y)'
162    assert str(Integral(sin(x), (y, 0, 1))) == 'Integral(sin(x), (y, 0, 1))'
163
164
165def test_Interval():
166    a = Symbol('a', extended_real=True)
167    assert str(Interval(0, a)) == '[0, a]'
168    assert str(Interval(0, a, False, False)) == '[0, a]'
169    assert str(Interval(0, a, True, False)) == '(0, a]'
170    assert str(Interval(0, a, False, True)) == '[0, a)'
171    assert str(Interval(0, a, True, True)) == '(0, a)'
172
173
174def test_Lambda():
175    assert str(Lambda(d, d**2)) == 'Lambda(_d, _d**2)'
176    # issue sympy/sympy#2908
177    assert str(Lambda((), 1)) == 'Lambda((), 1)'
178    assert str(Lambda((), x)) == 'Lambda((), x)'
179
180
181def test_Limit():
182    assert str(Limit(sin(x)/x, x, y)) == 'Limit(sin(x)/x, x, y)'
183    assert str(Limit(1/x, x, 0)) == 'Limit(1/x, x, 0)'
184    assert str(
185        Limit(sin(x)/x, x, y, dir='-')) == "Limit(sin(x)/x, x, y, dir='-')"
186
187
188def test_list():
189    assert sstr([x]) == '[x]'
190    assert str([x]) == "[Symbol('x')]"
191    assert sstr([x**2, x*y + 1]) == '[x**2, x*y + 1]'
192    assert str([x**2, x*y + 1]) == "[Pow(Symbol('x'), Integer(2)), Add(Mul(Symbol('x'), Symbol('y')), Integer(1))]"
193    assert sstr([x**2, [y + x]]) == '[x**2, [x + y]]'
194    assert str([x**2, [y + x]]) == "[Pow(Symbol('x'), Integer(2)), [Add(Symbol('x'), Symbol('y'))]]"
195
196
197def test_Matrix_str():
198    M = Matrix([[x**+1, 1], [y, x + y]])
199    assert str(M) == 'Matrix([\n[x,     1],\n[y, x + y]])'
200    assert sstr(M) == 'Matrix([\n[x,     1],\n[y, x + y]])'
201    M = Matrix([[1]])
202    assert str(M) == sstr(M) == 'Matrix([[1]])'
203    M = Matrix([[1, 2]])
204    assert str(M) == sstr(M) == 'Matrix([[1, 2]])'
205    M = Matrix()
206    assert str(M) == sstr(M) == 'Matrix(0, 0, [])'
207    M = Matrix(0, 1, lambda i, j: 0)
208    assert str(M) == sstr(M) == 'Matrix(0, 1, [])'
209
210
211def test_BlockMatrix():
212    n, m = symbols('n m', integer=True)
213    X = MatrixSymbol('X', n, n)
214    Y = MatrixSymbol('Y', m, m)
215    Z = MatrixSymbol('Z', n, m)
216    B = BlockMatrix([[X, Z], [ZeroMatrix(m, n), Y]])
217    assert str(B) == 'Matrix([\n[X, Z],\n[0, Y]])'
218
219
220def test_Mul():
221    assert str(x/y) == 'x/y'
222    assert str(y/x) == 'y/x'
223    assert str(x/y/z) == 'x/(y*z)'
224    assert str((x + 1)/(y + 2)) == '(x + 1)/(y + 2)'
225    assert str(2*x/3) == '2*x/3'
226    assert str(-2*x/3) == '-2*x/3'
227    assert str(-1.0*x) == '-1.0*x'
228    assert str(1.0*x) == '1.0*x'
229
230    class CustomClass1(Expr):
231        is_commutative = True
232
233    class CustomClass2(Expr):
234        is_commutative = True
235    cc1 = CustomClass1()
236    cc2 = CustomClass2()
237    assert str(2*cc1) == '2*CustomClass1()'
238    assert str(cc1*2) == '2*CustomClass1()'
239    assert str(cc1*Float('1.5')) == '1.5*CustomClass1()'
240    assert str(cc2*2) == '2*CustomClass2()'
241    assert str(cc2*2*cc1) == '2*CustomClass1()*CustomClass2()'
242    assert str(cc1*2*cc2) == '2*CustomClass1()*CustomClass2()'
243    assert str(Mul(1, 1, evaluate=False)) == '1*1'
244
245
246def test_NaN():
247    assert str(nan) == 'nan'
248
249
250def test_NegativeInfinity():
251    assert str(-oo) == '-oo'
252
253
254def test_Order():
255    assert str(O(x)) == 'O(x)'
256    assert str(O(x**2)) == 'O(x**2)'
257    assert str(O(x*y)) == 'O(x*y, x, y)'
258    assert str(O(x, x)) == 'O(x)'
259    assert str(O(x, (x, 0))) == 'O(x)'
260    assert str(O(x, (x, oo))) == 'O(x, (x, oo))'
261    assert str(O(x, x, y)) == 'O(x, x, y)'
262    assert str(O(x, x, y)) == 'O(x, x, y)'
263    assert str(O(x, (x, oo), (y, oo))) == 'O(x, (x, oo), (y, oo))'
264
265
266def test_Permutation_Cycle():
267    # general principle: economically, canonically show all moved elements
268    # and the size of the permutation.
269
270    for p, s in [
271        (Cycle(),
272         'Cycle()'),
273        (Cycle(2),
274         'Cycle(2)'),
275        (Cycle(2, 1),
276         'Cycle(1, 2)'),
277        (Cycle(1, 2)(5)(6, 7)(10),
278         'Cycle(1, 2)(6, 7)(10)'),
279        (Cycle(3, 4)(1, 2)(3, 4),
280         'Cycle(1, 2)(4)'),
281    ]:
282        assert str(p) == s
283
284    Permutation.print_cyclic = False
285    for p, s in [
286        (Permutation([]),
287         'Permutation([])'),
288        (Permutation([], size=1),
289         'Permutation([0])'),
290        (Permutation([], size=2),
291         'Permutation([0, 1])'),
292        (Permutation([], size=10),
293         'Permutation([], size=10)'),
294        (Permutation([1, 0, 2]),
295         'Permutation([1, 0, 2])'),
296        (Permutation([1, 0, 2, 3, 4, 5]),
297         'Permutation([1, 0], size=6)'),
298        (Permutation([1, 0, 2, 3, 4, 5], size=10),
299         'Permutation([1, 0], size=10)'),
300    ]:
301        assert str(p) == s
302
303    Permutation.print_cyclic = True
304    for p, s in [
305        (Permutation([]),
306         'Permutation()'),
307        (Permutation([], size=1),
308         'Permutation(0)'),
309        (Permutation([], size=2),
310         'Permutation(1)'),
311        (Permutation([], size=10),
312         'Permutation(9)'),
313        (Permutation([1, 0, 2]),
314         'Permutation(2)(0, 1)'),
315        (Permutation([1, 0, 2, 3, 4, 5]),
316         'Permutation(5)(0, 1)'),
317        (Permutation([1, 0, 2, 3, 4, 5], size=10),
318         'Permutation(9)(0, 1)'),
319        (Permutation([0, 1, 3, 2, 4, 5], size=10),
320         'Permutation(9)(2, 3)'),
321    ]:
322        assert str(p) == s
323
324    assert str(AbelianGroup(3, 4)) == ('PermutationGroup([\n    '
325                                       'Permutation(6)(0, 1, 2),\n'
326                                       '    Permutation(3, 4, 5, 6)])')
327    assert sstr(Cycle(1, 2)) == repr(Cycle(1, 2))
328
329
330def test_Pi():
331    assert str(pi) == 'pi'
332
333
334def test_Poly():
335    assert str(Poly(0, x)) == "Poly(0, x, domain='ZZ')"
336    assert str(Poly(1, x)) == "Poly(1, x, domain='ZZ')"
337    assert str(Poly(x, x)) == "Poly(x, x, domain='ZZ')"
338
339    assert str(Poly(2*x + 1, x)) == "Poly(2*x + 1, x, domain='ZZ')"
340    assert str(Poly(2*x - 1, x)) == "Poly(2*x - 1, x, domain='ZZ')"
341
342    assert str(Poly(-1, x)) == "Poly(-1, x, domain='ZZ')"
343    assert str(Poly(-x, x)) == "Poly(-x, x, domain='ZZ')"
344
345    assert str(Poly(-2*x + 1, x)) == "Poly(-2*x + 1, x, domain='ZZ')"
346    assert str(Poly(-2*x - 1, x)) == "Poly(-2*x - 1, x, domain='ZZ')"
347
348    assert str(Poly(x - 1, x)) == "Poly(x - 1, x, domain='ZZ')"
349
350    assert str(
351        Poly(x**2 + 1 + y, x)) == "Poly(x**2 + y + 1, x, domain='ZZ[y]')"
352    assert str(
353        Poly(x**2 - 1 + y, x)) == "Poly(x**2 + y - 1, x, domain='ZZ[y]')"
354
355    assert str(Poly(x**2 + I*x, x)) == "Poly(x**2 + I*x, x, domain='QQ<I>')"
356    assert str(Poly(x**2 - I*x, x)) == "Poly(x**2 - I*x, x, domain='QQ<I>')"
357
358    assert str(Poly(-x*y*z + x*y - 1, x, y, z)
359               ) == "Poly(-x*y*z + x*y - 1, x, y, z, domain='ZZ')"
360    assert str(Poly(-w*x**21*y**7*z + (1 + w)*z**3 - 2*x*z + 1, x, y, z)) == \
361        "Poly(-w*x**21*y**7*z - 2*x*z + (w + 1)*z**3 + 1, x, y, z, domain='ZZ[w]')"
362
363    assert str(Poly(x**2 + 1, x, modulus=2)) == 'Poly(x**2 + 1, x, modulus=2)'
364    assert str(Poly(2*x**2 + 3*x + 4, x, modulus=17)) == 'Poly(2*x**2 + 3*x + 4, x, modulus=17)'
365
366    assert str(Poly(2**(2*x), 2**x)) == "Poly((2**x)**2, 2**x, domain='ZZ')"
367    assert str(Poly((x + 1)**2, x + 1, expand=False)) == "Poly((x + 1)**2, x + 1, domain='ZZ')"
368
369    assert str(Poly(y*x*sqrt(3), x, sqrt(3))) == \
370        "Poly(y*x*sqrt(3), x, sqrt(3), domain='ZZ[y]')"
371
372
373def test_PolynomialRing():
374    assert str(ZZ.inject('x')) == 'ZZ[x]'
375    assert str(QQ.poly_ring('x', 'y', order=grlex)) == 'QQ[x,y]'
376    assert str(ZZ.inject('x', 'y', 'z', 't').eject('t')) == 'ZZ[t][x,y,z]'
377
378
379def test_FractionField():
380    assert str(ZZ.inject('x').field) == 'ZZ(x)'
381    assert str(QQ.frac_field('x', 'y', order=grlex)) == 'QQ(x,y)'
382    assert str(ZZ.inject('x', 'y', 'z', 't').eject('t').field) == 'ZZ[t](x,y,z)'
383
384
385def test_PolyElement():
386    Ruv,  u, v = ring('u v', ZZ)
387    _,  x, y, _ = ring('x y z', Ruv)
388
389    assert str(x - x) == '0'
390    assert str(x - 1) == 'x - 1'
391    assert str(x + 1) == 'x + 1'
392
393    assert str((u**2 + 3*u*v + 1)*x**2*y + u + 1) == '(u**2 + 3*u*v + 1)*x**2*y + u + 1'
394    assert str((u**2 + 3*u*v + 1)*x**2*y + (u + 1)*x) == '(u**2 + 3*u*v + 1)*x**2*y + (u + 1)*x'
395    assert str((u**2 + 3*u*v + 1)*x**2*y + (u + 1)*x + 1) == '(u**2 + 3*u*v + 1)*x**2*y + (u + 1)*x + 1'
396    assert str((-u**2 + 3*u*v - 1)*x**2*y - (u + 1)*x - 1) == '-(u**2 - 3*u*v + 1)*x**2*y - (u + 1)*x - 1'
397
398    assert str(-(v**2 + v + 1)*x + 3*u*v + 1) == '-(v**2 + v + 1)*x + 3*u*v + 1'
399    assert str(-(v**2 + v + 1)*x - 3*u*v + 1) == '-(v**2 + v + 1)*x - 3*u*v + 1'
400
401    K, t = field('t', ZZ)
402    _, x = ring('x', K)
403
404    assert str(x/t) == '1/t*x'
405
406    assert str(CC.inject(w).convert(I)) == '(0.0 + 1.0j)'
407
408
409def test_FracElement():
410    Fuv,  u, v = field('u v', ZZ)
411    _,  x, y, z, t = field('x y z t', Fuv)
412
413    assert str(x - x) == '0'
414    assert str(x - 1) == 'x - 1'
415    assert str(x + 1) == 'x + 1'
416
417    assert str(x/3) == 'x/3'
418    assert str(x/z) == 'x/z'
419    assert str(x*y/z) == 'x*y/z'
420    assert str(x/(z*t)) == 'x/(z*t)'
421    assert str(x*y/(z*t)) == 'x*y/(z*t)'
422
423    assert str((x - 1)/y) == '(x - 1)/y'
424    assert str((x + 1)/y) == '(x + 1)/y'
425    assert str((-x - 1)/y) == '(-x - 1)/y'
426    assert str((x + 1)/(y*z)) == '(x + 1)/(y*z)'
427    assert str(-y/(x + 1)) == '-y/(x + 1)'
428    assert str(y*z/(x + 1)) == 'y*z/(x + 1)'
429
430    assert str(((u + 1)*x*y + 1)/((v - 1)*z - 1)) == '((u + 1)*x*y + 1)/((v - 1)*z - 1)'
431    assert str(((u + 1)*x*y + 1)/((v - 1)*z - t*u*v - 1)) == '((u + 1)*x*y + 1)/((v - 1)*z - u*v*t - 1)'
432
433
434def test_Pow():
435    assert str(x**-1) == '1/x'
436    assert str(x**-2) == 'x**(-2)'
437    assert str(x**2) == 'x**2'
438    assert str((x + y)**-1) == '1/(x + y)'
439    assert str((x + y)**-2) == '(x + y)**(-2)'
440    assert str((x + y)**2) == '(x + y)**2'
441    assert str((x + y)**(1 + x)) == '(x + y)**(x + 1)'
442    assert str(cbrt(x)) == 'x**(1/3)'
443    assert str(1/cbrt(x)) == 'x**(-1/3)'
444    assert str(sqrt(sqrt(x))) == 'x**(1/4)'
445    # not the same as x**-1
446    assert str(x**-1.0) == 'x**(-1.0)'
447    # see issue sympy/sympy#2860
448    assert str(Pow(Integer(2), -1.0, evaluate=False)) == '2**(-1.0)'
449
450
451def test_sqrt():
452    assert str(sqrt(x)) == 'sqrt(x)'
453    assert str(sqrt(x**2)) == 'sqrt(x**2)'
454    assert str(1/sqrt(x)) == '1/sqrt(x)'
455    assert str(1/sqrt(x**2)) == '1/sqrt(x**2)'
456    assert str(y/sqrt(x)) == 'y/sqrt(x)'
457    assert str(x**(1/2)) == 'x**0.5'
458    assert str(1/x**(1/2)) == 'x**(-0.5)'
459
460
461def test_Rational():
462    n1 = Rational(1, 4)
463    n2 = Rational(1, 3)
464    n3 = Rational(2, 4)
465    n4 = Rational(2, -4)
466    n5 = Integer(0)
467    n7 = Integer(3)
468    n8 = Integer(-3)
469    assert str(n1*n2) == '1/12'
470    assert str(n1*n2) == '1/12'
471    assert str(n3) == '1/2'
472    assert str(n1*n3) == '1/8'
473    assert str(n1 + n3) == '3/4'
474    assert str(n1 + n2) == '7/12'
475    assert str(n1 + n4) == '-1/4'
476    assert str(n4*n4) == '1/4'
477    assert str(n4 + n2) == '-1/6'
478    assert str(n4 + n5) == '-1/2'
479    assert str(n4*n5) == '0'
480    assert str(n3 + n4) == '0'
481    assert str(n1**n7) == '1/64'
482    assert str(n2**n7) == '1/27'
483    assert str(n2**n8) == '27'
484    assert str(n7**n8) == '1/27'
485    assert str(Rational('-25')) == '-25'
486    assert str(Rational('1.25')) == '5/4'
487    assert str(Rational('-2.6e-2')) == '-13/500'
488    assert str(Rational(25, 7)) == '25/7'
489    assert str(Rational(-123, 569)) == '-123/569'
490
491    assert str(sqrt(Rational(1, 4))) == '1/2'
492    assert str(sqrt(Rational(1, 36))) == '1/6'
493
494    assert str(root(123**25, 25)) == '123'
495    assert str(root(123**25 + 1, 25)) != '123'
496    assert str(root(123**25 - 1, 25)) != '123'
497    assert str(root(123**25 - 1, 25)) != '122'
498
499    assert str(sqrt(Rational(81, 36))**3) == '27/8'
500    assert str(1/sqrt(Rational(81, 36))**3) == '8/27'
501
502    assert str(sqrt(-4)) == str(2*I)
503    assert str(root(2, 10**10)) == '2**(1/10000000000)'
504
505
506def test_Float():
507    # NOTE prec is the whole number of decimal digits
508    assert str(Float('1.23', dps=1 + 2)) == '1.23'
509    assert str(Float('1.23456789', dps=1 + 8)) == '1.23456789'
510    assert str(
511        Float('1.234567890123456789', dps=1 + 18)) == '1.234567890123456789'
512    assert str(pi.evalf(1 + 2)) == '3.14'
513    assert str(pi.evalf(1 + 14)) == '3.14159265358979'
514    assert str(pi.evalf(1 + 64)) == ('3.141592653589793238462643383279'
515                                     '5028841971693993751058209749445923')
516    assert str(pi.round(-1)) == '0.'
517    assert str((pi**400 - (pi**400).round(1)).evalf(2, strict=False)) == '-0.e+9'
518    assert str(Float(+oo)) == 'inf'
519    assert str(Float(-oo)) == '-inf'
520
521
522def test_Relational():
523    assert str(Rel(x, y, '<')) == 'x < y'
524    assert str(Rel(x + y, y, '==')) == 'Eq(x + y, y)'
525    assert str(Rel(x, y, '!=')) == 'Ne(x, y)'
526    assert str(Eq(x, 1) | Eq(x, 2)) == 'Eq(x, 1) | Eq(x, 2)'
527    assert str(Ne(x, 1) & Ne(x, 2)) == 'Ne(x, 1) & Ne(x, 2)'
528
529
530def test_RootOf():
531    assert str(RootOf(x**5 + 2*x - 1, 0)) == 'RootOf(x**5 + 2*x - 1, 0)'
532    assert str(RootOf(x**3 + y*x + 1, x, 0)) == 'RootOf(x**3 + x*y + 1, x, 0)'
533
534
535def test_RootSum():
536    f = x**5 + 2*x - 1
537
538    assert str(
539        RootSum(f, Lambda(z, z), auto=False)) == 'RootSum(x**5 + 2*x - 1)'
540    assert str(RootSum(f, Lambda(
541        z, z**2), auto=False)) == 'RootSum(x**5 + 2*x - 1, Lambda(z, z**2))'
542
543
544def test_GroebnerBasis():
545    assert str(groebner(
546        [], x, y)) == "GroebnerBasis([], x, y, domain='ZZ', order='lex')"
547
548    F = [x**2 - 3*y - x + 1, y**2 - 2*x + y - 1]
549
550    assert str(groebner(F, order='grlex')) == \
551        "GroebnerBasis([x**2 - x - 3*y + 1, y**2 - 2*x + y - 1], x, y, domain='ZZ', order='grlex')"
552    assert str(groebner(F, order='lex')) == \
553        "GroebnerBasis([2*x - y**2 - y + 1, y**4 + 2*y**3 - 3*y**2 - 16*y + 7], x, y, domain='ZZ', order='lex')"
554
555
556def test_set():
557    assert sstr(set()) == 'set()'
558    assert sstr(frozenset()) == 'frozenset()'
559
560    assert sstr({1, 2, 3}) == '{1, 2, 3}'
561    assert sstr(frozenset({1, 2, 3})) == 'frozenset({1, 2, 3})'
562    assert sstr(
563        {1, x, x**2, x**3, x**4}) == '{1, x, x**2, x**3, x**4}'
564
565
566def test_SparseMatrix():
567    M = SparseMatrix([[x**+1, 1], [y, x + y]])
568    assert str(M) == 'Matrix([\n[x,     1],\n[y, x + y]])'
569    assert sstr(M) == 'Matrix([\n[x,     1],\n[y, x + y]])'
570
571
572def test_Sum():
573    assert str(summation(cos(3*z), (z, x, y))) == 'Sum(cos(3*z), (z, x, y))'
574    assert str(Sum(x*y**2, (x, -2, 2), (y, -5, 5))) == \
575        'Sum(x*y**2, (x, -2, 2), (y, -5, 5))'
576
577
578def test_Symbol():
579    assert str(y) == 'y'
580    assert str(x) == 'x'
581    e = x
582    assert str(e) == 'x'
583
584
585def test_tuple():
586    assert sstr((x,)) == '(x,)'
587    assert str((x,)) == "(Symbol('x'),)"
588    assert sstr((x + y, 1 + x)) == '(x + y, x + 1)'
589    assert str((x + y, 1 + x)) == "(Add(Symbol('x'), Symbol('y')), Add(Symbol('x'), Integer(1)))"
590    assert sstr((x + y, (1 + x, x**2))) == '(x + y, (x + 1, x**2))'
591    assert str((x + y, (1 + x, x**2))) == "(Add(Symbol('x'), Symbol('y')), (Add(Symbol('x'), Integer(1)), Pow(Symbol('x'), Integer(2))))"
592
593
594def test_wild_str():
595    # Check expressions containing Wild not causing infinite recursion
596    w = Wild('x')
597    assert str(w + 1) == 'x_ + 1'
598    assert str(exp(2**w) + 5) == 'E**(2**x_) + 5'
599    assert str(3*w + 1) == '3*x_ + 1'
600    assert str(1/w + 1) == '1 + 1/x_'
601    assert str(w**2 + 1) == 'x_**2 + 1'
602    assert str(1/(1 - w)) == '1/(-x_ + 1)'
603
604
605def test_zeta():
606    assert str(zeta(3)) == 'zeta(3)'
607
608
609def test_sympyissue_3101():
610    e = x - y
611    a = str(e)
612    b = str(e)
613    assert a == b
614
615
616def test_sympyissue_3103():
617    e = -2*sqrt(x) - y/sqrt(x)/2
618    assert str(e) not in ['(-2)*x**1/2(-1/2)*x**(-1/2)*y',
619                          '-2*x**1/2(-1/2)*x**(-1/2)*y', '-2*x**1/2-1/2*x**-1/2*w']
620    assert str(e) == '-2*sqrt(x) - y/(2*sqrt(x))'
621
622
623def test_sympyissue_4021():
624    e = Integral(x, x) + 1
625    assert str(e) == 'Integral(x, x) + 1'
626
627
628def test_sstrrepr():
629    assert sstr('abc') == 'abc'
630    assert sstrrepr('abc') == "'abc'"
631
632    e = ['a', 'b', 'c', x]
633    assert sstr(e) == '[a, b, c, x]'
634    assert sstrrepr(e) == "['a', 'b', 'c', x]"
635
636
637def test_infinity():
638    assert sstr(oo*I) == 'oo*I'
639
640
641def test_full_prec():
642    assert sstr(Float(0.3), full_prec=True) == '0.300000000000000'
643    assert sstr(Float(0.3), full_prec='auto') == '0.300000000000000'
644    assert sstr(Float(0.3), full_prec=False) == '0.3'
645    assert sstr(Float(0.3)*x, full_prec=True) in [
646        '0.300000000000000*x',
647        'x*0.300000000000000'
648    ]
649    assert sstr(Float(0.3)*x, full_prec='auto') in [
650        '0.3*x',
651        'x*0.3'
652    ]
653    assert sstr(Float(0.3)*x, full_prec=False) in [
654        '0.3*x',
655        'x*0.3'
656    ]
657
658
659def test_noncommutative():
660    A, B, C = symbols('A,B,C', commutative=False)
661
662    assert sstr(A*B*C**-1) == 'A*B*C**(-1)'
663    assert sstr(C**-1*A*B) == 'C**(-1)*A*B'
664    assert sstr(A*C**-1*B) == 'A*C**(-1)*B'
665    assert sstr(sqrt(A)) == 'sqrt(A)'
666    assert sstr(1/sqrt(A)) == 'A**(-1/2)'
667
668
669def test_empty_printer():
670    str_printer = StrPrinter()
671    assert str_printer.emptyPrinter('foo') == 'foo'
672    assert str_printer.emptyPrinter(x*y) == 'x*y'
673    assert str_printer.emptyPrinter(32) == '32'
674
675
676def test_settings():
677    pytest.raises(TypeError, lambda: sstr(Integer(4), method='garbage'))
678
679
680def test_RandomDomain():
681    X = Normal('x1', 0, 1)
682    assert str(where(X > 0)) == 'Domain: (0 < x1) & (x1 < oo)'
683
684    D = Die('d1', 6)
685    assert str(where(D > 4)) == 'Domain: Eq(d1, 5) | Eq(d1, 6)'
686
687    A = Exponential('a', 1)
688    B = Exponential('b', 1)
689    assert str(pspace(Tuple(A, B)).domain) == 'Domain: (0 <= a) & (0 <= b) & (a < oo) & (b < oo)'
690
691
692def test_FiniteSet():
693    assert str(FiniteSet(*range(1, 51))) == '{1, 2, 3, ..., 48, 49, 50}'
694    assert str(FiniteSet(*range(1, 6))) == '{1, 2, 3, 4, 5}'
695
696
697def test_PrettyPoly():
698    F = QQ.inject(x, y).field
699    R = QQ.inject(x, y)
700    assert sstr(F.convert(x/(x + y))) == sstr(x/(x + y))
701    assert sstr(R.convert(x + y)) == sstr(x + y)
702
703
704def test_Tr():
705    A, B = symbols('A B', commutative=False)
706    t = Tr(A*B)
707    assert str(t) == 'Tr(A*B)'
708
709
710def test_sympyissue_6387():
711    assert str(factor(-3.0*z + 3)) == '-3.0*(1.0*z - 1.0)'
712
713
714def test_MatMul_MatAdd():
715    assert str(2*(MatrixSymbol('X', 2, 2) + MatrixSymbol('Y', 2, 2))) == \
716        '2*(X + Y)'
717
718
719def test_MatPow():
720    assert str(MatrixSymbol('M', 2, 2)**2) == 'M**2'
721
722
723def test_MatrixSlice():
724    assert str(MatrixSymbol('X', 10, 10)[:5, 1:9:2]) == 'X[:5, 1:9:2]'
725    assert str(MatrixSymbol('X', 10, 10)[5, :5:2]) == 'X[5, :5:2]'
726
727
728def test_MatrixInverse():
729    assert str(MatrixSymbol('X', 3, 3).inverse()) == 'X^-1'
730
731
732def test_true_false():
733    assert str(true) == repr(true) == sstr(true) == 'true'
734    assert str(false) == repr(false) == sstr(false) == 'false'
735
736
737def test_Equivalent():
738    assert str(Equivalent(y, x)) == 'Equivalent(x, y)'
739
740
741def test_Xor():
742    assert str(Xor(y, x, evaluate=False)) == 'Xor(x, y)'
743
744
745def test_Complement():
746    assert str(Complement(S.Reals, S.Naturals)) == '(-oo, oo) \\ Naturals()'
747
748
749def test_SymmetricDifference():
750    assert str(SymmetricDifference(Interval(2, 3), Interval(3, 4), evaluate=False)) == \
751        'SymmetricDifference([2, 3], [3, 4])'
752
753
754def test_AlgebraicElement():
755    K = QQ.algebraic_field(sqrt(2))
756    assert str(K([0, 1])) == 'sqrt(2)'
757
758
759def test_Differential():
760    tp = TensorProduct(R2.dx, R2.dy)
761    assert sstr(LieDerivative(R2.e_x, tp)) == 'LieDerivative(e_x, TensorProduct(dx, dy))'
762
763    g = Function('g')
764    s_field = g(R2.x, R2.y)
765    assert sstr(Differential(s_field)) == 'd(g(x, y))'
766
767
768def test_ImmutableDenseNDimArray():
769    m = [2*i + j for i in range(2) for j in range(2)]
770    assert sstr(ImmutableDenseNDimArray(m, (2, 2))) == '[[0, 1], [2, 3]]'
771