order.py 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. from sympy.assumptions import Predicate
  2. from sympy.multipledispatch import Dispatcher
  3. class NegativePredicate(Predicate):
  4. r"""
  5. Negative number predicate.
  6. Explanation
  7. ===========
  8. ``Q.negative(x)`` is true iff ``x`` is a real number and :math:`x < 0`, that is,
  9. it is in the interval :math:`(-\infty, 0)`. Note in particular that negative
  10. infinity is not negative.
  11. A few important facts about negative numbers:
  12. - Note that ``Q.nonnegative`` and ``~Q.negative`` are *not* the same
  13. thing. ``~Q.negative(x)`` simply means that ``x`` is not negative,
  14. whereas ``Q.nonnegative(x)`` means that ``x`` is real and not
  15. negative, i.e., ``Q.nonnegative(x)`` is logically equivalent to
  16. ``Q.zero(x) | Q.positive(x)``. So for example, ``~Q.negative(I)`` is
  17. true, whereas ``Q.nonnegative(I)`` is false.
  18. - See the documentation of ``Q.real`` for more information about
  19. related facts.
  20. Examples
  21. ========
  22. >>> from sympy import Q, ask, symbols, I
  23. >>> x = symbols('x')
  24. >>> ask(Q.negative(x), Q.real(x) & ~Q.positive(x) & ~Q.zero(x))
  25. True
  26. >>> ask(Q.negative(-1))
  27. True
  28. >>> ask(Q.nonnegative(I))
  29. False
  30. >>> ask(~Q.negative(I))
  31. True
  32. """
  33. name = 'negative'
  34. handler = Dispatcher(
  35. "NegativeHandler",
  36. doc=("Handler for Q.negative. Test that an expression is strictly less"
  37. " than zero.")
  38. )
  39. class NonNegativePredicate(Predicate):
  40. """
  41. Nonnegative real number predicate.
  42. Explanation
  43. ===========
  44. ``ask(Q.nonnegative(x))`` is true iff ``x`` belongs to the set of
  45. positive numbers including zero.
  46. - Note that ``Q.nonnegative`` and ``~Q.negative`` are *not* the same
  47. thing. ``~Q.negative(x)`` simply means that ``x`` is not negative,
  48. whereas ``Q.nonnegative(x)`` means that ``x`` is real and not
  49. negative, i.e., ``Q.nonnegative(x)`` is logically equivalent to
  50. ``Q.zero(x) | Q.positive(x)``. So for example, ``~Q.negative(I)`` is
  51. true, whereas ``Q.nonnegative(I)`` is false.
  52. Examples
  53. ========
  54. >>> from sympy import Q, ask, I
  55. >>> ask(Q.nonnegative(1))
  56. True
  57. >>> ask(Q.nonnegative(0))
  58. True
  59. >>> ask(Q.nonnegative(-1))
  60. False
  61. >>> ask(Q.nonnegative(I))
  62. False
  63. >>> ask(Q.nonnegative(-I))
  64. False
  65. """
  66. name = 'nonnegative'
  67. handler = Dispatcher(
  68. "NonNegativeHandler",
  69. doc=("Handler for Q.nonnegative.")
  70. )
  71. class NonZeroPredicate(Predicate):
  72. """
  73. Nonzero real number predicate.
  74. Explanation
  75. ===========
  76. ``ask(Q.nonzero(x))`` is true iff ``x`` is real and ``x`` is not zero. Note in
  77. particular that ``Q.nonzero(x)`` is false if ``x`` is not real. Use
  78. ``~Q.zero(x)`` if you want the negation of being zero without any real
  79. assumptions.
  80. A few important facts about nonzero numbers:
  81. - ``Q.nonzero`` is logically equivalent to ``Q.positive | Q.negative``.
  82. - See the documentation of ``Q.real`` for more information about
  83. related facts.
  84. Examples
  85. ========
  86. >>> from sympy import Q, ask, symbols, I, oo
  87. >>> x = symbols('x')
  88. >>> print(ask(Q.nonzero(x), ~Q.zero(x)))
  89. None
  90. >>> ask(Q.nonzero(x), Q.positive(x))
  91. True
  92. >>> ask(Q.nonzero(x), Q.zero(x))
  93. False
  94. >>> ask(Q.nonzero(0))
  95. False
  96. >>> ask(Q.nonzero(I))
  97. False
  98. >>> ask(~Q.zero(I))
  99. True
  100. >>> ask(Q.nonzero(oo))
  101. False
  102. """
  103. name = 'nonzero'
  104. handler = Dispatcher(
  105. "NonZeroHandler",
  106. doc=("Handler for key 'zero'. Test that an expression is not identically"
  107. " zero.")
  108. )
  109. class ZeroPredicate(Predicate):
  110. """
  111. Zero number predicate.
  112. Explanation
  113. ===========
  114. ``ask(Q.zero(x))`` is true iff the value of ``x`` is zero.
  115. Examples
  116. ========
  117. >>> from sympy import ask, Q, oo, symbols
  118. >>> x, y = symbols('x, y')
  119. >>> ask(Q.zero(0))
  120. True
  121. >>> ask(Q.zero(1/oo))
  122. True
  123. >>> print(ask(Q.zero(0*oo)))
  124. None
  125. >>> ask(Q.zero(1))
  126. False
  127. >>> ask(Q.zero(x*y), Q.zero(x) | Q.zero(y))
  128. True
  129. """
  130. name = 'zero'
  131. handler = Dispatcher(
  132. "ZeroHandler",
  133. doc="Handler for key 'zero'."
  134. )
  135. class NonPositivePredicate(Predicate):
  136. """
  137. Nonpositive real number predicate.
  138. Explanation
  139. ===========
  140. ``ask(Q.nonpositive(x))`` is true iff ``x`` belongs to the set of
  141. negative numbers including zero.
  142. - Note that ``Q.nonpositive`` and ``~Q.positive`` are *not* the same
  143. thing. ``~Q.positive(x)`` simply means that ``x`` is not positive,
  144. whereas ``Q.nonpositive(x)`` means that ``x`` is real and not
  145. positive, i.e., ``Q.nonpositive(x)`` is logically equivalent to
  146. `Q.negative(x) | Q.zero(x)``. So for example, ``~Q.positive(I)`` is
  147. true, whereas ``Q.nonpositive(I)`` is false.
  148. Examples
  149. ========
  150. >>> from sympy import Q, ask, I
  151. >>> ask(Q.nonpositive(-1))
  152. True
  153. >>> ask(Q.nonpositive(0))
  154. True
  155. >>> ask(Q.nonpositive(1))
  156. False
  157. >>> ask(Q.nonpositive(I))
  158. False
  159. >>> ask(Q.nonpositive(-I))
  160. False
  161. """
  162. name = 'nonpositive'
  163. handler = Dispatcher(
  164. "NonPositiveHandler",
  165. doc="Handler for key 'nonpositive'."
  166. )
  167. class PositivePredicate(Predicate):
  168. r"""
  169. Positive real number predicate.
  170. Explanation
  171. ===========
  172. ``Q.positive(x)`` is true iff ``x`` is real and `x > 0`, that is if ``x``
  173. is in the interval `(0, \infty)`. In particular, infinity is not
  174. positive.
  175. A few important facts about positive numbers:
  176. - Note that ``Q.nonpositive`` and ``~Q.positive`` are *not* the same
  177. thing. ``~Q.positive(x)`` simply means that ``x`` is not positive,
  178. whereas ``Q.nonpositive(x)`` means that ``x`` is real and not
  179. positive, i.e., ``Q.nonpositive(x)`` is logically equivalent to
  180. `Q.negative(x) | Q.zero(x)``. So for example, ``~Q.positive(I)`` is
  181. true, whereas ``Q.nonpositive(I)`` is false.
  182. - See the documentation of ``Q.real`` for more information about
  183. related facts.
  184. Examples
  185. ========
  186. >>> from sympy import Q, ask, symbols, I
  187. >>> x = symbols('x')
  188. >>> ask(Q.positive(x), Q.real(x) & ~Q.negative(x) & ~Q.zero(x))
  189. True
  190. >>> ask(Q.positive(1))
  191. True
  192. >>> ask(Q.nonpositive(I))
  193. False
  194. >>> ask(~Q.positive(I))
  195. True
  196. """
  197. name = 'positive'
  198. handler = Dispatcher(
  199. "PositiveHandler",
  200. doc=("Handler for key 'positive'. Test that an expression is strictly"
  201. " greater than zero.")
  202. )
  203. class ExtendedPositivePredicate(Predicate):
  204. r"""
  205. Positive extended real number predicate.
  206. Explanation
  207. ===========
  208. ``Q.extended_positive(x)`` is true iff ``x`` is extended real and
  209. `x > 0`, that is if ``x`` is in the interval `(0, \infty]`.
  210. Examples
  211. ========
  212. >>> from sympy import ask, I, oo, Q
  213. >>> ask(Q.extended_positive(1))
  214. True
  215. >>> ask(Q.extended_positive(oo))
  216. True
  217. >>> ask(Q.extended_positive(I))
  218. False
  219. """
  220. name = 'extended_positive'
  221. handler = Dispatcher("ExtendedPositiveHandler")
  222. class ExtendedNegativePredicate(Predicate):
  223. r"""
  224. Negative extended real number predicate.
  225. Explanation
  226. ===========
  227. ``Q.extended_negative(x)`` is true iff ``x`` is extended real and
  228. `x < 0`, that is if ``x`` is in the interval `[-\infty, 0)`.
  229. Examples
  230. ========
  231. >>> from sympy import ask, I, oo, Q
  232. >>> ask(Q.extended_negative(-1))
  233. True
  234. >>> ask(Q.extended_negative(-oo))
  235. True
  236. >>> ask(Q.extended_negative(-I))
  237. False
  238. """
  239. name = 'extended_negative'
  240. handler = Dispatcher("ExtendedNegativeHandler")
  241. class ExtendedNonZeroPredicate(Predicate):
  242. """
  243. Nonzero extended real number predicate.
  244. Explanation
  245. ===========
  246. ``ask(Q.extended_nonzero(x))`` is true iff ``x`` is extended real and
  247. ``x`` is not zero.
  248. Examples
  249. ========
  250. >>> from sympy import ask, I, oo, Q
  251. >>> ask(Q.extended_nonzero(-1))
  252. True
  253. >>> ask(Q.extended_nonzero(oo))
  254. True
  255. >>> ask(Q.extended_nonzero(I))
  256. False
  257. """
  258. name = 'extended_nonzero'
  259. handler = Dispatcher("ExtendedNonZeroHandler")
  260. class ExtendedNonPositivePredicate(Predicate):
  261. """
  262. Nonpositive extended real number predicate.
  263. Explanation
  264. ===========
  265. ``ask(Q.extended_nonpositive(x))`` is true iff ``x`` is extended real and
  266. ``x`` is not positive.
  267. Examples
  268. ========
  269. >>> from sympy import ask, I, oo, Q
  270. >>> ask(Q.extended_nonpositive(-1))
  271. True
  272. >>> ask(Q.extended_nonpositive(oo))
  273. False
  274. >>> ask(Q.extended_nonpositive(0))
  275. True
  276. >>> ask(Q.extended_nonpositive(I))
  277. False
  278. """
  279. name = 'extended_nonpositive'
  280. handler = Dispatcher("ExtendedNonPositiveHandler")
  281. class ExtendedNonNegativePredicate(Predicate):
  282. """
  283. Nonnegative extended real number predicate.
  284. Explanation
  285. ===========
  286. ``ask(Q.extended_nonnegative(x))`` is true iff ``x`` is extended real and
  287. ``x`` is not negative.
  288. Examples
  289. ========
  290. >>> from sympy import ask, I, oo, Q
  291. >>> ask(Q.extended_nonnegative(-1))
  292. False
  293. >>> ask(Q.extended_nonnegative(oo))
  294. True
  295. >>> ask(Q.extended_nonnegative(0))
  296. True
  297. >>> ask(Q.extended_nonnegative(I))
  298. False
  299. """
  300. name = 'extended_nonnegative'
  301. handler = Dispatcher("ExtendedNonNegativeHandler")