1use std::hash::Hash;
9
10use derivative::Derivative;
11use derive_more::{Constructor, From};
12use nonempty::NonEmpty;
13use ref_cast::RefCast;
14use thiserror::Error;
15use ustr::Ustr;
16
17use crate::validate::{self, Validate};
18use crate::zero::*;
19
20pub trait Graph {
26 type V: Eq + Clone;
28
29 type E: Eq + Clone;
31
32 fn has_vertex(&self, v: &Self::V) -> bool;
34
35 fn has_edge(&self, e: &Self::E) -> bool;
37
38 fn src(&self, e: &Self::E) -> Self::V;
40
41 fn tgt(&self, e: &Self::E) -> Self::V;
43}
44
45pub trait FinGraph: Graph {
47 fn vertices(&self) -> impl Iterator<Item = Self::V>;
49
50 fn edges(&self) -> impl Iterator<Item = Self::E>;
52
53 fn in_edges(&self, v: &Self::V) -> impl Iterator<Item = Self::E> {
58 self.edges().filter(|e| self.tgt(e) == *v)
59 }
60
61 fn out_edges(&self, v: &Self::V) -> impl Iterator<Item = Self::E> {
66 self.edges().filter(|e| self.src(e) == *v)
67 }
68
69 fn out_neighbors(&self, v: &Self::V) -> impl Iterator<Item = Self::V> {
73 self.out_edges(v).map(|e| self.tgt(&e))
74 }
75
76 fn in_neighbors(&self, v: &Self::V) -> impl Iterator<Item = Self::V> {
80 self.in_edges(v).map(|e| self.src(&e))
81 }
82
83 fn vertex_count(&self) -> usize {
85 self.vertices().count()
86 }
87
88 fn edge_count(&self) -> usize {
90 self.edges().count()
91 }
92
93 fn in_degree(&self, v: &Self::V) -> usize {
95 self.in_edges(v).count()
96 }
97
98 fn out_degree(&self, v: &Self::V) -> usize {
100 self.out_edges(v).count()
101 }
102
103 fn degree(&self, v: &Self::V) -> usize {
107 self.in_degree(v) + self.out_degree(v)
108 }
109}
110
111pub trait ReflexiveGraph: Graph {
115 fn refl(&self, v: Self::V) -> Self::E;
117}
118
119#[derive(From, RefCast)]
121#[repr(transparent)]
122pub struct VertexSet<G>(G);
123
124impl<G: Graph> Set for VertexSet<G> {
125 type Elem = G::V;
126
127 fn contains(&self, v: &Self::Elem) -> bool {
128 self.0.has_vertex(v)
129 }
130}
131
132impl<G: FinGraph> FinSet for VertexSet<G> {
133 fn iter(&self) -> impl Iterator<Item = Self::Elem> {
134 self.0.vertices()
135 }
136 fn len(&self) -> usize {
137 self.0.vertex_count()
138 }
139}
140
141pub trait ColumnarGraph {
150 type V: Eq + Clone;
152
153 type E: Eq + Clone;
155
156 type Vertices: Set<Elem = Self::V>;
158
159 type Edges: Set<Elem = Self::E>;
161
162 type Src: Mapping<Dom = Self::E, Cod = Self::V>;
164
165 type Tgt: Mapping<Dom = Self::E, Cod = Self::V>;
167
168 fn vertex_set(&self) -> &Self::Vertices;
170
171 fn edge_set(&self) -> &Self::Edges;
173
174 fn src_map(&self) -> &Self::Src;
176
177 fn tgt_map(&self) -> &Self::Tgt;
179
180 fn iter_invalid(&self) -> impl Iterator<Item = InvalidGraph<Self::E>>
182 where
183 Self::Edges: FinSet<Elem = Self::E>,
184 {
185 let (dom, cod) = (self.edge_set(), self.vertex_set());
186 let srcs = Function(self.src_map(), dom, cod)
187 .iter_invalid()
188 .map(|e| InvalidGraph::Src(e.take()));
189 let tgts = Function(self.tgt_map(), dom, cod)
190 .iter_invalid()
191 .map(|e| InvalidGraph::Tgt(e.take()));
192 srcs.chain(tgts)
193 }
194}
195
196pub trait ColumnarFinGraph:
202 ColumnarGraph<
203 Vertices: FinSet<Elem = Self::V>,
204 Edges: FinSet<Elem = Self::E>,
205 Src: Column<Dom = Self::E, Cod = Self::V>,
206 Tgt: Column<Dom = Self::E, Cod = Self::V>,
207 >
208{
209}
210
211pub trait MutColumnarGraph:
213 ColumnarGraph<
214 Src: MutMapping<Dom = Self::E, Cod = Self::V>,
215 Tgt: MutMapping<Dom = Self::E, Cod = Self::V>,
216 >
217{
218 fn src_map_mut(&mut self) -> &mut Self::Src;
221
222 fn tgt_map_mut(&mut self) -> &mut Self::Tgt;
225
226 fn get_src(&self, e: &Self::E) -> Option<&Self::V> {
228 self.src_map().get(e)
229 }
230
231 fn get_tgt(&self, e: &Self::E) -> Option<&Self::V> {
233 self.tgt_map().get(e)
234 }
235
236 fn set_src(&mut self, e: Self::E, v: Self::V) -> Option<Self::V> {
238 self.src_map_mut().set(e, v)
239 }
240
241 fn set_tgt(&mut self, e: Self::E, v: Self::V) -> Option<Self::V> {
243 self.tgt_map_mut().set(e, v)
244 }
245}
246
247impl<G: ColumnarGraph> Graph for G {
248 type V = G::V;
249 type E = G::E;
250
251 fn has_vertex(&self, v: &Self::V) -> bool {
252 self.vertex_set().contains(v)
253 }
254 fn has_edge(&self, e: &Self::E) -> bool {
255 self.edge_set().contains(e)
256 }
257 fn src(&self, e: &Self::E) -> Self::V {
258 self.src_map().apply_to_ref(e).expect("Source of edge should be set")
259 }
260 fn tgt(&self, e: &Self::E) -> Self::V {
261 self.tgt_map().apply_to_ref(e).expect("Target of edge should be set")
262 }
263}
264
265impl<G: ColumnarFinGraph> FinGraph for G {
266 fn vertices(&self) -> impl Iterator<Item = Self::V> {
267 self.vertex_set().iter()
268 }
269 fn edges(&self) -> impl Iterator<Item = Self::E> {
270 self.edge_set().iter()
271 }
272 fn in_edges(&self, v: &Self::V) -> impl Iterator<Item = Self::E> {
273 self.tgt_map().preimage(v)
274 }
275 fn out_edges(&self, v: &Self::V) -> impl Iterator<Item = Self::E> {
276 self.src_map().preimage(v)
277 }
278 fn vertex_count(&self) -> usize {
279 self.vertex_set().len()
280 }
281 fn edge_count(&self) -> usize {
282 self.edge_set().len()
283 }
284}
285
286#[derive(Debug, Error)]
291pub enum InvalidGraph<E> {
292 #[error("Source of edge `{0}` is not a vertex in the graph")]
294 Src(E),
295
296 #[error("Target of edge `{0}` is not a vertex in the graph")]
298 Tgt(E),
299}
300
301#[derive(Clone, Default, PartialEq, Eq)]
306pub struct SkelGraph {
307 nv: usize,
308 ne: usize,
309 src_map: SkelIndexedColumn,
310 tgt_map: SkelIndexedColumn,
311}
312
313impl ColumnarGraph for SkelGraph {
314 type V = usize;
315 type E = usize;
316
317 type Vertices = SkelFinSet;
318 type Edges = SkelFinSet;
319 type Src = SkelIndexedColumn;
320 type Tgt = SkelIndexedColumn;
321
322 fn vertex_set(&self) -> &Self::Vertices {
323 SkelFinSet::ref_cast(&self.nv)
324 }
325 fn edge_set(&self) -> &Self::Edges {
326 SkelFinSet::ref_cast(&self.ne)
327 }
328 fn src_map(&self) -> &Self::Src {
329 &self.src_map
330 }
331 fn tgt_map(&self) -> &Self::Tgt {
332 &self.tgt_map
333 }
334}
335
336impl MutColumnarGraph for SkelGraph {
337 fn src_map_mut(&mut self) -> &mut Self::Src {
338 &mut self.src_map
339 }
340 fn tgt_map_mut(&mut self) -> &mut Self::Tgt {
341 &mut self.tgt_map
342 }
343}
344
345impl ColumnarFinGraph for SkelGraph {}
346
347impl SkelGraph {
348 pub fn add_vertex(&mut self) -> usize {
350 let v = self.nv;
351 self.nv += 1;
352 v
353 }
354
355 pub fn add_vertices(&mut self, n: usize) -> std::ops::Range<usize> {
357 let start = self.nv;
358 self.nv += n;
359 start..(self.nv)
360 }
361
362 pub fn add_edge(&mut self, src: usize, tgt: usize) -> usize {
364 let e = self.make_edge();
365 self.src_map.set(e, src);
366 self.tgt_map.set(e, tgt);
367 e
368 }
369
370 pub fn make_edge(&mut self) -> usize {
372 let e = self.ne;
373 self.ne += 1;
374 e
375 }
376
377 #[cfg(test)]
379 pub fn path(n: usize) -> Self {
380 let mut g: Self = Default::default();
381 g.add_vertices(n);
382 for (i, j) in std::iter::zip(0..(n - 1), 1..n) {
383 g.add_edge(i, j);
384 }
385 g
386 }
387
388 #[cfg(test)]
390 pub fn triangle() -> Self {
391 let mut g: Self = Default::default();
392 g.add_vertices(3);
393 g.add_edge(0, 1);
394 g.add_edge(1, 2);
395 g.add_edge(0, 2);
396 g
397 }
398
399 #[cfg(test)]
401 pub fn cycle(n: usize) -> Self {
402 assert!(n > 0);
403 let mut g = SkelGraph::path(n);
404 g.add_edge(n - 1, 0);
405 g
406 }
407}
408
409impl Validate for SkelGraph {
410 type ValidationError = InvalidGraph<usize>;
411
412 fn validate(&self) -> Result<(), NonEmpty<Self::ValidationError>> {
413 validate::wrap_errors(self.iter_invalid())
414 }
415}
416
417#[derive(Clone, Derivative, Debug)]
422#[derivative(PartialEq(bound = "V: Eq + Hash, E: Eq + Hash"))]
423#[derivative(Eq(bound = "V: Eq + Hash, E: Eq + Hash"))]
424#[derivative(Default(bound = ""))]
425pub struct HashGraph<V, E> {
426 vertex_set: HashFinSet<V>,
427 edge_set: HashFinSet<E>,
428 src_map: IndexedHashColumn<E, V>,
429 tgt_map: IndexedHashColumn<E, V>,
430}
431
432pub type UstrGraph = HashGraph<Ustr, Ustr>;
434
435impl<V, E> ColumnarGraph for HashGraph<V, E>
436where
437 V: Eq + Hash + Clone,
438 E: Eq + Hash + Clone,
439{
440 type V = V;
441 type E = E;
442
443 type Vertices = HashFinSet<V>;
444 type Edges = HashFinSet<E>;
445 type Src = IndexedHashColumn<E, V>;
446 type Tgt = IndexedHashColumn<E, V>;
447
448 fn vertex_set(&self) -> &Self::Vertices {
449 &self.vertex_set
450 }
451 fn edge_set(&self) -> &Self::Edges {
452 &self.edge_set
453 }
454 fn src_map(&self) -> &Self::Src {
455 &self.src_map
456 }
457 fn tgt_map(&self) -> &Self::Tgt {
458 &self.tgt_map
459 }
460}
461
462impl<V, E> MutColumnarGraph for HashGraph<V, E>
463where
464 V: Eq + Hash + Clone,
465 E: Eq + Hash + Clone,
466{
467 fn src_map_mut(&mut self) -> &mut Self::Src {
468 &mut self.src_map
469 }
470 fn tgt_map_mut(&mut self) -> &mut Self::Tgt {
471 &mut self.tgt_map
472 }
473}
474
475impl<V, E> ColumnarFinGraph for HashGraph<V, E>
476where
477 V: Eq + Hash + Clone,
478 E: Eq + Hash + Clone,
479{
480}
481
482impl<V, E> HashGraph<V, E>
483where
484 V: Eq + Hash + Clone,
485 E: Eq + Hash + Clone,
486{
487 pub fn add_vertex(&mut self, v: V) -> bool {
489 self.vertex_set.insert(v)
490 }
491
492 pub fn add_vertices<T>(&mut self, iter: T)
494 where
495 T: IntoIterator<Item = V>,
496 {
497 self.vertex_set.extend(iter)
498 }
499
500 pub fn add_edge(&mut self, e: E, src: V, tgt: V) -> bool {
504 self.src_map.set(e.clone(), src);
505 self.tgt_map.set(e.clone(), tgt);
506 self.make_edge(e)
507 }
508
509 pub fn make_edge(&mut self, e: E) -> bool {
511 self.edge_set.insert(e)
512 }
513}
514
515impl<V, E> Validate for HashGraph<V, E>
516where
517 V: Eq + Hash + Clone,
518 E: Eq + Hash + Clone,
519{
520 type ValidationError = InvalidGraph<E>;
521
522 fn validate(&self) -> Result<(), NonEmpty<Self::ValidationError>> {
523 validate::wrap_errors(self.iter_invalid())
524 }
525}
526
527pub trait GraphMapping {
537 type DomV: Eq + Clone;
539
540 type DomE: Eq + Clone;
542
543 type CodV: Eq + Clone;
545
546 type CodE: Eq + Clone;
548
549 type VertexMap: Mapping<Dom = Self::DomV, Cod = Self::CodV>;
551
552 type EdgeMap: Mapping<Dom = Self::DomE, Cod = Self::CodE>;
554
555 fn vertex_map(&self) -> &Self::VertexMap;
557
558 fn edge_map(&self) -> &Self::EdgeMap;
560
561 fn apply_vertex(&self, v: Self::DomV) -> Option<Self::CodV> {
563 self.vertex_map().apply(v)
564 }
565
566 fn apply_edge(&self, e: Self::DomE) -> Option<Self::CodE> {
568 self.edge_map().apply(e)
569 }
570
571 fn is_vertex_assigned(&self, v: &Self::DomV) -> bool {
573 self.vertex_map().is_set(v)
574 }
575
576 fn is_edge_assigned(&self, e: &Self::DomE) -> bool {
578 self.edge_map().is_set(e)
579 }
580}
581
582pub struct GraphMorphism<'a, Map, Dom, Cod>(pub &'a Map, pub &'a Dom, pub &'a Cod);
588
589impl<'a, Map, Dom, Cod> GraphMorphism<'a, Map, Dom, Cod>
590where
591 Map: GraphMapping,
592 Map::DomE: Clone,
593 Dom: FinGraph<V = Map::DomV, E = Map::DomE>,
594 Cod: Graph<V = Map::CodV, E = Map::CodE>,
595{
596 pub fn iter_invalid(
598 &self,
599 ) -> impl Iterator<Item = InvalidGraphMorphism<Map::DomV, Map::DomE>> + 'a + use<'a, Map, Dom, Cod>
600 {
601 let GraphMorphism(mapping, dom, cod) = *self;
602 let vertex_errors = dom.vertices().filter_map(|v| {
603 if mapping.vertex_map().apply_to_ref(&v).is_some_and(|w| cod.has_vertex(&w)) {
604 None
605 } else {
606 Some(InvalidGraphMorphism::Vertex(v))
607 }
608 });
609
610 let edge_errors = dom.edges().flat_map(|e| {
611 if let Some(f) = mapping.edge_map().apply_to_ref(&e)
612 && cod.has_edge(&f)
613 {
614 let mut errs = Vec::new();
615 if mapping.apply_vertex(dom.src(&e)).is_some_and(|v| v != cod.src(&f)) {
616 errs.push(InvalidGraphMorphism::Src(e.clone()))
617 }
618 if mapping.apply_vertex(dom.tgt(&e)).is_some_and(|v| v != cod.tgt(&f)) {
619 errs.push(InvalidGraphMorphism::Tgt(e.clone()))
620 }
621 return errs;
622 }
623 vec![InvalidGraphMorphism::Edge(e)]
624 });
625
626 vertex_errors.chain(edge_errors)
627 }
628}
629
630impl<Map, Dom, Cod> Validate for GraphMorphism<'_, Map, Dom, Cod>
631where
632 Map: GraphMapping,
633 Map::DomE: Clone,
634 Dom: FinGraph<V = Map::DomV, E = Map::DomE>,
635 Cod: Graph<V = Map::CodV, E = Map::CodE>,
636{
637 type ValidationError = InvalidGraphMorphism<Map::DomV, Map::DomE>;
638
639 fn validate(&self) -> Result<(), NonEmpty<Self::ValidationError>> {
640 validate::wrap_errors(self.iter_invalid())
641 }
642}
643
644#[derive(Debug, Error)]
647pub enum InvalidGraphMorphism<V, E> {
648 #[error("Vertex `{0}` is not mapped to a vertex in the codomain")]
650 Vertex(V),
651
652 #[error("Edge `{0}` is not mapped to an edge in the codomain")]
654 Edge(E),
655
656 #[error("Mapping of edge `{0}` does not preserve its source")]
658 Src(E),
659
660 #[error("Mapping of edge `{0}` does not preserve its target")]
662 Tgt(E),
663}
664
665#[derive(Clone, Debug, Default, PartialEq, Eq, Constructor)]
670pub struct ColumnarGraphMapping<VMap, EMap> {
671 vertex_map: VMap,
672 edge_map: EMap,
673}
674
675impl<VMap, EMap> GraphMapping for ColumnarGraphMapping<VMap, EMap>
676where
677 VMap: Mapping,
678 EMap: Mapping,
679{
680 type DomV = VMap::Dom;
681 type DomE = EMap::Dom;
682 type CodV = VMap::Cod;
683 type CodE = EMap::Cod;
684 type VertexMap = VMap;
685 type EdgeMap = EMap;
686
687 fn vertex_map(&self) -> &Self::VertexMap {
688 &self.vertex_map
689 }
690 fn edge_map(&self) -> &Self::EdgeMap {
691 &self.edge_map
692 }
693}
694
695pub type SkelGraphMapping = ColumnarGraphMapping<VecColumn<usize>, VecColumn<usize>>;
697
698impl SkelGraphMapping {
699 pub fn from_vec(vertex_map: Vec<usize>, edge_map: Vec<usize>) -> Self {
701 Self::new(VecColumn::new(vertex_map), VecColumn::new(edge_map))
702 }
703}
704
705#[derive(Clone, Debug, PartialEq, Eq)]
710pub enum GraphElem<V, E> {
711 Vertex(V),
713
714 Edge(E),
716}
717
718#[cfg(test)]
719mod tests {
720 use super::*;
721
722 #[test]
723 fn skel_graph() {
724 let g = SkelGraph::triangle();
725 assert_eq!(g.vertex_count(), 3);
726 assert_eq!(g.edge_count(), 3);
727 assert_eq!(g.src(&1), 1);
728 assert_eq!(g.tgt(&1), 2);
729 assert_eq!(g.out_edges(&0).collect::<Vec<_>>(), vec![0, 2]);
730 assert_eq!(g.in_edges(&2).collect::<Vec<_>>(), vec![1, 2]);
731 assert_eq!(g.out_degree(&0), 2);
732 assert_eq!(g.in_degree(&2), 2);
733 assert_eq!(g.degree(&1), 2);
734 }
735
736 #[test]
737 fn hash_graph() {
738 let mut g: HashGraph<char, &str> = Default::default();
739 assert!(g.add_vertex('x'));
740 g.add_vertices(['y', 'z']);
741 assert!(g.add_edge("f", 'x', 'y'));
742 assert!(g.add_edge("g", 'y', 'z'));
743 assert!(g.make_edge("fg"));
744 g.set_src("fg", 'x');
745 g.set_tgt("fg", 'z');
746 assert_eq!(g.src(&"fg"), 'x');
747 assert_eq!(g.tgt(&"fg"), 'z');
748 }
749
750 #[test]
751 fn vertex_set() {
752 let set: VertexSet<_> = SkelGraph::triangle().into();
753 assert!(set.contains(&2));
754 assert_eq!(set.len(), 3);
755 }
756
757 #[test]
758 fn validate_columnar_graph() {
759 let mut g = SkelGraph::triangle();
760 assert!(g.validate().is_ok());
761 g.src_map.set(2, 3); assert!(g.validate().is_err());
763 assert_eq!(g.add_vertex(), 3); assert!(g.validate().is_ok());
765 }
766
767 #[test]
768 fn validate_graph_morphism() {
769 let g = SkelGraph::path(3);
770 let h = SkelGraph::path(4);
771 let f = SkelGraphMapping::from_vec(vec![1, 2, 3], vec![1, 2]);
772 assert!(GraphMorphism(&f, &g, &h).validate().is_ok());
773
774 let f = SkelGraphMapping::from_vec(vec![1, 2, 3], vec![2, 1]); assert!(GraphMorphism(&f, &g, &h).validate().is_err());
776 }
777}