use selen::prelude::*;
use selen::variables::Val;
#[test]
fn test_count_with_constant_target_via_val() {
let mut m = Model::default();
let vars = vec![m.int(1, 5), m.int(1, 5), m.int(1, 5)];
let count = m.int(0, 3);
m.count(&vars, Val::int(3), count);
if let Ok(solution) = m.solve() {
let c = solution[count].as_int().unwrap();
let matches = vars.iter()
.filter(|&&v| solution[v].as_int().unwrap() == 3)
.count();
assert_eq!(c as usize, matches, "Count should match actual occurrences");
}
}
#[test]
fn test_count_with_variable_target_unchanged() {
let mut m = Model::default();
let vars = vec![m.int(1, 5), m.int(1, 5), m.int(1, 5)];
let var_target = m.int(1, 5); let count = m.int(0, 3);
m.count(&vars, var_target, count);
if let Ok(solution) = m.solve() {
let target_val = solution[var_target].as_int().unwrap();
let c = solution[count].as_int().unwrap();
let matches = vars.iter()
.filter(|&&v| solution[v].as_int().unwrap() == target_val)
.count();
assert_eq!(c as usize, matches, "Count should match actual occurrences");
}
}
#[test]
fn test_count_with_computed_target_expression() {
let mut m = Model::default();
let vars = vec![m.int(1, 5), m.int(1, 5), m.int(1, 5)];
let x = m.int(1, 3);
let computed_target = m.add(x, Val::int(1)); let count = m.int(0, 3);
m.count(&vars, computed_target, count);
if let Ok(solution) = m.solve() {
let x_val = solution[x].as_int().unwrap();
let target_val = solution[computed_target].as_int().unwrap();
let c = solution[count].as_int().unwrap();
assert_eq!(target_val, x_val + 1, "Computed target should be x + 1");
let matches = vars.iter()
.filter(|&&v| solution[v].as_int().unwrap() == target_val)
.count();
assert_eq!(c as usize, matches, "Count should match actual occurrences");
}
}
#[test]
fn test_count_api_consistency_with_arithmetic() {
let mut m = Model::default();
let x = m.int(1, 10);
let y = m.int(1, 10);
let sum = m.add(x, Val::int(3)); let _diff = m.sub(y, Val::int(2)); let _product = m.mul(x, Val::int(4));
let vars = vec![m.int(1, 5), m.int(1, 5), m.int(1, 5)];
let count = m.int(0, 3);
m.count(&vars, Val::int(3), count);
if let Ok(solution) = m.solve() {
let sum_val = solution[sum].as_int().unwrap();
let x_val = solution[x].as_int().unwrap();
assert_eq!(sum_val, x_val + 3);
}
}
#[test]
fn test_count_zero_matches_with_val() {
let mut m = Model::default();
let vars = vec![m.int(1, 2), m.int(1, 2), m.int(1, 2)];
let count = m.int(0, 3);
m.count(&vars, Val::int(5), count);
if let Ok(solution) = m.solve() {
let c = solution[count].as_int().unwrap();
assert_eq!(c, 0, "Should count zero matches");
}
}
#[test]
fn test_count_all_matches_with_val() {
let mut m = Model::default();
let vars = vec![m.int(3, 3), m.int(3, 3), m.int(3, 3)];
let count = m.int(0, 3);
m.count(&vars, Val::int(3), count);
if let Ok(solution) = m.solve() {
let c = solution[count].as_int().unwrap();
assert_eq!(c, 3, "Should count all three matches");
}
}
#[test]
fn test_count_with_gcc_using_internal_val() {
let mut m = Model::default();
let vars = vec![m.int(1, 3), m.int(1, 3), m.int(1, 3), m.int(1, 3)];
let count1 = m.int(0, 4);
let count2 = m.int(0, 4);
let count3 = m.int(0, 4);
m.gcc(&vars, &[1, 2, 3], &[count1, count2, count3]);
if let Ok(solution) = m.solve() {
let c1 = solution[count1].as_int().unwrap();
let c2 = solution[count2].as_int().unwrap();
let c3 = solution[count3].as_int().unwrap();
assert_eq!(c1 + c2 + c3, 4, "Total count should equal number of variables");
}
}
#[test]
fn test_count_target_with_negative_val() {
let mut m = Model::default();
let vars = vec![m.int(-5, 5), m.int(-5, 5), m.int(-5, 5)];
let count = m.int(0, 3);
m.count(&vars, Val::int(-3), count);
if let Ok(solution) = m.solve() {
let c = solution[count].as_int().unwrap();
let matches = vars.iter()
.filter(|&&v| solution[v].as_int().unwrap() == -3)
.count();
assert_eq!(c as usize, matches);
}
}
#[test]
fn test_count_old_vs_new_api_both_work() {
let mut m = Model::default();
let vars = vec![m.int(1, 5), m.int(1, 5), m.int(1, 5)];
let count_old = m.int(0, 3);
let count_new = m.int(0, 3);
let target_old = m.int(3, 3);
m.count(&vars, target_old, count_old);
m.count(&vars, Val::int(3), count_new);
if let Ok(solution) = m.solve() {
let c_old = solution[count_old].as_int().unwrap();
let c_new = solution[count_new].as_int().unwrap();
assert_eq!(c_old, c_new, "Both APIs should produce same count");
}
}