Skip to main content

solverforge_solver/phase/
sequence.rs

1use std::fmt::{self, Debug};
2
3use solverforge_core::domain::PlanningSolution;
4use solverforge_scoring::Director;
5
6use crate::phase::Phase;
7use crate::scope::{ProgressCallback, SolverScope};
8use crate::stats::CandidateTracePhasePlan;
9
10pub struct PhaseSequence<P> {
11    phases: Vec<P>,
12}
13
14impl<P> PhaseSequence<P> {
15    pub fn new(phases: Vec<P>) -> Self {
16        Self { phases }
17    }
18
19    pub fn phases(&self) -> &[P] {
20        &self.phases
21    }
22
23    pub fn into_phases(self) -> Vec<P> {
24        self.phases
25    }
26}
27
28impl<P: Debug> Debug for PhaseSequence<P> {
29    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
30        f.debug_struct("PhaseSequence")
31            .field("phases", &self.phases)
32            .finish()
33    }
34}
35
36impl<S, D, ProgressCb, P> Phase<S, D, ProgressCb> for PhaseSequence<P>
37where
38    S: PlanningSolution,
39    D: Director<S>,
40    ProgressCb: ProgressCallback<S>,
41    P: Phase<S, D, ProgressCb>,
42{
43    fn solve(&mut self, solver_scope: &mut SolverScope<'_, S, D, ProgressCb>) {
44        for phase in &mut self.phases {
45            phase.solve(solver_scope);
46        }
47    }
48
49    fn phase_type_name(&self) -> &'static str {
50        "PhaseSequence"
51    }
52
53    fn on_solver_terminal(&mut self, solver_scope: &mut SolverScope<'_, S, D, ProgressCb>) {
54        for phase in &mut self.phases {
55            phase.on_solver_terminal(solver_scope);
56        }
57    }
58
59    fn candidate_trace_plan(&self) -> CandidateTracePhasePlan {
60        CandidateTracePhasePlan::known(
61            "solverforge.phase.sequence",
62            [("phase_count", self.phases.len().to_string())],
63            self.phases
64                .iter()
65                .map(|phase| phase.candidate_trace_plan())
66                .collect(),
67        )
68    }
69}