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