def test_diop_ternary_quadratic():
    # Commented out test cases should be uncommented after
    # the bug with factor_list() gets merged.

    assert check_solutions(2*x**2 + z**2 + y**2 - 4*x*y)
    assert check_solutions(x**2 - y**2 - z**2 - x*y - y*z)
    assert check_solutions(3*x**2 - x*y - y*z - x*z)
    assert check_solutions(x**2 - y*z - x*z)
    # assert check_solutions(5*x**2 - 3*x*y - x*z)
    assert check_solutions(4*x**2 - 5*y**2 - x*z)
    assert check_solutions(3*x**2 + 2*y**2 - z**2 - 2*x*y + 5*y*z - 7*y*z)
    assert check_solutions(8*x**2 - 12*y*z)
    assert check_solutions(45*x**2 - 7*y**2 - 8*x*y - z**2)
    assert check_solutions(x**2 - 49*y**2 - z**2 + 13*z*y - 8*x*y)
    assert check_solutions(90*x**2 + 3*y**2 + 5*x*y + 2*z*y + 5*x*z)
    assert check_solutions(x**2 + 3*y**2 + z**2 - x*y - 17*y*z)
    assert check_solutions(x**2 + 3*y**2 + z**2 - x*y - 16*y*z + 12*x*z)
    assert check_solutions(x**2 + 3*y**2 + z**2 - 13*x*y - 16*y*z + 12*x*z)
    assert check_solutions(x*y - 7*y*z + 13*x*z)

    assert diop_ternary_quadratic_normal(x**2 + y**2 + z**2) == (None, None, None)
    assert diop_ternary_quadratic_normal(x**2 + y**2) is None
    pytest.raises(ValueError,
                  lambda: _diop_ternary_quadratic_normal((x, y, z),
                                                         {x*y: 1, x**2: 2,
                                                          y**2: 3, z**2: 0}))
    eq = -2*x*y - 6*x*z + 7*y**2 - 3*y*z + 4*z**2
    assert diop_ternary_quadratic(eq) == (7, 2, 0)
    assert diop_ternary_quadratic_normal(4*x**2 + 5*y**2 - z**2) == (1, 0, 2)
    assert diop_ternary_quadratic(x*y + 2*y*z) == (-2, 0, n1)
    eq = -5*x*y - 8*x*z - 3*y*z + 8*z**2
    assert parametrize_ternary_quadratic(eq) == (64*p**2 - 24*p*q, -64*p*q + 64*q**2, 40*p*q)
    # this cannot be tested with diophantine because it will
    # factor into a product
    assert diop_solve(x*y + 2*y*z) == (-4*p*q, -2*n1*p**2 + 2*p**2, 2*p*q)
def test_diop_ternary_quadratic():
    # Commented out test cases should be uncommented after
    # the bug with factor_list() gets merged.

    assert check_solutions(2 * x**2 + z**2 + y**2 - 4 * x * y)
    assert check_solutions(x**2 - y**2 - z**2 - x * y - y * z)
    assert check_solutions(3 * x**2 - x * y - y * z - x * z)
    assert check_solutions(x**2 - y * z - x * z)
    # assert check_solutions(5*x**2 - 3*x*y - x*z)
    assert check_solutions(4 * x**2 - 5 * y**2 - x * z)
    assert check_solutions(3 * x**2 + 2 * y**2 - z**2 - 2 * x * y + 5 * y * z -
                           7 * y * z)
    assert check_solutions(8 * x**2 - 12 * y * z)
    assert check_solutions(45 * x**2 - 7 * y**2 - 8 * x * y - z**2)
    assert check_solutions(x**2 - 49 * y**2 - z**2 + 13 * z * y - 8 * x * y)
    assert check_solutions(90 * x**2 + 3 * y**2 + 5 * x * y + 2 * z * y +
                           5 * x * z)
    assert check_solutions(x**2 + 3 * y**2 + z**2 - x * y - 17 * y * z)
    assert check_solutions(x**2 + 3 * y**2 + z**2 - x * y - 16 * y * z +
                           12 * x * z)
    assert check_solutions(x**2 + 3 * y**2 + z**2 - 13 * x * y - 16 * y * z +
                           12 * x * z)
    assert check_solutions(x * y - 7 * y * z + 13 * x * z)

    assert diop_ternary_quadratic_normal(x**2 + y**2 + z**2) == (None, None,
                                                                 None)
    assert diop_ternary_quadratic_normal(x**2 + y**2) is None
    pytest.raises(
        ValueError, lambda: _diop_ternary_quadratic_normal((x, y, z), {
            x * y: 1,
            x**2: 2,
            y**2: 3,
            z**2: 0
        }))
    eq = -2 * x * y - 6 * x * z + 7 * y**2 - 3 * y * z + 4 * z**2
    assert diop_ternary_quadratic(eq) == (7, 2, 0)
    assert diop_ternary_quadratic_normal(4 * x**2 + 5 * y**2 - z**2) == (1, 0,
                                                                         2)
    assert diop_ternary_quadratic(x * y + 2 * y * z) == (-2, 0, n1)
    eq = -5 * x * y - 8 * x * z - 3 * y * z + 8 * z**2
    assert parametrize_ternary_quadratic(eq) == (64 * p**2 - 24 * p * q,
                                                 -64 * p * q + 64 * q**2,
                                                 40 * p * q)
    # this cannot be tested with diophantine because it will
    # factor into a product
    assert diop_solve(x * y + 2 * y * z) == (-4 * p * q,
                                             -2 * n1 * p**2 + 2 * p**2,
                                             2 * p * q)
def test_diophantine():
    # Commented out test cases should be uncommented after
    # the bug with factor_list() gets merged.

    assert check_solutions((x - y) * (y - z) * (z - x))
    assert check_solutions((x - y) * (x**2 + y**2 - z**2))
    assert check_solutions((x - 3 * y + 7 * z) * (x**2 + y**2 - z**2))
    assert check_solutions((x**2 - 3 * y**2 - 1))
    # assert check_solutions(y**2 + 7*x*y)
    # assert check_solutions(x**2 - 3*x*y + y**2)
    # assert check_solutions(z*(x**2 - y**2 - 15))
    # assert check_solutions(x*(2*y - 2*z + 5))
    assert check_solutions((x**2 - 3 * y**2 - 1) * (x**2 - y**2 - 15))
    assert check_solutions((x**2 - 3 * y**2 - 1) * (y - 7 * z))
    assert check_solutions((x**2 + y**2 - z**2) * (x - 7 * y - 3 * z + 4 * w))
    # Following test case caused problems in parametric representation
    # But this can be solved by factroing out y.
    # No need to use methods for ternary quadratic equations.
    # assert check_solutions(y**2 - 7*x*y + 4*y*z)
    assert check_solutions(x**2 - 2 * x + 1)

    assert diophantine(Integer(0)) == {(t, )}
    assert diophantine(x - y) == diophantine(Eq(x, y))
    assert diophantine(3 * x * pi - 2 * y * pi) == {(2 * t_0, 3 * t_0)}
    assert diophantine(x**2 + y**2 + z**2 - 14) == {(1, 2, 3)}
    assert diophantine(x**2 + 15 * x / 14 - 3) == set()

    # test issue sympy/sympy#11049
    eq = 92 * x**2 - 99 * y**2 - z**2
    coeff = eq.as_coefficients_dict()
    assert _diop_ternary_quadratic_normal((x, y, z), coeff) == (9, 7, 51)
    assert diophantine(eq) == {
        (891 * p**2 + 9 * q**2, -693 * p**2 - 102 * p * q + 7 * q**2,
         5049 * p**2 - 1386 * p * q - 51 * q**2)
    }
    eq = 2 * x**2 + 2 * y**2 - z**2
    coeff = eq.as_coefficients_dict()
    assert _diop_ternary_quadratic_normal((x, y, z), coeff) == (1, 1, 2)
    assert diophantine(eq) == {(2 * p**2 - q**2, -2 * p**2 + 4 * p * q - q**2,
                                4 * p**2 - 4 * p * q + 2 * q**2)}
    eq = 411 * x**2 + 57 * y**2 - 221 * z**2
    coeff = eq.as_coefficients_dict()
    assert _diop_ternary_quadratic_normal((x, y, z),
                                          coeff) == (2021, 2645, 3066)
    assert diophantine(eq) == {
        (115197 * p**2 - 446641 * q**2,
         -150765 * p**2 + 1355172 * p * q - 584545 * q**2,
         174762 * p**2 - 301530 * p * q + 677586 * q**2)
    }
    eq = 573 * x**2 + 267 * y**2 - 984 * z**2
    coeff = eq.as_coefficients_dict()
    assert _diop_ternary_quadratic_normal((x, y, z), coeff) == (49, 233, 127)
    assert diophantine(eq) == {(4361 * p**2 - 16072 * q**2,
                                -20737 * p**2 + 83312 * p * q - 76424 * q**2,
                                11303 * p**2 - 41474 * p * q + 41656 * q**2)}

    # this produces factors during reconstruction
    eq = x**2 + 3 * y**2 - 12 * z**2
    coeff = eq.as_coefficients_dict()
    assert _diop_ternary_quadratic_normal((x, y, z), coeff) == (0, 2, 1)
    assert diophantine(eq) == {(24 * p * q, 2 * p**2 - 24 * q**2,
                                p**2 + 12 * q**2)}
    # solvers have not been written for every type
    pytest.raises(NotImplementedError, lambda: diophantine(x * y**2 + 1))

    # rational expressions
    assert diophantine(1 / x) == set()
    assert diophantine(1 / x + 1 / y - Rational(1, 2)) == {(6, 3), (-2, 1),
                                                           (4, 4), (1, -2),
                                                           (3, 6)}

    # issue sympy/sympy#9538
    eq = x - 3 * y + 2

    assert diophantine(eq, syms=[y, x]) == {(t_0, 3 * t_0 - 2)}
    assert diophantine(eq, syms=[x, y]) == {(3 * t_0 - 2, t_0)}

    pytest.raises(TypeError, lambda: diophantine(eq, syms={y, x}))
def test_diophantine():
    # Commented out test cases should be uncommented after
    # the bug with factor_list() gets merged.

    assert check_solutions((x - y)*(y - z)*(z - x))
    assert check_solutions((x - y)*(x**2 + y**2 - z**2))
    assert check_solutions((x - 3*y + 7*z)*(x**2 + y**2 - z**2))
    assert check_solutions((x**2 - 3*y**2 - 1))
    # assert check_solutions(y**2 + 7*x*y)
    # assert check_solutions(x**2 - 3*x*y + y**2)
    # assert check_solutions(z*(x**2 - y**2 - 15))
    # assert check_solutions(x*(2*y - 2*z + 5))
    assert check_solutions((x**2 - 3*y**2 - 1)*(x**2 - y**2 - 15))
    assert check_solutions((x**2 - 3*y**2 - 1)*(y - 7*z))
    assert check_solutions((x**2 + y**2 - z**2)*(x - 7*y - 3*z + 4*w))
    # Following test case caused problems in parametric representation
    # But this can be solved by factroing out y.
    # No need to use methods for ternary quadratic equations.
    # assert check_solutions(y**2 - 7*x*y + 4*y*z)
    assert check_solutions(x**2 - 2*x + 1)

    assert diophantine(Integer(0)) == {(t,)}
    assert diophantine(x - y) == diophantine(Eq(x, y))
    assert diophantine(3*x*pi - 2*y*pi) == {(2*t_0, 3*t_0)}
    assert diophantine(x**2 + y**2 + z**2 - 14) == {(1, 2, 3)}
    assert diophantine(x**2 + 15*x/14 - 3) == set()

    # test issue sympy/sympy#11049
    eq = 92*x**2 - 99*y**2 - z**2
    coeff = eq.as_coefficients_dict()
    assert _diop_ternary_quadratic_normal((x, y, z), coeff) == (9, 7, 51)
    assert diophantine(eq) == {(891*p**2 + 9*q**2, -693*p**2 - 102*p*q + 7*q**2,
                                5049*p**2 - 1386*p*q - 51*q**2)}
    eq = 2*x**2 + 2*y**2 - z**2
    coeff = eq.as_coefficients_dict()
    assert _diop_ternary_quadratic_normal((x, y, z), coeff) == (1, 1, 2)
    assert diophantine(eq) == {(2*p**2 - q**2, -2*p**2 + 4*p*q - q**2,
                                4*p**2 - 4*p*q + 2*q**2)}
    eq = 411*x**2+57*y**2-221*z**2
    coeff = eq.as_coefficients_dict()
    assert _diop_ternary_quadratic_normal((x, y, z), coeff) == (2021, 2645, 3066)
    assert diophantine(eq) == {(115197*p**2 - 446641*q**2,
                                -150765*p**2 + 1355172*p*q - 584545*q**2,
                                174762*p**2 - 301530*p*q + 677586*q**2)}
    eq = 573*x**2+267*y**2-984*z**2
    coeff = eq.as_coefficients_dict()
    assert _diop_ternary_quadratic_normal((x, y, z), coeff) == (49, 233, 127)
    assert diophantine(eq) == {(4361*p**2 - 16072*q**2,
                                -20737*p**2 + 83312*p*q - 76424*q**2,
                                11303*p**2 - 41474*p*q + 41656*q**2)}

    # this produces factors during reconstruction
    eq = x**2 + 3*y**2 - 12*z**2
    coeff = eq.as_coefficients_dict()
    assert _diop_ternary_quadratic_normal((x, y, z), coeff) == (0, 2, 1)
    assert diophantine(eq) == {(24*p*q, 2*p**2 - 24*q**2, p**2 + 12*q**2)}
    # solvers have not been written for every type
    pytest.raises(NotImplementedError, lambda: diophantine(x*y**2 + 1))

    # rational expressions
    assert diophantine(1/x) == set()
    assert diophantine(1/x + 1/y - Rational(1, 2)) == {(6, 3), (-2, 1),
                                                       (4, 4), (1, -2), (3, 6)}