Expand description
§dotloom-constraints
Constraint solving for Dotloom (ADR-0004).
- Rules are rows of scalar
Exprresiduals with exact derivatives. - The problem is split into connected components. Purely linear components go to kasuari (a maintained Cassowary implementation); nonlinear/mixed components go to a damped Gauss–Newton backend that solves hard rules as exact equality constraints and preferences as least squares inside the hard-feasible set.
- Results distinguish
solved,underconstrained,conflicting(with evidence),notConverged(with or without a suspected conflict),cancelledandunsupported, and carry structuredDiagnostics. SolveJobruns in budgeted steps so hosts can cancel between steps.LinearSessionre-solves a linear problem incrementally while a drag moves its target (Cassowary edit variables), verified like a full solve.
This crate has no document, DOM or GPU dependency.
use dotloom_constraints::{Problem, Rule, Strength, Variable, Expr, rules, solve, SolveOptions, Status};
// Shelf: total = w1 + w2 + w3, w1 locked at 600 mm, w2 = w3 ≥ 400 mm.
let mut p = Problem::default();
let total = p.add_var(Variable::new(1800.0).scale(1000.0));
let w1 = p.add_var(Variable::new(600.0).scale(1000.0));
let w2 = p.add_var(Variable::new(600.0).scale(1000.0));
let w3 = p.add_var(Variable::new(600.0).scale(1000.0));
let v = |id| Expr::Var(id);
p.rules.push(Rule::new(1, rules::linear(&[(1.0, v(w1)), (1.0, v(w2)), (1.0, v(w3)), (-1.0, v(total))], rules::Cmp::Eq, 0.0, 1000.0), Strength::Required));
p.rules.push(Rule::new(2, rules::equal(v(w2), v(w3), 1000.0), Strength::Required));
p.rules.push(Rule::new(3, rules::at_least(v(w2), 400.0, 1000.0), Strength::Required));
p.rules.push(Rule::new(4, rules::at_least(v(w3), 400.0, 1000.0), Strength::Required));
p.rules.push(Rule::new(5, rules::fix(v(w1), 600.0, 1000.0), Strength::Required));
p.rules.push(Rule::new(6, rules::fix(v(total), 1600.0, 1000.0), Strength::Required));
let s = solve(&p, &SolveOptions::default());
assert!(s.accepted());
assert!((s.values[w2.index()] - 500.0).abs() < 1e-6);Modules§
- rules
- Residual builders for the supported rule classes.
Structs§
- Component
- A connected component of free variables and the rules that couple them.
- Component
Report - Report of one solved component.
- Diagnostic
- A structured diagnostic.
- Dual
- Value plus sparse gradient, sorted by variable index.
- Linear
Form - Affine form
Σ cᵢ·xᵢ + constant. - Linear
Session - An incremental solve session for repeated solves of one linear problem whose constants change (see the module documentation).
- Point
Expr - A 2D point as a pair of expressions.
- Problem
- A complete solve request.
- Row
- One scalar residual of a rule.
- Rule
- A rule: one or more rows with shared metadata.
- Solution
- Complete solve result.
- Solve
Job - A resumable solve.
- Solve
Options - Solver options.
- Target
- A desired value for a variable (drag target, typed preference). Targets are never
hard; hard edits are expressed as
Requiredrules. - VarId
- Index of a solver variable within a
crate::Problem. - Variable
- A solver variable.
Enums§
- Backend
- Which backend handled a component.
- Certainty
- Certainty of a diagnostic.
- Diagnostic
Kind - Diagnostic category.
- Expr
- A scalar expression.
- Progress
- Progress of a job after a step.
- Relation
- Relation of a row:
expr = 0orexpr ≤ 0. - Status
- Status of one component (or the aggregate solve).
- Strength
- Constraint strength.
Requiredrules are hard: a solution violating them is never accepted. The others are preferences ordered by priority.
Constants§
- STAY_
WEIGHT - Weight of the implicit “stay near the previous valid value” preference. It is below every user strength so any explicit preference wins over staying put.
Functions§
- components
- Split a problem into independent components.
- solve
- Solve to completion.
- stay_
factor - Clamp a stay multiplier to the supported range.