open_hypergraphs/lax/
open_hypergraph.rs1use super::hypergraph::*;
3
4#[derive(Debug, Clone)]
7pub struct OpenHypergraph<O, A> {
8 pub sources: Vec<NodeId>,
9 pub targets: Vec<NodeId>,
10 pub hypergraph: Hypergraph<O, A>,
11}
12
13impl<O, A> OpenHypergraph<O, A> {
15 pub fn empty() -> Self {
19 OpenHypergraph {
20 sources: vec![],
21 targets: vec![],
22 hypergraph: Hypergraph::empty(),
23 }
24 }
25
26 pub fn new_node(&mut self, w: O) -> NodeId {
28 self.hypergraph.new_node(w)
29 }
30
31 pub fn new_edge(&mut self, x: A, interface: Hyperedge) -> EdgeId {
32 self.hypergraph.new_edge(x, interface)
33 }
34
35 pub fn new_operation(
46 &mut self,
47 x: A,
48 source_type: Vec<O>,
49 target_type: Vec<O>,
50 ) -> (EdgeId, Interface) {
51 self.hypergraph.new_operation(x, source_type, target_type)
52 }
53
54 pub fn unify(&mut self, v: NodeId, w: NodeId) {
56 self.hypergraph.unify(v, w);
57 }
58
59 pub fn add_edge_source(&mut self, edge_id: EdgeId, w: O) -> NodeId {
60 self.hypergraph.add_edge_source(edge_id, w)
61 }
62
63 pub fn add_edge_target(&mut self, edge_id: EdgeId, w: O) -> NodeId {
64 self.hypergraph.add_edge_target(edge_id, w)
65 }
66}
67
68impl<O: Clone + PartialEq, A: Clone + PartialEq> OpenHypergraph<O, A> {
69 pub fn quotient(&mut self) {
72 let q = self.hypergraph.quotient();
74
75 self.sources
78 .iter_mut()
79 .for_each(|x| *x = NodeId(q.table[x.0]));
80 self.targets
81 .iter_mut()
82 .for_each(|x| *x = NodeId(q.table[x.0]));
83 }
84
85 pub fn to_open_hypergraph(mut self) -> crate::prelude::OpenHypergraph<O, A> {
88 use crate::array::vec::VecArray;
89 use crate::finite_function::FiniteFunction;
90 use crate::open_hypergraph::OpenHypergraph;
91
92 self.quotient();
93
94 let target = self.hypergraph.nodes.len();
95
96 let s = {
97 let table = self.sources.iter().map(|x| x.0).collect();
98 FiniteFunction::new(VecArray(table), target).expect("Valid by construction")
99 };
100
101 let t = {
102 let table = self.targets.iter().map(|x| x.0).collect();
103 FiniteFunction::new(VecArray(table), target).expect("Valid by construction")
104 };
105
106 let h = self.hypergraph.to_hypergraph();
107
108 OpenHypergraph::new(s, t, h).expect("any valid lax::Hypergraph must be quotientable!")
109 }
110}