common.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. """
  2. This module defines base class for handlers and some core handlers:
  3. ``Q.commutative`` and ``Q.is_true``.
  4. """
  5. from sympy.assumptions import Q, ask, AppliedPredicate
  6. from sympy.core import Basic, Symbol
  7. from sympy.core.logic import _fuzzy_group
  8. from sympy.core.numbers import NaN, Number
  9. from sympy.logic.boolalg import (And, BooleanTrue, BooleanFalse, conjuncts,
  10. Equivalent, Implies, Not, Or)
  11. from sympy.utilities.exceptions import sympy_deprecation_warning
  12. from ..predicates.common import CommutativePredicate, IsTruePredicate
  13. class AskHandler:
  14. """Base class that all Ask Handlers must inherit."""
  15. def __new__(cls, *args, **kwargs):
  16. sympy_deprecation_warning(
  17. """
  18. The AskHandler system is deprecated. The AskHandler class should
  19. be replaced with the multipledispatch handler of Predicate
  20. """,
  21. deprecated_since_version="1.8",
  22. active_deprecations_target='deprecated-askhandler',
  23. )
  24. return super().__new__(cls, *args, **kwargs)
  25. class CommonHandler(AskHandler):
  26. # Deprecated
  27. """Defines some useful methods common to most Handlers. """
  28. @staticmethod
  29. def AlwaysTrue(expr, assumptions):
  30. return True
  31. @staticmethod
  32. def AlwaysFalse(expr, assumptions):
  33. return False
  34. @staticmethod
  35. def AlwaysNone(expr, assumptions):
  36. return None
  37. NaN = AlwaysFalse
  38. # CommutativePredicate
  39. @CommutativePredicate.register(Symbol)
  40. def _(expr, assumptions):
  41. """Objects are expected to be commutative unless otherwise stated"""
  42. assumps = conjuncts(assumptions)
  43. if expr.is_commutative is not None:
  44. return expr.is_commutative and not ~Q.commutative(expr) in assumps
  45. if Q.commutative(expr) in assumps:
  46. return True
  47. elif ~Q.commutative(expr) in assumps:
  48. return False
  49. return True
  50. @CommutativePredicate.register(Basic)
  51. def _(expr, assumptions):
  52. for arg in expr.args:
  53. if not ask(Q.commutative(arg), assumptions):
  54. return False
  55. return True
  56. @CommutativePredicate.register(Number)
  57. def _(expr, assumptions):
  58. return True
  59. @CommutativePredicate.register(NaN)
  60. def _(expr, assumptions):
  61. return True
  62. # IsTruePredicate
  63. @IsTruePredicate.register(bool)
  64. def _(expr, assumptions):
  65. return expr
  66. @IsTruePredicate.register(BooleanTrue)
  67. def _(expr, assumptions):
  68. return True
  69. @IsTruePredicate.register(BooleanFalse)
  70. def _(expr, assumptions):
  71. return False
  72. @IsTruePredicate.register(AppliedPredicate)
  73. def _(expr, assumptions):
  74. return ask(expr, assumptions)
  75. @IsTruePredicate.register(Not)
  76. def _(expr, assumptions):
  77. arg = expr.args[0]
  78. if arg.is_Symbol:
  79. # symbol used as abstract boolean object
  80. return None
  81. value = ask(arg, assumptions=assumptions)
  82. if value in (True, False):
  83. return not value
  84. else:
  85. return None
  86. @IsTruePredicate.register(Or)
  87. def _(expr, assumptions):
  88. result = False
  89. for arg in expr.args:
  90. p = ask(arg, assumptions=assumptions)
  91. if p is True:
  92. return True
  93. if p is None:
  94. result = None
  95. return result
  96. @IsTruePredicate.register(And)
  97. def _(expr, assumptions):
  98. result = True
  99. for arg in expr.args:
  100. p = ask(arg, assumptions=assumptions)
  101. if p is False:
  102. return False
  103. if p is None:
  104. result = None
  105. return result
  106. @IsTruePredicate.register(Implies)
  107. def _(expr, assumptions):
  108. p, q = expr.args
  109. return ask(~p | q, assumptions=assumptions)
  110. @IsTruePredicate.register(Equivalent)
  111. def _(expr, assumptions):
  112. p, q = expr.args
  113. pt = ask(p, assumptions=assumptions)
  114. if pt is None:
  115. return None
  116. qt = ask(q, assumptions=assumptions)
  117. if qt is None:
  118. return None
  119. return pt == qt
  120. #### Helper methods
  121. def test_closed_group(expr, assumptions, key):
  122. """
  123. Test for membership in a group with respect
  124. to the current operation.
  125. """
  126. return _fuzzy_group(
  127. (ask(key(a), assumptions) for a in expr.args), quick_exit=True)