use std::default::Default;
use progress::CountMap;
use order::PartialOrder;
#[derive(Default, Clone, Debug)]
pub struct Antichain<T> {
elements: Vec<T>
}
impl<T: PartialOrder> Antichain<T> {
pub fn insert(&mut self, element: T) -> bool {
if !self.elements.iter().any(|x| x.less_equal(&element)) {
self.elements.retain(|x| !element.less_equal(x));
self.elements.push(element);
true
}
else {
false
}
}
pub fn new() -> Antichain<T> { Antichain { elements: Vec::new() } }
pub fn from_elem(element: T) -> Antichain<T> { Antichain { elements: vec![element] } }
pub fn clear(&mut self) { self.elements.clear() }
#[inline]
pub fn less_than(&self, time: &T) -> bool {
self.elements.iter().any(|x| x.less_than(time))
}
#[inline]
pub fn less_equal(&self, time: &T) -> bool {
self.elements.iter().any(|x| x.less_equal(time))
}
#[inline]
pub fn dominates(&self, other: &Antichain<T>) -> bool {
other.elements().iter().all(|t2| self.elements().iter().any(|t1| t1.less_equal(t2)))
}
#[inline] pub fn elements(&self) -> &[T] { &self.elements[..] }
}
#[derive(Default, Debug, Clone)]
pub struct MutableAntichain<T:Eq> {
occurrences: CountMap<T>, precedents: Vec<(T, i64)>, elements: Vec<T>, }
impl<T: PartialOrder+Eq+Clone+'static> MutableAntichain<T> {
pub fn new() -> MutableAntichain<T> {
MutableAntichain {
occurrences: Default::default(),
precedents: Default::default(),
elements: Vec::new(),
}
}
pub fn clear(&mut self) {
self.occurrences.clear();
self.precedents.clear();
self.elements.clear();
}
pub fn elements(&self) -> &[T] { &self.elements }
pub fn new_bottom(bottom: T) -> MutableAntichain<T> {
let mut result = MutableAntichain::new();
result.update_weight(&bottom, 1, &mut Default::default());
result
}
pub fn empty(&self) -> bool { self.elements.is_empty() }
#[inline]
pub fn less_than(&self, time: &T) -> bool {
self.elements.iter().any(|x| x.less_than(time))
}
#[inline]
pub fn less_equal(&self, time: &T) -> bool {
self.elements.iter().any(|x| x.less_equal(time))
}
#[inline]
pub fn count(&self, time: &T) -> Option<i64> {
self.occurrences.iter().filter(|x| time.eq(&x.0)).next().map(|i| i.1)
}
pub fn update_into_cm(&mut self, updates: &CountMap<T>, results: &mut CountMap<T>) -> () {
self.update_iter_and(updates.iter().cloned(), |time, val| { results.update(time, val); });
}
pub fn update_weight(&mut self, elem: &T, delta: i64, results: &mut CountMap<T>) -> () {
self.update_and(elem, delta, |time, delta| { results.update(time, delta); });
}
#[inline] pub fn update(&mut self, elem: &T, delta: i64) { self.update_and(elem, delta, |_,_| {}); }
pub fn update_iter_and<I: Iterator<Item = (T, i64)>,
A: FnMut(&T, i64) -> ()>(&mut self, updates: I, mut action: A) -> () {
for (ref elem, delta) in updates {
self.update_and(elem, delta, |t,d| action(t,d));
}
}
#[inline]
pub fn test_size(&self, threshold: usize, name: &str) {
if self.occurrences.len() > threshold {
println!("{}:\toccurrences:\tlen() = {}", name, self.occurrences.len());
}
if self.precedents.len() > threshold {
println!("{}: precedents:\tlen() = {}", name, self.precedents.len());
}
}
#[inline]
pub fn update_and<A: FnMut(&T, i64)->()>(&mut self, elem: &T, delta: i64, mut action: A) -> () {
if delta != 0 {
let new_value = self.occurrences.update(elem, delta);
let old_value = new_value - delta;
if old_value <= 0 && new_value > 0 {
let mut preceded_by = 0;
for &mut (ref key, ref mut val) in &mut self.precedents {
if elem.less_than(key) {
if *val == 0 {
self.elements.retain(|x| x != key);
action(key, -1);
}
*val += 1;
}
else if key.less_than(elem) {
preceded_by += 1;
}
}
self.precedents.push((elem.clone(), preceded_by));
if preceded_by == 0 {
self.elements.push(elem.clone());
action(elem, 1);
}
}
if old_value > 0 && new_value <= 0 {
for &mut (ref key, ref mut val) in &mut self.precedents {
if elem.less_than(key) {
*val -= 1;
if *val == 0 {
self.elements.push(key.clone());
action(key, 1);
}
}
}
if let Some(position) = self.elements.iter().position(|x| x == elem) {
action(elem, -1);
self.elements.swap_remove(position);
}
self.precedents.retain(|x| &x.0 != elem);
}
}
}
}