ordec.core.constraints — Linear constraint solving

This module allows generating attributes values from a set of user-defined linear constraints (equalities and inequalities) instead of manually computing attribute values. It is used the following way:

  1. Create a Solver instance for the subgraph.

  2. Add constaints via the constrain() method.

  3. Call the solve() method to solve the constriants and fill in the attributes.

Only ConstrainableAttr attributes can be constrained.

Example:

l = Layout(ref_layers=layers)
l.r1 = LayoutRect(layer=layers.Metal1)
l.r2 = LayoutRect(layer=layers.Metal1)

s = Solver(l)
s.constrain(l.r1.height >= 500)
s.constrain(l.r1.width >= 150)
s.constrain(l.r1.southwest == (100, -100))
s.constrain(l.r2.lx >= l.r1.ux + 150)
s.constrain(l.r2.width == -l.r1.height + 800)
s.constrain(l.r2.width <= 150)
s.constrain(l.r2.height == 150)
s.constrain(l.r2.cy == l.r1.cy)
s.solve()
class ordec.core.constraints.Solver(subgraph: SubgraphRoot)

Collects and solves constraints for a set of ConstrainableAttr attributes of specified subgraph.

constrain(constraint: Constraint | MultiConstraint)

Add constraint that must be satisfied by the solution.

solve(allow_ambiguous: bool = False)

Using linear programming, calculates a solution that satisfies all specified constraints. The solution values are then written to all affected ConstrainableAttr attributes.

Parameters:

allow_ambiguous – If False (default), checks that the solution is unique. Raises SolverError if multiple optimal solutions exist, indicating missing constraints. If True, skips uniqueness checking and allows ambiguous solutions.

Raises:

SolverError – If the LP solver fails, or if allow_ambiguous=False and the solution is not unique (has degrees of freedom).

Linear terms

class ordec.core.constraints.Variable(subgraph: MutableSubgraph, nid: int, attr: ConstrainableAttr, subid: int)

Represents scalar integer or rational variable whose value is to be determined using a solver.

subgraph: MutableSubgraph

Subgraph to which the variable belongs.

nid: int

The nid of the node to which the variable belongs.

attr: ConstrainableAttr

The attribute to which the variable belongs.

subid: int

Using the subid, multiple variables can be associated with one attribute. For example the subids (0, 1, 2, 3) for (lx, ly, ux, uy) of a constrainable Rect4 attribute.

class ordec.core.constraints.LinearTerm(variables: tuple[Variable], coefficients: tuple[float], constant: float)

Represents the linear term: (sum over n of coefficient_n * variable_n) + constant

variables: tuple[Variable]

Tuple of all variables of the term.

coefficients: tuple[float]

Tuple of all coefficients of the term, must have the same length as the variables tuple.

constant: float

Constant value of the term.

same_as(other) bool

Returns whether self and other is the identical term. Sort of a replacement for __eq__, since __eq__ returns EqualsZero objects.

class ordec.core.constraints.Vec2LinearTerm(x: LinearTerm, y: LinearTerm)

Bases: Vec2Generic, ConstrainableAttrPlaceholder

Point in 2D space.

x

x coordinate

Type:

LinearTerm

y

y coordinate

Type:

LinearTerm

class ordec.core.constraints.Rect4LinearTerm(lx: LinearTerm, ly: LinearTerm, ux: LinearTerm, uy: LinearTerm)

Bases: Rect4Generic, ConstrainableAttrPlaceholder

vector_cls

alias of Vec2LinearTerm

contains(other) MultiConstraint

Sadly, Python’s ‘in’ operator coerces to booleans, so we cannt use it for our purpose here.

class ordec.core.constraints.TD4LinearTerm(transl=None, d4=None)

Bases: TD4

LinearTerm version of TD4, supports both integer and Rational types.

vec_cls

alias of Vec2LinearTerm

Constraints

class ordec.core.constraints.Constraint
class ordec.core.constraints.MultiConstraint(constraints: tuple[ordec.core.constraints.Constraint])
class ordec.core.constraints.LessThanOrEqualsZero(term: LinearTerm)

Bases: Constraint

Inequality constraint of the form: term <= 0

term: LinearTerm

Constrained term.

class ordec.core.constraints.EqualsZero(term: LinearTerm)

Bases: Constraint

Equality constraint of the form: term == 0

term: LinearTerm

Constrained term.

Under the hood

class ordec.core.constraints.ConstrainableAttr(type: type, placeholder: ConstrainableAttrPlaceholder, **kwargs)

An attribute that can be constrained. When the underlying attribute value in the database is None, it is considered undefined / variable. In this case, the attribute’s read hook returns a placeholder object instead of None. When the underlying attribute value in the databse is not None, the attribute acts like a regular attribute.

The target_type is inferred from the type parameter: Vec2R/Rect4R use R, Vec2I/Rect4I use int.

class ordec.core.constraints.ConstrainableAttrPlaceholder

Abstract base class for classes that implement placeholder values for ConstrainableAttrs. The placeholder values (i.e. instances of ConstrainableAttrPlaceholder subclasses) are returned by ConstrainableAttr when the underlying DB value is None.

classmethod collect_values(mav, value_of_var)

Collect solved values for all subids of an attribute.