1use std::collections::HashMap;
4use std::hash::Hash;
5use std::marker::PhantomData;
6
7use derivative::Derivative;
8use indexmap::IndexMap;
9use nonempty::NonEmpty;
10use thiserror::Error;
11
12use super::set::{FinSet, Set, SkelFinSet};
13use crate::validate::{self, Validate};
14
15pub trait Mapping {
32 type Dom: Eq + Clone;
34
35 type Cod: Eq + Clone;
37
38 fn apply(&self, x: Self::Dom) -> Option<Self::Cod>;
40
41 fn apply_to_ref(&self, x: &Self::Dom) -> Option<Self::Cod> {
46 self.apply(x.clone())
47 }
48
49 fn is_set(&self, x: &Self::Dom) -> bool {
55 self.apply_to_ref(x).is_some()
56 }
57}
58
59pub trait MutMapping: Mapping {
64 fn get(&self, x: &Self::Dom) -> Option<&Self::Cod>;
69
70 fn set(&mut self, x: Self::Dom, y: Self::Cod) -> Option<Self::Cod>;
74
75 fn unset(&mut self, x: &Self::Dom) -> Option<Self::Cod>;
79
80 fn update(&mut self, x: Self::Dom, maybe_y: Option<Self::Cod>) -> Option<Self::Cod> {
84 match maybe_y {
85 Some(y) => self.set(x, y),
86 None => self.unset(&x),
87 }
88 }
89}
90
91pub trait Column: Mapping {
97 fn iter(&self) -> impl Iterator<Item = (Self::Dom, &Self::Cod)>;
99
100 fn values(&self) -> impl Iterator<Item = &Self::Cod> {
102 self.iter().map(|(_, y)| y)
103 }
104
105 fn preimage(&self, y: &Self::Cod) -> impl Iterator<Item = Self::Dom> {
111 self.iter().filter(|&(_, z)| *z == *y).map(|(x, _)| x)
112 }
113
114 fn len(&self) -> usize {
116 self.iter().count()
117 }
118
119 fn is_empty(&self) -> bool {
121 self.iter().next().is_none()
122 }
123}
124
125pub trait MutColumn:
130 MutMapping
131 + Column
132 + IntoIterator<Item = (Self::Dom, Self::Cod)>
133 + FromIterator<(Self::Dom, Self::Cod)>
134{
135 fn postcompose<F>(self, f: &F) -> Self
141 where
142 F: Mapping<Dom = Self::Cod, Cod = Self::Cod>,
143 {
144 self.into_iter().filter_map(|(x, y)| f.apply(y).map(|z| (x, z))).collect()
145 }
146}
147
148pub struct Function<'a, Map, Dom, Cod>(pub &'a Map, pub &'a Dom, pub &'a Cod);
153
154impl<'a, Map, Dom, Cod> Function<'a, Map, Dom, Cod>
155where
156 Map: Mapping,
157 Dom: FinSet<Elem = Map::Dom>,
158 Cod: Set<Elem = Map::Cod>,
159{
160 pub fn iter_invalid(
162 &self,
163 ) -> impl Iterator<Item = InvalidFunction<Map::Dom>> + 'a + use<'a, Map, Dom, Cod> {
164 let Function(mapping, dom, cod) = self;
165 dom.iter().filter_map(|x| match mapping.apply_to_ref(&x) {
166 Some(y) => {
167 if cod.contains(&y) {
168 None
169 } else {
170 Some(InvalidFunction::Cod(x))
171 }
172 }
173 None => Some(InvalidFunction::Dom(x)),
174 })
175 }
176}
177
178impl<Map, Dom, Cod> Validate for Function<'_, Map, Dom, Cod>
179where
180 Map: Mapping,
181 Dom: FinSet<Elem = Map::Dom>,
182 Cod: Set<Elem = Map::Cod>,
183{
184 type ValidationError = InvalidFunction<Map::Dom>;
185
186 fn validate(&self) -> Result<(), NonEmpty<Self::ValidationError>> {
187 validate::wrap_errors(self.iter_invalid())
188 }
189}
190
191#[derive(Debug, Error, PartialEq, Eq)]
193pub enum InvalidFunction<T> {
194 #[error("Mapping not defined at point `{0}` in domain")]
196 Dom(T),
197
198 #[error("Image of mapping at point `{0}` is not in codomain")]
200 Cod(T),
201}
202
203impl<T> InvalidFunction<T> {
204 pub(crate) fn take(self) -> T {
205 match self {
206 InvalidFunction::Dom(x) | InvalidFunction::Cod(x) => x,
207 }
208 }
209}
210
211pub fn retraction<Dom, Cod, InvMap>(
218 mapping: &impl Column<Dom = Dom, Cod = Cod>,
219) -> Result<InvMap, (Dom, Dom)>
220where
221 Dom: Clone,
222 Cod: Clone,
223 InvMap: MutMapping<Dom = Cod, Cod = Dom> + Default,
224{
225 let mut inv = InvMap::default();
226 for (x, y) in mapping.iter() {
227 if let Some(other_x) = inv.set(y.clone(), x.clone()) {
228 return Err((x, other_x));
229 }
230 }
231 Ok(inv)
232}
233
234#[derive(Clone, Debug, Derivative)]
236#[derivative(Default(bound = ""))]
237#[derivative(PartialEq(bound = "T: PartialEq"))]
238#[derivative(Eq(bound = "T: Eq"))]
239pub struct VecColumn<T>(Vec<Option<T>>);
240
241pub struct VecColumnIter<T> {
243 vec: Vec<Option<T>>,
244 index: usize,
245}
246
247impl<T> VecColumn<T> {
248 pub fn new(values: Vec<T>) -> Self {
250 Self(values.into_iter().map(Some).collect())
251 }
252}
253
254impl<T> Iterator for VecColumnIter<T> {
255 type Item = (usize, T);
256
257 fn next(&mut self) -> Option<Self::Item> {
258 let n = self.vec.len();
259 while self.index < n && self.vec[self.index].is_none() {
260 self.index += 1;
261 }
262 if self.index < n {
263 Some((self.index, self.vec[self.index].take().unwrap()))
264 } else {
265 None
266 }
267 }
268}
269
270impl<T> IntoIterator for VecColumn<T> {
271 type Item = (usize, T);
272 type IntoIter = VecColumnIter<T>;
273
274 fn into_iter(self) -> Self::IntoIter {
275 VecColumnIter { vec: self.0, index: 0 }
276 }
277}
278
279impl<T> FromIterator<(usize, T)> for VecColumn<T> {
280 fn from_iter<Iter: IntoIterator<Item = (usize, T)>>(iter: Iter) -> Self {
281 let mut vec = Vec::new();
282 for (i, y) in iter {
283 if i >= vec.len() {
284 vec.resize_with(i + 1, Default::default);
285 }
286 vec[i] = Some(y);
287 }
288 VecColumn(vec)
289 }
290}
291
292impl<T: Eq + Clone> Mapping for VecColumn<T> {
293 type Dom = usize;
294 type Cod = T;
295
296 fn apply(&self, i: usize) -> Option<T> {
297 self.0.get(i).cloned().flatten()
298 }
299
300 fn apply_to_ref(&self, i: &usize) -> Option<T> {
301 self.apply(*i)
302 }
303
304 fn is_set(&self, i: &usize) -> bool {
305 *i < self.0.len() && self.0[*i].is_some()
306 }
307}
308
309impl<T: Eq + Clone> MutMapping for VecColumn<T> {
310 fn get(&self, i: &usize) -> Option<&T> {
311 if *i < self.0.len() {
312 self.0[*i].as_ref()
313 } else {
314 None
315 }
316 }
317
318 fn set(&mut self, i: usize, y: T) -> Option<T> {
319 if i >= self.0.len() {
320 self.0.resize_with(i + 1, Default::default);
321 }
322 self.0[i].replace(y)
323 }
324
325 fn unset(&mut self, i: &usize) -> Option<T> {
326 if *i < self.0.len() {
327 self.0[*i].take()
328 } else {
329 None
330 }
331 }
332}
333
334impl<T: Eq + Clone> Column for VecColumn<T> {
335 fn iter(&self) -> impl Iterator<Item = (usize, &T)> {
336 let filtered = self.0.iter().enumerate().filter(|(_, y)| y.is_some());
337 filtered.map(|(i, y)| (i, y.as_ref().unwrap()))
338 }
339
340 fn values(&self) -> impl Iterator<Item = &Self::Cod> {
341 self.0.iter().flatten()
342 }
343
344 fn len(&self) -> usize {
345 self.0.iter().filter(|y| y.is_some()).count()
346 }
347
348 fn is_empty(&self) -> bool {
349 self.0.iter().all(|y| y.is_none())
350 }
351}
352
353impl<T: Eq + Clone> MutColumn for VecColumn<T> {}
354
355pub type SkelColumn = VecColumn<usize>;
357
358impl SkelColumn {
359 pub fn is_function(&self, m: usize, n: usize) -> bool {
361 let (dom, cod): (SkelFinSet, SkelFinSet) = (m.into(), n.into());
362 Function(self, &dom, &cod).iter_invalid().next().is_none()
363 }
364
365 pub fn is_partial_injection(&self) -> bool {
367 let result: Result<Self, _> = retraction(self);
368 result.is_ok()
369 }
370
371 pub fn is_injection(&self, m: usize, n: usize) -> bool {
373 self.is_function(m, n) && self.is_partial_injection()
374 }
375
376 pub fn is_permutation(&self, n: usize) -> bool {
378 self.is_injection(n, n)
379 }
380}
381
382#[derive(Clone, Debug, Derivative)]
388#[derivative(PartialEq(bound = "K: Eq + Hash, V: PartialEq"))]
389#[derivative(Eq(bound = "K: Eq + Hash, V: Eq"))]
390#[derivative(Default(bound = ""))]
391pub struct HashColumn<K, V>(IndexMap<K, V>);
392
393impl<K, V> IntoIterator for HashColumn<K, V> {
394 type Item = (K, V);
395 type IntoIter = indexmap::map::IntoIter<K, V>;
396
397 fn into_iter(self) -> Self::IntoIter {
398 self.0.into_iter()
399 }
400}
401
402impl<K, V> FromIterator<(K, V)> for HashColumn<K, V>
403where
404 K: Eq + Hash,
405{
406 fn from_iter<Iter: IntoIterator<Item = (K, V)>>(iter: Iter) -> Self {
407 HashColumn(IndexMap::from_iter(iter))
408 }
409}
410
411impl<K, V> Mapping for HashColumn<K, V>
412where
413 K: Eq + Hash + Clone,
414 V: Eq + Clone,
415{
416 type Dom = K;
417 type Cod = V;
418
419 fn apply(&self, x: K) -> Option<V> {
420 self.apply_to_ref(&x)
421 }
422 fn apply_to_ref(&self, x: &K) -> Option<V> {
423 self.0.get(x).cloned()
424 }
425 fn is_set(&self, x: &K) -> bool {
426 self.0.contains_key(x)
427 }
428}
429
430impl<K, V> MutMapping for HashColumn<K, V>
431where
432 K: Eq + Hash + Clone,
433 V: Eq + Clone,
434{
435 fn get(&self, x: &K) -> Option<&V> {
436 self.0.get(x)
437 }
438 fn set(&mut self, x: K, y: V) -> Option<V> {
439 self.0.insert(x, y)
440 }
441 fn unset(&mut self, x: &K) -> Option<V> {
442 self.0.swap_remove(x)
443 }
444}
445
446impl<K, V> Column for HashColumn<K, V>
447where
448 K: Eq + Hash + Clone,
449 V: Eq + Clone,
450{
451 fn iter(&self) -> impl Iterator<Item = (K, &V)> {
452 self.0.iter().map(|(k, v)| (k.clone(), v))
453 }
454 fn values(&self) -> impl Iterator<Item = &Self::Cod> {
455 self.0.values()
456 }
457 fn len(&self) -> usize {
458 self.0.len()
459 }
460 fn is_empty(&self) -> bool {
461 self.0.is_empty()
462 }
463}
464
465impl<K, V> MutColumn for HashColumn<K, V>
466where
467 K: Eq + Hash + Clone,
468 V: Eq + Clone,
469{
470}
471
472trait Index {
478 type Dom;
479 type Cod;
480
481 fn preimage(&self, y: &Self::Cod) -> impl Iterator<Item = Self::Dom>;
483
484 fn insert(&mut self, x: Self::Dom, y: &Self::Cod);
486
487 fn remove(&mut self, x: &Self::Dom, y: &Self::Cod);
491}
492
493#[derive(Clone, Debug, Derivative)]
495#[derivative(Default(bound = ""))]
496struct VecIndex<T>(Vec<Vec<T>>);
497
498impl<T: Eq + Clone> Index for VecIndex<T> {
499 type Dom = T;
500 type Cod = usize;
501
502 fn preimage(&self, y: &usize) -> impl Iterator<Item = T> {
503 let iter = match self.0.get(*y) {
504 Some(vec) => vec.iter(),
505 None => ([] as [T; 0]).iter(),
506 };
507 iter.cloned()
508 }
509
510 fn insert(&mut self, x: T, y: &usize) {
511 let i = *y;
512 if i >= self.0.len() {
513 self.0.resize_with(i + 1, Default::default);
514 }
515 self.0[i].push(x);
516 }
517
518 fn remove(&mut self, x: &T, y: &usize) {
519 let vec = &mut self.0[*y];
520 let i = vec.iter().rposition(|w| *w == *x).unwrap();
521 vec.remove(i);
522 }
523}
524
525#[derive(Clone, Debug, Derivative)]
527#[derivative(Default(bound = ""))]
528struct HashIndex<X, Y>(HashMap<Y, Vec<X>>);
529
530impl<X, Y> Index for HashIndex<X, Y>
531where
532 X: Eq + Clone,
533 Y: Eq + Hash + Clone,
534{
535 type Dom = X;
536 type Cod = Y;
537
538 fn preimage(&self, y: &Y) -> impl Iterator<Item = X> {
539 let iter = match self.0.get(y) {
540 Some(vec) => vec.iter(),
541 None => ([] as [X; 0]).iter(),
542 };
543 iter.cloned()
544 }
545
546 fn insert(&mut self, x: X, y: &Y) {
547 match self.0.get_mut(y) {
548 Some(vec) => {
549 vec.push(x);
550 }
551 None => {
552 self.0.insert(y.clone(), vec![x]);
553 }
554 }
555 }
556
557 fn remove(&mut self, x: &X, y: &Y) {
558 let vec = self.0.get_mut(y).unwrap();
559 let i = vec.iter().rposition(|w| *w == *x).unwrap();
560 vec.remove(i);
561 }
562}
563
564#[derive(Clone, Derivative, Debug)]
569#[derivative(PartialEq, Eq)]
570struct IndexedColumn<Dom, Cod, Col, Ind> {
571 mapping: Col,
572 #[derivative(PartialEq = "ignore")]
573 index: Ind,
574 dom_type: PhantomData<Dom>,
575 cod_type: PhantomData<Cod>,
576}
577
578impl<Dom, Cod, Col, Ind> Default for IndexedColumn<Dom, Cod, Col, Ind>
579where
580 Col: Default,
581 Ind: Default,
582{
583 fn default() -> Self {
584 Self {
585 mapping: Default::default(),
586 index: Default::default(),
587 dom_type: PhantomData,
588 cod_type: PhantomData,
589 }
590 }
591}
592
593impl<Dom, Cod, Col, Ind> IntoIterator for IndexedColumn<Dom, Cod, Col, Ind>
594where
595 Col: IntoIterator<Item = (Dom, Cod)>,
596{
597 type Item = (Dom, Cod);
598 type IntoIter = Col::IntoIter;
599
600 fn into_iter(self) -> Self::IntoIter {
601 self.mapping.into_iter()
602 }
603}
604
605impl<Dom, Cod, Col, Ind> FromIterator<(Dom, Cod)> for IndexedColumn<Dom, Cod, Col, Ind>
606where
607 Dom: Eq + Clone,
608 Cod: Eq + Clone,
609 Col: Default + MutMapping<Dom = Dom, Cod = Cod>,
610 Ind: Default + Index<Dom = Dom, Cod = Cod>,
611{
612 fn from_iter<Iter: IntoIterator<Item = (Dom, Cod)>>(iter: Iter) -> Self {
613 let mut col: Self = Default::default();
614 for (x, y) in iter {
615 col.set(x, y);
616 }
617 col
618 }
619}
620
621impl<Dom, Cod, Col, Ind> Mapping for IndexedColumn<Dom, Cod, Col, Ind>
622where
623 Dom: Eq + Clone,
624 Cod: Eq + Clone,
625 Col: Mapping<Dom = Dom, Cod = Cod>,
626{
627 type Dom = Dom;
628 type Cod = Cod;
629
630 fn apply(&self, x: Dom) -> Option<Cod> {
631 self.mapping.apply(x)
632 }
633 fn apply_to_ref(&self, x: &Dom) -> Option<Cod> {
634 self.mapping.apply_to_ref(x)
635 }
636 fn is_set(&self, x: &Dom) -> bool {
637 self.mapping.is_set(x)
638 }
639}
640
641impl<Dom, Cod, Col, Ind> MutMapping for IndexedColumn<Dom, Cod, Col, Ind>
642where
643 Dom: Eq + Clone,
644 Cod: Eq + Clone,
645 Col: MutMapping<Dom = Dom, Cod = Cod>,
646 Ind: Index<Dom = Dom, Cod = Cod>,
647{
648 fn get(&self, x: &Dom) -> Option<&Cod> {
649 self.mapping.get(x)
650 }
651
652 fn set(&mut self, x: Dom, y: Cod) -> Option<Cod> {
653 if let Some(y_prev) = self.mapping.get(&x) {
654 self.index.remove(&x, y_prev);
655 }
656 self.index.insert(x.clone(), &y);
657 self.mapping.set(x, y)
658 }
659
660 fn unset(&mut self, x: &Dom) -> Option<Cod> {
661 let old = self.mapping.unset(x);
662 if let Some(y) = &old {
663 self.index.remove(x, y);
664 }
665 old
666 }
667}
668
669impl<Dom, Cod, Col, Ind> Column for IndexedColumn<Dom, Cod, Col, Ind>
670where
671 Dom: Eq + Clone,
672 Cod: Eq + Clone,
673 Col: Column<Dom = Dom, Cod = Cod>,
674 Ind: Index<Dom = Dom, Cod = Cod>,
675{
676 fn iter(&self) -> impl Iterator<Item = (Dom, &Cod)> {
677 self.mapping.iter()
678 }
679 fn values(&self) -> impl Iterator<Item = &Self::Cod> {
680 self.mapping.values()
681 }
682 fn preimage(&self, y: &Cod) -> impl Iterator<Item = Dom> {
683 self.index.preimage(y)
684 }
685 fn len(&self) -> usize {
686 self.mapping.len()
687 }
688 fn is_empty(&self) -> bool {
689 self.mapping.is_empty()
690 }
691}
692
693#[derive(Clone, Debug, Derivative, PartialEq, Eq, Default)]
698pub struct SkelIndexedColumn(IndexedColumn<usize, usize, VecColumn<usize>, VecIndex<usize>>);
699
700impl SkelIndexedColumn {
701 pub fn new(values: &[usize]) -> Self {
703 let mut col: Self = Default::default();
704 for (x, y) in values.iter().enumerate() {
705 col.set(x, *y);
706 }
707 col
708 }
709}
710
711impl IntoIterator for SkelIndexedColumn {
712 type Item = (usize, usize);
713 type IntoIter = VecColumnIter<usize>;
714
715 fn into_iter(self) -> Self::IntoIter {
716 self.0.into_iter()
717 }
718}
719
720impl FromIterator<(usize, usize)> for SkelIndexedColumn {
721 fn from_iter<Iter: IntoIterator<Item = (usize, usize)>>(iter: Iter) -> Self {
722 Self(IndexedColumn::from_iter(iter))
723 }
724}
725
726impl Mapping for SkelIndexedColumn {
727 type Dom = usize;
728 type Cod = usize;
729
730 fn apply(&self, x: usize) -> Option<usize> {
731 self.0.apply(x)
732 }
733 fn apply_to_ref(&self, x: &usize) -> Option<usize> {
734 self.0.apply(*x)
735 }
736 fn is_set(&self, x: &usize) -> bool {
737 self.0.is_set(x)
738 }
739}
740
741impl MutMapping for SkelIndexedColumn {
742 fn get(&self, x: &usize) -> Option<&usize> {
743 self.0.get(x)
744 }
745 fn set(&mut self, x: usize, y: usize) -> Option<usize> {
746 self.0.set(x, y)
747 }
748 fn unset(&mut self, x: &usize) -> Option<usize> {
749 self.0.unset(x)
750 }
751}
752
753impl Column for SkelIndexedColumn {
754 fn iter(&self) -> impl Iterator<Item = (usize, &usize)> {
755 self.0.iter()
756 }
757 fn values(&self) -> impl Iterator<Item = &Self::Cod> {
758 self.0.values()
759 }
760 fn preimage(&self, y: &usize) -> impl Iterator<Item = usize> {
761 self.0.preimage(y)
762 }
763 fn len(&self) -> usize {
764 self.0.len()
765 }
766 fn is_empty(&self) -> bool {
767 self.0.is_empty()
768 }
769}
770
771impl MutColumn for SkelIndexedColumn {}
772
773#[derive(Clone, Debug, Derivative, PartialEq, Eq)]
778#[derivative(Default(bound = ""))]
779pub struct IndexedVecColumn<T>(IndexedColumn<usize, T, VecColumn<T>, HashIndex<usize, T>>);
780
781impl<T: Eq + Hash + Clone> IndexedVecColumn<T> {
782 pub fn new(values: &[T]) -> Self {
784 values.iter().cloned().enumerate().collect()
785 }
786}
787
788impl<T> IntoIterator for IndexedVecColumn<T> {
789 type Item = (usize, T);
790 type IntoIter = VecColumnIter<T>;
791
792 fn into_iter(self) -> Self::IntoIter {
793 self.0.into_iter()
794 }
795}
796
797impl<T: Eq + Hash + Clone> FromIterator<(usize, T)> for IndexedVecColumn<T> {
798 fn from_iter<Iter: IntoIterator<Item = (usize, T)>>(iter: Iter) -> Self {
799 Self(IndexedColumn::from_iter(iter))
800 }
801}
802
803impl<T: Eq + Hash + Clone> Mapping for IndexedVecColumn<T> {
804 type Dom = usize;
805 type Cod = T;
806
807 fn apply(&self, x: usize) -> Option<T> {
808 self.0.apply(x)
809 }
810 fn apply_to_ref(&self, x: &usize) -> Option<T> {
811 self.0.apply(*x)
812 }
813 fn is_set(&self, x: &usize) -> bool {
814 self.0.is_set(x)
815 }
816}
817
818impl<T: Eq + Hash + Clone> MutMapping for IndexedVecColumn<T> {
819 fn get(&self, x: &usize) -> Option<&T> {
820 self.0.get(x)
821 }
822 fn set(&mut self, x: usize, y: T) -> Option<T> {
823 self.0.set(x, y)
824 }
825 fn unset(&mut self, x: &usize) -> Option<T> {
826 self.0.unset(x)
827 }
828}
829
830impl<T: Eq + Hash + Clone> Column for IndexedVecColumn<T> {
831 fn iter(&self) -> impl Iterator<Item = (usize, &T)> {
832 self.0.iter()
833 }
834 fn values(&self) -> impl Iterator<Item = &Self::Cod> {
835 self.0.values()
836 }
837 fn preimage(&self, y: &T) -> impl Iterator<Item = usize> {
838 self.0.preimage(y)
839 }
840 fn len(&self) -> usize {
841 self.0.len()
842 }
843 fn is_empty(&self) -> bool {
844 self.0.is_empty()
845 }
846}
847
848impl<T: Eq + Hash + Clone> MutColumn for IndexedVecColumn<T> {}
849
850#[derive(Clone, Derivative, Debug)]
852#[derivative(Default(bound = ""))]
853#[derivative(PartialEq(bound = "K: Eq + Hash, V: PartialEq"))]
854#[derivative(Eq(bound = "K: Eq + Hash, V: Eq"))]
855pub struct IndexedHashColumn<K, V>(IndexedColumn<K, V, HashColumn<K, V>, HashIndex<K, V>>);
856
857impl<K, V> IntoIterator for IndexedHashColumn<K, V>
858where
859 K: Eq + Hash,
860 V: Eq + Hash,
861{
862 type Item = (K, V);
863 type IntoIter = <HashColumn<K, V> as IntoIterator>::IntoIter;
864
865 fn into_iter(self) -> Self::IntoIter {
866 self.0.into_iter()
867 }
868}
869
870impl<K, V> FromIterator<(K, V)> for IndexedHashColumn<K, V>
871where
872 K: Eq + Hash + Clone,
873 V: Eq + Hash + Clone,
874{
875 fn from_iter<Iter: IntoIterator<Item = (K, V)>>(iter: Iter) -> Self {
876 Self(IndexedColumn::from_iter(iter))
877 }
878}
879
880impl<K, V> Mapping for IndexedHashColumn<K, V>
881where
882 K: Eq + Hash + Clone,
883 V: Eq + Hash + Clone,
884{
885 type Dom = K;
886 type Cod = V;
887
888 fn apply(&self, x: K) -> Option<V> {
889 self.0.apply(x)
890 }
891 fn apply_to_ref(&self, x: &K) -> Option<V> {
892 self.0.apply_to_ref(x)
893 }
894 fn is_set(&self, x: &K) -> bool {
895 self.0.is_set(x)
896 }
897}
898
899impl<K, V> MutMapping for IndexedHashColumn<K, V>
900where
901 K: Eq + Hash + Clone,
902 V: Eq + Hash + Clone,
903{
904 fn get(&self, x: &K) -> Option<&V> {
905 self.0.get(x)
906 }
907 fn set(&mut self, x: K, y: V) -> Option<V> {
908 self.0.set(x, y)
909 }
910 fn unset(&mut self, x: &K) -> Option<V> {
911 self.0.unset(x)
912 }
913}
914
915impl<K, V> Column for IndexedHashColumn<K, V>
916where
917 K: Eq + Hash + Clone,
918 V: Eq + Hash + Clone,
919{
920 fn iter(&self) -> impl Iterator<Item = (K, &V)> {
921 self.0.iter()
922 }
923 fn values(&self) -> impl Iterator<Item = &Self::Cod> {
924 self.0.values()
925 }
926 fn preimage(&self, y: &V) -> impl Iterator<Item = K> {
927 self.0.preimage(y)
928 }
929 fn len(&self) -> usize {
930 self.0.len()
931 }
932 fn is_empty(&self) -> bool {
933 self.0.is_empty()
934 }
935}
936
937impl<K, V> MutColumn for IndexedHashColumn<K, V>
938where
939 K: Eq + Hash + Clone,
940 V: Eq + Hash + Clone,
941{
942}
943
944#[cfg(test)]
945mod tests {
946 use super::*;
947
948 #[test]
949 fn vec_column() {
950 let mut col = VecColumn::new(vec!["foo", "bar", "baz"]);
951 assert!(!col.is_empty());
952 assert_eq!(col.len(), 3);
953 assert!(col.is_set(&2));
954 assert_eq!(col.apply(2), Some("baz"));
955 assert_eq!(col.apply(3), None);
956 assert_eq!(col.apply_to_ref(&2), Some("baz"));
957 assert_eq!(col.get(&2), Some(&"baz"));
958 assert_eq!(col.update(2, None), Some("baz"));
959 assert!(!col.is_set(&2));
960
961 col.set(5, "baz");
962 col.set(3, "bar");
963 let preimage: Vec<_> = col.preimage(&"bar").collect();
964 assert_eq!(preimage, vec![1, 3]);
965
966 let data: Vec<_> = col.clone().into_iter().collect();
967 assert_eq!(data, vec![(0, "foo"), (1, "bar"), (3, "bar"), (5, "baz")]);
968 let new_col: VecColumn<_> = data.into_iter().collect();
969 assert_eq!(new_col, col);
970 }
971
972 #[test]
973 fn hash_column() {
974 let mut col: HashColumn<char, &str> = Default::default();
975 assert!(col.is_empty());
976 col.set('a', "foo");
977 col.set('b', "bar");
978 col.set('c', "baz");
979 assert!(!col.is_empty());
980 assert_eq!(col.len(), 3);
981 assert_eq!(col.apply('c'), Some("baz"));
982 assert_eq!(col.apply_to_ref(&'c'), Some("baz"));
983 assert_eq!(col.get(&'c'), Some(&"baz"));
984 assert_eq!(col.unset(&'c'), Some("baz"));
985 assert!(!col.is_set(&'c'));
986 col.set('c', "bar");
987
988 let mut preimage: Vec<_> = col.preimage(&"bar").collect();
989 preimage.sort();
990 assert_eq!(preimage, vec!['b', 'c']);
991
992 let mut data: Vec<_> = col.clone().into_iter().collect();
993 data.sort();
994 assert_eq!(data, vec![('a', "foo"), ('b', "bar"), ('c', "bar")]);
995 let new_col: HashColumn<_, _> = data.into_iter().collect();
996 assert_eq!(new_col, col);
997 }
998
999 #[test]
1000 fn skel_function_properties() {
1001 let map = SkelColumn::new(vec![1, 3, 5]);
1002 assert!(!map.is_function(3, 5));
1003 assert!(map.is_injection(3, 6));
1004 let map = SkelColumn::new(vec![0, 1, 0]);
1005 assert!(map.is_function(3, 2));
1006 assert!(!map.is_injection(3, 2));
1007 let map = SkelColumn::new(vec![3, 1, 2, 0]);
1008 assert!(map.is_permutation(4));
1009 }
1010
1011 #[test]
1012 fn skel_indexed_column() {
1013 let mut col = SkelIndexedColumn::new(&[1, 3, 5]);
1014 assert!(!col.is_empty());
1015 assert_eq!(col.len(), 3);
1016 assert!(col.is_set(&2));
1017 assert_eq!(col.apply(2), Some(5));
1018 assert_eq!(col.apply_to_ref(&2), Some(5));
1019 assert_eq!(col.get(&2), Some(&5));
1020 let preimage: Vec<_> = col.preimage(&5).collect();
1021 assert_eq!(preimage, vec![2]);
1022
1023 assert_eq!(col.set(0, 5), Some(1));
1024 assert_eq!(col.preimage(&1).count(), 0);
1025 let mut preimage: Vec<_> = col.preimage(&5).collect();
1026 preimage.sort();
1027 assert_eq!(preimage, vec![0, 2]);
1028
1029 let new_col: SkelIndexedColumn = col.clone().into_iter().collect();
1030 assert_eq!(new_col, col);
1031 }
1032
1033 #[test]
1034 fn indexed_vec_column() {
1035 let mut col = IndexedVecColumn::new(&["foo", "bar", "baz"]);
1036 assert!(!col.is_empty());
1037 assert_eq!(col.len(), 3);
1038 assert!(col.is_set(&2));
1039 assert_eq!(col.apply(2), Some("baz"));
1040 let preimage: Vec<_> = col.preimage(&"baz").collect();
1041 assert_eq!(preimage, vec![2]);
1042
1043 assert_eq!(col.set(0, "baz"), Some("foo"));
1044 assert_eq!(col.preimage(&"foo").count(), 0);
1045 let mut preimage: Vec<_> = col.preimage(&"baz").collect();
1046 preimage.sort();
1047 assert_eq!(preimage, vec![0, 2]);
1048
1049 let new_col: IndexedVecColumn<_> = col.clone().into_iter().collect();
1050 assert_eq!(new_col, col);
1051 }
1052
1053 #[test]
1054 fn indexed_hash_column() {
1055 let mut col: IndexedHashColumn<char, &str> = Default::default();
1056 assert!(col.is_empty());
1057 col.set('a', "foo");
1058 col.set('b', "bar");
1059 col.set('c', "baz");
1060 assert!(!col.is_empty());
1061 assert_eq!(col.len(), 3);
1062 assert_eq!(col.apply('c'), Some("baz"));
1063 let preimage: Vec<_> = col.preimage(&"baz").collect();
1064 assert_eq!(preimage, vec!['c']);
1065
1066 assert_eq!(col.set('a', "baz"), Some("foo"));
1067 assert_eq!(col.preimage(&"foo").count(), 0);
1068 let mut preimage: Vec<_> = col.preimage(&"baz").collect();
1069 preimage.sort();
1070 assert_eq!(preimage, vec!['a', 'c']);
1071
1072 let new_col: IndexedHashColumn<_, _> = col.clone().into_iter().collect();
1073 assert_eq!(new_col, col);
1074 }
1075
1076 #[test]
1077 fn validate_function() {
1078 let col = VecColumn::new(vec![1, 2, 4]);
1079 let validate = |m, n| Function(&col, &SkelFinSet::from(m), &SkelFinSet::from(n)).validate();
1080 assert!(validate(3, 5).is_ok());
1081 assert_eq!(validate(4, 5).unwrap_err(), NonEmpty::new(InvalidFunction::Dom::<usize>(3)));
1082 assert_eq!(validate(3, 4).unwrap_err(), NonEmpty::new(InvalidFunction::Cod::<usize>(2)));
1083 }
1084}