schedulrv0.14.0

CASOON Open Source

Describe the plan, let the solver place it.

schedulr is a scheduling framework for Rust. You describe activities, rooms, people and time windows as plain data; schedulr finds a plan that fits, and when none exists it tells you why, in your own names.

cargo add schedulr
schedulr = "0.14"
MITcrates.io 0.14.0Rust 1.87+built on unifier 0.6
Terminal: cargo run -q --example workshop_plan prints Status: Feasible (optimal: true) and the plan: Mon 09:00-10:00 a1 Kickoff in Room Aurora with Ana, Ben and Chris; Mon 10:00-12:00 a4 Solver deep dive in Room Aurora with Chris; Mon 13:00-16:00 a2 Rust fundamentals in Room Aurora with Ben; Tue 09:00-11:00 a3 Hands-on lab in Lab 1 with Ben; Tue 15:00-16:00 a5 Q&A in Room Aurora with Ana, Ben and Chris. Below it a timeline with one column per hour from 09 to 16 on Monday and Tuesday, one row per room and person. On a phone the scene shows the input instead (3 resources, 3 participants, 5 activities), the status and the score: hard 0, and 0 for each preference.

Who it is for

  1. Course and training planners

    Sessions, rooms, trainers and a slot calendar with closed hours. schedulr places every session and picks the room and the trainer from the pools you allow.

  2. Booking applications

    One appointment at a time: check, book, move or cancel it against everything already booked, without running a solver search.

  3. Anyone who has to explain a no

    When no plan exists, schedulr names the rule, the activities and the room or person that collide, so the answer can go straight to the user.

dependency: the unifier constraint solver
1
preference levels: Strong, Medium, Weak
3
solver searches for a single booking check
0
unit and integration tests
164

How it works

A SchedulingProblem is plain data: activities with their time windows and durations, the rooms and people they need, calendars, rules and goals. compilechecks it and turns it into a constraint model for unifier.

solve builds a feasible plan first, then improves it with the time that is left. Without a plan, explain lists the conflicts. Single bookings skip the search: SchedulingState checks one create or move against what is booked.

How schedulr worksA SchedulingProblem holds activities, resources, participants, calendars, rules and goals. compile validates it and builds a unifier constraint model; invalid input comes back as one CompileError with every message. solve constructs a feasible schedule first and optimizes it with the remaining time budget. A feasible result is a Solution with the assignments and the score of every rule; without one, explain returns the conflicts, named after your resources, participants and activities.How schedulr worksSchedulingProblem → compilecompile → solvecompile → CompileError: invalid inputsolve → Solution: feasiblesolve → Conflicts: explain()invalid inputfeasibleexplain()SchedulingProblem – activities, rooms, peopleSchedulingProblemactivities, rooms, peoplecompile – builds the unifier modelcompilebuilds the unifier modelsolve – construct, then optimizesolveconstruct, then optimizeSolution – assignments, scoresSolutionassignments, scoresCompileError – every message at onceCompileErrorevery message at onceConflicts – in your namesConflictsin your names
How schedulr worksA SchedulingProblem holds activities, resources, participants, calendars, rules and goals. compile validates it and builds a unifier constraint model; invalid input comes back as one CompileError with every message. solve constructs a feasible schedule first and optimizes it with the remaining time budget. A feasible result is a Solution with the assignments and the score of every rule; without one, explain returns the conflicts, named after your resources, participants and activities.How schedulr worksSchedulingProblem → compilecompile → solvecompile → CompileError: invalid inputsolve → Solution: feasiblesolve → Conflicts: explain()invalid inputfeasibleexplain()SchedulingProblem – activities, rooms, peopleSchedulingProblemactivities, rooms, peoplecompile – builds the unifier modelcompilebuilds the unifier modelsolve – construct, then optimizesolveconstruct, then optimizeSolution – assignments, scoresSolutionassignments, scoresCompileError – every message at onceCompileErrorevery message at onceConflicts – in your namesConflictsin your names
How schedulr worksA SchedulingProblem holds activities, resources, participants, calendars, rules and goals. compile validates it and builds a unifier constraint model; invalid input comes back as one CompileError with every message. solve constructs a feasible schedule first and optimizes it with the remaining time budget. A feasible result is a Solution with the assignments and the score of every rule; without one, explain returns the conflicts, named after your resources, participants and activities.How schedulr worksSchedulingProblem → compilecompile → solvecompile → CompileError: invalid inputsolve → Solution: feasiblesolve → Conflicts: explain()invalid inputfeasibleexplain()SchedulingProblem – activities, rooms, peopleSchedulingProblemactivities, rooms,peoplecompile – builds the unifier modelcompilebuilds the unifiermodelsolve – construct, then optimizesolveconstruct, thenoptimizeSolution – assignments, scoresSolutionassignments,scoresCompileError – every message at onceCompileErrorevery messageat onceConflicts – in your namesConflictsin your names
How schedulr worksA SchedulingProblem holds activities, resources, participants, calendars, rules and goals. compile validates it and builds a unifier constraint model; invalid input comes back as one CompileError with every message. solve constructs a feasible schedule first and optimizes it with the remaining time budget. A feasible result is a Solution with the assignments and the score of every rule; without one, explain returns the conflicts, named after your resources, participants and activities.How schedulr worksSchedulingProblem → compilecompile → solvecompile → CompileError: invalid inputsolve → Solution: feasiblesolve → Conflicts: explain()invalid inputfeasibleexplain()SchedulingProblem – activities, rooms, peopleSchedulingProblemactivities, rooms,peoplecompile – builds the unifier modelcompilebuilds the unifiermodelsolve – construct, then optimizesolveconstruct, thenoptimizeSolution – assignments, scoresSolutionassignments,scoresCompileError – every message at onceCompileErrorevery messageat onceConflicts – in your namesConflictsin your names

What you get

  1. Domain types, not solver variables

    Resources, participants, activities, requirements and time windows are the whole model. Plans and conflicts come back in the same vocabulary, with your ids and names.

  2. Calendars and preferences

    Slot calendars with exceptions decide when activities may start. Day rules shape each person’s day, and preferences on three levels are scored one by one.

  3. Book, explain and repair

    Check a finished plan, ask what a move would break, get suggestions, and repair a plan with as few changes as possible.

Quickstart

From a problem description to a plan or an explanation. The quickstart in the documentation builds the problem step by step.

  1. Add schedulr to your crate.
  2. Describe resources, participants and activities in a SchedulingProblem.
  3. Call compile and solve(), then read the assignments, or explain() why no plan exists.
main.rsRust
let compiled = compile(&problem).expect("problem compiles");
let result = compiled.solve();
for conflict in compiled.explain(&result) {
    println!("{}: {}", conflict.constraint_name, conflict.message);
}
Read the quickstart