use crate::constraints::props::PropId;
use crate::search::Space;
use crate::variables::{Vars, Val};
use crate::variables::views::View;
pub trait Mode: core::fmt::Debug {
fn on_branch(&self, _: &mut Space) -> impl Iterator<Item = PropId> {
core::iter::empty()
}
fn on_solution(&mut self, _vars: &Vars) {}
fn lp_objective(&self) -> Option<(crate::variables::VarId, bool)> {
None
}
}
#[derive(Debug)]
pub struct Enumerate;
impl Mode for Enumerate {}
#[derive(Debug)]
pub struct Minimize<V> {
objective: V,
minimum_opt: Option<Val>,
}
impl<V: View> Minimize<V> {
pub const fn new(objective: V) -> Self {
Self {
objective,
minimum_opt: None,
}
}
}
impl<V: View> Mode for Minimize<V> {
fn on_branch(&self, space: &mut Space) -> impl Iterator<Item = PropId> {
if let Some(minimum) = self.minimum_opt {
let prop_id = space.props.less_than(self.objective, minimum);
Some(prop_id).into_iter()
} else {
None.into_iter()
}
}
fn on_solution(&mut self, vars: &Vars) {
self.minimum_opt = Some(self.objective.min_raw(vars));
}
fn lp_objective(&self) -> Option<(crate::variables::VarId, bool)> {
use std::any::TypeId;
let type_id = TypeId::of::<V>();
if type_id == TypeId::of::<crate::variables::VarId>() {
let var_id = unsafe { *(&self.objective as *const V as *const crate::variables::VarId) };
return Some((var_id, true)); }
if type_id == TypeId::of::<crate::variables::views::Opposite<crate::variables::VarId>>() {
let var_id = unsafe { *(&self.objective as *const V as *const crate::variables::VarId) };
return Some((var_id, false)); }
None
}
}