algebraeon_geometry/simplexes/
simplex_collection.rs1use 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}