solverforge_scoring/director/
traits.rs1use solverforge_core::domain::{PlanningSolution, SolutionDescriptor};
4use solverforge_core::ConstraintRef;
5
6use crate::api::constraint_set::ConstraintMetadata;
7
8#[derive(Debug, PartialEq, Eq)]
13pub struct DirectorScoreState<Sc> {
14 pub solution_score: Option<Sc>,
15 pub committed_score: Option<Sc>,
16 pub initialized: bool,
17}
18
19pub trait Director<S: PlanningSolution>: Send {
28 fn working_solution(&self) -> &S;
30
31 fn working_solution_mut(&mut self) -> &mut S;
33
34 fn calculate_score(&mut self) -> S::Score;
36
37 fn fresh_score(&self) -> Option<S::Score> {
39 None
40 }
41
42 fn solution_descriptor(&self) -> &SolutionDescriptor;
44
45 fn clone_working_solution(&self) -> S;
47
48 fn before_variable_changed(&mut self, descriptor_index: usize, entity_index: usize);
50
51 fn after_variable_changed(&mut self, descriptor_index: usize, entity_index: usize);
53
54 fn entity_count(&self, descriptor_index: usize) -> Option<usize>;
56
57 fn total_entity_count(&self) -> Option<usize>;
59
60 fn constraint_metadata(&self) -> Vec<ConstraintMetadata<'_>>;
62
63 fn constraint_is_hard(&self, constraint_ref: &ConstraintRef) -> Option<bool> {
65 let metadata = self.constraint_metadata();
66 metadata
67 .iter()
68 .find(|metadata| metadata.constraint_ref == constraint_ref)
69 .map(|metadata| metadata.is_hard)
70 }
71
72 fn is_incremental(&self) -> bool {
74 false
75 }
76
77 fn snapshot_score_state(&self) -> DirectorScoreState<S::Score> {
80 let solution_score = self.working_solution().score();
81 DirectorScoreState {
82 solution_score,
83 committed_score: solution_score,
84 initialized: solution_score.is_some(),
85 }
86 }
87
88 fn restore_score_state(&mut self, state: DirectorScoreState<S::Score>) {
90 self.working_solution_mut().set_score(state.solution_score);
91 }
92
93 fn reset(&mut self) {}
95}