Documentation
# mps

A fast MPS parser written in Rust

[![ci](https://github.com/integrated-reasoning/mps/actions/workflows/ci.yml/badge.svg)](https://github.com/integrated-reasoning/mps/actions/workflows/ci.yml)
![docs.rs](https://img.shields.io/docsrs/mps)
[![dependency status](https://deps.rs/repo/github/integrated-reasoning/mps/status.svg)](https://deps.rs/repo/github/integrated-reasoning/mps)
[![license: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE-MIT)
[![codecov](https://codecov.io/github/integrated-reasoning/mps/graph/badge.svg?token=K0GLHFU1ZF)](https://codecov.io/github/integrated-reasoning/mps)
![Docker Image Size (tag)](https://img.shields.io/docker/image-size/integratedreasoning/mps/latest)
[![FlakeHub](https://img.shields.io/endpoint?url=https://flakehub.com/f/integrated-reasoning/mps/badge)](https://flakehub.com/flake/integrated-reasoning/mps)
[![Minimum Stable Rust Version](https://img.shields.io/badge/Rust-1.71.1-blue?color=fc8d62&logo=rust)](https://blog.rust-lang.org/2023/08/03/Rust-1.71.1.html)

## About

`mps` is a parser for the Mathematical Programming System (MPS) file format, commonly used to represent optimization problems.

This crate provides both a library and a CLI for parsing MPS data. Key features include:

- **Configurable Parsing**:
  - Supported feature flags:
    - `trace` - Enhanced debugging and statistics via `nom_tracable` and `nom_locate`.
    - `proptest` - Property testing integrations.
    - `cli` - Command line interface.
- **Robustness**: Extensively tested against [Netlib LP test suite]http://www.netlib.org/lp/data/.
- **Performance**: Benchmarked using [Criterion.rs]https://github.com/bheisler/criterion.rs.

## Examples

**Library**

```rust
use mps::Parser;

let contents = "MPS data...";
match Parser::<f32>::parse(&contents) {
    Ok((_, model)) => { /* use MPS model */ },
    Err(e) => eprintln!("Parsing error: {}", e),
}
```

**CLI**

```bash
$ mps --input-path ./data/netlib/afiro
```

## Usage as a flake

Add `mps` to your `flake.nix`:

```nix
{
  inputs.mps.url = "https://flakehub.com/f/integrated-reasoning/mps/*.tar.gz";

  outputs = { self, mps }: {
    # Use in your outputs
  };
}

```

## Running with Docker

```bash
docker run -it integratedreasoning/mps:latest
```

## Roadmap

### Semantic validation

Conduct semantic validation to uncover potential issues upfront before passing models to the solver.

- Structural checks
  - Detect and flag unreachable constraints that can be automatically satisfied or violated given bounds
  - Identify redundant constraints that are logical duplicates of existing rows
  - Check for dominating constraints that make other constraints redundant
  - Validate presence of slack variables where needed to avoid unboundedness
  - Verify dual feasibility through analyzing bounds, objective, and right hand sides
  - Cross-validate variable objective costs with cost coefficients from other provided perspectives
  - Check for overlapping/duplicated terms across constraints modeling the same logical relationship
  - Identify variables not participating in any constraints, unless intended as free variables
- Numerical checks
  - Check for numerics - flag near zero coefficients that could lead to weak formulations
  - Raise issues with over-aggressive bounds that over-constrain the feasible region undesirably
  - Analyze term sparsity to call out potential compact formulation opportunities
  - Diagnose poor model scaling that could introduce solution inaccuracies
- Logical checks
  - Flag discrete variables implicitly constrained to be continuous due to coefficient assignments
  - Check for logically contradictory bounds on variables that conflict with constraint implications