diff --git a/test_files/guppy_examples/modifiers.hugr b/test_files/guppy_examples/modifiers.hugr deleted file mode 100644 index 549f687a6..000000000 Binary files a/test_files/guppy_examples/modifiers.hugr and /dev/null differ diff --git a/test_files/guppy_examples/modifiers.py b/test_files/guppy_examples/modifiers.py deleted file mode 100644 index 7284821b2..000000000 --- a/test_files/guppy_examples/modifiers.py +++ /dev/null @@ -1,31 +0,0 @@ -# /// script -# requires-python = ">=3.13" -# dependencies = [ -# "guppylang ==0.21.14", -# ] -# [tool.uv.sources] -# guppylang = {git = "https://github.com/quantinuum/guppylang", subdirectory = "guppylang", branch = "ts/future-measure"} -# /// -"""A simple controlled gate using modifiers""" - -from pathlib import Path -from sys import argv - -from guppylang import guppy -from guppylang.std.builtins import control, dagger -from guppylang.std.quantum import qubit, s - -from guppylang.experimental import enable_experimental_features - -enable_experimental_features() - - -@guppy -def control_sdg(q0: qubit, q1: qubit) -> None: - with control(q0): - with dagger: - s(q1) - - -program = control_sdg.compile_function() -Path(argv[0]).with_suffix(".hugr").write_bytes(program.to_bytes()) diff --git a/test_files/guppy_examples/use_of_power.py b/test_files/guppy_examples/use_of_power.py index 376510ce9..291cafb6c 100644 --- a/test_files/guppy_examples/use_of_power.py +++ b/test_files/guppy_examples/use_of_power.py @@ -11,8 +11,7 @@ from pathlib import Path from sys import argv -from guppylang import guppy -from guppylang.experimental import enable_experimental_features +from guppylang import guppy, enable_experimental_features from guppylang.std.builtins import control, power from guppylang.std.quantum import angle, discard, qubit from guppylang.std.quantum import h, rx diff --git a/test_files/modifier_examples/assign_in_dagger.hugr b/test_files/modifier_examples/assign_in_dagger.hugr deleted file mode 100644 index d700db0c0..000000000 Binary files a/test_files/modifier_examples/assign_in_dagger.hugr and /dev/null differ diff --git a/test_files/modifier_examples/assign_in_dagger.py b/test_files/modifier_examples/assign_in_dagger.py deleted file mode 100644 index 838f11c94..000000000 --- a/test_files/modifier_examples/assign_in_dagger.py +++ /dev/null @@ -1,43 +0,0 @@ -# /// script -# requires-python = ">=3.13" -# dependencies = [ -# "guppylang==1.0.0a5", -# "guppylang-internals==1.0.0a5", -# ] -# /// -"""Testing assignment in dagger context""" - -from pathlib import Path -from sys import argv -import sys - -from guppylang import guppy -from guppylang.std.builtins import control, dagger -from guppylang.std.debug import state_result -from guppylang.std.quantum import discard, qubit, angle -from guppylang.std.quantum import h, rx - -sys.path.append(str(Path(__file__).resolve().parents[1])) - -from guppylang.experimental import enable_experimental_features - -enable_experimental_features() - - -@guppy -def main() -> None: - c1 = qubit() - t = qubit() - h(c1) - with dagger: - a = angle(1 / 3) - with control(c1): - rx(t, a) - - state_result("r", c1, t) - discard(c1) - discard(t) - - -program = main.compile() -Path(argv[0]).with_suffix(".hugr").write_bytes(program.to_bytes()) diff --git a/test_files/modifier_examples/call1_in_ctrl.hugr b/test_files/modifier_examples/call1_in_ctrl.hugr deleted file mode 100644 index f77f8fb4e..000000000 Binary files a/test_files/modifier_examples/call1_in_ctrl.hugr and /dev/null differ diff --git a/test_files/modifier_examples/call1_in_ctrl.py b/test_files/modifier_examples/call1_in_ctrl.py deleted file mode 100644 index 87d669e9a..000000000 --- a/test_files/modifier_examples/call1_in_ctrl.py +++ /dev/null @@ -1,46 +0,0 @@ -# /// script -# requires-python = ">=3.13" -# dependencies = [ -# "guppylang==1.0.0a5", -# "guppylang-internals==1.0.0a5", -# ] -# /// -"""Controlling a quantum function""" - -from pathlib import Path -from sys import argv -import sys - -from guppylang import guppy -from guppylang.std.builtins import control -from guppylang.std.debug import state_result -from guppylang.std.quantum import discard, qubit -from guppylang.std.quantum import h, x - -sys.path.append(str(Path(__file__).resolve().parents[1])) - -from guppylang.experimental import enable_experimental_features - -enable_experimental_features() - - -@guppy(unitary=True) -def bar(q: qubit) -> None: - x(q) - - -@guppy -def main() -> None: - q1 = qubit() - q2 = qubit() - h(q1) - with control(q1): - bar(q2) - - state_result("r", q1, q2) - discard(q1) - discard(q2) - - -program = main.compile() -Path(argv[0]).with_suffix(".hugr").write_bytes(program.to_bytes()) diff --git a/test_files/modifier_examples/call2_in_ctrl.hugr b/test_files/modifier_examples/call2_in_ctrl.hugr deleted file mode 100644 index 7f0cb55f7..000000000 Binary files a/test_files/modifier_examples/call2_in_ctrl.hugr and /dev/null differ diff --git a/test_files/modifier_examples/call2_in_ctrl.py b/test_files/modifier_examples/call2_in_ctrl.py deleted file mode 100644 index 3e7e4281c..000000000 --- a/test_files/modifier_examples/call2_in_ctrl.py +++ /dev/null @@ -1,52 +0,0 @@ -# /// script -# requires-python = ">=3.13" -# dependencies = [ -# "guppylang==1.0.0a5", -# "guppylang-internals==1.0.0a5", -# ] -# /// -"""Controlling a quantum function""" - -from pathlib import Path -from sys import argv -import sys - -from guppylang import guppy -from guppylang.std.builtins import control -from guppylang.std.debug import state_result -from guppylang.std.quantum import discard, qubit, angle -from guppylang.std.quantum import h, rx, x - -sys.path.append(str(Path(__file__).resolve().parents[1])) - -from guppylang.experimental import enable_experimental_features - -enable_experimental_features() - - -@guppy(unitary=True) -def bar(q: qubit) -> None: - rx(q, angle(1 / 3)) - - -@guppy -def main() -> None: - c1 = qubit() - t = qubit() - c2 = qubit() - c3 = qubit() - h(c1) - x(c2) - x(c3) - with control(c1, c2, c3): - bar(t) - - state_result("r", c1, c2, c3, t) - discard(c1) - discard(t) - discard(c3) - discard(c2) - - -program = main.compile() -Path(argv[0]).with_suffix(".hugr").write_bytes(program.to_bytes()) diff --git a/test_files/modifier_examples/call_in_dagger.hugr b/test_files/modifier_examples/call_in_dagger.hugr deleted file mode 100644 index f03b2b9d4..000000000 Binary files a/test_files/modifier_examples/call_in_dagger.hugr and /dev/null differ diff --git a/test_files/modifier_examples/call_in_dagger.py b/test_files/modifier_examples/call_in_dagger.py deleted file mode 100644 index d9880db56..000000000 --- a/test_files/modifier_examples/call_in_dagger.py +++ /dev/null @@ -1,45 +0,0 @@ -# /// script -# requires-python = ">=3.13" -# dependencies = [ -# "guppylang==1.0.0a5", -# "guppylang-internals==1.0.0a5", -# ] -# /// -"""Dagger modifier on a function call""" - -from pathlib import Path -from sys import argv -import sys - -from guppylang import guppy -from guppylang.std.builtins import dagger -from guppylang.std.debug import state_result -from guppylang.std.quantum import discard, qubit -from guppylang.std.quantum import s, h - -sys.path.append(str(Path(__file__).resolve().parents[1])) - -from guppylang.experimental import enable_experimental_features - -enable_experimental_features() - - -@guppy(unitary=True) -def bar(q: qubit) -> None: - s(q) - - -@guppy -def main() -> None: - t = qubit() - h(t) - - with dagger: - bar(t) - - state_result("r", t) - discard(t) - - -program = main.compile() -Path(argv[0]).with_suffix(".hugr").write_bytes(program.to_bytes()) diff --git a/test_files/modifier_examples/ctrl_on_cfg.hugr b/test_files/modifier_examples/cfg_in_ctrl.hugr similarity index 100% rename from test_files/modifier_examples/ctrl_on_cfg.hugr rename to test_files/modifier_examples/cfg_in_ctrl.hugr diff --git a/test_files/modifier_examples/ctrl_on_cfg.py b/test_files/modifier_examples/cfg_in_ctrl.py similarity index 80% rename from test_files/modifier_examples/ctrl_on_cfg.py rename to test_files/modifier_examples/cfg_in_ctrl.py index 6444a9c05..2e50286a9 100644 --- a/test_files/modifier_examples/ctrl_on_cfg.py +++ b/test_files/modifier_examples/cfg_in_ctrl.py @@ -5,21 +5,16 @@ # "guppylang-internals==1.0.0a5", # ] # /// -"""Controlling a function with internal control flow""" +"""Test control modifier on functions with internal control flow""" from pathlib import Path from sys import argv -import sys -from guppylang import guppy +from guppylang import enable_experimental_features, guppy +from guppylang.std.angles import angle from guppylang.std.builtins import control from guppylang.std.debug import state_result -from guppylang.std.quantum import discard, h, qubit, rx, x, rz -from guppylang.std.angles import angle - -sys.path.append(str(Path(__file__).resolve().parents[1])) - -from guppylang.experimental import enable_experimental_features +from guppylang.std.quantum import discard, h, qubit, rx, rz, x enable_experimental_features() diff --git a/test_files/modifier_examples/classical_array_op.hugr b/test_files/modifier_examples/classical_array_op.hugr deleted file mode 100644 index 25e803cec..000000000 Binary files a/test_files/modifier_examples/classical_array_op.hugr and /dev/null differ diff --git a/test_files/modifier_examples/classical_array_op.py b/test_files/modifier_examples/classical_array_op.py deleted file mode 100644 index 51838dba5..000000000 --- a/test_files/modifier_examples/classical_array_op.py +++ /dev/null @@ -1,45 +0,0 @@ -# /// script -# requires-python = ">=3.13" -# dependencies = [ -# "guppylang==1.0.0a5", -# "guppylang-internals==1.0.0a5", -# ] -# /// -"""Testing classical array operations in modifiers""" - -from pathlib import Path -from sys import argv -import sys - -from guppylang import guppy -from guppylang.std.debug import state_result -from guppylang.std.quantum import discard, qubit, h, x -from guppylang.std.builtins import array -import guppylang -from guppylang.std.builtins import control, dagger - -sys.path.append(str(Path(__file__).resolve().parents[1])) - - -guppylang.enable_experimental_features() - - -@guppy -def main() -> None: - arr = array(1, 1, 1, 1, 1) - q = qubit() - x(q) - with control(q), dagger: - arr[0] += 1 - arr[0] *= 2 - - if arr[0] == 4: - h(q) - - state_result("r", q) - discard(q) - - -program = main.compile_function() -program_bytes = program.to_bytes() -Path(argv[0]).with_suffix(".hugr").write_bytes(program_bytes) diff --git a/test_files/modifier_examples/classical_function.hugr b/test_files/modifier_examples/classical_function.hugr new file mode 100644 index 000000000..50345c794 Binary files /dev/null and b/test_files/modifier_examples/classical_function.hugr differ diff --git a/test_files/modifier_examples/classical_function.py b/test_files/modifier_examples/classical_function.py new file mode 100644 index 000000000..3f1d41d51 --- /dev/null +++ b/test_files/modifier_examples/classical_function.py @@ -0,0 +1,71 @@ +# /// script +# requires-python = ">=3.13" +# dependencies = [ +# "guppylang==1.0.0a5", +# "guppylang-internals==1.0.0a5", +# ] +# /// +"""Test the use of a classical function inside modifiers""" + +from pathlib import Path +from sys import argv + +from guppylang import enable_experimental_features, guppy +from guppylang.std.array import array_swap +from guppylang.std.builtins import array, control, dagger +from guppylang.std.debug import state_result +from guppylang.std.quantum import angle, discard, h, measure, qubit, rx, x + +enable_experimental_features() + + +@guppy +def fuu(i: int) -> int: + q = qubit() + x(q) + if measure(q): + i = i + 1 + return i + + +@guppy +def main() -> None: + t = qubit() + c1 = qubit() + c2 = qubit() + arr = array(1, 1, 2, 1, 1) + + # Testing that array operations are happening in the correct order + with control(t), dagger: + arr[1] += 1 + arr[1] *= 2 + if arr[1] == 4: + h(c1) + + # Test that array swap in a dagger and control context works correctly + with dagger: + array_swap(arr, 2, 4) + with control(c2): + array_swap(arr, 0, 4) + if arr[0] == 2: + h(c2) + + # Test that dagger and control does not affect the classical function + with control(c1): + d1 = fuu(2) + with dagger: + i = 2 + d2 = fuu(i) + d3 = fuu(i) + with control(c2): + d = (d1 + d2 + d3) / (i + 1) + rx(t, angle(1 / d)) + + state_result("r", c1, c2, t) + discard(c1) + discard(c2) + discard(t) + + +program = main.compile() +Path(argv[0]).with_suffix(".hugr").write_bytes(program.to_bytes()) diff --git a/test_files/modifier_examples/classical_function1.hugr b/test_files/modifier_examples/classical_function1.hugr deleted file mode 100644 index 5dd3eb9a1..000000000 Binary files a/test_files/modifier_examples/classical_function1.hugr and /dev/null differ diff --git a/test_files/modifier_examples/classical_function1.py b/test_files/modifier_examples/classical_function1.py deleted file mode 100644 index 0cce49faf..000000000 --- a/test_files/modifier_examples/classical_function1.py +++ /dev/null @@ -1,43 +0,0 @@ -# /// script -# requires-python = ">=3.13" -# dependencies = [ -# "guppylang==1.0.0a5", -# "guppylang-internals==1.0.0a5", -# ] -# /// -"""Test the use of a classical function inside modifiers""" - -from pathlib import Path -from sys import argv -import sys - -from guppylang import guppy -from guppylang.std.builtins import dagger -from guppylang.std.debug import state_result -from guppylang.std.quantum import discard, qubit, angle -from guppylang.std.quantum import rx - -sys.path.append(str(Path(__file__).resolve().parents[1])) - -from guppylang.experimental import enable_experimental_features - -enable_experimental_features() - - -@guppy -def fuu(i: int) -> int: - return i + 1 - - -@guppy -def main() -> None: - q = qubit() - with dagger: - rx(q, angle(1 / fuu(2))) - - state_result("r", q) - discard(q) - - -program = main.compile() -Path(argv[0]).with_suffix(".hugr").write_bytes(program.to_bytes()) diff --git a/test_files/modifier_examples/classical_function2.hugr b/test_files/modifier_examples/classical_function2.hugr deleted file mode 100644 index 55acb77fd..000000000 Binary files a/test_files/modifier_examples/classical_function2.hugr and /dev/null differ diff --git a/test_files/modifier_examples/classical_function2.py b/test_files/modifier_examples/classical_function2.py deleted file mode 100644 index 3a2b849ba..000000000 --- a/test_files/modifier_examples/classical_function2.py +++ /dev/null @@ -1,52 +0,0 @@ -# /// script -# requires-python = ">=3.13" -# dependencies = [ -# "guppylang==1.0.0a5", -# "guppylang-internals==1.0.0a5", -# ] -# /// -"""Test the use of a classical function inside modifiers""" - -from pathlib import Path -from sys import argv -import sys - -from guppylang import guppy -from guppylang.std.builtins import control, dagger -from guppylang.std.debug import state_result -from guppylang.std.quantum import discard, qubit, angle, measure -from guppylang.std.quantum import h, rx, x - -sys.path.append(str(Path(__file__).resolve().parents[1])) - -from guppylang.experimental import enable_experimental_features - -enable_experimental_features() - - -@guppy -def fuu(i: int) -> int: - q = qubit() - x(q) - if measure(q): - i = i + 1 - return i - - -@guppy -def main() -> None: - t = qubit() - c1 = qubit() - h(c1) - with control(c1): - d = fuu(2) - with dagger: - rx(t, angle(1 / d)) - - state_result("r", c1, t) - discard(c1) - discard(t) - - -program = main.compile() -Path(argv[0]).with_suffix(".hugr").write_bytes(program.to_bytes()) diff --git a/test_files/modifier_examples/classical_function3.hugr b/test_files/modifier_examples/classical_function3.hugr deleted file mode 100644 index 1f3f58223..000000000 Binary files a/test_files/modifier_examples/classical_function3.hugr and /dev/null differ diff --git a/test_files/modifier_examples/classical_function3.py b/test_files/modifier_examples/classical_function3.py deleted file mode 100644 index 28acbe044..000000000 --- a/test_files/modifier_examples/classical_function3.py +++ /dev/null @@ -1,56 +0,0 @@ -# /// script -# requires-python = ">=3.13" -# dependencies = [ -# "guppylang==1.0.0a5", -# "guppylang-internals==1.0.0a5", -# ] -# /// -"""Test the use of a classical function inside modifiers""" - -from pathlib import Path -from sys import argv -import sys - -from guppylang import guppy -from guppylang.std.builtins import control, dagger -from guppylang.std.debug import state_result -from guppylang.std.quantum import discard, qubit, angle, measure -from guppylang.std.quantum import h, rx, x - -sys.path.append(str(Path(__file__).resolve().parents[1])) - -from guppylang.experimental import enable_experimental_features - -enable_experimental_features() - - -@guppy -def fuu(i: int) -> int: - q = qubit() - x(q) - if measure(q): - i = i + 1 - return i - - -@guppy -def main() -> None: - t = qubit() - c1 = qubit() - c2 = qubit() - h(c1) - h(c2) - with control(c1): - with control(c2): - with dagger: - d = fuu(2) - rx(t, angle(1 / d)) - - state_result("r", c1, c2, t) - discard(c1) - discard(c2) - discard(t) - - -program = main.compile() -Path(argv[0]).with_suffix(".hugr").write_bytes(program.to_bytes()) diff --git a/test_files/modifier_examples/complex_cfg_higher_order.hugr b/test_files/modifier_examples/complex_cfg_higher_order.hugr new file mode 100644 index 000000000..172fbf840 Binary files /dev/null and b/test_files/modifier_examples/complex_cfg_higher_order.hugr differ diff --git a/test_files/modifier_examples/complex_cfg_higher_order.py b/test_files/modifier_examples/complex_cfg_higher_order.py new file mode 100644 index 000000000..2f5e7697c --- /dev/null +++ b/test_files/modifier_examples/complex_cfg_higher_order.py @@ -0,0 +1,79 @@ +# /// script +# requires-python = ">=3.13" +# dependencies = [ +# "guppylang==1.0.0a5", +# "guppylang-internals==1.0.0a5", +# ] +# /// +"""Test the use of a higher-order function with complex control flow inside modifiers""" + +from collections.abc import Callable +from pathlib import Path +from sys import argv + +from guppylang import enable_experimental_features, guppy +from guppylang.std.builtins import Controllable, Unitary, array, control, dagger +from guppylang.std.debug import state_result +from guppylang.std.quantum import angle, discard_array, h, qubit, rx, rz + +enable_experimental_features() + + +@guppy +def get_angle(f: float) -> angle: + return angle(f) + + +@guppy +def get_get_angle() -> Callable[[float], angle]: + return get_angle + + +@guppy(unitary=True) +def apply_r( + f: Unitary[[qubit, angle], None], + q: array[qubit, 2], + fun_angle: Callable[[float], angle], + radiant: float, +) -> None: + f(q[1], fun_angle(radiant)) + + +@guppy(controllable=True) +def apply_c( + f: Controllable[[qubit], None], + g: Unitary[[qubit, angle], None], + classic_fun: Callable[[], Callable[[float], angle]], + q: qubit, + b: bool, +) -> None: + n = 3 + if b: + while n > 0: + f(q) + n -= 1 + else: + get_a = classic_fun() + for _ in range(2): + g(q, get_a(0.5)) + + +@guppy +def main() -> None: + qs: array[qubit, 2] = array(qubit(), qubit()) + h(qs[0]) + flag = 2 > 10 + with control(qs[0]): + apply_c(h, rx, get_get_angle, qs[1], True) + apply_c(h, rx, get_get_angle, qs[1], flag) + + with control(qs[0]), dagger: + apply_r(rz, qs, get_angle, 0.25) + apply_r(rz, qs, get_angle, 0.5) + + state_result("r", qs[0], qs[1]) + discard_array(qs) + + +program = main.compile() +Path(argv[0]).with_suffix(".hugr").write_bytes(program.to_bytes()) diff --git a/test_files/modifier_examples/complex_modifier_stress.hugr b/test_files/modifier_examples/complex_modifier_stress.hugr deleted file mode 100644 index d6ec0fdb4..000000000 Binary files a/test_files/modifier_examples/complex_modifier_stress.hugr and /dev/null differ diff --git a/test_files/modifier_examples/complex_modifier_stress.py b/test_files/modifier_examples/complex_modifier_stress.py deleted file mode 100644 index a337d904b..000000000 --- a/test_files/modifier_examples/complex_modifier_stress.py +++ /dev/null @@ -1,143 +0,0 @@ -# /// script -# requires-python = ">=3.13" -# dependencies = [ -# "guppylang==1.0.0a5", -# "guppylang-internals==1.0.0a5", -# ] -# /// -"""A stress test for nested control and dagger modifiers.""" - -from pathlib import Path -from sys import argv -import sys - -from guppylang import guppy -from guppylang.std.builtins import array, control, dagger -from guppylang.std.debug import state_result -from guppylang.std.quantum import ( - angle, - discard, - discard_array, - measure, - qubit, - h, - rx, - rz, - x, -) - -sys.path.append(str(Path(__file__).resolve().parents[1])) - -from guppylang.experimental import enable_experimental_features - -enable_experimental_features() - - -@guppy -def measured_offset(i: int) -> int: - q = qubit() - x(q) - if measure(q): - i = i + 1 - return i - - -@guppy(unitary=True) -def rotation(q: qubit) -> None: - rx(q, angle(-1 / 7)) - - -@guppy(unitary=True) -def flip(q: qubit) -> None: - x(q) - - -@guppy(unitary=True) -def phase_ladder(q: qubit) -> None: - with dagger: - rotation(q) - x(q) - rz(q, angle(1 / 5)) - - -@guppy -def main() -> None: - array_controllers: array[qubit, 2] = array(qubit(), qubit()) - control_a = qubit() - control_b = qubit() - control_c = qubit() - target_a = qubit() - target_b = qubit() - target_c = qubit() - - h(array_controllers[0]) - h(array_controllers[1]) - h(control_a) - h(control_b) - h(control_c) - h(target_a) - h(target_b) - h(target_c) - - with control(control_a): - with dagger: - rotation(target_a) - - with control(control_a, control_b): - with dagger: - phase_ladder(target_a) - - with dagger: - with control(control_b): - rotation(target_b) - - with control(array_controllers): - with dagger: - rotation(target_b) - - with control(control_a): - denominator = measured_offset(4) - with control(control_b, control_c): - with dagger: - rz(target_c, angle(1 / denominator)) - - with dagger: - with dagger: - with control(control_c): - flip(target_c) - - with control(control_a, control_b, control_c): - with dagger: - rz(target_c, angle(1 / 6)) - - with control(control_a, control_b, control_c): - a = 3 - x(target_a) - with dagger: - rz(target_b, angle(1 / a)) - with control(array_controllers): - rz(target_c, angle(1 / (a + 2))) - - state_result( - "r", - array_controllers[0], - array_controllers[1], - control_a, - control_b, - control_c, - target_a, - target_b, - target_c, - ) - - discard_array(array_controllers) - discard(control_a) - discard(control_b) - discard(control_c) - discard(target_a) - discard(target_b) - discard(target_c) - - -program = main.compile() -Path(argv[0]).with_suffix(".hugr").write_bytes(program.to_bytes()) diff --git a/test_files/modifier_examples/ctrl_array_controller.hugr b/test_files/modifier_examples/ctrl_array_controller.hugr deleted file mode 100644 index ed63ad5d2..000000000 Binary files a/test_files/modifier_examples/ctrl_array_controller.hugr and /dev/null differ diff --git a/test_files/modifier_examples/ctrl_array_controller.py b/test_files/modifier_examples/ctrl_array_controller.py deleted file mode 100644 index 8219097c0..000000000 --- a/test_files/modifier_examples/ctrl_array_controller.py +++ /dev/null @@ -1,51 +0,0 @@ -# /// script -# requires-python = ">=3.13" -# dependencies = [ -# "guppylang==1.0.0a5", -# "guppylang-internals==1.0.0a5", -# ] -# /// -"""A controlled gate where the controller is an array of qubits""" - -from pathlib import Path -from sys import argv -import sys - -from guppylang import guppy -from guppylang.std.builtins import array, control -from guppylang.std.debug import state_result -from guppylang.std.quantum import discard, discard_array, qubit -from guppylang.std.quantum import h, x - -sys.path.append(str(Path(__file__).resolve().parents[1])) - -from guppylang.experimental import enable_experimental_features - -enable_experimental_features() - - -@guppy(unitary=True) -def bar(q: qubit) -> None: - x(q) - - -@guppy -def main() -> None: - controllers: array[qubit, 3] = array(qubit(), qubit(), qubit()) - t = qubit() - - h(controllers[0]) - h(controllers[1]) - h(controllers[2]) - - with control(controllers): - bar(t) - - state_result("r", controllers[0], controllers[1], controllers[2], t) - - discard_array(controllers) - discard(t) - - -program = main.compile() -Path(argv[0]).with_suffix(".hugr").write_bytes(program.to_bytes()) diff --git a/test_files/modifier_examples/double_modifier.hugr b/test_files/modifier_examples/double_modifier.hugr index 70f12fdfa..cd03c3d4b 100644 Binary files a/test_files/modifier_examples/double_modifier.hugr and b/test_files/modifier_examples/double_modifier.hugr differ diff --git a/test_files/modifier_examples/double_modifier.py b/test_files/modifier_examples/double_modifier.py index 36921e21d..e938b1044 100644 --- a/test_files/modifier_examples/double_modifier.py +++ b/test_files/modifier_examples/double_modifier.py @@ -5,21 +5,18 @@ # "guppylang-internals==1.0.0a5", # ] # /// -"""Testing nested modifiers""" +"""Testing nested modifiers + +The hugr generated from this script is also used to benchmark the performance of modifier passes resolver +""" from pathlib import Path from sys import argv -import sys -from guppylang import guppy +from guppylang import enable_experimental_features, guppy from guppylang.std.builtins import control, dagger from guppylang.std.debug import state_result -from guppylang.std.quantum import discard, qubit, angle -from guppylang.std.quantum import h, rx - -sys.path.append(str(Path(__file__).resolve().parents[1])) - -from guppylang.experimental import enable_experimental_features +from guppylang.std.quantum import angle, discard, h, qubit, ry enable_experimental_features() @@ -31,7 +28,7 @@ def main() -> None: h(c1) with control(c1): with dagger: - rx(t, angle(1 / 3)) + ry(t, angle(1 / 3)) state_result("r", c1, t) discard(c1) diff --git a/test_files/modifier_examples/even_dagger.hugr b/test_files/modifier_examples/even_dagger.hugr index b3e40d964..64d4018e7 100644 Binary files a/test_files/modifier_examples/even_dagger.hugr and b/test_files/modifier_examples/even_dagger.hugr differ diff --git a/test_files/modifier_examples/even_dagger.py b/test_files/modifier_examples/even_dagger.py index c45226c20..6acb5dda9 100644 --- a/test_files/modifier_examples/even_dagger.py +++ b/test_files/modifier_examples/even_dagger.py @@ -5,31 +5,46 @@ # "guppylang-internals==1.0.0a5", # ] # /// -"""A stress test for nested control and dagger modifiers.""" +"""Test that an even number of daggers is equivalent to no dagger at all""" from pathlib import Path from sys import argv -from guppylang import guppy +from guppylang import enable_experimental_features, guppy from guppylang.std.builtins import control, dagger from guppylang.std.debug import state_result -from guppylang.std.quantum import angle, discard, qubit, rx, h +from guppylang.std.quantum import angle, discard, h, qubit, rx +enable_experimental_features() -from guppylang.experimental import enable_experimental_features -enable_experimental_features() +@guppy(controllable=True) +def rotation(q: qubit, f: float) -> None: + rx(q, angle(f)) @guppy def main() -> None: c = qubit() q = qubit() + flag = True + + with dagger, dagger: + # cfg is normally forbidden in a dagger context + if flag: + rotation(c, 1 / 4) + + with dagger, dagger: + f = 1 / 4 + with dagger: + rx(c, angle(f)) + h(c) with dagger: with control(c): with dagger: - rx(q, angle(1 / 3)) + # rotation is only `controllable`: fine since we have 2 daggers + rotation(q, 1 / 3) state_result("r", c, q) diff --git a/test_files/modifier_examples/gate_in_ctrl.hugr b/test_files/modifier_examples/gate_in_ctrl.hugr deleted file mode 100644 index 43309a1d7..000000000 Binary files a/test_files/modifier_examples/gate_in_ctrl.hugr and /dev/null differ diff --git a/test_files/modifier_examples/gate_in_ctrl.py b/test_files/modifier_examples/gate_in_ctrl.py deleted file mode 100644 index 1d47051bc..000000000 --- a/test_files/modifier_examples/gate_in_ctrl.py +++ /dev/null @@ -1,40 +0,0 @@ -# /// script -# requires-python = ">=3.13" -# dependencies = [ -# "guppylang==1.0.0a5", -# "guppylang-internals==1.0.0a5", -# ] -# /// -"""A simple controlled gate using modifiers""" - -from pathlib import Path -from sys import argv -import sys - -from guppylang import guppy -from guppylang.std.builtins import control -from guppylang.std.debug import state_result -from guppylang.std.quantum import qubit, discard -from guppylang.std.quantum import h, x - -sys.path.append(str(Path(__file__).resolve().parents[1])) -from guppylang.experimental import enable_experimental_features - -enable_experimental_features() - - -@guppy -def main() -> None: - q1 = qubit() - q2 = qubit() - h(q1) - with control(q1): - x(q2) - - state_result("r", q1, q2) - discard(q1) - discard(q2) - - -program = main.compile() -Path(argv[0]).with_suffix(".hugr").write_bytes(program.to_bytes()) diff --git a/test_files/modifier_examples/higher_order_classical.hugr b/test_files/modifier_examples/higher_order_classical.hugr deleted file mode 100644 index 4ed4bc05d..000000000 Binary files a/test_files/modifier_examples/higher_order_classical.hugr and /dev/null differ diff --git a/test_files/modifier_examples/higher_order_classical.py b/test_files/modifier_examples/higher_order_classical.py deleted file mode 100644 index 9e1b0d064..000000000 --- a/test_files/modifier_examples/higher_order_classical.py +++ /dev/null @@ -1,65 +0,0 @@ -# /// script -# requires-python = ">=3.13" -# dependencies = [ -# "guppylang==1.0.0a5", -# "guppylang-internals==1.0.0a5", -# ] -# /// -"""Test the use of a higher-order classical function inside modifiers""" - -from pathlib import Path -from sys import argv -from typing import Callable - -from guppylang import guppy -from guppylang.std.builtins import ( - Unitary, - control, - dagger, -) -from guppylang.std.debug import state_result -from guppylang.std.quantum import discard, qubit, angle, ry, rz, rx -from guppylang.experimental import enable_experimental_features - -enable_experimental_features() - - -@guppy(unitary=True) -def apply_c( - g: Unitary[[qubit, angle], None], - fun: Callable[[float], angle], - q: qubit, -) -> None: - a = fun(0.5) - g(q, a) - - -@guppy -def fun(f: float) -> angle: - return angle(f) - - -@guppy -def gun(f: float) -> angle: - return angle(-f) - - -@guppy -def main() -> None: - q = qubit() - c = qubit() - - with dagger: - apply_c(ry, gun, c) - - with control(c), dagger(): - apply_c(rz, fun, q) - apply_c(rx, fun, q) - - state_result("r", c, q) - discard(q) - discard(c) - - -program = main.compile() -Path(argv[0]).with_suffix(".hugr").write_bytes(program.to_bytes()) diff --git a/test_files/modifier_examples/higher_order_function_w_loops.hugr b/test_files/modifier_examples/higher_order_function_w_loops.hugr deleted file mode 100644 index 3d03a2295..000000000 Binary files a/test_files/modifier_examples/higher_order_function_w_loops.hugr and /dev/null differ diff --git a/test_files/modifier_examples/higher_order_function_w_loops.py b/test_files/modifier_examples/higher_order_function_w_loops.py deleted file mode 100644 index 97d8f5eb0..000000000 --- a/test_files/modifier_examples/higher_order_function_w_loops.py +++ /dev/null @@ -1,66 +0,0 @@ -# /// script -# requires-python = ">=3.13" -# dependencies = [ -# "guppylang==1.0.0a5", -# "guppylang-internals==1.0.0a5", -# ] -# /// -"""Test the use of a higher-order function with loops inside modifiers""" - -from pathlib import Path -from sys import argv - -from guppylang import guppy -from guppylang.std.builtins import ( - Controllable, - Unitary, - array, - control, - dagger, -) -from guppylang.std.debug import state_result -from guppylang.std.quantum import discard_array, qubit, angle, rz -from guppylang.std.quantum import h, rx -from guppylang.experimental import enable_experimental_features - -enable_experimental_features() - - -@guppy(unitary=True) -def apply_r(f: Unitary[[qubit, angle], None], q: array[qubit, 2], angle: angle) -> None: - f(q[1], angle) - - -@guppy(controllable=True) -def apply_c( - f: Controllable[[qubit], None], g: Unitary[[qubit, angle], None], q: qubit, b: bool -) -> None: - n = 3 - if b: - while n > 0: - f(q) - n -= 1 - else: - for _ in range(2): - g(q, angle(0.5)) - - -@guppy -def main() -> None: - qs: array[qubit, 2] = array(qubit(), qubit()) - h(qs[0]) - flag = 2 > 10 - with control(qs[0]): - apply_c(h, rx, qs[1], True) - apply_c(h, rx, qs[1], flag) - - with control(qs[0]), dagger: - apply_r(rz, qs, angle(0.25)) - apply_r(rz, qs, angle(0.5)) - - state_result("r", qs[0], qs[1]) - discard_array(qs) - - -program = main.compile() -Path(argv[0]).with_suffix(".hugr").write_bytes(program.to_bytes()) diff --git a/test_files/modifier_examples/higher_order_recursive.hugr b/test_files/modifier_examples/higher_order_recursive.hugr index 7f2cd58d8..40d4fbd70 100644 Binary files a/test_files/modifier_examples/higher_order_recursive.hugr and b/test_files/modifier_examples/higher_order_recursive.hugr differ diff --git a/test_files/modifier_examples/higher_order_recursive.py b/test_files/modifier_examples/higher_order_recursive.py index f2db602ab..e65d53a69 100644 --- a/test_files/modifier_examples/higher_order_recursive.py +++ b/test_files/modifier_examples/higher_order_recursive.py @@ -10,16 +10,14 @@ from pathlib import Path from sys import argv -from guppylang import guppy +from guppylang import enable_experimental_features, guppy from guppylang.std.builtins import ( Unitary, control, dagger, ) from guppylang.std.debug import state_result -from guppylang.std.quantum import discard, qubit -from guppylang.std.quantum import h, s -from guppylang.experimental import enable_experimental_features +from guppylang.std.quantum import discard, h, qubit, s, x enable_experimental_features() @@ -39,12 +37,23 @@ def apply2(f: Unitary[[qubit], None], q: qubit) -> None: f(q) +@guppy(controllable=True) +def apply_if(f: Unitary[[qubit], None], q: qubit, b: bool) -> None: + if b: + apply(f, q) + + @guppy def main() -> None: q = qubit() c = qubit() - h(c) + x(c) + flag = True + with control(c): + apply_if(x, q, flag) + apply_if(h, q, not flag) + h(c) with control(c), dagger: apply(s, q) apply(h, q) diff --git a/test_files/modifier_examples/justfile b/test_files/modifier_examples/justfile index ed80d92ba..37deb9165 100644 --- a/test_files/modifier_examples/justfile +++ b/test_files/modifier_examples/justfile @@ -2,9 +2,6 @@ help: @just --list --justfile {{justfile()}} -# Re-generate all hugr files -r: recompile-hugrs - # Re-generate all hugr files. recompile-hugrs: #!/usr/bin/env sh diff --git a/test_files/modifier_examples/loaded_pytket.hugr b/test_files/modifier_examples/loaded_pytket.hugr new file mode 100644 index 000000000..ed4b92edf Binary files /dev/null and b/test_files/modifier_examples/loaded_pytket.hugr differ diff --git a/test_files/modifier_examples/loaded_pytket.py b/test_files/modifier_examples/loaded_pytket.py new file mode 100644 index 000000000..afa281ed9 --- /dev/null +++ b/test_files/modifier_examples/loaded_pytket.py @@ -0,0 +1,47 @@ +# /// script +# requires-python = ">=3.13" +# dependencies = [ +# "guppylang" +# ] +# [tool.uv.sources] +# guppylang = {git = "https://github.com/quantinuum/guppylang", subdirectory = "guppylang", branch = "na/1325-inferflag"} +# /// +"""Testing modifier on a loaded pytket circuit""" + +from pathlib import Path +from sys import argv + +from guppylang import enable_experimental_features, guppy +from guppylang.std.builtins import control, dagger +from guppylang.std.debug import state_result +from guppylang.std.quantum import discard, h, qubit +from pytket import Circuit + +enable_experimental_features() + +# PyTket circuit +circ = Circuit(2) +circ.Rz(-0.5, 0) +circ.Ry(-0.5, 1) +circ.H(0) + +guppy_circ = guppy.load_pytket("guppy_circ_2", circ, use_arrays=False) + + +@guppy +def main() -> None: + q1 = qubit() + q2 = qubit() + c = qubit() + h(c) + with control(c), dagger: + guppy_circ(q1, q2) + + state_result("r", c, q1, q2) + discard(q1) + discard(q2) + discard(c) + + +program = main.compile() +Path(argv[0]).with_suffix(".hugr").write_bytes(program.to_bytes()) diff --git a/test_files/modifier_examples/modify_array.hugr b/test_files/modifier_examples/modify_array.hugr deleted file mode 100644 index f7321bc61..000000000 Binary files a/test_files/modifier_examples/modify_array.hugr and /dev/null differ diff --git a/test_files/modifier_examples/modify_array.py b/test_files/modifier_examples/modify_array.py deleted file mode 100644 index ce714b43f..000000000 --- a/test_files/modifier_examples/modify_array.py +++ /dev/null @@ -1,46 +0,0 @@ -# /// script -# requires-python = ">=3.13" -# dependencies = [ -# "guppylang==1.0.0a5", -# "guppylang-internals==1.0.0a5", -# ] -# /// -"""Test control modifiers on an array element""" - -from pathlib import Path -from sys import argv -import sys - -from guppylang import guppy -from guppylang.std.builtins import control -from guppylang.std.debug import state_result -from guppylang.std.quantum import discard, qubit, array, discard_array -from guppylang.std.quantum import h - -sys.path.append(str(Path(__file__).resolve().parents[1])) - - -from guppylang.experimental import enable_experimental_features - -enable_experimental_features() - -hugr_pdf_directory = Path(__file__).resolve().parents[1] / "0_hugr_pdf" -hugr_pdf_directory.mkdir(exist_ok=True) - - -@guppy -def main() -> None: - q = qubit() - h(q) - array_controllers: array[qubit, 2] = array(qubit(), qubit()) - - with control(q): - h(array_controllers[1]) - - state_result("r", q, array_controllers[0], array_controllers[1]) - discard_array(array_controllers) - discard(q) - - -program = main.compile() -Path(argv[0]).with_suffix(".hugr").write_bytes(program.to_bytes()) diff --git a/test_files/modifier_examples/multiple_dagger.hugr b/test_files/modifier_examples/multiple_dagger.hugr deleted file mode 100644 index 4452f63f6..000000000 Binary files a/test_files/modifier_examples/multiple_dagger.hugr and /dev/null differ diff --git a/test_files/modifier_examples/multiple_dagger.py b/test_files/modifier_examples/multiple_dagger.py deleted file mode 100644 index bb28769a3..000000000 --- a/test_files/modifier_examples/multiple_dagger.py +++ /dev/null @@ -1,48 +0,0 @@ -# /// script -# requires-python = ">=3.13" -# dependencies = [ -# "guppylang==1.0.0a5", -# "guppylang-internals==1.0.0a5", -# ] -# /// -"""An example with an even number of daggers, which should cancel out""" - -from pathlib import Path -from sys import argv -import sys - -from guppylang import guppy -from guppylang.std.builtins import dagger -from guppylang.std.debug import state_result -from guppylang.std.quantum import discard, qubit, angle -from guppylang.std.quantum import rx - -sys.path.append(str(Path(__file__).resolve().parents[1])) - -from guppylang.experimental import enable_experimental_features - -enable_experimental_features() - - -@guppy(unitary=True) -def rotation(q: qubit) -> None: - rx(q, angle(1 / 4)) - - -@guppy -def main() -> None: - t = qubit() - - with dagger: - with dagger: - rotation(t) - - with dagger, dagger, dagger: - rotation(t) - - state_result("r", t) - discard(t) - - -program = main.compile() -Path(argv[0]).with_suffix(".hugr").write_bytes(program.to_bytes()) diff --git a/test_files/modifier_examples/multiple_functions.hugr b/test_files/modifier_examples/multiple_functions.hugr new file mode 100644 index 000000000..69415fc72 Binary files /dev/null and b/test_files/modifier_examples/multiple_functions.hugr differ diff --git a/test_files/modifier_examples/multiple_functions_in_ctrl_dagger.py b/test_files/modifier_examples/multiple_functions.py similarity index 64% rename from test_files/modifier_examples/multiple_functions_in_ctrl_dagger.py rename to test_files/modifier_examples/multiple_functions.py index 4ade3c92b..4da997552 100644 --- a/test_files/modifier_examples/multiple_functions_in_ctrl_dagger.py +++ b/test_files/modifier_examples/multiple_functions.py @@ -5,22 +5,17 @@ # "guppylang-internals==1.0.0a5", # ] # /// -"""Testing a dagger modifier on multiple functions""" +"""Testing a dagger modifier on multiple functions, to ensure that the dagger is +reversing the order of quantum operations""" from pathlib import Path from sys import argv -import sys -from guppylang import guppy +from guppylang import enable_experimental_features, guppy +from guppylang.std.angles import angle from guppylang.std.builtins import control, dagger from guppylang.std.debug import state_result -from guppylang.std.quantum import discard, qubit -from guppylang.std.quantum import s, rx, h -from guppylang.std.angles import angle - -sys.path.append(str(Path(__file__).resolve().parents[1])) - -from guppylang.experimental import enable_experimental_features +from guppylang.std.quantum import discard, qubit, rx, s enable_experimental_features() @@ -36,22 +31,27 @@ def foo1(q: qubit) -> None: @guppy(unitary=True) -def foo2(q: qubit, f: float) -> None: +def foo2(q: qubit) -> None: s(q) - rx(q, angle(f)) + rx(q, angle(1 / 6)) + + +@guppy(unitary=True) +def foo3(q: qubit, f: float) -> None: + rx(q, angle(f / 2)) @guppy def main() -> None: - t = qubit() c = qubit() - h(c) + t = qubit() with dagger: with control(c): - foo1(t) f = get_f() - foo2(t, f) + foo2(t) + foo3(t, f) + foo1(c) state_result("r", c, t) discard(t) diff --git a/test_files/modifier_examples/multiple_functions_in_ctrl_dagger.hugr b/test_files/modifier_examples/multiple_functions_in_ctrl_dagger.hugr deleted file mode 100644 index bad59d852..000000000 Binary files a/test_files/modifier_examples/multiple_functions_in_ctrl_dagger.hugr and /dev/null differ diff --git a/test_files/modifier_examples/multiple_functions_in_dagger.hugr b/test_files/modifier_examples/multiple_functions_in_dagger.hugr deleted file mode 100644 index fbb7d1e49..000000000 Binary files a/test_files/modifier_examples/multiple_functions_in_dagger.hugr and /dev/null differ diff --git a/test_files/modifier_examples/multiple_functions_in_dagger.py b/test_files/modifier_examples/multiple_functions_in_dagger.py deleted file mode 100644 index 9d982e11c..000000000 --- a/test_files/modifier_examples/multiple_functions_in_dagger.py +++ /dev/null @@ -1,63 +0,0 @@ -# /// script -# requires-python = ">=3.13" -# dependencies = [ -# "guppylang==1.0.0a5", -# "guppylang-internals==1.0.0a5", -# ] -# /// -"""Testing a dagger modifier on multiple functions""" - -from pathlib import Path -from sys import argv -import sys - -from guppylang import guppy -from guppylang.std.builtins import dagger -from guppylang.std.debug import state_result -from guppylang.std.quantum import discard, qubit -from guppylang.std.quantum import s, rx -from guppylang.std.angles import angle - -sys.path.append(str(Path(__file__).resolve().parents[1])) - -from guppylang.experimental import enable_experimental_features - -enable_experimental_features() - - -@guppy -def get_f() -> float: - return 1 / 3 - - -@guppy(unitary=True) -def foo1(q: qubit) -> None: - rx(q, angle(1 / 2)) - - -@guppy(unitary=True) -def foo2(q: qubit) -> None: - s(q) - - -@guppy(unitary=True) -def foo3(q: qubit, f: float) -> None: - rx(q, angle(f)) - - -@guppy -def main() -> None: - t = qubit() - - with dagger: - foo1(t) - f = get_f() - foo2(t) - foo3(t, f) - - state_result("r", t) - discard(t) - - -program = main.compile() -Path(argv[0]).with_suffix(".hugr").write_bytes(program.to_bytes()) diff --git a/test_files/modifier_examples/multiple_gates1_in_ctrl.hugr b/test_files/modifier_examples/multiple_gates1_in_ctrl.hugr deleted file mode 100644 index 624473683..000000000 Binary files a/test_files/modifier_examples/multiple_gates1_in_ctrl.hugr and /dev/null differ diff --git a/test_files/modifier_examples/multiple_gates1_in_ctrl.py b/test_files/modifier_examples/multiple_gates1_in_ctrl.py deleted file mode 100644 index 0b2135b0a..000000000 --- a/test_files/modifier_examples/multiple_gates1_in_ctrl.py +++ /dev/null @@ -1,44 +0,0 @@ -# /// script -# requires-python = ">=3.13" -# dependencies = [ -# "guppylang==1.0.0a5", -# "guppylang-internals==1.0.0a5", -# ] -# /// -"""Testing a control modifier on multiple gates""" - -from pathlib import Path -from sys import argv -import sys - -from guppylang import guppy -from guppylang.std.builtins import control -from guppylang.std.debug import state_result -from guppylang.std.quantum import discard, qubit -from guppylang.std.quantum import rz, h, angle - -sys.path.append(str(Path(__file__).resolve().parents[1])) - -from guppylang.experimental import enable_experimental_features - -enable_experimental_features() - - -@guppy -def main() -> None: - c = qubit() - t = qubit() - h(c) - - with control(c): - h(t) - rz(t, angle(1 / 3)) - h(t) - - state_result("r", c, t) - discard(t) - discard(c) - - -program = main.compile() -Path(argv[0]).with_suffix(".hugr").write_bytes(program.to_bytes()) diff --git a/test_files/modifier_examples/multiple_gates1_in_dagger.hugr b/test_files/modifier_examples/multiple_gates1_in_dagger.hugr deleted file mode 100644 index ce0f840e8..000000000 Binary files a/test_files/modifier_examples/multiple_gates1_in_dagger.hugr and /dev/null differ diff --git a/test_files/modifier_examples/multiple_gates1_in_dagger.py b/test_files/modifier_examples/multiple_gates1_in_dagger.py deleted file mode 100644 index c5cfc8cb0..000000000 --- a/test_files/modifier_examples/multiple_gates1_in_dagger.py +++ /dev/null @@ -1,41 +0,0 @@ -# /// script -# requires-python = ">=3.13" -# dependencies = [ -# "guppylang==1.0.0a5", -# "guppylang-internals==1.0.0a5", -# ] -# /// -"""Testing a dagger modifier on multiple gates""" - -from pathlib import Path -from sys import argv -import sys - -from guppylang import guppy -from guppylang.std.builtins import dagger -from guppylang.std.debug import state_result -from guppylang.std.quantum import discard, qubit -from guppylang.std.quantum import sdg, h - -sys.path.append(str(Path(__file__).resolve().parents[1])) - -from guppylang.experimental import enable_experimental_features - -enable_experimental_features() - - -@guppy -def main() -> None: - t = qubit() - - with dagger: - h(t) - sdg(t) - h(t) - - state_result("r", t) - discard(t) - - -program = main.compile() -Path(argv[0]).with_suffix(".hugr").write_bytes(program.to_bytes()) diff --git a/test_files/modifier_examples/multiple_gates2_in_ctrl.hugr b/test_files/modifier_examples/multiple_gates2_in_ctrl.hugr deleted file mode 100644 index c6907dfac..000000000 Binary files a/test_files/modifier_examples/multiple_gates2_in_ctrl.hugr and /dev/null differ diff --git a/test_files/modifier_examples/multiple_gates2_in_ctrl.py b/test_files/modifier_examples/multiple_gates2_in_ctrl.py deleted file mode 100644 index a0522c53b..000000000 --- a/test_files/modifier_examples/multiple_gates2_in_ctrl.py +++ /dev/null @@ -1,49 +0,0 @@ -# /// script -# requires-python = ">=3.13" -# dependencies = [ -# "guppylang==1.0.0a5", -# "guppylang-internals==1.0.0a5", -# ] -# /// -"""Testing a control modifier on multiple gates""" - -from pathlib import Path -from sys import argv -import sys - -from guppylang import guppy -from guppylang.std.builtins import control -from guppylang.std.debug import state_result -from guppylang.std.quantum import discard, qubit -from guppylang.std.quantum import rz, h, angle - -sys.path.append(str(Path(__file__).resolve().parents[1])) - -from guppylang.experimental import enable_experimental_features - -enable_experimental_features() - - -@guppy(unitary=True) -def bar(q: qubit) -> None: - h(q) - rz(q, angle(1 / 3)) - h(q) - - -@guppy -def main() -> None: - t = qubit() - c = qubit() - h(c) - - with control(c): - bar(t) - - state_result("r", c, t) - discard(t) - discard(c) - - -program = main.compile() -Path(argv[0]).with_suffix(".hugr").write_bytes(program.to_bytes()) diff --git a/test_files/modifier_examples/multiple_gates2_in_dagger.hugr b/test_files/modifier_examples/multiple_gates2_in_dagger.hugr deleted file mode 100644 index cc5841a74..000000000 Binary files a/test_files/modifier_examples/multiple_gates2_in_dagger.hugr and /dev/null differ diff --git a/test_files/modifier_examples/multiple_gates2_in_dagger.py b/test_files/modifier_examples/multiple_gates2_in_dagger.py deleted file mode 100644 index be2deb3ef..000000000 --- a/test_files/modifier_examples/multiple_gates2_in_dagger.py +++ /dev/null @@ -1,46 +0,0 @@ -# /// script -# requires-python = ">=3.13" -# dependencies = [ -# "guppylang==1.0.0a5", -# "guppylang-internals==1.0.0a5", -# ] -# /// -"""Testing a dagger modifier on multiple gates""" - -from pathlib import Path -from sys import argv -import sys - -from guppylang import guppy -from guppylang.std.builtins import dagger -from guppylang.std.debug import state_result -from guppylang.std.quantum import discard, qubit -from guppylang.std.quantum import s, h - -sys.path.append(str(Path(__file__).resolve().parents[1])) - -from guppylang.experimental import enable_experimental_features - -enable_experimental_features() - - -@guppy(unitary=True) -def bar(q: qubit) -> None: - h(q) - s(q) - h(q) - - -@guppy -def main() -> None: - t = qubit() - - with dagger: - bar(t) - - state_result("r", t) - discard(t) - - -program = main.compile() -Path(argv[0]).with_suffix(".hugr").write_bytes(program.to_bytes()) diff --git a/test_files/modifier_examples/multiple_gates3_in_dagger.hugr b/test_files/modifier_examples/multiple_gates3_in_dagger.hugr deleted file mode 100644 index dcf73d362..000000000 Binary files a/test_files/modifier_examples/multiple_gates3_in_dagger.hugr and /dev/null differ diff --git a/test_files/modifier_examples/multiple_gates3_in_dagger.py b/test_files/modifier_examples/multiple_gates3_in_dagger.py deleted file mode 100644 index ef571dba0..000000000 --- a/test_files/modifier_examples/multiple_gates3_in_dagger.py +++ /dev/null @@ -1,47 +0,0 @@ -# /// script -# requires-python = ">=3.13" -# dependencies = [ -# "guppylang==1.0.0a5", -# "guppylang-internals==1.0.0a5", -# ] -# /// -"""Testing a dagger modifier on multiple gates""" - -from pathlib import Path -from sys import argv -import sys - -from guppylang import guppy -from guppylang.std.builtins import dagger -from guppylang.std.debug import state_result -from guppylang.std.quantum import discard, qubit -from guppylang.std.quantum import s, rx -from guppylang.std.angles import angle - -sys.path.append(str(Path(__file__).resolve().parents[1])) - -from guppylang.experimental import enable_experimental_features - -enable_experimental_features() - - -@guppy(unitary=True) -def bar(q: qubit) -> None: - rx(q, angle(1 / 2)) - s(q) - rx(q, angle(1 / 3)) - - -@guppy -def main() -> None: - t = qubit() - - with dagger: - bar(t) - - state_result("r", t) - discard(t) - - -program = main.compile() -Path(argv[0]).with_suffix(".hugr").write_bytes(program.to_bytes()) diff --git a/test_files/modifier_examples/nested_ctrl_dagger1.hugr b/test_files/modifier_examples/nested_ctrl_dagger1.hugr deleted file mode 100644 index 183bea689..000000000 Binary files a/test_files/modifier_examples/nested_ctrl_dagger1.hugr and /dev/null differ diff --git a/test_files/modifier_examples/nested_ctrl_dagger1.py b/test_files/modifier_examples/nested_ctrl_dagger1.py deleted file mode 100644 index fc54a2fcb..000000000 --- a/test_files/modifier_examples/nested_ctrl_dagger1.py +++ /dev/null @@ -1,63 +0,0 @@ -# /// script -# requires-python = ">=3.13" -# dependencies = [ -# "guppylang==1.0.0a5", -# "guppylang-internals==1.0.0a5", -# ] -# /// -"""Nested control and dagger modifiers in various combinations""" - -from pathlib import Path -from sys import argv -import sys - -from guppylang import guppy -from guppylang.std.builtins import control, dagger -from guppylang.std.debug import state_result -from guppylang.std.quantum import discard, qubit, angle -from guppylang.std.quantum import h, rx, x - -sys.path.append(str(Path(__file__).resolve().parents[1])) - -from guppylang.experimental import enable_experimental_features - -enable_experimental_features() - - -@guppy(unitary=True) -def rotation(q: qubit) -> None: - rx(q, angle(-1 / 3)) - - -@guppy(unitary=True) -def flip(q: qubit) -> None: - x(q) - - -@guppy -def main() -> None: - c1 = qubit() - c2 = qubit() - t1 = qubit() - t2 = qubit() - - h(c1) - h(c2) - - with control(c1): - with dagger: - rotation(t2) - - with dagger: - with control(c2): - rotation(t1) - - state_result("r", c1, c2, t1, t2) - discard(c1) - discard(c2) - discard(t1) - discard(t2) - - -program = main.compile() -Path(argv[0]).with_suffix(".hugr").write_bytes(program.to_bytes()) diff --git a/test_files/modifier_examples/nested_multiple.hugr b/test_files/modifier_examples/nested_multiple.hugr new file mode 100644 index 000000000..8cd266909 Binary files /dev/null and b/test_files/modifier_examples/nested_multiple.hugr differ diff --git a/test_files/modifier_examples/nested_multiple_ctrl1.py b/test_files/modifier_examples/nested_multiple.py similarity index 60% rename from test_files/modifier_examples/nested_multiple_ctrl1.py rename to test_files/modifier_examples/nested_multiple.py index 60d5c3bb3..4b1b74a08 100644 --- a/test_files/modifier_examples/nested_multiple_ctrl1.py +++ b/test_files/modifier_examples/nested_multiple.py @@ -5,22 +5,15 @@ # "guppylang-internals==1.0.0a5", # ] # /// -"""Nested modifiers with multiple control qubits""" +"""Multiple modifiers nested""" from pathlib import Path from sys import argv -import sys -from guppylang import guppy +from guppylang import enable_experimental_features, guppy from guppylang.std.builtins import control, dagger from guppylang.std.debug import state_result -from guppylang.std.quantum import discard, qubit, angle -from guppylang.std.quantum import h, rz - -sys.path.append(str(Path(__file__).resolve().parents[1])) - - -from guppylang.experimental import enable_experimental_features +from guppylang.std.quantum import angle, discard, h, qubit, rz, x enable_experimental_features() @@ -32,13 +25,17 @@ def main() -> None: c2 = qubit() c3 = qubit() h(c1) - h(c2) + x(c2) h(c3) - h(t) + x(t) with control(c1, c2): - with control(c3): - with dagger: - rz(t, angle(1 / 2)) + f = 1 / 3 + with dagger: + a = angle(-f) + with control(c3): + x(t) + rz(t, a) + h(t) state_result("r", c1, c2, c3, t) discard(c1) diff --git a/test_files/modifier_examples/nested_multiple_ctrl1.hugr b/test_files/modifier_examples/nested_multiple_ctrl1.hugr deleted file mode 100644 index b76cae067..000000000 Binary files a/test_files/modifier_examples/nested_multiple_ctrl1.hugr and /dev/null differ diff --git a/test_files/modifier_examples/simple_higher_order.py b/test_files/modifier_examples/simple_higher_order.py index 55df74416..33f77deeb 100644 --- a/test_files/modifier_examples/simple_higher_order.py +++ b/test_files/modifier_examples/simple_higher_order.py @@ -13,16 +13,10 @@ from pathlib import Path from sys import argv -from guppylang import array, guppy -from guppylang.std.builtins import ( - Unitary, - control, - dagger, -) +from guppylang import array, enable_experimental_features, guppy +from guppylang.std.builtins import Unitary, control, dagger from guppylang.std.debug import state_result -from guppylang.std.quantum import cx, discard_array, qubit -from guppylang.std.quantum import h, s -from guppylang.experimental import enable_experimental_features +from guppylang.std.quantum import cx, discard_array, h, qubit, s enable_experimental_features() diff --git a/test_files/modifier_examples/subscript_as_controller.hugr b/test_files/modifier_examples/subscript_as_controller.hugr deleted file mode 100644 index 072d5ba20..000000000 Binary files a/test_files/modifier_examples/subscript_as_controller.hugr and /dev/null differ diff --git a/test_files/modifier_examples/subscript_as_controller.py b/test_files/modifier_examples/subscript_as_controller.py deleted file mode 100644 index 31dc2993c..000000000 --- a/test_files/modifier_examples/subscript_as_controller.py +++ /dev/null @@ -1,52 +0,0 @@ -# /// script -# requires-python = ">=3.13" -# dependencies = [ -# "guppylang==1.0.0a5", -# "guppylang-internals==1.0.0a5", -# ] -# /// -"""A simple controlled gate using modifiers""" - -from pathlib import Path -from sys import argv -import sys - -from guppylang import array, guppy -from guppylang.std.builtins import control -from guppylang.std.debug import state_result -from guppylang.std.quantum import discard, discard_array, qubit, angle -from guppylang.std.quantum import h, x, rx - -sys.path.append(str(Path(__file__).resolve().parents[1])) - -from guppylang.experimental import enable_experimental_features - -enable_experimental_features() - - -@guppy -def f(array_controllers: array[qubit, 3], c: qubit) -> None: - a = angle(1 / 3) - with control(array_controllers[0], c): - h(array_controllers[1]) - with control(array_controllers[1]): - rx(array_controllers[2], a) - - -@guppy -def main() -> None: - q = qubit() - array_controllers: array[qubit, 3] = array(qubit(), qubit(), qubit()) - x(array_controllers[0]) - h(q) - f(array_controllers, q) - - state_result( - "r", q, array_controllers[0], array_controllers[1], array_controllers[2] - ) - discard_array(array_controllers) - discard(q) - - -program = main.compile() -Path(argv[0]).with_suffix(".hugr").write_bytes(program.to_bytes()) diff --git a/test_files/modifier_examples/subscript_in_ctrl.hugr b/test_files/modifier_examples/subscript_in_ctrl.hugr deleted file mode 100644 index f9475079b..000000000 Binary files a/test_files/modifier_examples/subscript_in_ctrl.hugr and /dev/null differ diff --git a/test_files/modifier_examples/subscript_in_ctrl.py b/test_files/modifier_examples/subscript_in_ctrl.py deleted file mode 100644 index c7ac95cce..000000000 --- a/test_files/modifier_examples/subscript_in_ctrl.py +++ /dev/null @@ -1,44 +0,0 @@ -# /// script -# requires-python = ">=3.13" -# dependencies = [ -# "guppylang==1.0.0a5", -# "guppylang-internals==1.0.0a5", -# ] -# /// -"""Subscript indexing in control context""" - -from pathlib import Path -from sys import argv -import sys - -from guppylang import array, guppy -from guppylang.std.builtins import control -from guppylang.std.debug import state_result -from guppylang.std.quantum import discard, discard_array, qubit -from guppylang.std.quantum import h, s - -sys.path.append(str(Path(__file__).resolve().parents[1])) - -from guppylang.experimental import enable_experimental_features - -enable_experimental_features() - - -@guppy -def main() -> None: - q = qubit() - array_qubits: array[qubit, 2] = array(qubit(), qubit()) - - h(q) - with control(q): - h(array_qubits[1]) - h(array_qubits[0]) - s(array_qubits[0]) - - state_result("r", array_qubits[0], array_qubits[1], q) - discard_array(array_qubits) - discard(q) - - -program = main.compile() -Path(argv[0]).with_suffix(".hugr").write_bytes(program.to_bytes()) diff --git a/test_files/modifier_examples/subscript_in_dagger.hugr b/test_files/modifier_examples/subscript_in_dagger.hugr deleted file mode 100644 index ff2245d5d..000000000 Binary files a/test_files/modifier_examples/subscript_in_dagger.hugr and /dev/null differ diff --git a/test_files/modifier_examples/subscript_in_dagger.py b/test_files/modifier_examples/subscript_in_dagger.py deleted file mode 100644 index 57a204d61..000000000 --- a/test_files/modifier_examples/subscript_in_dagger.py +++ /dev/null @@ -1,40 +0,0 @@ -# /// script -# requires-python = ">=3.13" -# dependencies = [ -# "guppylang==1.0.0a5", -# "guppylang-internals==1.0.0a5", -# ] -# /// -"""Subscript indexing in dagger context""" - -from pathlib import Path -from sys import argv -import sys - -from guppylang import array, guppy -from guppylang.std.builtins import dagger -from guppylang.std.debug import state_result -from guppylang.std.quantum import qubit, discard_array -from guppylang.std.quantum import h, s - -sys.path.append(str(Path(__file__).resolve().parents[1])) - -from guppylang.experimental import enable_experimental_features - -enable_experimental_features() - - -@guppy -def main() -> None: - array_qubits: array[qubit, 2] = array(qubit(), qubit()) - - with dagger: - s(array_qubits[1]) - h(array_qubits[1]) - - state_result("r", array_qubits[0], array_qubits[1]) - discard_array(array_qubits) - - -program = main.compile() -Path(argv[0]).with_suffix(".hugr").write_bytes(program.to_bytes()) diff --git a/test_files/modifier_examples/subscript_in_dagger_ctrl.hugr b/test_files/modifier_examples/subscript_in_dagger_ctrl.hugr index bf8fc2696..cfe71e4bf 100644 Binary files a/test_files/modifier_examples/subscript_in_dagger_ctrl.hugr and b/test_files/modifier_examples/subscript_in_dagger_ctrl.hugr differ diff --git a/test_files/modifier_examples/subscript_in_dagger_ctrl.py b/test_files/modifier_examples/subscript_in_dagger_ctrl.py index c747fe0fb..ef9dffbfe 100644 --- a/test_files/modifier_examples/subscript_in_dagger_ctrl.py +++ b/test_files/modifier_examples/subscript_in_dagger_ctrl.py @@ -9,32 +9,35 @@ from pathlib import Path from sys import argv -import sys -from guppylang import array, guppy +from guppylang import array, enable_experimental_features, guppy from guppylang.std.builtins import control, dagger from guppylang.std.debug import state_result -from guppylang.std.quantum import qubit, discard_array -from guppylang.std.quantum import h, s +from guppylang.std.quantum import angle, discard_array, h, qubit, rx, s, x -sys.path.append(str(Path(__file__).resolve().parents[1])) +enable_experimental_features() -from guppylang.experimental import enable_experimental_features -enable_experimental_features() +@guppy(unitary=True) +def f(controller: qubit, target: qubit) -> None: + a = angle(1 / 3) + with control(controller): + rx(target, a) @guppy def main() -> None: - controller = array(qubit()) - array_qubits: array[qubit, 2] = array(qubit(), qubit()) + controller = array(qubit(), qubit()) + array_qubits = array(qubit(), qubit()) h(controller[0]) + x(controller[1]) with dagger: - with control(controller[0]): - s(array_qubits[1]) - h(array_qubits[1]) + with control(controller): + f(array_qubits[0], array_qubits[1]) + s(array_qubits[0]) + h(array_qubits[0]) - state_result("r", controller[0], array_qubits[0], array_qubits[1]) + state_result("r", controller[0], controller[1], array_qubits[0], array_qubits[1]) discard_array(array_qubits) discard_array(controller) diff --git a/test_files/modifier_examples/swap_in_dagger.hugr b/test_files/modifier_examples/swap_in_dagger.hugr deleted file mode 100644 index 840a259df..000000000 Binary files a/test_files/modifier_examples/swap_in_dagger.hugr and /dev/null differ diff --git a/test_files/modifier_examples/swap_in_dagger.py b/test_files/modifier_examples/swap_in_dagger.py deleted file mode 100644 index 4dd4fb1de..000000000 --- a/test_files/modifier_examples/swap_in_dagger.py +++ /dev/null @@ -1,42 +0,0 @@ -# /// script -# requires-python = ">=3.13" -# dependencies = [ -# "guppylang==1.0.0a5", -# "guppylang-internals==1.0.0a5", -# ] -# /// -"""Dagger of a swap on an array""" - -from pathlib import Path -from sys import argv -import sys - -from guppylang import guppy -from guppylang.std.array import array_swap -from guppylang.std.quantum import discard, qubit, h -from guppylang.std.builtins import array -import guppylang -from guppylang.std.builtins import dagger -from guppylang.std.debug import state_result - -sys.path.append(str(Path(__file__).resolve().parents[1])) - - -guppylang.enable_experimental_features() - - -@guppy -def main() -> None: - arr = array(1, 1, 2, 1, 1) - with dagger: - array_swap(arr, 2, 4) - array_swap(arr, 0, 4) - q = qubit() - if arr[0] == 2: - h(q) - state_result("r", q) - discard(q) - - -program = main.compile_function() -Path(argv[0]).with_suffix(".hugr").write_bytes(program.to_bytes()) diff --git a/test_files/run_modifier_examples/hugr_results.txt b/test_files/run_modifier_examples/hugr_results.txt index 8426355a4..288fc15a2 100644 --- a/test_files/run_modifier_examples/hugr_results.txt +++ b/test_files/run_modifier_examples/hugr_results.txt @@ -1,438 +1,61 @@ -assign_in_dagger_solved: +cfg_in_ctrl_solved: 00 -> 0.7071+0j - 10 -> 0.6124+0j - 11 -> 0+0.3536j ------ -call1_in_ctrl_solved: - 00 -> 0.7071+0j - 11 -> 0.7071+0j ------ -call2_in_ctrl_solved: - 0110 -> 0.7071+0j - 1110 -> 0.6124+0j - 1111 -> 0-0.3536j ------ -call_in_dagger_solved: - 0 -> 0.7071+0j - 1 -> 0-0.7071j ------ -classical_array_op_solved: - 0 -> 0.7071+0j - 1 -> -0.7071-0j ------ -classical_function1_solved: - 0 -> 0.866+0j - 1 -> 0+0.5j ------ -classical_function2_solved: - 00 -> 0.7071+0j - 10 -> 0.6124+0j - 11 -> 0+0.3536j + 10 -> -0.1913+0.1913j + 11 -> -0.4619-0.4619j ----- -classical_function3_solved: +classical_function_solved: 000 -> 0.5+0j 010 -> 0.5+0j 100 -> 0.5+0j 110 -> 0.433+0j 111 -> 0+0.25j ----- -complex_modifier_stress_solved: - 00000000 -> 0.0625-6.516e-19j - 00000001 -> 0.0625+2.035e-16j - 00000010 -> 0.0625+4.805e-18j - 00000011 -> 0.0625+2.544e-16j - 00000100 -> 0.0625-7.362e-17j - 00000101 -> 0.0625+1.113e-16j - 00000110 -> 0.0625-6.817e-17j - 00000111 -> 0.0625+2.037e-16j - 00001000 -> 0.0625+1.441e-15j - 00001001 -> 0.0625+1.534e-15j - 00001010 -> 0.0625+1.398e-15j - 00001011 -> 0.0625+1.489e-15j - 00001100 -> 0.0625+1.412e-15j - 00001101 -> 0.0625+1.472e-15j - 00001110 -> 0.0625+1.367e-15j - 00001111 -> 0.0625+1.422e-15j - 00010000 -> 0.06093-0.01391j - 00010001 -> 0.06093-0.01391j - 00010010 -> 0.06093-0.01391j - 00010011 -> 0.06093-0.01391j - 00010100 -> 0.06093-0.01391j - 00010101 -> 0.06093-0.01391j - 00010110 -> 0.06093-0.01391j - 00010111 -> 0.06093-0.01391j - 00011000 -> 0.06093-0.01391j - 00011001 -> 0.06093-0.01391j - 00011010 -> 0.06093-0.01391j - 00011011 -> 0.06093-0.01391j - 00011100 -> 0.06093-0.01391j - 00011101 -> 0.06093-0.01391j - 00011110 -> 0.06093-0.01391j - 00011111 -> 0.06093-0.01391j - 00100000 -> 0.06093-0.01391j - 00100001 -> 0.06093-0.01391j - 00100010 -> 0.06093-0.01391j - 00100011 -> 0.06093-0.01391j - 00100100 -> 0.06093-0.01391j - 00100101 -> 0.06093-0.01391j - 00100110 -> 0.06093-0.01391j - 00100111 -> 0.06093-0.01391j - 00101000 -> 0.06093-0.01391j - 00101001 -> 0.06093-0.01391j - 00101010 -> 0.06093-0.01391j - 00101011 -> 0.06093-0.01391j - 00101100 -> 0.06093-0.01391j - 00101101 -> 0.06093-0.01391j - 00101110 -> 0.06093-0.01391j - 00101111 -> 0.06093-0.01391j - 00110000 -> 0.04591-0.02833j - 00110001 -> 0.04591-0.02833j - 00110010 -> 0.04591-0.02833j - 00110011 -> 0.04591-0.02833j - 00110100 -> 0.06999+0.001873j - 00110101 -> 0.06999+0.001873j - 00110110 -> 0.06999+0.001873j - 00110111 -> 0.06999+0.001873j - 00111000 -> 0.06151+0.03344j - 00111001 -> 0.05768+0.03969j - 00111010 -> 0.05972-0.03655j - 00111011 -> 0.06321-0.03011j - 00111100 -> 0.05377-0.004397j - 00111101 -> 0.05393+0.001247j - 00111110 -> 0.02307-0.04876j - 00111111 -> 0.02805-0.04608j - 01000000 -> 0.0625+6.388e-16j - 01000001 -> 0.0625+7.844e-16j - 01000010 -> 0.0625+6.223e-16j - 01000011 -> 0.0625+6.784e-16j - 01000100 -> 0.0625+5.669e-16j - 01000101 -> 0.0625+7.45e-16j - 01000110 -> 0.0625+5.382e-16j - 01000111 -> 0.0625+5.986e-16j - 01001000 -> 0.0625+1.425e-15j - 01001001 -> 0.0625+1.24e-15j - 01001010 -> 0.0625+1.271e-15j - 01001011 -> 0.0625+1.136e-15j - 01001100 -> 0.0625+1.407e-15j - 01001101 -> 0.0625+1.214e-15j - 01001110 -> 0.0625+1.296e-15j - 01001111 -> 0.0625+1.15e-15j - 01010000 -> 0.06093-0.01391j - 01010001 -> 0.06093-0.01391j - 01010010 -> 0.06093-0.01391j - 01010011 -> 0.06093-0.01391j - 01010100 -> 0.06093-0.01391j - 01010101 -> 0.06093-0.01391j - 01010110 -> 0.06093-0.01391j - 01010111 -> 0.06093-0.01391j - 01011000 -> 0.06093-0.01391j - 01011001 -> 0.06093-0.01391j - 01011010 -> 0.06093-0.01391j - 01011011 -> 0.06093-0.01391j - 01011100 -> 0.06093-0.01391j - 01011101 -> 0.06093-0.01391j - 01011110 -> 0.06093-0.01391j - 01011111 -> 0.06093-0.01391j - 01100000 -> 0.06093-0.01391j - 01100001 -> 0.06093-0.01391j - 01100010 -> 0.06093-0.01391j - 01100011 -> 0.06093-0.01391j - 01100100 -> 0.06093-0.01391j - 01100101 -> 0.06093-0.01391j - 01100110 -> 0.06093-0.01391j - 01100111 -> 0.06093-0.01391j - 01101000 -> 0.06093-0.01391j - 01101001 -> 0.06093-0.01391j - 01101010 -> 0.06093-0.01391j - 01101011 -> 0.06093-0.01391j - 01101100 -> 0.06093-0.01391j - 01101101 -> 0.06093-0.01391j - 01101110 -> 0.06093-0.01391j - 01101111 -> 0.06093-0.01391j - 01110000 -> 0.04591-0.02833j - 01110001 -> 0.04591-0.02833j - 01110010 -> 0.04591-0.02833j - 01110011 -> 0.04591-0.02833j - 01110100 -> 0.06999+0.001873j - 01110101 -> 0.06999+0.001873j - 01110110 -> 0.06999+0.001873j - 01110111 -> 0.06999+0.001873j - 01111000 -> 0.06151+0.03344j - 01111001 -> 0.05768+0.03969j - 01111010 -> 0.05972-0.03655j - 01111011 -> 0.06321-0.03011j - 01111100 -> 0.05377-0.004397j - 01111101 -> 0.05393+0.001247j - 01111110 -> 0.02307-0.04876j - 01111111 -> 0.02805-0.04608j - 10000000 -> 0.0625-5.489e-17j - 10000001 -> 0.0625+2.576e-17j - 10000010 -> 0.0625-3.619e-17j - 10000011 -> 0.0625-6.208e-18j - 10000100 -> 0.0625-1.638e-16j - 10000101 -> 0.0625-4.76e-17j - 10000110 -> 0.0625-1.604e-16j - 10000111 -> 0.0625-1.056e-16j - 10001000 -> 0.0625+1.316e-15j - 10001001 -> 0.0625+1.468e-15j - 10001010 -> 0.0625+1.416e-15j - 10001011 -> 0.0625+1.407e-15j - 10001100 -> 0.0625+1.285e-15j - 10001101 -> 0.0625+1.452e-15j - 10001110 -> 0.0625+1.388e-15j - 10001111 -> 0.0625+1.395e-15j - 10010000 -> 0.06093-0.01391j - 10010001 -> 0.06093-0.01391j - 10010010 -> 0.06093-0.01391j - 10010011 -> 0.06093-0.01391j - 10010100 -> 0.06093-0.01391j - 10010101 -> 0.06093-0.01391j - 10010110 -> 0.06093-0.01391j - 10010111 -> 0.06093-0.01391j - 10011000 -> 0.06093-0.01391j - 10011001 -> 0.06093-0.01391j - 10011010 -> 0.06093-0.01391j - 10011011 -> 0.06093-0.01391j - 10011100 -> 0.06093-0.01391j - 10011101 -> 0.06093-0.01391j - 10011110 -> 0.06093-0.01391j - 10011111 -> 0.06093-0.01391j - 10100000 -> 0.06093-0.01391j - 10100001 -> 0.06093-0.01391j - 10100010 -> 0.06093-0.01391j - 10100011 -> 0.06093-0.01391j - 10100100 -> 0.06093-0.01391j - 10100101 -> 0.06093-0.01391j - 10100110 -> 0.06093-0.01391j - 10100111 -> 0.06093-0.01391j - 10101000 -> 0.06093-0.01391j - 10101001 -> 0.06093-0.01391j - 10101010 -> 0.06093-0.01391j - 10101011 -> 0.06093-0.01391j - 10101100 -> 0.06093-0.01391j - 10101101 -> 0.06093-0.01391j - 10101110 -> 0.06093-0.01391j - 10101111 -> 0.06093-0.01391j - 10110000 -> 0.04591-0.02833j - 10110001 -> 0.04591-0.02833j - 10110010 -> 0.04591-0.02833j - 10110011 -> 0.04591-0.02833j - 10110100 -> 0.06999+0.001873j - 10110101 -> 0.06999+0.001873j - 10110110 -> 0.06999+0.001873j - 10110111 -> 0.06999+0.001873j - 10111000 -> 0.06151+0.03344j - 10111001 -> 0.05768+0.03969j - 10111010 -> 0.05972-0.03655j - 10111011 -> 0.06321-0.03011j - 10111100 -> 0.05377-0.004397j - 10111101 -> 0.05393+0.001247j - 10111110 -> 0.02307-0.04876j - 10111111 -> 0.02805-0.04608j - 11000000 -> 0.06093-0.01391j - 11000001 -> 0.06093-0.01391j - 11000010 -> 0.06093-0.01391j - 11000011 -> 0.06093-0.01391j - 11000100 -> 0.06093-0.01391j - 11000101 -> 0.06093-0.01391j - 11000110 -> 0.06093-0.01391j - 11000111 -> 0.06093-0.01391j - 11001000 -> 0.06093-0.01391j - 11001001 -> 0.06093-0.01391j - 11001010 -> 0.06093-0.01391j - 11001011 -> 0.06093-0.01391j - 11001100 -> 0.06093-0.01391j - 11001101 -> 0.06093-0.01391j - 11001110 -> 0.06093-0.01391j - 11001111 -> 0.06093-0.01391j - 11010000 -> 0.05631-0.02712j - 11010001 -> 0.05631-0.02712j - 11010010 -> 0.05631-0.02712j - 11010011 -> 0.05631-0.02712j - 11010100 -> 0.05631-0.02712j - 11010101 -> 0.05631-0.02712j - 11010110 -> 0.05631-0.02712j - 11010111 -> 0.05631-0.02712j - 11011000 -> 0.05631-0.02712j - 11011001 -> 0.05631-0.02712j - 11011010 -> 0.05631-0.02712j - 11011011 -> 0.05631-0.02712j - 11011100 -> 0.05631-0.02712j - 11011101 -> 0.05631-0.02712j - 11011110 -> 0.05631-0.02712j - 11011111 -> 0.05631-0.02712j - 11100000 -> 0.05631-0.02712j - 11100001 -> 0.05631-0.02712j - 11100010 -> 0.05631-0.02712j - 11100011 -> 0.05631-0.02712j - 11100100 -> 0.05631-0.02712j - 11100101 -> 0.05631-0.02712j - 11100110 -> 0.05631-0.02712j - 11100111 -> 0.05631-0.02712j - 11101000 -> 0.05631-0.02712j - 11101001 -> 0.05631-0.02712j - 11101010 -> 0.05631-0.02712j - 11101011 -> 0.05631-0.02712j - 11101100 -> 0.05631-0.02712j - 11101101 -> 0.05631-0.02712j - 11101110 -> 0.05631-0.02712j - 11101111 -> 0.05631-0.02712j - 11110000 -> 0.03845-0.03783j - 11110001 -> 0.03845-0.03783j - 11110010 -> 0.03845-0.03783j - 11110011 -> 0.03845-0.03783j - 11110100 -> 0.06865-0.01375j - 11110101 -> 0.06865-0.01375j - 11110110 -> 0.06865-0.01375j - 11110111 -> 0.06865-0.01375j - 11111000 -> 0.05827+0.03882j - 11111001 -> 0.06987+0.004489j - 11111010 -> 0.06276-0.03105j - 11111011 -> 0.03882-0.05827j - 11111100 -> 0.05394+0.00044j - 11111101 -> 0.04694-0.02659j - 11111110 -> 0.02735-0.0465j - 11111111 -> 0.00044-0.05394j ------ -ctrl_array_controller_solved: - 0000 -> 0.3536+0j - 0010 -> 0.3536+0j - 0100 -> 0.3536+0j - 0110 -> 0.3536+0j - 1000 -> 0.3536+0j - 1010 -> 0.3536+0j - 1100 -> 0.3536+0j - 1111 -> 0.3536+0j ------ -ctrl_on_cfg_solved: +complex_cfg_higher_order_solved: 00 -> 0.7071+0j - 10 -> -0.1913+0.1913j - 11 -> -0.4619-0.4619j + 10 -> 0.4619-0.1913j + 11 -> -0.4619-0.1913j ----- double_modifier_solved: 00 -> 0.7071+0j 10 -> 0.6124+0j - 11 -> 0+0.3536j + 11 -> -0.3536+0j ----- even_dagger_solved: 00 -> 0.7071+0j 10 -> 0.6124+0j 11 -> 0-0.3536j ----- -gate_in_ctrl_solved: - 00 -> 0.7071+0j - 11 -> 0.7071+0j ------ -higher_order_classical_solved: - 00 -> 0.7071+0j - 10 -> 0.3536+0.3536j - 11 -> 0.3536+0.3536j ------ -higher_order_function_w_loops_solved: - 00 -> 0.7071+0j - 10 -> 0.4619-0.1913j - 11 -> -0.4619-0.1913j ------ higher_order_recursive_solved: - 00 -> 0.7071+0j - 10 -> 0.5+0j + 01 -> 0.7071+0j + 10 -> -0.5+0j 11 -> 0-0.5j ----- -modify_array_solved: +loaded_pytket_solved: 000 -> 0.7071+0j - 100 -> 0.5+0j - 101 -> 0.5+0j ------ -multiple_dagger_solved: - 0 -> 1+0j ------ -multiple_functions_in_ctrl_dagger_solved: - 00 -> 0.7071+0j - 10 -> 0.433+0.25j - 11 -> 0.25+0.433j ------ -multiple_functions_in_dagger_solved: - 0 -> 0.7071-4.304e-17j - 1 -> 0.6124+0.3536j + 100 -> 0.25-0.25j + 101 -> 0.25-0.25j + 110 -> 0.25+0.25j + 111 -> 0.25+0.25j ----- -multiple_gates1_in_ctrl_solved: +multiple_functions_solved: 00 -> 0.7071+0j - 10 -> 0.6124+0j - 11 -> 0-0.3536j ------ -multiple_gates1_in_dagger_solved: - 0 -> 0.7071+0j - 1 -> 0-0.7071j ------ -multiple_gates2_in_ctrl_solved: - 00 -> 0.7071+0j - 10 -> 0.6124+0j - 11 -> 0-0.3536j ------ -multiple_gates2_in_dagger_solved: - 0 -> 0.7071+0j - 1 -> 0+0.7071j ------ -multiple_gates3_in_dagger_solved: - 0 -> 0.7071-4.304e-17j - 1 -> 0.6124+0.3536j ------ -nested_ctrl_dagger1_solved: - 0000 -> 0.5+0j - 0100 -> 0.433+0j - 0110 -> 0-0.25j - 1000 -> 0.433+0j - 1001 -> 0-0.25j - 1100 -> 0.375+0j - 1101 -> 0-0.2165j - 1110 -> 0-0.2165j - 1111 -> -0.125+0j + 10 -> 0+0.6124j + 11 -> 0+0.3536j ----- -nested_multiple_ctrl1_solved: - 0000 -> 0.25+0j - 0001 -> 0.25+0j - 0010 -> 0.25+0j - 0011 -> 0.25+0j - 0100 -> 0.25+0j - 0101 -> 0.25+0j - 0110 -> 0.25+0j - 0111 -> 0.25+0j - 1000 -> 0.25+0j - 1001 -> 0.25+0j - 1010 -> 0.25+0j - 1011 -> 0.25+0j - 1100 -> 0.25+0j - 1101 -> 0.25+0j - 1110 -> 0.1768+0.1768j - 1111 -> 0.1768-0.1768j +nested_multiple_solved: + 0101 -> 0.5+0j + 0111 -> 0.5+0j + 1101 -> 0.5+0j + 1110 -> -0.3062-0.1768j + 1111 -> 0.3062-0.1768j ----- simple_higher_order_solved: 000 -> 0.7071+0j 100 -> 0.5+0j 111 -> 0-0.5j ----- -subscript_as_controller_solved: +subscript_in_dagger_ctrl_solved: 0100 -> 0.7071+0j 1100 -> 0.5+0j - 1110 -> 0.433+0j - 1111 -> 0-0.25j ------ -subscript_in_ctrl_solved: - 000 -> 0.7071+0j - 001 -> 0.3536+0j - 011 -> 0.3536+0j - 101 -> 0+0.3536j - 111 -> 0+0.3536j ------ -subscript_in_dagger_ctrl_solved: - 000 -> 0.7071+0j - 100 -> 0.5+0j - 101 -> 0-0.5j ------ -subscript_in_dagger_solved: - 00 -> 0.7071+0j - 01 -> 0-0.7071j ------ -swap_in_dagger_solved: - 0 -> 0.7071+0j - 1 -> 0.7071+0j + 1110 -> 0-0.433j + 1111 -> 0.25+0j diff --git a/test_files/run_modifier_examples/hugr_results/call1_in_ctrl_solved.npy b/test_files/run_modifier_examples/hugr_results/call1_in_ctrl_solved.npy deleted file mode 100644 index 1b4e66782..000000000 Binary files a/test_files/run_modifier_examples/hugr_results/call1_in_ctrl_solved.npy and /dev/null differ diff --git a/test_files/run_modifier_examples/hugr_results/call_in_dagger_solved.npy b/test_files/run_modifier_examples/hugr_results/call_in_dagger_solved.npy deleted file mode 100644 index 67edd0627..000000000 Binary files a/test_files/run_modifier_examples/hugr_results/call_in_dagger_solved.npy and /dev/null differ diff --git a/test_files/run_modifier_examples/hugr_results/ctrl_on_cfg_solved.npy b/test_files/run_modifier_examples/hugr_results/cfg_in_ctrl_solved.npy similarity index 100% rename from test_files/run_modifier_examples/hugr_results/ctrl_on_cfg_solved.npy rename to test_files/run_modifier_examples/hugr_results/cfg_in_ctrl_solved.npy diff --git a/test_files/run_modifier_examples/hugr_results/classical_array_op_solved.npy b/test_files/run_modifier_examples/hugr_results/classical_array_op_solved.npy deleted file mode 100644 index b5f9a6978..000000000 Binary files a/test_files/run_modifier_examples/hugr_results/classical_array_op_solved.npy and /dev/null differ diff --git a/test_files/run_modifier_examples/hugr_results/classical_function1_solved.npy b/test_files/run_modifier_examples/hugr_results/classical_function1_solved.npy deleted file mode 100644 index 19aab2972..000000000 Binary files a/test_files/run_modifier_examples/hugr_results/classical_function1_solved.npy and /dev/null differ diff --git a/test_files/run_modifier_examples/hugr_results/classical_function2_solved.npy b/test_files/run_modifier_examples/hugr_results/classical_function2_solved.npy deleted file mode 100644 index aceda8cdf..000000000 Binary files a/test_files/run_modifier_examples/hugr_results/classical_function2_solved.npy and /dev/null differ diff --git a/test_files/run_modifier_examples/hugr_results/classical_function3_solved.npy b/test_files/run_modifier_examples/hugr_results/classical_function_solved.npy similarity index 100% rename from test_files/run_modifier_examples/hugr_results/classical_function3_solved.npy rename to test_files/run_modifier_examples/hugr_results/classical_function_solved.npy diff --git a/test_files/run_modifier_examples/hugr_results/higher_order_function_w_loops_solved.npy b/test_files/run_modifier_examples/hugr_results/complex_cfg_higher_order_solved.npy similarity index 100% rename from test_files/run_modifier_examples/hugr_results/higher_order_function_w_loops_solved.npy rename to test_files/run_modifier_examples/hugr_results/complex_cfg_higher_order_solved.npy diff --git a/test_files/run_modifier_examples/hugr_results/complex_modifier_stress_solved.npy b/test_files/run_modifier_examples/hugr_results/complex_modifier_stress_solved.npy deleted file mode 100644 index fa7562145..000000000 Binary files a/test_files/run_modifier_examples/hugr_results/complex_modifier_stress_solved.npy and /dev/null differ diff --git a/test_files/run_modifier_examples/hugr_results/ctrl_array_controller_solved.npy b/test_files/run_modifier_examples/hugr_results/ctrl_array_controller_solved.npy deleted file mode 100644 index 5fa28fa14..000000000 Binary files a/test_files/run_modifier_examples/hugr_results/ctrl_array_controller_solved.npy and /dev/null differ diff --git a/test_files/run_modifier_examples/hugr_results/double_modifier_solved.npy b/test_files/run_modifier_examples/hugr_results/double_modifier_solved.npy index aceda8cdf..3606cf2fe 100644 Binary files a/test_files/run_modifier_examples/hugr_results/double_modifier_solved.npy and b/test_files/run_modifier_examples/hugr_results/double_modifier_solved.npy differ diff --git a/test_files/run_modifier_examples/hugr_results/gate_in_ctrl_solved.npy b/test_files/run_modifier_examples/hugr_results/gate_in_ctrl_solved.npy deleted file mode 100644 index 1b4e66782..000000000 Binary files a/test_files/run_modifier_examples/hugr_results/gate_in_ctrl_solved.npy and /dev/null differ diff --git a/test_files/run_modifier_examples/hugr_results/higher_order_classical_solved.npy b/test_files/run_modifier_examples/hugr_results/higher_order_classical_solved.npy deleted file mode 100644 index 44a76d3e7..000000000 Binary files a/test_files/run_modifier_examples/hugr_results/higher_order_classical_solved.npy and /dev/null differ diff --git a/test_files/run_modifier_examples/hugr_results/higher_order_recursive_solved.npy b/test_files/run_modifier_examples/hugr_results/higher_order_recursive_solved.npy index a6b9adc1f..7dd1cfba9 100644 Binary files a/test_files/run_modifier_examples/hugr_results/higher_order_recursive_solved.npy and b/test_files/run_modifier_examples/hugr_results/higher_order_recursive_solved.npy differ diff --git a/test_files/run_modifier_examples/hugr_results/modify_array_solved.npy b/test_files/run_modifier_examples/hugr_results/loaded_pytket_solved.npy similarity index 50% rename from test_files/run_modifier_examples/hugr_results/modify_array_solved.npy rename to test_files/run_modifier_examples/hugr_results/loaded_pytket_solved.npy index d5c2cbfa4..4ca4cdbaa 100644 Binary files a/test_files/run_modifier_examples/hugr_results/modify_array_solved.npy and b/test_files/run_modifier_examples/hugr_results/loaded_pytket_solved.npy differ diff --git a/test_files/run_modifier_examples/hugr_results/multiple_dagger_solved.npy b/test_files/run_modifier_examples/hugr_results/multiple_dagger_solved.npy deleted file mode 100644 index 3ecbf3051..000000000 Binary files a/test_files/run_modifier_examples/hugr_results/multiple_dagger_solved.npy and /dev/null differ diff --git a/test_files/run_modifier_examples/hugr_results/multiple_functions_in_ctrl_dagger_solved.npy b/test_files/run_modifier_examples/hugr_results/multiple_functions_in_ctrl_dagger_solved.npy deleted file mode 100644 index d6e13c98f..000000000 Binary files a/test_files/run_modifier_examples/hugr_results/multiple_functions_in_ctrl_dagger_solved.npy and /dev/null differ diff --git a/test_files/run_modifier_examples/hugr_results/multiple_functions_in_dagger_solved.npy b/test_files/run_modifier_examples/hugr_results/multiple_functions_in_dagger_solved.npy deleted file mode 100644 index 0e289815c..000000000 Binary files a/test_files/run_modifier_examples/hugr_results/multiple_functions_in_dagger_solved.npy and /dev/null differ diff --git a/test_files/run_modifier_examples/hugr_results/assign_in_dagger_solved.npy b/test_files/run_modifier_examples/hugr_results/multiple_functions_solved.npy similarity index 66% rename from test_files/run_modifier_examples/hugr_results/assign_in_dagger_solved.npy rename to test_files/run_modifier_examples/hugr_results/multiple_functions_solved.npy index aceda8cdf..8866bb46e 100644 Binary files a/test_files/run_modifier_examples/hugr_results/assign_in_dagger_solved.npy and b/test_files/run_modifier_examples/hugr_results/multiple_functions_solved.npy differ diff --git a/test_files/run_modifier_examples/hugr_results/multiple_gates1_in_ctrl_solved.npy b/test_files/run_modifier_examples/hugr_results/multiple_gates1_in_ctrl_solved.npy deleted file mode 100644 index 7bd06475a..000000000 Binary files a/test_files/run_modifier_examples/hugr_results/multiple_gates1_in_ctrl_solved.npy and /dev/null differ diff --git a/test_files/run_modifier_examples/hugr_results/multiple_gates1_in_dagger_solved.npy b/test_files/run_modifier_examples/hugr_results/multiple_gates1_in_dagger_solved.npy deleted file mode 100644 index ec88dcf80..000000000 Binary files a/test_files/run_modifier_examples/hugr_results/multiple_gates1_in_dagger_solved.npy and /dev/null differ diff --git a/test_files/run_modifier_examples/hugr_results/multiple_gates2_in_ctrl_solved.npy b/test_files/run_modifier_examples/hugr_results/multiple_gates2_in_ctrl_solved.npy deleted file mode 100644 index 7bd06475a..000000000 Binary files a/test_files/run_modifier_examples/hugr_results/multiple_gates2_in_ctrl_solved.npy and /dev/null differ diff --git a/test_files/run_modifier_examples/hugr_results/multiple_gates2_in_dagger_solved.npy b/test_files/run_modifier_examples/hugr_results/multiple_gates2_in_dagger_solved.npy deleted file mode 100644 index 0fd55674c..000000000 Binary files a/test_files/run_modifier_examples/hugr_results/multiple_gates2_in_dagger_solved.npy and /dev/null differ diff --git a/test_files/run_modifier_examples/hugr_results/multiple_gates3_in_dagger_solved.npy b/test_files/run_modifier_examples/hugr_results/multiple_gates3_in_dagger_solved.npy deleted file mode 100644 index 0e289815c..000000000 Binary files a/test_files/run_modifier_examples/hugr_results/multiple_gates3_in_dagger_solved.npy and /dev/null differ diff --git a/test_files/run_modifier_examples/hugr_results/nested_ctrl_dagger1_solved.npy b/test_files/run_modifier_examples/hugr_results/nested_ctrl_dagger1_solved.npy deleted file mode 100644 index ec7489319..000000000 Binary files a/test_files/run_modifier_examples/hugr_results/nested_ctrl_dagger1_solved.npy and /dev/null differ diff --git a/test_files/run_modifier_examples/hugr_results/nested_multiple_ctrl1_solved.npy b/test_files/run_modifier_examples/hugr_results/nested_multiple_ctrl1_solved.npy deleted file mode 100644 index bb9afe803..000000000 Binary files a/test_files/run_modifier_examples/hugr_results/nested_multiple_ctrl1_solved.npy and /dev/null differ diff --git a/test_files/run_modifier_examples/hugr_results/call2_in_ctrl_solved.npy b/test_files/run_modifier_examples/hugr_results/nested_multiple_solved.npy similarity index 66% rename from test_files/run_modifier_examples/hugr_results/call2_in_ctrl_solved.npy rename to test_files/run_modifier_examples/hugr_results/nested_multiple_solved.npy index 995bcca39..4ccc144d0 100644 Binary files a/test_files/run_modifier_examples/hugr_results/call2_in_ctrl_solved.npy and b/test_files/run_modifier_examples/hugr_results/nested_multiple_solved.npy differ diff --git a/test_files/run_modifier_examples/hugr_results/subscript_as_controller_solved.npy b/test_files/run_modifier_examples/hugr_results/subscript_as_controller_solved.npy deleted file mode 100644 index 7e9d00412..000000000 Binary files a/test_files/run_modifier_examples/hugr_results/subscript_as_controller_solved.npy and /dev/null differ diff --git a/test_files/run_modifier_examples/hugr_results/subscript_in_ctrl_solved.npy b/test_files/run_modifier_examples/hugr_results/subscript_in_ctrl_solved.npy deleted file mode 100644 index 0ef6214a1..000000000 Binary files a/test_files/run_modifier_examples/hugr_results/subscript_in_ctrl_solved.npy and /dev/null differ diff --git a/test_files/run_modifier_examples/hugr_results/subscript_in_dagger_ctrl_solved.npy b/test_files/run_modifier_examples/hugr_results/subscript_in_dagger_ctrl_solved.npy index 03152b116..1928d1096 100644 Binary files a/test_files/run_modifier_examples/hugr_results/subscript_in_dagger_ctrl_solved.npy and b/test_files/run_modifier_examples/hugr_results/subscript_in_dagger_ctrl_solved.npy differ diff --git a/test_files/run_modifier_examples/hugr_results/subscript_in_dagger_solved.npy b/test_files/run_modifier_examples/hugr_results/subscript_in_dagger_solved.npy deleted file mode 100644 index 2b9e39f07..000000000 Binary files a/test_files/run_modifier_examples/hugr_results/subscript_in_dagger_solved.npy and /dev/null differ diff --git a/test_files/run_modifier_examples/hugr_results/swap_in_dagger_solved.npy b/test_files/run_modifier_examples/hugr_results/swap_in_dagger_solved.npy deleted file mode 100644 index 538eff5b6..000000000 Binary files a/test_files/run_modifier_examples/hugr_results/swap_in_dagger_solved.npy and /dev/null differ diff --git a/test_files/run_modifier_examples/justfile b/test_files/run_modifier_examples/justfile index d55bd1405..dd187045c 100644 --- a/test_files/run_modifier_examples/justfile +++ b/test_files/run_modifier_examples/justfile @@ -2,9 +2,6 @@ help: @just --list --justfile {{justfile()}} -# Re-generate all hugr files and their mermaid diagrams. -r: run-hugrs - # Re-generate all hugr files. run-hugrs: just apply-passes diff --git a/test_files/run_modifier_examples/run_hugrs.py b/test_files/run_modifier_examples/run_hugrs.py index 96e2069c7..d16a78007 100644 --- a/test_files/run_modifier_examples/run_hugrs.py +++ b/test_files/run_modifier_examples/run_hugrs.py @@ -7,13 +7,14 @@ # /// """Run on selene the passed hugrs""" -from pathlib import Path import shutil import sys +from pathlib import Path + import numpy as np import numpy.typing as npt -from hugr import Hugr from guppylang.emulator import EmulatorBuilder +from hugr import Hugr def format_statevector( diff --git a/tket-py/test/test_pass.py b/tket-py/test/test_pass.py index c1fba774f..e0bd65474 100644 --- a/tket-py/test/test_pass.py +++ b/tket-py/test/test_pass.py @@ -261,13 +261,16 @@ def test_modifier_resolver() -> None: normalize = NormalizeGuppy(resolve_modifiers=False) normalize_with_modifier_resolution = NormalizeGuppy() mr_pass = ModifierResolverPass() - modifier_hugr: Hugr = _hugr_from_path("test_files/guppy_examples/modifiers.hugr") + # We consider a simple hugr for this test + modifier_hugr: Hugr = _hugr_from_path( + "test_files/modifier_examples/double_modifier.hugr" + ) normalized_and_resolved: Hugr = normalize_with_modifier_resolution(modifier_hugr) assert _count_ops(normalized_and_resolved, "tket.modifier.ControlModifier") == 0 assert _count_ops(normalized_and_resolved, "tket.modifier.DaggerModifier") == 0 - modifier_hugr = _hugr_from_path("test_files/guppy_examples/modifiers.hugr") + modifier_hugr = _hugr_from_path("test_files/modifier_examples/double_modifier.hugr") modifier_hugr = normalize(modifier_hugr) assert _count_ops(modifier_hugr, "tket.modifier.ControlModifier") == 1 diff --git a/tket/src/modifier/modifier_resolver.rs b/tket/src/modifier/modifier_resolver.rs index 4b91312dd..81a3a4aa7 100644 --- a/tket/src/modifier/modifier_resolver.rs +++ b/tket/src/modifier/modifier_resolver.rs @@ -133,7 +133,7 @@ use hugr::{ types::{EdgeKind, FuncTypeBase, Signature, Term, Type, TypeRow}, }; -/// A wire of eigher direction. +/// A wire of either direction. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] struct DirWire(N, Port); @@ -281,7 +281,7 @@ impl PortVector { outputs: impl Iterator, iter: impl Iterator, ) -> Self { - let iter = iter.collect::>(); + let iter = iter.collect::>(); let incoming = inputs .map(|p| { if iter.contains(&p) { @@ -457,6 +457,23 @@ impl ModifierResolverErrors { } } +/// Shared traversal context for the recursive function-input-requirement search. +/// +/// Bundles the parameters that are constant across recursive calls to +/// [`ModifierResolver::function_input_requirements_for_value`], +/// [`ModifierResolver::function_input_requirements_for_sum_field`], and +/// [`ModifierResolver::function_input_requirements_from_input`]. +struct FunctionInputContext<'a, N> { + /// Indices of function-typed inputs in the top-level function signature. + function_input_indices: &'a HashSet, + /// The top-level function node whose inputs are being analysed. + func: N, + /// Visited (node, port) pairs to prevent infinite recursion through values. + visited_values: &'a mut HashSet<(N, OutgoingPort)>, + /// Visited (node, port, variant, field) tuples to prevent infinite recursion through sum fields. + visited_sum_fields: &'a mut HashSet<(N, OutgoingPort, usize, usize)>, +} + // Utility functions for ModifierResolver impl ModifierResolver { fn modifiers_mut(&mut self) -> &mut CombinedModifier { @@ -471,7 +488,7 @@ impl ModifierResolver { fn controls(&mut self) -> &mut Vec { &mut self.controls } - fn controls_ref(&self) -> &Vec { + fn controls_ref(&self) -> &[Wire] { &self.controls } fn worklist(&mut self) -> &mut VecDeque { @@ -503,6 +520,11 @@ impl ModifierResolver { .unwrap_or_default() } + /// Follow a value through consecutive modifier nodes. + /// + /// This only consumes nodes such as `Control` and `Dagger`, accumulating + /// them into `modifiers`. It stops at the first non-modifier node, which is + /// often an `Input` node local to a nested container. fn trace_modifier_chain_with( &self, h: &impl HugrMut, @@ -568,12 +590,6 @@ impl ModifierResolver { .enumerate() .filter_map(|(index, ty)| matches!(**ty, Term::FunctionType(_)).then_some(index)) .collect::>(); - let mut quantum_function_input_indices = HashSet::new(); - for (index, ty) in function_inputs.iter().enumerate() { - if self.function_type_has_quantum_data(ty)? { - quantum_function_input_indices.insert(index); - } - } let mut requirements = Vec::new(); for node in h.descendants(func) { @@ -598,7 +614,17 @@ impl ModifierResolver { self.modifiers().clone(), )?; if matches!(h.get_optype(target), OpType::Input(_)) { - requirements.push((target_port.index(), modifiers)); + requirements.extend(self.function_input_requirements_from_input( + h, + &mut FunctionInputContext { + function_input_indices: &function_input_indices, + func, + visited_values: &mut HashSet::new(), + visited_sum_fields: &mut HashSet::new(), + }, + Wire::new(target, target_port), + modifiers, + )?); } } OpType::Call(call) => { @@ -625,7 +651,17 @@ impl ModifierResolver { let (target, target_port, modifiers) = self.trace_modifier_chain_with(h, source.0, source.1, modifiers)?; if matches!(h.get_optype(target), OpType::Input(_)) { - requirements.push((target_port.index(), modifiers)); + requirements.extend(self.function_input_requirements_from_input( + h, + &mut FunctionInputContext { + function_input_indices: &function_input_indices, + func, + visited_values: &mut HashSet::new(), + visited_sum_fields: &mut HashSet::new(), + }, + Wire::new(target, target_port), + modifiers, + )?); } } } @@ -635,18 +671,229 @@ impl ModifierResolver { visiting.remove(&func); requirements.retain(|(input, _)| function_input_indices.contains(input)); - if !requirements.is_empty() { - requirements.extend( - quantum_function_input_indices - .iter() - .copied() - .map(|input| (input, self.modifiers().clone())), - ); - } Ok(requirements.into_iter().unique().collect()) } + /// Trace a plain value back to the top-level function input that provides it. + fn function_input_requirements_for_value( + &self, + h: &impl HugrMut, + ctx: &mut FunctionInputContext<'_, N>, + source: Wire, + modifiers: CombinedModifier, + ) -> Result, ModifierResolverErrors> { + let (target, target_port, modifiers) = + self.trace_modifier_chain_with(h, source.node(), source.source(), modifiers)?; + if !ctx.visited_values.insert((target, target_port)) { + return Ok(Vec::new()); + } + + if matches!(h.get_optype(target), OpType::Input(_)) { + self.function_input_requirements_from_input( + h, + ctx, + Wire::new(target, target_port), + modifiers, + ) + } else { + Ok(Vec::new()) + } + } + + /// Trace one field of a sum value back to the top-level function input that + /// provides it. + fn function_input_requirements_for_sum_field( + &self, + h: &impl HugrMut, + ctx: &mut FunctionInputContext<'_, N>, + source: Wire, + variant: usize, + field: usize, + modifiers: CombinedModifier, + ) -> Result, ModifierResolverErrors> { + if !ctx + .visited_sum_fields + .insert((source.node(), source.source(), variant, field)) + { + return Ok(Vec::new()); + } + + match h.get_optype(source.node()) { + OpType::Tag(tag) if source.source().index() == 0 && tag.tag == variant => { + if h.num_inputs(source.node()) <= field { + return Ok(Vec::new()); + } + let Some((field_source, field_source_port)) = + h.single_linked_output(source.node(), field) + else { + return Ok(Vec::new()); + }; + self.function_input_requirements_for_value( + h, + ctx, + Wire::new(field_source, field_source_port), + modifiers, + ) + } + OpType::Conditional(_) => { + let Some(case) = h.children(source.node()).nth(variant) else { + return Ok(Vec::new()); + }; + let Some([_, case_output]) = h.get_io(case) else { + return Ok(Vec::new()); + }; + let Some((case_source, case_source_port)) = + h.single_linked_output(case_output, source.source().index()) + else { + return Ok(Vec::new()); + }; + self.function_input_requirements_for_sum_field( + h, + ctx, + Wire::new(case_source, case_source_port), + variant, + field, + modifiers, + ) + } + _ => Ok(Vec::new()), + } + } + + /// Lift a local container input back to an input of `func`. + /// + /// `input_node` may be the `Input` of `func` itself, or it may belong to a + /// nested `Case`, `DFG`, `TailLoop`, `CFG`, or `DataflowBlock`. The function + /// walks outward through those container boundaries, following the actual + /// incoming edge or carried branch payload instead of reusing the local port + /// number as a top-level function input index. + fn function_input_requirements_from_input( + &self, + h: &impl HugrMut, + ctx: &mut FunctionInputContext<'_, N>, + input: Wire, + modifiers: CombinedModifier, + ) -> Result, ModifierResolverErrors> { + let Some(parent) = h.get_parent(input.node()) else { + return Ok(Vec::new()); + }; + let input_index = input.source().index(); + if parent == ctx.func { + return Ok(ctx + .function_input_indices + .contains(&input_index) + .then_some((input_index, modifiers)) + .into_iter() + .collect()); + } + + match h.get_optype(parent) { + OpType::Case(_) => { + let Some(conditional) = h.get_parent(parent) else { + return Ok(Vec::new()); + }; + let OpType::Conditional(conditional_op) = h.get_optype(conditional) else { + return Ok(Vec::new()); + }; + let Some(case_index) = h.children(conditional).position(|case| case == parent) + else { + return Ok(Vec::new()); + }; + let tag_inputs = conditional_op + .sum_rows + .get(case_index) + .map(TypeRow::len) + .unwrap_or_default(); + let Some((source, source_port)) = + h.single_linked_output(conditional, input_index - tag_inputs + 1) + else { + return Ok(Vec::new()); + }; + self.function_input_requirements_for_value( + h, + ctx, + Wire::new(source, source_port), + modifiers, + ) + } + OpType::DataflowBlock(_) => { + let predecessors = if h.num_inputs(parent) > 0 { + h.linked_outputs(parent, IncomingPort::from(0)) + .collect::>() + } else { + Vec::new() + }; + if predecessors.is_empty() { + let Some(cfg) = h.get_parent(parent) else { + return Ok(Vec::new()); + }; + if h.num_inputs(cfg) <= input_index { + return Ok(Vec::new()); + } + let Some((source, source_port)) = h.single_linked_output(cfg, input_index) + else { + return Ok(Vec::new()); + }; + return self.function_input_requirements_for_value( + h, + ctx, + Wire::new(source, source_port), + modifiers, + ); + } + + let mut requirements = Vec::new(); + for (predecessor, branch_port) in predecessors { + let OpType::DataflowBlock(predecessor_block) = h.get_optype(predecessor) else { + continue; + }; + let Some([_, predecessor_output]) = h.get_io(predecessor) else { + continue; + }; + let Some((sum_source, sum_source_port)) = + h.single_linked_output(predecessor_output, 0) + else { + continue; + }; + // CFG blocks carry branch data in two equivalent shapes: + // the first output is the branch sum value, while following + // output ports flatten every variant payload. Trace both so + // provenance is recovered for HUGRs using either encoding. + requirements.extend(self.function_input_requirements_for_sum_field( + h, + ctx, + Wire::new(sum_source, sum_source_port), + branch_port.index(), + input_index, + modifiers.clone(), + )?); + let field_input = 1 + + predecessor_block + .sum_rows + .iter() + .take(branch_port.index()) + .map(TypeRow::len) + .sum::() + + input_index; + if h.num_inputs(predecessor_output) > field_input + && let Some((field_source, field_source_port)) = + h.single_linked_output(predecessor_output, field_input) + { + requirements.extend(self.function_input_requirements_for_value( + h, + ctx, + Wire::new(field_source, field_source_port), + modifiers.clone(), + )?); + } + } + Ok(requirements) + } + _ => Ok(Vec::new()), + } + } + fn modified_function_input_type(&self, ty: &Type) -> Result> { let Term::FunctionType(func_ty) = &**ty else { return Err(ModifierResolverErrors::unreachable(format!( @@ -815,24 +1062,15 @@ impl ModifierResolver { old: DirWire, new: DirWire, ) -> Result<(), ModifierResolverErrors> { - match self.corresp_map().entry(old) { - std::collections::hash_map::Entry::Vacant(entry) => { - entry.insert(vec![new]); - Ok(()) - } - // Empty entry means that the old wire has no correspondence, so we can insert the new wire. - std::collections::hash_map::Entry::Occupied(mut entry) if entry.get().is_empty() => { - entry.insert(vec![new]); - Ok(()) - } - // If the old wire is already registered, raise an error. - std::collections::hash_map::Entry::Occupied(entry) => { - let former = entry.get(); - Err(ModifierResolverErrors::unreachable(format!( - "Wire already registered for node {}. Former [{},...], Latter {}.", - old.0, former[0], new - ))) - } + let vec = self.corresp_map().entry(old).or_default(); + if vec.is_empty() { + vec.push(new); + Ok(()) + } else { + Err(ModifierResolverErrors::unreachable(format!( + "Wire already registered for node {}. Former [{},...], Latter {}.", + old.0, vec[0], new + ))) } } @@ -866,7 +1104,7 @@ impl ModifierResolver { Ok(()) } - /// This function adds a node to the builder, that does not affected by the modifiers. + /// This function adds a node to the builder that is not affected by the modifiers. fn add_node_no_modification( &mut self, h: &impl HugrMut, @@ -978,9 +1216,9 @@ impl ModifierResolver { Ok(()) } - /// Apply the resolver the current node `n`. + /// Apply the resolver to the current node `n`. /// It first checks if the node is a modifier and can be applied. - /// If not, it returns an [`ModifierError`]. + /// If not, it returns a [`ModifierError`]. /// If yes, it applies the modifier to the loaded function, fn try_rewrite( &mut self, @@ -1047,7 +1285,7 @@ impl ModifierResolver { } } - // We take arbitral topological order of the circuit so that we can plug the control qubits + // We take an arbitrary topological order of the circuit so that we can plug the control qubits // and pass around them in that order. This might not be ideal, as it may produce an inefficient order. fn modify_op( &mut self, @@ -1155,7 +1393,7 @@ impl ModifierResolver { /// * `new_offset`: the offset of the ports of the new node, especially the number of control qubits. /// /// The order of the resulting ports is determined as follows: - /// - Every ports are devided into quantum ports and non-quantum ports. + /// - Every port is divided into quantum ports and non-quantum ports. /// - Until the first quantum port is reached, the non-quantum ports are wired in order. /// - When a quantum port is reached for both inputs and outputs, /// if the dagger is applied, the quantum input is wired to the output, @@ -2406,52 +2644,18 @@ mod tests { /// Run the pass on hugrs generated by guppy and modifier examples. #[rstest::rstest] + #[case::cfg_in_ctrl("../test_files/modifier_examples/cfg_in_ctrl.hugr")] + #[case::classical_function("../test_files/modifier_examples/classical_function.hugr")] + #[case::complex_cfg_higher_order( + "../test_files/modifier_examples/complex_cfg_higher_order.hugr" + )] + #[case::double_modifier("../test_files/modifier_examples/double_modifier.hugr")] #[case::even_dagger("../test_files/modifier_examples/even_dagger.hugr")] #[case::higher_order_recursive("../test_files/modifier_examples/higher_order_recursive.hugr")] - #[case::higher_order_classical("../test_files/modifier_examples/higher_order_classical.hugr")] - #[case::higher_order_function_w_loops( - "../test_files/modifier_examples/higher_order_function_w_loops.hugr" - )] + #[case::loaded_pytket("../test_files/modifier_examples/loaded_pytket.hugr")] + #[case::multiple_functions("../test_files/modifier_examples/multiple_functions.hugr")] + #[case::nested_multiple("../test_files/modifier_examples/nested_multiple.hugr")] #[case::simple_higher_order("../test_files/modifier_examples/simple_higher_order.hugr")] - #[case::multiple_functions_in_ctrl_dagger( - "../test_files/modifier_examples/multiple_functions_in_ctrl_dagger.hugr" - )] - #[case::guppy_modifiers("../test_files/guppy_examples/modifiers.hugr")] - #[case::assign_in_dagger("../test_files/modifier_examples/assign_in_dagger.hugr")] - #[case::classical_array_op("../test_files/modifier_examples/classical_array_op.hugr")] - #[case::classical_function1("../test_files/modifier_examples/classical_function1.hugr")] - #[case::classical_function2("../test_files/modifier_examples/classical_function2.hugr")] - #[case::classical_function3("../test_files/modifier_examples/classical_function3.hugr")] - #[case::ctrl_on_cfg("../test_files/modifier_examples/ctrl_on_cfg.hugr")] - #[case::multiple_gates2_in_ctrl("../test_files/modifier_examples/multiple_gates2_in_ctrl.hugr")] - #[case::subscript_in_ctrl("../test_files/modifier_examples/subscript_in_ctrl.hugr")] - #[case::subscript_in_dagger("../test_files/modifier_examples/subscript_in_dagger.hugr")] - #[case::subscript_as_controller("../test_files/modifier_examples/subscript_as_controller.hugr")] - #[case::complex_modifier_stress("../test_files/modifier_examples/complex_modifier_stress.hugr")] - #[case::ctrl_array_controller("../test_files/modifier_examples/ctrl_array_controller.hugr")] - #[case::call1_in_ctrl("../test_files/modifier_examples/call1_in_ctrl.hugr")] - #[case::call2_in_ctrl("../test_files/modifier_examples/call2_in_ctrl.hugr")] - #[case::multiple_gates1_in_ctrl("../test_files/modifier_examples/multiple_gates1_in_ctrl.hugr")] - #[case::gate_in_ctrl("../test_files/modifier_examples/gate_in_ctrl.hugr")] - #[case::call_in_dagger("../test_files/modifier_examples/call_in_dagger.hugr")] - #[case::multiple_functions_in_dagger( - "../test_files/modifier_examples/multiple_functions_in_dagger.hugr" - )] - #[case::multiple_gates1_in_dagger( - "../test_files/modifier_examples/multiple_gates1_in_dagger.hugr" - )] - #[case::multiple_gates2_in_dagger( - "../test_files/modifier_examples/multiple_gates2_in_dagger.hugr" - )] - #[case::multiple_gates3_in_dagger( - "../test_files/modifier_examples/multiple_gates3_in_dagger.hugr" - )] - #[case::double_modifier("../test_files/modifier_examples/double_modifier.hugr")] - #[case::modify_array("../test_files/modifier_examples/modify_array.hugr")] - #[case::multiple_dagger("../test_files/modifier_examples/multiple_dagger.hugr")] - #[case::nested_ctrl_dagger1("../test_files/modifier_examples/nested_ctrl_dagger1.hugr")] - #[case::nested_multiple_ctrl1("../test_files/modifier_examples/nested_multiple_ctrl1.hugr")] - #[case::swap_in_dagger("../test_files/modifier_examples/swap_in_dagger.hugr")] #[case::subscript_in_dagger_ctrl( "../test_files/modifier_examples/subscript_in_dagger_ctrl.hugr" )] diff --git a/tket/src/modifier/modifier_resolver/call_modify.rs b/tket/src/modifier/modifier_resolver/call_modify.rs index de3241b53..aa21849bd 100644 --- a/tket/src/modifier/modifier_resolver/call_modify.rs +++ b/tket/src/modifier/modifier_resolver/call_modify.rs @@ -306,24 +306,37 @@ impl ModifierResolver { // Instead, we record the modifiers to be applied to that input and propagate // the requirement to callers. if matches!(h.get_optype(targ), OpType::Input(_)) { - // If no quantum data is involved, we can skip modifying the call + // If no quantum data is involved, we can skip modifying the call. if !self.signature_has_quantum_data(&indir_call.signature) { + *self.modifiers_mut() = modifiers; self.add_node_no_modification(h, n, indir_call.clone(), new_dfg)?; return Ok(()); } *self.modifiers_mut() = modifiers; return self.modify_input_indirect_call(n, chain_tail.1.index(), indir_call, new_dfg); } + if let OpType::CallIndirect(source_indir_call) = h.get_optype(targ) { + *self.modifiers_mut() = modifiers; + if self.signature_has_quantum_data(&source_indir_call.signature) { + return Err(ModifierResolverErrors::unresolvable( + n, + "Cannot modify consecutive indirect calls with a quantum signature: + the produced callable consumes or allocates qubits, so this pattern is not allowed + in a modifier context.", + indir_call.clone().into(), + )); + } + self.add_node_no_modification(h, n, indir_call.clone(), new_dfg)?; + return Ok(()); + } // If the target is not a input, we expect it to be a LoadFunction node loading the function to call. let (func, load) = Self::get_loaded_function(h, n, targ, h.get_optype(targ)).map_err(wrap_modifier_err)?; - // Modify the function (if needed) let Some(modified_fn) = self.modify_fn_if_needed(h, func)? else { // The loaded function does not satisfy the active modifier, so keep - // it unchanged. - // If same modifier are present, we raise an error instead of silently skipping modification, - // since that likely indicates a mistake in the input graph + // it unchanged. If same modifier are present, we raise an error instead + // of silently skipping modification. *self.modifiers_mut() = modifiers; if trace.len() > 1 { return Err(ModifierResolverErrors::unresolvable(