def __new__(cls, name, **assumptions): """Symbols are identified by name and assumptions:: >>> from sympy import Symbol >>> Symbol("x") == Symbol("x") True >>> Symbol("x", real=True) == Symbol("x", real=False) False """ if "dummy" in assumptions: SymPyDeprecationWarning( feature="Symbol('x', dummy=True)", useinstead="Dummy() or symbols(..., cls=Dummy)", issue=3378, deprecated_since_version="0.7.0", ).warn() if assumptions.pop("dummy"): return Dummy(name, **assumptions) if assumptions.get("zero", False): return S.Zero is_commutative = fuzzy_bool(assumptions.get("commutative", True)) if is_commutative is None: raise ValueError("""Symbol commutativity must be True or False.""") assumptions["commutative"] = is_commutative return Symbol.__xnew_cached_(cls, name, **assumptions)
def _sanitize(assumptions, obj=None): """Remove None, covert values to bool, check commutativity *in place*. """ # be strict about commutativity: cannot be None is_commutative = fuzzy_bool(assumptions.get('commutative', True)) if is_commutative is None: whose = '%s ' % obj.__name__ if obj else '' raise ValueError( '%scommutativity must be True or False.' % whose) # sanitize other assumptions so 1 -> True and 0 -> False for key in list(assumptions.keys()): from collections import defaultdict from sympy.utilities.exceptions import SymPyDeprecationWarning keymap = defaultdict(lambda: None) keymap.update({'bounded': 'finite', 'unbounded': 'infinite', 'infinitesimal': 'zero'}) if keymap[key]: SymPyDeprecationWarning( feature="%s assumption" % key, useinstead="%s" % keymap[key], issue=8071, deprecated_since_version="0.7.6").warn() assumptions[keymap[key]] = assumptions[key] assumptions.pop(key) key = keymap[key] v = assumptions[key] if v is None: assumptions.pop(key) continue assumptions[key] = bool(v)
def __new__(cls, name, **assumptions): """Symbols are identified by name and assumptions:: >>> from sympy import Symbol >>> Symbol("x") == Symbol("x") True >>> Symbol("x", real=True) == Symbol("x", real=False) False """ if 'dummy' in assumptions: SymPyDeprecationWarning( feature="Symbol('x', dummy=True)", useinstead="Dummy() or symbols(..., cls=Dummy)" ).warn() if assumptions.pop('dummy'): return Dummy(name, **assumptions) if assumptions.get('zero', False): return S.Zero is_commutative = fuzzy_bool(assumptions.get('commutative', True)) if is_commutative is None: raise ValueError( '''Symbol commutativity must be True or False.''') assumptions['commutative'] = is_commutative return Symbol.__xnew_cached_(cls, name, **assumptions)
def wrapper(*args, **kw_args): """ Assemble the args and kw_args to compute the hash. It is important that kw_args be standardized since if they have the same meaning but in different forms (e.g. one kw_arg having a value of 1 for an object and another object with identical args but a kw_arg of True) then two different hashes will be computed and the two objects will not be identical. """ if kw_args: keys = kw_args.keys() # make keywords all the same for k in keys: kw_args[k] = fuzzy_bool(kw_args[k]) keys.sort() items = [(k+'=', kw_args[k]) for k in keys] k = args + tuple(items) else: k = args k = k + tuple(map(lambda x: type(x), k)) try: return func_cache_it_cache[k] except KeyError: pass func_cache_it_cache[k] = r = func(*args, **kw_args) return r
def __new__(cls, name, exclude=(), properties=(), **assumptions): exclude = tuple([sympify(x) for x in exclude]) properties = tuple(properties) is_commutative = fuzzy_bool(assumptions.get("commutative", True)) if is_commutative is None: raise ValueError("""Wild's commutativity must be True or False.""") assumptions["commutative"] = is_commutative return Wild.__xnew__(cls, name, exclude, properties, **assumptions)
def pred(x): if x is S.ImaginaryUnit: return S.ImaginaryUnit polar = x.is_polar if polar: return True if polar is None: return fuzzy_bool(x.is_nonnegative)
def __new__(cls, sym, condition, base_set=S.UniversalSet): # nonlinsolve uses ConditionSet to return an unsolved system # of equations (see _return_conditionset in solveset) so until # that is changed we do minimal checking of the args if isinstance(sym, (Tuple, tuple)): # unsolved eqns syntax sym = Tuple(*sym) condition = FiniteSet(*condition) return Basic.__new__(cls, sym, condition, base_set) condition = as_Boolean(condition) if isinstance(base_set, set): base_set = FiniteSet(*base_set) elif not isinstance(base_set, Set): raise TypeError('expecting set for base_set') if condition is S.false: return S.EmptySet if condition is S.true: return base_set if isinstance(base_set, EmptySet): return base_set know = None if isinstance(base_set, FiniteSet): sifted = sift( base_set, lambda _: fuzzy_bool( condition.subs(sym, _))) if sifted[None]: know = FiniteSet(*sifted[True]) base_set = FiniteSet(*sifted[None]) else: return FiniteSet(*sifted[True]) if isinstance(base_set, cls): s, c, base_set = base_set.args if sym == s: condition = And(condition, c) elif sym not in c.free_symbols: condition = And(condition, c.xreplace({s: sym})) elif s not in condition.free_symbols: condition = And(condition.xreplace({sym: s}), c) sym = s else: # user will have to use cls.sym to get symbol dum = Symbol('lambda') if dum in condition.free_symbols or \ dum in c.free_symbols: dum = Dummy(str(dum)) condition = And( condition.xreplace({sym: dum}), c.xreplace({s: dum})) sym = dum if not isinstance(sym, Symbol): s = Dummy('lambda') if s not in condition.xreplace({sym: s}).free_symbols: raise ValueError( 'non-symbol dummy not recognized in condition') rv = Basic.__new__(cls, sym, condition, base_set) return rv if know is None else Union(know, rv)
def __new__(cls, name, **assumptions): if assumptions.get('zero', False): return S.Zero check_commutative = fuzzy_bool(assumptions.get('commutative', True)) if check_commutative is None: raise ValueError( '''commutativity symbol must take values eighter a True or False.''') assumptions['commutative'] = check_commutative for key in assumptions.keys(): assumptions[key] = bool(assumptions[key]) return sympy.Symbol.__xnew__(cls, name, uuid=str(int(round(1e16*random.random()))), **assumptions)
def encloses_point(self, p): """ Return True if p is enclosed by (is inside of) self. Notes ----- Being on the border of self is considered False. Parameters ========== p : Point Returns ======= encloses_point : True, False or None See Also ======== sympy.geometry.point.Point Examples ======== >>> from sympy import Ellipse, S >>> from sympy.abc import t >>> e = Ellipse((0, 0), 3, 2) >>> e.encloses_point((0, 0)) True >>> e.encloses_point(e.arbitrary_point(t).subs(t, S.Half)) False >>> e.encloses_point((4, 0)) False """ p = Point(p, dim=2) if p in self: return False if len(self.foci) == 2: # if the combined distance from the foci to p (h1 + h2) is less # than the combined distance from the foci to the minor axis # (which is the same as the major axis length) then p is inside # the ellipse h1, h2 = [f.distance(p) for f in self.foci] test = 2*self.major - (h1 + h2) else: test = self.radius - self.center.distance(p) return fuzzy_bool(test.is_positive)
def _eval_is_positive(self): arg = self.args[0] if arg.is_real: return True re, im = arg.as_real_imag() im_mod = im % (2*pi) if im_mod == 0: return True if re == 0: if im_mod < pi/2 or im_mod > 3*pi/2: return True elif im_mod >= pi/2 or im_mod <= 3*pi/2: return False return fuzzy_or([fuzzy_and([fuzzy_bool(Eq(re, 0)), fuzzy_or([fuzzy_bool(im_mod < pi/2), fuzzy_bool(im_mod > 3*pi/2)])]), fuzzy_bool(Eq(im_mod, 0))])
def _(mat, assumptions): rows, cols = mat.shape ret_val = True for i in range(rows): for j in range(i, cols): cond = fuzzy_bool(Eq(mat[i, j], -conjugate(mat[j, i]))) if cond == None: ret_val = None if cond == False: return False if ret_val is None: raise MDNotImplementedError return ret_val
def __new__(cls, name=None, **assumptions): if name is None: name = str(Dummy._count) is_commutative = fuzzy_bool(assumptions.get("commutative", True)) if is_commutative is None: raise ValueError("""Dummy's commutativity must be True or False.""") assumptions["commutative"] = is_commutative obj = Symbol.__xnew__(cls, name, **assumptions) Dummy._count += 1 obj.dummy_index = Dummy._count return obj
def __new__(cls, name, **assumptions): if assumptions.get('zero', False): return S.Zero is_commutative = fuzzy_bool(assumptions.get('commutative', True)) if is_commutative is None: raise ValueError( '''Symbol commutativity must be True or False.''') assumptions['commutative'] = is_commutative for key in assumptions.keys(): assumptions[key] = bool(assumptions[key]) return sympy.Symbol.__xnew__(cls, name, uuid=str(int(round(1e16 * random.random()))), **assumptions) # uuid.uuid1()
def __new__(cls, name=None, **assumptions): if name is None: name = "Dummy_" + str(Dummy._count) is_commutative = fuzzy_bool(assumptions.get('commutative', True)) if is_commutative is None: raise ValueError( '''Dummy's commutativity must be True or False.''') assumptions['commutative'] = is_commutative obj = Symbol.__xnew__(cls, name, **assumptions) Dummy._count += 1 obj.dummy_index = Dummy._count return obj
def __new__(cls, sym, condition, base_set): if condition == S.false: return S.EmptySet if condition == S.true: return base_set if isinstance(base_set, EmptySet): return base_set if isinstance(base_set, FiniteSet): sifted = sift(base_set, lambda _: fuzzy_bool(condition.subs(sym, _))) if sifted[None]: return Union(FiniteSet(*sifted[True]), Basic.__new__(cls, sym, condition, FiniteSet(*sifted[None]))) else: return FiniteSet(*sifted[True]) return Basic.__new__(cls, sym, condition, base_set)
def _eval_Eq(self, other): from sympy.core.function import AppliedUndef from sympy.core.logic import fuzzy_and, fuzzy_bool from sympy.core.relational import Eq if other.is_Symbol or isinstance(other, AppliedUndef): return None if not isinstance(other, Tuple) or len(self) != len(other): return S.false r = fuzzy_and(fuzzy_bool(Eq(s, o)) for s, o in zip(self, other)) if r is True: return S.true elif r is False: return S.false
def _sanitize(assumptions): """Remove None, covert values to bool, make sure commutativity is T/F""" # be strict about commutativity is_commutative = fuzzy_bool(assumptions.get('commutative', True)) if is_commutative is None: raise ValueError('%s commutativity must be True or False.' % cls.__name__) assumptions['commutative'] = is_commutative # sanitize other assumptions so 1 -> True and 0 -> False for key in list(assumptions.keys()): v = assumptions[key] if v is None: assumptions.pop(key) continue assumptions[key] = bool(v)
def _sanitize(assumptions, obj=None): """Remove None, covert values to bool, check commutativity *in place*. """ # be strict about commutativity: cannot be None is_commutative = fuzzy_bool(assumptions.get('commutative', True)) if is_commutative is None: whose = '%s ' % obj.__name__ if obj else '' raise ValueError('%scommutativity must be True or False.' % whose) # sanitize other assumptions so 1 -> True and 0 -> False for key in list(assumptions.keys()): v = assumptions[key] if v is None: assumptions.pop(key) continue assumptions[key] = bool(v)
def _sanitize(assumptions): """Remove None, covert values to bool, make sure commutativity is T/F""" # be strict about commutativity is_commutative = fuzzy_bool(assumptions.get('commutative', True)) if is_commutative is None: raise ValueError( '%s commutativity must be True or False.' % cls.__name__) assumptions['commutative'] = is_commutative # sanitize other assumptions so 1 -> True and 0 -> False for key in list(assumptions.keys()): v = assumptions[key] if v is None: assumptions.pop(key) continue assumptions[key] = bool(v)
def __new__(cls, name, **assumptions): """Symbols are identified by name and assumptions:: >>> from sympy import Symbol >>> Symbol("x") == Symbol("x") True >>> Symbol("x", real=True) == Symbol("x", real=False) False """ if assumptions.get('zero', False): return S.Zero is_commutative = fuzzy_bool(assumptions.get('commutative', True)) if is_commutative is None: raise ValueError('''Symbol commutativity must be True or False.''') assumptions['commutative'] = is_commutative return Symbol.__xnew_cached_(cls, name, **assumptions)
def __new__(cls, sym, condition, base_set): if condition == S.false: return S.EmptySet if condition == S.true: return base_set if isinstance(base_set, EmptySet): return base_set if isinstance(base_set, FiniteSet): sifted = sift(base_set, lambda _: fuzzy_bool(condition.subs(sym, _))) if sifted[None]: return Union( FiniteSet(*sifted[True]), Basic.__new__(cls, sym, condition, FiniteSet(*sifted[None]))) else: return FiniteSet(*sifted[True]) return Basic.__new__(cls, sym, condition, base_set)
def __new__(cls, name, **assumptions): """Symbols are identified by name and assumptions:: >>> from sympy import Symbol >>> Symbol("x") == Symbol("x") True >>> Symbol("x", real=True) == Symbol("x", real=False) False """ is_commutative = fuzzy_bool(assumptions.get('commutative', True)) if is_commutative is None: raise ValueError( '''Symbol commutativity must be True or False.''') assumptions['commutative'] = is_commutative for key in assumptions.keys(): assumptions[key] = bool(assumptions[key]) return Symbol.__xnew_cached_(cls, name, **assumptions)
def _sanitize(assumptions, obj=None): """Remove None, covert values to bool, check commutativity *in place*. """ # be strict about commutativity is_commutative = fuzzy_bool(assumptions.get('commutative', True)) if is_commutative is None: whose = '%s ' % obj.__name__ if obj else '' raise ValueError( '%scommutativity must be True or False.' % whose) assumptions['commutative'] = is_commutative # sanitize other assumptions so 1 -> True and 0 -> False for key in list(assumptions.keys()): v = assumptions[key] if v is None: assumptions.pop(key) continue assumptions[key] = bool(v)
def __new_stage2__(cls, name, **assumptions): if not isinstance(name, string_types): raise TypeError("name should be a string, not %s" % repr(type(name))) obj = Expr.__new__(cls) obj.name = name # TODO: Issue #8873: Forcing the commutative assumption here means # later code such as ``srepr()`` cannot tell whether the user # specified ``commutative=True`` or omitted it. To workaround this, # we keep a copy of the assumptions dict, then create the StdFactKB, # and finally overwrite its ``._generator`` with the dict copy. This # is a bit of a hack because we assume StdFactKB merely copies the # given dict as ``._generator``, but future modification might, e.g., # compute a minimal equivalent assumption set. tmp_asm_copy = assumptions.copy() # be strict about commutativity is_commutative = fuzzy_bool(assumptions.get('commutative', True)) assumptions['commutative'] = is_commutative obj._assumptions = StdFactKB(assumptions) obj._assumptions._generator = tmp_asm_copy # Issue #8873 return obj
def _sanitize(assumptions, obj=None): """Remove None, covert values to bool, check commutativity *in place*. """ # be strict about commutativity is_commutative = fuzzy_bool(assumptions.get('commutative', True)) if is_commutative is None: whose = '%s ' % obj.__name__ if obj else '' raise ValueError('%scommutativity must be True or False.' % whose) assumptions['commutative'] = is_commutative # sanitize other assumptions so 1 -> True and 0 -> False for key in list(assumptions.keys()): from collections import defaultdict from sympy.utilities.exceptions import SymPyDeprecationWarning keymap = defaultdict(lambda: None) keymap.update({ 'bounded': 'finite', 'unbounded': 'infinite', 'infinitesimal': 'zero' }) if keymap[key]: SymPyDeprecationWarning( feature="%s assumption" % key, useinstead="%s" % keymap[key], issue=8071, deprecated_since_version="0.7.6").warn() assumptions[keymap[key]] = assumptions[key] assumptions.pop(key) key = keymap[key] v = assumptions[key] if v is None: assumptions.pop(key) continue assumptions[key] = bool(v)
def __new__(cls, name, **assumptions): """Symbols are identified by name and assumptions:: >>> from sympy import Symbol >>> Symbol("x") == Symbol("x") True >>> Symbol("x", real=True) == Symbol("x", real=False) False """ if 'dummy' in assumptions: SymPyDeprecationWarning( feature="Symbol('x', dummy=True)", useinstead="Dummy() or symbols(..., cls=Dummy)").warn() if assumptions.pop('dummy'): return Dummy(name, **assumptions) if assumptions.get('zero', False): return S.Zero is_commutative = fuzzy_bool(assumptions.get('commutative', True)) if is_commutative is None: raise ValueError('''Symbol commutativity must be True or False.''') assumptions['commutative'] = is_commutative return Symbol.__xnew_cached_(cls, name, **assumptions)
def _eval_is_eq(lhs, rhs): # noqa:F811 if len(lhs) != len(rhs): return False return fuzzy_and(fuzzy_bool(is_eq(s, o)) for s, o in zip(lhs, rhs))
def is_eq(lhs, rhs, assumptions=None): """ Fuzzy bool representing mathematical equality between *lhs* and *rhs*. Parameters ========== lhs : Expr The left-hand side of the expression, must be sympified. rhs : Expr The right-hand side of the expression, must be sympified. assumptions: Boolean, optional Assumptions taken to evaluate the equality. Returns ======= ``True`` if *lhs* is equal to *rhs*, ``False`` is *lhs* is not equal to *rhs*, and ``None`` if the comparison between *lhs* and *rhs* is indeterminate. Explanation =========== This function is intended to give a relatively fast determination and deliberately does not attempt slow calculations that might help in obtaining a determination of True or False in more difficult cases. :func:`~.is_neq` calls this function to return its value, so supporting new type with this function will ensure correct behavior for ``is_neq`` as well. Examples ======== >>> from sympy import Q, S >>> from sympy.core.relational import is_eq, is_neq >>> from sympy.abc import x >>> is_eq(S(0), S(0)) True >>> is_neq(S(0), S(0)) False >>> is_eq(S(0), S(2)) False >>> is_neq(S(0), S(2)) True Assumptions can be passed to evaluate the equality which is otherwise indeterminate. >>> print(is_eq(x, S(0))) None >>> is_eq(x, S(0), assumptions=Q.zero(x)) True New types can be supported by dispatching to ``_eval_is_eq``. >>> from sympy import Basic, sympify >>> from sympy.multipledispatch import dispatch >>> class MyBasic(Basic): ... def __new__(cls, arg): ... return Basic.__new__(cls, sympify(arg)) ... @property ... def value(self): ... return self.args[0] ... >>> @dispatch(MyBasic, MyBasic) ... def _eval_is_eq(a, b): ... return is_eq(a.value, b.value) ... >>> a = MyBasic(1) >>> b = MyBasic(1) >>> is_eq(a, b) True >>> is_neq(a, b) False """ from sympy.assumptions.wrapper import (AssumptionsWrapper, is_infinite, is_extended_real) from sympy.core.add import Add from sympy.functions.elementary.complexes import arg from sympy.simplify.simplify import clear_coefficients from sympy.utilities.iterables import sift # here, _eval_Eq is only called for backwards compatibility # new code should use is_eq with multiple dispatch as # outlined in the docstring for side1, side2 in (lhs, rhs), (rhs, lhs): eval_func = getattr(side1, '_eval_Eq', None) if eval_func is not None: retval = eval_func(side2) if retval is not None: return retval retval = _eval_is_eq(lhs, rhs) if retval is not None: return retval if dispatch(type(lhs), type(rhs)) != dispatch(type(rhs), type(lhs)): retval = _eval_is_eq(rhs, lhs) if retval is not None: return retval # retval is still None, so go through the equality logic # If expressions have the same structure, they must be equal. if lhs == rhs: return True # e.g. True == True elif all(isinstance(i, BooleanAtom) for i in (rhs, lhs)): return False # True != False elif not (lhs.is_Symbol or rhs.is_Symbol) and (isinstance(lhs, Boolean) != isinstance(rhs, Boolean)): return False # only Booleans can equal Booleans _lhs = AssumptionsWrapper(lhs, assumptions) _rhs = AssumptionsWrapper(rhs, assumptions) if _lhs.is_infinite or _rhs.is_infinite: if fuzzy_xor([_lhs.is_infinite, _rhs.is_infinite]): return False if fuzzy_xor([_lhs.is_extended_real, _rhs.is_extended_real]): return False if fuzzy_and([_lhs.is_extended_real, _rhs.is_extended_real]): return fuzzy_xor([ _lhs.is_extended_positive, fuzzy_not(_rhs.is_extended_positive) ]) # Try to split real/imaginary parts and equate them I = S.ImaginaryUnit def split_real_imag(expr): real_imag = lambda t: ( 'real' if is_extended_real(t, assumptions) else 'imag' if is_extended_real(I * t, assumptions) else None) return sift(Add.make_args(expr), real_imag) lhs_ri = split_real_imag(lhs) if not lhs_ri[None]: rhs_ri = split_real_imag(rhs) if not rhs_ri[None]: eq_real = is_eq(Add(*lhs_ri['real']), Add(*rhs_ri['real']), assumptions) eq_imag = is_eq(I * Add(*lhs_ri['imag']), I * Add(*rhs_ri['imag']), assumptions) return fuzzy_and(map(fuzzy_bool, [eq_real, eq_imag])) # Compare e.g. zoo with 1+I*oo by comparing args arglhs = arg(lhs) argrhs = arg(rhs) # Guard against Eq(nan, nan) -> Falsesymp if not (arglhs == S.NaN and argrhs == S.NaN): return fuzzy_bool(is_eq(arglhs, argrhs, assumptions)) if all(isinstance(i, Expr) for i in (lhs, rhs)): # see if the difference evaluates dif = lhs - rhs _dif = AssumptionsWrapper(dif, assumptions) z = _dif.is_zero if z is not None: if z is False and _dif.is_commutative: # issue 10728 return False if z: return True n2 = _n2(lhs, rhs) if n2 is not None: return _sympify(n2 == 0) # see if the ratio evaluates n, d = dif.as_numer_denom() rv = None _n = AssumptionsWrapper(n, assumptions) _d = AssumptionsWrapper(d, assumptions) if _n.is_zero: rv = _d.is_nonzero elif _n.is_finite: if _d.is_infinite: rv = True elif _n.is_zero is False: rv = _d.is_infinite if rv is None: # if the condition that makes the denominator # infinite does not make the original expression # True then False can be returned l, r = clear_coefficients(d, S.Infinity) args = [_.subs(l, r) for _ in (lhs, rhs)] if args != [lhs, rhs]: rv = fuzzy_bool(is_eq(*args, assumptions)) if rv is True: rv = None elif any(is_infinite(a, assumptions) for a in Add.make_args(n)): # (inf or nan)/x != 0 rv = False if rv is not None: return rv
def _contains(self, other): if not isinstance(other, Set): return None return fuzzy_bool(self.arg.is_superset(other))
def __new__(cls, sym, condition, base_set=S.UniversalSet): # nonlinsolve uses ConditionSet to return an unsolved system # of equations (see _return_conditionset in solveset) so until # that is changed we do minimal checking of the args sym = _sympify(sym) base_set = _sympify(base_set) condition = _sympify(condition) if isinstance(condition, FiniteSet): condition_orig = condition temp = (Eq(lhs, 0) for lhs in condition) condition = And(*temp) SymPyDeprecationWarning( feature="Using {} for condition".format(condition_orig), issue=17651, deprecated_since_version="1.5", useinstead="{} for condition".format(condition), ).warn() condition = as_Boolean(condition) if isinstance(sym, Tuple): # unsolved eqns syntax return Basic.__new__(cls, sym, condition, base_set) if not isinstance(base_set, Set): raise TypeError("expecting set for base_set") if condition is S.false: return S.EmptySet elif condition is S.true: return base_set if isinstance(base_set, EmptySet): return base_set know = None if isinstance(base_set, FiniteSet): sifted = sift(base_set, lambda _: fuzzy_bool(condition.subs(sym, _))) if sifted[None]: know = FiniteSet(*sifted[True]) base_set = FiniteSet(*sifted[None]) else: return FiniteSet(*sifted[True]) if isinstance(base_set, cls): s, c, base_set = base_set.args if sym == s: condition = And(condition, c) elif sym not in c.free_symbols: condition = And(condition, c.xreplace({s: sym})) elif s not in condition.free_symbols: condition = And(condition.xreplace({sym: s}), c) sym = s else: # user will have to use cls.sym to get symbol dum = Symbol("lambda") if dum in condition.free_symbols or dum in c.free_symbols: dum = Dummy(str(dum)) condition = And(condition.xreplace({sym: dum}), c.xreplace({s: dum})) sym = dum if not isinstance(sym, Symbol): s = Dummy("lambda") if s not in condition.xreplace({sym: s}).free_symbols: raise ValueError( "non-symbol dummy not recognized in condition") rv = Basic.__new__(cls, sym, condition, base_set) return rv if know is None else Union(know, rv)
def __new__(cls, lhs, rhs=None, **options): from sympy.core.add import Add from sympy.core.containers import Tuple from sympy.core.logic import fuzzy_bool, fuzzy_xor, fuzzy_and, fuzzy_not from sympy.core.expr import _n2 from sympy.functions.elementary.complexes import arg from sympy.simplify.simplify import clear_coefficients from sympy.utilities.iterables import sift if rhs is None: SymPyDeprecationWarning(feature="Eq(expr) with rhs default to 0", useinstead="Eq(expr, 0)", issue=16587, deprecated_since_version="1.5").warn() rhs = 0 lhs = _sympify(lhs) rhs = _sympify(rhs) evaluate = options.pop('evaluate', global_parameters.evaluate) if evaluate: # If one expression has an _eval_Eq, return its results. if hasattr(lhs, '_eval_Eq'): r = lhs._eval_Eq(rhs) if r is not None: return r if hasattr(rhs, '_eval_Eq'): r = rhs._eval_Eq(lhs) if r is not None: return r # If expressions have the same structure, they must be equal. if lhs == rhs: return S.true # e.g. True == True elif all(isinstance(i, BooleanAtom) for i in (rhs, lhs)): return S.false # True != False elif not (lhs.is_Symbol or rhs.is_Symbol) and (isinstance( lhs, Boolean) != isinstance(rhs, Boolean)): return S.false # only Booleans can equal Booleans if lhs.is_infinite or rhs.is_infinite: if fuzzy_xor([lhs.is_infinite, rhs.is_infinite]): return S.false if fuzzy_xor([lhs.is_extended_real, rhs.is_extended_real]): return S.false if fuzzy_and([lhs.is_extended_real, rhs.is_extended_real]): r = fuzzy_xor([ lhs.is_extended_positive, fuzzy_not(rhs.is_extended_positive) ]) return S(r) # Try to split real/imaginary parts and equate them I = S.ImaginaryUnit def split_real_imag(expr): real_imag = lambda t: ('real' if t.is_extended_real else 'imag' if (I * t).is_extended_real else None) return sift(Add.make_args(expr), real_imag) lhs_ri = split_real_imag(lhs) if not lhs_ri[None]: rhs_ri = split_real_imag(rhs) if not rhs_ri[None]: eq_real = Eq(Add(*lhs_ri['real']), Add(*rhs_ri['real'])) eq_imag = Eq(I * Add(*lhs_ri['imag']), I * Add(*rhs_ri['imag'])) res = fuzzy_and(map(fuzzy_bool, [eq_real, eq_imag])) if res is not None: return S(res) # Compare e.g. zoo with 1+I*oo by comparing args arglhs = arg(lhs) argrhs = arg(rhs) # Guard against Eq(nan, nan) -> False if not (arglhs == S.NaN and argrhs == S.NaN): res = fuzzy_bool(Eq(arglhs, argrhs)) if res is not None: return S(res) return Relational.__new__(cls, lhs, rhs, **options) if all(isinstance(i, Expr) for i in (lhs, rhs)): # see if the difference evaluates dif = lhs - rhs z = dif.is_zero if z is not None: if z is False and dif.is_commutative: # issue 10728 return S.false if z: return S.true # evaluate numerically if possible n2 = _n2(lhs, rhs) if n2 is not None: return _sympify(n2 == 0) # see if the ratio evaluates n, d = dif.as_numer_denom() rv = None if n.is_zero: rv = d.is_nonzero elif n.is_finite: if d.is_infinite: rv = S.true elif n.is_zero is False: rv = d.is_infinite if rv is None: # if the condition that makes the denominator # infinite does not make the original expression # True then False can be returned l, r = clear_coefficients(d, S.Infinity) args = [_.subs(l, r) for _ in (lhs, rhs)] if args != [lhs, rhs]: rv = fuzzy_bool(Eq(*args)) if rv is True: rv = None elif any(a.is_infinite for a in Add.make_args(n)): # (inf or nan)/x != 0 rv = S.false if rv is not None: return _sympify(rv) return Relational.__new__(cls, lhs, rhs, **options)
def is_eq(lhs, rhs): """ Fuzzy bool representing mathematical equality between lhs and rhs. Parameters ========== lhs: Expr The left-hand side of the expression, must be sympified. rhs: Expr The right-hand side of the expression, must be sympified. Returns ======= True if lhs is equal to rhs, false is lhs is not equal to rhs, and None if the comparison between lhs and rhs is indeterminate. Explanation =========== This function is intended to give a relatively fast determination and deliberately does not attempt slow calculations that might help in obtaining a determination of True or False in more difficult cases. InEquality classes, such as Lt, Gt, etc. Use one of is_ge, is_le, etc. To implement comparisons with ``Gt(a, b)`` or ``a > b`` etc for an ``Expr`` subclass it is only necessary to define a dispatcher method for ``_eval_is_ge`` like >>> from sympy.core.relational import is_eq >>> from sympy.core.relational import is_neq >>> from sympy import S, Basic, Eq, sympify >>> from sympy.abc import x >>> from sympy.multipledispatch import dispatch >>> class MyBasic(Basic): ... def __new__(cls, arg): ... return Basic.__new__(cls, sympify(arg)) ... @property ... def value(self): ... return self.args[0] ... >>> @dispatch(MyBasic, MyBasic) ... def _eval_is_eq(a, b): ... return is_eq(a.value, b.value) ... >>> a = MyBasic(1) >>> b = MyBasic(1) >>> a == b True >>> Eq(a, b) True >>> a != b False >>> is_eq(a, b) True Examples ======== >>> is_eq(S(0), S(0)) True >>> Eq(0, 0) True >>> is_neq(S(0), S(0)) False >>> is_eq(S(0), S(2)) False >>> Eq(0, 2) False >>> is_neq(S(0), S(2)) True >>> is_eq(S(0), x) >>> Eq(S(0), x) Eq(0, x) """ from sympy.core.add import Add from sympy.functions.elementary.complexes import arg from sympy.simplify.simplify import clear_coefficients from sympy.utilities.iterables import sift # here, _eval_Eq is only called for backwards compatibility # new code should use is_eq with multiple dispatch as # outlined in the docstring for side1, side2 in (lhs, rhs), (rhs, lhs): eval_func = getattr(side1, '_eval_Eq', None) if eval_func is not None: retval = eval_func(side2) if retval is not None: return retval retval = _eval_is_eq(lhs, rhs) if retval is not None: return retval if dispatch(type(lhs), type(rhs)) != dispatch(type(rhs), type(lhs)): retval = _eval_is_eq(rhs, lhs) if retval is not None: return retval # retval is still None, so go through the equality logic # If expressions have the same structure, they must be equal. if lhs == rhs: return True # e.g. True == True elif all(isinstance(i, BooleanAtom) for i in (rhs, lhs)): return False # True != False elif not (lhs.is_Symbol or rhs.is_Symbol) and (isinstance(lhs, Boolean) != isinstance(rhs, Boolean)): return False # only Booleans can equal Booleans if lhs.is_infinite or rhs.is_infinite: if fuzzy_xor([lhs.is_infinite, rhs.is_infinite]): return False if fuzzy_xor([lhs.is_extended_real, rhs.is_extended_real]): return False if fuzzy_and([lhs.is_extended_real, rhs.is_extended_real]): return fuzzy_xor([ lhs.is_extended_positive, fuzzy_not(rhs.is_extended_positive) ]) # Try to split real/imaginary parts and equate them I = S.ImaginaryUnit def split_real_imag(expr): real_imag = lambda t: ('real' if t.is_extended_real else 'imag' if (I * t).is_extended_real else None) return sift(Add.make_args(expr), real_imag) lhs_ri = split_real_imag(lhs) if not lhs_ri[None]: rhs_ri = split_real_imag(rhs) if not rhs_ri[None]: eq_real = Eq(Add(*lhs_ri['real']), Add(*rhs_ri['real'])) eq_imag = Eq(I * Add(*lhs_ri['imag']), I * Add(*rhs_ri['imag'])) return fuzzy_and(map(fuzzy_bool, [eq_real, eq_imag])) # Compare e.g. zoo with 1+I*oo by comparing args arglhs = arg(lhs) argrhs = arg(rhs) # Guard against Eq(nan, nan) -> Falsesymp if not (arglhs == S.NaN and argrhs == S.NaN): return fuzzy_bool(Eq(arglhs, argrhs)) if all(isinstance(i, Expr) for i in (lhs, rhs)): # see if the difference evaluates dif = lhs - rhs z = dif.is_zero if z is not None: if z is False and dif.is_commutative: # issue 10728 return False if z: return True n2 = _n2(lhs, rhs) if n2 is not None: return _sympify(n2 == 0) # see if the ratio evaluates n, d = dif.as_numer_denom() rv = None if n.is_zero: rv = d.is_nonzero elif n.is_finite: if d.is_infinite: rv = True elif n.is_zero is False: rv = d.is_infinite if rv is None: # if the condition that makes the denominator # infinite does not make the original expression # True then False can be returned l, r = clear_coefficients(d, S.Infinity) args = [_.subs(l, r) for _ in (lhs, rhs)] if args != [lhs, rhs]: rv = fuzzy_bool(Eq(*args)) if rv is True: rv = None elif any(a.is_infinite for a in Add.make_args(n)): # (inf or nan)/x != 0 rv = False if rv is not None: return rv
def __new__(cls, sym, condition, base_set=S.UniversalSet): from sympy.core.function import BadSignatureError from sympy.utilities.iterables import flatten, has_dups sym = _sympify(sym) flat = flatten([sym]) if has_dups(flat): raise BadSignatureError("Duplicate symbols detected") base_set = _sympify(base_set) if not isinstance(base_set, Set): raise TypeError('base set should be a Set object, not %s' % base_set) condition = _sympify(condition) if isinstance(condition, FiniteSet): condition_orig = condition temp = (Eq(lhs, 0) for lhs in condition) condition = And(*temp) SymPyDeprecationWarning( feature="Using {} for condition".format(condition_orig), issue=17651, deprecated_since_version='1.5', useinstead="{} for condition".format(condition)).warn() condition = as_Boolean(condition) if condition is S.true: return base_set if condition is S.false: return S.EmptySet if isinstance(base_set, EmptySet): return base_set # no simple answers, so now check syms for i in flat: if not getattr(i, '_diff_wrt', False): raise ValueError('`%s` is not symbol-like' % i) if base_set.contains(sym) is S.false: raise TypeError('sym `%s` is not in base_set `%s`' % (sym, base_set)) know = None if isinstance(base_set, FiniteSet): sifted = sift(base_set, lambda _: fuzzy_bool(condition.subs(sym, _))) if sifted[None]: know = FiniteSet(*sifted[True]) base_set = FiniteSet(*sifted[None]) else: return FiniteSet(*sifted[True]) if isinstance(base_set, cls): s, c, b = base_set.args def sig(s): return cls(s, Eq(adummy, 0)).as_dummy().sym sa, sb = map(sig, (sym, s)) if sa != sb: raise BadSignatureError('sym does not match sym of base set') reps = dict(zip(flatten([sym]), flatten([s]))) if s == sym: condition = And(condition, c) base_set = b elif not c.free_symbols & sym.free_symbols: reps = {v: k for k, v in reps.items()} condition = And(condition, c.xreplace(reps)) base_set = b elif not condition.free_symbols & s.free_symbols: sym = sym.xreplace(reps) condition = And(condition.xreplace(reps), c) base_set = b # flatten ConditionSet(Contains(ConditionSet())) expressions if isinstance(condition, Contains) and (sym == condition.args[0]): if isinstance(condition.args[1], Set): return condition.args[1].intersect(base_set) rv = Basic.__new__(cls, sym, condition, base_set) return rv if know is None else Union(know, rv)
def __new__(cls, lhs, rhs=0, **options): from sympy.core.add import Add from sympy.core.logic import fuzzy_bool from sympy.core.expr import _n2 from sympy.simplify.simplify import clear_coefficients lhs = _sympify(lhs) rhs = _sympify(rhs) evaluate = options.pop('evaluate', global_evaluate[0]) if evaluate: # If one expression has an _eval_Eq, return its results. if hasattr(lhs, '_eval_Eq'): r = lhs._eval_Eq(rhs) if r is not None: return r if hasattr(rhs, '_eval_Eq'): r = rhs._eval_Eq(lhs) if r is not None: return r # If expressions have the same structure, they must be equal. if lhs == rhs: return S.true # e.g. True == True elif all(isinstance(i, BooleanAtom) for i in (rhs, lhs)): return S.false # True != False elif not (lhs.is_Symbol or rhs.is_Symbol) and (isinstance( lhs, Boolean) != isinstance(rhs, Boolean)): return S.false # only Booleans can equal Booleans # check finiteness fin = L, R = [i.is_finite for i in (lhs, rhs)] if None not in fin: if L != R: return S.false if L is False: if lhs == -rhs: # Eq(oo, -oo) return S.false return S.true elif None in fin and False in fin: return Relational.__new__(cls, lhs, rhs, **options) if all(isinstance(i, Expr) for i in (lhs, rhs)): # see if the difference evaluates dif = lhs - rhs z = dif.is_zero if z is not None: if z is False and dif.is_commutative: # issue 10728 return S.false if z: return S.true # evaluate numerically if possible n2 = _n2(lhs, rhs) if n2 is not None: return _sympify(n2 == 0) # see if the ratio evaluates n, d = dif.as_numer_denom() rv = None if n.is_zero: rv = d.is_nonzero elif n.is_finite: if d.is_infinite: rv = S.true elif n.is_zero is False: rv = d.is_infinite if rv is None: # if the condition that makes the denominator infinite does not # make the original expression True then False can be returned l, r = clear_coefficients(d, S.Infinity) args = [_.subs(l, r) for _ in (lhs, rhs)] if args != [lhs, rhs]: rv = fuzzy_bool(Eq(*args)) if rv is True: rv = None elif any(a.is_infinite for a in Add.make_args(n)): # (inf or nan)/x != 0 rv = S.false if rv is not None: return _sympify(rv) return Relational.__new__(cls, lhs, rhs, **options)
def __new__(cls, lhs, rhs=0, **options): from sympy.core.add import Add from sympy.core.logic import fuzzy_bool from sympy.core.expr import _n2 from sympy.simplify.simplify import clear_coefficients lhs = _sympify(lhs) rhs = _sympify(rhs) evaluate = options.pop('evaluate', global_evaluate[0]) if evaluate: # If one expression has an _eval_Eq, return its results. if hasattr(lhs, '_eval_Eq'): r = lhs._eval_Eq(rhs) if r is not None: return r if hasattr(rhs, '_eval_Eq'): r = rhs._eval_Eq(lhs) if r is not None: return r # If expressions have the same structure, they must be equal. if lhs == rhs: return S.true elif all(isinstance(i, BooleanAtom) for i in (rhs, lhs)): return S.false # check finiteness fin = L, R = [i.is_finite for i in (lhs, rhs)] if None not in fin: if L != R: return S.false if L is False: if lhs == -rhs: # Eq(oo, -oo) return S.false return S.true elif None in fin and False in fin: return Relational.__new__(cls, lhs, rhs, **options) if all(isinstance(i, Expr) for i in (lhs, rhs)): # see if the difference evaluates dif = lhs - rhs z = dif.is_zero if z is not None: if z is False and dif.is_commutative: # issue 10728 return S.false if z: return S.true # evaluate numerically if possible n2 = _n2(lhs, rhs) if n2 is not None: return _sympify(n2 == 0) # see if the ratio evaluates n, d = dif.as_numer_denom() rv = None if n.is_zero: rv = d.is_nonzero elif n.is_finite: if d.is_infinite: rv = S.true elif n.is_zero is False: rv = d.is_infinite if rv is None: # if the condition that makes the denominator infinite does not # make the original expression True then False can be returned l, r = clear_coefficients(d, S.Infinity) args = [_.subs(l, r) for _ in (lhs, rhs)] if args != [lhs, rhs]: rv = fuzzy_bool(Eq(*args)) if rv is True: rv = None elif any(a.is_infinite for a in Add.make_args(n)): # (inf or nan)/x != 0 rv = S.false if rv is not None: return _sympify(rv) return Relational.__new__(cls, lhs, rhs, **options)
def _(a, b): if a.step == b.step == 1: return fuzzy_and( [fuzzy_bool(a.start >= b.start), fuzzy_bool(a.stop <= b.stop)])
def is_subset_sets(a, b): # noqa:F811 if a.step == b.step == 1: return fuzzy_and( [fuzzy_bool(a.start >= b.start), fuzzy_bool(a.stop <= b.stop)])