open_hypergraphs/lax/var/
forget.rs1use crate::category::*;
8use crate::finite_function::FiniteFunction;
9use crate::lax::functor::*;
10use crate::lax::var::*;
11use crate::lax::*;
12
13pub fn forget<
15 O: Clone + PartialEq + std::fmt::Debug,
16 A: Clone + PartialEq + HasVar + std::fmt::Debug,
17>(
18 f: &OpenHypergraph<O, A>,
19) -> OpenHypergraph<O, A> {
20 Forget.map_arrow(f)
21}
22
23pub fn forget_monogamous<
25 O: Clone + PartialEq + std::fmt::Debug,
26 A: Clone + PartialEq + HasVar + std::fmt::Debug,
27>(
28 f: &OpenHypergraph<O, A>,
29) -> OpenHypergraph<O, A> {
30 ForgetMonogamous.map_arrow(f)
31}
32
33#[derive(Clone)]
47pub struct Forget;
48
49impl<O: Clone + PartialEq, A: HasVar + Clone + PartialEq> Functor<O, A, O, A> for Forget {
50 fn map_object(&self, o: &O) -> impl ExactSizeIterator<Item = O> {
52 std::iter::once(o.clone())
53 }
54
55 fn map_operation(&self, a: &A, source: &[O], target: &[O]) -> OpenHypergraph<O, A> {
56 if *a == HasVar::var() && all_elements_equal(source, target) {
58 if source.is_empty() && target.is_empty() {
60 return OpenHypergraph::empty();
61 }
62
63 let label = {
65 if source.is_empty() {
66 target[0].clone()
67 } else {
68 source[0].clone()
69 }
70 };
71
72 let s = FiniteFunction::terminal(source.len());
73 let t = FiniteFunction::terminal(target.len());
74
75 return OpenHypergraph::<O, A>::spider(s, t, vec![label]).unwrap();
76 }
77 OpenHypergraph::singleton(a.clone(), source.to_vec(), target.to_vec())
78 }
79
80 fn map_arrow(&self, f: &OpenHypergraph<O, A>) -> OpenHypergraph<O, A> {
81 define_map_arrow(self, f)
82 }
83}
84
85fn all_elements_equal<T: PartialEq>(a: &[T], b: &[T]) -> bool {
87 a.iter()
88 .chain(b.iter())
89 .all(|x| *x == *a.first().unwrap_or(x))
90}
91
92#[derive(Clone)]
94struct ForgetMonogamous;
95
96impl<O: Clone + PartialEq + std::fmt::Debug, A: HasVar + Clone + PartialEq + std::fmt::Debug>
97 Functor<O, A, O, A> for ForgetMonogamous
98{
99 fn map_object(&self, o: &O) -> impl ExactSizeIterator<Item = O> {
101 std::iter::once(o.clone())
102 }
103
104 fn map_operation(&self, a: &A, source: &[O], target: &[O]) -> OpenHypergraph<O, A> {
105 if source.len() != 1 || target.len() != 1 {
106 return OpenHypergraph::singleton(a.clone(), source.to_vec(), target.to_vec());
107 }
108
109 if *a == HasVar::var() && all_elements_equal(source, target) {
111 if source.is_empty() && target.is_empty() {
113 return OpenHypergraph::empty();
114 }
115
116 let label = {
118 if source.is_empty() {
119 target[0].clone()
120 } else {
121 source[0].clone()
122 }
123 };
124
125 let s = FiniteFunction::terminal(source.len());
126 let t = FiniteFunction::terminal(target.len());
127
128 return OpenHypergraph::<O, A>::spider(s, t, vec![label]).unwrap();
129 }
130 OpenHypergraph::singleton(a.clone(), source.to_vec(), target.to_vec())
131 }
132
133 fn map_arrow(&self, f: &OpenHypergraph<O, A>) -> OpenHypergraph<O, A> {
134 define_map_arrow(self, f)
135 }
136}