use std::fmt;
use std::ops::Mul;
use std::ops::Not;
use relp_num::NonZeroSign;
use crate::data::linear_program::solution::Solution;
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum InequalityRelation {
Less,
Greater,
}
impl From<InequalityRelation> for ConstraintRelation {
fn from(relation: InequalityRelation) -> Self {
match relation {
InequalityRelation::Less => Self::Less,
InequalityRelation::Greater => Self::Greater
}
}
}
#[allow(missing_docs)]
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum ConstraintRelation {
Less,
Equal,
Greater,
}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum RangedConstraintRelation<F> {
Equal,
Range(F),
Less,
Greater,
}
impl<F> From<InequalityRelation> for RangedConstraintRelation<F> {
fn from(relation: InequalityRelation) -> Self {
match relation {
InequalityRelation::Less => Self::Less,
InequalityRelation::Greater => Self::Greater,
}
}
}
impl<F> From<ConstraintRelation> for RangedConstraintRelation<F> {
fn from(relation: ConstraintRelation) -> Self {
match relation {
ConstraintRelation::Less => Self::Less,
ConstraintRelation::Equal => Self::Equal,
ConstraintRelation::Greater => Self::Greater,
}
}
}
impl<F: fmt::Display> fmt::Display for RangedConstraintRelation<F> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
RangedConstraintRelation::Less => f.write_str("<="),
RangedConstraintRelation::Equal => f.write_str("=="),
RangedConstraintRelation::Greater => f.write_str(">="),
RangedConstraintRelation::Range(r) => write!(f, "={}=", r),
}
}
}
pub enum RangedConstraintRelationKind {
Equal,
Range,
Less,
Greater,
}
impl<F> From<&RangedConstraintRelation<F>> for RangedConstraintRelationKind {
fn from(constraint: &RangedConstraintRelation<F>) -> Self {
match constraint {
RangedConstraintRelation::Equal => Self::Equal,
RangedConstraintRelation::Range(_) => Self::Range,
RangedConstraintRelation::Less => Self::Less,
RangedConstraintRelation::Greater => Self::Greater,
}
}
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub enum BoundDirection {
Lower,
Upper,
}
impl Not for BoundDirection {
type Output = Self;
fn not(self) -> Self::Output {
match self {
Self::Lower => Self::Upper,
Self::Upper => Self::Lower,
}
}
}
impl Mul<NonZeroSign> for BoundDirection {
type Output = Self;
fn mul(self, other: NonZeroSign) -> Self::Output {
match (self, other) {
(Self::Upper, NonZeroSign::Positive) | (Self::Lower, NonZeroSign::Negative) => Self::Upper,
(Self::Lower, NonZeroSign::Positive) | (Self::Upper, NonZeroSign::Negative) => Self::Lower,
}
}
}
#[allow(missing_docs)]
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum VariableType {
Continuous,
Integer,
}
impl Not for VariableType {
type Output = VariableType;
fn not(self) -> VariableType {
match self {
VariableType::Continuous => VariableType::Integer,
VariableType::Integer => VariableType::Continuous,
}
}
}
#[allow(missing_docs)]
#[derive(Debug, Eq, PartialEq)]
pub enum LinearProgramType<F> {
FiniteOptimum(Solution<F>),
Infeasible,
Unbounded,
}
#[allow(missing_docs)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Objective {
Maximize,
Minimize,
}
impl Default for Objective {
fn default() -> Self {
Objective::Minimize
}
}
#[cfg(test)]
mod test {
use relp_num::{NonZeroSign, Sign};
use crate::data::linear_program::elements::BoundDirection;
#[test]
fn test_mul() {
assert_eq!(BoundDirection::Lower * NonZeroSign::Positive, BoundDirection::Lower);
assert_eq!(BoundDirection::Upper * NonZeroSign::Positive, BoundDirection::Upper);
assert_eq!(!BoundDirection::Lower * NonZeroSign::Positive, BoundDirection::Upper);
assert_eq!(BoundDirection::Lower * Sign::Positive.into(), BoundDirection::Lower);
assert_eq!(BoundDirection::Upper * Sign::Positive.into(), BoundDirection::Upper);
assert_eq!(!BoundDirection::Lower * Sign::Positive.into(), BoundDirection::Upper);
}
}