use crate::prelude::*;
#[derive(Clone, Default, AsRef, Display, Into, PartialEq, Eq, PartialOrd)]
#[repr(transparent)]
pub struct Set(Mset);
impl From<Set> for Vec<Set> {
fn from(set: Set) -> Self {
unsafe { Set::cast_vec(set.0 .0) }
}
}
impl Debug for Set {
fn fmt(&self, f: &mut Formatter) -> FmtResult {
write!(f, "{:?}", self.mset())
}
}
impl FromStr for Set {
type Err = SetError;
fn from_str(s: &str) -> Result<Self, SetError> {
s.parse().map(Mset::flatten)
}
}
unsafe fn dedup_by<T: Default, U: Ord + Copy>(
set: &mut Vec<T>,
keys: &[U],
buf: &mut Vec<T>,
buf_pairs: &mut Vec<(usize, U)>,
) {
buf_pairs.clear();
buf_pairs.extend(keys.iter().copied().enumerate());
buf_pairs.sort_unstable_by_key(|(_, k)| *k);
buf_pairs.dedup_by_key(|(_, k)| *k);
for (i, _) in &*buf_pairs {
let el = mem::take(set.get_unchecked_mut(*i));
buf.push(el);
}
set.clear();
set.append(buf);
}
impl Mset {
#[must_use]
pub fn is_set_iter<'a, I: IntoIterator<Item = &'a Self>>(iter: I) -> bool {
let levels = Levels::new_iter(iter).mod_ahu(
0,
BTreeMap::new(),
|sets, slice, _| {
slice.sort_unstable();
if consecutive_eq(slice) {
return None;
}
let children: SmallVec<_> = slice.iter().copied().collect();
Some(btree_index(sets, children))
},
BTreeMap::clear,
);
if let Some(mut slice) = levels {
slice.sort_unstable();
!consecutive_eq(&slice)
} else {
false
}
}
#[must_use]
pub fn is_set(&self) -> bool {
Self::is_set_iter(self)
}
#[must_use]
pub fn flatten(mut self) -> Set {
let levels = Levels::new_mut(&mut self);
let mut buf = Vec::new();
let mut buf_pairs = Vec::new();
unsafe {
levels.mod_ahu_gen(
0,
BTreeMap::new(),
|sets, slice, set| {
dedup_by(&mut (*set).0, slice, &mut buf, &mut buf_pairs);
let children: SmallVec<_> = buf_pairs.iter().map(|(_, k)| *k).collect();
Some(btree_index(sets, children))
},
BTreeMap::clear,
);
}
unsafe { self.into_set_unchecked() }
}
#[must_use]
pub unsafe fn into_set_unchecked(self) -> Set {
Set(self)
}
#[must_use]
pub fn into_set(self) -> Option<Set> {
if self.is_set() {
unsafe { Some(self.into_set_unchecked()) }
} else {
None
}
}
#[must_use]
pub unsafe fn as_set_unchecked(&self) -> &Set {
&*(ptr::from_ref(self).cast())
}
#[must_use]
pub fn as_set(&self) -> Option<&Set> {
if self.is_set() {
Some(unsafe { self.as_set_unchecked() })
} else {
None
}
}
#[must_use]
pub unsafe fn as_set_mut_unchecked(&mut self) -> &mut Set {
&mut *(ptr::from_mut(self).cast())
}
#[must_use]
pub fn as_set_mut(&mut self) -> Option<&mut Set> {
if self.is_set() {
Some(unsafe { self.as_set_mut_unchecked() })
} else {
None
}
}
#[must_use]
pub fn cast_vec(vec: Vec<Set>) -> Vec<Self> {
unsafe { crate::transmute_vec(vec) }
}
}
impl Set {
#[must_use]
pub const fn mset(&self) -> &Mset {
&self.0
}
pub fn is_set_iter<'a, I: IntoIterator<Item = &'a Self>>(iter: I) -> bool {
!Levels::new_iter(iter.into_iter().map(AsRef::as_ref)).duplicate(0)
}
#[must_use]
pub fn is_set(slice: &[Self]) -> bool {
Self::is_set_iter(slice.iter())
}
pub fn flatten(mut vec: Vec<Self>) -> Self {
let keys = Levels::new_iter(vec.iter().map(AsRef::as_ref)).ahu(0);
let mut buf = Vec::new();
let mut buf_pairs = Vec::new();
unsafe {
dedup_by(&mut vec, &keys, &mut buf, &mut buf_pairs);
Self::from_vec_unchecked(vec)
}
}
#[must_use]
pub unsafe fn from_vec_unchecked(vec: Vec<Self>) -> Self {
Self(Mset::cast_vec(vec).into())
}
#[must_use]
pub fn from_vec(vec: Vec<Self>) -> Option<Self> {
if Self::is_set(&vec) {
unsafe { Some(Self::from_vec_unchecked(vec)) }
} else {
None
}
}
#[must_use]
pub unsafe fn cast_vec(vec: Vec<Mset>) -> Vec<Self> {
crate::transmute_vec(vec)
}
}
pub struct Cast<I>(I);
impl Iterator for Cast<std::vec::IntoIter<Mset>> {
type Item = Set;
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(|s| unsafe { s.into_set_unchecked() })
}
}
impl<'a> Iterator for Cast<slice::Iter<'a, Mset>> {
type Item = &'a Set;
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(|s| unsafe { s.as_set_unchecked() })
}
}
impl<'a> Iterator for Cast<slice::IterMut<'a, Mset>> {
type Item = &'a mut Set;
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(|s| unsafe { s.as_set_mut_unchecked() })
}
}
impl IntoIterator for Set {
type Item = Set;
type IntoIter = Cast<std::vec::IntoIter<Mset>>;
fn into_iter(self) -> Self::IntoIter {
Cast(self.0.into_iter())
}
}
#[allow(clippy::into_iter_without_iter)]
impl<'a> IntoIterator for &'a Set {
type Item = &'a Set;
type IntoIter = Cast<slice::Iter<'a, Mset>>;
fn into_iter(self) -> Self::IntoIter {
Cast(self.0.iter())
}
}
impl<'a> IntoIterator for &'a mut Set {
type Item = &'a mut Set;
type IntoIter = Cast<slice::IterMut<'a, Mset>>;
fn into_iter(self) -> Self::IntoIter {
Cast(self.0.iter_mut())
}
}
impl crate::Seal for Set {}
impl SetTrait for Set {
fn as_slice(&self) -> &[Self] {
let slice = self.0.as_slice();
unsafe { slice::from_raw_parts(slice.as_ptr().cast(), slice.len()) }
}
unsafe fn _as_mut_slice(&mut self) -> &mut [Self] {
let slice = self.0.as_mut_slice();
slice::from_raw_parts_mut(slice.as_mut_ptr().cast(), slice.len())
}
fn as_vec(&self) -> &Vec<Mset> {
self.0.as_vec()
}
#[allow(deprecated)]
unsafe fn _as_mut_vec(&mut self) -> &mut Vec<Mset> {
self.0._as_mut_vec()
}
fn _flatten_vec(vec: Vec<Self>) -> Self {
Self::flatten(vec)
}
fn empty() -> Self {
Self(Mset::empty())
}
fn with_capacity(capacity: usize) -> Self {
Self(Mset::with_capacity(capacity))
}
fn singleton(self) -> Self {
Self(self.0.singleton())
}
fn into_singleton(self) -> Option<Self> {
self.0.into_singleton().map(Self)
}
fn insert_mut(&mut self, set: Self) {
self.try_insert(set);
}
fn select_mut<P: FnMut(&Set) -> bool>(&mut self, mut pred: P) {
self.0
.select_mut(|set| pred(unsafe { set.as_set_unchecked() }));
}
fn count(&self, other: &Self) -> usize {
usize::from(self.contains(other))
}
fn sum_vec(vec: Vec<Self>) -> Self {
Self::flatten(vec.into_iter().flatten().collect())
}
fn union_vec(vec: Vec<Self>) -> Self {
Self::sum_vec(vec)
}
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.iter().map(AsRef::as_ref));
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() {
if sets.insert(*set, (i, false)).is_some() {
unsafe { hint::unreachable_unchecked() }
}
}
for slice in iter {
for set in slice {
if let Entry::Occupied(mut entry) = sets.entry(*set) {
entry.get_mut().1 = true;
}
}
sets.retain(|_, (_, count)| {
let retain = *count;
*count = false;
retain
});
}
let mut fst = vec.swap_remove(0);
let mut snd = vec.swap_remove(0);
snd.clear();
for (i, _) in sets.into_values() {
let set = mem::take(unsafe { fst.as_mut_slice().get_unchecked_mut(i) });
snd.insert_mut(set);
}
Some(snd)
}
fn powerset(self) -> Self {
Self(self.0.powerset())
}
fn nat(n: usize) -> Self {
Self(Mset::nat(n))
}
fn zermelo(n: usize) -> Self {
Self(Mset::zermelo(n))
}
fn neumann(n: usize) -> Self {
Self(Mset::neumann(n))
}
fn into_choose(mut self) -> Option<Self> {
self.0 .0.pop().map(
|s| unsafe { s.into_set_unchecked() },
)
}
fn choose_uniq(&self) -> Option<&Self> {
self.0.choose_uniq().map(
|s| unsafe { s.as_set_unchecked() },
)
}
fn into_choose_uniq(self) -> Option<Self> {
self.0.into_choose_uniq().map(
|s| unsafe { s.into_set_unchecked() },
)
}
fn disjoint_iter<'a, I: IntoIterator<Item = &'a Self>>(iter: I) -> bool {
Mset::disjoint_iter(iter.into_iter().map(AsRef::as_ref))
}
fn disjoint_pairwise<'a, I: IntoIterator<Item = &'a Self>>(iter: I) -> bool {
!Levels::new_iter(iter.into_iter().map(AsRef::as_ref)).duplicate(1)
}
}
impl Set {
#[allow(deprecated)]
pub unsafe fn as_mut_slice(&mut self) -> &mut [Self] {
self._as_mut_slice()
}
pub unsafe fn as_mut_vec(&mut self) -> &mut Vec<Mset> {
&mut self.0 .0
}
pub unsafe fn iter_mut(&mut self) -> slice::IterMut<Self> {
self.as_mut_slice().iter_mut()
}
pub unsafe fn insert_mut_unchecked(&mut self, other: Self) {
self.0.insert_mut(other.0);
}
#[must_use]
pub unsafe fn insert_unchecked(mut self, other: Self) -> Self {
self.insert_mut_unchecked(other);
self
}
pub fn try_insert(&mut self, set: Self) -> bool {
let res = !self.contains(&set);
if res {
unsafe {
self.insert_mut_unchecked(set);
}
}
res
}
#[must_use]
pub unsafe fn pair_unchecked(self, other: Self) -> Self {
Self(self.0.pair(other.0))
}
#[must_use]
pub unsafe fn replace_unchecked<F: FnMut(&Self) -> Self>(&self, mut func: F) -> Self {
Self(self.0.replace(|set| func(set.as_set_unchecked()).0))
}
#[must_use]
pub unsafe fn into_replace_unchecked<F: FnMut(Self) -> Self>(self, mut func: F) -> Self {
Self(self.0.into_replace(|set| func(set.into_set_unchecked()).0))
}
}
pub enum Kpair<T> {
Same(T),
Distinct(T, T),
}
impl<T> Kpair<T> {
pub fn new(x: T, y: T) -> Self
where
T: PartialEq,
{
if x == y {
Self::Same(x)
} else {
Self::Distinct(x, y)
}
}
pub fn into_fst(self) -> T {
match self {
Self::Same(x) | Self::Distinct(x, _) => x,
}
}
pub fn into_snd(self) -> T {
match self {
Self::Same(x) | Self::Distinct(_, x) => x,
}
}
pub const fn fst(&self) -> &T {
match self {
Self::Same(x) | Self::Distinct(x, _) => x,
}
}
pub const fn snd(&self) -> &T {
match self {
Self::Same(x) | Self::Distinct(_, x) => x,
}
}
pub fn into_pair(self) -> (T, T)
where
T: Clone,
{
match self {
Self::Same(x) => (x.clone(), x),
Self::Distinct(x, y) => (x, y),
}
}
pub fn pair(self) -> (T, T)
where
T: Copy,
{
self.into_pair()
}
}
impl Set {
#[must_use]
pub fn id_kpair(self) -> Self {
self.singleton().singleton()
}
#[must_use]
pub unsafe fn kpair_unchecked(self, other: Self) -> Self {
let (x, y) = (self.0, other.0);
x.clone().singleton().pair(x.pair(y)).into_set_unchecked()
}
#[must_use]
pub fn kpair(self, other: Self) -> Self {
if self == other {
self.id_kpair()
} else {
unsafe { self.kpair_unchecked(other) }
}
}
#[must_use]
pub fn ksplit(&self) -> Option<Kpair<&Self>> {
match self.as_slice() {
[set] => match set.as_slice() {
[a] => Some(Kpair::Same(a)),
_ => None,
},
[fst, snd] => match (fst.as_slice(), snd.as_slice()) {
([a], [b, c]) | ([b, c], [a]) => {
if a == b {
Some(Kpair::Distinct(a, c))
} else if a == c {
Some(Kpair::Distinct(a, b))
} else {
None
}
}
_ => None,
},
_ => None,
}
}
#[must_use]
pub fn into_ksplit(mut self) -> Option<Kpair<Self>> {
unsafe {
match self.as_mut_slice() {
[set] => match set.as_mut_slice() {
[a] => Some(Kpair::Same(mem::take(a))),
_ => None,
},
[fst, snd] => match (fst.as_mut_slice(), snd.as_mut_slice()) {
([a], [b, c]) | ([b, c], [a]) => {
if a == b {
Some(Kpair::Distinct(mem::take(a), mem::take(c)))
} else if a == c {
Some(Kpair::Distinct(mem::take(a), mem::take(b)))
} else {
None
}
}
_ => None,
},
_ => None,
}
}
}
pub fn tag_union_iter<I: IntoIterator<Item = Self>>(iter: I) -> Self {
let mut union = Self::empty();
for set in iter {
unsafe {
for element in &set.as_slice()[1..] {
union.insert_mut_unchecked(set.clone().kpair(element.clone()));
}
if let Some(fst) = set.as_slice().first().cloned() {
union.insert_mut_unchecked(set.kpair(fst));
}
}
}
union
}
#[must_use]
pub fn tag_union_vec(vec: Vec<Self>) -> Self {
Self::tag_union_iter(vec)
}
#[must_use]
pub fn tag_union(self, other: Self) -> Self {
Self::tag_union_iter([self, other])
}
#[must_use]
pub fn prod(mut self, mut other: Self) -> Self {
let a = self.card();
let b = other.card();
if b < a {
mem::swap(&mut other, &mut self);
}
let mut prod = Self::with_capacity(a * b);
unsafe {
for (i, fst) in self.iter().enumerate() {
for (j, snd) in other.iter().enumerate() {
if i != j {
prod.insert_mut_unchecked(fst.clone().kpair(snd.clone()));
}
}
}
for (fst, snd) in self.into_iter().zip(other.into_iter()) {
prod.insert_mut_unchecked(fst.kpair(snd));
}
}
prod
}
}
impl Set {
fn dom_range<F: FnMut(Kpair<Self>) -> Self>(self, mut entry: F) -> Option<Vec<Self>> {
let mut vec = self.into_vec();
for set in &mut vec {
let s = mem::take(set);
*set = entry(s.into_ksplit()?);
}
Some(vec)
}
pub fn dom(self) -> Option<Self> {
self.dom_range(Kpair::into_fst).map(Self::flatten)
}
pub fn range(self) -> Option<Self> {
self.dom_range(Kpair::into_snd).map(Self::flatten)
}
pub unsafe fn dom_func(self) -> Option<Self> {
self.dom_range(Kpair::into_fst)
.map(|vec| Self::from_vec_unchecked(vec))
}
#[must_use]
pub fn eval(&self, set: &Self) -> Option<&Self> {
let mut cmp = Compare::new(set.mset());
self.iter().map_while(Set::ksplit).find_map(|pair| {
if cmp.eq(pair.fst().mset()) {
Some(pair.into_snd())
} else {
None
}
})
}
#[must_use]
pub fn into_eval(self, set: &Self) -> Option<Self> {
let mut cmp = Compare::new(set.mset());
self.into_iter()
.map_while(Set::into_ksplit)
.find_map(|pair| {
if cmp.eq(pair.fst().mset()) {
Some(pair.into_snd())
} else {
None
}
})
}
#[must_use]
pub fn id_func(self) -> Self {
unsafe { Self::from_vec_unchecked(self.into_iter().map(Set::id_kpair).collect()) }
}
#[must_use]
pub fn const_func(self, cst: Set) -> Self {
let mut func = Set::with_capacity(self.card());
let mut vec = self.into_vec();
unsafe {
for set in vec.drain(1..) {
func.insert_mut_unchecked(set.kpair(cst.clone()));
}
if let Some(fst) = vec.pop() {
func.insert_mut_unchecked(fst.kpair(cst));
}
}
func
}
#[must_use]
pub fn func(self, mut other: Self) -> Self {
let dom_card = self.card();
let cod_card = other.card();
if dom_card == 0 {
return Self::empty().singleton();
}
match cod_card {
0 => return Self::empty(),
1 => {
return Self::const_func(self, unsafe {
other.into_singleton().unwrap_unchecked()
})
.singleton();
}
_ => {}
}
let size = cod_card.pow(dom_card.try_into().expect("domain too large"));
let mut funcs = Self::with_capacity(size);
let mut indices = vec![0; dom_card];
for _ in 1..size {
let mut idx = dom_card - 1;
loop {
unsafe {
let index = indices.get_unchecked_mut(idx);
*index += 1;
if *index == cod_card {
*index = 0;
} else {
break;
}
idx = idx.unchecked_sub(1);
}
}
unsafe {
let mut func = Self::with_capacity(dom_card);
for (i, &j) in indices.iter().enumerate() {
func.insert_mut_unchecked(
self.as_slice()
.get_unchecked(i)
.clone()
.kpair(other.as_slice().get_unchecked(j).clone()),
);
}
funcs.insert_mut_unchecked(func);
}
}
unsafe {
funcs.insert_mut_unchecked(
self.const_func(mem::take(other.as_mut_slice().get_unchecked_mut(0))),
);
}
funcs
}
}