Rust LP File Parser, Writer, and Diff Tool
A robust Rust library and CLI for parsing, analysing, modifying, and writing Linear Programming (LP) files. Built on LALRPOP; grammar lives in lp.lalrpop.
Supported specifications: IBM CPLEX v22.1.1, FICO Xpress, Gurobi, Mosek.
Features
- Parsing & writing — round-trip LP files (parse → modify → write → parse) with configurable formatting
- Problem modification — rename / update / remove objectives, constraints, variables, coefficients, and RHS values
- Variable types — integer, general, bounded, free, semi-continuous
- Analysis — statistics, matrix density, sparsity, coefficient ranges, issue detection with configurable thresholds
- Diff (
difffeature) — structural comparison between two LP files - Serialisation (
serdefeature) — JSON / YAML support - External solvers (
lp-solversfeature) — CBC, Gurobi, CPLEX, GLPK via the lp-solvers crate
Library Usage
Add to Cargo.toml:
[]
= { = "3.0.0", = ["serde", "diff"] } # x-release-please-version
Parse and inspect:
use ;
use Path;
let content = parse_file?;
let problem = parse?;
println!;
Modify and write:
use ;
let mut problem = parse?;
problem.update_objective_coefficient?;
problem.rename_objective?;
problem.update_constraint_coefficient?;
problem.update_constraint_rhs?;
problem.rename_variable?;
problem.update_variable_type?;
write?;
Available modification methods on LpProblem: update_objective_coefficient, rename_objective, remove_objective, update_constraint_coefficient, update_constraint_rhs, rename_constraint, remove_constraint, rename_variable, update_variable_type, remove_variable.
Writer options: write_lp_string_with_options(&problem, &LpWriterOptions { include_problem_name, max_line_length, decimal_precision, include_section_spacing }).
Command-Line Interface (lp_parser)
Install
# Or from source
&&
Global options
| Flag | Description |
|---|---|
-v, --verbose |
Increase output verbosity (repeatable) |
-q, --quiet |
Suppress non-essential output |
-h, --help / -V, --version |
Print help / version |
parse — display file structure
| Option | Default | Description |
|---|---|---|
<FILE> |
— | Path to the LP file (required) |
-o, --output <PATH> |
stdout | Write output to file |
-f, --format <FMT> |
text |
text, json (serde), yaml (serde) |
--pretty |
off | Pretty-print JSON/YAML |
info — summary statistics
Adds to the parse options:
| Option | Description |
|---|---|
--variables |
List all variables with their types |
--constraints |
List all constraints |
--objectives |
List all objectives |
analyze — structural analysis & issue detection
Adds to the parse options:
| Option | Default | Description |
|---|---|---|
--issues-only |
off | Skip full analysis; show warnings/errors only |
--large-coeff-threshold <F> |
1e9 |
Warn on coefficients larger than this |
--small-coeff-threshold <F> |
1e-9 |
Warn on coefficients smaller than this |
--ratio-threshold <F> |
1e6 |
Warn on coefficient scaling ratios above this |
summary:
variables:
constraints:
coefficients:
issues:
diff — compare two LP files (requires diff feature)
| Option | Default | Description |
|---|---|---|
<FILE1> <FILE2> |
— | Base and comparison files |
-o, --output <PATH> |
stdout | Write output to file |
-f, --format <FMT> |
text |
text, json, yaml |
--pretty |
off | Pretty-print structured output |
--abs-tol <F> |
0.0 |
Absolute tolerance for numeric comparisons |
--rel-tol <F> |
0.0 |
Relative tolerance: ` |
--rename <PATTERN> <REPL> |
— | Regex rewrite applied to names in both files before matching; repeatable |
convert — translate to another format
| Option | Default | Description |
|---|---|---|
<FILE> |
— | Path to the LP file |
-o, --output <PATH> |
stdout | Output file or directory (required for CSV) |
-f, --format <FMT> |
lp |
lp, csv, json, yaml |
--pretty |
off | Pretty-print JSON/YAML |
--precision <N> |
6 |
Decimal precision for numbers |
--max-line-length <N> |
80 |
Line-wrap threshold for LP output |
--no-problem-name |
off | Omit problem-name comment in LP output |
--compact |
off | No section spacing |
solve — run an external solver (requires lp-solvers feature)
| Option | Default | Description |
|---|---|---|
<FILE> |
— | Path to the LP file |
-s, --solver <NAME> |
cbc |
cbc, gurobi, cplex, glpk |
-o, --output <PATH> |
stdout | Write solution to file |
-f, --format <FMT> |
text |
text, json, yaml |
--pretty |
off | Pretty-print structured output |
The selected solver binary must be installed on your PATH. The compatibility layer does not support multiple objectives (errors), strict inequalities (<, >), or SOS constraints (ignored with a warning).
Interactive TUI Diff Viewer (lp_diff)
A terminal UI for comparing LP/MPS files with coefficient-level side-by-side diffs, fuzzy search, filtering, and integrated HiGHS solving. Built with ratatui.
Tolerance & rename (parity with lp_parser diff)
lp_diff accepts the same name-rewrite and numeric-tolerance flags as the CLI diff command. Active options are shown on the Summary panel (and in --summary output) so results are reproducible.
| Option | Default | Description |
|---|---|---|
--abs-tol <F> |
0.0 |
Absolute tolerance for RHS & coefficient comparisons |
--rel-tol <F> |
0.0 |
Relative tolerance: ` |
--rename <PATTERN> <REPL> |
— | Regex rewrite applied to names in both files before matching; repeatable |
# Collapse indexed names (e.g. x[1,2,foo] / x[9,9,baz] → x[idx]) so structural diffs survive renumbering
# Hide near-equal RHS/coefficient drift
# Combine with --summary for scripting
Highlights: three-panel layout, four sections (Summary / Variables / Constraints / Objectives), filtering (a/+/-/m), telescope-style search (fuzzy, r: regex, s: substring), HiGHS solve-and-compare (S), vim-style navigation and jumplist, clipboard yank (y/Y), CSV export (w), ? for full help.
See tui/README.md for the complete reference.
Development
Test data sources: Jplex, LPWriter.jl, Lp-Parser.
Contributing
Contributions are welcome — please open a Pull Request.