use std::{
collections::{BTreeSet, HashSet},
hash::{BuildHasher, Hash},
};
pub trait Collection {
type Item;
fn contains(&self, point: &Self::Item) -> bool;
fn is_empty(&self) -> bool;
}
pub trait Poset: Collection {
fn leq(&self, a: &Self::Item, b: &Self::Item) -> Option<bool>;
fn upset(&self, a: Self::Item) -> HashSet<Self::Item>;
fn downset(&self, a: Self::Item) -> HashSet<Self::Item>;
fn minimal_elements(&self) -> HashSet<Self::Item>;
fn maximal_elements(&self) -> HashSet<Self::Item>;
fn join(&self, a: Self::Item, b: Self::Item) -> Option<Self::Item>;
fn meet(&self, a: Self::Item, b: Self::Item) -> Option<Self::Item>;
fn successors(&self, a: Self::Item) -> HashSet<Self::Item>;
fn predecessors(&self, a: Self::Item) -> HashSet<Self::Item>;
}
impl<T: Hash + Eq + Clone, S: BuildHasher + Default> Collection for HashSet<T, S> {
type Item = T;
fn contains(&self, point: &Self::Item) -> bool { Self::contains(self, point) }
fn is_empty(&self) -> bool { Self::is_empty(self) }
}
impl<T: Ord + Clone> Collection for BTreeSet<T> {
type Item = T;
fn contains(&self, point: &Self::Item) -> bool { Self::contains(self, point) }
fn is_empty(&self) -> bool { Self::is_empty(self) }
}
impl<T: PartialEq> Collection for Vec<T> {
type Item = T;
fn contains(&self, point: &Self::Item) -> bool { self.iter().any(|p| p == point) }
fn is_empty(&self) -> bool { self.is_empty() }
}