from diofant import (Add, Dummy, I, Mul, Rational, Symbol, cos, cosh, cot,
                     coth, exp, fu, pi, powsimp, root, sin, sinh, sqrt,
                     symbols, tan, tanh)
from diofant.abc import a, b, c, x, y, z
from diofant.simplify.fu import _TR56 as T
from diofant.simplify.fu import (TR1, TR2, TR3, TR5, TR6, TR7, TR8, TR9, TR10,
                                 TR11, TR12, TR13, TR14, TR15, TR16, TR111, L,
                                 TR2i, TR10i, TR12i, TRmorrie, TRpower)
from diofant.simplify.fu import _osborne as o
from diofant.simplify.fu import _osbornei as i
from diofant.simplify.fu import (as_f_sign_1, csc, hyper_as_trig,
                                 process_common_addends, sec, trig_split)
from diofant.utilities.randtest import verify_numerically


__all__ = ()


def test_TR1():
    assert TR1(2*csc(x) + sec(x)) == 1/cos(x) + 2/sin(x)


def test_TR2():
    assert TR2(tan(x)) == sin(x)/cos(x)
    assert TR2(cot(x)) == cos(x)/sin(x)
    assert TR2(tan(tan(x) - sin(x)/cos(x))) == 0


def test_TR2i():
    # just a reminder that ratios of powers only simplify if both
    # numerator and denominator satisfy the condition that each
    # has a positive base or an integer exponent; e.g. the following,
    # at y=-1, x=1/2 gives sqrt(2)*I != -sqrt(2)*I
    assert powsimp(2**x/y**x) != (2/y)**x

    assert TR2i(sin(x)/cos(x)) == tan(x)
    assert TR2i(sin(x)*sin(y)/cos(x)) == tan(x)*sin(y)
    assert TR2i(1/(sin(x)/cos(x))) == 1/tan(x)
    assert TR2i(1/(sin(x)*sin(y)/cos(x))) == 1/tan(x)/sin(y)
    assert TR2i(sin(x)/2/(cos(x) + 1)) == sin(x)/(cos(x) + 1)/2

    assert TR2i(sin(x)/2/(cos(x) + 1), half=True) == tan(x/2)/2
    assert TR2i(sin(1)/(cos(1) + 1), half=True) == tan(Rational(1, 2))
    assert TR2i(sin(2)/(cos(2) + 1), half=True) == tan(1)
    assert TR2i(sin(4)/(cos(4) + 1), half=True) == tan(2)
    assert TR2i(sin(5)/(cos(5) + 1), half=True) == tan(Rational(5, 2))
    assert TR2i((cos(1) + 1)/sin(1), half=True) == 1/tan(Rational(1, 2))
    assert TR2i((cos(2) + 1)/sin(2), half=True) == 1/tan(1)
    assert TR2i((cos(4) + 1)/sin(4), half=True) == 1/tan(2)
    assert TR2i((cos(5) + 1)/sin(5), half=True) == 1/tan(Rational(5, 2))
    assert TR2i((cos(1) + 1)**(-a)*sin(1)**a, half=True) == tan(Rational(1, 2))**a
    assert TR2i((cos(2) + 1)**(-a)*sin(2)**a, half=True) == tan(1)**a
    assert TR2i((cos(4) + 1)**(-a)*sin(4)**a, half=True) == (cos(4) + 1)**(-a)*sin(4)**a
    assert TR2i((cos(5) + 1)**(-a)*sin(5)**a, half=True) == (cos(5) + 1)**(-a)*sin(5)**a
    assert TR2i((cos(1) + 1)**a*sin(1)**(-a), half=True) == tan(Rational(1, 2))**(-a)
    assert TR2i((cos(2) + 1)**a*sin(2)**(-a), half=True) == tan(1)**(-a)
    assert TR2i((cos(4) + 1)**a*sin(4)**(-a), half=True) == (cos(4) + 1)**a*sin(4)**(-a)
    assert TR2i((cos(5) + 1)**a*sin(5)**(-a), half=True) == (cos(5) + 1)**a*sin(5)**(-a)

    i = symbols('i', integer=True)
    assert TR2i(((cos(5) + 1)**i*sin(5)**(-i)), half=True) == tan(Rational(5, 2))**(-i)
    assert TR2i(1/((cos(5) + 1)**i*sin(5)**(-i)), half=True) == tan(Rational(5, 2))**i


def test_TR3():
    assert TR3(cos(y - x*(y - x))) == cos(x*(x - y) + y)
    assert cos(pi/2 + x) == -sin(x)
    assert cos(30*pi/2 + x) == -cos(x)

    for f in (cos, sin, tan, cot, csc, sec):
        i = f(3*pi/7)
        j = TR3(i)
        assert verify_numerically(i, j)
        assert i.func != j.func


def test__TR56():
    def h(x):
        return 1 - x
    assert T(sin(x)**3, sin, cos, h, 4, False) == sin(x)**3
    assert T(sin(x)**10, sin, cos, h, 4, False) == sin(x)**10
    assert T(sin(x)**6, sin, cos, h, 6, False) == (-cos(x)**2 + 1)**3
    assert T(sin(x)**6, sin, cos, h, 6, True) == sin(x)**6
    assert T(sin(x)**8, sin, cos, h, 10, True) == (-cos(x)**2 + 1)**4


def test_TR5():
    assert TR5(sin(x)**2) == -cos(x)**2 + 1
    assert TR5(sin(x)**-2) == sin(x)**(-2)
    assert TR5(sin(x)**4) == (-cos(x)**2 + 1)**2


def test_TR6():
    assert TR6(cos(x)**2) == -sin(x)**2 + 1
    assert TR6(cos(x)**-2) == cos(x)**(-2)
    assert TR6(cos(x)**4) == (-sin(x)**2 + 1)**2


def test_TR7():
    assert TR7(cos(x)**2) == cos(2*x)/2 + Rational(1, 2)
    assert TR7(cos(x)**2 + 1) == cos(2*x)/2 + Rational(3, 2)


def test_TR8():
    assert TR8(cos(2)*cos(3)) == cos(5)/2 + cos(1)/2
    assert TR8(cos(2)*sin(3)) == sin(5)/2 + sin(1)/2
    assert TR8(sin(2)*sin(3)) == -cos(5)/2 + cos(1)/2
    assert TR8(sin(1)*sin(2)*sin(3)) == sin(4)/4 - sin(6)/4 + sin(2)/4
    assert TR8(cos(2)*cos(3)*cos(4)*cos(5)) == \
        cos(4)/4 + cos(10)/8 + cos(2)/8 + cos(8)/8 + cos(14)/8 + \
        cos(6)/8 + Rational(1, 8)
    assert TR8(cos(2)*cos(3)*cos(4)*cos(5)*cos(6)) == \
        cos(10)/8 + cos(4)/8 + 3*cos(2)/16 + cos(16)/16 + cos(8)/8 + \
        cos(14)/16 + cos(20)/16 + cos(12)/16 + Rational(1, 16) + cos(6)/8
    assert TR8(sin(3*pi/7)**2*cos(3*pi/7)**2/(16*sin(pi/7)**2)) == Rational(1, 64)


def test_TR9():
    a = Rational(1, 2)
    b = 3*a
    assert TR9(a) == a
    assert TR9(cos(1) + cos(2)) == 2*cos(a)*cos(b)
    assert TR9(cos(1) - cos(2)) == 2*sin(a)*sin(b)
    assert TR9(sin(1) - sin(2)) == -2*sin(a)*cos(b)
    assert TR9(sin(1) + sin(2)) == 2*sin(b)*cos(a)
    assert TR9(cos(1) + 2*sin(1) + 2*sin(2)) == cos(1) + 4*sin(b)*cos(a)
    assert TR9(cos(4) + cos(2) + 2*cos(1)*cos(3)) == 4*cos(1)*cos(3)
    assert TR9((cos(4) + cos(2))/cos(3)/2 + cos(3)) == 2*cos(1)*cos(2)
    assert TR9(cos(3) + cos(4) + cos(5) + cos(6)) == \
        4*cos(Rational(1, 2))*cos(1)*cos(Rational(9, 2))
    assert TR9(cos(3) + cos(3)*cos(2)) == cos(3) + cos(2)*cos(3)
    assert TR9(-cos(y) + cos(x*y)) == -2*sin(x*y/2 - y/2)*sin(x*y/2 + y/2)
    assert TR9(-sin(y) + sin(x*y)) == 2*sin(x*y/2 - y/2)*cos(x*y/2 + y/2)
    c = cos(x)
    s = sin(x)
    for si in ((1, 1), (1, -1), (-1, 1), (-1, -1)):
        for a in ((c, s), (s, c), (cos(x), cos(x*y)), (sin(x), sin(x*y))):
            args = zip(si, a)
            ex = Add(*[Mul(*ai) for ai in args])
            t = TR9(ex)
            assert not (a[0].func == a[1].func and (
                not verify_numerically(ex, t.expand(trig=True)) or t.is_Add)
                and ex != t)


def test_TR10():
    assert TR10(cos(a + b)) == -sin(a)*sin(b) + cos(a)*cos(b)
    assert TR10(sin(a + b)) == sin(a)*cos(b) + sin(b)*cos(a)
    assert TR10(sin(a + b + c)) == \
        (-sin(a)*sin(b) + cos(a)*cos(b))*sin(c) + \
        (sin(a)*cos(b) + sin(b)*cos(a))*cos(c)
    assert TR10(cos(a + b + c)) == \
        (-sin(a)*sin(b) + cos(a)*cos(b))*cos(c) - \
        (sin(a)*cos(b) + sin(b)*cos(a))*sin(c)


def test_TR10i():
    assert TR10i(cos(1)*cos(3) + sin(1)*sin(3)) == cos(2)
    assert TR10i(cos(1)*cos(3) - sin(1)*sin(3)) == cos(4)
    assert TR10i(cos(1)*sin(3) - sin(1)*cos(3)) == sin(2)
    assert TR10i(cos(1)*sin(3) + sin(1)*cos(3)) == sin(4)
    assert TR10i(cos(1)*sin(3) + sin(1)*cos(3) + 7) == sin(4) + 7
    assert TR10i(cos(1)*sin(3) + sin(1)*cos(3) + cos(3)) == cos(3) + sin(4)
    assert TR10i(2*cos(1)*sin(3) + 2*sin(1)*cos(3) + cos(3)) == \
        2*sin(4) + cos(3)
    assert TR10i(cos(2)*cos(3) + sin(2)*(cos(1)*sin(2) + cos(2)*sin(1))) == \
        cos(1)
    eq = (cos(2)*cos(3) + sin(2)*(
        cos(1)*sin(2) + cos(2)*sin(1)))*cos(5) + sin(1)*sin(5)
    assert TR10i(eq) == TR10i(eq.expand()) == cos(4)
    assert TR10i(sqrt(2)*cos(x)*x + sqrt(6)*sin(x)*x) == \
        2*sqrt(2)*x*sin(x + pi/6)
    assert TR10i(cos(x)/sqrt(6) + sin(x)/sqrt(2) +
                 cos(x)/sqrt(6)/3 + sin(x)/sqrt(2)/3) == 4*sqrt(6)*sin(x + pi/6)/9
    assert TR10i(cos(x)/sqrt(6) + sin(x)/sqrt(2) +
                 cos(y)/sqrt(6)/3 + sin(y)/sqrt(2)/3) == \
        sqrt(6)*sin(x + pi/6)/3 + sqrt(6)*sin(y + pi/6)/9
    assert TR10i(cos(x) + sqrt(3)*sin(x) + 2*sqrt(3)*cos(x + pi/6)) == 4*cos(x)
    assert TR10i(cos(x) + sqrt(3)*sin(x) +
                 2*sqrt(3)*cos(x + pi/6) + 4*sin(x)) == 4*sqrt(2)*sin(x + pi/4)
    assert TR10i(cos(2)*sin(3) + sin(2)*cos(4)) == \
        sin(2)*cos(4) + sin(3)*cos(2)

    A = Symbol('A', commutative=False)
    assert TR10i(sqrt(2)*cos(x)*A + sqrt(6)*sin(x)*A) == \
        2*sqrt(2)*sin(x + pi/6)*A

    c = cos(x)
    s = sin(x)
    h = sin(y)
    r = cos(y)
    for si in ((1, 1), (1, -1), (-1, 1), (-1, -1)):
        for a in ((c*r, s*h), (c*h, s*r)):  # explicit 2-args
            args = zip(si, a)
            ex = Add(*[Mul(*ai) for ai in args])
            t = TR10i(ex)
            assert not ex - t.expand(trig=True)
            assert not t.is_Add

    c = cos(x)
    s = sin(x)
    h = sin(pi/6)
    r = cos(pi/6)
    for si in ((1, 1), (1, -1), (-1, 1), (-1, -1)):
        for a in ((c*r, s*h), (c*h, s*r)):  # induced
            args = zip(si, a)
            ex = Add(*[Mul(*ai) for ai in args])
            t = TR10i(ex)
            assert not ex - t.expand(trig=True)
            assert not t.is_Add


def test_TR11():

    assert TR11(sin(2*x)) == 2*sin(x)*cos(x)
    assert TR11(sin(4*x)) == 4*((-sin(x)**2 + cos(x)**2)*sin(x)*cos(x))
    assert TR11(sin(4*x/3)) == \
        4*((-sin(x/3)**2 + cos(x/3)**2)*sin(x/3)*cos(x/3))

    assert TR11(cos(2*x)) == -sin(x)**2 + cos(x)**2
    assert TR11(cos(4*x)) == \
        (-sin(x)**2 + cos(x)**2)**2 - 4*sin(x)**2*cos(x)**2

    assert TR11(cos(2)) == cos(2)

    assert TR11(cos(3*pi/7), 2*pi/7) == -cos(2*pi/7)**2 + sin(2*pi/7)**2
    assert TR11(cos(4), 2) == -sin(2)**2 + cos(2)**2
    assert TR11(cos(6), 2) == cos(6)
    assert TR11(sin(x)/cos(x/2), x/2) == 2*sin(x/2)


def test_TR12():
    assert TR12(tan(x + y)) == (tan(x) + tan(y))/(-tan(x)*tan(y) + 1)
    assert TR12(tan(x + y + z)) ==\
        (tan(z) + (tan(x) + tan(y))/(-tan(x)*tan(y) + 1))/(
        1 - (tan(x) + tan(y))*tan(z)/(-tan(x)*tan(y) + 1))
    assert TR12(tan(x*y)) == tan(x*y)


def test_TR13():
    assert TR13(tan(3)*tan(2)) == -tan(2)/tan(5) - tan(3)/tan(5) + 1
    assert TR13(cot(3)*cot(2)) == 1 + cot(3)*cot(5) + cot(2)*cot(5)
    assert TR13(tan(1)*tan(2)*tan(3)) == \
        (-tan(2)/tan(5) - tan(3)/tan(5) + 1)*tan(1)
    assert TR13(tan(1)*tan(2)*cot(3)) == \
        (-tan(2)/tan(3) + 1 - tan(1)/tan(3))*cot(3)


def test_L():
    assert L(cos(x) + sin(x)) == 2


def test_fu():
    assert fu(sin(50)**2 + cos(50)**2 + sin(pi/6)) == Rational(3, 2)
    assert fu(sqrt(6)*cos(x) + sqrt(2)*sin(x)) == 2*sqrt(2)*sin(x + pi/3)

    eq = sin(x)**4 - cos(y)**2 + sin(y)**2 + 2*cos(x)**2
    assert fu(eq) == cos(x)**4 - 2*cos(y)**2 + 2

    assert fu(Rational(1, 2) - cos(2*x)/2) == sin(x)**2

    assert fu(sin(a)*(cos(b) - sin(b)) + cos(a)*(sin(b) + cos(b))) == \
        sqrt(2)*sin(a + b + pi/4)

    assert fu(sqrt(3)*cos(x)/2 + sin(x)/2) == sin(x + pi/3)

    assert fu(1 - sin(2*x)**2/4 - sin(y)**2 - cos(x)**4) == \
        -cos(x)**2 + cos(y)**2

    assert fu(cos(4*pi/9)) == sin(pi/18)
    assert fu(cos(pi/9)*cos(2*pi/9)*cos(3*pi/9)*cos(4*pi/9)) == Rational(1, 16)

    assert fu(
        tan(7*pi/18) + tan(5*pi/18) - sqrt(3)*tan(5*pi/18)*tan(7*pi/18)) == \
        -sqrt(3)

    assert fu(tan(1)*tan(2)) == tan(1)*tan(2)

    expr = Mul(*[cos(2**i) for i in range(10)])
    assert fu(expr) == sin(1024)/(1024*sin(1))


def test_objective():
    assert fu(sin(x)/cos(x), measure=lambda x: x.count_ops()) == \
        tan(x)
    assert fu(sin(x)/cos(x), measure=lambda x: -x.count_ops()) == \
        sin(x)/cos(x)


def test_process_common_addends():
    # this tests that the args are not evaluated as they are given to do
    # and that key2 works when key1 is False
    def do(x):
        return Add(*[i**(i % 2) for i in x.args])
    assert process_common_addends(Add(*[1, 2, 3, 4], evaluate=False), do,
                                  key2=lambda x: x % 2, key1=False) == 1**1 + 3**1 + 2**0 + 4**0


def test_trig_split():
    assert trig_split(cos(x), cos(y)) == (1, 1, 1, x, y, True)
    assert trig_split(2*cos(x), -2*cos(y)) == (2, 1, -1, x, y, True)
    assert trig_split(cos(x)*sin(y), cos(y)*sin(y)) == \
        (sin(y), 1, 1, x, y, True)

    assert trig_split(cos(x), -sqrt(3)*sin(x), two=True) == \
        (2, 1, -1, x, pi/6, False)
    assert trig_split(cos(x), sin(x), two=True) == \
        (sqrt(2), 1, 1, x, pi/4, False)
    assert trig_split(cos(x), -sin(x), two=True) == \
        (sqrt(2), 1, -1, x, pi/4, False)
    assert trig_split(sqrt(2)*cos(x), -sqrt(6)*sin(x), two=True) == \
        (2*sqrt(2), 1, -1, x, pi/6, False)
    assert trig_split(-sqrt(6)*cos(x), -sqrt(2)*sin(x), two=True) == \
        (-2*sqrt(2), 1, 1, x, pi/3, False)
    assert trig_split(cos(x)/sqrt(6), sin(x)/sqrt(2), two=True) == \
        (sqrt(6)/3, 1, 1, x, pi/6, False)
    assert trig_split(-sqrt(6)*cos(x)*sin(y),
                      -sqrt(2)*sin(x)*sin(y), two=True) == \
        (-2*sqrt(2)*sin(y), 1, 1, x, pi/3, False)

    assert trig_split(cos(x), sin(x)) is None
    assert trig_split(cos(x), sin(z)) is None
    assert trig_split(2*cos(x), -sin(x)) is None
    assert trig_split(cos(x), -sqrt(3)*sin(x)) is None
    assert trig_split(cos(x)*cos(y), sin(x)*sin(z)) is None
    assert trig_split(cos(x)*cos(y), sin(x)*sin(y)) is None
    assert trig_split(-sqrt(6)*cos(x), sqrt(2)*sin(x)*sin(y), two=True) is \
        None

    assert trig_split(sqrt(3)*sqrt(x), cos(3), two=True) is None
    assert trig_split(sqrt(3)*root(x, 3), sin(3)*cos(2), two=True) is None
    assert trig_split(cos(5)*cos(6), cos(7)*sin(5), two=True) is None


def test_TRmorrie():
    assert TRmorrie(7*Mul(*[cos(i) for i in range(10)])) == \
        7*sin(12)*sin(16)*cos(5)*cos(7)*cos(9)/(64*sin(1)*sin(3))
    assert TRmorrie(x) == x
    assert TRmorrie(2*x) == 2*x
    e = cos(pi/7)*cos(2*pi/7)*cos(4*pi/7)
    assert TR8(TRmorrie(e)) == -Rational(1, 8)
    e = Mul(*[cos(2**i*pi/17) for i in range(1, 17)])
    assert TR8(TR3(TRmorrie(e))) == Rational(1, 65536)


def test_TRpower():
    assert TRpower(1/sin(x)**2) == 1/sin(x)**2
    assert TRpower(cos(x)**3*sin(x/2)**4) == \
        (3*cos(x)/4 + cos(3*x)/4)*(-cos(x)/2 + cos(2*x)/8 + Rational(3, 8))
    for k in range(2, 8):
        assert verify_numerically(sin(x)**k, TRpower(sin(x)**k))
        assert verify_numerically(cos(x)**k, TRpower(cos(x)**k))


def test_hyper_as_trig():
    eq = sinh(x)**2 + cosh(x)**2
    t, f = hyper_as_trig(eq)
    assert f(fu(t)) == cosh(2*x)
    e, f = hyper_as_trig(tanh(x + y))
    assert f(TR12(e)) == (tanh(x) + tanh(y))/(tanh(x)*tanh(y) + 1)

    d = Dummy()
    assert o(sinh(x), d) == I*sin(x*d)
    assert o(tanh(x), d) == I*tan(x*d)
    assert o(coth(x), d) == cot(x*d)/I
    assert o(cosh(x), d) == cos(x*d)
    for func in (sinh, cosh, tanh, coth):
        h = func(pi)
        assert i(o(h, d), d) == h
    # /!\ the _osborne functions are not meant to work
    # in the o(i(trig, d), d) direction so we just check
    # that they work as they are supposed to work
    assert i(cos(x*y), y) == cosh(x)
    assert i(sin(x*y), y) == sinh(x)/I
    assert i(tan(x*y), y) == tanh(x)/I
    assert i(cot(x*y), y) == coth(x)*I
    assert i(sec(x*y), y) == 1/cosh(x)
    assert i(csc(x*y), y) == I/sinh(x)


def test_TR12i():
    ta, tb, tc = map(tan, (a, b, c))
    assert TR12i((ta + tb)/(-ta*tb + 1)) == tan(a + b)
    assert TR12i((ta + tb)/(ta*tb - 1)) == -tan(a + b)
    assert TR12i((-ta - tb)/(ta*tb - 1)) == tan(a + b)
    eq = (ta + tb)/(-ta*tb + 1)**2*(-3*ta - 3*tc)/(2*(ta*tc - 1))
    assert TR12i(eq.expand()) == \
        -3*tan(a + b)*tan(a + c)/(tan(a) + tan(b) - 1)/2
    assert TR12i(tan(x)/sin(x)) == tan(x)/sin(x)
    eq = (ta + cos(2))/(-ta*tb + 1)
    assert TR12i(eq) == eq
    eq = (ta + tb + 2)**2/(-ta*tb + 1)
    assert TR12i(eq) == eq
    eq = ta/(-ta*tb + 1)
    assert TR12i(eq) == eq
    eq = (((ta + tb)*(a + 1)).expand())**2/(ta*tb - 1)
    assert TR12i(eq) == -(a + 1)**2*tan(a + b)


def test_TR14():
    eq = (cos(x) - 1)*(cos(x) + 1)
    ans = -sin(x)**2
    assert TR14(eq) == ans
    assert TR14(1/eq) == 1/ans
    assert TR14((cos(x) - 1)**2*(cos(x) + 1)**2) == ans**2
    assert TR14((cos(x) - 1)**2*(cos(x) + 1)**3) == ans**2*(cos(x) + 1)
    assert TR14((cos(x) - 1)**3*(cos(x) + 1)**2) == ans**2*(cos(x) - 1)
    eq = (cos(x) - 1)**y*(cos(x) + 1)**y
    assert TR14(eq) == eq
    eq = (cos(x) - 2)**y*(cos(x) + 1)
    assert TR14(eq) == eq
    eq = (tan(x) - 2)**2*(cos(x) + 1)
    assert TR14(eq) == eq
    i = symbols('i', integer=True)
    assert TR14((cos(x) - 1)**i*(cos(x) + 1)**i) == ans**i
    assert TR14((sin(x) - 1)**i*(sin(x) + 1)**i) == (-cos(x)**2)**i
    # could use extraction in this case
    eq = (cos(x) - 1)**(i + 1)*(cos(x) + 1)**i
    assert TR14(eq) in [(cos(x) - 1)*ans**i, eq]

    assert TR14((sin(x) - 1)*(sin(x) + 1)) == -cos(x)**2
    p1 = (cos(x) + 1)*(cos(x) - 1)
    p2 = (cos(y) - 1)*2*(cos(y) + 1)
    p3 = (3*(cos(y) - 1))*(3*(cos(y) + 1))
    assert TR14(p1*p2*p3*(x - 1)) == -18*((x - 1)*sin(x)**2*sin(y)**4)


def test_TR15_16_17():
    assert TR15(1 - 1/sin(x)**2) == -cot(x)**2
    assert TR16(1 - 1/cos(x)**2) == -tan(x)**2
    assert TR111(1 - 1/tan(x)**2) == 1 - cot(x)**2


def test_as_f_sign_1():
    assert as_f_sign_1(x + 1) == (1, x, 1)
    assert as_f_sign_1(x - 1) == (1, x, -1)
    assert as_f_sign_1(-x + 1) == (-1, x, -1)
    assert as_f_sign_1(-x - 1) == (-1, x, 1)
    assert as_f_sign_1(2*x + 2) == (2, x, 1)
    assert as_f_sign_1(x*y - y) == (y, x, -1)
    assert as_f_sign_1(-x*y + y) == (-y, x, -1)


def test_sympyissue_22878():
    assert (fu(8*sqrt(2)*(-exp(2*I*x)*sin(2*x) +
                          (-1 + 2*I)*exp(2*I*x)*cos(2*x) +
                          1 + I)*exp(-x*(1 + 2*I))) ==
            8*sqrt(2)*exp(-x*(1 + 2*I))*(-exp(2*I*x)*sin(2*x) +
                                         exp(2*I*x)*(-1 + 2*I)*cos(2*x) +
                                         1 + I))
