Skip to main content

solverforge_solver/builder/
context.rs

1//! Context types that carry domain function pointers into the builder layer.
2
3use std::marker::PhantomData;
4
5/// Function-pointer context for basic (non-list) variable solvers.
6///
7/// Carries all domain callbacks needed to construct move selectors
8/// without requiring `dyn` or closures.
9pub struct BasicContext<S> {
10    /// Gets the planning variable for entity `i`.
11    pub get_variable: fn(&S, usize) -> Option<usize>,
12    /// Sets the planning variable for entity `i`.
13    pub set_variable: fn(&mut S, usize, Option<usize>),
14    /// All valid values for the variable.
15    pub values: Vec<usize>,
16    /// Descriptor index for the entity collection.
17    pub descriptor_index: usize,
18    /// Variable field name.
19    pub variable_field: &'static str,
20}
21
22impl<S> std::fmt::Debug for BasicContext<S> {
23    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
24        f.debug_struct("BasicContext")
25            .field("descriptor_index", &self.descriptor_index)
26            .field("variable_field", &self.variable_field)
27            .field("values_len", &self.values.len())
28            .finish()
29    }
30}
31
32/// Function-pointer context for list variable solvers.
33///
34/// Carries all domain callbacks and distance meters needed to construct
35/// list move selectors without requiring `dyn` or closures.
36pub struct ListContext<S, V, DM, IDM> {
37    /// Returns the length of the list for entity `i`.
38    pub list_len: fn(&S, usize) -> usize,
39    /// Removes element at `pos` from entity `i`, returning it (returns `None` if out of bounds).
40    pub list_remove: fn(&mut S, usize, usize) -> Option<V>,
41    /// Inserts `val` at `pos` in entity `i`.
42    pub list_insert: fn(&mut S, usize, usize, V),
43    /// Gets element at `pos` in entity `i`.
44    pub list_get: fn(&S, usize, usize) -> Option<V>,
45    /// Replaces element at `pos` in entity `i`.
46    pub list_set: fn(&mut S, usize, usize, V),
47    /// Reverses the segment `[start, end)` in entity `i`.
48    pub list_reverse: fn(&mut S, usize, usize, usize),
49    /// Removes segment `[start, end)` from entity `i`.
50    pub sublist_remove: fn(&mut S, usize, usize, usize) -> Vec<V>,
51    /// Inserts `items` at `pos` in entity `i`.
52    pub sublist_insert: fn(&mut S, usize, usize, Vec<V>),
53    /// Removes element at `pos` from entity `i` for ruin moves (panics if out of bounds).
54    pub ruin_remove: fn(&mut S, usize, usize) -> V,
55    /// Inserts `val` at `pos` in entity `i` for ruin reinsertion.
56    pub ruin_insert: fn(&mut S, usize, usize, V),
57    /// Returns the total number of list owner entities.
58    pub entity_count: fn(&S) -> usize,
59    /// Cross-entity (inter-route) distance meter.
60    pub cross_distance_meter: DM,
61    /// Intra-entity (intra-route) distance meter.
62    pub intra_distance_meter: IDM,
63    /// List variable field name.
64    pub variable_name: &'static str,
65    /// Descriptor index for the list owner entity collection.
66    pub descriptor_index: usize,
67    _phantom: PhantomData<(fn() -> S, fn() -> V)>,
68}
69
70impl<S, V, DM, IDM> ListContext<S, V, DM, IDM> {
71    /// Creates a new list context.
72    #[allow(clippy::too_many_arguments)]
73    pub fn new(
74        list_len: fn(&S, usize) -> usize,
75        list_remove: fn(&mut S, usize, usize) -> Option<V>,
76        list_insert: fn(&mut S, usize, usize, V),
77        list_get: fn(&S, usize, usize) -> Option<V>,
78        list_set: fn(&mut S, usize, usize, V),
79        list_reverse: fn(&mut S, usize, usize, usize),
80        sublist_remove: fn(&mut S, usize, usize, usize) -> Vec<V>,
81        sublist_insert: fn(&mut S, usize, usize, Vec<V>),
82        ruin_remove: fn(&mut S, usize, usize) -> V,
83        ruin_insert: fn(&mut S, usize, usize, V),
84        entity_count: fn(&S) -> usize,
85        cross_distance_meter: DM,
86        intra_distance_meter: IDM,
87        variable_name: &'static str,
88        descriptor_index: usize,
89    ) -> Self {
90        Self {
91            list_len,
92            list_remove,
93            list_insert,
94            list_get,
95            list_set,
96            list_reverse,
97            sublist_remove,
98            sublist_insert,
99            ruin_remove,
100            ruin_insert,
101            entity_count,
102            cross_distance_meter,
103            intra_distance_meter,
104            variable_name,
105            descriptor_index,
106            _phantom: PhantomData,
107        }
108    }
109}
110
111impl<S, V, DM: std::fmt::Debug, IDM: std::fmt::Debug> std::fmt::Debug
112    for ListContext<S, V, DM, IDM>
113{
114    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
115        f.debug_struct("ListContext")
116            .field("variable_name", &self.variable_name)
117            .field("descriptor_index", &self.descriptor_index)
118            .finish()
119    }
120}