open_hypergraphs/strict/hypergraph/
arrow.rs

1use super::object::Hypergraph;
2use crate::array::{Array, ArrayKind};
3use crate::finite_function::FiniteFunction;
4
5use core::fmt::Debug;
6
7#[derive(Debug)]
8pub enum InvalidHypergraphArrow {
9    NotNaturalW,
10    NotNaturalX,
11}
12
13pub struct HypergraphArrow<K: ArrayKind, O, A> {
14    /// Source hypergraph
15    pub source: Hypergraph<K, O, A>,
16
17    /// target hypergraph
18    pub target: Hypergraph<K, O, A>,
19
20    /// Natural transformation on wires
21    pub w: FiniteFunction<K>,
22
23    /// Natural transformation on operations
24    pub x: FiniteFunction<K>,
25}
26
27impl<K: ArrayKind, O, A> HypergraphArrow<K, O, A>
28where
29    K::Type<O>: Array<K, O>,
30    K::Type<A>: Array<K, A>,
31{
32    /// Safely create a new HypergraphArrow by checking naturality of `w` and `x`.
33    pub fn new(
34        source: Hypergraph<K, O, A>,
35        target: Hypergraph<K, O, A>,
36        w: FiniteFunction<K>,
37        x: FiniteFunction<K>,
38    ) -> Result<Self, InvalidHypergraphArrow> {
39        HypergraphArrow {
40            source,
41            target,
42            w,
43            x,
44        }
45        .validate()
46    }
47
48    /// Check validity of a HypergraphArrow.
49    pub fn validate(self) -> Result<Self, InvalidHypergraphArrow> {
50        // for self : g → h
51        let g = &self.source;
52        let h = &self.target;
53
54        // Naturality checks:
55        // wire labels, operation labels, and operation types should be preserved under the natural
56        // transformations w and x.
57
58        // Check naturality of w
59        if g.w != (&self.w >> &h.w).unwrap() {
60            return Err(InvalidHypergraphArrow::NotNaturalW);
61        }
62
63        // Check naturality of x
64        if g.x != (&self.x >> &h.x).unwrap() {
65            return Err(InvalidHypergraphArrow::NotNaturalX);
66        }
67
68        Ok(self)
69
70        // TODO: add this check.
71        // Types of operations are also preserved under w and x.
72        //assert_eq!(g.s.values >> g.w, h.s.indexed_values(f.x) >> h.w);
73        //assert_eq!(g.t.values >> g.w, h.t.indexed_values(f.x) >> h.w);
74    }
75}
76
77impl<K: ArrayKind, O: Debug, A: Debug> Debug for HypergraphArrow<K, O, A>
78where
79    K::Index: Debug,
80    K::Type<K::I>: Debug,
81    K::Type<A>: Debug,
82    K::Type<O>: Debug,
83{
84    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
85        f.debug_struct("HypergraphArrow")
86            .field("source", &self.source)
87            .field("target", &self.target)
88            .field("w", &self.w)
89            .field("x", &self.x)
90            .finish()
91    }
92}
93
94impl<K: ArrayKind, O: Debug, A: Debug> Clone for HypergraphArrow<K, O, A>
95where
96    K::Type<K::I>: Clone,
97    K::Type<A>: Clone,
98    K::Type<O>: Clone,
99{
100    fn clone(&self) -> Self {
101        Self {
102            source: self.source.clone(),
103            target: self.target.clone(),
104            w: self.w.clone(),
105            x: self.x.clone(),
106        }
107    }
108}