from __future__ import division

from sympy import Symbol, sin, cos, exp, O, sqrt, Rational, Float, re, pi, \
        sympify, sqrt, Add, Mul, Pow, I, log, S
from sympy.utilities.pytest import XFAIL

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 == (a+b)**(Rational(1)/2)
    assert e.expand() == (a+b)**(Rational(1)/2)

    n=n5**(n1/n2)
    assert n == Rational(5)**(Rational(1)/2)
    e=n*a*b-n*b*a
    assert e == Rational(0)
    e=n*a*b+n*b*a
    assert e == 2*a*b*5**(Rational(1)/2)
    assert e.diff(a) == 2*b*5**(Rational(1)/2)
    assert e.diff(a) == 2*b*5**(Rational(1)/2)
    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 (-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_pow_issue417():
    assert 4**Rational(1, 4) == 2**Rational(1, 2)

def test_pow3():
    assert 2**(Rational(3)/2) == 2 * 2**Rational(1, 2)
    assert 2**(Rational(3)/2) == sqrt(8)

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():
    Float(0) * pi * x == Float(0)
    Float(1) * pi * x == pi * x
    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)

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 2**Rational(1,2)*2**Rational(1,2) == 2
    assert 2**x*2**(2*x) == 2**(3*x)
    assert 2**Rational(1,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

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

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', even=True)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    assert (u*v).is_negative == None

    assert (k*u).is_negative == None
    assert (k*v).is_negative == False

    assert (n*u).is_negative == False
    assert (n*v).is_negative == None

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

    assert (-v*k*u).is_negative == None
    assert (-v*n*u).is_negative == False

    assert (17*v*k*u).is_negative == False
    assert (17*v*n*u).is_negative == None

    assert (k*v*n*u).is_negative == False

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

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

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

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

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

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

    assert (u*v).is_positive == False

    assert (k*u).is_positive == False
    assert (k*v).is_positive == None

    assert (n*u).is_positive == None
    assert (n*v).is_positive == False

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

    assert (-v*k*u).is_positive == False
    assert (-v*n*u).is_positive == None

    assert (17*v*k*u).is_positive == None
    assert (17*v*n*u).is_positive == False

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

    assert (x*k).is_positive == None
    assert (u*v*n*x*k).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_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_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

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


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 (Rational(1,3)**Rational(1,2)).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

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(1,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 == (1,3,2)
    assert b != 6
    assert b.func is Mul
    assert b.args == (1,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 (S.Half)**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_Add_primitive():
    (x + 2).primitive() == (1, x + 2)

    (3*x + 2).primitive() == (1, x + 2)
    (2*x + 2).primitive() == (2, x + 1)
    (3*x + 3).primitive() == (3, x + 1)
    (4*x + 8).primitive() == (4, x + 2)

    (3*x + 2*y).primitive() == (1, x + 2*y)
    (2*x + 2*y).primitive() == (2, x + y)
    (3*x + 3*y).primitive() == (3, x + y)
    (4*x + 8*y).primitive() == (4, x + 2*y)

    (3/x + 2*x*y*z**2).primitive() == (1, 1/x + 2*x*y*z**2)
    (2/x + 2*x*y*z**2).primitive() == (2, 1/x + x*y*z**2)
    (3/x + 3*x*y*z**2).primitive() == (3, 1/x + x*y*z**2)
    (4/x + 8*x*y*z**2).primitive() == (4, 1/x + 2*x*y*z**2)

    (2*x/3 + 4*y/9).primitive() == (2/9, 3*x + 2*y)
    (2*x/3 + 4.1*y).primitive() == (1, 2*x/3 + 4.1*y)

def test_issue2361():
    u = Mul(2, (1 + x), evaluate=False)
    assert 2 + u == 4 + 2*x
    n = Symbol('n', commutative=False)
    u = 2*(1 + n)
    assert u.is_Mul
    assert (2 + u).args == (S(2), u)
