test_relational.py 42 KB

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