1use std::ops::{Index, IndexMut};
3
4use keyed_priority_queue::KeyedPriorityQueue;
5use ordered_float::OrderedFloat;
6
7use crate::constants::{
8 DEFAULT_VAR_DECAY, DEFAULT_VAR_DECAY_INC, DEFAULT_VAR_INC, INIT_PHASE, MAX_VAR_DECAY,
9};
10
11#[derive(Debug, Clone, Copy, Default)]
18pub struct Variable {
19 pub level: usize,
21 pub trail_index: usize,
23 pub reason: Option<usize>,
28}
29
30pub type Literal = isize;
32
33#[derive(Debug, Clone, Default)]
34pub struct Clause {
40 lbd: u32,
42 literals: Vec<Literal>,
44 garbage: bool,
46}
47
48#[cfg_attr(doc, aquamarine::aquamarine)]
64#[derive(Debug, Clone, Default, Copy)]
65pub struct Watches {
66 pub clause_id: usize,
67 pub blocker: Literal,
68}
69
70pub struct ActivityTable {
84 pq: KeyedPriorityQueue<usize, OrderedFloat<f64>>,
85 activities: Vec<f64>,
86 var_inc: f64,
87 var_decay: f64,
88}
89
90pub struct Phases {
96 target_phase: Vec<bool>,
98 saved_phases: Vec<bool>,
100}
101
102impl Clause {
103 pub fn new() -> Self {
105 Self { lbd: 0, literals: Vec::new(), garbage: false }
106 }
107
108 pub fn with_literals(mut self, literals: Vec<Literal>) -> Self {
110 self.literals = literals;
111 self.literals.sort_by_key(|l1| l1.unsigned_abs());
112 self
113 }
114
115 pub fn with_ordered_literals(mut self, literals: Vec<Literal>) -> Self {
117 self.literals = literals;
118 self
119 }
120
121 pub fn with_lbd(mut self, lbd: u32) -> Self {
123 self.lbd = lbd;
124 self
125 }
126
127 pub fn lbd(&self) -> u32 {
129 self.lbd
130 }
131
132 pub fn literals(&self) -> &[Literal] {
134 &self.literals
135 }
136
137 pub fn garbage(&self) -> bool {
139 self.garbage
140 }
141}
142
143impl IntoIterator for Clause {
144 type Item = Literal;
145 type IntoIter = std::vec::IntoIter<Literal>;
146
147 fn into_iter(self) -> Self::IntoIter {
148 self.literals.into_iter()
149 }
150}
151
152impl<'a> IntoIterator for &'a Clause {
153 type Item = &'a Literal;
154 type IntoIter = std::slice::Iter<'a, Literal>;
155
156 fn into_iter(self) -> Self::IntoIter {
157 self.literals.iter()
158 }
159}
160
161impl Index<usize> for Clause {
162 type Output = Literal;
163
164 fn index(&self, index: usize) -> &Self::Output {
165 &self.literals[index]
166 }
167}
168
169impl IndexMut<usize> for Clause {
170 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
171 &mut self.literals[index]
172 }
173}
174
175impl ActivityTable {
176 pub fn new(max_vars: usize) -> Self {
178 let mut ret = Self {
179 pq: KeyedPriorityQueue::new(),
180 activities: vec![0.0; max_vars + 1],
181 var_inc: DEFAULT_VAR_INC,
182 var_decay: DEFAULT_VAR_DECAY,
183 };
184 for var in 1..=max_vars {
185 ret.pq.push(var, OrderedFloat(0.0));
186 }
187 ret
188 }
189
190 pub fn bump_var_score(&mut self, var_id: usize) {
195 match self.pq.entry(var_id) {
196 keyed_priority_queue::Entry::Occupied(e) => {
197 self.activities[var_id] += self.var_inc;
198 let p = OrderedFloat(self.activities[var_id]);
199 e.set_priority(p);
200 }
201 keyed_priority_queue::Entry::Vacant(e) => {
202 let p = OrderedFloat(self.activities[var_id]);
203 e.set_priority(p);
204 }
205 }
206 }
207
208 #[inline]
209 pub fn decay_inc(&mut self) {
211 self.var_inc /= self.var_decay
212 }
213
214 #[inline]
215 pub fn bump_decay_factor(&mut self) {
217 self.var_decay += DEFAULT_VAR_DECAY_INC;
218 if self.var_decay > MAX_VAR_DECAY {
219 self.var_decay = MAX_VAR_DECAY;
220 }
221 }
222
223 pub fn next_variable<F>(&mut self, not_assigned: &F) -> Option<usize>
227 where
228 F: Fn(usize) -> bool,
229 {
230 while let Some((var_id, _)) = self.pq.pop() {
231 if not_assigned(var_id) {
232 return Some(var_id);
233 }
234 }
235 None
236 }
237}
238
239impl Phases {
240 pub fn new(max_var: usize) -> Self {
242 Self {
243 target_phase: vec![INIT_PHASE; max_var + 1],
244 saved_phases: vec![INIT_PHASE; max_var + 1],
245 }
246 }
247
248 #[cfg_attr(doc, aquamarine::aquamarine)]
264 pub fn decide_phase(&self, var_id: usize, target: bool) -> Literal {
265 if target {
266 return var_id as isize * (if self.target_phase[var_id] { 1 } else { -1 });
267 }
268 var_id as isize * (if self.saved_phases[var_id] { 1 } else { -1 })
269 }
270
271 #[inline]
272 pub fn save_phase_for_variable(&mut self, var_id: usize, phase: bool) {
274 self.saved_phases[var_id] = phase;
275 }
276}