Transformations API Reference
Core runtime
PassManager
Manage and execute a sequence of passes on a model.
The PassManager implements a compiler-style pass pattern, enabling both general-purpose and algorithm-specific manipulations of optimization models. Each pass is an atomic operation that transforms the model or extracts information from the model. The PassManager runs each pass in order and produces an IR that records the transformations applied and supports back-transformations.
Parameters:
-
passes(Sequence[BasePass], default:None) –An ordered sequence of Pass instances to apply, default None.
add(pass_: Pass) -> None
Append a pass to the configured passes.
Parameters:
-
pass_(TransformationPass | AnalysisPass | ControlFlowPass) –The pass to add to this PassManager's configured passes.
run(model: Model) -> TransformationOutput
Apply all configured passes.
Apply all configured passes to the given model and return the resulting intermediate representation.
Parameters:
-
model(Model) –The model to be transformed.
Returns:
-
TransformationOutput–The transformation ouput after transformation.
__str__() -> str
Human readable string.
__repr__() -> str
Debug string.
TransformationOutput
The result of the PassManager's run method.
It contains the transformed model, the TransformationRecord and the final PassContext.
model: Model
property
record: TransformationRecord
property
Get the transformation record produced during the PassManager execution.
Returns:
-
TransformationRecord–The transformation record after execution of the PassManager.
context: PassContext
property
Get the final context produced during the PassManager execution.
Returns:
-
PassContext–The final context after execution of the PassManager.
PassContext
Bases: PyPassContext
The pass context provides access to the analysis results in Transformation and analysis passes.
require_analysis(key: AnalysisKey[T], *, default: T | None = None) -> T
Get the analysis entry for the specified key.
Parameters:
-
key(AnalysisKey[T]) –The cache key to retrieve.
-
default(T, default:None) –Value to return when no result for
keyis found. If not provided, and thekeyis not found, an error is raised.
Returns:
-
T–The cached value associated with the key.
Pipeline
Bases: PyPipeline
A pipeline for executing multiple transformation passes in sequence.
Pipelines organize and execute multiple passes, managing dependencies and ensuring they run in the correct order.
__new__(steps: Sequence[Pass | Self], name: str) -> Self
name() -> str
Get the name of this pipeline.
add(new_pass: Pass | Self) -> None
Add a new pass to the pipeline.
Parameters:
-
new_pass(Pass | Self) –The pass to add to the pipeline.
requires() -> list[str]
invalidates() -> list[str]
provides() -> list[str]
clear() -> None
Clear all passes from the pipeline.
Removes all transformation passes, leaving an empty pipeline.
passes() -> list[Pass | Self]
__str__() -> str
Human readable string.
__repr__() -> str
Debug representation string.
Record and entries
TransformationRecord
The transformation record contains all information required to back transform a solution.
entries: list[PassEntry]
property
backward(solution: Solution) -> Solution
Apply the back transformation to the given solution.
Disclaimer
When multiple samples are condensed into a single record (e.g., by omitting
slack variables), only the first sample's raw_energy is retained. As a
result, the raw_energy value may no longer accurately represent the
condensed group.
Parameters:
-
solution(Solution) –The solution to transform back to a representation fitting the original model.
Returns:
-
Solution–A solution object representing a solution to the original problem.
encode() -> bytes
serialize() -> bytes
decode(data: bytes) -> TransformationRecord
classmethod
Decode a transformation record from bytes.
Parameters:
-
data(bytes) –Encoded transformation record data.
Returns:
-
TransformationRecord–Decoded transformation record.
deserialize(data: bytes) -> TransformationRecord
classmethod
Deserialize a transformation record from bytes.
This is an alias for :meth:decode.
Parameters:
-
data(bytes) –Serialized transformation record data.
Returns:
-
TransformationRecord–Deserialized transformation record.
find(query: str, *, exact: bool = False) -> PassEntry
Find the first pass entry whose name/id matches the query.
Searches this record and nested pipeline/control-flow records in forward order.
Parameters:
-
query(str) –Full pass name/id or partial fragment.
-
exact(bool, default:False) –If True, require exact equality. Otherwise use case-insensitive substring matching. Defaults to False.
Returns:
-
PassEntry–The first matching pass entry.
Raises:
-
ValueError–If query is empty.
-
LookupError–If no matching entry is found.
PassEntry
TransformEntry
Bases: Generic[A]
Transform entry containing pass identity and serialized artifact.
pass_id: str
property
Unique pass identifier used by backward dispatch.
pass_name: str
property
Human-readable pass name.
artifact: A
property
Artifact produced by the transform pass.
__str__() -> str
Human readable string.
AnalysisEntry
Analysis entry representing a non-reversible analysis execution.
pass_name: str
property
Human-readable analysis pass name.
__str__() -> str
Human readable string.
CompositeEntry
Bases: Generic[A]
Composite entry containing pass identity and serialized artifact.
pass_id: str
property
Unique pass identifier used by backward dispatch.
pass_name: str
property
Human-readable pass name.
artifact: A
property
Artifact produced by the transform pass.
__str__() -> str
Human readable string.
PipelineEntry
Nested pipeline entry containing a sub-record.
name: str
property
Nested pipeline name.
record: TransformationRecord
property
Nested transformation record for this pipeline step.
__str__() -> str
Human readable string.
ControlFlowEntry
Control-flow entry containing the selected branch record.
pass_name: str
property
Name of the control-flow pass that selected the branch.
name: str
property
Name of the selected control-flow branch plan.
record: TransformationRecord
property
Nested transformation record executed for the selected branch.
__str__() -> str
Human readable string.
Pass base classes
TransformationPass
Bases: PyTransformationPass, Generic[Artifact]
Abstract base class for transformation passes that modify models.
Transformation passes apply changes to models and can also convert solutions backwards to match the input representation.
Notes
This is an abstract class. Subclasses must implement the name, forward methods
and the backward function. Additionally, the requires and invalidates methods
can be implemented.
name() -> str
abstractmethod
forward(model: Model, ctx: PassContext) -> tuple[Model, Artifact]
abstractmethod
Run/Execute this transformation pass.
Parameters:
-
model(Model) –The model to transform.
-
ctx(PassContext) –Context for this pass providing read-access to the analysis cache.
Returns:
backward(artifact: Artifact, solution: Solution) -> Solution
abstractmethod
classmethod
Apply the back transformation to the given solution.
Parameters:
-
artifact(Artifact) –The artifact produced by the forward execution.
-
solution(Solution) –The solution to transform back to a representation fitting the original (input) model transformed by the forward method.
Returns:
-
Solution–A solution object representing a solution to the original problem passed to this TransformationPass' forward method.
requires() -> list[str]
invalidates() -> list[str]
Get a list of passes that are invalidated by this pass.
Returns:
-
list of str–Names of passes whose results become invalid after this pass runs.
AnalysisPass
Bases: PyAnalysisPass, Generic[Result]
Abstract base class for analysis passes that analyse models.
Analysis passes retrieve information from models can used by transformation passes.
Notes
This is an abstract class. Subclasses must implement the name and run methods and
the PROVIDES class variable.
Additionally, the requires method can be implemented to indicate which passes must
be executed before the analysis is run.
name() -> str
abstractmethod
run(model: Model, ctx: PassContext) -> Result
abstractmethod
Run/Execute this analysis pass.
Parameters:
-
model(Model) –The model to analyse.
-
ctx(PassContext) –Context for this pass providing read-access to the analysis cache.
Returns:
-
Result–The analysis result.
requires() -> list[str]
provides() -> str
classmethod
Get the identifier for the analysis cache elment this pass generates.
Returns:
-
str–The identifier of the cache elment
key() -> AnalysisKey[Result]
classmethod
Get the analysis key used to access the analysis result from the PassContext.
ControlFlowPass
Bases: PyControlFlowPass
Abstract base class for control-flow passes.
Control-Flow passes guide the transformation at runtime. Execution of a
ControlFlowPass return a ControlFlowPlan that consist of transformation
and analysis (or more control-flow passes) to be executed.
Notes
This is an abstract class. Subclasses must implement the name, run methods.
Additionally, the requires and invalidates and provides methods can be implemented.
name() -> str
abstractmethod
run(model: Model, ctx: PassContext) -> ControlFlowPlan
abstractmethod
Run/Execute this transformation pass.
Parameters:
-
model(Model) –The model to transform.
-
ctx(PassContext) –Context for this pass providing read-access to the analysis cache.
Returns:
requires() -> list[str]
invalidates() -> list[str]
Get a list of passes that are invalidated by this control-flow's plan.
Returns:
-
list of str–Names of passes whose results become invalid after this pass runs.
provides() -> list[str]
Get the identifier for the analysis cache elments this control-flow's plan generates.
Returns:
-
str–The identifiers of the cache elements
CompositePass
Bases: PyCompositePass, Generic[Artifact, Result]
Abstract base class for composite passes that modify and analyze models.
Composite passes apply changes to models analyze them and can also convert solutions backwards to match the input representation.
Notes
This is an abstract class. Subclasses must implement the name, forward methods,
the backward function and the PROVIDES class variable.
Additionally, the requires and invalidates methods can be implemented.
name() -> str
abstractmethod
forward(model: Model, ctx: PassContext) -> tuple[Model, Artifact, Result]
abstractmethod
Run/Execute this composite pass.
Parameters:
-
model(Model) –The model to transform.
-
ctx(PassContext) –Context for this pass providing read-access to the analysis cache.
Returns:
backward(artifact: Artifact, solution: Solution) -> Solution
abstractmethod
classmethod
Apply the back transformation to the given solution.
Parameters:
-
artifact(Artifact) –The artifact produced by the forward execution.
-
solution(Solution) –The solution to transform back to a representation fitting the original (input) model transformed by the forward method.
Returns:
-
Solution–A solution object representing a solution to the original problem passed to this CompositePass' forward method.
requires() -> list[str]
invalidates() -> list[str]
Get a list of passes that are invalidated by this pass.
Returns:
-
list of str–Names of passes whose results become invalid after this pass runs.
provides() -> str
classmethod
Get the identifier for the analysis cache elment this pass generates.
Returns:
-
str–The identifier of the cache elment
key() -> AnalysisKey[Result]
classmethod
Get the analysis key used to access the analysis result from the PassContext.
ControlFlowPlan
Execution plan produced by a control-flow pass.
A ControlFlowPlan describes which sub-pipeline should be executed next
based on a runtime decision (for example, an if/else condition). It is the
output of a control-flow pass and contains a plan name plus an ordered list
of passes/steps to run.
This object does not execute anything itself. Instead, the pass manager consumes it and runs the selected steps, then records the nested execution in the transformation record so backward replay remains deterministic after serialization/deserialization.
Parameters:
-
name(str) –Human-readable identifier for the selected branch/plan.
-
steps(Sequence[Pass]) –Ordered steps that should be executed for this plan.
Notes
The plan should be deterministic for a given model/context state, and should only include steps that are valid within the current pipeline scope.
Decorators
transform
Create a TransformationPass from a function decorator.
This decorator converts a regular function into a TransformationPass that modifies
models in transformation pipelines. Transformation passes can restructure models,
add/remove constraints, change variable types, or perform other model modifications.
Disclaimer
Dynamic artifact/backward resolution is restricted to an import allowlist.
By default, only modules under luna_model. are allowed.
Use register_allowed_import_prefix(...) to allow custom plugin namespaces.
Parameters:
-
name(str, default:None) –The name of the transformation pass. If not provided, uses the function name with underscores replaced by hyphens.
-
requires(list[str], default:None) –List of pass names that must run before this transformation. Defaults to
[]. -
invalidates(list[str], default:None) –List of analysis pass names whose results become invalid after this transformation. Defaults to
[]. -
backward(Callable[[A, Solution], Solution], default:None) –Optional function to map solutions from the transformed model back to the original model's variable space. If not provided, solutions pass through unchanged.
Returns:
-
Callable[[TransformationSignature], _DynamicTransformationPass[A]]–A decorator that transforms the decorated function into a
TransformationPass. The genericAis the artifact produced by this transformation pass.
Examples:
Create a simple transformation:
>>> from luna_model.transformation import transform
>>> @transform(name="scale-objective")
... def scale_obj(model: Model, ctx: PassContext) -> tuple[Model, NothingArtifact]:
... model.objective = model.objective * 2.0
... return model, NothingArtifact()
Notes
Dynamic artifact/backward resolution is restricted to an import allowlist.
By default, only modules under luna_model. are allowed.
Use register_allowed_import_prefix(...) to allow custom plugin namespaces.
The decorated function must return:
(Model, Artifact)tuple
The backwards function is crucial when transformations change the variable space (e.g., adding/removing variables, changing variable types). It ensures solutions from downstream solvers can be correctly interpreted in the original model's context.
analyze
Create an AnalysisPass from a function decorator.
This decorator converts a regular function into an AnalysisPass that can be used
in transformation pipelines. Analysis passes inspect models without modifying them,
computing properties or metadata that other passes can use.
Parameters:
-
name(str, default:None) –The name of the analysis pass. If not provided, uses the function name with underscores replaced by hyphens (e.g.,
my_analysisbecomesmy-analysis). -
provides(str, default:None) –The key for the result the analysis pass provides. If not specified, uses the function name with underscores replaced by hyphens prefixed with
decorated_analysis::(e.g.,my_analysisbecomesdecorated_analysis::my-analysis). -
requires(list[str], default:None) –List of analysis pass names that must run before this analysis. The results of required passes are available in the
AnalysisCache. Defaults to[].
Returns:
-
Callable[[Callable[[Model, PassContext], R]], _DynamicAnalysisPass[R]]–A decorator that transforms the decorated function into an
AnalysisPass.
Examples:
Create a simple analysis pass:
>>> from luna_model.transformation import analyze
>>> @analyze(name="count-variables")
... def count_vars(model, cache) -> float:
... return model.num_variables
Notes
The decorated function must have the signature::
def my_analysis(model: Model, ctx: PassContext) -> R: ...
The return value is stored in the AnalysisCache under the pass's name
and can be accessed by subsequent passes.
control_flow
ControlFlowPlan
Execution plan produced by a control-flow pass.
A ControlFlowPlan describes which sub-pipeline should be executed next
based on a runtime decision (for example, an if/else condition). It is the
output of a control-flow pass and contains a plan name plus an ordered list
of passes/steps to run.
This object does not execute anything itself. Instead, the pass manager consumes it and runs the selected steps, then records the nested execution in the transformation record so backward replay remains deterministic after serialization/deserialization.
Parameters:
-
name(str) –Human-readable identifier for the selected branch/plan.
-
steps(Sequence[Pass]) –Ordered steps that should be executed for this plan.
Notes
The plan should be deterministic for a given model/context state, and should only include steps that are valid within the current pipeline scope.
ControlFlowPass
Bases: PyControlFlowPass
Abstract base class for control-flow passes.
Control-Flow passes guide the transformation at runtime. Execution of a
ControlFlowPass return a ControlFlowPlan that consist of transformation
and analysis (or more control-flow passes) to be executed.
Notes
This is an abstract class. Subclasses must implement the name, run methods.
Additionally, the requires and invalidates and provides methods can be implemented.
name() -> str
abstractmethod
run(model: Model, ctx: PassContext) -> ControlFlowPlan
abstractmethod
Run/Execute this transformation pass.
Parameters:
-
model(Model) –The model to transform.
-
ctx(PassContext) –Context for this pass providing read-access to the analysis cache.
Returns:
requires() -> list[str]
invalidates() -> list[str]
Get a list of passes that are invalidated by this control-flow's plan.
Returns:
-
list of str–Names of passes whose results become invalid after this pass runs.
provides() -> list[str]
Get the identifier for the analysis cache elments this control-flow's plan generates.
Returns:
-
str–The identifiers of the cache elements
composite
CompositePass
Bases: PyCompositePass, Generic[Artifact, Result]
Abstract base class for composite passes that modify and analyze models.
Composite passes apply changes to models analyze them and can also convert solutions backwards to match the input representation.
Notes
This is an abstract class. Subclasses must implement the name, forward methods,
the backward function and the PROVIDES class variable.
Additionally, the requires and invalidates methods can be implemented.
name() -> str
abstractmethod
forward(model: Model, ctx: PassContext) -> tuple[Model, Artifact, Result]
abstractmethod
Run/Execute this composite pass.
Parameters:
-
model(Model) –The model to transform.
-
ctx(PassContext) –Context for this pass providing read-access to the analysis cache.
Returns:
backward(artifact: Artifact, solution: Solution) -> Solution
abstractmethod
classmethod
Apply the back transformation to the given solution.
Parameters:
-
artifact(Artifact) –The artifact produced by the forward execution.
-
solution(Solution) –The solution to transform back to a representation fitting the original (input) model transformed by the forward method.
Returns:
-
Solution–A solution object representing a solution to the original problem passed to this CompositePass' forward method.
requires() -> list[str]
invalidates() -> list[str]
Get a list of passes that are invalidated by this pass.
Returns:
-
list of str–Names of passes whose results become invalid after this pass runs.
provides() -> str
classmethod
Get the identifier for the analysis cache elment this pass generates.
Returns:
-
str–The identifier of the cache elment
key() -> AnalysisKey[Result]
classmethod
Get the analysis key used to access the analysis result from the PassContext.
register_allowed_import_prefix
Allow dynamic import resolution for modules under a given prefix.
Parameters:
-
prefix(str) –Allowed module prefix, e.g.
"my_package.transforms.".
allowed_import_prefixes
Built-in pipelines
ToUnconstrainedBinaryPipeline
Bases: PyToUnconstrainedBinaryPipeline
Convert a model to an unconstrained binary model.
This pipeline transforms any model with constraints to an unconstrained binary model.
It allows the input model to contain binary, spin or integer variables. Spin and integer
variables are automatically converted to a binary representation. If the input model has
linear constraints they are added to the model's objective as quadratic penalties scaled by
the the maximum bias of the input model's objective times the penalty_scaling paramter.
Notes
If the model's constraints are not linear, an error is raised.
Known Limitations
If the constraints contain real-valued coefficients, the optimal solution may not be reached, as the transformation pipeline only creates integer-valued slack variables, not real-valued slack variables.
Paramters
penalty_scaling : float The factor used to scale the quadratic penalties with, by default 10.
Raises:
-
AnalysisPassError–If the model's constraints are not all linear.
Example
from luna_model import Model, Vtype from luna_model.transformation import PassManager, pipelines model = Model() x = model.add_variable("x", vtype=Vtype.BINARY) y = model.add_variable("y", vtype=Vtype.SPIN) z = model.add_variable("z", vtype=Vtype.INTEGER, lower=0, upper=12) model.objective = x + y + z model.constraints += x + y + z <= 3, "c0" model.constraints += x - y - z >= 0, "c1" model.constraints += x + y == 2, "c2" pm = PassManager([pipelines.ToUnconstrainedBinaryPipeline()]) ir = pm.run(model)
__new__(penalty_scaling: float = 10.0) -> Self
__str__() -> str
Human readable string.
ToBinaryMinimizationPipeline
Bases: PyToBinaryMinimizationPipeline
Convert a model to an binary model and minimize.
This pipeline transforms any model with integers and spins to an binary model.
Raises:
-
AnalysisPassError–If the model has real valued variables.
Example
from luna_model import Model, Vtype from luna_model.transformation import PassManager, pipelines model = Model() x = model.add_variable("x", vtype=Vtype.BINARY) y = model.add_variable("y", vtype=Vtype.SPIN) z = model.add_variable("z", vtype=Vtype.INTEGER, lower=0, upper=12) model.objective = x + y + z pm = PassManager([pipelines.ToBinaryMinimizationPipeline()]) ir = pm.run(model)
__new__() -> Self
__str__() -> str
Human readable string.
Built-in passes
BinarySpinPass
Bases: PyBinarySpinPass, BuiltinTransformation[BinarySpinPassArtifact]
Convert between Binary and Spin variable types.
Transform the variables of type binary to spin typed variables or vice versa.
Target vtype is set by the vtype parameter.
Parameters:
-
vtype(Literal[BINARY, SPIN]) –The target vtype to convert the variables to. If set to
Vtype.SPINall binary variables in the model are converted to spin variables. If set toVtype.BINARYall spin variables are converted to binary variables. -
prefix(str, default:None) –An optional prefix to prepend to the name of the new variables created. If none specified a default prefix is used.
Examples:
>>> from luna_model import Model, Vtype
>>> from luna_model.transformation import PassManager
>>> from luna_model.transformation.passes import BinarySpinPass
>>> model = Model()
>>> x = model.add_variable("x", vtype=Vtype.BINARY)
>>> y = model.add_variable("y", vtype=Vtype.BINARY)
>>> model.objective = x * y + x - 2 * y
>>> pm = PassManager([BinarySpinPass(vtype=Vtype.SPIN)])
>>> output = pm.run(model)
>>> spin_model = output.model
vtype: Vtype
property
Get the target variable type to convert to.
prefix: str | None
property
Get the optional naming prefix.
name() -> str
forward(model: Model, ctx: PassContext) -> tuple[Model, Artifact]
Run/Execute this transformation pass.
Parameters:
-
model(Model) –The model to transform.
-
ctx(PassContext) –Context for this pass providing read-access to the analysis cache.
Returns:
backward(artifact: Artifact, solution: Solution) -> Solution
classmethod
Apply the back transformation to the given solution.
Parameters:
-
artifact(Artifact) –The artifact produced by the forward execution.
-
solution(Solution) –The solution to transform back to a representation fitting the original (input) model transformed by the forward method.
Returns:
-
Solution–A solution object representing a solution to the original problem passed to this TransformationPass' forward method.
requires() -> list[str]
invalidates() -> list[str]
Get a list of passes that are invalidated by this pass.
Returns:
-
list of str–Names of passes whose results become invalid after this pass runs.
__str__() -> str
Human readable string.
__new__(vtype: Literal[Vtype.BINARY, Vtype.SPIN], prefix: str | None = None) -> Self
Create a new binary spin pass instance.
Parameters:
-
vtype(Literal[BINARY, SPIN]) –The target vtype to convert the variables to. If set to
Vtype.SPINall binary variables in the model are converted to spin variables. If set toVtype.BINARYall spin variables are converted to binary variables. -
prefix(str, default:None) –An optional prefix to prepend to the name of the new variables created. If none specified a default prefix is used.
ChangeSensePass
Bases: PyChangeSensePass, BuiltinTransformation[ChangeSensePassArtifact]
Change the optimization sense between minimization and maximization.
Converts the optimization sense by negating the objective function.
Parameters:
-
sense(Sense) –The target sense to convert the optimization sense to.
Examples:
>>> from luna_model import Model, Vtype, Sense
>>> from luna_model.transformation import PassManager
>>> from luna_model.transformation.passes import ChangeSensePass
>>> model = Model(sense=Sense.MAX)
>>> x = model.add_variable("x", vtype=Vtype.BINARY)
>>> y = model.add_variable("y", vtype=Vtype.BINARY)
>>> model.objective = x * y + x - 2 * y
>>> pm = PassManager([ChangeSensePass(Sense.MIN)])
>>> output = pm.run(model)
>>> min_model = output.model
sense: Sense
property
Get the target optimization sense.
name() -> str
forward(model: Model, ctx: PassContext) -> tuple[Model, Artifact]
Run/Execute this transformation pass.
Parameters:
-
model(Model) –The model to transform.
-
ctx(PassContext) –Context for this pass providing read-access to the analysis cache.
Returns:
backward(artifact: Artifact, solution: Solution) -> Solution
classmethod
Apply the back transformation to the given solution.
Parameters:
-
artifact(Artifact) –The artifact produced by the forward execution.
-
solution(Solution) –The solution to transform back to a representation fitting the original (input) model transformed by the forward method.
Returns:
-
Solution–A solution object representing a solution to the original problem passed to this TransformationPass' forward method.
requires() -> list[str]
invalidates() -> list[str]
Get a list of passes that are invalidated by this pass.
Returns:
-
list of str–Names of passes whose results become invalid after this pass runs.
__str__() -> str
Human readable string.
__new__(sense: Sense) -> Self
Create a new change sense pass instance.
Parameters:
-
sense(Sense) –The target sense to convert the optimization sense to.
EqualityConstraintsToQuadraticPenaltyPass
Bases: PyEqualityConstraintsToQuadraticPenaltyPass, BuiltinTransformation[EqualityConstraintsToQuadraticPenaltyPassArtifact]
Move all equality constraints to the model's objective as a quadratic penalties.
Converts the model by moving all equality constraints to the objective as quadratic penalties.
Requires the MaxBiasAnalysis pass to be executed before this pass.
Less-equal (<=) or greater-equal (>=) constraints are not respected by this transformation
and have to be handled before this pass using, e.g., the GeToLeConstraintsPass and the
LeToEqConstraintsPass.
Notes
This pass requires the MaxBiasAnalysis pass to be executed before this pass.
Parameters:
-
penalty_scaling(float, default:10.0) –The factor used to scale the penalties with, default 10.0.
Examples:
>>> from luna_model import Model, Vtype, Sense
>>> from luna_model.transformation import PassManager
>>> from luna_model.transformation.passes import MaxBiasAnalysis
>>> from luna_model.transformation.passes import EqualityConstraintsToQuadraticPenaltyPass
>>> model = Model(sense=Sense.MAX)
>>> x = model.add_variable("x", vtype=Vtype.BINARY)
>>> y = model.add_variable("y", vtype=Vtype.BINARY)
>>> model.objective = x * y + x - 2 * y
>>> model.constraints += x + y == 0
>>> pm = PassManager(
... [
... MaxBiasAnalysis(),
... EqualityConstraintsToQuadraticPenaltyPass(),
... ]
... )
>>> output = pm.run(model)
>>> print(output.model.objective)
41 x y + 21 x + 18 y
penalty_scaling: float
property
Get the penalty scaling factor.
name() -> str
forward(model: Model, ctx: PassContext) -> tuple[Model, Artifact]
Run/Execute this transformation pass.
Parameters:
-
model(Model) –The model to transform.
-
ctx(PassContext) –Context for this pass providing read-access to the analysis cache.
Returns:
backward(artifact: Artifact, solution: Solution) -> Solution
classmethod
Apply the back transformation to the given solution.
Parameters:
-
artifact(Artifact) –The artifact produced by the forward execution.
-
solution(Solution) –The solution to transform back to a representation fitting the original (input) model transformed by the forward method.
Returns:
-
Solution–A solution object representing a solution to the original problem passed to this TransformationPass' forward method.
requires() -> list[str]
invalidates() -> list[str]
Get a list of passes that are invalidated by this pass.
Returns:
-
list of str–Names of passes whose results become invalid after this pass runs.
__str__() -> str
Human readable string.
__new__(penalty_scaling: float = 10.0) -> Self
Create a new equality constraints to quadratic penalty pass.
Parameters:
-
penalty_scaling(float, default:10.0) –The factor used to scale the penalties with, default 10.0.
GeToLeConstraintsPass
Bases: PyGeToLeConstraintsPass, BuiltinTransformation[GeToLeConstraintsPassArtifact]
Convert the model's constraints by chaning all greater-equal (>=) constraints to less-equal (<=) constraints.
Examples:
>>> from luna_model import Model, Vtype, Sense
>>> from luna_model.transformation import PassManager
>>> from luna_model.transformation.passes import GeToLeConstraintsPass
>>> model = Model(sense=Sense.MAX)
>>> x = model.add_variable("x", vtype=Vtype.BINARY)
>>> y = model.add_variable("y", vtype=Vtype.BINARY)
>>> model.objective = x * y + x - 2 * y
>>> model.constraints += x + y >= 0, "ge_constr"
>>> pm = PassManager([GeToLeConstraintsPass()])
>>> output = pm.run(model)
>>> output.model.constraints["ge_constr"]
-x - y <= 0
name() -> str
forward(model: Model, ctx: PassContext) -> tuple[Model, Artifact]
Run/Execute this transformation pass.
Parameters:
-
model(Model) –The model to transform.
-
ctx(PassContext) –Context for this pass providing read-access to the analysis cache.
Returns:
backward(artifact: Artifact, solution: Solution) -> Solution
classmethod
Apply the back transformation to the given solution.
Parameters:
-
artifact(Artifact) –The artifact produced by the forward execution.
-
solution(Solution) –The solution to transform back to a representation fitting the original (input) model transformed by the forward method.
Returns:
-
Solution–A solution object representing a solution to the original problem passed to this TransformationPass' forward method.
requires() -> list[str]
invalidates() -> list[str]
Get a list of passes that are invalidated by this pass.
Returns:
-
list of str–Names of passes whose results become invalid after this pass runs.
__str__() -> str
Human readable string.
__new__() -> Self
Create a new ge to le constraints pass.
IntegerToBinaryPass
Bases: PyIntegerToBinaryPass, BuiltinTransformation[IntegerToBinaryPassArtifact]
Convert integer variables to a binary representation.
Transform the variables of type integer to be represented by binary typed variables.
Examples:
>>> from luna_model import Model, Vtype
>>> from luna_model.transformation import PassManager
>>> from luna_model.transformation.passes import BinarySpinPass
>>> model = Model()
>>> x = model.add_variable("x", vtype=Vtype.INTEGER, lower=0, upper=3)
>>> y = model.add_variable("y", vtype=Vtype.BINARY)
>>> model.objective = x * y + x - 2 * y
>>> pm = PassManager([IntegerToBinaryPass()])
>>> output = pm.run(model)
>>> print(output.model.objective)
y x_b0 + 2 y x_b1 - 2 y + x_b0 + 2 x_b1
name() -> str
forward(model: Model, ctx: PassContext) -> tuple[Model, Artifact]
Run/Execute this transformation pass.
Parameters:
-
model(Model) –The model to transform.
-
ctx(PassContext) –Context for this pass providing read-access to the analysis cache.
Returns:
backward(artifact: Artifact, solution: Solution) -> Solution
classmethod
Apply the back transformation to the given solution.
Parameters:
-
artifact(Artifact) –The artifact produced by the forward execution.
-
solution(Solution) –The solution to transform back to a representation fitting the original (input) model transformed by the forward method.
Returns:
-
Solution–A solution object representing a solution to the original problem passed to this TransformationPass' forward method.
requires() -> list[str]
invalidates() -> list[str]
Get a list of passes that are invalidated by this pass.
Returns:
-
list of str–Names of passes whose results become invalid after this pass runs.
__str__() -> str
Human readable string.
__new__() -> Self
Create a new integer to binary pass.
LeToEqConstraintsPass
Bases: PyLeToEqConstraintsPass, BuiltinTransformation[LeToEqConstraintsPassArtifact]
Convert the model's constraints by chaning all less-equal (<=) constraints to equality (==) constraints.
Examples:
>>> from luna_model import Model, Vtype, Sense
>>> from luna_model.transformation import PassManager
>>> from luna_model.transformation.passes import MinValueForConstraintAnalysis
>>> from luna_model.transformation.passes import LeToEqConstraintsPass
>>> model = Model(sense=Sense.MAX)
>>> x = model.add_variable("x", vtype=Vtype.BINARY)
>>> y = model.add_variable("y", vtype=Vtype.BINARY)
>>> model.objective = x * y + x - 2 * y
>>> model.constraints += x + y <= 3, "le_constr"
>>> pm = PassManager([MinValueForConstraintAnalysis(), LeToEqConstraintsPass()])
>>> output = pm.run(model)
>>> output.model.constraints["le_constr"]
x + y - slack_le_constr == 0
>>> print(output.model.get_variable("slack_le_constr"))
slack_le_constr: Integer(lower=0, upper=3)
name() -> str
forward(model: Model, ctx: PassContext) -> tuple[Model, Artifact]
Run/Execute this transformation pass.
Parameters:
-
model(Model) –The model to transform.
-
ctx(PassContext) –Context for this pass providing read-access to the analysis cache.
Returns:
backward(artifact: Artifact, solution: Solution) -> Solution
classmethod
Apply the back transformation to the given solution.
Parameters:
-
artifact(Artifact) –The artifact produced by the forward execution.
-
solution(Solution) –The solution to transform back to a representation fitting the original (input) model transformed by the forward method.
Returns:
-
Solution–A solution object representing a solution to the original problem passed to this TransformationPass' forward method.
requires() -> list[str]
invalidates() -> list[str]
Get a list of passes that are invalidated by this pass.
Returns:
-
list of str–Names of passes whose results become invalid after this pass runs.
__str__() -> str
Human readable string.
__new__() -> Self
Create a new le to eq constraints pass.
MaxBiasAnalysis
Bases: PyMaxBiasAnalysis, BuiltinAnalysis[MaxBias]
Analysis pass that computes the maximum absolute coefficient value in the objective.
Examples:
>>> from luna_model import Model, Vtype
>>> from luna_model.transformation import PassManager
>>> from luna_model.transformation.passes import MaxBiasAnalysis
>>> model = Model()
>>> x = model.add_variable("x", vtype=Vtype.BINARY)
>>> y = model.add_variable("y", vtype=Vtype.BINARY)
>>> model.objective = x * y + x - 2 * y
>>> pm = PassManager([MaxBiasAnalysis()])
>>> output = pm.run(model)
>>> output.context.require_analysis(MaxBiasAnalysis.key()).val
2.0
name() -> str
run(model: Model, ctx: PassContext) -> Result
Run/Execute this analysis pass.
Parameters:
-
model(Model) –The model to analyse.
-
ctx(PassContext) –Context for this pass providing read-access to the analysis cache.
Returns:
-
Result–The analysis result.
requires() -> list[str]
provides() -> str
classmethod
Get the identifier for the analysis cache elment this pass generates.
Returns:
-
str–The identifier of the cache element
key() -> AnalysisKey[Result]
classmethod
Get the analysis key used to access the analysis result from the PassContext.
__str__() -> str
Human readable string.
__new__() -> Self
Create a new max bias analysis pass.
CheckModelSpecsAnalysis
Bases: PyCheckModelSpecsAnalysis, BuiltinAnalysis[None]
Analysis pass that checks the model's specs for correctness.
This analysis pass checks if the input model satisfies the
specifications (ModelSpecs) this pass is initilized with. If the specs
are not satified by the model it raises an error during runtime.
Examples:
>>> from luna_model import Model, Vtype
>>> from luna_model.transformation import PassManager
>>> from luna_model.transformation.passes import CheckModelSpecsAnalysis
>>> model = Model()
>>> x = model.add_variable("x", vtype=Vtype.BINARY)
>>> y = model.add_variable("y", vtype=Vtype.BINARY)
>>> model.objective = x * y + x - 2 * y
>>> specs = ModelSpecs(max_degree=2)
>>> pm = PassManager([CheckModelSpecsAnalysis(specs)])
>>> output = pm.run(model)
>>> # no errors raised
name() -> str
run(model: Model, ctx: PassContext) -> Result
Run/Execute this analysis pass.
Parameters:
-
model(Model) –The model to analyse.
-
ctx(PassContext) –Context for this pass providing read-access to the analysis cache.
Returns:
-
Result–The analysis result.
requires() -> list[str]
provides() -> str
classmethod
Get the identifier for the analysis cache elment this pass generates.
Returns:
-
str–The identifier of the cache element
key() -> AnalysisKey[Result]
classmethod
Get the analysis key used to access the analysis result from the PassContext.
__str__() -> str
Human readable string.
__new__(specs: ModelSpecs) -> Self
Create a new check model specs analysis pass.
Parameters:
-
specs(ModelSpecs) –The model specs the model passed to this analysis pass has to fulfill.
MinValueForConstraintAnalysis
Bases: PyMinValueForConstraintAnalysis, BuiltinAnalysis[MinConstraintValues]
Analysis pass that computes the min value possible for all constraints.
This analysis pass computes the minimal value possible for all constraints of the input model.
Examples:
>>> from luna_model import Model, Vtype
>>> from luna_model.transformation import PassManager
>>> from luna_model.transformation.passes import CheckModelSpecsAnalysis
>>> model = Model()
>>> x = model.add_variable("x", vtype=Vtype.BINARY)
>>> y = model.add_variable("y", vtype=Vtype.BINARY)
>>> model.objective = x * y + x - 2 * y
>>> model.constraints += -5 * x + y <= 2, "my-constraint"
>>> pm = PassManager([MinValueForConstraintAnalysis()])
>>> output = pm.run(model)
>>> output.context.require_analysis(MinValueForConstraintAnalysis.key()).vals
{'my-constraint': -5.0}
name() -> str
run(model: Model, ctx: PassContext) -> Result
Run/Execute this analysis pass.
Parameters:
-
model(Model) –The model to analyse.
-
ctx(PassContext) –Context for this pass providing read-access to the analysis cache.
Returns:
-
Result–The analysis result.
requires() -> list[str]
provides() -> str
classmethod
Get the identifier for the analysis cache elment this pass generates.
Returns:
-
str–The identifier of the cache element
key() -> AnalysisKey[Result]
classmethod
Get the analysis key used to access the analysis result from the PassContext.
__str__() -> str
Human readable string.
__new__() -> Self
Create a new min value for constraint analysis pass.
SpecsAnalysis
Bases: PySpecsAnalysis, BuiltinAnalysis[ModelSpecs]
Analysis pass that computes the model's specs and stores them in the cache.
This analysis pass computes the ModelSpecs of the input model and writes it
to the AnalysisCache to be used by transformation passes following it during
the PassManager execution. This analysis pass can, for example, be used in
combination with the IfElsePass to guide the transformation depending on the
specifications (ModelSpecs) of a model.
Notes
This pass is not to be confused with the CheckModelSpecsAnalysis, which checks
if an input model's specs satisfy a given set of ModelSpecs.
Examples:
>>> from luna_model import Model, Vtype
>>> from luna_model.transformation import PassManager
>>> from luna_model.transformation.passes import SpecsAnalysis
>>> model = Model()
>>> x = model.add_variable("x", vtype=Vtype.BINARY)
>>> y = model.add_variable("y", vtype=Vtype.BINARY)
>>> model.objective = x * y + x - 2 * y
>>> pm = PassManager([SpecsAnalysis()])
>>> output = pm.run(model)
>>> output.context.require_analysis(SpecsAnalysis.key())
ModelSpecs(sense=Minimize, vtype=Binary, constraints=, max_degree=2, max_constraint_degree=0, max_num_variables=2)
name() -> str
run(model: Model, ctx: PassContext) -> Result
Run/Execute this analysis pass.
Parameters:
-
model(Model) –The model to analyse.
-
ctx(PassContext) –Context for this pass providing read-access to the analysis cache.
Returns:
-
Result–The analysis result.
requires() -> list[str]
provides() -> str
classmethod
Get the identifier for the analysis cache elment this pass generates.
Returns:
-
str–The identifier of the cache element
key() -> AnalysisKey[Result]
classmethod
Get the analysis key used to access the analysis result from the PassContext.
__str__() -> str
Human readable string.
__new__() -> Self
Create a new specs analysis pass.
IfElsePass
Bases: PyIfElsePass, BuiltinControlFlow
Conditional pass that returns different branches based on a runtime condition.
The IfElsePass evaluates a condition function against the model and the context at runtime
and returns a plan containing either the then pipeline or the otherwise pipeline based
on the result. This enables branching logic in transformation workflows, allowing different
transformation strategies based on model properties discovered during analysis.
Examples:
Execute different transformations based on the maximum bias:
>>> from luna_model import Model, Vtype
>>> from luna_model.transformation import PassManager
>>> from luna_model.transformation.passes import MaxBiasAnalysis, BinarySpinPass, IfElsePass
>>> # Create conditional pass
>>> conditional = IfElsePass(
... condition=lambda _, ctx: ctx.require_analysis(MaxBiasAnalysis.key()).val > 10.0,
... then=[BinarySpinPass(Vtype.BINARY)],
... otherwise=[],
... name="conditional-spin-conversion",
... )
Let's create a model that satisfies the condition:
>>> model = Model("example")
>>> x = model.add_variable("x", vtype=Vtype.SPIN)
>>> y = model.add_variable("y")
>>> z = model.add_variable("z")
>>> model.objective = 2 * x + 12 * y * z
And use it in the pass manager:
>>> pm = PassManager([MaxBiasAnalysis(), conditional])
>>> result = pm.run(model)
>>> print(result.model)
Model: example
Minimize
12 * y * z - 4 * x_x + 2
Binary
y z x_x
And now a model that does not satisfy the condition:
>>> model = Model("example")
>>> x = model.add_variable("x", vtype=Vtype.SPIN)
>>> y = model.add_variable("y")
>>> z = model.add_variable("z")
>>> model.objective = 2 * x + 8 * y * z
And use it in the pass manager:
>>> pm = PassManager([MaxBiasAnalysis(), conditional])
>>> result = pm.run(model)
>>> print(result.model)
Model: example
Minimize
8 * y * z + 2 * x
Binary
y z
Spin
x
Notes
Both pipelines can contain arbitrarily complex sequences of transformations and analyses.
The condition is evaluated once per IfElsePass execution. If you need to
re-evaluate during pipeline execution, nest multiple IfElsePass instances.
run(model: Model, ctx: PassContext) -> ControlFlowPlan
Run/Execute this control-flow pass.
Parameters:
-
model(Model) –The model to analyse.
-
ctx(PassContext) –Context for this pass providing read-access to the analysis cache.
Returns:
-
Result–The plan to be executed.
name() -> str
requires() -> list[str]
invalidates() -> list[str]
Get a list of passes that are invalidated by this control-flow's plan.
Returns:
-
list of str–Names of passes whose results become invalid after this pass runs.
provides() -> list[str]
Get the identifier for the analysis cache elments this control-flow's plan generates.
Returns:
-
str–The identifiers of the cache elements
__str__() -> str
Human readable string.
__new__(condition: Callable[[Model, PassContext], bool], then: Pipeline | Sequence[Pass], otherwise: Pipeline | Sequence[Pass], name: str | None = None) -> Self
Construct a new IfElsePass instance.
Parameters:
-
condition(Callable[[Model, PassContext], bool]) –Predicate evaluated at runtime. If it returns
True,thenis selected; otherwiseotherwiseis selected. -
then(Pipeline | Sequence[Pass]) –Pipeline/steps executed when the condition is
True. -
otherwise(Pipeline | Sequence[Pass]) –Pipeline/steps executed when the condition is
False. -
name(str | None, default:None) –Optional pass name. If omitted, a default name is used.