from __future__ import division

from sympy import (Symbol, sin, cos, exp, O, sqrt, Rational, Float, re, pi,
        sympify, Add, Mul, Pow, Mod, I, log, S, Max, Or, symbols, oo, Integer,
        Tuple)
from sympy.utilities.pytest import XFAIL, raises

x = Symbol('x')
y = Symbol('y')
z = Symbol('z')

def test_bug1():
    assert re(x) != x
    x.series(x,0,1)
    assert re(x) != x

a = Symbol("a")
b = Symbol("b", positive=True)
c = Symbol("c")

def test_Symbol():
    e=a*b
    assert e==a*b
    assert a*b*b==a*b**2
    assert a*b*b+c==c+a*b**2
    assert a*b*b-c==-c+a*b**2

def test_arit0():
    p = Rational(5)
    e=a*b
    assert e == a*b
    e=a*b+b*a
    assert e == 2*a*b
    e=a*b+b*a+a*b+p*b*a
    assert e == 8*a*b
    e=a*b+b*a+a*b+p*b*a+a
    assert e == a+8*a*b
    e=a+a
    assert e == 2*a
    e=a+b+a
    assert e == b+2*a
    e=a+b*b+a+b*b
    assert e == 2*a+2*b**2
    e=a+Rational(2)+b*b+a+b*b+p
    assert e == 7+2*a+2*b**2
    e=(a+b*b+a+b*b)*p
    assert e == 5*(2*a+2*b**2)
    e=(a*b*c+c*b*a+b*a*c)*p
    assert e == 15*a*b*c
    e=(a*b*c+c*b*a+b*a*c)*p-Rational(15)*a*b*c
    assert e == Rational(0)
    e = Rational(50)*(a-a)
    assert e == Rational(0)
    e=b*a-b-a*b+b
    assert e == Rational(0)
    e=a*b+c**p
    assert e == a*b+c**5
    e=a/b
    assert e == a*b**(-1)
    e=a*2*2
    assert e == 4*a
    e=2+a*2/2
    assert e == 2+a
    e=2-a-2
    assert e == -a
    e=2*a*2
    assert e == 4*a
    e=2/a/2
    assert e == a**(-1)
    e=2**a**2
    assert e == 2**(a**2)
    e = -(1+a)
    assert e == -1 -a
    e = Rational(1,2)*(1+a)
    assert e == Rational(1,2) + a/2

def test_div():
    e=a/b
    assert e == a*b**(-1)
    e=a/b+c/2
    assert e == a*b**(-1)+Rational(1)/2*c
    e=(1-b)/(b-1)
    assert e == (1+-b)*((-1)+b)**(-1)

def test_pow():
    n1 = Rational(1)
    n2 = Rational(2)
    n5 = Rational(5)
    e=a*a
    assert e == a**2
    e=a*a*a
    assert e == a**3
    e=a*a*a*a**Rational(6)
    assert e == a**9
    e=a*a*a*a**Rational(6)-a**Rational(9)
    assert e == Rational(0)
    e=a**(b-b)
    assert e == Rational(1)
    e=(a-a)**b
    assert e == Rational(0)
    e=(a+Rational(1)-a)**b
    assert e == Rational(1)

    e=(a+b+c)**n2
    assert e == (a+b+c)**2
    assert e.expand() == 2*b*c+2*a*c+2*a*b+a**2+c**2+b**2

    e=(a+b)**n2
    assert e == (a+b)**2
    assert e.expand() == 2*a*b+a**2+b**2

    e=(a+b)**(n1/n2)
    assert e == sqrt(a+b)
    assert e.expand() == sqrt(a+b)

    n=n5**(n1/n2)
    assert n == sqrt(5)
    e=n*a*b-n*b*a
    assert e == Rational(0)
    e=n*a*b+n*b*a
    assert e == 2*a*b*sqrt(5)
    assert e.diff(a) == 2*b*sqrt(5)
    assert e.diff(a) == 2*b*sqrt(5)
    e=a/b**2
    assert e == a*b**(-2)

    assert sqrt(2*(1+sqrt(2))) == (2*(1+2**Rational(1,2)))**Rational(1,2)

    x = Symbol('x')
    y = Symbol('y')

    assert ((x*y)**3).expand() == y**3 * x**3
    assert ((x*y)**-3).expand() == y**-3 * x**-3

    assert (x**5*(3*x)**(3)).expand() == 27 * x**8
    assert (x**5*(-3*x)**(3)).expand() == -27 * x**8
    assert (x**5*(3*x)**(-3)).expand() == Rational(1,27) * x**2
    assert (x**5*(-3*x)**(-3)).expand() == -Rational(1,27) * x**2

    # expand_power_exp
    assert (x**(y**(x+exp(x+y))+z)).expand(deep=False) == x**z*x**(y**(x + exp(x + y)))
    assert (x**(y**(x+exp(x+y))+z)).expand() == x**z*x**(y**x*y**(exp(x)*exp(y)))

    n = Symbol('k', even=False)
    k = Symbol('k', even=True)

    assert (-1)**x == (-1)**x
    assert (-1)**n == (-1)**n
    assert (-2)**k == 2**k
    assert (-2*x)**k == 2**k*x**k
    assert (-1)**k == 1

def test_pow2():
    # x**(2*y) is always (x**y)**2 but is only (x**2)**y if
    #                                  x.is_positive or y.is_integer
    # let x = 1 to see why the following are not true.
    assert ((-x)**2)**Rational(1,3) != ((-x)**Rational(1,3))**2
    assert (-x)**Rational(2,3) != x**Rational(2,3)
    assert (-x)**Rational(5,7) != -x**Rational(5,7)

def test_pow3():
    assert sqrt(2)**3 == 2 * sqrt(2)
    assert sqrt(2)**3 == sqrt(8)

def test_pow_issue417():
    assert 4**Rational(1, 4) == sqrt(2)

def test_pow_im():
    for m in (-2, -1, 2):
        for d in (3, 4, 5):
            b = m*I
            for i in range(1, 4*d + 1):
                e = Rational(i, d)
                assert (b**e - b.n()**e.n()).n(2, chop=1e-10) == 0

    e = Rational(7, 3)
    assert (2*x*I)**e == 4*2**Rational(1, 3)*(I*x)**e # same as Wolfram Alpha
    im = symbols('im', imaginary=True)
    assert (2*im*I)**e == 4*2**Rational(1, 3)*(I*im)**e

    args = [I, I, I, I, 2]
    e = Rational(1, 3)
    ans = 2**e
    assert Mul(*args, **dict(evaluate=False))**e == ans
    assert Mul(*args)**e == ans
    args = [I, I, I, 2]
    e = Rational(1, 3)
    ans = -(-1)**Rational(5, 6)*2**e
    assert Mul(*args, **dict(evaluate=False))**e == ans
    assert Mul(*args)**e == ans
    args = [I, I, 2]
    e = Rational(1, 3)
    ans = (-2)**e
    assert Mul(*args, **dict(evaluate=False))**e == ans
    assert Mul(*args)**e == ans

def test_expand():
    p = Rational(5)
    e = (a+b)*c
    assert e == c*(a+b)
    assert (e.expand()-a*c-b*c) == Rational(0)
    e=(a+b)*(a+b)
    assert e == (a+b)**2
    assert e.expand() == 2*a*b+a**2+b**2
    e=(a+b)*(a+b)**Rational(2)
    assert e == (a+b)**3
    assert e.expand() == 3*b*a**2+3*a*b**2+a**3+b**3
    assert e.expand() == 3*b*a**2+3*a*b**2+a**3+b**3
    e=(a+b)*(a+c)*(b+c)
    assert e == (a+c)*(a+b)*(b+c)
    assert e.expand() == 2*a*b*c+b*a**2+c*a**2+b*c**2+a*c**2+c*b**2+a*b**2
    e=(a+Rational(1))**p
    assert e == (1+a)**5
    assert e.expand() == 1+5*a+10*a**2+10*a**3+5*a**4+a**5
    e=(a+b+c)*(a+c+p)
    assert e == (5+a+c)*(a+b+c)
    assert e.expand() == 5*a+5*b+5*c+2*a*c+b*c+a*b+a**2+c**2
    x=Symbol("x")
    s=exp(x*x)-1
    e=s.nseries(x,0,3)/x**2
    assert e.expand() ==  1+x**2/2+O(x**4)

    e = (x*(y+z))**(x*(y+z))*(x+y)
    assert e.expand(power_exp=False, power_base=False) == x*(x*y + x*z)**(x*y + x*z) + y*(x*y + x*z)**(x*y + x*z)
    assert e.expand(power_exp=False, power_base=False, deep=False) == x*(x*(y + z))**(x*(y + z)) + y*(x*(y + z))**(x*(y + z))
    e = (x*(y+z))**z
    assert e.expand(power_base=True, mul=True, deep=True) in [x**z*(y + z)**z, (x*y + x*z)**z]
    assert ((2*y)**z).expand() == 2**z*y**z
    p=Symbol('p', positive=True)
    assert sqrt(-x).expand().is_Pow
    assert sqrt(-x).expand(force=True) == I*sqrt(x)
    assert ((2*y*p)**z).expand() == 2**z*p**z*y**z
    assert ((2*y*p*x)**z).expand() == 2**z*p**z*(x*y)**z
    assert ((2*y*p*x)**z).expand(force=True) == 2**z*p**z*x**z*y**z
    assert ((2*y*p*-pi)**z).expand() ==  2**z*pi**z*p**z*(-y)**z
    assert ((2*y*p*-pi*x)**z).expand() == 2**z*pi**z*p**z*(-x*y)**z
    n=Symbol('n', negative=True)
    m=Symbol('m', negative=True)
    assert ((-2*x*y*n)**z).expand() == 2**z*(-n)**z*(x*y)**z
    assert ((-2*x*y*n*m)**z).expand() == 2**z*(-m)**z*(-n)**z*(-x*y)**z
    # issue 2383
    assert sqrt(-2*x*n) == sqrt(2)*sqrt(-n)*sqrt(x)
    # issue 2506 (2)
    assert (cos(x+y)**2).expand(trig=True) == \
      sin(x)**2*sin(y)**2 - 2*sin(x)*sin(y)*cos(x)*cos(y) + cos(x)**2*cos(y)**2

    # Check that this isn't too slow
    x = Symbol('x')
    W = 1
    for i in range(1, 21):
        W = W * (x-i)
    W = W.expand()
    assert W.has(-1672280820*x**15)

def test_power_expand():
    """Test for Pow.expand()"""
    a = Symbol('a')
    b = Symbol('b')
    p = (a+b)**2
    assert p.expand() == a**2 + b**2 + 2*a*b

    p = (1+2*(1+a))**2
    assert p.expand() == 9 + 4*(a**2) + 12*a

    p = 2**(a+b)
    assert p.expand() == 2**a*2**b

    A = Symbol('A', commutative=False)
    B = Symbol('B', commutative=False)
    assert (2**(A+B)).expand() == 2**(A+B)
    assert (A**(a+b)).expand() != A**(a+b)

def test_real_mul():
    assert Float(0) * pi * x == Float(0)
    assert Float(1) * pi * x == pi * x
    assert len((Float(2) * pi * x).args) == 3

def test_ncmul():
    A = Symbol("A", commutative=False)
    B = Symbol("B", commutative=False)
    C = Symbol("C", commutative=False)
    assert A*B != B*A
    assert A*B*C != C*B*A
    assert A*b*B*3*C == 3*b*A*B*C
    assert A*b*B*3*C != 3*b*B*A*C
    assert A*b*B*3*C == 3*A*B*C*b

    assert A+B == B+A
    assert (A+B)*C != C*(A+B)

    assert C*(A+B)*C != C*C*(A+B)

    assert (C*(A+B)).expand() == C*A+C*B
    assert (C*(A+B)).expand() != A*C+B*C

    assert A*A == A**2
    assert (A+B)*(A+B) == (A+B)**2
    assert ((A+B)**2).expand() == A**2 + A*B + B*A +B**2

    assert A**-1  * A == 1
    assert A/A == 1
    assert A/(A**2) == 1/A

    assert A/(1+A) == A/(1+A)

    assert (A+B + 2*(A+B)) == 3*A + 3*B

def test_ncpow():
    x = Symbol('x', commutative=False)
    y = Symbol('y', commutative=False)
    z = Symbol('z', commutative=False)
    a = Symbol('a')
    b = Symbol('b')
    c = Symbol('c')

    assert (x**2)*(y**2) != (y**2)*(x**2)
    assert (x**-2)*y != y*(x**2)
    assert 2**x*2**y != 2**(x+y)
    assert 2**x*2**y*2**z != 2**(x+y+z)
    assert 2**x*2**(2*x) == 2**(3*x)
    assert 2**x*2**(2*x)*2**x == 2**(4*x)
    assert exp(x)*exp(y) != exp(y)*exp(x)
    assert exp(x)*exp(y)*exp(z) != exp(y)*exp(x)*exp(z)
    assert exp(x)*exp(y)*exp(z) != exp(x+y+z)
    assert x**a*x**b != x**(a+b)
    assert x**a*x**b*x**c != x**(a+b+c)
    assert x**3*x**4 == x**7
    assert x**3*x**4*x**2 == x**9
    assert x**a*x**(4*a) == x**(5*a)
    assert x**a*x**(4*a)*x**a == x**(6*a)

def test_powerbug():
    x=Symbol("x")
    assert x**1 != (-x)**1
    assert x**2 == (-x)**2
    assert x**3 != (-x)**3
    assert x**4 == (-x)**4
    assert x**5 != (-x)**5
    assert x**6 == (-x)**6

    assert x**128 == (-x)**128
    assert x**129 != (-x)**129

    assert (2*x)**2 == (-2*x)**2

def test_Mul_doesnt_expand_exp():
    x = Symbol('x')
    y = Symbol('y')
    assert exp(x)*exp(y) == exp(x)*exp(y)
    assert 2**x*2**y == 2**x*2**y
    assert x**2*x**3 == x**5
    assert 2**x*3**x == 6**x
    assert x**(y)*x**(2*y) == x**(3*y)
    assert sqrt(2)*sqrt(2) == 2
    assert 2**x*2**(2*x) == 2**(3*x)
    assert sqrt(2)*2**Rational(1,4)*5**Rational(3,4) == 10**Rational(3,4)
    assert (x**(-log(5)/log(3))*x)/(x*x**( - log(5)/log(3))) == sympify(1)

def test_Add_Mul_is_integer():
    x = Symbol('x')

    k = Symbol('k', integer=True)
    n = Symbol('n', integer=True)

    assert (2*k).is_integer == True
    assert (-k).is_integer == True
    assert (k/3).is_integer == False
    assert (x*k*n).is_integer == None

    assert (k+n).is_integer == True
    assert (k+x).is_integer == None
    assert (k+n*x).is_integer == None
    assert (k+n/3).is_integer == False

    assert ((1 + sqrt(3))*(-sqrt(3) + 1)).is_integer != False
    assert (1 + (1 + sqrt(3))*(-sqrt(3) + 1)).is_integer != False

def test_Add_Mul_is_bounded():
    x = Symbol('x', real=True, bounded=False)

    assert sin(x).is_bounded == True
    assert (x*sin(x)).is_bounded == False
    assert (1024*sin(x)).is_bounded == True
    assert (sin(x)*exp(x)).is_bounded is not True
    assert (sin(x)*cos(x)).is_bounded == True
    assert (x*sin(x)*exp(x)).is_bounded is not True

    assert (sin(x)-67).is_bounded == True
    assert (sin(x)+exp(x)).is_bounded is not True
    assert (1 + x).is_bounded is False
    assert (1 + x**2 + (1 + x)*(1 - x)).is_bounded is None
    assert (sqrt(2)*(1 + x)).is_bounded is False
    assert (sqrt(2)*(1 + x)*(1 - x)).is_bounded is False

def test_Mul_is_even_odd():
    x = Symbol('x', integer=True)

    k = Symbol('k', odd=True)
    n = Symbol('n', odd=True)
    m = Symbol('m', even=True)

    assert (2*x).is_even == True
    assert (2*x).is_odd == False

    assert (3*x).is_even == None
    assert (3*x).is_odd == None

    assert (k/3).is_integer == False
    assert (k/3).is_even    == False
    assert (k/3).is_odd     == False

    assert (2*n).is_even == True
    assert (2*n).is_odd == False

    assert (2*m).is_even == True
    assert (2*m).is_odd == False

    assert (-n).is_even == False
    assert (-n).is_odd == True

    assert (k*n).is_even == False
    assert (k*n).is_odd == True

    assert (k*m).is_even == True
    assert (k*m).is_odd == False

    assert (k*n*m).is_even == True
    assert (k*n*m).is_odd == False

    assert (k*m*x).is_even == True
    assert (k*m*x).is_odd == False

def test_Add_is_even_odd():
    x = Symbol('x', integer=True)

    k = Symbol('k', odd=True)
    n = Symbol('n', odd=True)
    m = Symbol('m', even=True)

    assert (k+7).is_even == True
    assert (k+7).is_odd == False

    assert (-k+7).is_even == True
    assert (-k+7).is_odd == False

    assert (k-12).is_even == False
    assert (k-12).is_odd == True

    assert (-k-12).is_even == False
    assert (-k-12).is_odd == True

    assert (k+n).is_even == True
    assert (k+n).is_odd == False

    assert (k+m).is_even == False
    assert (k+m).is_odd == True

    assert (k+n+m).is_even == True
    assert (k+n+m).is_odd == False

    assert (k+n+x+m).is_even == None
    assert (k+n+x+m).is_odd == None

def test_Mul_is_negative_positive():
    x = Symbol('x', real=True)
    y = Symbol('y', real=False)

    neg = Symbol('neg', negative=True)
    pos = Symbol('pos', positive=True)
    nneg = Symbol('nneg', nonnegative=True)
    npos = Symbol('npos', nonpositive=True)

    assert neg.is_negative == True
    assert (-neg).is_negative == False
    assert (2*neg).is_negative == True

    assert (2*pos)._eval_is_negative() == False
    assert (2*pos).is_negative == False

    assert pos.is_negative == False
    assert (-pos).is_negative == True
    assert (2*pos).is_negative == False

    assert (pos*neg).is_negative == True
    assert (2*pos*neg).is_negative == True
    assert (-pos*neg).is_negative == False
    assert (pos*neg*y).is_negative == False     # y.is_real=F;  !real -> !neg

    assert nneg.is_negative == False
    assert (-nneg).is_negative == None
    assert (2*nneg).is_negative == False

    assert npos.is_negative == None
    assert (-npos).is_negative == False
    assert (2*npos).is_negative == None

    assert (nneg*npos).is_negative == None

    assert (neg*nneg).is_negative == None
    assert (neg*npos).is_negative == False

    assert (pos*nneg).is_negative == False
    assert (pos*npos).is_negative == None

    assert (npos*neg*nneg).is_negative == False
    assert (npos*pos*nneg).is_negative == None

    assert (-npos*neg*nneg).is_negative == None
    assert (-npos*pos*nneg).is_negative == False

    assert (17*npos*neg*nneg).is_negative == False
    assert (17*npos*pos*nneg).is_negative == None

    assert (neg*npos*pos*nneg).is_negative == False

    assert (x*neg).is_negative == None
    assert (nneg*npos*pos*x*neg).is_negative == None

    assert neg.is_positive == False
    assert (-neg).is_positive == True
    assert (2*neg).is_positive == False

    assert pos.is_positive == True
    assert (-pos).is_positive == False
    assert (2*pos).is_positive == True

    assert (pos*neg).is_positive == False
    assert (2*pos*neg).is_positive == False
    assert (-pos*neg).is_positive == True
    assert (-pos*neg*y).is_positive == False    # y.is_real=F;  !real -> !neg

    assert nneg.is_positive == None
    assert (-nneg).is_positive == False
    assert (2*nneg).is_positive == None

    assert npos.is_positive == False
    assert (-npos).is_positive == None
    assert (2*npos).is_positive == False

    assert (nneg*npos).is_positive == False

    assert (neg*nneg).is_positive == False
    assert (neg*npos).is_positive == None

    assert (pos*nneg).is_positive == None
    assert (pos*npos).is_positive == False

    assert (npos*neg*nneg).is_positive == None
    assert (npos*pos*nneg).is_positive == False

    assert (-npos*neg*nneg).is_positive == False
    assert (-npos*pos*nneg).is_positive == None

    assert (17*npos*neg*nneg).is_positive == None
    assert (17*npos*pos*nneg).is_positive == False

    assert (neg*npos*pos*nneg).is_positive == None

    assert (x*neg).is_positive == None
    assert (nneg*npos*pos*x*neg).is_positive == None

def test_Mul_is_negative_positive_2():
    a = Symbol('a', nonnegative=True)
    b = Symbol('b', nonnegative=True)
    c = Symbol('c', nonpositive=True)
    d = Symbol('d', nonpositive=True)

    assert (a*b).is_nonnegative == True
    assert (a*b).is_negative    == False
    assert (a*b).is_zero        == None
    assert (a*b).is_positive    == None

    assert (c*d).is_nonnegative == True
    assert (c*d).is_negative    == False
    assert (c*d).is_zero        == None
    assert (c*d).is_positive    == None

    assert (a*c).is_nonpositive == True
    assert (a*c).is_positive    == False
    assert (a*c).is_zero        == None
    assert (a*c).is_negative    == None


def test_Mul_is_nonpositive_nonnegative():
    x = Symbol('x', real=True)

    k = Symbol('k', negative=True)
    n = Symbol('n', positive=True)
    u = Symbol('u', nonnegative=True)
    v = Symbol('v', nonpositive=True)

    assert k.is_nonpositive == True
    assert (-k).is_nonpositive == False
    assert (2*k).is_nonpositive == True

    assert n.is_nonpositive == False
    assert (-n).is_nonpositive == True
    assert (2*n).is_nonpositive == False

    assert (n*k).is_nonpositive == True
    assert (2*n*k).is_nonpositive == True
    assert (-n*k).is_nonpositive == False

    assert u.is_nonpositive == None
    assert (-u).is_nonpositive == True
    assert (2*u).is_nonpositive == None

    assert v.is_nonpositive == True
    assert (-v).is_nonpositive == None
    assert (2*v).is_nonpositive == True

    assert (u*v).is_nonpositive == True

    assert (k*u).is_nonpositive == True
    assert (k*v).is_nonpositive == None

    assert (n*u).is_nonpositive == None
    assert (n*v).is_nonpositive == True

    assert (v*k*u).is_nonpositive == None
    assert (v*n*u).is_nonpositive == True

    assert (-v*k*u).is_nonpositive == True
    assert (-v*n*u).is_nonpositive == None

    assert (17*v*k*u).is_nonpositive == None
    assert (17*v*n*u).is_nonpositive == True

    assert (k*v*n*u).is_nonpositive == None

    assert (x*k).is_nonpositive == None
    assert (u*v*n*x*k).is_nonpositive == None

    assert k.is_nonnegative == False
    assert (-k).is_nonnegative == True
    assert (2*k).is_nonnegative == False

    assert n.is_nonnegative == True
    assert (-n).is_nonnegative == False
    assert (2*n).is_nonnegative == True

    assert (n*k).is_nonnegative == False
    assert (2*n*k).is_nonnegative == False
    assert (-n*k).is_nonnegative == True

    assert u.is_nonnegative == True
    assert (-u).is_nonnegative == None
    assert (2*u).is_nonnegative == True

    assert v.is_nonnegative == None
    assert (-v).is_nonnegative == True
    assert (2*v).is_nonnegative == None

    assert (u*v).is_nonnegative == None

    assert (k*u).is_nonnegative == None
    assert (k*v).is_nonnegative == True

    assert (n*u).is_nonnegative == True
    assert (n*v).is_nonnegative == None

    assert (v*k*u).is_nonnegative == True
    assert (v*n*u).is_nonnegative == None

    assert (-v*k*u).is_nonnegative == None
    assert (-v*n*u).is_nonnegative == True

    assert (17*v*k*u).is_nonnegative == True
    assert (17*v*n*u).is_nonnegative == None

    assert (k*v*n*u).is_nonnegative == True

    assert (x*k).is_nonnegative == None
    assert (u*v*n*x*k).is_nonnegative == None

def test_Add_is_negative_positive():
    x = Symbol('x', real=True)

    k = Symbol('k', negative=True)
    n = Symbol('n', positive=True)
    u = Symbol('u', nonnegative=True)
    v = Symbol('v', nonpositive=True)

    assert (k-2).is_negative == True
    assert (k+17).is_negative == None
    assert (-k-5).is_negative == None
    assert (-k+123).is_negative == False

    assert (k-n).is_negative == True
    assert (k+n).is_negative == None
    assert (-k-n).is_negative == None
    assert (-k+n).is_negative == False

    assert (k-n-2).is_negative == True
    assert (k+n+17).is_negative == None
    assert (-k-n-5).is_negative == None
    assert (-k+n+123).is_negative == False

    assert (-2*k+123*n+17).is_negative == False

    assert (k+u).is_negative == None
    assert (k+v).is_negative == True
    assert (n+u).is_negative == False
    assert (n+v).is_negative == None

    assert (u-v).is_negative == False
    assert (u+v).is_negative == None
    assert (-u-v).is_negative == None
    assert (-u+v).is_negative == None

    assert (u-v+n+2).is_negative == False
    assert (u+v+n+2).is_negative == None
    assert (-u-v+n+2).is_negative == None
    assert (-u+v+n+2).is_negative == None

    assert (k+x).is_negative == None
    assert (k+x-n).is_negative == None

    assert (k-2).is_positive == False
    assert (k+17).is_positive == None
    assert (-k-5).is_positive == None
    assert (-k+123).is_positive == True

    assert (k-n).is_positive == False
    assert (k+n).is_positive == None
    assert (-k-n).is_positive == None
    assert (-k+n).is_positive == True

    assert (k-n-2).is_positive == False
    assert (k+n+17).is_positive == None
    assert (-k-n-5).is_positive == None
    assert (-k+n+123).is_positive == True

    assert (-2*k+123*n+17).is_positive == True

    assert (k+u).is_positive == None
    assert (k+v).is_positive == False
    assert (n+u).is_positive == True
    assert (n+v).is_positive == None

    assert (u-v).is_positive == None
    assert (u+v).is_positive == None
    assert (-u-v).is_positive == None
    assert (-u+v).is_positive == False

    assert (u-v-n-2).is_positive == None
    assert (u+v-n-2).is_positive == None
    assert (-u-v-n-2).is_positive == None
    assert (-u+v-n-2).is_positive == False

    assert (n+x).is_positive == None
    assert (n+x-k).is_positive == None

    assert (-3 - sqrt(5) + (-sqrt(10)/2 - sqrt(2)/2)**2).is_zero != False

def test_Add_is_nonpositive_nonnegative():
    x = Symbol('x', real=True)

    k = Symbol('k', negative=True)
    n = Symbol('n', positive=True)
    u = Symbol('u', nonnegative=True)
    v = Symbol('v', nonpositive=True)

    assert (u-2).is_nonpositive == None
    assert (u+17).is_nonpositive == False
    assert (-u-5).is_nonpositive == True
    assert (-u+123).is_nonpositive == None

    assert (u-v).is_nonpositive == None
    assert (u+v).is_nonpositive == None
    assert (-u-v).is_nonpositive == None
    assert (-u+v).is_nonpositive == True

    assert (u-v-2).is_nonpositive == None
    assert (u+v+17).is_nonpositive == None
    assert (-u-v-5).is_nonpositive == None
    assert (-u+v-123).is_nonpositive == True

    assert (-2*u+123*v-17).is_nonpositive == True

    assert (k+u).is_nonpositive == None
    assert (k+v).is_nonpositive == True
    assert (n+u).is_nonpositive == False
    assert (n+v).is_nonpositive == None

    assert (k-n).is_nonpositive == True
    assert (k+n).is_nonpositive == None
    assert (-k-n).is_nonpositive == None
    assert (-k+n).is_nonpositive == False

    assert (k-n+u+2).is_nonpositive == None
    assert (k+n+u+2).is_nonpositive == None
    assert (-k-n+u+2).is_nonpositive == None
    assert (-k+n+u+2).is_nonpositive == False

    assert (u+x).is_nonpositive == None
    assert (v-x-n).is_nonpositive == None

    assert (u-2).is_nonnegative == None
    assert (u+17).is_nonnegative == True
    assert (-u-5).is_nonnegative == False
    assert (-u+123).is_nonnegative == None

    assert (u-v).is_nonnegative == True
    assert (u+v).is_nonnegative == None
    assert (-u-v).is_nonnegative == None
    assert (-u+v).is_nonnegative == None

    assert (u-v+2).is_nonnegative == True
    assert (u+v+17).is_nonnegative == None
    assert (-u-v-5).is_nonnegative == None
    assert (-u+v-123).is_nonnegative == False

    assert (2*u-123*v+17).is_nonnegative == True

    assert (k+u).is_nonnegative == None
    assert (k+v).is_nonnegative == False
    assert (n+u).is_nonnegative == True
    assert (n+v).is_nonnegative == None

    assert (k-n).is_nonnegative == False
    assert (k+n).is_nonnegative == None
    assert (-k-n).is_nonnegative == None
    assert (-k+n).is_nonnegative == True

    assert (k-n-u-2).is_nonnegative == False
    assert (k+n-u-2).is_nonnegative == None
    assert (-k-n-u-2).is_nonnegative == None
    assert (-k+n-u-2).is_nonnegative == None

    assert (u-x).is_nonnegative == None
    assert (v+x+n).is_nonnegative == None

def test_Pow_is_integer():
    x = Symbol('x')

    k = Symbol('k', integer=True)
    n = Symbol('n', integer=True, nonnegative=True)
    m = Symbol('m', integer=True, positive=True)

    assert (k**2).is_integer == True
    assert (k**(-2)).is_integer == False

    assert (2**k).is_integer == None
    assert (2**(-k)).is_integer == None

    assert (2**n).is_integer == True
    assert (2**(-n)).is_integer == None

    assert (2**m).is_integer == True
    assert (2**(-m)).is_integer == False

    assert (x**2).is_integer == None
    assert (2**x).is_integer == None

    assert (k**n).is_integer == True
    assert (k**(-n)).is_integer == None

    assert (k**x).is_integer == None
    assert (x**k).is_integer == None

    assert (k**(n*m)).is_integer == True
    assert (k**(-n*m)).is_integer == None

    assert sqrt(3).is_integer is False
    assert sqrt(.3).is_integer is False
    assert Pow(3, 2, evaluate=False).is_integer is True
    assert Pow(3, 0, evaluate=False).is_integer is True
    assert Pow(3, -2, evaluate=False).is_integer is False
    assert Pow(S.Half, 3, evaluate=False).is_integer is False
    # decided by re-evaluating
    assert Pow(3, S.Half, evaluate=False).is_integer is False
    assert Pow(3, S.Half, evaluate=False).is_integer is False
    assert Pow(4, S.Half, evaluate=False).is_integer is True
    assert Pow(S.Half, -2, evaluate=False).is_integer is True

def test_Pow_is_real():
    x = Symbol('x', real=True)
    y = Symbol('y', real=True, positive=True)

    assert (x**2).is_real   == True
    assert (x**3).is_real   == True
    assert (x**x).is_real   == None
    assert (y**x).is_real   == True

    assert (x**Rational(1,3)).is_real  == None
    assert (y**Rational(1,3)).is_real  == True

    assert sqrt(-1 - sqrt(2)).is_real == False

    i = Symbol('i', imaginary=True)
    assert (i**i).is_real is None
    assert (I**i).is_real is None
    assert ((-I)**i).is_real is None
    assert (2**i).is_real is None # (2**(pi/log(2) * I)) is real, 2**I is not
    assert (2**I).is_real is False
    assert (2**-I).is_real is False
    assert (i**2).is_real
    assert (i**3).is_real is False
    assert (i**x).is_real is None # could be (-I)**(2/3)
    e = Symbol('e', even=True)
    o = Symbol('o', odd=True)
    k = Symbol('k', integer=True)
    assert (i**e).is_real
    assert (i**o).is_real is False
    assert (i**k).is_real is None

@XFAIL
def test_real_Pow():
    """
    This test fails perhaps because (pi/log(x)).is_real is True even with
    no assumptions on x. See issue 2322.
    """
    k = Symbol('k', integer=True, nonzero=True)
    assert (k**(I*pi/log(k))).is_real

def test_Pow_is_bounded():
    x = Symbol('x', real=True)
    p = Symbol('p', positive=True)
    n = Symbol('n', negative=True)

    assert (x**2).is_bounded == None # x could be oo
    assert (x**x).is_bounded == None # ditto
    assert (p**x).is_bounded == None # ditto
    assert (n**x).is_bounded == None # ditto
    assert (1/S.Pi).is_bounded
    assert (sin(x)**2).is_bounded == True
    assert (sin(x)**x).is_bounded == None
    assert (sin(x)**exp(x)).is_bounded == None
    assert (1/sin(x)).is_bounded == None # if zero, no, otherwise yes
    assert (1/exp(x)).is_bounded == None # x could be -oo

def test_Pow_is_even_odd():
    x = Symbol('x')

    k = Symbol('k', even=True)
    n = Symbol('n', odd=True)
    m = Symbol('m', integer=True, nonnegative=True)

    assert (k**2).is_even == True
    assert (n**2).is_even == False
    assert (2**k).is_even == None
    assert (x**2).is_even == None

    assert (k**m).is_even == True
    assert (n**m).is_even == False

    assert (k**x).is_even == None
    assert (n**x).is_even == None

    assert (k**2).is_odd == False
    assert (n**2).is_odd == True
    assert (3**k).is_odd == None

    assert (k**m).is_odd == False
    assert (n**m).is_odd == True

    assert (k**x).is_odd == None
    assert (n**x).is_odd == None

def test_Pow_is_negative_positive():
    x = Symbol('x', real=True)

    k = Symbol('k', integer=True, positive=True)
    n = Symbol('n', even=True)
    m = Symbol('m', odd=True)

    z = Symbol('z')

    assert (2**x).is_positive == True
    assert ((-2)**x).is_positive == None
    assert ((-2)**n).is_positive == True
    assert ((-2)**m).is_positive == False

    assert (k**2).is_positive == True
    assert (k**(-2)).is_positive == True

    assert (k**x).is_positive == True
    assert ((-k)**x).is_positive == None
    assert ((-k)**n).is_positive == True
    assert ((-k)**m).is_positive == False

    assert (2**x).is_negative == False
    assert ((-2)**x).is_negative == None
    assert ((-2)**n).is_negative == False
    assert ((-2)**m).is_negative == True

    assert (k**2).is_negative == False
    assert (k**(-2)).is_negative == False

    assert (k**x).is_negative == False
    assert ((-k)**x).is_negative == None
    assert ((-k)**n).is_negative == False
    assert ((-k)**m).is_negative == True

    assert (2**z).is_positive   == None
    assert (2**z).is_negative   == None

def test_Pow_is_nonpositive_nonnegative():
    x = Symbol('x', real=True)

    k = Symbol('k', integer=True, nonnegative=True)
    l = Symbol('l', integer=True, positive=True)
    n = Symbol('n', even=True)
    m = Symbol('m', odd=True)

    assert (2**x).is_nonnegative == True
    assert ((-2)**x).is_nonnegative == None
    assert ((-2)**n).is_nonnegative == True
    assert ((-2)**m).is_nonnegative == False

    assert (k**2).is_nonnegative == True
    assert (k**(-2)).is_nonnegative == True

    assert (k**x).is_nonnegative == None    # NOTE (0**x).is_real = U
    assert (l**x).is_nonnegative == True
    assert (l**x).is_positive    == True
    assert ((-k)**x).is_nonnegative == None
    assert ((-k)**n).is_nonnegative == True
    assert ((-k)**m).is_nonnegative == None

    assert (2**x).is_nonpositive == False
    assert ((-2)**x).is_nonpositive == None
    assert ((-2)**n).is_nonpositive == False
    assert ((-2)**m).is_nonpositive == True

    assert (k**2).is_nonpositive == None
    assert (k**(-2)).is_nonpositive == None

    assert (k**x).is_nonpositive == None
    assert ((-k)**x).is_nonpositive == None
    assert ((-k)**n).is_nonpositive == None
    assert ((-k)**m).is_nonpositive == True


def test_Mul_is_imaginary_real():
    r = Symbol('r', real=True)
    i = Symbol('i', imaginary=True)
    ii= Symbol('ii',imaginary=True)
    x = Symbol('x')

    assert    I  .is_imaginary  == True
    assert    I  .is_real       == False
    assert  (-I) .is_imaginary  == True
    assert  (-I) .is_real       == False
    assert (3*I) .is_imaginary  == True
    assert (3*I) .is_real       == False
    assert (I*I) .is_imaginary  == False
    assert (I*I) .is_real       == True

    assert (r*i) .is_imaginary  == True
    assert (r*i) .is_real       == False

    assert (x*i) .is_imaginary  == None
    assert (x*i) .is_real       == None

    assert (i*ii).is_imaginary  == False
    assert (i*ii).is_real       == True

    assert (r*i*ii).is_imaginary == False
    assert (r*i*ii).is_real      == True



def test_Add_is_comparable():
    assert (x+y).is_comparable  == False
    assert (x+1).is_comparable  == False
    assert (Rational(1,3) - sqrt(8)).is_comparable == True

def test_Mul_is_comparable():
    assert (x*y).is_comparable  == False
    assert (x*2).is_comparable  == False
    assert (sqrt(2)*Rational(1,3)).is_comparable == True


def test_Pow_is_comparable():
    assert (x**y).is_comparable == False
    assert (x**2).is_comparable == False
    assert (sqrt(Rational(1,3))).is_comparable == True


def test_Add_is_positive_2():
    e = Rational(1,3) - sqrt(8)
    assert e.is_positive    == False
    assert e.is_negative    == True

    e = pi - 1
    assert e.is_positive    == True
    assert e.is_negative    == False


def test_Add_is_irrational():
    i = Symbol('i', irrational=True)

    assert i.is_irrational  == True
    assert i.is_rational    == False

    assert (i+1).is_irrational  == True
    assert (i+1).is_rational    == False

@XFAIL
def test_issue432():
    class MightyNumeric(tuple):
        def __rdiv__(self, other):
            return "something"

        def __rtruediv__(self, other):
            return "something"
    assert sympify(1)/MightyNumeric((1,2)) == "something"

def test_issue432b():
    class Foo:
        def __init__(self):
            self.field = 1.0
        def __mul__(self, other):
            self.field = self.field * other
        def __rmul__(self, other):
            self.field = other * self.field
    f = Foo()
    x = Symbol("x")
    assert f*x == x*f

def test_bug3():
    a = Symbol("a")
    b = Symbol("b", positive=True)
    e = 2*a + b
    f = b + 2*a
    assert e == f

def test_suppressed_evaluation():
    a = Add(0,3,2,evaluate=False)
    b = Mul(1,3,2,evaluate=False)
    c = Pow(3,2,evaluate=False)
    assert a != 6
    assert a.func is Add
    assert a.args == (3,2)
    assert b != 6
    assert b.func is Mul
    assert b.args == (3,2)
    assert c != 9
    assert c.func is Pow
    assert c.args == (3,2)


def test_Add_as_coeff_mul():
    # Issue 2425.  These should all be (1, self)
    assert (x + 1).as_coeff_mul()   == (1, (x + 1,) )
    assert (x + 2).as_coeff_mul()   == (1, (x + 2,) )
    assert (x + 3).as_coeff_mul()   == (1, (x + 3,) )

    assert (x - 1).as_coeff_mul()   == (1, (x - 1,) )
    assert (x - 2).as_coeff_mul()   == (1, (x - 2,) )
    assert (x - 3).as_coeff_mul()   == (1, (x - 3,) )

    n = Symbol('n', integer=True)
    assert (n + 1).as_coeff_mul()   == (1, (n + 1,) )
    assert (n + 2).as_coeff_mul()   == (1, (n + 2,) )
    assert (n + 3).as_coeff_mul()   == (1, (n + 3,) )

    assert (n - 1).as_coeff_mul()   == (1, (n - 1,) )
    assert (n - 2).as_coeff_mul()   == (1, (n - 2,) )
    assert (n - 3).as_coeff_mul()   == (1, (n - 3,) )

def test_Pow_as_coeff_mul_doesnt_expand():
    assert exp(x + y).as_coeff_mul() == (1, (exp(x + y),))
    assert exp(x + exp(x + y)) != exp(x + exp(x)*exp(y))

def test_issue415():
    assert sqrt(S.Half) * sqrt(6) == 2 * sqrt(3)/2
    assert S(1)/2*sqrt(6)*sqrt(2) == sqrt(3)
    assert sqrt(6)/2*sqrt(2) == sqrt(3)
    assert sqrt(6)*sqrt(2)/2 == sqrt(3)

def test_make_args():
    assert Add.make_args(x) == (x,)
    assert Mul.make_args(x) == (x,)

    assert Add.make_args(x*y*z) == (x*y*z,)
    assert Mul.make_args(x*y*z) == (x*y*z).args

    assert Add.make_args(x+y+z) == (x+y+z).args
    assert Mul.make_args(x+y+z) == (x+y+z,)

    assert Add.make_args((x+y)**z) == ((x+y)**z,)
    assert Mul.make_args((x+y)**z) == ((x+y)**z,)

def test_issue2027():
    assert (-2)**x*(-3)**x != 6**x
    i = Symbol('i', integer=1)
    assert (-2)**i*(-3)**i == 6**i

def test_Rational_as_content_primitive():
    c, p = S(1), S(0)
    assert (c*p).as_content_primitive() == (c, p)
    c, p = S(1)/2, S(1)
    assert (c*p).as_content_primitive() == (c, p)

def test_Add_as_content_primitive():
    assert (x + 2).as_content_primitive() == (1, x + 2)

    assert (3*x + 2).as_content_primitive() == (1, 3*x + 2)
    assert (3*x + 3).as_content_primitive() == (3, x + 1)
    assert (3*x + 6).as_content_primitive() == (3, x + 2)

    assert (3*x + 2*y).as_content_primitive() == (1, 3*x + 2*y)
    assert (3*x + 3*y).as_content_primitive() == (3, x + y)
    assert (3*x + 6*y).as_content_primitive() == (3, x + 2*y)

    assert (3/x + 2*x*y*z**2).as_content_primitive() == (1, 3/x + 2*x*y*z**2)
    assert (3/x + 3*x*y*z**2).as_content_primitive() == (3, 1/x + x*y*z**2)
    assert (3/x + 6*x*y*z**2).as_content_primitive() == (3, 1/x + 2*x*y*z**2)

    assert (2*x/3 + 4*y/9).as_content_primitive() == (Rational(2, 9), 3*x + 2*y)
    assert (2*x/3 + 2.5*y).as_content_primitive() == (Rational(1, 3), 2*x + 7.5*y)

    # the coefficient may sort to a position other than 0
    p = 3 + x + y
    assert (2*p).expand().as_content_primitive() == (2, p)
    assert (2.0*p).expand().as_content_primitive() == (1, 2.*p)
    p *= -1
    assert (2*p).expand().as_content_primitive() == (2, p)

def test_Mul_as_content_primitive():
    assert (2*x).as_content_primitive() == (2, x)
    assert (x*(2+2*x)).as_content_primitive() == (2, x*(1 + x))
    assert (x*(2 + 2*y)*(3*x + 3)**2).as_content_primitive() == (18, x*(1 + y)*(x + 1)**2)
    assert ((2+2*x)**2*(3+6*x)+S.Half).as_content_primitive() == (S.Half, 24*(x + 1)**2*(2*x + 1) + 1)

def test_Pow_as_content_primitive():
    assert (x**y).as_content_primitive() == (1, x**y)
    assert ((2*x + 2)**y).as_content_primitive() == (1, (Mul(2,(x + 1), evaluate=False))**y)
    assert ((2*x + 2)**3).as_content_primitive() == (8, (x + 1)**3)

def test_issue2361():
    u = Mul(2, (1 + x), evaluate=False)
    assert 2 + u == 4 + 2*x
    # the Number is only suppose to distribute on a commutative Add
    n = Symbol('n', commutative=False)
    u = 2*(1 + n)
    assert u.is_Mul
    assert 2 + u == 4 + 2*n

def test_product_irrational():
    from sympy import I, pi
    assert (I*pi).is_irrational is False
    # The following used to be deduced from the above bug:
    assert (I*pi).is_positive is False

def test_issue_2820():
    assert (x/(y*(1 + y))).expand() == x/(y**2 + y)

def test_Mod():
    assert Mod(5, 3) == 2
    assert Mod(-5, 3) == 1
    assert Mod(5, -3) == -1
    assert Mod(-5, -3) == -2
    assert type(Mod(3.2, 2, evaluate=False)) == Mod
    assert 5 % x == Mod(5, x)
    assert x % 5 == Mod(x, 5)
    assert x % y == Mod(x, y)
    assert (x % y).subs({x: 5, y: 3}) == 2
    assert (x + 3) % 1 == Mod(x, 1)
    assert (x + 3.0) % 1 == Mod(x, 1)
    assert (x - S(33)/10) % 1 == Mod(x + S(7)/10, 1)
    assert (x - 3.3) % 1 == Mod(x + 0.7, 1)
    assert Mod(-3.3, 1) == Mod(0.7, 1) == Float(0.7)
    e = Mod(1.3, 1)
    assert e == .3 and e.is_Float
    e = Mod(1.3, .7)
    assert e == .6 and e.is_Float
    e = Mod(1.3, Rational(7, 10))
    assert e == .6 and e.is_Float
    e = Mod(Rational(13, 10), 0.7)
    assert e == .6 and e.is_Float
    e = Mod(Rational(13, 10), Rational(7, 10))
    assert e == .6 and e.is_Rational

def test_issue_2902():
    A = Symbol("A", commutative=False)
    eq = A + A**2
    # it doesn't matter whether it's True or False; they should
    # just all be the same
    assert (
        eq.is_commutative ==
        (eq + 1).is_commutative ==
        (A + 1).is_commutative)

    B = Symbol("B", commutative=False)
    # Although commutative terms could cancel we return True
    # meaning "there are non-commutative symbols; aftersubstitution
    # that definition can change, e.g. (A*B).subs(B,A**-1) -> 1
    assert (sqrt(2)*A).is_commutative is False
    assert (sqrt(2)*A*B).is_commutative is False

def test_polar():
    from sympy import polar_lift
    p = Symbol('p', polar=True)
    x = Symbol('x')
    assert p.is_polar
    assert x.is_polar is None
    assert S(1).is_polar is None
    assert (p**x).is_polar is True
    assert (x**p).is_polar is None
    assert ((2*p)**x).is_polar is True
    assert (2*p).is_polar is True
    assert (-2*p).is_polar is not True
    assert (polar_lift(-2)*p).is_polar is True

    q = Symbol('q', polar=True)
    assert (p*q)**2 == p**2 * q**2
    assert (2*q)**2 == 4 * q**2
    assert ((p*q)**x).expand() == p**x * q**x

def test_issue_2941():
    a, b = Pow(1, 2, evaluate=False), S.One
    assert a != b
    assert b != a
    assert not (a == b)
    assert not (b == a)

def test_issue_2983():
    assert Max(x, 1) * Max(x, 2) == Max(x, 1) * Max(x, 2)
    assert Or(x, z) * Or(x, z) == Or(x, z) * Or(x, z)

def test_issue_2978():
    assert x**2.0/x == x**1.0
    assert x/x**2.0 == x**-1.0
    assert x*x**2.0 == x**3.0
    assert x**1.5*x**2.5 == x**4.0

    assert 2**(2.0*x)/2**x == 2**(1.0*x)
    assert 2**x/2**(2.0*x) == 2**(-1.0*x)
    assert 2**x*2**(2.0*x) == 2**(3.0*x)
    assert 2**(1.5*x)*2**(2.5*x) == 2**(4.0*x)

def test_mul_flatten_oo():
    p = symbols('p', positive=True)
    n, m = symbols('n,m', negative=True)
    x_im = symbols('x_im', imaginary=True)
    assert n*oo == -oo
    assert n*m*oo == oo
    assert p*oo == oo
    assert x_im*oo != I*oo # i could be +/- 3*I -> +/-oo

def test_issue_2061_2988_2990_2991():
    #2988
    assert ((-2*x*y**y)**3.2).n(2) == (2**3.2*(-x*y**y)**3.2).n(2)
    #2990
    A, B, C = symbols('A,B,C', commutative=False)
    assert (2.*B*C)**3 == 8.0*(B*C)**3
    assert (-2.*B*C)**3 == -8.0*(B*C)**3
    assert (-2*B*C)**2 == 4*(B*C)**2
    #2061
    assert sqrt(-1.0*x) == 1.0*sqrt(-x)
    #2991
    assert (-2*x*y*A*B)**2 == 4*x**2*y**2*(A*B)**2

def test_float_int():
    assert int(float(sqrt(10))) == int(sqrt(10))
    assert int(pi**1000) % 10 == 2
    assert int(Float('1.123456789012345678901234567890e20','')) == \
        112345678901234567890L
    assert int(Float('1.123456789012345678901234567890e25','')) == \
        11234567890123456789012345L
    assert int(Float('1.123456789012345678901234567890e35','')) == \
        112345678901234567890123456789000000L
    assert Integer(Float('1.123456789012345678901234567890e20','')) == \
        112345678901234567890
    assert Integer(Float('1.123456789012345678901234567890e25','')) == \
        11234567890123456789012345
    assert Integer(Float('1.123456789012345678901234567890e35','')) == \
        112345678901234567890123456789000000
    assert int(1 + Rational('.9999999999999999999999999')) == 1
    assert int(pi/1e20) == 0
    assert int(1 + pi/1e20) == 1
    assert int(Add(1.2, -2, evaluate=False)) == int(1.2 - 2)
    assert int(Add(1.2, +2, evaluate=False)) == int(1.2 + 2)
    assert int(Add(1 + Float('.99999999999999999', ''), evaluate=False)) == 1
    raises(TypeError, 'float(x)')
    raises(TypeError, 'float(sqrt(-1))')

    assert int(12345678901234567890 + cos(1)**2 + sin(1)**2) == 12345678901234567891
