use crate::prelude::*;
#[derive(Clone, Default, Eq, IntoIterator)]
pub struct Mset(#[into_iterator(owned, ref, ref_mut)] pub Vec<Mset>);
impl AsRef<Mset> for Mset {
fn as_ref(&self) -> &Mset {
self
}
}
impl From<Mset> for Vec<Mset> {
fn from(set: Mset) -> Self {
set.0
}
}
impl From<Vec<Mset>> for Mset {
fn from(vec: Vec<Mset>) -> Self {
Self(vec)
}
}
impl FromIterator<Mset> for Mset {
fn from_iter<T: IntoIterator<Item = Mset>>(iter: T) -> Self {
Self(iter.into_iter().collect())
}
}
impl Debug for Mset {
fn fmt(&self, f: &mut Formatter) -> FmtResult {
f.write_char('(')?;
for el in self {
write!(f, "{el:?}")?;
}
f.write_char(')')
}
}
impl Display for Mset {
fn fmt(&self, f: &mut Formatter) -> FmtResult {
write!(f, "{}", self.ahu())
}
}
impl PartialEq for Mset {
fn eq(&self, other: &Self) -> bool {
if self.card() != other.card() {
return false;
}
if let Some((fst, snd)) = self.eq_levels(other) {
fst.subset(&snd)
} else {
false
}
}
}
impl PartialOrd for Mset {
fn le(&self, other: &Self) -> bool {
if self.card() > other.card() {
return false;
}
if let Some((fst, snd)) = self.le_levels(other) {
fst.subset(&snd)
} else {
false
}
}
fn ge(&self, other: &Self) -> bool {
other.le(self)
}
fn lt(&self, other: &Self) -> bool {
if self.card() >= other.card() {
return false;
}
if let Some((fst, snd)) = self.le_levels(other) {
fst.subset(&snd)
} else {
false
}
}
fn gt(&self, other: &Self) -> bool {
other.lt(self)
}
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
let cmp = self.card().cmp(&other.card());
let test = match cmp {
Ordering::Equal => self.eq(other),
Ordering::Less => self.le(other),
Ordering::Greater => self.ge(other),
};
if test {
Some(cmp)
} else {
None
}
}
}
#[derive(Clone, Copy, Debug)]
pub struct SetError;
impl Display for SetError {
fn fmt(&self, f: &mut Formatter) -> FmtResult {
f.write_str("mismatched brackets")
}
}
impl std::error::Error for SetError {}
impl FromStr for Mset {
type Err = SetError;
fn from_str(s: &str) -> Result<Self, SetError> {
let mut stack = Vec::new();
let mut iter = s.chars();
loop {
let c = iter.next().ok_or(SetError)?;
match c {
'{' => stack.push(Self::empty()),
'}' => {
let last = stack.pop().ok_or(SetError)?;
if let Some(prev) = stack.last_mut() {
prev.insert_mut(last);
} else {
for c in iter {
if ['{', '}'].contains(&c) {
return Err(SetError);
}
}
return Ok(last);
}
}
_ => {}
}
}
}
}
impl crate::Seal for Mset {}
impl SetTrait for Mset {
fn as_slice(&self) -> &[Self] {
&self.0
}
unsafe fn _as_mut_slice(&mut self) -> &mut [Self] {
&mut self.0
}
fn as_vec(&self) -> &Vec<Mset> {
&self.0
}
unsafe fn _as_mut_vec(&mut self) -> &mut Vec<Mset> {
&mut self.0
}
fn _flatten_vec(vec: Vec<Self>) -> Self {
vec.into()
}
fn empty() -> Self {
Self(Vec::new())
}
fn with_capacity(capacity: usize) -> Self {
Self(Vec::with_capacity(capacity))
}
fn singleton(self) -> Self {
Self(vec![self])
}
fn into_singleton(mut self) -> Option<Self> {
if self.card() != 1 {
return None;
}
self.0.pop()
}
fn insert_mut(&mut self, other: Self) {
self.0.push(other);
}
fn select_mut<P: FnMut(&Mset) -> bool>(&mut self, mut pred: P) {
let mut i = 0;
while i < self.card() {
if pred(&self.0[i]) {
i += 1;
} else {
self.0.swap_remove(i);
}
}
}
fn count(&self, set: &Self) -> usize {
let mut cmp = Compare::new(set);
self.iter().filter(|el| cmp.eq(el)).count()
}
fn sum(mut self, mut other: Self) -> Self {
self.0.append(&mut other.0);
self
}
fn sum_vec(vec: Vec<Self>) -> Self {
Self::sum_iter(vec)
}
fn union_vec(mut vec: Vec<Self>) -> Self {
match vec.len() {
0 => return Self::empty(),
1 => return vec.pop().unwrap(),
_ => {}
}
let levels = Levels::new_iter(&vec);
let next = levels.ahu(1);
let mut iter = unsafe { levels.children_slice(0, &next) }.enumerate();
let fst = unsafe { iter.next().unwrap_unchecked().1 };
let mut sets = BTreeMap::new();
for (i, &set) in fst.iter().enumerate() {
let el_idx = (0, i);
match sets.entry(set) {
Entry::Vacant(entry) => {
entry.insert((smallvec![el_idx], 0));
}
Entry::Occupied(mut entry) => {
entry.get_mut().0.push(el_idx);
}
}
}
for (n, slice) in iter {
for (i, &set) in slice.iter().enumerate() {
let el_idx = (n, i);
match sets.entry(set) {
Entry::Vacant(entry) => {
entry.insert((smallvec![el_idx], 1));
}
Entry::Occupied(mut entry) => {
let (indices, count) = entry.get_mut();
if indices.len() == *count {
indices.push(el_idx);
}
*count += 1;
}
}
}
for (_, count) in sets.values_mut() {
*count = 0;
}
}
let mut union = Self::empty();
for (indices, _) in sets.into_values() {
for (n, i) in indices {
let set = mem::take(unsafe { vec.get_unchecked_mut(n).0.get_unchecked_mut(i) });
union.insert_mut(set);
}
}
union
}
fn inter_vec(mut vec: Vec<Self>) -> Option<Self> {
match vec.len() {
0 => return None,
1 => return Some(vec.pop().unwrap()),
_ => {}
}
let levels = Levels::new_iter(&vec);
let next = levels.ahu(1);
let mut iter = unsafe { levels.children_slice(0, &next) };
let fst = unsafe { iter.next().unwrap_unchecked() };
let mut sets = BTreeMap::new();
for (i, &set) in fst.iter().enumerate() {
match sets.entry(set) {
Entry::Vacant(entry) => {
entry.insert((smallvec![i], 0));
}
Entry::Occupied(mut entry) => {
entry.get_mut().0.push(i);
}
}
}
for slice in iter {
for &set in slice {
match sets.entry(set) {
Entry::Vacant(_) => {}
Entry::Occupied(mut entry) => {
entry.get_mut().1 += 1;
}
}
}
sets.retain(|_, (indices, count)| {
indices.truncate(*count);
let retain = *count != 0;
*count = 0;
retain
});
}
let mut fst = vec.swap_remove(0);
let mut snd = vec.swap_remove(0);
snd.clear();
for (indices, _) in sets.into_values() {
for i in indices {
let set = mem::take(unsafe { fst.0.get_unchecked_mut(i) });
snd.insert_mut(set);
}
}
Some(snd)
}
fn powerset(self) -> Self {
let n = self.card();
let mut powerset = Self::empty().singleton();
if n == 0 {
return powerset;
}
for mut i in 1..((1 << n) - 1) {
let mut subset = Self::empty();
for j in 0..n {
if i % 2 == 1 {
subset.insert_mut(self.0[j].clone());
}
i /= 2;
}
powerset.insert_mut(subset);
}
powerset.insert(self)
}
fn nat(n: usize) -> Self {
let mut res = Mset::empty();
for _ in 0..n {
res.insert_mut(res.clone());
}
res
}
fn zermelo(n: usize) -> Self {
let mut res = Mset::empty();
for _ in 0..n {
res = res.singleton();
}
res
}
fn neumann(n: usize) -> Self {
debug_assert!(
n <= 5,
"the sixth set in the von Neumann hierarchy has 2^65536 elements"
);
let mut set = Self::empty();
for _ in 0..n {
set = set.powerset();
}
set
}
fn disjoint_iter<'a, I: IntoIterator<Item = &'a Self>>(iter: I) -> bool {
let levels = Levels::new_iter(iter);
let slice = levels.nest_vec().get(0);
match slice.len() {
0 => return false,
1 => return levels.nest_vec().len() == 1,
_ => {}
}
let next = levels.ahu(1);
let mut iter = unsafe { levels.children_slice(0, &next) };
let fst = unsafe { iter.next().unwrap_unchecked() };
let mut sets = BTreeMap::new();
for &set in fst {
sets.insert(set, false);
}
for slice in iter {
for &set in slice {
if let Entry::Occupied(mut entry) = sets.entry(set) {
*entry.get_mut() = true;
}
}
sets.retain(|_, count| {
let retain = *count;
*count = false;
retain
});
if sets.is_empty() {
return true;
}
}
false
}
fn disjoint_pairwise<'a, I: IntoIterator<Item = &'a Self>>(iter: I) -> bool {
let levels = Levels::new_iter(iter);
if levels.nest_vec().get(0).len() <= 1 {
return true;
}
let next = levels.ahu(1);
let mut iter = unsafe { levels.children_slice(0, &next).enumerate() };
let (_, fst) = unsafe { iter.next().unwrap_unchecked() };
let mut sets = BTreeMap::new();
for &set in fst {
sets.insert(set, 0);
}
for (i, slice) in iter {
for &set in slice {
match sets.entry(set) {
Entry::Vacant(entry) => {
entry.insert(i);
}
Entry::Occupied(entry) => {
if *entry.get() != i {
return false;
}
}
}
}
}
true
}
fn into_choose(mut self) -> Option<Self> {
if self.is_empty() {
None
} else {
Some(self.0.swap_remove(0))
}
}
fn choose_uniq(&self) -> Option<&Self> {
self.choose_uniq_idx().map(
|idx| unsafe { self.0.get_unchecked(idx) },
)
}
fn into_choose_uniq(mut self) -> Option<Self> {
self.choose_uniq_idx()
.map(|idx| unsafe { mem::take(self.0.get_unchecked_mut(idx)) })
}
}
impl Mset {
pub fn as_mut_slice(&mut self) -> &mut [Self] {
&mut self.0
}
pub fn as_mut_vec(&mut self) -> &mut Vec<Self> {
&mut self.0
}
pub fn iter_mut(&mut self) -> slice::IterMut<Self> {
self.0.iter_mut()
}
#[must_use]
pub fn duplicate(&self) -> bool {
Levels::new(self).duplicate(1)
}
pub fn sum_iter<I: IntoIterator<Item = Self>>(iter: I) -> Self {
iter.into_iter().flatten().collect()
}
fn choose_uniq_idx(&self) -> Option<usize> {
Ahu::new_iter(self)
.iter()
.enumerate()
.min_by_key(|s| s.1)
.map(|(idx, _)| idx)
}
}