stalmarck_sat/solver/
variable_frequency.rs1use crate::core::formula::TripletVar;
2use std::collections::HashMap;
3
4#[derive(Debug, Default)]
5pub struct VariableFrequency {
6 frequency_map: HashMap<i32, usize>,
8
9 sorted_variables: Vec<(i32, usize)>,
11}
12
13impl VariableFrequency {
14 pub fn new() -> Self {
15 Self::default()
16 }
17
18 pub fn analyze_triplets(&mut self, triplets: &[(TripletVar, TripletVar, TripletVar)]) {
20 self.frequency_map.clear();
21
22 for (a, b, c) in triplets {
23 for triplet_var in [a, b, c] {
24 if let TripletVar::Var(id) = triplet_var {
25 *self.frequency_map.entry(*id).or_insert(0) += 1;
26 }
27 }
28 }
29
30 self.sorted_variables = self
32 .frequency_map
33 .iter()
34 .map(|(&var, &freq)| (var, freq))
35 .collect();
36 self.sorted_variables.sort_by(|a, b| b.1.cmp(&a.1));
37 }
38
39 pub fn get_most_frequent_unassigned(
41 &self,
42 assignments: &HashMap<i32, bool>,
43 original_vars_only: bool,
44 max_original_var: i32,
45 ) -> Option<i32> {
46 for &(var_id, _freq) in &self.sorted_variables {
47 if !assignments.contains_key(&var_id) {
48 if original_vars_only && var_id > max_original_var {
50 continue;
51 }
52 return Some(var_id);
53 }
54 }
55 None
56 }
57
58 pub fn get_triplet_frequency(&self, triplet: &(TripletVar, TripletVar, TripletVar)) -> usize {
60 let (a, b, c) = triplet;
61 let mut score = 0;
62
63 for triplet_var in [a, b, c] {
64 if let TripletVar::Var(id) = triplet_var {
65 score += self.frequency_map.get(id).unwrap_or(&0);
66 }
67 }
68 score
69 }
70
71 pub fn get_potential_deduction_score(
73 &self,
74 triplet: &(TripletVar, TripletVar, TripletVar),
75 ) -> usize {
76 let (a, b, c) = triplet;
77 let base_frequency_score = self.get_triplet_frequency(triplet);
78
79 let mut potential_deductions = 0;
81 if a == b {
82 potential_deductions = 2;
84 } else if b == c {
85 potential_deductions = 1;
87 }
88
89 (1 + potential_deductions) * base_frequency_score
91 }
92}