use solverforge_core::score::Score;
use solverforge_core::ConstraintRef;
use super::super::analysis::{ConstraintAnalysis, DetailedConstraintMatch};
pub trait IncrementalConstraint<S, Sc: Score>: Send + Sync {
fn evaluate(&self, solution: &S) -> Sc;
fn match_count(&self, solution: &S) -> usize;
fn initialize(&mut self, solution: &S) -> Sc;
fn on_insert(&mut self, solution: &S, entity_index: usize, descriptor_index: usize) -> Sc;
fn on_retract(&mut self, solution: &S, entity_index: usize, descriptor_index: usize) -> Sc;
fn reset(&mut self);
fn name(&self) -> &str;
fn is_hard(&self) -> bool {
false
}
fn constraint_ref(&self) -> ConstraintRef {
ConstraintRef::new("", self.name())
}
fn get_matches(&self, _solution: &S) -> Vec<DetailedConstraintMatch<Sc>> {
Vec::new()
}
fn weight(&self) -> Sc {
Sc::zero()
}
}
#[derive(Debug, Clone)]
pub struct ConstraintResult<Sc> {
pub name: String,
pub score: Sc,
pub match_count: usize,
pub is_hard: bool,
}
pub trait ConstraintSet<S, Sc: Score>: Send + Sync {
fn evaluate_all(&self, solution: &S) -> Sc;
fn constraint_count(&self) -> usize;
fn evaluate_each(&self, solution: &S) -> Vec<ConstraintResult<Sc>>;
fn evaluate_detailed(&self, solution: &S) -> Vec<ConstraintAnalysis<Sc>>;
fn initialize_all(&mut self, solution: &S) -> Sc;
fn on_insert_all(&mut self, solution: &S, entity_index: usize, descriptor_index: usize) -> Sc;
fn on_retract_all(&mut self, solution: &S, entity_index: usize, descriptor_index: usize) -> Sc;
fn reset_all(&mut self);
}
impl<S: Send + Sync, Sc: Score> ConstraintSet<S, Sc> for () {
#[inline]
fn evaluate_all(&self, _solution: &S) -> Sc {
Sc::zero()
}
#[inline]
fn constraint_count(&self) -> usize {
0
}
#[inline]
fn evaluate_each(&self, _solution: &S) -> Vec<ConstraintResult<Sc>> {
Vec::new()
}
#[inline]
fn evaluate_detailed(&self, _solution: &S) -> Vec<ConstraintAnalysis<Sc>> {
Vec::new()
}
#[inline]
fn initialize_all(&mut self, _solution: &S) -> Sc {
Sc::zero()
}
#[inline]
fn on_insert_all(
&mut self,
_solution: &S,
_entity_index: usize,
_descriptor_index: usize,
) -> Sc {
Sc::zero()
}
#[inline]
fn on_retract_all(
&mut self,
_solution: &S,
_entity_index: usize,
_descriptor_index: usize,
) -> Sc {
Sc::zero()
}
#[inline]
fn reset_all(&mut self) {}
}
macro_rules! impl_constraint_set_for_tuple {
($($idx:tt: $T:ident),+) => {
impl<S, Sc, $($T),+> ConstraintSet<S, Sc> for ($($T,)+)
where
S: Send + Sync,
Sc: Score,
$($T: IncrementalConstraint<S, Sc>,)+
{
#[inline]
fn evaluate_all(&self, solution: &S) -> Sc {
let mut total = Sc::zero();
$(total = total + self.$idx.evaluate(solution);)+
total
}
#[inline]
fn constraint_count(&self) -> usize {
let mut count = 0;
$(let _ = &self.$idx; count += 1;)+
count
}
fn evaluate_each(&self, solution: &S) -> Vec<ConstraintResult<Sc>> {
vec![$(ConstraintResult {
name: self.$idx.name().to_string(),
score: self.$idx.evaluate(solution),
match_count: self.$idx.match_count(solution),
is_hard: self.$idx.is_hard(),
}),+]
}
fn evaluate_detailed(&self, solution: &S) -> Vec<ConstraintAnalysis<Sc>> {
vec![$(ConstraintAnalysis::new(
self.$idx.constraint_ref(),
self.$idx.weight(),
self.$idx.evaluate(solution),
self.$idx.get_matches(solution),
self.$idx.is_hard(),
)),+]
}
#[inline]
fn initialize_all(&mut self, solution: &S) -> Sc {
let mut total = Sc::zero();
$(total = total + self.$idx.initialize(solution);)+
total
}
#[inline]
fn on_insert_all(&mut self, solution: &S, entity_index: usize, descriptor_index: usize) -> Sc {
let mut total = Sc::zero();
$(total = total + self.$idx.on_insert(solution, entity_index, descriptor_index);)+
total
}
#[inline]
fn on_retract_all(&mut self, solution: &S, entity_index: usize, descriptor_index: usize) -> Sc {
let mut total = Sc::zero();
$(total = total + self.$idx.on_retract(solution, entity_index, descriptor_index);)+
total
}
#[inline]
fn reset_all(&mut self) {
$(self.$idx.reset();)+
}
}
};
}
impl_constraint_set_for_tuple!(0: C0);
impl_constraint_set_for_tuple!(0: C0, 1: C1);
impl_constraint_set_for_tuple!(0: C0, 1: C1, 2: C2);
impl_constraint_set_for_tuple!(0: C0, 1: C1, 2: C2, 3: C3);
impl_constraint_set_for_tuple!(0: C0, 1: C1, 2: C2, 3: C3, 4: C4);
impl_constraint_set_for_tuple!(0: C0, 1: C1, 2: C2, 3: C3, 4: C4, 5: C5);
impl_constraint_set_for_tuple!(0: C0, 1: C1, 2: C2, 3: C3, 4: C4, 5: C5, 6: C6);
impl_constraint_set_for_tuple!(0: C0, 1: C1, 2: C2, 3: C3, 4: C4, 5: C5, 6: C6, 7: C7);
impl_constraint_set_for_tuple!(0: C0, 1: C1, 2: C2, 3: C3, 4: C4, 5: C5, 6: C6, 7: C7, 8: C8);
impl_constraint_set_for_tuple!(0: C0, 1: C1, 2: C2, 3: C3, 4: C4, 5: C5, 6: C6, 7: C7, 8: C8, 9: C9);
impl_constraint_set_for_tuple!(0: C0, 1: C1, 2: C2, 3: C3, 4: C4, 5: C5, 6: C6, 7: C7, 8: C8, 9: C9, 10: C10);
impl_constraint_set_for_tuple!(0: C0, 1: C1, 2: C2, 3: C3, 4: C4, 5: C5, 6: C6, 7: C7, 8: C8, 9: C9, 10: C10, 11: C11);
impl_constraint_set_for_tuple!(0: C0, 1: C1, 2: C2, 3: C3, 4: C4, 5: C5, 6: C6, 7: C7, 8: C8, 9: C9, 10: C10, 11: C11, 12: C12);
impl_constraint_set_for_tuple!(0: C0, 1: C1, 2: C2, 3: C3, 4: C4, 5: C5, 6: C6, 7: C7, 8: C8, 9: C9, 10: C10, 11: C11, 12: C12, 13: C13);
impl_constraint_set_for_tuple!(0: C0, 1: C1, 2: C2, 3: C3, 4: C4, 5: C5, 6: C6, 7: C7, 8: C8, 9: C9, 10: C10, 11: C11, 12: C12, 13: C13, 14: C14);
impl_constraint_set_for_tuple!(0: C0, 1: C1, 2: C2, 3: C3, 4: C4, 5: C5, 6: C6, 7: C7, 8: C8, 9: C9, 10: C10, 11: C11, 12: C12, 13: C13, 14: C14, 15: C15);
impl_constraint_set_for_tuple!(0: C0, 1: C1, 2: C2, 3: C3, 4: C4, 5: C5, 6: C6, 7: C7, 8: C8, 9: C9, 10: C10, 11: C11, 12: C12, 13: C13, 14: C14, 15: C15, 16: C16);
impl_constraint_set_for_tuple!(0: C0, 1: C1, 2: C2, 3: C3, 4: C4, 5: C5, 6: C6, 7: C7, 8: C8, 9: C9, 10: C10, 11: C11, 12: C12, 13: C13, 14: C14, 15: C15, 16: C16, 17: C17);
impl_constraint_set_for_tuple!(0: C0, 1: C1, 2: C2, 3: C3, 4: C4, 5: C5, 6: C6, 7: C7, 8: C8, 9: C9, 10: C10, 11: C11, 12: C12, 13: C13, 14: C14, 15: C15, 16: C16, 17: C17, 18: C18);
impl_constraint_set_for_tuple!(0: C0, 1: C1, 2: C2, 3: C3, 4: C4, 5: C5, 6: C6, 7: C7, 8: C8, 9: C9, 10: C10, 11: C11, 12: C12, 13: C13, 14: C14, 15: C15, 16: C16, 17: C17, 18: C18, 19: C19);
impl_constraint_set_for_tuple!(0: C0, 1: C1, 2: C2, 3: C3, 4: C4, 5: C5, 6: C6, 7: C7, 8: C8, 9: C9, 10: C10, 11: C11, 12: C12, 13: C13, 14: C14, 15: C15, 16: C16, 17: C17, 18: C18, 19: C19, 20: C20);
impl_constraint_set_for_tuple!(0: C0, 1: C1, 2: C2, 3: C3, 4: C4, 5: C5, 6: C6, 7: C7, 8: C8, 9: C9, 10: C10, 11: C11, 12: C12, 13: C13, 14: C14, 15: C15, 16: C16, 17: C17, 18: C18, 19: C19, 20: C20, 21: C21);
impl_constraint_set_for_tuple!(0: C0, 1: C1, 2: C2, 3: C3, 4: C4, 5: C5, 6: C6, 7: C7, 8: C8, 9: C9, 10: C10, 11: C11, 12: C12, 13: C13, 14: C14, 15: C15, 16: C16, 17: C17, 18: C18, 19: C19, 20: C20, 21: C21, 22: C22);
impl_constraint_set_for_tuple!(0: C0, 1: C1, 2: C2, 3: C3, 4: C4, 5: C5, 6: C6, 7: C7, 8: C8, 9: C9, 10: C10, 11: C11, 12: C12, 13: C13, 14: C14, 15: C15, 16: C16, 17: C17, 18: C18, 19: C19, 20: C20, 21: C21, 22: C22, 23: C23);
impl_constraint_set_for_tuple!(0: C0, 1: C1, 2: C2, 3: C3, 4: C4, 5: C5, 6: C6, 7: C7, 8: C8, 9: C9, 10: C10, 11: C11, 12: C12, 13: C13, 14: C14, 15: C15, 16: C16, 17: C17, 18: C18, 19: C19, 20: C20, 21: C21, 22: C22, 23: C23, 24: C24);
impl_constraint_set_for_tuple!(0: C0, 1: C1, 2: C2, 3: C3, 4: C4, 5: C5, 6: C6, 7: C7, 8: C8, 9: C9, 10: C10, 11: C11, 12: C12, 13: C13, 14: C14, 15: C15, 16: C16, 17: C17, 18: C18, 19: C19, 20: C20, 21: C21, 22: C22, 23: C23, 24: C24, 25: C25);
impl_constraint_set_for_tuple!(0: C0, 1: C1, 2: C2, 3: C3, 4: C4, 5: C5, 6: C6, 7: C7, 8: C8, 9: C9, 10: C10, 11: C11, 12: C12, 13: C13, 14: C14, 15: C15, 16: C16, 17: C17, 18: C18, 19: C19, 20: C20, 21: C21, 22: C22, 23: C23, 24: C24, 25: C25, 26: C26);
impl_constraint_set_for_tuple!(0: C0, 1: C1, 2: C2, 3: C3, 4: C4, 5: C5, 6: C6, 7: C7, 8: C8, 9: C9, 10: C10, 11: C11, 12: C12, 13: C13, 14: C14, 15: C15, 16: C16, 17: C17, 18: C18, 19: C19, 20: C20, 21: C21, 22: C22, 23: C23, 24: C24, 25: C25, 26: C26, 27: C27);
impl_constraint_set_for_tuple!(0: C0, 1: C1, 2: C2, 3: C3, 4: C4, 5: C5, 6: C6, 7: C7, 8: C8, 9: C9, 10: C10, 11: C11, 12: C12, 13: C13, 14: C14, 15: C15, 16: C16, 17: C17, 18: C18, 19: C19, 20: C20, 21: C21, 22: C22, 23: C23, 24: C24, 25: C25, 26: C26, 27: C27, 28: C28);
impl_constraint_set_for_tuple!(0: C0, 1: C1, 2: C2, 3: C3, 4: C4, 5: C5, 6: C6, 7: C7, 8: C8, 9: C9, 10: C10, 11: C11, 12: C12, 13: C13, 14: C14, 15: C15, 16: C16, 17: C17, 18: C18, 19: C19, 20: C20, 21: C21, 22: C22, 23: C23, 24: C24, 25: C25, 26: C26, 27: C27, 28: C28, 29: C29);
impl_constraint_set_for_tuple!(0: C0, 1: C1, 2: C2, 3: C3, 4: C4, 5: C5, 6: C6, 7: C7, 8: C8, 9: C9, 10: C10, 11: C11, 12: C12, 13: C13, 14: C14, 15: C15, 16: C16, 17: C17, 18: C18, 19: C19, 20: C20, 21: C21, 22: C22, 23: C23, 24: C24, 25: C25, 26: C26, 27: C27, 28: C28, 29: C29, 30: C30);
impl_constraint_set_for_tuple!(0: C0, 1: C1, 2: C2, 3: C3, 4: C4, 5: C5, 6: C6, 7: C7, 8: C8, 9: C9, 10: C10, 11: C11, 12: C12, 13: C13, 14: C14, 15: C15, 16: C16, 17: C17, 18: C18, 19: C19, 20: C20, 21: C21, 22: C22, 23: C23, 24: C24, 25: C25, 26: C26, 27: C27, 28: C28, 29: C29, 30: C30, 31: C31);