From 7fd861f0b1b7b51df3562f1d0d5c613bc9b0c81d Mon Sep 17 00:00:00 2001 From: mstechly Date: Tue, 21 Apr 2026 14:04:09 +0200 Subject: [PATCH 01/14] feat: add public API for post-compilation derived resources --- src/bartiq/__init__.py | 5 +- src/bartiq/compilation/__init__.py | 4 +- src/bartiq/transform.py | 46 +++++++++++++-- tests/test_transform.py | 95 ++++++++++++++++++++++++++++-- 4 files changed, 137 insertions(+), 13 deletions(-) diff --git a/src/bartiq/__init__.py b/src/bartiq/__init__.py index 89393b0d..a787590c 100644 --- a/src/bartiq/__init__.py +++ b/src/bartiq/__init__.py @@ -21,8 +21,9 @@ Routine, routine_to_qref, ) -from .compilation import compile_routine, evaluate +from .compilation import DerivedResources, compile_routine, evaluate from .symbolics import sympy_backend +from .transform import add_derived_resources __all__ = [ "Port", @@ -32,7 +33,9 @@ "Resource", "CompiledRoutine", "routine_to_qref", + "DerivedResources", "compile_routine", "evaluate", "sympy_backend", + "add_derived_resources", ] diff --git a/src/bartiq/compilation/__init__.py b/src/bartiq/compilation/__init__.py index 42303616..8bd1ce1e 100644 --- a/src/bartiq/compilation/__init__.py +++ b/src/bartiq/compilation/__init__.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. """The compilation submodule contains routine compilation functionality.""" -from ._compile import CompilationFlags, CompilationResult, compile_routine +from ._compile import CompilationFlags, CompilationResult, DerivedResources, compile_routine from ._evaluate import EvaluationResult, evaluate -__all__ = ["compile_routine", "CompilationResult", "evaluate", "EvaluationResult", "CompilationFlags"] +__all__ = ["compile_routine", "CompilationResult", "DerivedResources", "evaluate", "EvaluationResult", "CompilationFlags"] diff --git a/src/bartiq/transform.py b/src/bartiq/transform.py index 29938d20..2f421482 100644 --- a/src/bartiq/transform.py +++ b/src/bartiq/transform.py @@ -14,19 +14,23 @@ from __future__ import annotations import copy +from collections.abc import Iterable from dataclasses import replace from functools import wraps from graphlib import TopologicalSorter -from typing import Any, Callable, Concatenate, ParamSpec, overload +from typing import TYPE_CHECKING, Any, Callable, Concatenate, ParamSpec, overload -from bartiq import CompiledRoutine, Resource, ResourceType, Routine -from bartiq.compilation._evaluate import evaluate -from bartiq.symbolics import sympy_backend -from bartiq.symbolics.backend import SymbolicBackend, T, TExpr +from ._routine import CompiledRoutine, Resource, ResourceType, Routine +from .compilation._evaluate import evaluate +from .symbolics import sympy_backend +from .symbolics.backend import SymbolicBackend, T, TExpr P = ParamSpec("P") BACKEND = sympy_backend +if TYPE_CHECKING: + from .compilation._compile import DerivedResources + RoutineTransform = Callable[Concatenate[Routine[T], SymbolicBackend[T], P], Routine[T]] CompiledRoutineTransform = Callable[Concatenate[CompiledRoutine[T], SymbolicBackend[T], P], CompiledRoutine[T]] @@ -90,6 +94,38 @@ def _inner(routine: Routine[T], backend: SymbolicBackend[T], *args, **kwargs) -> AggregationDict = dict[str, dict[str, TExpr[T]]] +def add_derived_resources( + routine: CompiledRoutine[T], + derived_resources: Iterable["DerivedResources[T]"] | None = None, + backend: SymbolicBackend[T] = BACKEND, +) -> CompiledRoutine[T]: + """Add derived resources to an already compiled routine. + + Args: + routine: The compiled routine to which the resources should be added. + derived_resources: Resource specifications matching the ``derived_resources`` argument + accepted by ``compile_routine``. + backend: Backend instance to use for handling expressions. + + Returns: + The routine with derived resources added to each subroutine in postorder. + """ + if not derived_resources: + return routine + return _add_derived_resources_postorder(routine, backend, tuple(derived_resources)) + + +@postorder_transform +def _add_derived_resources_postorder( + routine: CompiledRoutine[T], + backend: SymbolicBackend[T], + derived_resources: tuple["DerivedResources[T]", ...], +) -> CompiledRoutine[T]: + from .compilation._compile import _add_derived_resources + + return _add_derived_resources(routine, backend, derived_resources) + + def add_aggregated_resources( routine: CompiledRoutine[T], aggregation_dict: AggregationDict[T], diff --git a/tests/test_transform.py b/tests/test_transform.py index 15d09655..20e8bb99 100644 --- a/tests/test_transform.py +++ b/tests/test_transform.py @@ -16,8 +16,8 @@ import sympy from qref.schema_v1 import RoutineV1 -from bartiq import CompiledRoutine, Routine -from bartiq.transform import add_aggregated_resources, add_circuit_volume +from bartiq import CompiledRoutine, Resource, ResourceType, Routine +from bartiq.transform import add_aggregated_resources, add_circuit_volume, add_derived_resources ccry_gate = { "name": "ccry_gate", @@ -248,9 +248,6 @@ def test_add_circuit_volume_simple(backend): def test_add_circuit_volume_with_children(backend): - from bartiq import CompiledRoutine, Resource, ResourceType - from bartiq.transform import add_circuit_volume - # Create a child routine with required resources child = CompiledRoutine( name="child", @@ -304,3 +301,91 @@ def test_add_circuit_volume_with_children(backend): ) assert "circuit_volume" in out2.resources assert out2.resources["circuit_volume"].value == 14 + + +def test_add_derived_resources_to_compiled_routine(backend): + routine = CompiledRoutine( + name="root", + type=None, + input_params=["n"], + children={}, + ports={}, + resources={ + "a": Resource("a", ResourceType.additive, backend.as_expression("n")), + "b": Resource("b", ResourceType.additive, backend.as_expression("2*n")), + }, + connections={}, + children_order=(), + ) + + def _sum_resources(compiled_routine, symbolic_backend): + return symbolic_backend.as_expression(compiled_routine.resource_values["a"]) + symbolic_backend.as_expression( + compiled_routine.resource_values["b"] + ) + + result = add_derived_resources( + routine, + [{"name": "c", "type": "additive", "calculate": _sum_resources}], + backend=backend, + ) + + assert str(result.resources["c"].value) == "3*n" + + +def test_add_derived_resources_is_applied_postorder(backend): + child = CompiledRoutine( + name="child", + type=None, + input_params=[], + children={}, + ports={}, + resources={"x": Resource("x", ResourceType.additive, 2)}, + connections={}, + children_order=(), + ) + parent = CompiledRoutine( + name="parent", + type=None, + input_params=[], + children={"child": child}, + ports={}, + resources={"x": Resource("x", ResourceType.additive, backend.as_expression("child.x"))}, + connections={}, + children_order=("child",), + ) + + def _double_x(compiled_routine, symbolic_backend): + return 2 * symbolic_backend.as_expression(compiled_routine.resource_values["x"]) + + result = add_derived_resources( + parent, + [{"name": "double_x", "type": "additive", "calculate": _double_x}], + backend=backend, + ) + + assert result.children["child"].resources["double_x"].value == 4 + assert str(result.resources["double_x"].value) == "2*child.x" + + +def test_add_derived_resources_accepts_iterables(backend): + routine = CompiledRoutine( + name="root", + type=None, + input_params=[], + children={}, + ports={}, + resources={"x": Resource("x", ResourceType.additive, 2)}, + connections={}, + children_order=(), + ) + + def _triple_x(compiled_routine, symbolic_backend): + return 3 * symbolic_backend.as_expression(compiled_routine.resource_values["x"]) + + result = add_derived_resources( + routine, + (spec for spec in [{"name": "triple_x", "type": "additive", "calculate": _triple_x}]), + backend=backend, + ) + + assert result.resources["triple_x"].value == 6 From cc6326e83064ecd20fd75b056b4652b08e66e3dc Mon Sep 17 00:00:00 2001 From: mstechly Date: Wed, 22 Apr 2026 10:11:32 +0200 Subject: [PATCH 02/14] refactor: minor fixes for add_derived_resources --- src/bartiq/transform.py | 18 +++++----- tests/test_transform.py | 80 ++++++++++++----------------------------- 2 files changed, 32 insertions(+), 66 deletions(-) diff --git a/src/bartiq/transform.py b/src/bartiq/transform.py index 2f421482..19afe108 100644 --- a/src/bartiq/transform.py +++ b/src/bartiq/transform.py @@ -112,18 +112,18 @@ def add_derived_resources( """ if not derived_resources: return routine - return _add_derived_resources_postorder(routine, backend, tuple(derived_resources)) + from .compilation._compile import _add_derived_resources + derived_resources = tuple(derived_resources) -@postorder_transform -def _add_derived_resources_postorder( - routine: CompiledRoutine[T], - backend: SymbolicBackend[T], - derived_resources: tuple["DerivedResources[T]", ...], -) -> CompiledRoutine[T]: - from .compilation._compile import _add_derived_resources + @postorder_transform + def _apply( + subroutine: CompiledRoutine[T], + subroutine_backend: SymbolicBackend[T], + ) -> CompiledRoutine[T]: + return _add_derived_resources(subroutine, subroutine_backend, derived_resources) - return _add_derived_resources(routine, backend, derived_resources) + return _apply(routine, backend) def add_aggregated_resources( diff --git a/tests/test_transform.py b/tests/test_transform.py index 20e8bb99..5768587a 100644 --- a/tests/test_transform.py +++ b/tests/test_transform.py @@ -304,19 +304,16 @@ def test_add_circuit_volume_with_children(backend): def test_add_derived_resources_to_compiled_routine(backend): - routine = CompiledRoutine( - name="root", - type=None, - input_params=["n"], - children={}, - ports={}, - resources={ - "a": Resource("a", ResourceType.additive, backend.as_expression("n")), - "b": Resource("b", ResourceType.additive, backend.as_expression("2*n")), - }, - connections={}, - children_order=(), - ) + input_qref = { + "name": "root", + "type": None, + "input_params": ["n"], + "resources": [ + {"name": "a", "type": "additive", "value": "n"}, + {"name": "b", "type": "additive", "value": "2*n"}, + ], + } + routine = CompiledRoutine.from_qref(RoutineV1(**input_qref), backend) def _sum_resources(compiled_routine, symbolic_backend): return symbolic_backend.as_expression(compiled_routine.resource_values["a"]) + symbolic_backend.as_expression( @@ -333,26 +330,19 @@ def _sum_resources(compiled_routine, symbolic_backend): def test_add_derived_resources_is_applied_postorder(backend): - child = CompiledRoutine( - name="child", - type=None, - input_params=[], - children={}, - ports={}, - resources={"x": Resource("x", ResourceType.additive, 2)}, - connections={}, - children_order=(), - ) - parent = CompiledRoutine( - name="parent", - type=None, - input_params=[], - children={"child": child}, - ports={}, - resources={"x": Resource("x", ResourceType.additive, backend.as_expression("child.x"))}, - connections={}, - children_order=("child",), - ) + input_qref = { + "name": "parent", + "type": None, + "children": [ + { + "name": "child", + "type": None, + "resources": [{"name": "x", "type": "additive", "value": 2}], + } + ], + "resources": [{"name": "x", "type": "additive", "value": "child.x"}], + } + parent = CompiledRoutine.from_qref(RoutineV1(**input_qref), backend) def _double_x(compiled_routine, symbolic_backend): return 2 * symbolic_backend.as_expression(compiled_routine.resource_values["x"]) @@ -365,27 +355,3 @@ def _double_x(compiled_routine, symbolic_backend): assert result.children["child"].resources["double_x"].value == 4 assert str(result.resources["double_x"].value) == "2*child.x" - - -def test_add_derived_resources_accepts_iterables(backend): - routine = CompiledRoutine( - name="root", - type=None, - input_params=[], - children={}, - ports={}, - resources={"x": Resource("x", ResourceType.additive, 2)}, - connections={}, - children_order=(), - ) - - def _triple_x(compiled_routine, symbolic_backend): - return 3 * symbolic_backend.as_expression(compiled_routine.resource_values["x"]) - - result = add_derived_resources( - routine, - (spec for spec in [{"name": "triple_x", "type": "additive", "calculate": _triple_x}]), - backend=backend, - ) - - assert result.resources["triple_x"].value == 6 From ba3261cd895ef7f6a0ced7a4069dd4965b6ecea4 Mon Sep 17 00:00:00 2001 From: mstechly Date: Thu, 23 Apr 2026 14:42:57 +0200 Subject: [PATCH 03/14] style: fix black & isort issues --- src/bartiq/analysis/__init__.py | 1 + src/bartiq/analysis/rewriters/__init__.py | 1 + .../analysis/rewriters/routine_rewriter.py | 1 + src/bartiq/analysis/rewriters/utils.py | 1 + src/bartiq/compilation/__init__.py | 17 +++++++++++++++-- src/bartiq/integrations/__init__.py | 1 + src/bartiq/symbolics/__init__.py | 1 + src/bartiq/symbolics/ast_parser.py | 1 + tests/test_transform.py | 6 +++++- 9 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/bartiq/analysis/__init__.py b/src/bartiq/analysis/__init__.py index f35411d9..fc9fc129 100644 --- a/src/bartiq/analysis/__init__.py +++ b/src/bartiq/analysis/__init__.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. """The bartiq analysis module provides methods to manipulate symbolic expressions.""" + from bartiq.analysis.rewriters import rewrite_routine_resources, sympy_rewriter __all__ = ["sympy_rewriter", "rewrite_routine_resources"] diff --git a/src/bartiq/analysis/rewriters/__init__.py b/src/bartiq/analysis/rewriters/__init__.py index 86859640..c632814d 100644 --- a/src/bartiq/analysis/rewriters/__init__.py +++ b/src/bartiq/analysis/rewriters/__init__.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. """Rewriters can be used to modify, or simplify, the form of symbolic expressions.""" + from bartiq.analysis.rewriters.routine_rewriter import rewrite_routine_resources from bartiq.analysis.rewriters.sympy_expression import sympy_rewriter diff --git a/src/bartiq/analysis/rewriters/routine_rewriter.py b/src/bartiq/analysis/rewriters/routine_rewriter.py index fcd6cb66..43a7fdec 100644 --- a/src/bartiq/analysis/rewriters/routine_rewriter.py +++ b/src/bartiq/analysis/rewriters/routine_rewriter.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. """Here we provide functionality to allow you to apply rewriters to CompiledRoutine resource expressions.""" + from __future__ import annotations from collections.abc import Iterable diff --git a/src/bartiq/analysis/rewriters/utils.py b/src/bartiq/analysis/rewriters/utils.py index 673a68ce..77a7eaa6 100644 --- a/src/bartiq/analysis/rewriters/utils.py +++ b/src/bartiq/analysis/rewriters/utils.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. """This module provides some helper functions for describing instructions in rewriters.""" + from __future__ import annotations import re diff --git a/src/bartiq/compilation/__init__.py b/src/bartiq/compilation/__init__.py index 8bd1ce1e..5e9add10 100644 --- a/src/bartiq/compilation/__init__.py +++ b/src/bartiq/compilation/__init__.py @@ -12,7 +12,20 @@ # See the License for the specific language governing permissions and # limitations under the License. """The compilation submodule contains routine compilation functionality.""" -from ._compile import CompilationFlags, CompilationResult, DerivedResources, compile_routine + +from ._compile import ( + CompilationFlags, + CompilationResult, + DerivedResources, + compile_routine, +) from ._evaluate import EvaluationResult, evaluate -__all__ = ["compile_routine", "CompilationResult", "DerivedResources", "evaluate", "EvaluationResult", "CompilationFlags"] +__all__ = [ + "compile_routine", + "CompilationResult", + "DerivedResources", + "evaluate", + "EvaluationResult", + "CompilationFlags", +] diff --git a/src/bartiq/integrations/__init__.py b/src/bartiq/integrations/__init__.py index 2eb064dc..452474a0 100644 --- a/src/bartiq/integrations/__init__.py +++ b/src/bartiq/integrations/__init__.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. """The integrations submodule permits LaTeX pretty-printing, and implements Jupyter notebook widgets.""" + from .latex import routine_to_latex __all__ = ["routine_to_latex"] diff --git a/src/bartiq/symbolics/__init__.py b/src/bartiq/symbolics/__init__.py index 023f12fd..e7594ac6 100644 --- a/src/bartiq/symbolics/__init__.py +++ b/src/bartiq/symbolics/__init__.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. """The symbolics submodule manages all implemented symbolic backends.""" + from .sympy_backend import sympy_backend __all__ = ["sympy_backend"] diff --git a/src/bartiq/symbolics/ast_parser.py b/src/bartiq/symbolics/ast_parser.py index 4da2d6d8..e42cddf4 100644 --- a/src/bartiq/symbolics/ast_parser.py +++ b/src/bartiq/symbolics/ast_parser.py @@ -50,6 +50,7 @@ binary expressions, and we assume that operators of the constructed objects behave like they should with built-in operators. """ + import ast import operator import re diff --git a/tests/test_transform.py b/tests/test_transform.py index 5768587a..34a97bc2 100644 --- a/tests/test_transform.py +++ b/tests/test_transform.py @@ -17,7 +17,11 @@ from qref.schema_v1 import RoutineV1 from bartiq import CompiledRoutine, Resource, ResourceType, Routine -from bartiq.transform import add_aggregated_resources, add_circuit_volume, add_derived_resources +from bartiq.transform import ( + add_aggregated_resources, + add_circuit_volume, + add_derived_resources, +) ccry_gate = { "name": "ccry_gate", From 147445c84b5f4fa44eb71ad69f9b71313dec8382 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konrad=20Ja=C5=82owiecki?= Date: Wed, 20 May 2026 12:45:06 +0200 Subject: [PATCH 04/14] chore: Migrate pre-commit-config --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9754708c..84104817 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -15,7 +15,7 @@ default_language_version: python: python3 -default_stages: [commit, push] +default_stages: [pre-commit, pre-push] repos: - repo: https://github.com/PyCQA/isort From 5919b3112c1dade50aad3fa645882e7abddb89f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konrad=20Ja=C5=82owiecki?= Date: Wed, 20 May 2026 12:47:57 +0200 Subject: [PATCH 05/14] refactor: Move _add_derived_resources to bartiq.compilation._common --- src/bartiq/compilation/__init__.py | 8 +--- src/bartiq/compilation/_common.py | 68 ++++++++++++++++++++++++++++-- src/bartiq/compilation/_compile.py | 58 ++----------------------- src/bartiq/transform.py | 2 +- 4 files changed, 71 insertions(+), 65 deletions(-) diff --git a/src/bartiq/compilation/__init__.py b/src/bartiq/compilation/__init__.py index 5e9add10..c54875be 100644 --- a/src/bartiq/compilation/__init__.py +++ b/src/bartiq/compilation/__init__.py @@ -13,12 +13,8 @@ # limitations under the License. """The compilation submodule contains routine compilation functionality.""" -from ._compile import ( - CompilationFlags, - CompilationResult, - DerivedResources, - compile_routine, -) +from ._common import DerivedResources +from ._compile import CompilationFlags, CompilationResult, compile_routine from ._evaluate import EvaluationResult, evaluate __all__ = [ diff --git a/src/bartiq/compilation/_common.py b/src/bartiq/compilation/_common.py index 0c40a80c..07d73c8e 100644 --- a/src/bartiq/compilation/_common.py +++ b/src/bartiq/compilation/_common.py @@ -13,11 +13,21 @@ # limitations under the License. from __future__ import annotations +import inspect from collections.abc import Iterable from dataclasses import dataclass, replace -from typing import Callable - -from .._routine import CompiledRoutine, Constraint, ConstraintStatus, Port, Resource +from typing import Callable, Generic, Protocol + +from typing_extensions import TypedDict, TypeIs + +from .._routine import ( + CompiledRoutine, + Constraint, + ConstraintStatus, + Port, + Resource, + ResourceType, +) from ..repetitions import Repetition from ..symbolics.backend import ComparisonResult, SymbolicBackend, T, TExpr @@ -39,6 +49,14 @@ def __init__(self, original_constraint: Constraint[T], compiled_constraint: Cons super().__init__(original_constraint, compiled_constraint) +class DerivedResources(TypedDict, Generic[T]): + """Contains information needed to calculate derived resources.""" + + name: str + type: str + calculate: Calculate[T] | CalculateWithName[T] + + def evaluate_ports( ports: dict[str, Port[T]], inputs: dict[str, TExpr[T]], @@ -130,3 +148,47 @@ def _collect_first_pass_resource_variables(children: dict[str, CompiledRoutine[T def collect_children_variables(children: dict[str, CompiledRoutine[T]]) -> dict[str, TExpr[T]]: return _collect_resource_variables(children) | _collect_first_pass_resource_variables(children) + + +def _accepts_resource_name(func: Calculate[T] | CalculateWithName[T]) -> TypeIs[CalculateWithName[T]]: + return "resource_name" in inspect.signature(func).parameters + + +class Calculate(Protocol[T]): + + def __call__(self, routine: CompiledRoutine[T], backend: SymbolicBackend[T]) -> TExpr[T] | None: + pass + + +class CalculateWithName(Protocol[T]): + + def __call__(self, routine: CompiledRoutine[T], backend: SymbolicBackend[T], resource_name: str) -> TExpr[T] | None: + pass + + +def _add_derived_resources( + routine: CompiledRoutine[T], + backend: SymbolicBackend[T], + derived_resources: Iterable[DerivedResources[T]] = (), +) -> CompiledRoutine[T]: + for specs in derived_resources: + name = specs["name"] + type = specs["type"] + calculate = specs["calculate"] + + value = ( + calculate(routine, backend, resource_name=name) + if _accepts_resource_name(calculate) + else calculate(routine, backend) + ) + + if value is not None: + resource = Resource(name, type=ResourceType(type), value=value) + routine = replace( + routine, + resources={ + **routine.resources, + name: resource, + }, + ) + return routine diff --git a/src/bartiq/compilation/_compile.py b/src/bartiq/compilation/_compile.py index 9e192626..b65636b8 100644 --- a/src/bartiq/compilation/_compile.py +++ b/src/bartiq/compilation/_compile.py @@ -14,7 +14,6 @@ from __future__ import annotations import ast -import inspect import operator import os import warnings @@ -24,13 +23,12 @@ from enum import Flag, auto from functools import reduce from graphlib import TopologicalSorter -from typing import Generic, Protocol +from typing import Generic from qref import SchemaV1 from qref.functools import ensure_routine from qref.schema_v1 import RoutineV1 from qref.verification import verify_topology -from typing_extensions import TypedDict, TypeIs from bartiq._routine import ( CompiledRoutine, @@ -44,6 +42,8 @@ from bartiq.compilation._common import ( ConstraintValidationError, Context, + DerivedResources, + _add_derived_resources, collect_children_variables, evaluate_constraints, evaluate_ports, @@ -92,26 +92,6 @@ class CompilationFlags(Flag): """Skip the verification step on the routine.""" -class Calculate(Protocol[T]): - - def __call__(self, routine: CompiledRoutine[T], backend: SymbolicBackend[T]) -> TExpr[T] | None: - pass - - -class CalculateWithName(Protocol[T]): - - def __call__(self, routine: CompiledRoutine[T], backend: SymbolicBackend[T], resource_name: str) -> TExpr[T] | None: - pass - - -class DerivedResources(TypedDict, Generic[T]): - """Contains information needed to calculate derived resources.""" - - name: str - type: str - calculate: Calculate[T] | CalculateWithName[T] - - @dataclass class CompilationResult(Generic[T]): """ @@ -436,10 +416,6 @@ def _compile( return replace(compiled_routine, resources=tmp_routine.resources) -def _accepts_resource_name(func: Calculate[T] | CalculateWithName[T]) -> TypeIs[CalculateWithName[T]]: - return "resource_name" in inspect.signature(func).parameters - - def _introduce_placeholder_resources( compiled_routine: CompiledRoutine[T], backend: SymbolicBackend[T] ) -> CompiledRoutine[T]: @@ -468,34 +444,6 @@ def _introduce_placeholder_child_resources( ) -def _add_derived_resources( - routine: CompiledRoutine[T], - backend: SymbolicBackend[T], - derived_resources: Iterable[DerivedResources[T]] = (), -) -> CompiledRoutine[T]: - for specs in derived_resources: - name = specs["name"] - type = specs["type"] - calculate = specs["calculate"] - - value = ( - calculate(routine, backend, resource_name=name) - if _accepts_resource_name(calculate) - else calculate(routine, backend) - ) - - if value is not None: - resource = Resource(name, type=ResourceType(type), value=value) - routine = replace( - routine, - resources={ - **routine.resources, - name: resource, - }, - ) - return routine - - def _generate_arithmetic_resources( resources: dict[str, Resource[T]], compiled_children: dict[str, CompiledRoutine[T]], backend: SymbolicBackend[T] ) -> dict[str, Resource[T]]: diff --git a/src/bartiq/transform.py b/src/bartiq/transform.py index 19afe108..c834c853 100644 --- a/src/bartiq/transform.py +++ b/src/bartiq/transform.py @@ -21,6 +21,7 @@ from typing import TYPE_CHECKING, Any, Callable, Concatenate, ParamSpec, overload from ._routine import CompiledRoutine, Resource, ResourceType, Routine +from .compilation._common import _add_derived_resources from .compilation._evaluate import evaluate from .symbolics import sympy_backend from .symbolics.backend import SymbolicBackend, T, TExpr @@ -112,7 +113,6 @@ def add_derived_resources( """ if not derived_resources: return routine - from .compilation._compile import _add_derived_resources derived_resources = tuple(derived_resources) From ea3f1206550a8726e4f55a2f37fd67dff8f8f8a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konrad=20Ja=C5=82owiecki?= Date: Wed, 20 May 2026 17:28:47 +0200 Subject: [PATCH 06/14] chore: Get rid of deprecation warnings raised in tests --- tests/analysis/test_optimization.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/analysis/test_optimization.py b/tests/analysis/test_optimization.py index 34b693cf..80ccb25e 100644 --- a/tests/analysis/test_optimization.py +++ b/tests/analysis/test_optimization.py @@ -172,7 +172,7 @@ def test_minimize_gradient_descent( { "method": "L-BFGS-B", "tol": 1e-6, - "options": {"disp": False}, + "options": {"maxls": 20}, }, math.pi, -1.0, @@ -189,7 +189,7 @@ def test_minimize_gradient_descent( { "method": "Nelder-Mead", "tol": 1e-6, - "options": {"disp": False}, + "options": {"adaptive": False}, }, 0.0, 0.0, @@ -266,7 +266,7 @@ def test_minimize_df_active_volume_scipy(lamda_initial, lamda_bounds, expected_r scipy_kwargs = { "method": "L-BFGS-B", "tol": 1e-6, - "options": {"disp": False}, + "options": {"maxls": 30}, } result = minimize( From b4662727169a8faa2a97290cb90d399bf5d82e13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konrad=20Ja=C5=82owiecki?= Date: Wed, 20 May 2026 17:29:08 +0200 Subject: [PATCH 07/14] refactor: Rename _add_derived_resources to add_derived_resources --- src/bartiq/compilation/_common.py | 2 +- src/bartiq/compilation/_compile.py | 4 ++-- src/bartiq/transform.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/bartiq/compilation/_common.py b/src/bartiq/compilation/_common.py index 07d73c8e..132352c5 100644 --- a/src/bartiq/compilation/_common.py +++ b/src/bartiq/compilation/_common.py @@ -166,7 +166,7 @@ def __call__(self, routine: CompiledRoutine[T], backend: SymbolicBackend[T], res pass -def _add_derived_resources( +def add_derived_resources( routine: CompiledRoutine[T], backend: SymbolicBackend[T], derived_resources: Iterable[DerivedResources[T]] = (), diff --git a/src/bartiq/compilation/_compile.py b/src/bartiq/compilation/_compile.py index b65636b8..e1310960 100644 --- a/src/bartiq/compilation/_compile.py +++ b/src/bartiq/compilation/_compile.py @@ -43,7 +43,7 @@ ConstraintValidationError, Context, DerivedResources, - _add_derived_resources, + add_derived_resources, collect_children_variables, evaluate_constraints, evaluate_ports, @@ -411,7 +411,7 @@ def _compile( if CompilationFlags.EXPAND_RESOURCES in compilation_flags else _introduce_placeholder_child_resources(compiled_routine, backend) ) - tmp_routine = _add_derived_resources(tmp_routine, backend, derived_resources) + tmp_routine = add_derived_resources(tmp_routine, backend, derived_resources) return replace(compiled_routine, resources=tmp_routine.resources) diff --git a/src/bartiq/transform.py b/src/bartiq/transform.py index c834c853..9ff8d4dc 100644 --- a/src/bartiq/transform.py +++ b/src/bartiq/transform.py @@ -21,7 +21,7 @@ from typing import TYPE_CHECKING, Any, Callable, Concatenate, ParamSpec, overload from ._routine import CompiledRoutine, Resource, ResourceType, Routine -from .compilation._common import _add_derived_resources +from .compilation._common import add_derived_resources as _add_derived_resources from .compilation._evaluate import evaluate from .symbolics import sympy_backend from .symbolics.backend import SymbolicBackend, T, TExpr From b8b401577e62e0f1ec34bfa9789c5ea0e8e9ff6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konrad=20Ja=C5=82owiecki?= Date: Wed, 20 May 2026 17:43:18 +0200 Subject: [PATCH 08/14] feat: Add ability to compute derived_resources through evaluate --- src/bartiq/compilation/_evaluate.py | 39 +++++++++++++------- tests/compilation/test_evaluate.py | 56 +++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 12 deletions(-) diff --git a/src/bartiq/compilation/_evaluate.py b/src/bartiq/compilation/_evaluate.py index 223197de..7d27a338 100644 --- a/src/bartiq/compilation/_evaluate.py +++ b/src/bartiq/compilation/_evaluate.py @@ -22,6 +22,8 @@ from bartiq.compilation._common import ( ConstraintValidationError, Context, + DerivedResources, + add_derived_resources, collect_children_variables, evaluate_constraints, evaluate_ports, @@ -63,6 +65,7 @@ def evaluate( *, backend: SymbolicBackend[T] = sympy_backend, functions_map: FunctionsMap[T] | None = None, + derived_resources: DerivedResources[T] = (), ) -> EvaluationResult[T]: """Substitutes variables into compiled routine. @@ -83,7 +86,7 @@ def evaluate( assignment: backend.parse_constant(backend.as_expression(value)) for assignment, value in assignments.items() } evaluated_routine = _evaluate_internal( - compiled_routine, parsed_assignments, backend, functions_map, Context(compiled_routine.name) + compiled_routine, parsed_assignments, backend, functions_map, derived_resources, Context(compiled_routine.name) ) return EvaluationResult(routine=evaluated_routine, _backend=backend) @@ -93,6 +96,7 @@ def _evaluate_internal( inputs: dict[str, TExpr[T]], backend: SymbolicBackend[T], functions_map: FunctionsMap[T], + derived_resources: DerivedResources[T], context: Context, ) -> CompiledRoutine[T]: try: @@ -106,22 +110,33 @@ def _evaluate_internal( updated_children: dict[str, CompiledRoutine[T]] = { name: _evaluate_internal( - child, inputs, backend=backend, functions_map=functions_map, context=context.descend(name) + child, + inputs, + backend=backend, + functions_map=functions_map, + derived_resources=derived_resources, + context=context.descend(name), ) for name, child in compiled_routine.children.items() } children_variables: dict[str, TExpr] = collect_children_variables(updated_children) - return replace( - compiled_routine, - input_params=sorted(set(compiled_routine.input_params).difference(inputs)), - ports=evaluate_ports(compiled_routine.ports, inputs, backend, functions_map), - resources=evaluate_resources(compiled_routine.resources, inputs | children_variables, backend, functions_map), - constraints=new_constraints, - repetition=evaluate_repetition(compiled_routine.repetition, inputs, backend, functions_map), - children=updated_children, - first_pass_resources=evaluate_resources( - compiled_routine.first_pass_resources, inputs | children_variables, backend, functions_map + return add_derived_resources( + replace( + compiled_routine, + input_params=sorted(set(compiled_routine.input_params).difference(inputs)), + ports=evaluate_ports(compiled_routine.ports, inputs, backend, functions_map), + resources=evaluate_resources( + compiled_routine.resources, inputs | children_variables, backend, functions_map + ), + constraints=new_constraints, + repetition=evaluate_repetition(compiled_routine.repetition, inputs, backend, functions_map), + children=updated_children, + first_pass_resources=evaluate_resources( + compiled_routine.first_pass_resources, inputs | children_variables, backend, functions_map + ), ), + backend, + derived_resources, ) diff --git a/tests/compilation/test_evaluate.py b/tests/compilation/test_evaluate.py index de45408b..b7f1461b 100644 --- a/tests/compilation/test_evaluate.py +++ b/tests/compilation/test_evaluate.py @@ -203,3 +203,59 @@ def test_compile_and_evaluate_double_factorization_routine(backend): for resource_name in expected_resources: assert expected_resources[resource_name] == evaluated_routine.resources[resource_name].value + + +def test_add_derived_resources_to_compiled_routine(backend): + input_qref = { + "name": "root", + "type": None, + "input_params": ["n"], + "resources": [ + {"name": "a", "type": "additive", "value": "n"}, + {"name": "b", "type": "additive", "value": "2*n"}, + ], + } + routine = CompiledRoutine.from_qref(RoutineV1(**input_qref), backend) + + def _sum_resources(compiled_routine, symbolic_backend): + return symbolic_backend.as_expression(compiled_routine.resource_values["a"]) + symbolic_backend.as_expression( + compiled_routine.resource_values["b"] + ) + + result = evaluate( + routine, + {}, + derived_resources=[{"name": "c", "type": "additive", "calculate": _sum_resources}], + backend=backend, + ).routine + + assert result.resources["c"].value == backend.as_expression("3*n") + + +def test_add_derived_resources_is_applied_postorder(backend): + input_qref = { + "name": "parent", + "type": None, + "children": [ + { + "name": "child", + "type": None, + "resources": [{"name": "x", "type": "additive", "value": 2}], + } + ], + "resources": [{"name": "x", "type": "additive", "value": "M"}], + } + parent = CompiledRoutine.from_qref(RoutineV1(**input_qref), backend) + + def _double_x(compiled_routine, symbolic_backend): + return 2 * symbolic_backend.as_expression(compiled_routine.resource_values["x"]) + + result = evaluate( + parent, + {}, + derived_resources=[{"name": "double_x", "type": "additive", "calculate": _double_x}], + backend=backend, + ).routine + + assert result.children["child"].resources["double_x"].value == 4 + assert result.resources["double_x"].value == backend.as_expression("2*M") From 627211077506b853ad05cd34f3d00e68abc50835 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konrad=20Ja=C5=82owiecki?= Date: Wed, 20 May 2026 17:48:31 +0200 Subject: [PATCH 09/14] refactor: Remove add_derived_resources from transoform.py --- src/bartiq/__init__.py | 2 -- src/bartiq/transform.py | 38 +------------------------- tests/test_transform.py | 60 +---------------------------------------- 3 files changed, 2 insertions(+), 98 deletions(-) diff --git a/src/bartiq/__init__.py b/src/bartiq/__init__.py index a787590c..45a543dc 100644 --- a/src/bartiq/__init__.py +++ b/src/bartiq/__init__.py @@ -23,7 +23,6 @@ ) from .compilation import DerivedResources, compile_routine, evaluate from .symbolics import sympy_backend -from .transform import add_derived_resources __all__ = [ "Port", @@ -37,5 +36,4 @@ "compile_routine", "evaluate", "sympy_backend", - "add_derived_resources", ] diff --git a/src/bartiq/transform.py b/src/bartiq/transform.py index 9ff8d4dc..95f6dcd4 100644 --- a/src/bartiq/transform.py +++ b/src/bartiq/transform.py @@ -14,14 +14,12 @@ from __future__ import annotations import copy -from collections.abc import Iterable from dataclasses import replace from functools import wraps from graphlib import TopologicalSorter -from typing import TYPE_CHECKING, Any, Callable, Concatenate, ParamSpec, overload +from typing import Any, Callable, Concatenate, ParamSpec, overload from ._routine import CompiledRoutine, Resource, ResourceType, Routine -from .compilation._common import add_derived_resources as _add_derived_resources from .compilation._evaluate import evaluate from .symbolics import sympy_backend from .symbolics.backend import SymbolicBackend, T, TExpr @@ -29,9 +27,6 @@ P = ParamSpec("P") BACKEND = sympy_backend -if TYPE_CHECKING: - from .compilation._compile import DerivedResources - RoutineTransform = Callable[Concatenate[Routine[T], SymbolicBackend[T], P], Routine[T]] CompiledRoutineTransform = Callable[Concatenate[CompiledRoutine[T], SymbolicBackend[T], P], CompiledRoutine[T]] @@ -95,37 +90,6 @@ def _inner(routine: Routine[T], backend: SymbolicBackend[T], *args, **kwargs) -> AggregationDict = dict[str, dict[str, TExpr[T]]] -def add_derived_resources( - routine: CompiledRoutine[T], - derived_resources: Iterable["DerivedResources[T]"] | None = None, - backend: SymbolicBackend[T] = BACKEND, -) -> CompiledRoutine[T]: - """Add derived resources to an already compiled routine. - - Args: - routine: The compiled routine to which the resources should be added. - derived_resources: Resource specifications matching the ``derived_resources`` argument - accepted by ``compile_routine``. - backend: Backend instance to use for handling expressions. - - Returns: - The routine with derived resources added to each subroutine in postorder. - """ - if not derived_resources: - return routine - - derived_resources = tuple(derived_resources) - - @postorder_transform - def _apply( - subroutine: CompiledRoutine[T], - subroutine_backend: SymbolicBackend[T], - ) -> CompiledRoutine[T]: - return _add_derived_resources(subroutine, subroutine_backend, derived_resources) - - return _apply(routine, backend) - - def add_aggregated_resources( routine: CompiledRoutine[T], aggregation_dict: AggregationDict[T], diff --git a/tests/test_transform.py b/tests/test_transform.py index 34a97bc2..c5267142 100644 --- a/tests/test_transform.py +++ b/tests/test_transform.py @@ -17,11 +17,7 @@ from qref.schema_v1 import RoutineV1 from bartiq import CompiledRoutine, Resource, ResourceType, Routine -from bartiq.transform import ( - add_aggregated_resources, - add_circuit_volume, - add_derived_resources, -) +from bartiq.transform import add_aggregated_resources, add_circuit_volume ccry_gate = { "name": "ccry_gate", @@ -305,57 +301,3 @@ def test_add_circuit_volume_with_children(backend): ) assert "circuit_volume" in out2.resources assert out2.resources["circuit_volume"].value == 14 - - -def test_add_derived_resources_to_compiled_routine(backend): - input_qref = { - "name": "root", - "type": None, - "input_params": ["n"], - "resources": [ - {"name": "a", "type": "additive", "value": "n"}, - {"name": "b", "type": "additive", "value": "2*n"}, - ], - } - routine = CompiledRoutine.from_qref(RoutineV1(**input_qref), backend) - - def _sum_resources(compiled_routine, symbolic_backend): - return symbolic_backend.as_expression(compiled_routine.resource_values["a"]) + symbolic_backend.as_expression( - compiled_routine.resource_values["b"] - ) - - result = add_derived_resources( - routine, - [{"name": "c", "type": "additive", "calculate": _sum_resources}], - backend=backend, - ) - - assert str(result.resources["c"].value) == "3*n" - - -def test_add_derived_resources_is_applied_postorder(backend): - input_qref = { - "name": "parent", - "type": None, - "children": [ - { - "name": "child", - "type": None, - "resources": [{"name": "x", "type": "additive", "value": 2}], - } - ], - "resources": [{"name": "x", "type": "additive", "value": "child.x"}], - } - parent = CompiledRoutine.from_qref(RoutineV1(**input_qref), backend) - - def _double_x(compiled_routine, symbolic_backend): - return 2 * symbolic_backend.as_expression(compiled_routine.resource_values["x"]) - - result = add_derived_resources( - parent, - [{"name": "double_x", "type": "additive", "calculate": _double_x}], - backend=backend, - ) - - assert result.children["child"].resources["double_x"].value == 4 - assert str(result.resources["double_x"].value) == "2*child.x" From 750b6bf52808f93d63f7488378accec7bd35d5a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konrad=20Ja=C5=82owiecki?= Date: Wed, 20 May 2026 17:54:28 +0200 Subject: [PATCH 10/14] fix: Typo DerivedResources -> DerivedResource --- src/bartiq/compilation/_common.py | 4 ++-- src/bartiq/compilation/_compile.py | 6 +++--- src/bartiq/compilation/_evaluate.py | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/bartiq/compilation/_common.py b/src/bartiq/compilation/_common.py index 132352c5..4d911e9c 100644 --- a/src/bartiq/compilation/_common.py +++ b/src/bartiq/compilation/_common.py @@ -49,7 +49,7 @@ def __init__(self, original_constraint: Constraint[T], compiled_constraint: Cons super().__init__(original_constraint, compiled_constraint) -class DerivedResources(TypedDict, Generic[T]): +class DerivedResource(TypedDict, Generic[T]): """Contains information needed to calculate derived resources.""" name: str @@ -169,7 +169,7 @@ def __call__(self, routine: CompiledRoutine[T], backend: SymbolicBackend[T], res def add_derived_resources( routine: CompiledRoutine[T], backend: SymbolicBackend[T], - derived_resources: Iterable[DerivedResources[T]] = (), + derived_resources: Iterable[DerivedResource[T]] = (), ) -> CompiledRoutine[T]: for specs in derived_resources: name = specs["name"] diff --git a/src/bartiq/compilation/_compile.py b/src/bartiq/compilation/_compile.py index e1310960..b55006ff 100644 --- a/src/bartiq/compilation/_compile.py +++ b/src/bartiq/compilation/_compile.py @@ -42,7 +42,7 @@ from bartiq.compilation._common import ( ConstraintValidationError, Context, - DerivedResources, + DerivedResource, add_derived_resources, collect_children_variables, evaluate_constraints, @@ -117,7 +117,7 @@ def compile_routine( backend: SymbolicBackend[T] = sympy_backend, preprocessing_stages: Iterable[PreprocessingStage[T]] = DEFAULT_PREPROCESSING_STAGES, postprocessing_stages: Iterable[PostprocessingStage[T]] = DEFAULT_POSTPROCESSING_STAGES, - derived_resources: Iterable[DerivedResources] = (), + derived_resources: Iterable[DerivedResource] = (), compilation_flags: CompilationFlags | None = None, ) -> CompilationResult[T]: """Performs symbolic compilation of a given routine. @@ -309,7 +309,7 @@ def _compile( backend: SymbolicBackend[T], inputs: dict[str, TExpr[T]], context: Context, - derived_resources: Iterable[DerivedResources] = (), + derived_resources: Iterable[DerivedResource] = (), compilation_flags: CompilationFlags = CompilationFlags(0), # CompilationsFlags(0) corresponds to no flags ) -> CompiledRoutine[T]: try: diff --git a/src/bartiq/compilation/_evaluate.py b/src/bartiq/compilation/_evaluate.py index 7d27a338..2c5f156e 100644 --- a/src/bartiq/compilation/_evaluate.py +++ b/src/bartiq/compilation/_evaluate.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -from collections.abc import Mapping +from collections.abc import Iterable, Mapping from dataclasses import dataclass, replace from typing import Callable, Generic, TypeVar @@ -22,7 +22,7 @@ from bartiq.compilation._common import ( ConstraintValidationError, Context, - DerivedResources, + DerivedResource, add_derived_resources, collect_children_variables, evaluate_constraints, @@ -65,7 +65,7 @@ def evaluate( *, backend: SymbolicBackend[T] = sympy_backend, functions_map: FunctionsMap[T] | None = None, - derived_resources: DerivedResources[T] = (), + derived_resources: Iterable[DerivedResource[T]] = (), ) -> EvaluationResult[T]: """Substitutes variables into compiled routine. @@ -96,7 +96,7 @@ def _evaluate_internal( inputs: dict[str, TExpr[T]], backend: SymbolicBackend[T], functions_map: FunctionsMap[T], - derived_resources: DerivedResources[T], + derived_resources: Iterable[DerivedResource[T]], context: Context, ) -> CompiledRoutine[T]: try: From 024eccd361e848275933b9aeec3d879c94709596 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konrad=20Ja=C5=82owiecki?= Date: Wed, 20 May 2026 17:58:17 +0200 Subject: [PATCH 11/14] fix: Fix incomplete rename --- src/bartiq/__init__.py | 4 ++-- src/bartiq/compilation/__init__.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/bartiq/__init__.py b/src/bartiq/__init__.py index 45a543dc..8210c73e 100644 --- a/src/bartiq/__init__.py +++ b/src/bartiq/__init__.py @@ -21,7 +21,7 @@ Routine, routine_to_qref, ) -from .compilation import DerivedResources, compile_routine, evaluate +from .compilation import DerivedResource, compile_routine, evaluate from .symbolics import sympy_backend __all__ = [ @@ -32,7 +32,7 @@ "Resource", "CompiledRoutine", "routine_to_qref", - "DerivedResources", + "DerivedResource", "compile_routine", "evaluate", "sympy_backend", diff --git a/src/bartiq/compilation/__init__.py b/src/bartiq/compilation/__init__.py index c54875be..1698ab56 100644 --- a/src/bartiq/compilation/__init__.py +++ b/src/bartiq/compilation/__init__.py @@ -13,14 +13,14 @@ # limitations under the License. """The compilation submodule contains routine compilation functionality.""" -from ._common import DerivedResources +from ._common import DerivedResource from ._compile import CompilationFlags, CompilationResult, compile_routine from ._evaluate import EvaluationResult, evaluate __all__ = [ "compile_routine", "CompilationResult", - "DerivedResources", + "DerivedResource", "evaluate", "EvaluationResult", "CompilationFlags", From 1b9245fa7a93fbc21dc2ea04faf2e8c59e33f922 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konrad=20Ja=C5=82owiecki?= Date: Wed, 20 May 2026 18:05:30 +0200 Subject: [PATCH 12/14] chore: Undo AI-introduced import changes --- src/bartiq/transform.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/bartiq/transform.py b/src/bartiq/transform.py index 95f6dcd4..29938d20 100644 --- a/src/bartiq/transform.py +++ b/src/bartiq/transform.py @@ -19,10 +19,10 @@ from graphlib import TopologicalSorter from typing import Any, Callable, Concatenate, ParamSpec, overload -from ._routine import CompiledRoutine, Resource, ResourceType, Routine -from .compilation._evaluate import evaluate -from .symbolics import sympy_backend -from .symbolics.backend import SymbolicBackend, T, TExpr +from bartiq import CompiledRoutine, Resource, ResourceType, Routine +from bartiq.compilation._evaluate import evaluate +from bartiq.symbolics import sympy_backend +from bartiq.symbolics.backend import SymbolicBackend, T, TExpr P = ParamSpec("P") BACKEND = sympy_backend From ea8451c47068ac9c4ec2e051d67e366f9176f30f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konrad=20Ja=C5=82owiecki?= Date: Wed, 20 May 2026 18:18:26 +0200 Subject: [PATCH 13/14] test: Refactor AI-generated tests --- tests/compilation/test_evaluate.py | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/tests/compilation/test_evaluate.py b/tests/compilation/test_evaluate.py index b7f1461b..ea0fef50 100644 --- a/tests/compilation/test_evaluate.py +++ b/tests/compilation/test_evaluate.py @@ -205,7 +205,7 @@ def test_compile_and_evaluate_double_factorization_routine(backend): assert expected_resources[resource_name] == evaluated_routine.resources[resource_name].value -def test_add_derived_resources_to_compiled_routine(backend): +def test_derived_resources_can_be_added_during_evaluation(backend): input_qref = { "name": "root", "type": None, @@ -218,9 +218,7 @@ def test_add_derived_resources_to_compiled_routine(backend): routine = CompiledRoutine.from_qref(RoutineV1(**input_qref), backend) def _sum_resources(compiled_routine, symbolic_backend): - return symbolic_backend.as_expression(compiled_routine.resource_values["a"]) + symbolic_backend.as_expression( - compiled_routine.resource_values["b"] - ) + return compiled_routine.resource_values["a"] + compiled_routine.resource_values["b"] result = evaluate( routine, @@ -232,23 +230,18 @@ def _sum_resources(compiled_routine, symbolic_backend): assert result.resources["c"].value == backend.as_expression("3*n") -def test_add_derived_resources_is_applied_postorder(backend): +def test_derived_resources_are_applied_in_postorder_fashion(backend): input_qref = { "name": "parent", "type": None, - "children": [ - { - "name": "child", - "type": None, - "resources": [{"name": "x", "type": "additive", "value": 2}], - } - ], + "children": [{"name": "child", "type": None, "resources": []}], "resources": [{"name": "x", "type": "additive", "value": "M"}], } parent = CompiledRoutine.from_qref(RoutineV1(**input_qref), backend) def _double_x(compiled_routine, symbolic_backend): - return 2 * symbolic_backend.as_expression(compiled_routine.resource_values["x"]) + our_x = compiled_routine.resource_values.get("x", 3) + return 2 * our_x + sum(child.resource_values["double_x"] for child in compiled_routine.children.values()) result = evaluate( parent, @@ -257,5 +250,5 @@ def _double_x(compiled_routine, symbolic_backend): backend=backend, ).routine - assert result.children["child"].resources["double_x"].value == 4 - assert result.resources["double_x"].value == backend.as_expression("2*M") + assert result.children["child"].resources["double_x"].value == 6 + assert result.resources["double_x"].value == backend.as_expression("2*M + 6") From 073ac31d7e792f1d01ed385cfd90a4aa3eaa8040 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konrad=20Ja=C5=82owiecki?= Date: Wed, 20 May 2026 18:29:15 +0200 Subject: [PATCH 14/14] chore: Add missing parameter in evaluate docstring --- src/bartiq/compilation/_evaluate.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/bartiq/compilation/_evaluate.py b/src/bartiq/compilation/_evaluate.py index 2c5f156e..d7cc1926 100644 --- a/src/bartiq/compilation/_evaluate.py +++ b/src/bartiq/compilation/_evaluate.py @@ -76,6 +76,9 @@ def evaluate( expressions understood by backend, or via strings, e.g. `{"N": 2, "M": "k+3"}. backend: a backend used for manipulating symbolic expressions. functions_map: a dictionary mapping function names to their concrete implementations. + derived_resources: iterable with dictionaries describing how to calculate derived resources. + Each dictionary should contain the derived resource's name, type + and the function mapping a routine to the value of resource. Returns: A new instance of CompiledRoutine with appropriate substitutions made.