algebraeon_geometry/simplexes/
simplex_collection.rs

1use std::collections::{HashMap, HashSet};
2
3use super::*;
4
5pub trait LabelledSimplexCollection<
6    FS: OrderedRingStructure + FieldStructure,
7    SP: Borrow<AffineSpace<FS>> + Clone,
8    T: Eq + Clone,
9>: Sized where
10    FS::Set: Hash,
11{
12    type WithLabel<S: Eq + Clone>: LabelledSimplexCollection<FS, SP, S>;
13    type SubsetType: LabelledSimplexCollection<FS, SP, T>;
14
15    fn new(
16        ambient_space: SP,
17        simplexes: HashSet<Simplex<FS, SP>>,
18    ) -> Result<Self::WithLabel<()>, &'static str> {
19        Self::WithLabel::<()>::new_labelled(
20            ambient_space,
21            simplexes.into_iter().map(|spx| (spx, ())).collect(),
22        )
23    }
24    fn new_unchecked(
25        ambient_space: SP,
26        simplexes: HashSet<Simplex<FS, SP>>,
27    ) -> Self::WithLabel<()> {
28        Self::WithLabel::<()>::new_labelled_unchecked(
29            ambient_space,
30            simplexes.into_iter().map(|spx| (spx, ())).collect(),
31        )
32    }
33
34    fn new_labelled(
35        ambient_space: SP,
36        simplexes: HashMap<Simplex<FS, SP>, T>,
37    ) -> Result<Self, &'static str>;
38    fn new_labelled_unchecked(ambient_space: SP, simplexes: HashMap<Simplex<FS, SP>, T>) -> Self;
39
40    fn ambient_space(&self) -> SP;
41
42    fn simplexes<'a>(&'a self) -> HashSet<&'a Simplex<FS, SP>>
43    where
44        T: 'a,
45    {
46        self.labelled_simplexes()
47            .into_iter()
48            .map(|(spx, _)| spx)
49            .collect()
50    }
51    fn into_simplexes(self) -> HashSet<Simplex<FS, SP>> {
52        self.into_labelled_simplexes()
53            .into_iter()
54            .map(|(spx, _)| spx)
55            .collect()
56    }
57
58    fn labelled_simplexes(&self) -> HashMap<&Simplex<FS, SP>, &T>;
59    fn into_labelled_simplexes(self) -> HashMap<Simplex<FS, SP>, T>;
60
61    fn subset_by_label(
62        &self,
63        label: &T,
64    ) -> <Self::SubsetType as LabelledSimplexCollection<FS, SP, T>>::WithLabel<()> {
65        self.subset_by_filter(|spx_label| spx_label == label)
66            .forget_labels()
67    }
68    fn into_subset_by_label(
69        self,
70        label: &T,
71    ) -> <Self::SubsetType as LabelledSimplexCollection<FS, SP, T>>::WithLabel<()> {
72        self.into_subset_by_filter(|spx_label| spx_label == label)
73            .forget_labels()
74    }
75    fn subset_by_filter(&self, f: impl Fn(&T) -> bool) -> Self::SubsetType {
76        Self::SubsetType::new_labelled_unchecked(
77            self.ambient_space(),
78            self.labelled_simplexes()
79                .into_iter()
80                .filter(|(_spx, label)| f(label))
81                .map(|(spx, label)| (spx.clone(), label.clone()))
82                .collect(),
83        )
84    }
85    fn into_subset_by_filter(self, f: impl Fn(&T) -> bool) -> Self::SubsetType {
86        Self::SubsetType::new_labelled_unchecked(
87            self.ambient_space(),
88            self.into_labelled_simplexes()
89                .into_iter()
90                .filter(|(_spx, label)| f(label))
91                .collect(),
92        )
93    }
94
95    fn into_partial_simplicial_complex(self) -> LabelledPartialSimplicialComplex<FS, SP, T>;
96
97    fn apply_label_function<S: Eq + Clone>(&self, f: impl Fn(&T) -> S) -> Self::WithLabel<S> {
98        LabelledSimplexCollection::new_labelled_unchecked(
99            self.ambient_space(),
100            self.labelled_simplexes()
101                .into_iter()
102                .map(|(spx, label)| (spx.clone(), f(label)))
103                .collect(),
104        )
105    }
106    fn into_apply_label_function<S: Eq + Clone>(self, f: impl Fn(T) -> S) -> Self::WithLabel<S> {
107        LabelledSimplexCollection::new_labelled_unchecked(
108            self.ambient_space(),
109            self.into_labelled_simplexes()
110                .into_iter()
111                .map(|(spx, label)| (spx, f(label)))
112                .collect(),
113        )
114    }
115    fn forget_labels(&self) -> Self::WithLabel<()> {
116        self.apply_label_function(|_| ())
117    }
118    fn into_forget_labels(self) -> Self::WithLabel<()> {
119        self.into_apply_label_function(|_| ())
120    }
121
122    fn common_label<'a>(
123        &'a self,
124        simplexes: impl Iterator<Item = &'a Simplex<FS, SP>>,
125    ) -> Option<&'a T>
126    where
127        FS: 'a,
128        SP: 'a,
129    {
130        let mut label = None;
131        for spx in simplexes {
132            let spx_label = *self.labelled_simplexes().get(&spx).unwrap();
133            match label {
134                Some(label) => {
135                    if label != spx_label {
136                        return None;
137                    }
138                }
139                None => {
140                    label = Some(spx_label);
141                }
142            }
143        }
144        label
145    }
146}