mod analyze;
mod emit_expr;
mod header;
mod options;
mod permute;
mod segments;
mod writer;
pub use options::{
Complementarity, DefinedVar, ImportedFunction, NlFormat, SuffixData, SuffixFlavour, SuffixKind,
WriteOptions,
};
use std::io::Write;
use std::path::Path;
use oximo_core::Model;
use crate::error::IoError;
use writer::Writer;
pub fn write_nl<W: Write>(model: &Model, out: &mut W) -> Result<(), IoError> {
write_nl_with(model, out, &WriteOptions::default())
}
pub fn to_nl_string(model: &Model) -> Result<String, IoError> {
to_nl_string_with(model, &WriteOptions::default())
}
pub fn write_nl_with<W: Write>(
model: &Model,
out: &mut W,
opts: &WriteOptions,
) -> Result<(), IoError> {
let vars = model.variables();
let constraints = model.constraints();
let objective = model.try_objective().map_err(|_| IoError::NoObjective)?;
let arena = model.arena();
let analysis =
analyze::Analysis::build(&arena, &vars, &constraints, &objective, opts.nonfinite_strings)?;
let perm = permute::Permutation::build(&vars, &analysis);
let stats = header::Stats::build(&vars, &constraints, &analysis, &perm, opts);
let mut w = Writer::new(out, opts);
header::write_header(&mut w, model, &stats, opts)?;
segments::write_segments(
&mut w,
&arena,
&vars,
&constraints,
&objective,
&analysis,
&perm,
&stats,
opts,
)?;
Ok(())
}
pub fn to_nl_string_with(model: &Model, opts: &WriteOptions) -> Result<String, IoError> {
if opts.format == NlFormat::Binary {
return Err(IoError::BinaryToString);
}
let mut buf = Vec::new();
write_nl_with(model, &mut buf, opts)?;
String::from_utf8(buf).map_err(|_| IoError::BinaryToString)
}
pub fn write_nl_files(model: &Model, stub: &Path, opts: &WriteOptions) -> Result<(), IoError> {
let nl_path = stub.with_extension("nl");
{
let mut f = std::fs::File::create(&nl_path)?;
write_nl_with(model, &mut f, opts)?;
}
if opts.aux_files {
write_aux_files(model, stub, opts.nonfinite_strings)?;
}
Ok(())
}
fn write_aux_files(model: &Model, stub: &Path, nonfinite_strings: bool) -> Result<(), IoError> {
let vars = model.variables();
let constraints = model.constraints();
let objective = model.try_objective().map_err(|_| IoError::NoObjective)?;
let arena = model.arena();
let analysis =
analyze::Analysis::build(&arena, &vars, &constraints, &objective, nonfinite_strings)?;
let perm = permute::Permutation::build(&vars, &analysis);
let row_path = stub.with_extension("row");
{
let mut f = std::fs::File::create(&row_path)?;
for &orig in &perm.con_order {
writeln!(f, "{}", constraints[orig].name)?;
}
writeln!(f, "{}", model.name)?;
}
let col_path = stub.with_extension("col");
{
let mut f = std::fs::File::create(&col_path)?;
for &vid in &perm.var_order {
writeln!(f, "{}", vars[vid.index()].name)?;
}
}
Ok(())
}