1use core::cmp::Ordering::{Equal, Greater, Less};
4use std::cmp::Ordering;
5use std::collections::HashMap;
6use std::hash::Hash;
7
8use variadics::variadic_collections::VariadicSet;
9use variadics::{CloneVariadic, PartialEqVariadic, SplitBySuffix, VariadicExt, var_expr, var_type};
10
11use crate::ght::{GeneralizedHashTrieNode, GhtGet, GhtInner, GhtLeaf};
12use crate::{IsBot, IsTop, LatticeBimorphism, LatticeOrd, Merge};
13
14impl<Head, Node> Merge<GhtInner<Head, Node>> for GhtInner<Head, Node>
15where
16 Node: GeneralizedHashTrieNode + Merge<Node>,
17 Node::Storage: VariadicSet<Schema = Node::Schema>, Self: GeneralizedHashTrieNode,
19 Head: Hash + Eq + Clone,
20{
21 fn merge(&mut self, other: GhtInner<Head, Node>) -> bool {
22 let mut changed = false;
23
24 for (k, v) in other.children {
25 match self.children.entry(k) {
26 std::collections::hash_map::Entry::Occupied(mut occupied) => {
27 changed |= occupied.get_mut().merge_node(v);
28 }
29 std::collections::hash_map::Entry::Vacant(vacant) => {
30 vacant.insert(v);
31 changed = true;
32 }
33 }
34 }
35 changed
36 }
37}
38
39impl<Schema, ValType, Storage> Merge<GhtLeaf<Schema, ValType, Storage>>
40 for GhtLeaf<Schema, ValType, Storage>
41where
42 Schema: Eq + Hash,
43 Storage: VariadicSet<Schema = Schema> + Extend<Schema> + IntoIterator<Item = Schema>,
44{
45 fn merge(&mut self, other: GhtLeaf<Schema, ValType, Storage>) -> bool {
46 let old_len = self.elements.len();
47 self.elements.extend(other.elements);
48 self.elements.len() > old_len
49 }
50}
51
52impl<Head, Node> PartialEq<GhtInner<Head, Node>> for GhtInner<Head, Node>
53where
54 Head: Hash + Eq + 'static + Clone,
55 Node: GeneralizedHashTrieNode + 'static + PartialEq,
56 Node::Storage: VariadicSet<Schema = Node::Schema>, Node::Schema: SplitBySuffix<var_type!(Head, ...Node::SuffixSchema)>,
58 GhtInner<Head, Node>: GhtGet,
59 <GhtInner<Head, Node> as GhtGet>::Get: PartialEq,
60{
61 fn eq(&self, other: &GhtInner<Head, Node>) -> bool {
62 if self.children.len() != other.children.len() {
63 return false;
64 }
65
66 for head in self.iter() {
67 let other_node = other.get(&head);
68 if other_node.is_none() {
69 return false;
70 }
71 let this_node = self.get(&head);
72 if this_node.is_none() {
73 return false;
74 }
75 if this_node.unwrap() != other_node.unwrap() {
76 return false;
77 }
78 }
79 true
80 }
81}
82
83impl<Head, Node> PartialOrd<GhtInner<Head, Node>> for GhtInner<Head, Node>
84where
85 Head: Hash + Eq + 'static + Clone,
86 Node: 'static + GeneralizedHashTrieNode + PartialEq + PartialOrd,
87 Node::Storage: VariadicSet<Schema = Node::Schema>, Node::Schema: SplitBySuffix<var_type!(Head, ...Node::SuffixSchema)>,
89{
90 fn partial_cmp(&self, other: &GhtInner<Head, Node>) -> Option<Ordering> {
91 let mut self_any_greater = false;
92 let mut other_any_greater = false;
93 if self.children.is_empty() && other.children.is_empty() {
94 Some(Equal)
95 } else {
96 for k in self.children.keys().chain(other.children.keys()) {
97 match (self.children.get(k), other.children.get(k)) {
98 (Some(self_value), Some(other_value)) => {
99 match self_value.partial_cmp(other_value)? {
100 Greater => {
101 self_any_greater = true;
102 }
103 Less => {
104 other_any_greater = true;
105 }
106 Equal => {}
107 }
108 }
109 (Some(_), None) => {
110 self_any_greater = true;
111 }
112 (None, Some(_)) => {
113 other_any_greater = true;
114 }
115 (None, None) => unreachable!(),
116 }
117 }
118 match (self_any_greater, other_any_greater) {
119 (true, false) => Some(Greater),
120 (false, true) => Some(Less),
121 (false, false) => Some(Equal),
122 (true, true) => unreachable!(),
123 }
124 }
125 }
126}
127
128impl<Schema, SuffixSchema, Storage> PartialOrd<GhtLeaf<Schema, SuffixSchema, Storage>>
129 for GhtLeaf<Schema, SuffixSchema, Storage>
130where
131 Schema: Eq + Hash + PartialEqVariadic,
132 SuffixSchema: Eq + Hash,
133 Storage: VariadicSet<Schema = Schema> + PartialEq,
134{
135 fn partial_cmp(&self, other: &GhtLeaf<Schema, SuffixSchema, Storage>) -> Option<Ordering> {
136 match self.elements.len().cmp(&other.elements.len()) {
137 Greater => {
138 if other.elements.iter().all(|tup| self.elements.contains(tup)) {
139 Some(Greater)
140 } else {
141 None
142 }
143 }
144 Equal => {
145 if self
146 .elements
147 .iter()
148 .all(|head| other.elements.contains(head))
149 {
150 Some(Equal)
151 } else {
152 None
153 }
154 }
155 Less => {
156 if self
157 .elements
158 .iter()
159 .all(|head| other.elements.contains(head))
160 {
161 Some(Less)
162 } else {
163 None
164 }
165 }
166 }
167 }
168}
169
170impl<Head, Node> LatticeOrd<GhtInner<Head, Node>> for GhtInner<Head, Node>
171where
172 Self: PartialOrd<GhtInner<Head, Node>>,
173 Head: Clone,
174 Node: GeneralizedHashTrieNode,
175 Node::Storage: VariadicSet<Schema = Node::Schema>, {
177}
178impl<Schema, SuffixSchema, Storage> LatticeOrd<GhtLeaf<Schema, SuffixSchema, Storage>>
179 for GhtLeaf<Schema, SuffixSchema, Storage>
180where
181 Schema: Eq + Hash + PartialEqVariadic,
182 SuffixSchema: Eq + Hash,
183 Storage: VariadicSet<Schema = Schema> + PartialEq,
184{
185}
186
187impl<Head, Node> IsBot for GhtInner<Head, Node>
188where
189 Head: Clone,
190 Node: GeneralizedHashTrieNode + IsBot,
191{
192 fn is_bot(&self) -> bool {
193 self.children.iter().all(|(_, v)| v.is_bot())
194 }
195}
196
197impl<Schema, SuffixSchema, Storage> IsBot for GhtLeaf<Schema, SuffixSchema, Storage>
198where
199 Schema: Eq + Hash,
200 SuffixSchema: Eq + Hash,
201 Storage: VariadicSet<Schema = Schema>,
202{
203 fn is_bot(&self) -> bool {
204 self.elements.is_empty()
205 }
206}
207
208impl<Head, Node> IsTop for GhtInner<Head, Node>
209where
210 Head: Clone,
211 Node: GeneralizedHashTrieNode,
212 Node::Storage: VariadicSet<Schema = Node::Schema>, {
214 fn is_top(&self) -> bool {
215 false
216 }
217}
218
219impl<Schema, SuffixSchema, Storage> IsTop for GhtLeaf<Schema, SuffixSchema, Storage>
220where
221 Schema: Eq + Hash,
222 SuffixSchema: Eq + Hash,
223 Storage: VariadicSet<Schema = Schema>,
224{
225 fn is_top(&self) -> bool {
226 false
227 }
228}
229
230pub struct GhtCartesianProductBimorphism<GhtOut> {
241 _phantom: std::marker::PhantomData<fn() -> GhtOut>,
242}
243impl<GhtOut> Default for GhtCartesianProductBimorphism<GhtOut> {
244 fn default() -> Self {
245 Self {
246 _phantom: Default::default(),
247 }
248 }
249}
250impl<'a, 'b, GhtA, GhtB, GhtOut> LatticeBimorphism<&'a GhtA, &'b GhtB>
251 for GhtCartesianProductBimorphism<GhtOut>
252where
253 GhtA: GeneralizedHashTrieNode,
254 GhtA::Storage: VariadicSet<Schema = GhtA::Schema>, GhtB: GeneralizedHashTrieNode,
256 GhtB::Storage: VariadicSet<Schema = GhtB::Schema>, GhtOut: FromIterator<var_type!(...GhtA::SuffixSchema, ...GhtB::SuffixSchema)>,
258 GhtA::SuffixSchema: CloneVariadic,
259 GhtB::SuffixSchema: CloneVariadic,
260{
261 type Output = GhtOut;
262
263 fn call(&mut self, ght_a: &'a GhtA, ght_b: &'b GhtB) -> Self::Output {
264 ght_a.recursive_iter().flat_map(|a| {
265 let (_a_prefix, a_suffix) = <GhtA::Schema as SplitBySuffix<GhtA::SuffixSchema>>::split_by_suffix_ref(a);
266 ght_b
267 .recursive_iter()
268 .map(move |b| {
269 let (_b_prefix, b_suffix) = <GhtB::Schema as SplitBySuffix<GhtB::SuffixSchema>>::split_by_suffix_ref(b);
270 var_expr!(...<GhtA::SuffixSchema as CloneVariadic>::clone_ref_var(a_suffix), ...<GhtB::SuffixSchema as CloneVariadic>::clone_ref_var(b_suffix))
271 })
272 }).collect()
273 }
274}
275
276pub struct GhtValTypeProductBimorphism<GhtOut> {
279 _phantom: std::marker::PhantomData<fn() -> GhtOut>,
280}
281impl<GhtOut> Default for GhtValTypeProductBimorphism<GhtOut> {
282 fn default() -> Self {
283 Self {
284 _phantom: Default::default(),
285 }
286 }
287}
288impl<'a, 'b, GhtA, GhtB, GhtOut> LatticeBimorphism<&'a GhtA, &'b GhtB>
289 for GhtValTypeProductBimorphism<GhtOut>
290where
291 GhtA: GeneralizedHashTrieNode,
292 GhtA::Storage: VariadicSet<Schema = GhtA::Schema>, GhtB: GeneralizedHashTrieNode,
294 GhtB::Storage: VariadicSet<Schema = GhtB::Schema>, GhtOut: FromIterator<var_type!(...GhtA::Schema, ...GhtB::ValType)>,
296 GhtA::Schema: Eq + Hash + CloneVariadic,
297 GhtB::Schema: Eq + Hash + SplitBySuffix<GhtB::ValType>,
298 GhtB::ValType: CloneVariadic,
299{
300 type Output = GhtOut;
301
302 fn call(&mut self, ght_a: &'a GhtA, ght_b: &'b GhtB) -> Self::Output {
303 ght_a.recursive_iter().flat_map(|a| {
304 ght_b
305 .recursive_iter()
306 .map(move |b| {
307 let (_prefix_b, suffix_b)
308 = <GhtB::Schema as SplitBySuffix<GhtB::ValType>>::split_by_suffix_ref(b);
309 var_expr!(...<GhtA::Schema as CloneVariadic>::clone_ref_var(a), ...<GhtB::ValType as CloneVariadic>::clone_ref_var(suffix_b))
310 }
311 )
312 }).collect()
313 }
314}
315
316#[derive(Default)]
320pub struct GhtBimorphism<Bimorphism> {
321 bimorphism: Bimorphism,
322 }
324impl<Bimorphism> GhtBimorphism<Bimorphism> {
325 pub fn new(bimorphism: Bimorphism) -> Self {
327 Self {
328 bimorphism,
329 }
331 }
332}
333
334impl<GhtA, GhtB, ValFunc, GhtOut> LatticeBimorphism<GhtA, GhtB> for GhtBimorphism<ValFunc>
335where
336 GhtA: GeneralizedHashTrieNode,
337 GhtA::Storage: VariadicSet<Schema = GhtA::Schema>, GhtB: GeneralizedHashTrieNode,
339 GhtB::Storage: VariadicSet<Schema = GhtB::Schema>, GhtOut: GeneralizedHashTrieNode, for<'a, 'b> ValFunc: LatticeBimorphism<&'a GhtA, &'b GhtB, Output = GhtOut>,
342{
343 type Output = GhtOut;
344
345 fn call(&mut self, ght_a: GhtA, ght_b: GhtB) -> Self::Output {
346 let node_bim = &mut self.bimorphism; node_bim.call(&ght_a, &ght_b)
348 }
349}
350
351#[derive(Default)]
352pub struct GhtNodeKeyedBimorphism<Bimorphism> {
354 bimorphism: Bimorphism,
355}
356impl<Bimorphism> GhtNodeKeyedBimorphism<Bimorphism> {
358 pub fn new(bimorphism: Bimorphism) -> Self {
360 Self { bimorphism }
361 }
362}
363impl<'a, 'b, Head, GhtA, GhtB, ValFunc> LatticeBimorphism<&'a GhtA, &'b GhtB>
365 for GhtNodeKeyedBimorphism<ValFunc>
366where
367 Head: Clone + Hash + Eq,
368 ValFunc: LatticeBimorphism<&'a GhtA::Get, &'b GhtB::Get>,
369 ValFunc::Output: GeneralizedHashTrieNode,
370 GhtA: GeneralizedHashTrieNode<Head = Head> + GhtGet,
371 GhtB: GeneralizedHashTrieNode<Head = Head, Schema = GhtA::Schema> + GhtGet,
372 GhtA::Storage: VariadicSet<Schema = GhtA::Schema>, GhtB::Storage: VariadicSet<Schema = GhtB::Schema>, <GhtA::SuffixSchema as VariadicExt>::AsRefVar<'a>: CloneVariadic,
375 <GhtB::SuffixSchema as VariadicExt>::AsRefVar<'b>: CloneVariadic,
376{
377 type Output = GhtInner<Head, ValFunc::Output>; fn call(&mut self, ght_a: &'a GhtA, ght_b: &'b GhtB) -> Self::Output {
380 let mut children = HashMap::<Head, ValFunc::Output>::new();
381 for head in ght_b.iter() {
383 if let Some(get_a) = ght_a.get(&head) {
384 let get_b = ght_b.get(&head).unwrap();
385 let val = self.bimorphism.call(get_a, get_b);
386 children.insert(head.clone(), val);
387 }
388 }
389 GhtInner { children }
390 }
391}
392
393pub trait DeepJoinLatticeBimorphism<Storage> {
395 type DeepJoinLatticeBimorphism;
397}
398impl<Head, NodeA, NodeB, Storage> DeepJoinLatticeBimorphism<Storage>
400 for (GhtInner<Head, NodeA>, GhtInner<Head, NodeB>)
401where
402 Head: 'static + Hash + Eq + Clone,
403 NodeA: 'static + GeneralizedHashTrieNode,
404 NodeB: 'static + GeneralizedHashTrieNode,
405 NodeA::Storage: VariadicSet<Schema = NodeA::Schema>, NodeB::Storage: VariadicSet<Schema = NodeB::Schema>, (NodeA, NodeB): DeepJoinLatticeBimorphism<Storage>,
408 Storage: VariadicSet<Schema = var_type!(...NodeA::Schema, ...NodeB::ValType)>,
409{
410 type DeepJoinLatticeBimorphism = GhtNodeKeyedBimorphism<
411 <(NodeA, NodeB) as DeepJoinLatticeBimorphism<Storage>>::DeepJoinLatticeBimorphism,
412 >;
413}
414impl<SchemaA, ValTypeA, StorageA, SchemaB, ValTypeB, StorageB, StorageOut>
415 DeepJoinLatticeBimorphism<StorageOut>
416 for (
417 GhtLeaf<SchemaA, ValTypeA, StorageA>,
418 GhtLeaf<SchemaB, ValTypeB, StorageB>,
419 )
420where
421 SchemaA: 'static + VariadicExt + Eq + Hash + SplitBySuffix<ValTypeA>, ValTypeA: 'static + VariadicExt + Eq + Hash, SchemaB: 'static + VariadicExt + Eq + Hash + SplitBySuffix<ValTypeB>, ValTypeB: 'static + VariadicExt + Eq + Hash, StorageA: VariadicSet<Schema = SchemaA>,
426 StorageB: VariadicSet<Schema = SchemaB>,
427 StorageOut: VariadicSet<Schema = var_type!(...SchemaA, ...ValTypeB)>,
428 for<'x> SchemaA::AsRefVar<'x>: CloneVariadic,
429 for<'x> SchemaB::AsRefVar<'x>: CloneVariadic,
430 var_type!(...SchemaA, ...ValTypeB): Eq + Hash,
431{
432 type DeepJoinLatticeBimorphism = GhtValTypeProductBimorphism<
433 GhtLeaf<
434 var_type!(...SchemaA, ...ValTypeB),
435 var_type!(...ValTypeA, ...ValTypeB),
436 StorageOut,
437 >,
438 >;
439}