# Source code for sympy.core.relational

from expr import Expr
from evalf import EvalfMixin
from sympify import _sympify

[docs]def Rel(a, b, op):
"""
A handy wrapper around the Relational class.
Rel(a,b, op)

Example:
>>> from sympy import Rel
>>> from sympy.abc import x, y
>>> Rel(y, x+x**2, '==')
y == x**2 + x

"""
return Relational(a,b,op)

[docs]def Eq(a, b=0):
"""
A handy wrapper around the Relational class.
Eq(a,b)

Example:
>>> from sympy import Eq
>>> from sympy.abc import x, y
>>> Eq(y, x+x**2)
y == x**2 + x

"""
return Relational(a,b,'==')

[docs]def Ne(a, b):
"""
A handy wrapper around the Relational class.
Ne(a,b)

Example:
>>> from sympy import Ne
>>> from sympy.abc import x, y
>>> Ne(y, x+x**2)
y != x**2 + x

"""
return Relational(a,b,'!=')

[docs]def Lt(a, b):
"""
A handy wrapper around the Relational class.
Lt(a,b)

Example:
>>> from sympy import Lt
>>> from sympy.abc import x, y
>>> Lt(y, x+x**2)
y < x**2 + x

"""
return Relational(a,b,'<')

[docs]def Le(a, b):
"""
A handy wrapper around the Relational class.
Le(a,b)

Example:
>>> from sympy import Le
>>> from sympy.abc import x, y
>>> Le(y, x+x**2)
y <= x**2 + x

"""
return Relational(a,b,'<=')

[docs]def Gt(a, b):
"""
A handy wrapper around the Relational class.
Gt(a,b)

Example:
>>> from sympy import Gt
>>> from sympy.abc import x, y
>>> Gt(y, x+x**2)
x**2 + x < y

"""
return Relational(a,b,'>')

[docs]def Ge(a, b):
"""
A handy wrapper around the Relational class.
Ge(a,b)

Example:
>>> from sympy import Ge
>>> from sympy.abc import x, y
>>> Ge(y, x+x**2)
x**2 + x <= y

"""
return Relational(a,b,'>=')

class Relational(Expr, EvalfMixin):

__slots__ = []

is_Relational = True

@staticmethod
def get_relational_class(rop):
if rop is None or rop in ['==','eq']: return Equality, False
if rop in ['!=','<>','ne']: return Unequality, False
if rop in ['<','lt']: return StrictInequality, False
if rop in ['>','gt']: return StrictInequality, True
if rop in ['<=','le']: return Inequality, False
if rop in ['>=','ge']: return Inequality, True
raise ValueError("Invalid relational operator symbol: %r" % (rop))

def __new__(cls, lhs, rhs, rop=None, **assumptions):
lhs = _sympify(lhs)
rhs = _sympify(rhs)
if cls is not Relational:
rop_cls = cls
else:
rop_cls, swap = Relational.get_relational_class(rop)
if swap: lhs, rhs = rhs, lhs
if lhs.is_real and lhs.is_number and rhs.is_real and rhs.is_number:
# Just becase something is a number, doesn't mean you can evalf it.
Nlhs = lhs.evalf()
if Nlhs.is_Number:
# S.Zero.evalf() returns S.Zero, so test Number instead of Float
Nrhs = rhs.evalf()
if Nrhs.is_Number:
return rop_cls._eval_relation(Nlhs, Nrhs)

obj = Expr.__new__(rop_cls, lhs, rhs, **assumptions)
return obj

@property
def lhs(self):
return self._args[0]

@property
def rhs(self):
return self._args[1]

def _eval_subs(self, old, new):
if self == old:
return new
return self.__class__(self.lhs._eval_subs(old, new), self.rhs._eval_subs(old, new))

def _eval_evalf(self, prec):
return self.func(*[s._evalf(prec) for s in self.args])

[docs]class Equality(Relational):

rel_op = '=='

__slots__ = []

is_Equality = True

@classmethod
def _eval_relation(cls, lhs, rhs):
return lhs == rhs

def __nonzero__(self):
return self.lhs.compare(self.rhs)==0

[docs]class Unequality(Relational):

rel_op = '!='

__slots__ = []

@classmethod
def _eval_relation(cls, lhs, rhs):
return lhs != rhs

def __nonzero__(self):
return self.lhs.compare(self.rhs)!=0

[docs]class StrictInequality(Relational):

rel_op = '<'

__slots__ = []

@classmethod
def _eval_relation(cls, lhs, rhs):
return lhs < rhs

def __nonzero__(self):
return self.lhs.compare(self.rhs)==-1

[docs]class Inequality(Relational):

rel_op = '<='

__slots__ = []

@classmethod
def _eval_relation(cls, lhs, rhs):
return lhs <= rhs

def __nonzero__(self):
return self.lhs.compare(self.rhs)<=0