1use super::*;
2use crate::{
3 ambient_space::AffineSpace, partial_simplicial_complex::LabelledPartialSimplicialComplex,
4 simplex::Simplex, simplicial_disjoint_union::LabelledSimplicialDisjointUnion,
5};
6use std::collections::{HashMap, HashSet};
7
8pub trait LabelledSimplexCollection<
10 'f,
11 FS: OrderedRingSignature + FieldSignature + 'f,
12 T: Eq + Clone + Send + Sync,
13>: Sized where
14 FS::Set: Hash,
15{
16 type WithLabel<S: Eq + Clone + Send + Sync>: LabelledSimplexCollection<'f, FS, S>;
17 type SubsetType: LabelledSimplexCollection<'f, FS, T>;
18
19 fn try_new(
20 ambient_space: AffineSpace<'f, FS>,
21 simplexes: HashSet<Simplex<'f, FS>>,
22 ) -> Result<Self::WithLabel<()>, &'static str> {
23 Self::WithLabel::<()>::try_new_labelled(
24 ambient_space,
25 simplexes.into_iter().map(|spx| (spx, ())).collect(),
26 )
27 }
28 fn new_unchecked(
29 ambient_space: AffineSpace<'f, FS>,
30 simplexes: HashSet<Simplex<'f, FS>>,
31 ) -> Self::WithLabel<()> {
32 Self::WithLabel::<()>::new_labelled_unchecked(
33 ambient_space,
34 simplexes.into_iter().map(|spx| (spx, ())).collect(),
35 )
36 }
37
38 fn try_new_labelled(
39 ambient_space: AffineSpace<'f, FS>,
40 simplexes: HashMap<Simplex<'f, FS>, T>,
41 ) -> Result<Self, &'static str>;
42 fn new_labelled_unchecked(
43 ambient_space: AffineSpace<'f, FS>,
44 simplexes: HashMap<Simplex<'f, FS>, T>,
45 ) -> Self;
46
47 fn ambient_space(&self) -> AffineSpace<'f, FS>;
48
49 fn simplexes<'a>(&'a self) -> HashSet<&'a Simplex<'f, FS>>
50 where
51 T: 'a,
52 {
53 self.labelled_simplexes().into_keys().collect()
54 }
55 fn into_simplexes(self) -> HashSet<Simplex<'f, FS>> {
56 self.into_labelled_simplexes().into_keys().collect()
57 }
58
59 fn labelled_simplexes(&self) -> HashMap<&Simplex<'f, FS>, &T>;
60 fn into_labelled_simplexes(self) -> HashMap<Simplex<'f, FS>, T>;
61
62 fn subset_by_label(
63 &self,
64 label: &T,
65 ) -> <Self::SubsetType as LabelledSimplexCollection<'f, FS, T>>::WithLabel<()> {
66 self.subset_by_filter(|spx_label| spx_label == label)
67 .forget_labels()
68 }
69 fn into_subset_by_label(
70 self,
71 label: &T,
72 ) -> <Self::SubsetType as LabelledSimplexCollection<'f, FS, T>>::WithLabel<()> {
73 self.into_subset_by_filter(|spx_label| spx_label == label)
74 .forget_labels()
75 }
76 fn subset_by_filter(&self, f: impl Fn(&T) -> bool) -> Self::SubsetType {
77 Self::SubsetType::new_labelled_unchecked(
78 self.ambient_space(),
79 self.labelled_simplexes()
80 .into_iter()
81 .filter(|(_spx, label)| f(label))
82 .map(|(spx, label)| (spx.clone(), label.clone()))
83 .collect(),
84 )
85 }
86 fn into_subset_by_filter(self, f: impl Fn(&T) -> bool) -> Self::SubsetType {
87 Self::SubsetType::new_labelled_unchecked(
88 self.ambient_space(),
89 self.into_labelled_simplexes()
90 .into_iter()
91 .filter(|(_spx, label)| f(label))
92 .collect(),
93 )
94 }
95
96 fn into_partial_simplicial_complex(self) -> LabelledPartialSimplicialComplex<'f, FS, T>;
97 fn to_partial_simplicial_complex(&self) -> LabelledPartialSimplicialComplex<'f, FS, T>;
98
99 fn into_simplicial_disjoint_union(self) -> LabelledSimplicialDisjointUnion<'f, FS, T>;
100 fn to_simplicial_disjoint_union(&self) -> LabelledSimplicialDisjointUnion<'f, FS, T>;
101
102 fn apply_label_function<S: Eq + Clone + Send + Sync>(
103 &self,
104 f: impl Fn(&T) -> S,
105 ) -> Self::WithLabel<S> {
106 LabelledSimplexCollection::new_labelled_unchecked(
107 self.ambient_space(),
108 self.labelled_simplexes()
109 .into_iter()
110 .map(|(spx, label)| (spx.clone(), f(label)))
111 .collect(),
112 )
113 }
114 fn into_apply_label_function<S: Eq + Clone + Send + Sync>(
115 self,
116 f: impl Fn(T) -> S,
117 ) -> Self::WithLabel<S> {
118 LabelledSimplexCollection::new_labelled_unchecked(
119 self.ambient_space(),
120 self.into_labelled_simplexes()
121 .into_iter()
122 .map(|(spx, label)| (spx, f(label)))
123 .collect(),
124 )
125 }
126 fn forget_labels(&self) -> Self::WithLabel<()> {
127 self.apply_label_function(|_| ())
128 }
129 fn into_forget_labels(self) -> Self::WithLabel<()> {
130 self.into_apply_label_function(|_| ())
131 }
132
133 fn common_label<'a>(
134 &'a self,
135 simplexes: impl Iterator<Item = &'a Simplex<'f, FS>>,
136 ) -> Option<&'a T>
137 where
138 FS: 'a,
139 'f: 'a,
140 AffineSpace<'f, FS>: 'a,
141 {
142 let mut label = None;
143 for spx in simplexes {
144 let spx_label = *self.labelled_simplexes().get(&spx).unwrap();
145 match label {
146 Some(label) => {
147 if label != spx_label {
148 return None;
149 }
150 }
151 None => {
152 label = Some(spx_label);
153 }
154 }
155 }
156 label
157 }
158}
159
160#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
161pub enum InteriorOrBoundary {
162 Interior,
163 Boundary,
164}
165
166pub trait InteriorOrBoundarySimplexCollection<'f, FS: OrderedRingSignature + FieldSignature + 'f>:
167 LabelledSimplexCollection<'f, FS, InteriorOrBoundary>
168where
169 FS::Set: Hash,
170{
171 fn interior(
172 &self,
173 ) -> <Self::SubsetType as LabelledSimplexCollection<'f, FS, InteriorOrBoundary>>::WithLabel<()>
174 {
175 self.subset_by_label(&InteriorOrBoundary::Interior)
176 }
177
178 fn boundary(
179 &self,
180 ) -> <Self::SubsetType as LabelledSimplexCollection<'f, FS, InteriorOrBoundary>>::WithLabel<()>
181 {
182 self.subset_by_label(&InteriorOrBoundary::Boundary)
183 }
184}
185
186impl<
187 'f,
188 FS: OrderedRingSignature + FieldSignature + 'f,
189 S: LabelledSimplexCollection<'f, FS, InteriorOrBoundary>,
190> InteriorOrBoundarySimplexCollection<'f, FS> for S
191where
192 FS::Set: Hash,
193{
194}