resolvo/solver/
decision_tracker.rs1use crate::internal::id::{ClauseId, VariableId};
2use crate::solver::{decision::Decision, decision_map::DecisionMap};
3
4#[derive(Default)]
7pub(crate) struct DecisionTracker {
8 map: DecisionMap,
9 stack: Vec<Decision>,
10 propagate_index: usize,
11}
12
13impl DecisionTracker {
14 pub(crate) fn clear(&mut self) {
15 *self = Default::default();
16 }
17
18 #[cfg(feature = "diagnostics")]
19 pub(crate) fn len(&self) -> usize {
20 self.map.len()
21 }
22
23 #[inline(always)]
24 pub(crate) fn assigned_value(&self, variable_id: VariableId) -> Option<bool> {
25 self.map.value(variable_id)
26 }
27
28 pub(crate) fn map(&self) -> &DecisionMap {
29 &self.map
30 }
31
32 pub(crate) fn stack(&self) -> impl DoubleEndedIterator<Item = Decision> + '_ {
33 self.stack.iter().copied()
34 }
35
36 pub(crate) fn level(&self, variable_id: VariableId) -> u32 {
37 self.map.level(variable_id)
38 }
39
40 pub(crate) fn find_clause_for_assignment(&self, variable_id: VariableId) -> Option<ClauseId> {
43 self.stack
44 .iter()
45 .find(|d| d.variable == variable_id)
46 .map(|d| d.derived_from)
47 }
48
49 pub(crate) fn try_add_decision(&mut self, decision: Decision, level: u32) -> Result<bool, ()> {
55 match self.map.value(decision.variable) {
56 None => {
57 self.map.set(decision.variable, decision.value, level);
58 self.stack.push(decision);
59 Ok(true)
60 }
61 Some(value) if value == decision.value => Ok(false),
62 _ => Err(()),
63 }
64 }
65
66 pub(crate) fn undo_until(&mut self, level: u32) {
67 if level == 0 {
68 self.clear();
69 return;
70 }
71
72 while let Some(decision) = self.stack.last() {
73 if self.level(decision.variable) <= level {
74 break;
75 }
76
77 self.undo_last();
78 }
79 }
80
81 pub(crate) fn undo_last(&mut self) -> (Decision, u32) {
82 let decision = self.stack.pop().unwrap();
83 self.map.reset(decision.variable);
84
85 self.propagate_index = self.stack.len();
86
87 let top_decision = self.stack.last().unwrap();
88 (decision, self.map.level(top_decision.variable))
89 }
90
91 pub(crate) fn next_unpropagated(&mut self) -> Option<Decision> {
95 let &decision = self.stack[self.propagate_index..].iter().next()?;
96 self.propagate_index += 1;
97 Some(decision)
98 }
99}