use crate::{
constraint::RemovedReason,
parse::{as_constraint_id, as_variable_id, Parse, ParseError, RawParseError},
v1, Constraint, ConstraintID, DecisionVariable, VariableID,
};
use std::collections::{BTreeMap, BTreeSet};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Sos1 {
pub binary_constraint_id: ConstraintID,
pub big_m_constraint_ids: BTreeSet<ConstraintID>,
pub variables: BTreeSet<VariableID>,
}
impl Parse for v1::Sos1 {
type Output = Sos1;
type Context = (
BTreeMap<VariableID, DecisionVariable>,
BTreeMap<ConstraintID, Constraint>,
BTreeMap<ConstraintID, (Constraint, RemovedReason)>,
);
fn parse(
self,
(decision_variable, constraints, removed_constraints): &Self::Context,
) -> Result<Self::Output, ParseError> {
let message = "ommx.v1.Sos1";
let binary_constraint_id =
as_constraint_id(constraints, removed_constraints, self.binary_constraint_id)
.map_err(|e| e.context(message, "binary_constraint_id"))?;
let mut big_m_constraint_ids = BTreeSet::new();
for id in &self.big_m_constraint_ids {
let id = as_constraint_id(constraints, removed_constraints, *id)
.map_err(|e| e.context(message, "big_m_constraint_ids"))?;
if !big_m_constraint_ids.insert(id) {
return Err(RawParseError::InvalidInstance(format!(
"Non-unique constraint ID is found where uniqueness is required: {id:?}"
))
.context(message, "big_m_constraint_ids"));
}
}
let mut variables = BTreeSet::new();
for id in &self.decision_variables {
let id = as_variable_id(decision_variable, *id)
.map_err(|e| e.context(message, "decision_variables"))?;
if !variables.insert(id) {
return Err(RawParseError::InvalidInstance(format!(
"Non-unique variable ID is found where uniqueness is required: {id:?}"
))
.context(message, "decision_variables"));
}
}
Ok(Sos1 {
binary_constraint_id,
big_m_constraint_ids,
variables,
})
}
}