solverforge_solver/scope/
step.rs1use solverforge_core::domain::PlanningSolution;
4use solverforge_scoring::Director;
5
6use crate::heuristic::r#move::Move;
7
8use super::solver::{PendingControl, ProgressCallback};
9use super::PhaseScope;
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12pub(crate) enum StepControlPolicy {
13 ObserveConfigLimits,
14 CompleteMandatoryConstruction,
15}
16
17pub struct StepScope<'t, 'a, 'b, S: PlanningSolution, D: Director<S>, BestCb = ()> {
27 phase_scope: &'a mut PhaseScope<'t, 'b, S, D, BestCb>,
29 step_index: u64,
31 step_score: Option<S::Score>,
33 control_policy: StepControlPolicy,
34}
35
36impl<'t, 'a, 'b, S: PlanningSolution, D: Director<S>, BestCb: ProgressCallback<S>>
37 StepScope<'t, 'a, 'b, S, D, BestCb>
38{
39 pub fn new(phase_scope: &'a mut PhaseScope<'t, 'b, S, D, BestCb>) -> Self {
40 Self::new_with_control_policy(phase_scope, StepControlPolicy::ObserveConfigLimits)
41 }
42
43 pub(crate) fn new_with_control_policy(
44 phase_scope: &'a mut PhaseScope<'t, 'b, S, D, BestCb>,
45 control_policy: StepControlPolicy,
46 ) -> Self {
47 let step_index = phase_scope.step_count();
48 Self {
49 phase_scope,
50 step_index,
51 step_score: None,
52 control_policy,
53 }
54 }
55
56 pub fn step_index(&self) -> u64 {
57 self.step_index
58 }
59
60 pub fn step_score(&self) -> Option<&S::Score> {
61 self.step_score.as_ref()
62 }
63
64 pub(crate) fn control_policy(&self) -> StepControlPolicy {
65 self.control_policy
66 }
67
68 pub(crate) fn pending_control(&self) -> PendingControl {
69 match self.control_policy {
70 StepControlPolicy::ObserveConfigLimits => {
71 self.phase_scope.solver_scope().pending_control()
72 }
73 StepControlPolicy::CompleteMandatoryConstruction => self
74 .phase_scope
75 .solver_scope()
76 .mandatory_construction_pending_control(),
77 }
78 }
79
80 pub fn set_step_score(&mut self, score: S::Score)
81 where
82 S::Score: Copy,
83 {
84 self.phase_scope.solver_scope_mut().set_current_score(score);
85 self.step_score = Some(score);
86 }
87
88 pub fn complete(&mut self) {
90 self.phase_scope.increment_step_count();
91 self.phase_scope.solver_scope_mut().pause_if_requested();
92 }
93
94 pub fn phase_scope(&self) -> &PhaseScope<'t, 'b, S, D, BestCb> {
95 self.phase_scope
96 }
97
98 pub fn phase_scope_mut(&mut self) -> &mut PhaseScope<'t, 'b, S, D, BestCb> {
99 self.phase_scope
100 }
101
102 pub fn score_director(&self) -> &D {
103 self.phase_scope.score_director()
104 }
105
106 pub(crate) fn score_director_mut(&mut self) -> &mut D {
107 self.phase_scope.score_director_mut()
108 }
109
110 pub fn mutate<T, F>(&mut self, mutate: F) -> T
111 where
112 F: FnOnce(&mut D) -> T,
113 {
114 self.phase_scope.mutate(mutate)
115 }
116
117 pub(crate) fn apply_committed_move<M>(&mut self, mov: &M)
118 where
119 M: Move<S>,
120 {
121 self.phase_scope
122 .solver_scope_mut()
123 .apply_committed_move(mov);
124 }
125
126 pub(crate) fn apply_committed_change<F>(&mut self, change: F)
127 where
128 F: FnOnce(&mut D),
129 {
130 self.phase_scope
131 .solver_scope_mut()
132 .apply_committed_change(change);
133 }
134
135 pub fn calculate_score(&mut self) -> S::Score {
137 self.phase_scope.calculate_score()
138 }
139}