You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
157 lines
4.0 KiB
157 lines
4.0 KiB
5 months ago
|
"""
|
||
|
This module defines base class for handlers and some core handlers:
|
||
|
``Q.commutative`` and ``Q.is_true``.
|
||
|
"""
|
||
|
|
||
|
from sympy.assumptions import Q, ask, AppliedPredicate
|
||
|
from sympy.core import Basic, Symbol
|
||
|
from sympy.core.logic import _fuzzy_group
|
||
|
from sympy.core.numbers import NaN, Number
|
||
|
from sympy.logic.boolalg import (And, BooleanTrue, BooleanFalse, conjuncts,
|
||
|
Equivalent, Implies, Not, Or)
|
||
|
from sympy.utilities.exceptions import sympy_deprecation_warning
|
||
|
|
||
|
from ..predicates.common import CommutativePredicate, IsTruePredicate
|
||
|
|
||
|
|
||
|
class AskHandler:
|
||
|
"""Base class that all Ask Handlers must inherit."""
|
||
|
def __new__(cls, *args, **kwargs):
|
||
|
sympy_deprecation_warning(
|
||
|
"""
|
||
|
The AskHandler system is deprecated. The AskHandler class should
|
||
|
be replaced with the multipledispatch handler of Predicate
|
||
|
""",
|
||
|
deprecated_since_version="1.8",
|
||
|
active_deprecations_target='deprecated-askhandler',
|
||
|
)
|
||
|
return super().__new__(cls, *args, **kwargs)
|
||
|
|
||
|
|
||
|
class CommonHandler(AskHandler):
|
||
|
# Deprecated
|
||
|
"""Defines some useful methods common to most Handlers. """
|
||
|
|
||
|
@staticmethod
|
||
|
def AlwaysTrue(expr, assumptions):
|
||
|
return True
|
||
|
|
||
|
@staticmethod
|
||
|
def AlwaysFalse(expr, assumptions):
|
||
|
return False
|
||
|
|
||
|
@staticmethod
|
||
|
def AlwaysNone(expr, assumptions):
|
||
|
return None
|
||
|
|
||
|
NaN = AlwaysFalse
|
||
|
|
||
|
|
||
|
# CommutativePredicate
|
||
|
|
||
|
@CommutativePredicate.register(Symbol)
|
||
|
def _(expr, assumptions):
|
||
|
"""Objects are expected to be commutative unless otherwise stated"""
|
||
|
assumps = conjuncts(assumptions)
|
||
|
if expr.is_commutative is not None:
|
||
|
return expr.is_commutative and not ~Q.commutative(expr) in assumps
|
||
|
if Q.commutative(expr) in assumps:
|
||
|
return True
|
||
|
elif ~Q.commutative(expr) in assumps:
|
||
|
return False
|
||
|
return True
|
||
|
|
||
|
@CommutativePredicate.register(Basic)
|
||
|
def _(expr, assumptions):
|
||
|
for arg in expr.args:
|
||
|
if not ask(Q.commutative(arg), assumptions):
|
||
|
return False
|
||
|
return True
|
||
|
|
||
|
@CommutativePredicate.register(Number)
|
||
|
def _(expr, assumptions):
|
||
|
return True
|
||
|
|
||
|
@CommutativePredicate.register(NaN)
|
||
|
def _(expr, assumptions):
|
||
|
return True
|
||
|
|
||
|
|
||
|
# IsTruePredicate
|
||
|
|
||
|
@IsTruePredicate.register(bool)
|
||
|
def _(expr, assumptions):
|
||
|
return expr
|
||
|
|
||
|
@IsTruePredicate.register(BooleanTrue)
|
||
|
def _(expr, assumptions):
|
||
|
return True
|
||
|
|
||
|
@IsTruePredicate.register(BooleanFalse)
|
||
|
def _(expr, assumptions):
|
||
|
return False
|
||
|
|
||
|
@IsTruePredicate.register(AppliedPredicate)
|
||
|
def _(expr, assumptions):
|
||
|
return ask(expr, assumptions)
|
||
|
|
||
|
@IsTruePredicate.register(Not)
|
||
|
def _(expr, assumptions):
|
||
|
arg = expr.args[0]
|
||
|
if arg.is_Symbol:
|
||
|
# symbol used as abstract boolean object
|
||
|
return None
|
||
|
value = ask(arg, assumptions=assumptions)
|
||
|
if value in (True, False):
|
||
|
return not value
|
||
|
else:
|
||
|
return None
|
||
|
|
||
|
@IsTruePredicate.register(Or)
|
||
|
def _(expr, assumptions):
|
||
|
result = False
|
||
|
for arg in expr.args:
|
||
|
p = ask(arg, assumptions=assumptions)
|
||
|
if p is True:
|
||
|
return True
|
||
|
if p is None:
|
||
|
result = None
|
||
|
return result
|
||
|
|
||
|
@IsTruePredicate.register(And)
|
||
|
def _(expr, assumptions):
|
||
|
result = True
|
||
|
for arg in expr.args:
|
||
|
p = ask(arg, assumptions=assumptions)
|
||
|
if p is False:
|
||
|
return False
|
||
|
if p is None:
|
||
|
result = None
|
||
|
return result
|
||
|
|
||
|
@IsTruePredicate.register(Implies)
|
||
|
def _(expr, assumptions):
|
||
|
p, q = expr.args
|
||
|
return ask(~p | q, assumptions=assumptions)
|
||
|
|
||
|
@IsTruePredicate.register(Equivalent)
|
||
|
def _(expr, assumptions):
|
||
|
p, q = expr.args
|
||
|
pt = ask(p, assumptions=assumptions)
|
||
|
if pt is None:
|
||
|
return None
|
||
|
qt = ask(q, assumptions=assumptions)
|
||
|
if qt is None:
|
||
|
return None
|
||
|
return pt == qt
|
||
|
|
||
|
|
||
|
#### Helper methods
|
||
|
def test_closed_group(expr, assumptions, key):
|
||
|
"""
|
||
|
Test for membership in a group with respect
|
||
|
to the current operation.
|
||
|
"""
|
||
|
return _fuzzy_group(
|
||
|
(ask(key(a), assumptions) for a in expr.args), quick_exit=True)
|