1use crate::constraint::VarId;
4use crate::domain::Domain;
5use crate::variable::Variable;
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9pub enum Ordering {
10 Chronological,
12 FailFirst,
14 DomWdeg,
16}
17
18pub fn select_variable<D: Domain>(
22 stack: &[VarId],
23 variables: &[Variable<D>],
24 ordering: Ordering,
25 constraint_weights: &[f64],
26 var_constraint_ids: &[Vec<usize>],
27) -> Option<usize> {
28 if stack.is_empty() {
29 return None;
30 }
31
32 match ordering {
33 Ordering::Chronological => Some(stack.len() - 1),
34
35 Ordering::FailFirst => {
36 let mut best_idx = 0;
37 let mut best_size = usize::MAX;
38 for (i, &var) in stack.iter().enumerate() {
39 let sz = variables[var as usize].domain.size();
40 if sz < best_size {
41 best_size = sz;
42 best_idx = i;
43 }
44 }
45 Some(best_idx)
46 }
47
48 Ordering::DomWdeg => {
49 let mut best_idx = 0;
50 let mut best_score = f64::MAX;
51 for (i, &var) in stack.iter().enumerate() {
52 let dom_size = variables[var as usize].domain.size() as f64;
53 let wdeg: f64 = var_constraint_ids[var as usize]
54 .iter()
55 .map(|&cid| constraint_weights[cid])
56 .sum();
57 let score = dom_size / wdeg.max(1e-9);
58 if score < best_score {
59 best_score = score;
60 best_idx = i;
61 }
62 }
63 Some(best_idx)
64 }
65 }
66}