Documentation

Current SolverForge release, published package status, completed runtime surface, and roadmap.

Status & Roadmap

Current Status

Component Status Description
Rust Core Published Native Rust constraint solver published as solverforge 0.15.2
CLI Scaffold Source current; package pending GitHub main solverforge-cli 2.2.1 scaffolds solverforge 0.15.1, solverforge-ui 0.6.5, and solverforge-maps 2.1.4; crates.io still serves solverforge-cli 2.2.0
Python Published PyPI solverforge 0.4.0 provides dynamic CPython 3.14 bindings backed by the Rust SolverForge engine
UI Published solverforge-ui 0.6.5 is the current UI patch line
Maps Published solverforge-maps 2.1.4 carries matrix route-distance access

Try It Today

  • Start with solverforge-cli Getting Started for the generic app shell.
  • Use SolverForge Python when you want to define models with Python classes, decorators, and callbacks while using the native SolverForge engine.
  • Continue with the worked use-case bundle: Hospital, Lessons, Deliveries, or FSR. Those guides stay aligned to the checked-in use-case bundle on solverforge 0.15.0; they are intentionally not part of the 0.15.2 runtime or 2.2.1 CLI scaffold refresh yet.
  • Use Constraint Node Sharing when a constraint function reuses the same grouped stream across several named terminal constraints.
  • Use Projected Scoring Rows when scoring needs retained rows derived from source entities, joined pairs, or oriented relationships between projected rows.

Completed Runtime Surface

  • Constraint Streams API: source-aware generated source methods, for_each, filter, unified join(...), direct cross-join group_by(...), direct cross-join grouped complements, flatten_last, project(...), projected grouped complements, balance, complement(...), if_exists(...), if_not_exists(...), collect_vec(...), indexed_presence(...), explicit score weighting, and .named(...)
  • Projected Scoring Rows: bounded single-source rows, joined-pair projected rows, symmetric projected self-joins through equal(...), and directed projected self-joins through equal_bi(left_key, right_key)
  • Constraint Compiler Node Sharing: #[solverforge_constraints] can share grouped, projected grouped, direct cross grouped, and complemented grouped stream nodes across repeated terminal constraints while preserving terminal names, order, metadata, and score explanation
  • Score Types: SoftScore, HardSoftScore, HardMediumSoftScore, HardSoftDecimalScore, BendableScore
  • Score Analysis: facade-level ScoreAnalysis and ConstraintAnalysis, plus lower-level detailed match/explanation APIs in solverforge-scoring
  • SERIO Engine: retained incremental scoring for real-time optimization
  • Solver Phases: scalar/list construction heuristics, assignment-backed grouped scalar construction, streaming local search, VND as a local-search type, precedence-list neighborhoods, and typed custom, exact, or partitioned search extensions
  • Move System: scalar, list, grouped scalar, assignment repair, conflict repair, cartesian, and composite move families
  • SolverManager API: retained job lifecycle with progress, best-solution, pause/resume, completion, cancellation, failure, snapshots, and snapshot-bound analysis
  • Configuration: stock solver.toml, TOML/YAML parsing helpers, bounded scalar candidates, grouped scalar selectors, level-aware simulated annealing, and per-solution config overlays

Python Package

  • Install: python3.14 -m pip install solverforge.
  • Modeling: Python classes, decorators, scalar variables, list variables, and callback constraints.
  • Runtime entry points: Solver.solve(...), Solver.analyze(...), and SolverManager(config=None).
  • Constraint surface: callback-authored unary streams, binary stream-level joins, grouped counts, balance scoring, fixed or callback-computed weights, and joiner.equal(...) / joiner.equal_bi(...).
  • Dynamic move parity: supported scalar and list local-search selectors, including grouped scalar, conflict repair, compound conflict repair, k-opt, list ruin, union, limited neighborhood, and two-child cartesian composition.

Runtime Notes

  • 0.15.2 published baseline: the core crate version is 0.15.2 and the Rust toolchain floor remains 1.95. The CI-green solverforge-cli 2.2.1 source line targets solverforge 0.15.1; the published solverforge-cli 2.2.0 package and checked-in use-case bundle still target solverforge 0.15.0 until their next publish or runtime-target refresh.
  • Dynamic bridge crate: solverforge-bridge carries host-language binding contracts for logical entity/fact/variable IDs, dynamic score families, and descriptor-resolved scalar/list slots. Python remains the first published binding, but the bridge contract is a Rust workspace crate.
  • Constraint node sharing: annotate reusable constraint factory functions with #[solverforge_constraints]. Reused same-binding grouped streams and syntax-proved identical grouped chains share retained incremental node work; separate terminal constraints keep their own names, impact direction, metadata, and explanation rows.
  • Generated source methods: #[planning_solution] now exposes collection sources as solution-associated functions such as Schedule::shifts(). Constraint streams use those generated methods through ConstraintFactory::for_each(...).
  • Assignment-backed scalar groups: ScalarGroup::assignment(...) declares required nullable scalar slots, capacity keys, sequence/position hooks, and construction ordering; grouped construction and grouped_scalar_move_selector consume the same group_name from solver.toml.
  • Collectors: consecutive_runs(...), collect_vec(...), and indexed_presence(...) cover streaks, owned grouped payloads, and ordinal presence/complement checks. The underlying Collector<Input> contract is generic over the stream match shape, so unary rows, projected rows, and direct cross-join pairs use the same collector protocol.
  • Scoring terminals: the current stream surface uses penalize(score), reward(score), typed dynamic closures, fixed_weight(...), and hard_weight(...); the older penalize_hard, penalize_with, and reward_soft helper family is historical.
  • Public runtime names: direct runtime assembly APIs use RuntimeModel, VariableSlot, ScalarVariableSlot, ListVariableSlot, ScalarGroup, ScalarAssignmentRule, ConflictRepair, RepairCandidate, and RepairLimits.
  • Facade configuration exports: app code can import SolverConfig, PhaseConfig, MoveSelectorConfig, AcceptorConfig, ForagerConfig, SolverConfigOverride, and related enums directly from solverforge.
  • Typed custom search: solutions can compile in search code with #[planning_solution(search = "...")], register named phases through SearchContext, and order those names from solver.toml.
  • Joined-pair projected rows: cross joins can use .project(|left, right| row) to retain one scoring row per joined pair.
  • Directed projected self-joins: projected rows can use .join(equal_bi(left_key, right_key)) when the left and right side of a same-row-type relationship are semantically different, such as parent-child projected rows.
  • Direct cross-join grouping: cross joins can group joined pairs with .group_by(|left, right| key, collector) without projecting first.
  • Projected grouped complements: projected grouped streams can continue into complement(...) or complement_with_key(...) for missing-key scoring rows.
  • Direct cross-join grouped complements: direct cross joins can group joined pairs and then call complement(...) against a generated fact or entity source for zero-match target rows.
  • Filtered keyed joins: filtered right-hand join sources, flattened keyed targets, custom keyed extractors, and filtered complement sources retain only rows that still satisfy their source filters.
  • Clone-free projected paths: projected outputs, projected self-join keys, and grouped collector values no longer need Clone in the 0.11.x release line.
  • Joined filter indexes: low-level joined filters receive semantic source indexes for direct, grouped, projected, flattened, and higher-arity joins.
  • Owner-aware route hooks: list construction uses shared route hooks route_get_fn, route_set_fn, route_depot_fn, route_metric_class_fn, route_distance_fn, and route_feasible_fn for Clarke-Wright and k-opt. Clarke-Wright can compute savings once per shared route metric class while keeping final feasibility checks owner-specific.
  • Assignment value-pattern neighborhoods: assignment-backed grouped scalar local search includes bounded value-window swaps, longer value-window swaps, same-sequence run-gap swaps, block reassignments, optional run releases, and three-value rotations. Required assignment construction still has a hard-first batched fill path for required slots.
  • Borrowed constraint identity: scoring metadata preserves full ConstraintRef identity borrowed from the owning constraint.
  • Model-owned scalar hooks: candidate_values, nearby_value_candidates, nearby_entity_candidates, construction_entity_order_key, and construction_value_order_key declare bounded scalar neighborhoods and construction ordering on the model.
  • Model-aware defaults: omitted runtime config builds construction plus one streaming local-search phase; omitted move_selector values use typed scalar/list/grouped defaults rather than prebuilding broad neighborhoods.
  • Exact retained telemetry: generated, evaluated, accepted, not-doable, acceptor-rejected, forager-ignored, hard-delta, conflict-repair, construction-slot, move-label, and bounded applied-move trace counters are retained as authoritative counters.

Roadmap

Native Solver Complete

The Rust-native constraint solver, derive macros, SERIO scoring engine, retained runtime lifecycle, and stock configuration surface are in place.

Rust API Refinement

Current work focuses on tightening public API contracts, making scoring and runtime paths easier to explain, and keeping source, docs, examples, and CLI scaffolds aligned as releases move.

Python Package

solverforge 0.4.0 is available on PyPI for CPython 3.14. Current work focuses on examples, compatibility hardening, and exposing more Python APIs where the runtime supports them.

Additional Language Bindings

Other language bindings remain future-facing. The Rust core remains the source of truth for solver behavior, while Python is the first published dynamic binding.

How You Can Help