Skip to content

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:

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:

__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

Get the transformed model.

Returns:

  • Model

    The model after execution of the PassManager.

record: TransformationRecord property

Get the transformation record produced during the PassManager execution.

Returns:

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

require_analysis(key: AnalysisKey[T]) -> T
require_analysis(key: AnalysisKey[T], *, default: T) -> 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 key is found. If not provided, and the key is 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

Create a new pipeline from a sequence of passes.

Parameters:

  • steps (Sequence[Pass | Self]) –

    Ordered passes/pipelines to execute.

  • name (str) –

    Human-readable pipeline name.

Returns:

  • Self

    New pipeline instance.

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]

List of passes that must run before this pipeline.

Returns:

  • list[str]

    Pass names that must execute first, or empty list if no dependencies.

invalidates() -> list[str]

Get analysis keys invalidated by this pipeline.

Returns:

  • list[str]

    Analysis/pass keys invalidated by at least one step.

provides() -> list[str]

Get analysis keys provided by this pipeline.

Returns:

  • list[str]

    Analysis/pass keys produced by at least one step.

clear() -> None

Clear all passes from the pipeline.

Removes all transformation passes, leaving an empty pipeline.

passes() -> list[Pass | Self]

Get all passes that are part of the pipeline.

Returns:

  • list[Pass | Self]

    The transformation passes in this pipeline.

__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

Get all recorded pass entries in forward execution order.

Returns:

  • list[PassEntry]

    Recorded pass entries converted to Python-facing entry wrappers.

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

Encode the transformation record to bytes.

Returns:

  • bytes

    Encoded transformation record

serialize() -> bytes

Serialize the transformation record to bytes.

Returns:

  • bytes

    Serialized transformation record.

decode(data: bytes) -> TransformationRecord classmethod

Decode a transformation record from bytes.

Parameters:

  • data (bytes) –

    Encoded transformation record data.

Returns:

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:

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:

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

Get the unique identifier for this pass.

Returns:

  • str

    The unique pass name.

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:

  • tuple[Model, Artifact]

    The transformation result containing the model and the artifact used for running the backward pass.

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]

List of passes that must run before this pass.

Returns:

  • list[str]

    Pass names that must execute first, or empty list if no dependencies.

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

Get the name for this pass.

Returns:

  • str

    The unique pass name.

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]

List of passes that must run before this pass.

Returns:

  • list[str]

    Pass names that must execute first, or empty list if no dependencies.

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

Get the unique identifier for this pass.

Returns:

  • str

    The unique pass name.

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:

  • tuple[Model, Artifact]

    The transformation result containing the model and the artifact used for running the backward pass.

requires() -> list[str]

List of passes that must run before the passes of this control-flow's plan.

Returns:

  • list[str]

    Pass names that must execute first, or empty list if no dependencies.

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

Get the unique identifier for this pass.

Returns:

  • str

    The unique pass name.

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:

  • tuple[Model, Artifact, Result]

    The transformation result containing the model, the artifact used for running the backward pass and the analysis result.

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]

List of passes that must run before this pass.

Returns:

  • list[str]

    Pass names that must execute first, or empty list if no dependencies.

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 generic A is 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_analysis becomes my-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_analysis becomes decorated_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:

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

Get the unique identifier for this pass.

Returns:

  • str

    The unique pass name.

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:

  • tuple[Model, Artifact]

    The transformation result containing the model and the artifact used for running the backward pass.

requires() -> list[str]

List of passes that must run before the passes of this control-flow's plan.

Returns:

  • list[str]

    Pass names that must execute first, or empty list if no dependencies.

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

Get the unique identifier for this pass.

Returns:

  • str

    The unique pass name.

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:

  • tuple[Model, Artifact, Result]

    The transformation result containing the model, the artifact used for running the backward pass and the analysis result.

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]

List of passes that must run before this pass.

Returns:

  • list[str]

    Pass names that must execute first, or empty list if no dependencies.

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

Get currently allowed import prefixes used by artifact resolution.

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

Create the unconstrained-binary conversion pipeline.

Parameters:

  • penalty_scaling (float, default: 10.0 ) –

    Multiplier used when adding quadratic penalty terms for converted constraints. Defaults to 10.0.

Returns:

  • Self

    New pipeline instance.

__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

Create the binary-minimization conversion pipeline.

Returns:

  • Self

    New pipeline instance.

__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.SPIN all binary variables in the model are converted to spin variables. If set to Vtype.BINARY all 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

Get the unique identifier for this pass.

Returns:

  • str

    The unique pass name.

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:

  • tuple[Model, Artifact]

    The transformation result containing the model and the artifact used for running the backward pass.

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]

List of passes that must run before this pass.

Returns:

  • list[str]

    Pass names that must execute first, or empty list if no dependencies.

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.SPIN all binary variables in the model are converted to spin variables. If set to Vtype.BINARY all 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

Get the unique identifier for this pass.

Returns:

  • str

    The unique pass name.

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:

  • tuple[Model, Artifact]

    The transformation result containing the model and the artifact used for running the backward pass.

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]

List of passes that must run before this pass.

Returns:

  • list[str]

    Pass names that must execute first, or empty list if no dependencies.

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

Get the unique identifier for this pass.

Returns:

  • str

    The unique pass name.

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:

  • tuple[Model, Artifact]

    The transformation result containing the model and the artifact used for running the backward pass.

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]

List of passes that must run before this pass.

Returns:

  • list[str]

    Pass names that must execute first, or empty list if no dependencies.

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

Get the unique identifier for this pass.

Returns:

  • str

    The unique pass name.

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:

  • tuple[Model, Artifact]

    The transformation result containing the model and the artifact used for running the backward pass.

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]

List of passes that must run before this pass.

Returns:

  • list[str]

    Pass names that must execute first, or empty list if no dependencies.

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

Get the unique identifier for this pass.

Returns:

  • str

    The unique pass name.

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:

  • tuple[Model, Artifact]

    The transformation result containing the model and the artifact used for running the backward pass.

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]

List of passes that must run before this pass.

Returns:

  • list[str]

    Pass names that must execute first, or empty list if no dependencies.

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

Get the unique identifier for this pass.

Returns:

  • str

    The unique pass name.

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:

  • tuple[Model, Artifact]

    The transformation result containing the model and the artifact used for running the backward pass.

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]

List of passes that must run before this pass.

Returns:

  • list[str]

    Pass names that must execute first, or empty list if no dependencies.

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

Get the name for this pass.

Returns:

  • str

    The unique pass name.

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]

List of passes that must run before this pass.

Returns:

  • list[str]

    Pass names that must execute first, or empty list if no dependencies.

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

Get the name for this pass.

Returns:

  • str

    The unique pass name.

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]

List of passes that must run before this pass.

Returns:

  • list[str]

    Pass names that must execute first, or empty list if no dependencies.

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

Get the name for this pass.

Returns:

  • str

    The unique pass name.

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]

List of passes that must run before this pass.

Returns:

  • list[str]

    Pass names that must execute first, or empty list if no dependencies.

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

Get the name for this pass.

Returns:

  • str

    The unique pass name.

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]

List of passes that must run before this pass.

Returns:

  • list[str]

    Pass names that must execute first, or empty list if no dependencies.

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

Get the unique identifier for this pass.

Returns:

  • str

    The unique pass name.

requires() -> list[str]

List of passes that must run before the passes of this control-flow's plan.

Returns:

  • list[str]

    Pass names that must execute first, or empty list if no dependencies.

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, then is selected; otherwise otherwise is 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.