Skip to main content

oxilean_std/hashmap/
types.rs

1//! Auto-generated module
2//!
3//! 🤖 Generated with [SplitRS](https://github.com/cool-japan/splitrs)
4
5use super::functions::*;
6use std::collections::{HashMap, HashSet, VecDeque};
7
8/// A node in a persistent binary search tree.
9#[derive(Debug, Clone)]
10enum PersistentNode<K, V> {
11    Leaf,
12    Node(K, V, Box<PersistentNode<K, V>>, Box<PersistentNode<K, V>>),
13}
14/// A simple interval map for ordered key types.
15///
16/// Stores a list of disjoint intervals, each associated with a value.
17/// Lookup is O(n) by linear scan.
18#[derive(Debug, Clone)]
19pub struct IntervalMap<T: Ord + Clone, V: Clone> {
20    pub(super) intervals: Vec<IntervalEntry<T, V>>,
21}
22impl<T: Ord + Clone, V: Clone> IntervalMap<T, V> {
23    /// Create an empty interval map.
24    pub fn new() -> Self {
25        Self::default()
26    }
27    /// Insert an interval [lo, hi] with a value.
28    pub fn insert(&mut self, lo: T, hi: T, value: V) {
29        self.intervals.push(IntervalEntry { lo, hi, value });
30    }
31    /// Query a point, returning all values whose interval contains the point.
32    pub fn query(&self, point: &T) -> Vec<&V> {
33        self.intervals
34            .iter()
35            .filter(|e| &e.lo <= point && point <= &e.hi)
36            .map(|e| &e.value)
37            .collect()
38    }
39    /// Number of intervals.
40    pub fn len(&self) -> usize {
41        self.intervals.len()
42    }
43    /// Check if empty.
44    pub fn is_empty(&self) -> bool {
45        self.intervals.is_empty()
46    }
47    /// Clear all intervals.
48    pub fn clear(&mut self) {
49        self.intervals.clear();
50    }
51}
52/// Simple LRU cache backed by a HashMap.
53#[allow(dead_code)]
54pub struct LRUCacheHm<K, V> {
55    pub capacity: usize,
56    pub store: std::collections::HashMap<K, V>,
57    pub order: std::collections::VecDeque<K>,
58}
59/// A map that associates each key with a list of values.
60#[derive(Debug, Clone)]
61pub struct MultiMap<K: PartialEq + Clone, V: Clone> {
62    inner: AssocMap<K, Vec<V>>,
63}
64impl<K: PartialEq + Clone, V: Clone> MultiMap<K, V> {
65    /// Create an empty multi-map.
66    pub fn new() -> Self {
67        Self {
68            inner: AssocMap::new(),
69        }
70    }
71    /// Insert a value for a key (appends if key already exists).
72    pub fn insert(&mut self, key: K, value: V) {
73        if let Some(vals) = self.inner.get_mut(&key) {
74            vals.push(value);
75        } else {
76            self.inner.insert(key, vec![value]);
77        }
78    }
79    /// Get all values for a key.
80    pub fn get(&self, key: &K) -> &[V] {
81        self.inner.get(key).map(|v| v.as_slice()).unwrap_or(&[])
82    }
83    /// Remove all values for a key.
84    pub fn remove(&mut self, key: &K) -> Vec<V> {
85        self.inner.remove(key).unwrap_or_default()
86    }
87    /// Check if a key has any values.
88    pub fn contains_key(&self, key: &K) -> bool {
89        self.inner.contains_key(key)
90    }
91    /// Total number of key-value associations.
92    pub fn total_count(&self) -> usize {
93        self.inner.values().map(|v| v.len()).sum()
94    }
95    /// Number of distinct keys.
96    pub fn key_count(&self) -> usize {
97        self.inner.len()
98    }
99    /// Check if empty.
100    pub fn is_empty(&self) -> bool {
101        self.inner.is_empty()
102    }
103    /// Clear the multi-map.
104    pub fn clear(&mut self) {
105        self.inner.clear();
106    }
107}
108/// A simple association list map.
109///
110/// Provides O(n) lookup but is useful in contexts where the number of entries
111/// is small and allocation overhead should be minimal.
112#[derive(Debug, Clone, PartialEq)]
113pub struct AssocMap<K, V> {
114    /// Stored entries in insertion order.
115    entries: Vec<(K, V)>,
116}
117impl<K: PartialEq + Clone, V: Clone> AssocMap<K, V> {
118    /// Create an empty association map.
119    pub fn new() -> Self {
120        Self {
121            entries: Vec::new(),
122        }
123    }
124    /// Insert a key-value pair, replacing any existing entry for that key.
125    pub fn insert(&mut self, key: K, value: V) {
126        if let Some(entry) = self.entries.iter_mut().find(|(k, _)| k == &key) {
127            entry.1 = value;
128        } else {
129            self.entries.push((key, value));
130        }
131    }
132    /// Look up a value by key.
133    pub fn get(&self, key: &K) -> Option<&V> {
134        self.entries.iter().find(|(k, _)| k == key).map(|(_, v)| v)
135    }
136    /// Look up a value by key (mutable).
137    pub fn get_mut(&mut self, key: &K) -> Option<&mut V> {
138        self.entries
139            .iter_mut()
140            .find(|(k, _)| k == key)
141            .map(|(_, v)| v)
142    }
143    /// Remove a key-value pair by key.
144    pub fn remove(&mut self, key: &K) -> Option<V> {
145        if let Some(pos) = self.entries.iter().position(|(k, _)| k == key) {
146            Some(self.entries.remove(pos).1)
147        } else {
148            None
149        }
150    }
151    /// Check if the map contains a key.
152    pub fn contains_key(&self, key: &K) -> bool {
153        self.entries.iter().any(|(k, _)| k == key)
154    }
155    /// Number of entries.
156    pub fn len(&self) -> usize {
157        self.entries.len()
158    }
159    /// Check if the map is empty.
160    pub fn is_empty(&self) -> bool {
161        self.entries.is_empty()
162    }
163    /// Iterate over key-value pairs in insertion order.
164    pub fn iter(&self) -> impl Iterator<Item = &(K, V)> {
165        self.entries.iter()
166    }
167    /// Iterate over keys in insertion order.
168    pub fn keys(&self) -> impl Iterator<Item = &K> {
169        self.entries.iter().map(|(k, _)| k)
170    }
171    /// Iterate over values in insertion order.
172    pub fn values(&self) -> impl Iterator<Item = &V> {
173        self.entries.iter().map(|(_, v)| v)
174    }
175    /// Clear all entries.
176    pub fn clear(&mut self) {
177        self.entries.clear();
178    }
179    /// Convert to a Vec of key-value pairs.
180    pub fn into_vec(self) -> Vec<(K, V)> {
181        self.entries
182    }
183    /// Merge another map into this one (entries from `other` overwrite).
184    pub fn merge(&mut self, other: &AssocMap<K, V>) {
185        for (k, v) in &other.entries {
186            self.insert(k.clone(), v.clone());
187        }
188    }
189    /// Retain only entries satisfying the predicate.
190    pub fn retain<F>(&mut self, mut f: F)
191    where
192        F: FnMut(&K, &V) -> bool,
193    {
194        self.entries.retain(|(k, v)| f(k, v));
195    }
196}
197/// Multi-map: each key maps to a list of values.
198#[allow(dead_code)]
199pub struct MultiMapHm<K, V> {
200    pub inner: std::collections::HashMap<K, Vec<V>>,
201}
202/// An entry in an interval map.
203#[derive(Debug, Clone)]
204pub struct IntervalEntry<T: Ord, V> {
205    /// Lower bound of the interval (inclusive).
206    pub lo: T,
207    /// Upper bound of the interval (inclusive).
208    pub hi: T,
209    /// Value associated with this interval.
210    pub value: V,
211}
212/// Immutable frozen snapshot of a HashMap.
213#[allow(dead_code)]
214pub struct FrozenHashMap<K, V> {
215    pub inner: std::collections::HashMap<K, V>,
216    pub frozen: bool,
217}
218/// A bidirectional map where both keys and values are unique.
219///
220/// Provides O(n) forward and reverse lookup, useful for managing bijections
221/// between names and indices in the elaboration context.
222#[derive(Debug, Clone, PartialEq)]
223pub struct BiMap<K: PartialEq + Clone, V: PartialEq + Clone> {
224    forward: AssocMap<K, V>,
225    backward: AssocMap<V, K>,
226}
227impl<K: PartialEq + Clone, V: PartialEq + Clone> BiMap<K, V> {
228    /// Create an empty bidirectional map.
229    pub fn new() -> Self {
230        Self {
231            forward: AssocMap::new(),
232            backward: AssocMap::new(),
233        }
234    }
235    /// Insert a (key, value) pair, evicting any existing entries that conflict.
236    pub fn insert(&mut self, key: K, value: V) {
237        if let Some(old_val) = self.forward.remove(&key) {
238            self.backward.remove(&old_val);
239        }
240        if let Some(old_key) = self.backward.remove(&value) {
241            self.forward.remove(&old_key);
242        }
243        self.forward.insert(key.clone(), value.clone());
244        self.backward.insert(value, key);
245    }
246    /// Forward lookup: key → value.
247    pub fn get_by_key(&self, key: &K) -> Option<&V> {
248        self.forward.get(key)
249    }
250    /// Reverse lookup: value → key.
251    pub fn get_by_val(&self, val: &V) -> Option<&K> {
252        self.backward.get(val)
253    }
254    /// Remove by key.
255    pub fn remove_by_key(&mut self, key: &K) -> Option<V> {
256        if let Some(val) = self.forward.remove(key) {
257            self.backward.remove(&val);
258            Some(val)
259        } else {
260            None
261        }
262    }
263    /// Remove by value.
264    pub fn remove_by_val(&mut self, val: &V) -> Option<K> {
265        if let Some(key) = self.backward.remove(val) {
266            self.forward.remove(&key);
267            Some(key)
268        } else {
269            None
270        }
271    }
272    /// Number of entries.
273    pub fn len(&self) -> usize {
274        self.forward.len()
275    }
276    /// Check if empty.
277    pub fn is_empty(&self) -> bool {
278        self.forward.is_empty()
279    }
280    /// Check if the key exists.
281    pub fn contains_key(&self, key: &K) -> bool {
282        self.forward.contains_key(key)
283    }
284    /// Check if the value exists.
285    pub fn contains_val(&self, val: &V) -> bool {
286        self.backward.contains_key(val)
287    }
288    /// Iterate over (key, value) pairs.
289    pub fn iter(&self) -> impl Iterator<Item = &(K, V)> {
290        self.forward.iter()
291    }
292    /// Clear all entries.
293    pub fn clear(&mut self) {
294        self.forward.clear();
295        self.backward.clear();
296    }
297}
298/// A map with LRU (least-recently-used) eviction policy.
299///
300/// When the capacity is exceeded, the least-recently-used entry is removed.
301/// Useful for memoization caches inside the type checker.
302#[derive(Debug, Clone)]
303pub struct LruMap<K: PartialEq + Clone, V: Clone> {
304    capacity: usize,
305    entries: Vec<(K, V)>,
306}
307impl<K: PartialEq + Clone, V: Clone> LruMap<K, V> {
308    /// Create an LRU map with the given capacity (must be > 0).
309    pub fn new(capacity: usize) -> Self {
310        assert!(capacity > 0, "LruMap capacity must be positive");
311        Self {
312            capacity,
313            entries: Vec::with_capacity(capacity),
314        }
315    }
316    /// Get a value by key, promoting it to the front (most recently used).
317    pub fn get(&mut self, key: &K) -> Option<&V> {
318        let pos = self.entries.iter().position(|(k, _)| k == key)?;
319        let entry = self.entries.remove(pos);
320        self.entries.insert(0, entry);
321        self.entries.first().map(|(_, v)| v)
322    }
323    /// Insert a key-value pair, evicting the LRU entry if at capacity.
324    pub fn insert(&mut self, key: K, value: V) {
325        if let Some(pos) = self.entries.iter().position(|(k, _)| k == &key) {
326            self.entries.remove(pos);
327        }
328        if self.entries.len() >= self.capacity {
329            self.entries.pop();
330        }
331        self.entries.insert(0, (key, value));
332    }
333    /// Peek at a value without updating LRU order.
334    pub fn peek(&self, key: &K) -> Option<&V> {
335        self.entries.iter().find(|(k, _)| k == key).map(|(_, v)| v)
336    }
337    /// Number of entries.
338    pub fn len(&self) -> usize {
339        self.entries.len()
340    }
341    /// Check if empty.
342    pub fn is_empty(&self) -> bool {
343        self.entries.is_empty()
344    }
345    /// Evict all entries.
346    pub fn clear(&mut self) {
347        self.entries.clear();
348    }
349    /// Current capacity.
350    pub fn capacity(&self) -> usize {
351        self.capacity
352    }
353    /// Iterate entries in MRU order.
354    pub fn iter_mru(&self) -> impl Iterator<Item = &(K, V)> {
355        self.entries.iter()
356    }
357}
358/// HashMap viewed as a monoid under union (left-biased merge).
359#[allow(dead_code)]
360pub struct HashMapMonoid<K, V> {
361    pub inner: std::collections::HashMap<K, V>,
362}
363/// An immutable persistent map based on a binary search tree.
364///
365/// Operations return new map instances sharing structure with the original.
366/// Suitable for use in backtracking algorithms where previous states must
367/// be preserved.
368#[derive(Debug, Clone)]
369pub struct PersistentMap<K: Ord + Clone, V: Clone> {
370    root: PersistentNode<K, V>,
371    size: usize,
372}
373impl<K: Ord + Clone, V: Clone> PersistentMap<K, V> {
374    /// Create an empty persistent map.
375    pub fn empty() -> Self {
376        Self {
377            root: PersistentNode::Leaf,
378            size: 0,
379        }
380    }
381    /// Look up a value by key.
382    pub fn get(&self, key: &K) -> Option<&V> {
383        Self::get_node(&self.root, key)
384    }
385    fn get_node<'a>(node: &'a PersistentNode<K, V>, key: &K) -> Option<&'a V> {
386        match node {
387            PersistentNode::Leaf => None,
388            PersistentNode::Node(k, v, left, right) => {
389                use std::cmp::Ordering;
390                match key.cmp(k) {
391                    Ordering::Equal => Some(v),
392                    Ordering::Less => Self::get_node(left, key),
393                    Ordering::Greater => Self::get_node(right, key),
394                }
395            }
396        }
397    }
398    /// Insert a key-value pair, returning a new map.
399    pub fn insert(&self, key: K, value: V) -> Self {
400        let (new_root, added) = Self::insert_node(&self.root, key, value);
401        Self {
402            root: new_root,
403            size: if added { self.size + 1 } else { self.size },
404        }
405    }
406    fn insert_node(node: &PersistentNode<K, V>, key: K, value: V) -> (PersistentNode<K, V>, bool) {
407        match node {
408            PersistentNode::Leaf => (
409                PersistentNode::Node(
410                    key,
411                    value,
412                    Box::new(PersistentNode::Leaf),
413                    Box::new(PersistentNode::Leaf),
414                ),
415                true,
416            ),
417            PersistentNode::Node(k, v, left, right) => {
418                use std::cmp::Ordering;
419                match key.cmp(k) {
420                    Ordering::Equal => (
421                        PersistentNode::Node(k.clone(), value, left.clone(), right.clone()),
422                        false,
423                    ),
424                    Ordering::Less => {
425                        let (new_left, added) = Self::insert_node(left, key, value);
426                        (
427                            PersistentNode::Node(
428                                k.clone(),
429                                v.clone(),
430                                Box::new(new_left),
431                                right.clone(),
432                            ),
433                            added,
434                        )
435                    }
436                    Ordering::Greater => {
437                        let (new_right, added) = Self::insert_node(right, key, value);
438                        (
439                            PersistentNode::Node(
440                                k.clone(),
441                                v.clone(),
442                                left.clone(),
443                                Box::new(new_right),
444                            ),
445                            added,
446                        )
447                    }
448                }
449            }
450        }
451    }
452    /// Check if the map contains a key.
453    pub fn contains_key(&self, key: &K) -> bool {
454        self.get(key).is_some()
455    }
456    /// Number of entries.
457    pub fn len(&self) -> usize {
458        self.size
459    }
460    /// Check if empty.
461    pub fn is_empty(&self) -> bool {
462        self.size == 0
463    }
464    /// Collect all key-value pairs in sorted order.
465    pub fn to_sorted_vec(&self) -> Vec<(K, V)> {
466        let mut result = Vec::new();
467        Self::collect_inorder(&self.root, &mut result);
468        result
469    }
470    fn collect_inorder(node: &PersistentNode<K, V>, out: &mut Vec<(K, V)>) {
471        if let PersistentNode::Node(k, v, left, right) = node {
472            Self::collect_inorder(left, out);
473            out.push((k.clone(), v.clone()));
474            Self::collect_inorder(right, out);
475        }
476    }
477}
478/// A map supporting scoped bindings with push/pop semantics.
479///
480/// Useful for implementing the typing context in the elaborator,
481/// where entering a binder pushes a new scope and exiting pops it.
482#[derive(Debug, Clone)]
483pub struct StackMap<K: PartialEq + Clone, V: Clone> {
484    scopes: Vec<Vec<(K, V)>>,
485}
486impl<K: PartialEq + Clone, V: Clone> StackMap<K, V> {
487    /// Create a new `StackMap` with a single (global) scope.
488    pub fn new() -> Self {
489        Self {
490            scopes: vec![Vec::new()],
491        }
492    }
493    /// Push a new scope.
494    pub fn push_scope(&mut self) {
495        self.scopes.push(Vec::new());
496    }
497    /// Pop the innermost scope, discarding its bindings.
498    pub fn pop_scope(&mut self) {
499        if self.scopes.len() > 1 {
500            self.scopes.pop();
501        }
502    }
503    /// Insert into the current (innermost) scope.
504    pub fn insert(&mut self, key: K, value: V) {
505        if let Some(scope) = self.scopes.last_mut() {
506            if let Some(entry) = scope.iter_mut().find(|(k, _)| k == &key) {
507                entry.1 = value;
508                return;
509            }
510            scope.push((key, value));
511        }
512    }
513    /// Look up by key, searching from innermost to outermost scope.
514    pub fn get(&self, key: &K) -> Option<&V> {
515        for scope in self.scopes.iter().rev() {
516            if let Some((_, v)) = scope.iter().rev().find(|(k, _)| k == key) {
517                return Some(v);
518            }
519        }
520        None
521    }
522    /// Check if a key is visible in any scope.
523    pub fn contains_key(&self, key: &K) -> bool {
524        self.get(key).is_some()
525    }
526    /// Number of current scope levels.
527    pub fn depth(&self) -> usize {
528        self.scopes.len()
529    }
530    /// Total number of bindings across all scopes.
531    pub fn total_bindings(&self) -> usize {
532        self.scopes.iter().map(|s| s.len()).sum()
533    }
534    /// Clear all scopes (but keep one empty global scope).
535    pub fn clear(&mut self) {
536        self.scopes.clear();
537        self.scopes.push(Vec::new());
538    }
539}
540/// A map counting how many times each key has been seen.
541#[derive(Debug, Clone)]
542pub struct FreqMap<K: PartialEq + Clone> {
543    pub(super) counts: AssocMap<K, usize>,
544}
545impl<K: PartialEq + Clone> FreqMap<K> {
546    /// Create an empty frequency map.
547    pub fn new() -> Self {
548        Self::default()
549    }
550    /// Record one occurrence of `key`.
551    pub fn record(&mut self, key: K) {
552        if let Some(c) = self.counts.get_mut(&key) {
553            *c += 1;
554        } else {
555            self.counts.insert(key, 1);
556        }
557    }
558    /// Get the count for `key`.
559    pub fn count(&self, key: &K) -> usize {
560        *self.counts.get(key).unwrap_or(&0)
561    }
562    /// Get the key with the highest count.
563    pub fn most_common(&self) -> Option<(&K, usize)> {
564        self.counts
565            .iter()
566            .map(|(k, c)| (k, *c))
567            .max_by_key(|(_, c)| *c)
568    }
569    /// Total number of distinct keys.
570    pub fn distinct_keys(&self) -> usize {
571        self.counts.len()
572    }
573    /// Total number of recorded occurrences.
574    pub fn total_count(&self) -> usize {
575        self.counts.values().sum()
576    }
577    /// Check if empty.
578    pub fn is_empty(&self) -> bool {
579        self.counts.is_empty()
580    }
581    /// Clear all counts.
582    pub fn clear(&mut self) {
583        self.counts.clear();
584    }
585}
586/// A vector-backed map where keys are dense integers 0..n.
587///
588/// Provides O(1) lookup and O(1) insertion (amortized).
589#[derive(Debug, Clone)]
590pub struct IndexedMap<V: Clone> {
591    pub(super) slots: Vec<Option<V>>,
592    pub(super) count: usize,
593}
594impl<V: Clone> IndexedMap<V> {
595    /// Create an empty indexed map.
596    pub fn new() -> Self {
597        Self::default()
598    }
599    /// Insert or overwrite the value at `index`.
600    pub fn insert(&mut self, index: usize, value: V) {
601        if index >= self.slots.len() {
602            self.slots.resize(index + 1, None);
603        }
604        if self.slots[index].is_none() {
605            self.count += 1;
606        }
607        self.slots[index] = Some(value);
608    }
609    /// Get the value at `index`.
610    pub fn get(&self, index: usize) -> Option<&V> {
611        self.slots.get(index).and_then(|s| s.as_ref())
612    }
613    /// Remove the value at `index`.
614    pub fn remove(&mut self, index: usize) -> Option<V> {
615        let slot = self.slots.get_mut(index)?;
616        let old = slot.take()?;
617        self.count -= 1;
618        Some(old)
619    }
620    /// Check if index is occupied.
621    pub fn contains(&self, index: usize) -> bool {
622        self.get(index).is_some()
623    }
624    /// Number of occupied slots.
625    pub fn len(&self) -> usize {
626        self.count
627    }
628    /// Check if empty.
629    pub fn is_empty(&self) -> bool {
630        self.count == 0
631    }
632    /// Capacity (highest index + 1).
633    pub fn capacity(&self) -> usize {
634        self.slots.len()
635    }
636    /// Iterate over (index, value) pairs.
637    pub fn iter(&self) -> impl Iterator<Item = (usize, &V)> {
638        self.slots
639            .iter()
640            .enumerate()
641            .filter_map(|(i, s)| s.as_ref().map(|v| (i, v)))
642    }
643    /// Clear all slots.
644    pub fn clear(&mut self) {
645        self.slots.clear();
646        self.count = 0;
647    }
648}
649/// Represents the structural difference between two HashMaps.
650#[allow(dead_code)]
651pub struct HashMapDiff<K, V> {
652    pub added: std::collections::HashMap<K, V>,
653    pub removed: std::collections::HashSet<K>,
654}