open_hypergraphs/lax/
open_hypergraph.rs1use super::hypergraph::*;
3use crate::array::vec::VecKind;
4
5#[derive(Debug, Clone)]
8#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9#[cfg_attr(
10 feature = "serde",
11 serde(
12 bound = "O: serde::Serialize + serde::de::DeserializeOwned, A: serde::Serialize + serde::de::DeserializeOwned"
13 )
14)]
15pub struct OpenHypergraph<O, A> {
16 pub sources: Vec<NodeId>,
17 pub targets: Vec<NodeId>,
18 pub hypergraph: Hypergraph<O, A>,
19}
20
21impl<O, A> OpenHypergraph<O, A> {
23 pub fn empty() -> Self {
27 OpenHypergraph {
28 sources: vec![],
29 targets: vec![],
30 hypergraph: Hypergraph::empty(),
31 }
32 }
33
34 pub fn from_strict(f: crate::strict::open_hypergraph::OpenHypergraph<VecKind, O, A>) -> Self {
35 let sources = f.s.table.0.into_iter().map(NodeId).collect();
36 let targets = f.t.table.0.into_iter().map(NodeId).collect();
37 let hypergraph = Hypergraph::from_strict(f.h);
38 OpenHypergraph {
39 sources,
40 targets,
41 hypergraph,
42 }
43 }
44
45 pub fn new_node(&mut self, w: O) -> NodeId {
47 self.hypergraph.new_node(w)
48 }
49
50 pub fn new_edge(&mut self, x: A, interface: Hyperedge) -> EdgeId {
51 self.hypergraph.new_edge(x, interface)
52 }
53
54 pub fn new_operation(
65 &mut self,
66 x: A,
67 source_type: Vec<O>,
68 target_type: Vec<O>,
69 ) -> (EdgeId, Interface) {
70 self.hypergraph.new_operation(x, source_type, target_type)
71 }
72
73 pub fn singleton(x: A, source_type: Vec<O>, target_type: Vec<O>) -> Self {
75 let mut f = Self::empty();
76 let (_, (s, t)) = f.new_operation(x, source_type, target_type);
77 f.sources = s;
78 f.targets = t;
79 f
80 }
81
82 pub fn unify(&mut self, v: NodeId, w: NodeId) {
84 self.hypergraph.unify(v, w);
85 }
86
87 pub fn add_edge_source(&mut self, edge_id: EdgeId, w: O) -> NodeId {
88 self.hypergraph.add_edge_source(edge_id, w)
89 }
90
91 pub fn add_edge_target(&mut self, edge_id: EdgeId, w: O) -> NodeId {
92 self.hypergraph.add_edge_target(edge_id, w)
93 }
94}
95
96impl<O: Clone + PartialEq, A: Clone> OpenHypergraph<O, A> {
97 pub fn quotient(&mut self) {
100 let q = self.hypergraph.quotient();
102
103 self.sources
106 .iter_mut()
107 .for_each(|x| *x = NodeId(q.table[x.0]));
108 self.targets
109 .iter_mut()
110 .for_each(|x| *x = NodeId(q.table[x.0]));
111 }
112
113 pub fn to_strict(mut self) -> crate::strict::OpenHypergraph<VecKind, O, A> {
116 use crate::array::vec::VecArray;
117 use crate::finite_function::FiniteFunction;
118 use crate::strict::open_hypergraph::OpenHypergraph;
119
120 self.quotient();
121
122 let target = self.hypergraph.nodes.len();
123
124 let s = {
125 let table = self.sources.iter().map(|x| x.0).collect();
126 FiniteFunction::new(VecArray(table), target).expect("Valid by construction")
127 };
128
129 let t = {
130 let table = self.targets.iter().map(|x| x.0).collect();
131 FiniteFunction::new(VecArray(table), target).expect("Valid by construction")
132 };
133
134 let h = self.hypergraph.to_hypergraph();
135
136 OpenHypergraph::new(s, t, h).expect("any valid lax::Hypergraph must be quotientable!")
137 }
138
139 #[deprecated(since = "0.2.4", note = "renamed to_strict")]
141 pub fn to_open_hypergraph(self) -> crate::strict::OpenHypergraph<VecKind, O, A> {
142 self.to_strict()
143 }
144}