1use crate::clause::ClauseId;
12use crate::literal::Var;
13#[allow(unused_imports)]
14use crate::prelude::*;
15
16#[derive(Debug, Clone, Default)]
18pub struct ActivityStats {
19 pub total_bumps: u64,
21 pub total_decays: u64,
23 pub rescales: u64,
25 pub current_increment: f64,
27}
28
29impl ActivityStats {
30 pub fn display(&self) {
32 println!("Activity Manager Statistics:");
33 println!(" Total bumps: {}", self.total_bumps);
34 println!(" Total decays: {}", self.total_decays);
35 println!(" Rescales: {}", self.rescales);
36 println!(" Current increment: {:.2e}", self.current_increment);
37 }
38}
39
40#[derive(Debug)]
44pub struct VariableActivityManager {
45 activities: Vec<f64>,
47 increment: f64,
49 decay: f64,
51 rescale_threshold: f64,
53 stats: ActivityStats,
55}
56
57impl Default for VariableActivityManager {
58 fn default() -> Self {
59 Self::new()
60 }
61}
62
63impl VariableActivityManager {
64 #[must_use]
68 pub fn new() -> Self {
69 Self::with_decay(0.95)
70 }
71
72 #[must_use]
78 pub fn with_decay(decay: f64) -> Self {
79 Self {
80 activities: Vec::new(),
81 increment: 1.0,
82 decay: decay.clamp(0.0, 1.0),
83 rescale_threshold: 1e100,
84 stats: ActivityStats {
85 current_increment: 1.0,
86 ..Default::default()
87 },
88 }
89 }
90
91 pub fn resize(&mut self, num_vars: usize) {
93 self.activities.resize(num_vars, 0.0);
94 }
95
96 pub fn bump(&mut self, var: Var) {
98 let idx = var.index();
99
100 if idx >= self.activities.len() {
102 self.activities.resize(idx + 1, 0.0);
103 }
104
105 self.activities[idx] += self.increment;
106 self.stats.total_bumps += 1;
107
108 if self.activities[idx] > self.rescale_threshold {
110 self.rescale();
111 }
112 }
113
114 pub fn decay(&mut self) {
116 self.increment /= self.decay;
117 self.stats.total_decays += 1;
118 self.stats.current_increment = self.increment;
119
120 if self.increment > self.rescale_threshold {
122 self.rescale();
123 }
124 }
125
126 fn rescale(&mut self) {
128 const RESCALE_FACTOR: f64 = 1e-100;
129
130 for activity in &mut self.activities {
131 *activity *= RESCALE_FACTOR;
132 }
133 self.increment *= RESCALE_FACTOR;
134 self.stats.rescales += 1;
135 self.stats.current_increment = self.increment;
136 }
137
138 #[must_use]
140 pub fn activity(&self, var: Var) -> f64 {
141 let idx = var.index();
142 if idx < self.activities.len() {
143 self.activities[idx]
144 } else {
145 0.0
146 }
147 }
148
149 pub fn set_activity(&mut self, var: Var, activity: f64) {
151 let idx = var.index();
152 if idx >= self.activities.len() {
153 self.activities.resize(idx + 1, 0.0);
154 }
155 self.activities[idx] = activity;
156 }
157
158 #[must_use]
160 pub fn activities(&self) -> &[f64] {
161 &self.activities
162 }
163
164 #[must_use]
166 pub fn stats(&self) -> &ActivityStats {
167 &self.stats
168 }
169
170 pub fn reset(&mut self) {
172 for activity in &mut self.activities {
173 *activity = 0.0;
174 }
175 self.increment = 1.0;
176 self.stats = ActivityStats {
177 current_increment: 1.0,
178 ..Default::default()
179 };
180 }
181}
182
183#[derive(Debug)]
187pub struct ClauseActivityManager {
188 activities: Vec<f64>,
190 increment: f64,
192 decay: f64,
194 rescale_threshold: f64,
196 stats: ActivityStats,
198}
199
200impl Default for ClauseActivityManager {
201 fn default() -> Self {
202 Self::new()
203 }
204}
205
206impl ClauseActivityManager {
207 #[must_use]
211 pub fn new() -> Self {
212 Self::with_decay(0.999)
213 }
214
215 #[must_use]
217 pub fn with_decay(decay: f64) -> Self {
218 Self {
219 activities: Vec::new(),
220 increment: 1.0,
221 decay: decay.clamp(0.0, 1.0),
222 rescale_threshold: 1e20,
223 stats: ActivityStats {
224 current_increment: 1.0,
225 ..Default::default()
226 },
227 }
228 }
229
230 pub fn bump(&mut self, clause_id: ClauseId) {
232 let idx = clause_id.0 as usize;
233
234 if idx >= self.activities.len() {
236 self.activities.resize(idx + 1, 0.0);
237 }
238
239 self.activities[idx] += self.increment;
240 self.stats.total_bumps += 1;
241
242 if self.activities[idx] > self.rescale_threshold {
243 self.rescale();
244 }
245 }
246
247 pub fn decay(&mut self) {
249 self.increment /= self.decay;
250 self.stats.total_decays += 1;
251 self.stats.current_increment = self.increment;
252
253 if self.increment > self.rescale_threshold {
254 self.rescale();
255 }
256 }
257
258 fn rescale(&mut self) {
260 const RESCALE_FACTOR: f64 = 1e-20;
261
262 for activity in &mut self.activities {
263 *activity *= RESCALE_FACTOR;
264 }
265 self.increment *= RESCALE_FACTOR;
266 self.stats.rescales += 1;
267 self.stats.current_increment = self.increment;
268 }
269
270 #[must_use]
272 pub fn activity(&self, clause_id: ClauseId) -> f64 {
273 let idx = clause_id.0 as usize;
274 if idx < self.activities.len() {
275 self.activities[idx]
276 } else {
277 0.0
278 }
279 }
280
281 pub fn set_activity(&mut self, clause_id: ClauseId, activity: f64) {
283 let idx = clause_id.0 as usize;
284 if idx >= self.activities.len() {
285 self.activities.resize(idx + 1, 0.0);
286 }
287 self.activities[idx] = activity;
288 }
289
290 #[must_use]
292 pub fn stats(&self) -> &ActivityStats {
293 &self.stats
294 }
295
296 pub fn reset(&mut self) {
298 self.activities.clear();
299 self.increment = 1.0;
300 self.stats = ActivityStats {
301 current_increment: 1.0,
302 ..Default::default()
303 };
304 }
305}
306
307#[cfg(test)]
308mod tests {
309 use super::*;
310
311 #[test]
312 fn test_variable_activity_manager_creation() {
313 let manager = VariableActivityManager::new();
314 assert_eq!(manager.decay, 0.95);
315 assert_eq!(manager.increment, 1.0);
316 }
317
318 #[test]
319 fn test_bump_variable() {
320 let mut manager = VariableActivityManager::new();
321 manager.resize(10);
322
323 manager.bump(Var::new(0));
324 assert_eq!(manager.activity(Var::new(0)), 1.0);
325
326 manager.bump(Var::new(0));
327 assert_eq!(manager.activity(Var::new(0)), 2.0);
328 }
329
330 #[test]
331 fn test_decay_variable() {
332 let mut manager = VariableActivityManager::with_decay(0.5);
333 manager.resize(10);
334
335 manager.bump(Var::new(0));
336 let initial_activity = manager.activity(Var::new(0));
337
338 manager.decay();
339 manager.bump(Var::new(1));
340
341 assert!(manager.activity(Var::new(1)) > initial_activity);
343 assert_eq!(manager.stats().total_decays, 1);
344 }
345
346 #[test]
347 fn test_rescale_variable() {
348 let mut manager = VariableActivityManager::new();
349 manager.resize(10);
350 manager.rescale_threshold = 10.0; for _ in 0..20 {
354 manager.bump(Var::new(0));
355 }
356
357 assert!(manager.stats().rescales > 0);
359 assert!(manager.activity(Var::new(0)) < 100.0);
360 }
361
362 #[test]
363 fn test_set_activity() {
364 let mut manager = VariableActivityManager::new();
365 manager.resize(10);
366
367 manager.set_activity(Var::new(0), 42.0);
368 assert_eq!(manager.activity(Var::new(0)), 42.0);
369 }
370
371 #[test]
372 fn test_reset_variable() {
373 let mut manager = VariableActivityManager::new();
374 manager.resize(10);
375
376 manager.bump(Var::new(0));
377 manager.decay();
378
379 manager.reset();
380
381 assert_eq!(manager.activity(Var::new(0)), 0.0);
382 assert_eq!(manager.increment, 1.0);
383 assert_eq!(manager.stats().total_bumps, 0);
384 }
385
386 #[test]
387 fn test_clause_activity_manager_creation() {
388 let manager = ClauseActivityManager::new();
389 assert_eq!(manager.decay, 0.999);
390 }
391
392 #[test]
393 fn test_bump_clause() {
394 let mut manager = ClauseActivityManager::new();
395
396 manager.bump(ClauseId(0));
397 assert_eq!(manager.activity(ClauseId(0)), 1.0);
398
399 manager.bump(ClauseId(0));
400 assert_eq!(manager.activity(ClauseId(0)), 2.0);
401 }
402
403 #[test]
404 fn test_decay_clause() {
405 let mut manager = ClauseActivityManager::with_decay(0.5);
406
407 manager.bump(ClauseId(0));
408 manager.decay();
409 manager.bump(ClauseId(1));
410
411 assert!(manager.activity(ClauseId(1)) > manager.activity(ClauseId(0)));
412 }
413
414 #[test]
415 fn test_clause_rescale() {
416 let mut manager = ClauseActivityManager::new();
417 manager.rescale_threshold = 5.0;
418
419 for _ in 0..10 {
420 manager.bump(ClauseId(0));
421 }
422
423 assert!(manager.stats().rescales > 0);
424 }
425
426 #[test]
427 fn test_reset_clause() {
428 let mut manager = ClauseActivityManager::new();
429
430 manager.bump(ClauseId(0));
431 manager.reset();
432
433 assert_eq!(manager.activity(ClauseId(0)), 0.0);
434 assert_eq!(manager.increment, 1.0);
435 }
436}