Documentation

Constraints

Define business rules using constraint streams, joiners, collectors, and score types.

Constraints are the business rules that define what makes a good solution. SolverForge uses a constraint streams API - a declarative, composable way to express rules that reads like a pipeline of filters and transformations.

How Constraints Work

  1. Select entities or facts from your solution using generated factory methods
  2. Filter, project, join, or group to narrow down the matches
  3. Penalize or reward to affect the score
  4. Name the constraint with .named()
let factory = ConstraintFactory::<Schedule, HardSoftScore>::new();

factory.shifts()                              // Select all shifts
    .filter(|s| s.employee_idx.is_none())     // Keep unassigned ones
    .penalize(HardSoftScore::ONE_HARD)        // Penalize each
    .named("Unassigned shift")                // Finalize

Constraints are returned as a tuple implementing ConstraintSet<S, Sc>, which the solver evaluates incrementally as it explores moves. In the 0.11.x release line, generated accessors preserve source metadata for localized incremental updates, projected streams can emit retained scoring rows from one source or one joined pair, and lower-level constraint metadata borrows full ConstraintRef identity from the owning constraint. Package-qualified constraints use ConstraintRef::full_name() as the configured key; package-less constraints use the short name.

Sections