def test_sympy_power_with_negative_one_exponent_gets_converted_to_division(
        sympy_power, expected_denominator):
    assert expression_from_sympy(sympy_power) == FunctionCall(
        "div", (1, expected_denominator))
def test_sympy_pow_is_converted_to_pow_function_call(sympy_power,
                                                     expected_args):
    assert expression_from_sympy(sympy_power) == FunctionCall(
        "pow", expected_args)
def test_add_resulting_from_subtraction_is_converted_to_sub_function_call(
        sympy_addition, expected_args):
    assert expression_from_sympy(sympy_addition) == FunctionCall(
        "sub", expected_args)
def test_mul_not_from_division_is_not_classified_as_multiplication_by_reciprocal(
    sympy_multiplication, ):
    # Note: obviously you can manually construct multiplication that would
    # be classified as multiplication by reciprocal. The bottom line of this
    # test is: usual, simple multiplications are multiplications, not divisions.
    assert not is_multiplication_by_reciprocal(sympy_multiplication)


@pytest.mark.parametrize(
    "sympy_multiplication, expected_args",
    [
        (sympy.Symbol("x") / sympy.Symbol("y"), (Symbol("x"), Symbol("y"))),
        (
            sympy.Symbol("x") /
            (sympy.Add(sympy.Symbol("z"), 1, evaluate=False)),
            (Symbol("x"), FunctionCall("add", (Symbol("z"), 1))),
        ),
    ],
)
def test_division_is_converted_into_div_fn_call_instead_of_multiplication_by_reciprocal(
        sympy_multiplication, expected_args):
    # Important note about sympy: there is no Div operator (as opposed to
    # e.g. Mul). The division on sympy expressions actually produces Mul
    # objects, in which second operand is a reciprocal of the original one.
    # We need to deal with this case, otherwise converting anything that
    # contains division will result in very confusing expressions.
    assert expression_from_sympy(sympy_multiplication) == FunctionCall(
        "div", expected_args)


@pytest.mark.parametrize(
import qiskit
from zquantum.core.wip.circuits.symbolic.expressions import FunctionCall, Symbol
from zquantum.core.wip.circuits.symbolic.qiskit_expressions import (
    QISKIT_DIALECT,
    expression_from_qiskit,
    integer_pow,
)
from zquantum.core.wip.circuits.symbolic.translations import translate_expression

THETA = qiskit.circuit.Parameter("theta")
PHI = qiskit.circuit.Parameter("phi")

EQUIVALENT_EXPRESSIONS = [
    (
        FunctionCall(
            name="add",
            args=(1, FunctionCall(name="mul", args=(2, Symbol(name="theta")))),
        ),
        THETA * 2 + 1,
    ),
    (
        FunctionCall(
            name="add",
            args=(1, FunctionCall(name="pow", args=(Symbol(name="theta"), 2))),
        ),
        THETA * THETA + 1,
    ),
    (
        FunctionCall(
            name="sub",
            args=(
                2,
    "pyquil_parameter, expected_symbol",
    [
        (quil.Parameter("theta"), Symbol("theta")),
        (quil.Parameter("x"), Symbol("x")),
        (quil.Parameter("x_1"), Symbol("x_1")),
    ],
)
def test_quil_parameters_are_converted_to_instance_of_symbol_with_correct_name(
        pyquil_parameter, expected_symbol):
    assert expression_from_pyquil(pyquil_parameter) == expected_symbol


@pytest.mark.parametrize(
    "pyquil_function_call, expected_function_call",
    [
        (quilatom.quil_cos(2), FunctionCall("cos", (2, ))),
        (
            quilatom.quil_sin(quil.Parameter("theta")),
            FunctionCall("sin", (Symbol("theta"), )),
        ),
        (quilatom.quil_exp(
            quil.Parameter("x")), FunctionCall("exp", (Symbol("x"), ))),
        (quilatom.quil_sqrt(np.pi), FunctionCall("sqrt", (np.pi, ))),
    ],
)
def test_pyquil_function_calls_are_converted_to_equivalent_function_call(
        pyquil_function_call, expected_function_call):
    assert expression_from_pyquil(
        pyquil_function_call) == expected_function_call