1from sympy.core.logic import fuzzy_and
2from sympy.core.sympify import _sympify
3from sympy.multipledispatch import dispatch
4from sympy.testing.pytest import XFAIL, raises, warns_deprecated_sympy
5from sympy import (S, Symbol, symbols, nan, oo, I, pi, Float, And, Or,
6                   Not, Implies, Xor, zoo, sqrt, Rational, simplify, Function,
7                   log, cos, sin, Add, Mul, Pow, floor, ceiling, trigsimp, Reals,
8                   Basic, Expr, Q, exp, exp_polar)
9from sympy.core.relational import (Relational, Equality, Unequality,
10                                   GreaterThan, LessThan, StrictGreaterThan,
11                                   StrictLessThan, Rel, Eq, Lt, Le,
12                                   Gt, Ge, Ne, is_le, is_gt, is_ge, is_lt, is_eq, is_neq)
13from sympy.sets.sets import Interval, FiniteSet
14
15from itertools import combinations
16
17x, y, z, t = symbols('x,y,z,t')
18
19
20def rel_check(a, b):
21    from sympy.testing.pytest import raises
22    assert a.is_number and b.is_number
23    for do in range(len({type(a), type(b)})):
24        if S.NaN in (a, b):
25            v = [(a == b), (a != b)]
26            assert len(set(v)) == 1 and v[0] == False
27            assert not (a != b) and not (a == b)
28            assert raises(TypeError, lambda: a < b)
29            assert raises(TypeError, lambda: a <= b)
30            assert raises(TypeError, lambda: a > b)
31            assert raises(TypeError, lambda: a >= b)
32        else:
33            E = [(a == b), (a != b)]
34            assert len(set(E)) == 2
35            v = [
36            (a < b), (a <= b), (a > b), (a >= b)]
37            i = [
38            [True,    True,     False,   False],
39            [False,   True,     False,   True], # <-- i == 1
40            [False,   False,    True,    True]].index(v)
41            if i == 1:
42                assert E[0] or (a.is_Float != b.is_Float) # ugh
43            else:
44                assert E[1]
45        a, b = b, a
46    return True
47
48
49def test_rel_ne():
50    assert Relational(x, y, '!=') == Ne(x, y)
51
52    # issue 6116
53    p = Symbol('p', positive=True)
54    assert Ne(p, 0) is S.true
55
56
57def test_rel_subs():
58    e = Relational(x, y, '==')
59    e = e.subs(x, z)
60
61    assert isinstance(e, Equality)
62    assert e.lhs == z
63    assert e.rhs == y
64
65    e = Relational(x, y, '>=')
66    e = e.subs(x, z)
67
68    assert isinstance(e, GreaterThan)
69    assert e.lhs == z
70    assert e.rhs == y
71
72    e = Relational(x, y, '<=')
73    e = e.subs(x, z)
74
75    assert isinstance(e, LessThan)
76    assert e.lhs == z
77    assert e.rhs == y
78
79    e = Relational(x, y, '>')
80    e = e.subs(x, z)
81
82    assert isinstance(e, StrictGreaterThan)
83    assert e.lhs == z
84    assert e.rhs == y
85
86    e = Relational(x, y, '<')
87    e = e.subs(x, z)
88
89    assert isinstance(e, StrictLessThan)
90    assert e.lhs == z
91    assert e.rhs == y
92
93    e = Eq(x, 0)
94    assert e.subs(x, 0) is S.true
95    assert e.subs(x, 1) is S.false
96
97
98def test_wrappers():
99    e = x + x**2
100
101    res = Relational(y, e, '==')
102    assert Rel(y, x + x**2, '==') == res
103    assert Eq(y, x + x**2) == res
104
105    res = Relational(y, e, '<')
106    assert Lt(y, x + x**2) == res
107
108    res = Relational(y, e, '<=')
109    assert Le(y, x + x**2) == res
110
111    res = Relational(y, e, '>')
112    assert Gt(y, x + x**2) == res
113
114    res = Relational(y, e, '>=')
115    assert Ge(y, x + x**2) == res
116
117    res = Relational(y, e, '!=')
118    assert Ne(y, x + x**2) == res
119
120
121def test_Eq_Ne():
122
123    assert Eq(x, x)  # issue 5719
124
125    with warns_deprecated_sympy():
126        assert Eq(x) == Eq(x, 0)
127
128    # issue 6116
129    p = Symbol('p', positive=True)
130    assert Eq(p, 0) is S.false
131
132    # issue 13348; 19048
133    # SymPy is strict about 0 and 1 not being
134    # interpreted as Booleans
135    assert Eq(True, 1) is S.false
136    assert Eq(False, 0) is S.false
137    assert Eq(~x, 0) is S.false
138    assert Eq(~x, 1) is S.false
139    assert Ne(True, 1) is S.true
140    assert Ne(False, 0) is S.true
141    assert Ne(~x, 0) is S.true
142    assert Ne(~x, 1) is S.true
143
144    assert Eq((), 1) is S.false
145    assert Ne((), 1) is S.true
146
147
148def test_as_poly():
149    from sympy.polys.polytools import Poly
150    # Only Eq should have an as_poly method:
151    assert Eq(x, 1).as_poly() == Poly(x - 1, x, domain='ZZ')
152    raises(AttributeError, lambda: Ne(x, 1).as_poly())
153    raises(AttributeError, lambda: Ge(x, 1).as_poly())
154    raises(AttributeError, lambda: Gt(x, 1).as_poly())
155    raises(AttributeError, lambda: Le(x, 1).as_poly())
156    raises(AttributeError, lambda: Lt(x, 1).as_poly())
157
158
159def test_rel_Infinity():
160    # NOTE: All of these are actually handled by sympy.core.Number, and do
161    # not create Relational objects.
162    assert (oo > oo) is S.false
163    assert (oo > -oo) is S.true
164    assert (oo > 1) is S.true
165    assert (oo < oo) is S.false
166    assert (oo < -oo) is S.false
167    assert (oo < 1) is S.false
168    assert (oo >= oo) is S.true
169    assert (oo >= -oo) is S.true
170    assert (oo >= 1) is S.true
171    assert (oo <= oo) is S.true
172    assert (oo <= -oo) is S.false
173    assert (oo <= 1) is S.false
174    assert (-oo > oo) is S.false
175    assert (-oo > -oo) is S.false
176    assert (-oo > 1) is S.false
177    assert (-oo < oo) is S.true
178    assert (-oo < -oo) is S.false
179    assert (-oo < 1) is S.true
180    assert (-oo >= oo) is S.false
181    assert (-oo >= -oo) is S.true
182    assert (-oo >= 1) is S.false
183    assert (-oo <= oo) is S.true
184    assert (-oo <= -oo) is S.true
185    assert (-oo <= 1) is S.true
186
187
188def test_infinite_symbol_inequalities():
189    x = Symbol('x', extended_positive=True, infinite=True)
190    y = Symbol('y', extended_positive=True, infinite=True)
191    z = Symbol('z', extended_negative=True, infinite=True)
192    w = Symbol('w', extended_negative=True, infinite=True)
193
194    inf_set = (x, y, oo)
195    ninf_set = (z, w, -oo)
196
197    for inf1 in inf_set:
198        assert (inf1 < 1) is S.false
199        assert (inf1 > 1) is S.true
200        assert (inf1 <= 1) is S.false
201        assert (inf1 >= 1) is S.true
202
203        for inf2 in inf_set:
204            assert (inf1 < inf2) is S.false
205            assert (inf1 > inf2) is S.false
206            assert (inf1 <= inf2) is S.true
207            assert (inf1 >= inf2) is S.true
208
209        for ninf1 in ninf_set:
210            assert (inf1 < ninf1) is S.false
211            assert (inf1 > ninf1) is S.true
212            assert (inf1 <= ninf1) is S.false
213            assert (inf1 >= ninf1) is S.true
214            assert (ninf1 < inf1) is S.true
215            assert (ninf1 > inf1) is S.false
216            assert (ninf1 <= inf1) is S.true
217            assert (ninf1 >= inf1) is S.false
218
219    for ninf1 in ninf_set:
220        assert (ninf1 < 1) is S.true
221        assert (ninf1 > 1) is S.false
222        assert (ninf1 <= 1) is S.true
223        assert (ninf1 >= 1) is S.false
224
225        for ninf2 in ninf_set:
226            assert (ninf1 < ninf2) is S.false
227            assert (ninf1 > ninf2) is S.false
228            assert (ninf1 <= ninf2) is S.true
229            assert (ninf1 >= ninf2) is S.true
230
231
232def test_bool():
233    assert Eq(0, 0) is S.true
234    assert Eq(1, 0) is S.false
235    assert Ne(0, 0) is S.false
236    assert Ne(1, 0) is S.true
237    assert Lt(0, 1) is S.true
238    assert Lt(1, 0) is S.false
239    assert Le(0, 1) is S.true
240    assert Le(1, 0) is S.false
241    assert Le(0, 0) is S.true
242    assert Gt(1, 0) is S.true
243    assert Gt(0, 1) is S.false
244    assert Ge(1, 0) is S.true
245    assert Ge(0, 1) is S.false
246    assert Ge(1, 1) is S.true
247    assert Eq(I, 2) is S.false
248    assert Ne(I, 2) is S.true
249    raises(TypeError, lambda: Gt(I, 2))
250    raises(TypeError, lambda: Ge(I, 2))
251    raises(TypeError, lambda: Lt(I, 2))
252    raises(TypeError, lambda: Le(I, 2))
253    a = Float('.000000000000000000001', '')
254    b = Float('.0000000000000000000001', '')
255    assert Eq(pi + a, pi + b) is S.false
256
257
258def test_rich_cmp():
259    assert (x < y) == Lt(x, y)
260    assert (x <= y) == Le(x, y)
261    assert (x > y) == Gt(x, y)
262    assert (x >= y) == Ge(x, y)
263
264
265def test_doit():
266    from sympy import Symbol
267    p = Symbol('p', positive=True)
268    n = Symbol('n', negative=True)
269    np = Symbol('np', nonpositive=True)
270    nn = Symbol('nn', nonnegative=True)
271
272    assert Gt(p, 0).doit() is S.true
273    assert Gt(p, 1).doit() == Gt(p, 1)
274    assert Ge(p, 0).doit() is S.true
275    assert Le(p, 0).doit() is S.false
276    assert Lt(n, 0).doit() is S.true
277    assert Le(np, 0).doit() is S.true
278    assert Gt(nn, 0).doit() == Gt(nn, 0)
279    assert Lt(nn, 0).doit() is S.false
280
281    assert Eq(x, 0).doit() == Eq(x, 0)
282
283
284def test_new_relational():
285    x = Symbol('x')
286
287    assert Eq(x, 0) == Relational(x, 0)       # None ==> Equality
288    assert Eq(x, 0) == Relational(x, 0, '==')
289    assert Eq(x, 0) == Relational(x, 0, 'eq')
290    assert Eq(x, 0) == Equality(x, 0)
291
292    assert Eq(x, 0) != Relational(x, 1)       # None ==> Equality
293    assert Eq(x, 0) != Relational(x, 1, '==')
294    assert Eq(x, 0) != Relational(x, 1, 'eq')
295    assert Eq(x, 0) != Equality(x, 1)
296
297    assert Eq(x, -1) == Relational(x, -1)       # None ==> Equality
298    assert Eq(x, -1) == Relational(x, -1, '==')
299    assert Eq(x, -1) == Relational(x, -1, 'eq')
300    assert Eq(x, -1) == Equality(x, -1)
301    assert Eq(x, -1) != Relational(x, 1)       # None ==> Equality
302    assert Eq(x, -1) != Relational(x, 1, '==')
303    assert Eq(x, -1) != Relational(x, 1, 'eq')
304    assert Eq(x, -1) != Equality(x, 1)
305
306    assert Ne(x, 0) == Relational(x, 0, '!=')
307    assert Ne(x, 0) == Relational(x, 0, '<>')
308    assert Ne(x, 0) == Relational(x, 0, 'ne')
309    assert Ne(x, 0) == Unequality(x, 0)
310    assert Ne(x, 0) != Relational(x, 1, '!=')
311    assert Ne(x, 0) != Relational(x, 1, '<>')
312    assert Ne(x, 0) != Relational(x, 1, 'ne')
313    assert Ne(x, 0) != Unequality(x, 1)
314
315    assert Ge(x, 0) == Relational(x, 0, '>=')
316    assert Ge(x, 0) == Relational(x, 0, 'ge')
317    assert Ge(x, 0) == GreaterThan(x, 0)
318    assert Ge(x, 1) != Relational(x, 0, '>=')
319    assert Ge(x, 1) != Relational(x, 0, 'ge')
320    assert Ge(x, 1) != GreaterThan(x, 0)
321    assert (x >= 1) == Relational(x, 1, '>=')
322    assert (x >= 1) == Relational(x, 1, 'ge')
323    assert (x >= 1) == GreaterThan(x, 1)
324    assert (x >= 0) != Relational(x, 1, '>=')
325    assert (x >= 0) != Relational(x, 1, 'ge')
326    assert (x >= 0) != GreaterThan(x, 1)
327
328    assert Le(x, 0) == Relational(x, 0, '<=')
329    assert Le(x, 0) == Relational(x, 0, 'le')
330    assert Le(x, 0) == LessThan(x, 0)
331    assert Le(x, 1) != Relational(x, 0, '<=')
332    assert Le(x, 1) != Relational(x, 0, 'le')
333    assert Le(x, 1) != LessThan(x, 0)
334    assert (x <= 1) == Relational(x, 1, '<=')
335    assert (x <= 1) == Relational(x, 1, 'le')
336    assert (x <= 1) == LessThan(x, 1)
337    assert (x <= 0) != Relational(x, 1, '<=')
338    assert (x <= 0) != Relational(x, 1, 'le')
339    assert (x <= 0) != LessThan(x, 1)
340
341    assert Gt(x, 0) == Relational(x, 0, '>')
342    assert Gt(x, 0) == Relational(x, 0, 'gt')
343    assert Gt(x, 0) == StrictGreaterThan(x, 0)
344    assert Gt(x, 1) != Relational(x, 0, '>')
345    assert Gt(x, 1) != Relational(x, 0, 'gt')
346    assert Gt(x, 1) != StrictGreaterThan(x, 0)
347    assert (x > 1) == Relational(x, 1, '>')
348    assert (x > 1) == Relational(x, 1, 'gt')
349    assert (x > 1) == StrictGreaterThan(x, 1)
350    assert (x > 0) != Relational(x, 1, '>')
351    assert (x > 0) != Relational(x, 1, 'gt')
352    assert (x > 0) != StrictGreaterThan(x, 1)
353
354    assert Lt(x, 0) == Relational(x, 0, '<')
355    assert Lt(x, 0) == Relational(x, 0, 'lt')
356    assert Lt(x, 0) == StrictLessThan(x, 0)
357    assert Lt(x, 1) != Relational(x, 0, '<')
358    assert Lt(x, 1) != Relational(x, 0, 'lt')
359    assert Lt(x, 1) != StrictLessThan(x, 0)
360    assert (x < 1) == Relational(x, 1, '<')
361    assert (x < 1) == Relational(x, 1, 'lt')
362    assert (x < 1) == StrictLessThan(x, 1)
363    assert (x < 0) != Relational(x, 1, '<')
364    assert (x < 0) != Relational(x, 1, 'lt')
365    assert (x < 0) != StrictLessThan(x, 1)
366
367    # finally, some fuzz testing
368    from random import randint
369    for i in range(100):
370        while 1:
371            strtype, length = (chr, 65535) if randint(0, 1) else (chr, 255)
372            relation_type = strtype(randint(0, length))
373            if randint(0, 1):
374                relation_type += strtype(randint(0, length))
375            if relation_type not in ('==', 'eq', '!=', '<>', 'ne', '>=', 'ge',
376                                     '<=', 'le', '>', 'gt', '<', 'lt', ':=',
377                                     '+=', '-=', '*=', '/=', '%='):
378                break
379
380        raises(ValueError, lambda: Relational(x, 1, relation_type))
381    assert all(Relational(x, 0, op).rel_op == '==' for op in ('eq', '=='))
382    assert all(Relational(x, 0, op).rel_op == '!='
383               for op in ('ne', '<>', '!='))
384    assert all(Relational(x, 0, op).rel_op == '>' for op in ('gt', '>'))
385    assert all(Relational(x, 0, op).rel_op == '<' for op in ('lt', '<'))
386    assert all(Relational(x, 0, op).rel_op == '>=' for op in ('ge', '>='))
387    assert all(Relational(x, 0, op).rel_op == '<=' for op in ('le', '<='))
388
389
390def test_relational_arithmetic():
391    for cls in [Eq, Ne, Le, Lt, Ge, Gt]:
392        rel = cls(x, y)
393        raises(TypeError, lambda: 0+rel)
394        raises(TypeError, lambda: 1*rel)
395        raises(TypeError, lambda: 1**rel)
396        raises(TypeError, lambda: rel**1)
397        raises(TypeError, lambda: Add(0, rel))
398        raises(TypeError, lambda: Mul(1, rel))
399        raises(TypeError, lambda: Pow(1, rel))
400        raises(TypeError, lambda: Pow(rel, 1))
401
402
403def test_relational_bool_output():
404    # https://github.com/sympy/sympy/issues/5931
405    raises(TypeError, lambda: bool(x > 3))
406    raises(TypeError, lambda: bool(x >= 3))
407    raises(TypeError, lambda: bool(x < 3))
408    raises(TypeError, lambda: bool(x <= 3))
409    raises(TypeError, lambda: bool(Eq(x, 3)))
410    raises(TypeError, lambda: bool(Ne(x, 3)))
411
412
413def test_relational_logic_symbols():
414    # See issue 6204
415    assert (x < y) & (z < t) == And(x < y, z < t)
416    assert (x < y) | (z < t) == Or(x < y, z < t)
417    assert ~(x < y) == Not(x < y)
418    assert (x < y) >> (z < t) == Implies(x < y, z < t)
419    assert (x < y) << (z < t) == Implies(z < t, x < y)
420    assert (x < y) ^ (z < t) == Xor(x < y, z < t)
421
422    assert isinstance((x < y) & (z < t), And)
423    assert isinstance((x < y) | (z < t), Or)
424    assert isinstance(~(x < y), GreaterThan)
425    assert isinstance((x < y) >> (z < t), Implies)
426    assert isinstance((x < y) << (z < t), Implies)
427    assert isinstance((x < y) ^ (z < t), (Or, Xor))
428
429
430def test_univariate_relational_as_set():
431    assert (x > 0).as_set() == Interval(0, oo, True, True)
432    assert (x >= 0).as_set() == Interval(0, oo)
433    assert (x < 0).as_set() == Interval(-oo, 0, True, True)
434    assert (x <= 0).as_set() == Interval(-oo, 0)
435    assert Eq(x, 0).as_set() == FiniteSet(0)
436    assert Ne(x, 0).as_set() == Interval(-oo, 0, True, True) + \
437        Interval(0, oo, True, True)
438
439    assert (x**2 >= 4).as_set() == Interval(-oo, -2) + Interval(2, oo)
440
441
442@XFAIL
443def test_multivariate_relational_as_set():
444    assert (x*y >= 0).as_set() == Interval(0, oo)*Interval(0, oo) + \
445        Interval(-oo, 0)*Interval(-oo, 0)
446
447
448def test_Not():
449    assert Not(Equality(x, y)) == Unequality(x, y)
450    assert Not(Unequality(x, y)) == Equality(x, y)
451    assert Not(StrictGreaterThan(x, y)) == LessThan(x, y)
452    assert Not(StrictLessThan(x, y)) == GreaterThan(x, y)
453    assert Not(GreaterThan(x, y)) == StrictLessThan(x, y)
454    assert Not(LessThan(x, y)) == StrictGreaterThan(x, y)
455
456
457def test_evaluate():
458    assert str(Eq(x, x, evaluate=False)) == 'Eq(x, x)'
459    assert Eq(x, x, evaluate=False).doit() == S.true
460    assert str(Ne(x, x, evaluate=False)) == 'Ne(x, x)'
461    assert Ne(x, x, evaluate=False).doit() == S.false
462
463    assert str(Ge(x, x, evaluate=False)) == 'x >= x'
464    assert str(Le(x, x, evaluate=False)) == 'x <= x'
465    assert str(Gt(x, x, evaluate=False)) == 'x > x'
466    assert str(Lt(x, x, evaluate=False)) == 'x < x'
467
468
469def assert_all_ineq_raise_TypeError(a, b):
470    raises(TypeError, lambda: a > b)
471    raises(TypeError, lambda: a >= b)
472    raises(TypeError, lambda: a < b)
473    raises(TypeError, lambda: a <= b)
474    raises(TypeError, lambda: b > a)
475    raises(TypeError, lambda: b >= a)
476    raises(TypeError, lambda: b < a)
477    raises(TypeError, lambda: b <= a)
478
479
480def assert_all_ineq_give_class_Inequality(a, b):
481    """All inequality operations on `a` and `b` result in class Inequality."""
482    from sympy.core.relational import _Inequality as Inequality
483    assert isinstance(a > b,  Inequality)
484    assert isinstance(a >= b, Inequality)
485    assert isinstance(a < b,  Inequality)
486    assert isinstance(a <= b, Inequality)
487    assert isinstance(b > a,  Inequality)
488    assert isinstance(b >= a, Inequality)
489    assert isinstance(b < a,  Inequality)
490    assert isinstance(b <= a, Inequality)
491
492
493def test_imaginary_compare_raises_TypeError():
494    # See issue #5724
495    assert_all_ineq_raise_TypeError(I, x)
496
497
498def test_complex_compare_not_real():
499    # two cases which are not real
500    y = Symbol('y', imaginary=True)
501    z = Symbol('z', complex=True, extended_real=False)
502    for w in (y, z):
503        assert_all_ineq_raise_TypeError(2, w)
504    # some cases which should remain un-evaluated
505    t = Symbol('t')
506    x = Symbol('x', real=True)
507    z = Symbol('z', complex=True)
508    for w in (x, z, t):
509        assert_all_ineq_give_class_Inequality(2, w)
510
511
512def test_imaginary_and_inf_compare_raises_TypeError():
513    # See pull request #7835
514    y = Symbol('y', imaginary=True)
515    assert_all_ineq_raise_TypeError(oo, y)
516    assert_all_ineq_raise_TypeError(-oo, y)
517
518
519def test_complex_pure_imag_not_ordered():
520    raises(TypeError, lambda: 2*I < 3*I)
521
522    # more generally
523    x = Symbol('x', real=True, nonzero=True)
524    y = Symbol('y', imaginary=True)
525    z = Symbol('z', complex=True)
526    assert_all_ineq_raise_TypeError(I, y)
527
528    t = I*x   # an imaginary number, should raise errors
529    assert_all_ineq_raise_TypeError(2, t)
530
531    t = -I*y   # a real number, so no errors
532    assert_all_ineq_give_class_Inequality(2, t)
533
534    t = I*z   # unknown, should be unevaluated
535    assert_all_ineq_give_class_Inequality(2, t)
536
537
538def test_x_minus_y_not_same_as_x_lt_y():
539    """
540    A consequence of pull request #7792 is that `x - y < 0` and `x < y`
541    are not synonymous.
542    """
543    x = I + 2
544    y = I + 3
545    raises(TypeError, lambda: x < y)
546    assert x - y < 0
547
548    ineq = Lt(x, y, evaluate=False)
549    raises(TypeError, lambda: ineq.doit())
550    assert ineq.lhs - ineq.rhs < 0
551
552    t = Symbol('t', imaginary=True)
553    x = 2 + t
554    y = 3 + t
555    ineq = Lt(x, y, evaluate=False)
556    raises(TypeError, lambda: ineq.doit())
557    assert ineq.lhs - ineq.rhs < 0
558
559    # this one should give error either way
560    x = I + 2
561    y = 2*I + 3
562    raises(TypeError, lambda: x < y)
563    raises(TypeError, lambda: x - y < 0)
564
565
566def test_nan_equality_exceptions():
567    # See issue #7774
568    import random
569    assert Equality(nan, nan) is S.false
570    assert Unequality(nan, nan) is S.true
571
572    # See issue #7773
573    A = (x, S.Zero, S.One/3, pi, oo, -oo)
574    assert Equality(nan, random.choice(A)) is S.false
575    assert Equality(random.choice(A), nan) is S.false
576    assert Unequality(nan, random.choice(A)) is S.true
577    assert Unequality(random.choice(A), nan) is S.true
578
579
580def test_nan_inequality_raise_errors():
581    # See discussion in pull request #7776.  We test inequalities with
582    # a set including examples of various classes.
583    for q in (x, S.Zero, S(10), S.One/3, pi, S(1.3), oo, -oo, nan):
584        assert_all_ineq_raise_TypeError(q, nan)
585
586
587def test_nan_complex_inequalities():
588    # Comparisons of NaN with non-real raise errors, we're not too
589    # fussy whether its the NaN error or complex error.
590    for r in (I, zoo, Symbol('z', imaginary=True)):
591        assert_all_ineq_raise_TypeError(r, nan)
592
593
594def test_complex_infinity_inequalities():
595    raises(TypeError, lambda: zoo > 0)
596    raises(TypeError, lambda: zoo >= 0)
597    raises(TypeError, lambda: zoo < 0)
598    raises(TypeError, lambda: zoo <= 0)
599
600
601def test_inequalities_symbol_name_same():
602    """Using the operator and functional forms should give same results."""
603    # We test all combinations from a set
604    # FIXME: could replace with random selection after test passes
605    A = (x, y, S.Zero, S.One/3, pi, oo, -oo)
606    for a in A:
607        for b in A:
608            assert Gt(a, b) == (a > b)
609            assert Lt(a, b) == (a < b)
610            assert Ge(a, b) == (a >= b)
611            assert Le(a, b) == (a <= b)
612
613    for b in (y, S.Zero, S.One/3, pi, oo, -oo):
614        assert Gt(x, b, evaluate=False) == (x > b)
615        assert Lt(x, b, evaluate=False) == (x < b)
616        assert Ge(x, b, evaluate=False) == (x >= b)
617        assert Le(x, b, evaluate=False) == (x <= b)
618
619    for b in (y, S.Zero, S.One/3, pi, oo, -oo):
620        assert Gt(b, x, evaluate=False) == (b > x)
621        assert Lt(b, x, evaluate=False) == (b < x)
622        assert Ge(b, x, evaluate=False) == (b >= x)
623        assert Le(b, x, evaluate=False) == (b <= x)
624
625
626def test_inequalities_symbol_name_same_complex():
627    """Using the operator and functional forms should give same results.
628    With complex non-real numbers, both should raise errors.
629    """
630    # FIXME: could replace with random selection after test passes
631    for a in (x, S.Zero, S.One/3, pi, oo, Rational(1, 3)):
632        raises(TypeError, lambda: Gt(a, I))
633        raises(TypeError, lambda: a > I)
634        raises(TypeError, lambda: Lt(a, I))
635        raises(TypeError, lambda: a < I)
636        raises(TypeError, lambda: Ge(a, I))
637        raises(TypeError, lambda: a >= I)
638        raises(TypeError, lambda: Le(a, I))
639        raises(TypeError, lambda: a <= I)
640
641
642def test_inequalities_cant_sympify_other():
643    # see issue 7833
644    from operator import gt, lt, ge, le
645
646    bar = "foo"
647
648    for a in (x, S.Zero, S.One/3, pi, I, zoo, oo, -oo, nan, Rational(1, 3)):
649        for op in (lt, gt, le, ge):
650            raises(TypeError, lambda: op(a, bar))
651
652
653def test_ineq_avoid_wild_symbol_flip():
654    # see issue #7951, we try to avoid this internally, e.g., by using
655    # __lt__ instead of "<".
656    from sympy.core.symbol import Wild
657    p = symbols('p', cls=Wild)
658    # x > p might flip, but Gt should not:
659    assert Gt(x, p) == Gt(x, p, evaluate=False)
660    # Previously failed as 'p > x':
661    e = Lt(x, y).subs({y: p})
662    assert e == Lt(x, p, evaluate=False)
663    # Previously failed as 'p <= x':
664    e = Ge(x, p).doit()
665    assert e == Ge(x, p, evaluate=False)
666
667
668def test_issue_8245():
669    a = S("6506833320952669167898688709329/5070602400912917605986812821504")
670    assert rel_check(a, a.n(10))
671    assert rel_check(a, a.n(20))
672    assert rel_check(a, a.n())
673    # prec of 30 is enough to fully capture a as mpf
674    assert Float(a, 30) == Float(str(a.p), '')/Float(str(a.q), '')
675    for i in range(31):
676        r = Rational(Float(a, i))
677        f = Float(r)
678        assert (f < a) == (Rational(f) < a)
679    # test sign handling
680    assert (-f < -a) == (Rational(-f) < -a)
681    # test equivalence handling
682    isa = Float(a.p,'')/Float(a.q,'')
683    assert isa <= a
684    assert not isa < a
685    assert isa >= a
686    assert not isa > a
687    assert isa > 0
688
689    a = sqrt(2)
690    r = Rational(str(a.n(30)))
691    assert rel_check(a, r)
692
693    a = sqrt(2)
694    r = Rational(str(a.n(29)))
695    assert rel_check(a, r)
696
697    assert Eq(log(cos(2)**2 + sin(2)**2), 0) is S.true
698
699
700def test_issue_8449():
701    p = Symbol('p', nonnegative=True)
702    assert Lt(-oo, p)
703    assert Ge(-oo, p) is S.false
704    assert Gt(oo, -p)
705    assert Le(oo, -p) is S.false
706
707
708def test_simplify_relational():
709    assert simplify(x*(y + 1) - x*y - x + 1 < x) == (x > 1)
710    assert simplify(x*(y + 1) - x*y - x - 1 < x) == (x > -1)
711    assert simplify(x < x*(y + 1) - x*y - x + 1) == (x < 1)
712    q, r = symbols("q r")
713    assert (((-q + r) - (q - r)) <= 0).simplify() == (q >= r)
714    root2 = sqrt(2)
715    equation = ((root2 * (-q + r) - root2 * (q - r)) <= 0).simplify()
716    assert equation == (q >= r)
717    r = S.One < x
718    # canonical operations are not the same as simplification,
719    # so if there is no simplification, canonicalization will
720    # be done unless the measure forbids it
721    assert simplify(r) == r.canonical
722    assert simplify(r, ratio=0) != r.canonical
723    # this is not a random test; in _eval_simplify
724    # this will simplify to S.false and that is the
725    # reason for the 'if r.is_Relational' in Relational's
726    # _eval_simplify routine
727    assert simplify(-(2**(pi*Rational(3, 2)) + 6**pi)**(1/pi) +
728                    2*(2**(pi/2) + 3**pi)**(1/pi) < 0) is S.false
729    # canonical at least
730    assert Eq(y, x).simplify() == Eq(x, y)
731    assert Eq(x - 1, 0).simplify() == Eq(x, 1)
732    assert Eq(x - 1, x).simplify() == S.false
733    assert Eq(2*x - 1, x).simplify() == Eq(x, 1)
734    assert Eq(2*x, 4).simplify() == Eq(x, 2)
735    z = cos(1)**2 + sin(1)**2 - 1  # z.is_zero is None
736    assert Eq(z*x, 0).simplify() == S.true
737
738    assert Ne(y, x).simplify() == Ne(x, y)
739    assert Ne(x - 1, 0).simplify() == Ne(x, 1)
740    assert Ne(x - 1, x).simplify() == S.true
741    assert Ne(2*x - 1, x).simplify() == Ne(x, 1)
742    assert Ne(2*x, 4).simplify() == Ne(x, 2)
743    assert Ne(z*x, 0).simplify() == S.false
744
745    # No real-valued assumptions
746    assert Ge(y, x).simplify() == Le(x, y)
747    assert Ge(x - 1, 0).simplify() == Ge(x, 1)
748    assert Ge(x - 1, x).simplify() == S.false
749    assert Ge(2*x - 1, x).simplify() == Ge(x, 1)
750    assert Ge(2*x, 4).simplify() == Ge(x, 2)
751    assert Ge(z*x, 0).simplify() == S.true
752    assert Ge(x, -2).simplify() == Ge(x, -2)
753    assert Ge(-x, -2).simplify() == Le(x, 2)
754    assert Ge(x, 2).simplify() == Ge(x, 2)
755    assert Ge(-x, 2).simplify() == Le(x, -2)
756
757    assert Le(y, x).simplify() == Ge(x, y)
758    assert Le(x - 1, 0).simplify() == Le(x, 1)
759    assert Le(x - 1, x).simplify() == S.true
760    assert Le(2*x - 1, x).simplify() == Le(x, 1)
761    assert Le(2*x, 4).simplify() == Le(x, 2)
762    assert Le(z*x, 0).simplify() == S.true
763    assert Le(x, -2).simplify() == Le(x, -2)
764    assert Le(-x, -2).simplify() == Ge(x, 2)
765    assert Le(x, 2).simplify() == Le(x, 2)
766    assert Le(-x, 2).simplify() == Ge(x, -2)
767
768    assert Gt(y, x).simplify() == Lt(x, y)
769    assert Gt(x - 1, 0).simplify() == Gt(x, 1)
770    assert Gt(x - 1, x).simplify() == S.false
771    assert Gt(2*x - 1, x).simplify() == Gt(x, 1)
772    assert Gt(2*x, 4).simplify() == Gt(x, 2)
773    assert Gt(z*x, 0).simplify() == S.false
774    assert Gt(x, -2).simplify() == Gt(x, -2)
775    assert Gt(-x, -2).simplify() == Lt(x, 2)
776    assert Gt(x, 2).simplify() == Gt(x, 2)
777    assert Gt(-x, 2).simplify() == Lt(x, -2)
778
779    assert Lt(y, x).simplify() == Gt(x, y)
780    assert Lt(x - 1, 0).simplify() == Lt(x, 1)
781    assert Lt(x - 1, x).simplify() == S.true
782    assert Lt(2*x - 1, x).simplify() == Lt(x, 1)
783    assert Lt(2*x, 4).simplify() == Lt(x, 2)
784    assert Lt(z*x, 0).simplify() == S.false
785    assert Lt(x, -2).simplify() == Lt(x, -2)
786    assert Lt(-x, -2).simplify() == Gt(x, 2)
787    assert Lt(x, 2).simplify() == Lt(x, 2)
788    assert Lt(-x, 2).simplify() == Gt(x, -2)
789
790    # Test particulat branches of _eval_simplify
791    m = exp(1) - exp_polar(1)
792    assert simplify(m*x > 1) is S.false
793    # These two tests the same branch
794    assert simplify(m*x + 2*m*y > 1) is S.false
795    assert simplify(m*x + y > 1 + y) is S.false
796
797
798def test_equals():
799    w, x, y, z = symbols('w:z')
800    f = Function('f')
801    assert Eq(x, 1).equals(Eq(x*(y + 1) - x*y - x + 1, x))
802    assert Eq(x, y).equals(x < y, True) == False
803    assert Eq(x, f(1)).equals(Eq(x, f(2)), True) == f(1) - f(2)
804    assert Eq(f(1), y).equals(Eq(f(2), y), True) == f(1) - f(2)
805    assert Eq(x, f(1)).equals(Eq(f(2), x), True) == f(1) - f(2)
806    assert Eq(f(1), x).equals(Eq(x, f(2)), True) == f(1) - f(2)
807    assert Eq(w, x).equals(Eq(y, z), True) == False
808    assert Eq(f(1), f(2)).equals(Eq(f(3), f(4)), True) == f(1) - f(3)
809    assert (x < y).equals(y > x, True) == True
810    assert (x < y).equals(y >= x, True) == False
811    assert (x < y).equals(z < y, True) == False
812    assert (x < y).equals(x < z, True) == False
813    assert (x < f(1)).equals(x < f(2), True) == f(1) - f(2)
814    assert (f(1) < x).equals(f(2) < x, True) == f(1) - f(2)
815
816
817def test_reversed():
818    assert (x < y).reversed == (y > x)
819    assert (x <= y).reversed == (y >= x)
820    assert Eq(x, y, evaluate=False).reversed == Eq(y, x, evaluate=False)
821    assert Ne(x, y, evaluate=False).reversed == Ne(y, x, evaluate=False)
822    assert (x >= y).reversed == (y <= x)
823    assert (x > y).reversed == (y < x)
824
825
826def test_canonical():
827    c = [i.canonical for i in (
828        x + y < z,
829        x + 2 > 3,
830        x < 2,
831        S(2) > x,
832        x**2 > -x/y,
833        Gt(3, 2, evaluate=False)
834        )]
835    assert [i.canonical for i in c] == c
836    assert [i.reversed.canonical for i in c] == c
837    assert not any(i.lhs.is_Number and not i.rhs.is_Number for i in c)
838
839    c = [i.reversed.func(i.rhs, i.lhs, evaluate=False).canonical for i in c]
840    assert [i.canonical for i in c] == c
841    assert [i.reversed.canonical for i in c] == c
842    assert not any(i.lhs.is_Number and not i.rhs.is_Number for i in c)
843
844
845@XFAIL
846def test_issue_8444_nonworkingtests():
847    x = symbols('x', real=True)
848    assert (x <= oo) == (x >= -oo) == True
849
850    x = symbols('x')
851    assert x >= floor(x)
852    assert (x < floor(x)) == False
853    assert x <= ceiling(x)
854    assert (x > ceiling(x)) == False
855
856
857def test_issue_8444_workingtests():
858    x = symbols('x')
859    assert Gt(x, floor(x)) == Gt(x, floor(x), evaluate=False)
860    assert Ge(x, floor(x)) == Ge(x, floor(x), evaluate=False)
861    assert Lt(x, ceiling(x)) == Lt(x, ceiling(x), evaluate=False)
862    assert Le(x, ceiling(x)) == Le(x, ceiling(x), evaluate=False)
863    i = symbols('i', integer=True)
864    assert (i > floor(i)) == False
865    assert (i < ceiling(i)) == False
866
867
868def test_issue_10304():
869    d = cos(1)**2 + sin(1)**2 - 1
870    assert d.is_comparable is False  # if this fails, find a new d
871    e = 1 + d*I
872    assert simplify(Eq(e, 0)) is S.false
873
874
875def test_issue_18412():
876    d = (Rational(1, 6) + z / 4 / y)
877    assert Eq(x, pi * y**3 * d).replace(y**3, z) == Eq(x, pi * z * d)
878
879
880def test_issue_10401():
881    x = symbols('x')
882    fin = symbols('inf', finite=True)
883    inf = symbols('inf', infinite=True)
884    inf2 = symbols('inf2', infinite=True)
885    infx = symbols('infx', infinite=True, extended_real=True)
886    # Used in the commented tests below:
887    #infx2 = symbols('infx2', infinite=True, extended_real=True)
888    infnx = symbols('inf~x', infinite=True, extended_real=False)
889    infnx2 = symbols('inf~x2', infinite=True, extended_real=False)
890    infp = symbols('infp', infinite=True, extended_positive=True)
891    infp1 = symbols('infp1', infinite=True, extended_positive=True)
892    infn = symbols('infn', infinite=True, extended_negative=True)
893    zero = symbols('z', zero=True)
894    nonzero = symbols('nz', zero=False, finite=True)
895
896    assert Eq(1/(1/x + 1), 1).func is Eq
897    assert Eq(1/(1/x + 1), 1).subs(x, S.ComplexInfinity) is S.true
898    assert Eq(1/(1/fin + 1), 1) is S.false
899
900    T, F = S.true, S.false
901    assert Eq(fin, inf) is F
902    assert Eq(inf, inf2) not in (T, F) and inf != inf2
903    assert Eq(1 + inf, 2 + inf2) not in (T, F) and inf != inf2
904    assert Eq(infp, infp1) is T
905    assert Eq(infp, infn) is F
906    assert Eq(1 + I*oo, I*oo) is F
907    assert Eq(I*oo, 1 + I*oo) is F
908    assert Eq(1 + I*oo, 2 + I*oo) is F
909    assert Eq(1 + I*oo, 2 + I*infx) is F
910    assert Eq(1 + I*oo, 2 + infx) is F
911    # FIXME: The test below fails because (-infx).is_extended_positive is True
912    # (should be None)
913    #assert Eq(1 + I*infx, 1 + I*infx2) not in (T, F) and infx != infx2
914    #
915    assert Eq(zoo, sqrt(2) + I*oo) is F
916    assert Eq(zoo, oo) is F
917    r = Symbol('r', real=True)
918    i = Symbol('i', imaginary=True)
919    assert Eq(i*I, r) not in (T, F)
920    assert Eq(infx, infnx) is F
921    assert Eq(infnx, infnx2) not in (T, F) and infnx != infnx2
922    assert Eq(zoo, oo) is F
923    assert Eq(inf/inf2, 0) is F
924    assert Eq(inf/fin, 0) is F
925    assert Eq(fin/inf, 0) is T
926    assert Eq(zero/nonzero, 0) is T and ((zero/nonzero) != 0)
927    # The commented out test below is incorrect because:
928    assert zoo == -zoo
929    assert Eq(zoo, -zoo) is T
930    assert Eq(oo, -oo) is F
931    assert Eq(inf, -inf) not in (T, F)
932
933    assert Eq(fin/(fin + 1), 1) is S.false
934
935    o = symbols('o', odd=True)
936    assert Eq(o, 2*o) is S.false
937
938    p = symbols('p', positive=True)
939    assert Eq(p/(p - 1), 1) is F
940
941
942def test_issue_10633():
943    assert Eq(True, False) == False
944    assert Eq(False, True) == False
945    assert Eq(True, True) == True
946    assert Eq(False, False) == True
947
948
949def test_issue_10927():
950    x = symbols('x')
951    assert str(Eq(x, oo)) == 'Eq(x, oo)'
952    assert str(Eq(x, -oo)) == 'Eq(x, -oo)'
953
954
955def test_issues_13081_12583_12534():
956    # 13081
957    r = Rational('905502432259640373/288230376151711744')
958    assert (r < pi) is S.false
959    assert (r > pi) is S.true
960    # 12583
961    v = sqrt(2)
962    u = sqrt(v) + 2/sqrt(10 - 8/sqrt(2 - v) + 4*v*(1/sqrt(2 - v) - 1))
963    assert (u >= 0) is S.true
964    # 12534; Rational vs NumberSymbol
965    # here are some precisions for which Rational forms
966    # at a lower and higher precision bracket the value of pi
967    # e.g. for p = 20:
968    # Rational(pi.n(p + 1)).n(25) = 3.14159265358979323846 2834
969    #                    pi.n(25) = 3.14159265358979323846 2643
970    # Rational(pi.n(p    )).n(25) = 3.14159265358979323846 1987
971    assert [p for p in range(20, 50) if
972            (Rational(pi.n(p)) < pi) and
973            (pi < Rational(pi.n(p + 1)))] == [20, 24, 27, 33, 37, 43, 48]
974    # pick one such precision and affirm that the reversed operation
975    # gives the opposite result, i.e. if x < y is true then x > y
976    # must be false
977    for i in (20, 21):
978        v = pi.n(i)
979        assert rel_check(Rational(v), pi)
980        assert rel_check(v, pi)
981    assert rel_check(pi.n(20), pi.n(21))
982    # Float vs Rational
983    # the rational form is less than the floating representation
984    # at the same precision
985    assert [i for i in range(15, 50) if Rational(pi.n(i)) > pi.n(i)] == []
986    # this should be the same if we reverse the relational
987    assert [i for i in range(15, 50) if pi.n(i) < Rational(pi.n(i))] == []
988
989def test_issue_18188():
990    from sympy.sets.conditionset import ConditionSet
991    result1 = Eq(x*cos(x) - 3*sin(x), 0)
992    assert result1.as_set() == ConditionSet(x, Eq(x*cos(x) - 3*sin(x), 0), Reals)
993
994    result2 = Eq(x**2 + sqrt(x*2) + sin(x), 0)
995    assert result2.as_set() == ConditionSet(x, Eq(sqrt(2)*sqrt(x) + x**2 + sin(x), 0), Reals)
996
997def test_binary_symbols():
998    ans = {x}
999    for f in Eq, Ne:
1000        for t in S.true, S.false:
1001            eq = f(x, S.true)
1002            assert eq.binary_symbols == ans
1003            assert eq.reversed.binary_symbols == ans
1004        assert f(x, 1).binary_symbols == set()
1005
1006
1007def test_rel_args():
1008    # can't have Boolean args; this is automatic for True/False
1009    # with Python 3 and we confirm that SymPy does the same
1010    # for true/false
1011    for op in ['<', '<=', '>', '>=']:
1012        for b in (S.true, x < 1, And(x, y)):
1013            for v in (0.1, 1, 2**32, t, S.One):
1014                raises(TypeError, lambda: Relational(b, v, op))
1015
1016
1017def test_Equality_rewrite_as_Add():
1018    eq = Eq(x + y, y - x)
1019    assert eq.rewrite(Add) == 2*x
1020    assert eq.rewrite(Add, evaluate=None).args == (x, x, y, -y)
1021    assert eq.rewrite(Add, evaluate=False).args == (x, y, x, -y)
1022
1023
1024def test_issue_15847():
1025    a = Ne(x*(x+y), x**2 + x*y)
1026    assert simplify(a) == False
1027
1028
1029def test_negated_property():
1030    eq = Eq(x, y)
1031    assert eq.negated == Ne(x, y)
1032
1033    eq = Ne(x, y)
1034    assert eq.negated == Eq(x, y)
1035
1036    eq = Ge(x + y, y - x)
1037    assert eq.negated == Lt(x + y, y - x)
1038
1039    for f in (Eq, Ne, Ge, Gt, Le, Lt):
1040        assert f(x, y).negated.negated == f(x, y)
1041
1042
1043def test_reversedsign_property():
1044    eq = Eq(x, y)
1045    assert eq.reversedsign == Eq(-x, -y)
1046
1047    eq = Ne(x, y)
1048    assert eq.reversedsign == Ne(-x, -y)
1049
1050    eq = Ge(x + y, y - x)
1051    assert eq.reversedsign == Le(-x - y, x - y)
1052
1053    for f in (Eq, Ne, Ge, Gt, Le, Lt):
1054        assert f(x, y).reversedsign.reversedsign == f(x, y)
1055
1056    for f in (Eq, Ne, Ge, Gt, Le, Lt):
1057        assert f(-x, y).reversedsign.reversedsign == f(-x, y)
1058
1059    for f in (Eq, Ne, Ge, Gt, Le, Lt):
1060        assert f(x, -y).reversedsign.reversedsign == f(x, -y)
1061
1062    for f in (Eq, Ne, Ge, Gt, Le, Lt):
1063        assert f(-x, -y).reversedsign.reversedsign == f(-x, -y)
1064
1065
1066def test_reversed_reversedsign_property():
1067    for f in (Eq, Ne, Ge, Gt, Le, Lt):
1068        assert f(x, y).reversed.reversedsign == f(x, y).reversedsign.reversed
1069
1070    for f in (Eq, Ne, Ge, Gt, Le, Lt):
1071        assert f(-x, y).reversed.reversedsign == f(-x, y).reversedsign.reversed
1072
1073    for f in (Eq, Ne, Ge, Gt, Le, Lt):
1074        assert f(x, -y).reversed.reversedsign == f(x, -y).reversedsign.reversed
1075
1076    for f in (Eq, Ne, Ge, Gt, Le, Lt):
1077        assert f(-x, -y).reversed.reversedsign == \
1078            f(-x, -y).reversedsign.reversed
1079
1080
1081def test_improved_canonical():
1082    def test_different_forms(listofforms):
1083        for form1, form2 in combinations(listofforms, 2):
1084            assert form1.canonical == form2.canonical
1085
1086    def generate_forms(expr):
1087        return [expr, expr.reversed, expr.reversedsign,
1088                expr.reversed.reversedsign]
1089
1090    test_different_forms(generate_forms(x > -y))
1091    test_different_forms(generate_forms(x >= -y))
1092    test_different_forms(generate_forms(Eq(x, -y)))
1093    test_different_forms(generate_forms(Ne(x, -y)))
1094    test_different_forms(generate_forms(pi < x))
1095    test_different_forms(generate_forms(pi - 5*y < -x + 2*y**2 - 7))
1096
1097    assert (pi >= x).canonical == (x <= pi)
1098
1099
1100def test_set_equality_canonical():
1101    a, b, c = symbols('a b c')
1102
1103    A = Eq(FiniteSet(a, b, c), FiniteSet(1, 2, 3))
1104    B = Ne(FiniteSet(a, b, c), FiniteSet(4, 5, 6))
1105
1106    assert A.canonical == A.reversed
1107    assert B.canonical == B.reversed
1108
1109
1110def test_trigsimp():
1111    # issue 16736
1112    s, c = sin(2*x), cos(2*x)
1113    eq = Eq(s, c)
1114    assert trigsimp(eq) == eq  # no rearrangement of sides
1115    # simplification of sides might result in
1116    # an unevaluated Eq
1117    changed = trigsimp(Eq(s + c, sqrt(2)))
1118    assert isinstance(changed, Eq)
1119    assert changed.subs(x, pi/8) is S.true
1120    # or an evaluated one
1121    assert trigsimp(Eq(cos(x)**2 + sin(x)**2, 1)) is S.true
1122
1123
1124def test_polynomial_relation_simplification():
1125    assert Ge(3*x*(x + 1) + 4, 3*x).simplify() in [Ge(x**2, -Rational(4,3)), Le(-x**2, Rational(4, 3))]
1126    assert Le(-(3*x*(x + 1) + 4), -3*x).simplify() in [Ge(x**2, -Rational(4,3)), Le(-x**2, Rational(4, 3))]
1127    assert ((x**2+3)*(x**2-1)+3*x >= 2*x**2).simplify() in [(x**4 + 3*x >= 3), (-x**4 - 3*x <= -3)]
1128
1129
1130def test_multivariate_linear_function_simplification():
1131    assert Ge(x + y, x - y).simplify() == Ge(y, 0)
1132    assert Le(-x + y, -x - y).simplify() == Le(y, 0)
1133    assert Eq(2*x + y, 2*x + y - 3).simplify() == False
1134    assert (2*x + y > 2*x + y - 3).simplify() == True
1135    assert (2*x + y < 2*x + y - 3).simplify() == False
1136    assert (2*x + y < 2*x + y + 3).simplify() == True
1137    a, b, c, d, e, f, g = symbols('a b c d e f g')
1138    assert Lt(a + b + c + 2*d, 3*d - f + g). simplify() == Lt(a, -b - c + d - f + g)
1139
1140
1141def test_nonpolymonial_relations():
1142    assert Eq(cos(x), 0).simplify() == Eq(cos(x), 0)
1143
1144def test_18778():
1145    raises(TypeError, lambda: is_le(Basic(), Basic()))
1146    raises(TypeError, lambda: is_gt(Basic(), Basic()))
1147    raises(TypeError, lambda: is_ge(Basic(), Basic()))
1148    raises(TypeError, lambda: is_lt(Basic(), Basic()))
1149
1150def test_EvalEq():
1151    """
1152
1153    This test exists to ensure backwards compatibility.
1154    The method to use is _eval_is_eq
1155    """
1156    from sympy import Expr
1157
1158    class PowTest(Expr):
1159        def __new__(cls, base, exp):
1160           return Basic.__new__(PowTest, _sympify(base), _sympify(exp))
1161
1162        def _eval_Eq(lhs, rhs):
1163            if type(lhs) == PowTest and type(rhs) == PowTest:
1164                return lhs.args[0] == rhs.args[0] and lhs.args[1] == rhs.args[1]
1165
1166    assert is_eq(PowTest(3, 4), PowTest(3,4))
1167    assert is_eq(PowTest(3, 4), _sympify(4)) is None
1168    assert is_neq(PowTest(3, 4), PowTest(3,7))
1169
1170
1171def test_is_eq():
1172    # test assumptions
1173    assert is_eq(x, y, Q.infinite(x) & Q.finite(y)) is False
1174    assert is_eq(x, y, Q.infinite(x) & Q.infinite(y) & Q.extended_real(x) & ~Q.extended_real(y)) is False
1175    assert is_eq(x, y, Q.infinite(x) & Q.infinite(y) & Q.extended_positive(x) & Q.extended_negative(y)) is False
1176
1177    assert is_eq(x+I, y+I, Q.infinite(x) & Q.finite(y)) is False
1178    assert is_eq(1+x*I, 1+y*I, Q.infinite(x) & Q.finite(y)) is False
1179
1180    assert is_eq(x, S(0), assumptions=Q.zero(x))
1181    assert is_eq(x, S(0), assumptions=~Q.zero(x)) is False
1182    assert is_eq(x, S(0), assumptions=Q.nonzero(x)) is False
1183    assert is_neq(x, S(0), assumptions=Q.zero(x)) is False
1184    assert is_neq(x, S(0), assumptions=~Q.zero(x))
1185    assert is_neq(x, S(0), assumptions=Q.nonzero(x))
1186
1187    # test registration
1188    class PowTest(Expr):
1189        def __new__(cls, base, exp):
1190            return Basic.__new__(cls, _sympify(base), _sympify(exp))
1191
1192    @dispatch(PowTest, PowTest)
1193    def _eval_is_eq(lhs, rhs):
1194        if type(lhs) == PowTest and type(rhs) == PowTest:
1195            return fuzzy_and([is_eq(lhs.args[0], rhs.args[0]), is_eq(lhs.args[1], rhs.args[1])])
1196
1197    assert is_eq(PowTest(3, 4), PowTest(3,4))
1198    assert is_eq(PowTest(3, 4), _sympify(4)) is None
1199    assert is_neq(PowTest(3, 4), PowTest(3,7))
1200
1201
1202def test_is_ge_le():
1203    # test assumptions
1204    assert is_ge(x, S(0), Q.nonnegative(x)) is True
1205    assert is_ge(x, S(0), Q.negative(x)) is False
1206
1207    # test registration
1208    class PowTest(Expr):
1209        def __new__(cls, base, exp):
1210            return Basic.__new__(cls, _sympify(base), _sympify(exp))
1211
1212    @dispatch(PowTest, PowTest)
1213    def _eval_is_ge(lhs, rhs):
1214        if type(lhs) == PowTest and type(rhs) == PowTest:
1215            return fuzzy_and([is_ge(lhs.args[0], rhs.args[0]), is_ge(lhs.args[1], rhs.args[1])])
1216
1217    assert is_ge(PowTest(3, 9), PowTest(3,2))
1218    assert is_gt(PowTest(3, 9), PowTest(3,2))
1219    assert is_le(PowTest(3, 2), PowTest(3,9))
1220    assert is_lt(PowTest(3, 2), PowTest(3,9))
1221