'Return True if self == other, False if it doesn\'t, or None. If
failing_expression is True then the expression which did not simplify
to a 0 will be returned instead of None.
If ``self`` is a Number (or complex number) that is not zero, then
the result is False.
If ``self`` is a number and has not evaluated to zero, evalf will be
used to test whether the expression evaluates to zero. If it does so
and the result has significance (i.e. the precision is either -1, for
a Rational result, or is greater than 1) then the evalf value will be
used to return True or False.'

def equals(self, other, failing_expression=False):

    from sympy.simplify.simplify import nsimplify, simplify
    from sympy.solvers.solveset import solveset
    from sympy.polys.polyerrors import NotAlgebraic
    from sympy.polys.numberfields import minimal_polynomial
    other = sympify(other)
    if (self == other):
        return True
    diff = factor_terms(simplify((self - other)), radical=True)
    if (not diff):
        return True
    if (not diff.has(Add, Mod)):
        return False
    constant = diff.is_constant(simplify=False, failing_number=True)
    if (constant is False):
        return False
    if ((constant is None) and (diff.free_symbols or (not diff.is_number))):
        return
    if (constant is True):
        ndiff = diff._random()
        if ndiff:
            return False
    if diff.is_number:
        approx = diff.nsimplify()
        if (not approx):
            surds = [s for s in diff.atoms(Pow) if s.args[0].is_Integer]
            surds.sort(key=(lambda x: (- x.args[0])))
            for s in surds:
                try:
                    if s.is_Symbol:
                        sol = list(solveset(diff, s))
                    else:
                        sol = [s]
                    if sol:
                        if (s in sol):
                            return True
                        if s.is_real:
                            if any((((nsimplify(si, [s]) == s) and (simplify(si) == s)) for si in sol)):
                                return True
                except NotImplementedError:
                    pass
            if True:
                try:
                    mp = minimal_polynomial(diff)
                    if mp.is_Symbol:
                        return True
                    return False
                except (NotAlgebraic, NotImplementedError):
                    pass
    if ((constant not in (True, None)) and (constant != 0)):
        return False
    if failing_expression:
        return diff
    return None
