use crate::prelude::*;
#[derive(Clone)]
pub struct Dedup<I: Iterator<Item = Set>> {
iter: I,
output: Set,
}
impl<I: Iterator<Item = Set>> Dedup<I> {
pub fn new(iter: I) -> Self {
Self {
iter,
output: Set::empty(),
}
}
}
impl<I: Iterator<Item = Set>> Iterator for Dedup<I> {
type Item = Set;
fn next(&mut self) -> Option<Self::Item> {
for set in self.iter.by_ref() {
if !self.output.contains(&set) {
unsafe {
self.output.insert_mut_unchecked(set.clone());
}
return Some(set);
}
}
None
}
}
#[derive(Clone, Default)]
pub struct Interleave<I: IntoIterator, J: Iterator<Item = I>> {
iter: J,
vec: Vec<I::IntoIter>,
index: usize,
}
impl<I: IntoIterator, J: Iterator<Item = I>> Interleave<I, J> {
#[must_use]
pub const fn new(iter: J) -> Self {
Self {
iter,
vec: Vec::new(),
index: 0,
}
}
}
impl<I: Iterator> Interleave<I, iter::Empty<I>> {
#[must_use]
pub const fn new_vec(vec: Vec<I>) -> Self {
Self {
iter: iter::empty(),
vec,
index: 0,
}
}
}
impl<I: IntoIterator, J: Iterator<Item = I>> Iterator for Interleave<I, J> {
type Item = I::Item;
fn next(&mut self) -> Option<I::Item> {
loop {
let len = self.vec.len();
debug_assert!(self.index <= len);
if self.index >= len {
self.index = 0;
if let Some(next) = self.iter.next() {
self.vec.push(next.into_iter());
}
if self.vec.is_empty() {
return None;
}
}
let next = self.vec[self.index].next();
if next.is_some() {
self.index += 1;
return next;
}
drop(self.vec.swap_remove(self.index));
}
}
}
pub struct Product<I: Iterator, J: Iterator> {
fst: I,
snd: J,
fst_values: Vec<I::Item>,
snd_values: Vec<J::Item>,
index: usize,
}
impl<I: Iterator, J: Iterator> Product<I, J>
where
I::Item: Clone,
J::Item: Clone,
{
pub const fn new(fst: I, snd: J) -> Self {
Self {
fst,
snd,
fst_values: Vec::new(),
snd_values: Vec::new(),
index: 0,
}
}
}
impl<I: Iterator, J: Iterator> Iterator for Product<I, J>
where
I::Item: Clone,
J::Item: Clone,
{
type Item = (I::Item, J::Item);
fn next(&mut self) -> Option<Self::Item> {
let a = self.fst_values.len();
let b = self.snd_values.len();
let idx = self.index;
Some(if a > b {
if idx >= b {
debug_assert_eq!(idx, b);
if let Some(snd_value) = self.snd.next() {
self.snd_values.push(snd_value.clone());
self.index = 1;
(self.fst_values[0].clone(), snd_value)
}
else {
let fst_value = self.fst.next()?;
self.fst_values.push(fst_value.clone());
self.index = 1;
unsafe {
(
fst_value,
self.snd_values.first().unwrap_unchecked().clone(),
)
}
}
} else {
self.index += 1;
(
self.fst_values.last().unwrap().clone(),
self.snd_values[idx].clone(),
)
}
}
else {
if idx >= a {
debug_assert_eq!(idx, a);
if let Some(fst_value) = self.fst.next() {
if let Some(snd_value) = self.snd_values.first() {
self.fst_values.push(fst_value.clone());
self.index = 1;
(fst_value, snd_value.clone())
}
else {
let snd_value = self.snd.next()?;
self.fst_values.push(fst_value.clone());
self.snd_values.push(snd_value.clone());
self.index = 1;
(fst_value, snd_value)
}
}
else {
let fst_value = self.fst_values.first()?;
let snd_value = self.snd.next()?;
self.snd_values.push(snd_value.clone());
self.index = 1;
(fst_value.clone(), snd_value)
}
} else {
self.index += 1;
(
self.fst_values[idx].clone(),
self.snd_values.last().unwrap().clone(),
)
}
})
}
}
pub unsafe trait Inj {
fn func(n: usize) -> Set;
}
#[derive(Clone, Default)]
#[allow(clippy::module_name_repetitions)]
pub struct NatClass<T: Inj>(pub usize, std::marker::PhantomData<T>);
impl<T: Inj> NatClass<T> {
#[must_use]
pub const fn new() -> Self {
Self(0, std::marker::PhantomData)
}
}
impl<T: Inj> Iterator for NatClass<T> {
type Item = Set;
fn next(&mut self) -> Option<Set> {
let res = T::func(self.0);
self.0 = self.0.checked_add(1)?;
Some(res)
}
fn nth(&mut self, n: usize) -> Option<Set> {
self.0 = self.0.saturating_add(n);
self.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
let len = usize::MAX - self.0;
(len, Some(len))
}
}
macro_rules! impl_nat {
($($name: ident, $func: ident, $doc: literal),*) => {$(
concat_idents::concat_idents!(name_func = $name, Func {
#[doc = concat!("A ZST representing [`Set::", stringify!($func), "`].")]
pub struct name_func;
unsafe impl Inj for name_func {
fn func(n: usize) -> Set {
Set::$func(n)
}
}
#[doc = $doc]
pub type $name = NatClass<name_func>;
});
)*};
}
impl_nat!(
Nat,
nat,
"The class of naturals ℕ, generated via [`Set::nat`].",
Zermelo,
zermelo,
"The class of Zermelo naturals ℕ, generated via [`Set::zermelo`].",
Neumann,
neumann,
"The von Neumman hierarchy up to V<sub>ω</sub>, generated via [`Set::neumann`]."
);
#[derive(Clone, Default)]
pub struct Univ(Vec<Set>);
impl Univ {
#[must_use]
pub const fn new() -> Self {
Self(Vec::new())
}
}
impl Iterator for Univ {
type Item = Set;
fn next(&mut self) -> Option<Set> {
let mut set = Set::empty();
let mut n = self.0.len();
let mut m = 0;
while n != 0 {
if n % 2 == 1 {
unsafe {
set.insert_mut_unchecked(self.0.get_unchecked(m).clone());
}
}
n /= 2;
m += 1;
}
if self.0.len() < usize::BITS as usize {
self.0.push(set.clone());
}
Some(set)
}
}
#[derive(IntoIterator)]
pub struct Class(Box<dyn Iterator<Item = Set>>);
impl Default for Class {
fn default() -> Self {
Self::empty()
}
}
impl From<Set> for Class {
fn from(value: Set) -> Self {
Self::new(value.into_iter())
}
}
impl Class {
pub unsafe fn new_unchecked<I: Iterator<Item = Set> + 'static>(iter: I) -> Self {
Self(Box::new(iter))
}
pub fn new<I: Iterator<Item = Set> + 'static>(iter: I) -> Self {
unsafe { Self::new_unchecked(Dedup::new(iter)) }
}
#[must_use]
pub fn contains(self, set: &Set) -> bool {
Set::contains_iter(self, set)
}
#[must_use]
pub fn empty() -> Self {
unsafe { Self::new_unchecked(iter::empty()) }
}
#[must_use]
pub fn univ() -> Self {
unsafe { Self::new_unchecked(Univ::new()) }
}
#[must_use]
pub fn nat() -> Self {
unsafe { Self::new_unchecked(Nat::new()) }
}
#[must_use]
pub fn zermelo() -> Self {
unsafe { Self::new_unchecked(Zermelo::new()) }
}
#[must_use]
pub fn neumann() -> Self {
unsafe { Self::new_unchecked(Neumann::new()) }
}
#[must_use]
pub fn select<P: FnMut(&Set) -> bool + 'static>(self, pred: P) -> Self {
unsafe { Self::new_unchecked(self.into_iter().filter(pred)) }
}
pub fn pred<P: FnMut(&Set) -> bool + 'static>(pred: P) -> Self {
Self::univ().select(pred)
}
pub fn union_iter<I: Iterator<Item = Self> + 'static>(iter: I) -> Self {
Self::new(Interleave::new(iter.into_iter()))
}
pub fn union_vec(vec: Vec<Self>) -> Self {
Self::new(Interleave::new_vec(
vec.into_iter().map(IntoIterator::into_iter).collect(),
))
}
#[must_use]
pub fn union(self, other: Self) -> Self {
Self::union_vec(vec![self, other])
}
#[must_use]
pub fn prod(self, other: Self) -> Self {
unsafe {
Self::new_unchecked(
Product::new(self.into_iter(), other.into_iter()).map(|(x, y)| x.kpair(y)),
)
}
}
#[must_use]
pub fn replace<F: FnMut(Set) -> Set + 'static>(self, func: F) -> Self {
Self::new(self.into_iter().map(func))
}
#[must_use]
pub unsafe fn replace_unchecked<F: FnMut(Set) -> Set + 'static>(self, func: F) -> Self {
Self::new_unchecked(self.into_iter().map(func))
}
#[must_use]
pub fn choose(mut self) -> Option<Set> {
self.0.next()
}
}