Skip to main content

pumpkin_core/optimisation/
solution_callback.rs

1use std::ops::ControlFlow;
2
3use crate::Solver;
4use crate::branching::Brancher;
5use crate::conflict_resolving::ConflictResolver;
6use crate::results::SolutionReference;
7
8/// Called during optimisation with every encountered solution.
9///
10/// The callback can determine whether to proceed optimising or whether to stop by returning a
11/// [`ControlFlow`] value. When [`ControlFlow::Break`] is returned, a value of
12/// [`SolutionCallback::Stop`] can be supplied that will be forwarded to the result of the
13/// optimisation call.
14pub trait SolutionCallback<B: Brancher, R: ConflictResolver> {
15    /// The type of value to return if optimisation should stop.
16    type Stop;
17
18    /// Called when a solution is encountered.
19    fn on_solution_callback(
20        &mut self,
21        solver: &Solver,
22        solution: SolutionReference,
23        brancher: &B,
24        resolver: &R,
25    ) -> ControlFlow<Self::Stop>;
26}
27
28impl<T, B, R, StopData> SolutionCallback<B, R> for T
29where
30    T: FnMut(&Solver, SolutionReference, &B, &R) -> ControlFlow<StopData>,
31    B: Brancher,
32    R: ConflictResolver,
33{
34    type Stop = StopData;
35
36    fn on_solution_callback(
37        &mut self,
38        solver: &Solver,
39        solution: SolutionReference,
40        brancher: &B,
41        resolver: &R,
42    ) -> ControlFlow<Self::Stop> {
43        (self)(solver, solution, brancher, resolver)
44    }
45}
46
47impl<T, StopData, B, R> SolutionCallback<B, R> for Option<T>
48where
49    T: SolutionCallback<B, R, Stop = StopData>,
50    B: Brancher,
51    R: ConflictResolver,
52{
53    type Stop = StopData;
54
55    fn on_solution_callback(
56        &mut self,
57        solver: &Solver,
58        solution: SolutionReference,
59        brancher: &B,
60        resolver: &R,
61    ) -> ControlFlow<Self::Stop> {
62        if let Some(callback) = self {
63            return callback.on_solution_callback(solver, solution, brancher, resolver);
64        }
65
66        ControlFlow::Continue(())
67    }
68}