use std::cmp::Ordering;
use std::cmp::Ordering::Equal;
use std::iter::Cloned;
use std::slice::Iter;
use bitset_fixed::BitSet;
use compare::Compare;
use crate::core::abstraction::heuristics::{LoadVars, VariableHeuristic, WidthHeuristic};
use crate::core::common::{Layer, Node, Variable, VarSet};
use std::ops::{Index, IndexMut};
#[derive(Clone)]
pub struct Matrix<T> {
pub n: usize,
pub m: usize,
pub data : Vec<T>
}
impl <T : Default + Clone> Matrix<T> {
pub fn new(m: usize, n: usize) -> Self {
Matrix { m, n, data: vec![Default::default(); m * n] }
}
}
impl <T : Clone> Matrix<T> {
pub fn new_default(m: usize, n: usize, item: T) -> Self {
Matrix { m, n, data: vec![item; m * n] }
}
}
impl <T> Matrix<T> {
fn pos(&self, idx: (usize, usize)) -> usize {
self.m * idx.0 + idx.1
}
}
impl <T> Index<(usize, usize)> for Matrix<T> {
type Output = T;
fn index(&self, idx: (usize, usize)) -> &Self::Output {
let position = self.pos(idx);
&self.data[position]
}
}
impl <T> IndexMut<(usize, usize)> for Matrix<T> {
fn index_mut(&mut self, idx: (usize, usize)) -> &mut Self::Output {
let position = self.pos(idx);
&mut self.data[position]
}
}
pub struct BitSetIter<'a> {
iter: Cloned<Iter<'a, u64>>,
word: Option<u64>,
base: usize,
offset: usize,
}
impl BitSetIter<'_> {
pub fn new(bs: &BitSet) -> BitSetIter {
let mut iter = bs.buffer().iter().cloned();
let word = iter.next();
BitSetIter {iter, word, base: 0, offset: 0}
}
}
impl Iterator for BitSetIter<'_> {
type Item = usize;
fn next(&mut self) -> Option<Self::Item> {
while let Some(w) = self.word {
if w == 0 || self.offset >= 64 {
self.word = self.iter.next();
self.base += 64;
self.offset = 0;
} else {
let mut mask = 1_u64 << self.offset as u64;
while (w & mask) == 0 && self.offset < 64 {
mask <<= 1;
self.offset += 1;
}
if self.offset < 64 {
let ret = Some(self.base + self.offset);
self.offset += 1;
return ret;
}
}
}
None
}
}
#[derive(Debug)]
pub struct LexBitSet<'a>(pub &'a BitSet);
impl Ord for LexBitSet<'_> {
fn cmp(&self, other: &Self) -> Ordering {
let mut x = self.0.buffer().iter().cloned();
let mut y = other.0.buffer().iter().cloned();
let end = x.len().max(y.len());
for _ in 0..end {
let xi = x.next().unwrap_or(0);
let yi = y.next().unwrap_or(0);
if xi != yi {
let mut mask = 1_u64;
for _ in 0..64 {
let bit_x = xi & mask;
let bit_y = yi & mask;
if bit_x != bit_y {
return bit_x.cmp(&bit_y);
}
mask <<= 1;
}
}
}
Equal
}
}
impl PartialOrd for LexBitSet<'_> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Eq for LexBitSet<'_> {}
impl PartialEq for LexBitSet<'_> {
fn eq(&self, other: &Self) -> bool {
self.0 == other.0 || self.cmp(other) == Equal
}
}
#[derive(Clone)]
pub struct Func<F>(pub F);
impl <T, F> Compare<Node<T>> for Func<F>
where F: Clone + Fn(&Node<T>, &Node<T>) -> Ordering {
fn compare(&self, a: &Node<T>, b: &Node<T>) -> Ordering {
(self.0)(a, b)
}
}
impl <F> WidthHeuristic for Func<F>
where F: Fn(&VarSet) -> usize {
fn max_width(&self, free_vars: &VarSet) -> usize {
(self.0)(free_vars)
}
}
impl <T, F> VariableHeuristic<T> for Func<F>
where F: Fn(&VarSet, Layer<'_, T>, Layer<'_, T>) -> Option<Variable> {
fn next_var(&self, free_vars: &VarSet, current: Layer<'_, T>, next: Layer<'_, T>) -> Option<Variable> {
(self.0)(free_vars, current, next)
}
}
impl <T, F> LoadVars<T> for Func<F>
where F: Fn(&Node<T>) -> VarSet {
fn variables(&self, node: &Node<T>) -> VarSet {
(self.0)(node)
}
}
#[cfg(test)]
mod tests_bitset_iter {
use bitset_fixed::BitSet;
use crate::core::utils::BitSetIter;
#[test]
fn bsiter_collect() {
let mut bit_set = BitSet::new(5);
bit_set.set(1, true);
bit_set.set(2, true);
bit_set.set(4, true);
let iter = BitSetIter::new(&bit_set);
let items = iter.collect::<Vec<usize>>();
assert_eq!(items, vec![1, 2, 4]);
}
#[test]
fn bsiter_next_normal_case() {
let mut bit_set = BitSet::new(5);
bit_set.set(1, true);
bit_set.set(2, true);
bit_set.set(4, true);
let mut iter = BitSetIter::new(&bit_set);
assert_eq!(Some(1), iter.next());
assert_eq!(Some(2), iter.next());
assert_eq!(Some(4), iter.next());
assert_eq!(None , iter.next());
}
#[test]
fn bsiter_no_items() {
let bit_set = BitSet::new(5);
let mut iter = BitSetIter::new(&bit_set);
assert_eq!(None, iter.next());
assert_eq!(None, iter.next());
assert_eq!(None, iter.next());
}
#[test]
fn bsiter_mutiple_words() {
let mut bit_set = BitSet::new(128);
bit_set.set( 1, true);
bit_set.set( 50, true);
bit_set.set( 66, true);
bit_set.set(100, true);
let mut iter = BitSetIter::new(&bit_set);
assert_eq!(Some( 1), iter.next());
assert_eq!(Some( 50), iter.next());
assert_eq!(Some( 66), iter.next());
assert_eq!(Some(100), iter.next());
assert_eq!(None , iter.next());
}
}
#[cfg(test)]
mod tests_lexbitset {
use bitset_fixed::BitSet;
use crate::core::utils::LexBitSet;
#[test]
fn same_size_less_than() {
let mut a = BitSet::new(200);
let mut b = BitSet::new(200);
a.set(2, true); b.set(2, true);
a.set(3, false); b.set(3, true);
a.set(4, true); b.set(4, false);
a.set(150, true);
b.set(150, true);
assert!(LexBitSet(&a) <= LexBitSet(&b));
assert!(LexBitSet(&a) < LexBitSet(&b));
}
#[test]
fn same_size_greater_than() {
let mut a = BitSet::new(200);
let mut b = BitSet::new(200);
a.set(2, true); b.set(2, true);
a.set(3, false); b.set(3, true);
a.set(4, true); b.set(4, false);
a.set(150, true);
b.set(150, true);
assert!(LexBitSet(&b) >= LexBitSet(&a));
assert!(LexBitSet(&b) > LexBitSet(&a));
}
#[test]
fn same_size_equal() {
let mut a = BitSet::new(200);
let mut b = BitSet::new(200);
a.set(2, true); b.set(2, true);
a.set(150, true);
b.set(150, true);
assert!(LexBitSet(&a) >= LexBitSet(&b));
assert!(LexBitSet(&b) >= LexBitSet(&a));
assert_eq!(LexBitSet(&a), LexBitSet(&b));
assert_eq!(LexBitSet(&a), LexBitSet(&a));
assert_eq!(LexBitSet(&b), LexBitSet(&b));
}
#[test]
fn different_sizes_considered_padded_with_zeroes() {
let mut a = BitSet::new(20);
let mut b = BitSet::new(200);
a.set(2, true); b.set(2, true);
assert_eq!(LexBitSet(&a), LexBitSet(&b));
b.set(150, true);
assert!(LexBitSet(&a) <= LexBitSet(&b));
assert!(LexBitSet(&a) < LexBitSet(&b));
}
}
#[cfg(test)]
mod test_matrix {
use crate::core::utils::Matrix;
#[test]
fn it_is_initialized_with_default_elem() {
let mat : Matrix<Option<usize>> = Matrix::new(5, 5);
for i in 0..5 {
for j in 0..5 {
assert_eq!(None, mat[(i, j)]);
}
}
}
#[test]
fn it_is_initialized_with_given_elem() {
let mat = Matrix::new_default(5, 5, Some(0));
for i in 0..5 {
for j in 0..5 {
assert_eq!(Some(0), mat[(i, j)]);
}
}
}
#[test]
fn it_can_be_accessed_and_mutated_with_2d_position() {
let mut mat = Matrix::new(5, 5);
mat[(2, 2)] = Some(-5);
assert_eq!(Some(-5), mat[(2, 2)]);
}
}