Language documentation · Web platform · Rust crate · TypeScript package
ROOC is a library and modeling language for linear and mixed-integer optimization. Define a model in Rust or in ROOC source, then solve it with the built-in solvers.
- Use the fluent Rust API when your application constructs models in code.
- Use the fluent TypeScript API for typed browser and JavaScript models backed by the WebAssembly solvers.
- Use the ROOC language when a formal, data-driven model is easier to read and maintain.
- Use the web platform to write and run ROOC models in the browser.
use rooc::builder::any;
use rooc::{Microlp, ModelBuilder, constraint, vars};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut model = ModelBuilder::new();
vars! { model =>
make_a: bool;
make_b: bool;
make_c: bool;
material: int(0, 8);
};
let solution = model
.maximize(6.0 * make_a + 5.0 * make_b + 4.0 * make_c - material)
.with(constraint!(2.0 * make_a + 3.0 * make_b + make_c <= material))
.with(constraint!(make_a -> make_b))
.with(constraint!(any(vec![make_a, make_c])))
.solve_with(Microlp::new())?;
println!("objective = {}", solution.value());
println!("make_a = {:?}", solution.var_value(make_a));
println!("material = {:?}", solution.var_value(material));
Ok(())
}The crate README covers variables, expressions, constraints, LP export, and direct linear models.
Use Auto for ROOC's safe general-purpose MILP default. It uses Microlp for every supported model. Use Microlp::new() when you need MIP options such as a time limit or mip gap. Select Clarabel explicitly for a continuous model.
The Rust crate enables microlp and clarabel by default. Every other solver
feature is opt-in. Only the default solvers are implemented entirely in Rust
and supported in WebAssembly builds.
| Cargo feature | Rust-only | WASM | Optional capabilities | Scope | Prerequisite |
|---|---|---|---|---|---|
microlp |
Yes | Yes | MIP gap, time limit | LP + MILP | None |
clarabel |
Yes | Yes | Shadow prices | Continuous LP | None |
coin_cbc |
No | No | Initial solution, MIP gap, time limit | LP + MILP | Native CBC toolchain |
highs |
No | No | Initial solution, MIP gap, time limit, shadow prices | LP + MILP | Native HiGHS toolchain |
lpsolve |
No | No | Time limit | LP + MILP | Native C build |
scip |
No | No | Initial solution, MIP gap, time limit | LP + MILP | SCIP installation |
scip_bundled |
No | No | Initial solution, MIP gap, time limit | LP + MILP | Bundled native SCIP build |
lp-solvers |
No | No | None through AllSolvers |
LP + MILP | Solver executable on PATH |
cplex-rs |
No | No | Time limit | LP + MILP | IBM CPLEX installation |
Configured solvers expose only their implemented capabilities:
use rooc::Highs;
use std::time::Duration;
let solver = Highs::new()
.with_time_limit(Duration::from_secs(30))
.with_mip_gap(0.01)
.with_initial_solution([("x", 1.0)]);Clarabel and HiGHS provide named shadow prices through the existing
DualValues solution capability. Reduced costs are not exposed.
Enable an opt-in solver explicitly in Cargo.toml:
[dependencies]
rooc = { version = "0.2.4", default-features = false, features = ["highs"] }Use features = ["microlp", "clarabel", "highs"] when an application needs
both default solvers and an additional native solver. Native-only features are
rejected for wasm32; browser and WebAssembly builds should keep the default
microlp and clarabel feature set. The lpsolve and cplex-rs features
cannot be enabled together.
ROOC source is useful for models built from data, sets, graphs, and iteration:
min sum(v in nodes(G)) { x_v }
s.t.
x_u or x_v for (u, v) in edges(G)
where
let G = Graph {
A -> [B, C],
B -> [D],
C -> [D],
D -> [E],
E
}
define
x_v as Boolean for v in nodes(G)The language supports arithmetic, boolean logic, indexed constraints, collections, graphs, and the abs { }, min { }, and max { } blocks. See the language documentation for the complete syntax and examples.
@specy/rooc provides a type-safe fluent builder over the existing WebAssembly
compiler, linearizer, and solvers:
import { ModelBuilder, sum } from "@specy/rooc";
const model = new ModelBuilder();
const { selected, capacity } = model.vars({
selected: model.bool().array(4),
capacity: model.int(0, 4),
});
const solution = model
.maximize(sum(selected))
.with(sum(selected).le(capacity))
.solve();
console.log(solution.valuesOf({ selected, capacity }));The source compiler and pipe-by-pipe APIs remain available for formal ROOC programs and intermediate pipeline inspection. See the TypeScript README for variables, expressions, solver selection, typed readback, generated source, and compatibility imports.
The Rust library is released under MPL-2.0. The web client is released under AGPL-3.0.
