Skip to main content

oxilean_std/data_structures/
functions.rs

1//! Auto-generated module
2//!
3//! 🤖 Generated with [SplitRS](https://github.com/cool-japan/splitrs)
4
5use oxilean_kernel::{BinderInfo, Declaration, Environment, Expr, Level, Name};
6
7use super::types::{
8    AvlNode, AvlTree, BTree, BinaryHeap, BinaryMinHeap, BloomFilterDs, Deque, DisjointSet,
9    FenwickTree, HyperLogLog, PersistArrayExt, PersistArrayV2, PersistentSegmentTree, SegmentTree,
10    SegmentTreeNew, SimpleHashMap, SkipList, SkipListData, SuccinctBitVector, TreapData, Trie,
11    UnionFind, VanEmdeBoasTree, WaveletTree, XFastTrie,
12};
13
14pub fn app(f: Expr, a: Expr) -> Expr {
15    Expr::App(Box::new(f), Box::new(a))
16}
17pub fn app2(f: Expr, a: Expr, b: Expr) -> Expr {
18    app(app(f, a), b)
19}
20pub fn app3(f: Expr, a: Expr, b: Expr, c: Expr) -> Expr {
21    app(app2(f, a, b), c)
22}
23pub fn cst(s: &str) -> Expr {
24    Expr::Const(Name::str(s), vec![])
25}
26pub fn prop() -> Expr {
27    Expr::Sort(Level::zero())
28}
29pub fn type0() -> Expr {
30    Expr::Sort(Level::succ(Level::zero()))
31}
32pub fn pi(bi: BinderInfo, name: &str, dom: Expr, body: Expr) -> Expr {
33    Expr::Pi(bi, Name::str(name), Box::new(dom), Box::new(body))
34}
35pub fn arrow(a: Expr, b: Expr) -> Expr {
36    pi(BinderInfo::Default, "_", a, b)
37}
38pub fn impl_pi(name: &str, dom: Expr, body: Expr) -> Expr {
39    pi(BinderInfo::Implicit, name, dom, body)
40}
41pub fn bvar(n: u32) -> Expr {
42    Expr::BVar(n)
43}
44pub fn nat_ty() -> Expr {
45    cst("Nat")
46}
47pub fn bool_ty() -> Expr {
48    cst("Bool")
49}
50/// `Heap α : Type 0` — polymorphic binary min-heap type constructor.
51///
52/// Takes an element type and returns the heap type over that element type.
53pub fn heap_ty() -> Expr {
54    arrow(type0(), type0())
55}
56/// `Trie α : Type 0` — trie (prefix tree) indexed by bit strings.
57///
58/// Takes a value type and returns the trie type storing values at bit-string keys.
59pub fn trie_ty() -> Expr {
60    arrow(type0(), type0())
61}
62/// `SegmentTree α n : Type 0` — segment tree over an array of size n.
63///
64/// Takes an element type and a size (Nat) and returns the segment tree type.
65pub fn segment_tree_ty() -> Expr {
66    arrow(type0(), arrow(nat_ty(), type0()))
67}
68/// `FingerTree α : Type 0` — functional finger tree (Hinze-Paterson).
69///
70/// Supports O(1) amortized cons/snoc and O(log n) concatenation/split.
71pub fn finger_tree_ty() -> Expr {
72    arrow(type0(), type0())
73}
74/// `AVLTree α : Type 0` — AVL self-balancing binary search tree.
75///
76/// Maintains height-balance invariant: |height(left) - height(right)| ≤ 1.
77pub fn avl_tree_ty() -> Expr {
78    arrow(type0(), type0())
79}
80/// `SkipList α : Type 0` — probabilistic skip list.
81///
82/// Expected O(log n) search, insert, and delete with high probability.
83pub fn skip_list_ty() -> Expr {
84    arrow(type0(), type0())
85}
86/// `PriorityQueue α : Type 0` — priority queue (backed by heap).
87pub fn priority_queue_ty() -> Expr {
88    arrow(type0(), type0())
89}
90/// `DisjointSet n : Type 0` — union-find structure over n elements.
91///
92/// Supports union and find with path compression and union by rank,
93/// giving inverse-Ackermann amortized complexity.
94pub fn disjoint_set_ty() -> Expr {
95    arrow(nat_ty(), type0())
96}
97/// `Deque α : Type 0` — double-ended queue.
98///
99/// Supports push/pop at both ends in amortized O(1).
100pub fn deque_ty() -> Expr {
101    arrow(type0(), type0())
102}
103/// `IntervalTree α : Type 0` — interval tree for overlap queries.
104///
105/// Stores intervals [lo, hi] with associated values; supports O(log n) overlap queries.
106pub fn interval_tree_ty() -> Expr {
107    arrow(type0(), type0())
108}
109/// `heap_push_preserves_invariant : ∀ (α : Type) (h : Heap α) (x : α), HeapInvariant (push h x)`
110///
111/// Pushing an element into a valid heap produces a valid heap.
112pub fn heap_push_ty() -> Expr {
113    impl_pi(
114        "α",
115        type0(),
116        arrow(app(cst("Heap"), bvar(0)), arrow(bvar(1), prop())),
117    )
118}
119/// `heap_pop_returns_minimum : ∀ (α : Type) (h : Heap α), IsMinimum (pop h) h`
120///
121/// The element returned by pop is the minimum element in the heap.
122pub fn heap_pop_ty() -> Expr {
123    impl_pi("α", type0(), arrow(app(cst("Heap"), bvar(0)), prop()))
124}
125/// `segment_tree_query_log : ∀ n, QueryComplexity (segTree n) = O(log n)`
126///
127/// Range queries on a segment tree of size n take O(log n) time.
128pub fn segment_tree_query_ty() -> Expr {
129    arrow(nat_ty(), prop())
130}
131/// `avl_balance_invariant : ∀ (α : Type) (t : AVLTree α), BalanceFactor t ≤ 1`
132///
133/// Every node in an AVL tree has balance factor in {-1, 0, 1}.
134pub fn avl_balance_ty() -> Expr {
135    impl_pi("α", type0(), arrow(app(cst("AVLTree"), bvar(0)), prop()))
136}
137/// `union_find_amortized : ∀ n ops, TotalCost (unionFind n) ops = O(ops * α(n))`
138///
139/// Union-find with path compression and union by rank has inverse-Ackermann
140/// amortized cost per operation.
141pub fn union_find_amortized_ty() -> Expr {
142    arrow(nat_ty(), arrow(nat_ty(), prop()))
143}
144/// Register all data structure axioms into the given kernel environment.
145///
146/// This adds axioms for the type constructors and core theorems of each
147/// data structure. These are axioms rather than definitions because the full
148/// inductive definitions would require significantly more kernel infrastructure.
149pub fn build_data_structures_env(env: &mut Environment) -> Result<(), String> {
150    let type_axioms: &[(&str, Expr)] = &[
151        ("Heap", heap_ty()),
152        ("Trie", trie_ty()),
153        ("SegmentTree", segment_tree_ty()),
154        ("FingerTree", finger_tree_ty()),
155        ("AVLTree", avl_tree_ty()),
156        ("SkipList", skip_list_ty()),
157        ("PriorityQueue", priority_queue_ty()),
158        ("DisjointSet", disjoint_set_ty()),
159        ("Deque", deque_ty()),
160        ("IntervalTree", interval_tree_ty()),
161    ];
162    for (name, ty) in type_axioms {
163        env.add(Declaration::Axiom {
164            name: Name::str(*name),
165            univ_params: vec![],
166            ty: ty.clone(),
167        })
168        .ok();
169    }
170    let thm_axioms: &[(&str, Expr)] = &[
171        ("heap_push_preserves_invariant", heap_push_ty()),
172        ("heap_pop_returns_minimum", heap_pop_ty()),
173        ("segment_tree_query_log", segment_tree_query_ty()),
174        ("avl_balance_invariant", avl_balance_ty()),
175        ("union_find_amortized_complexity", union_find_amortized_ty()),
176    ];
177    for (name, ty) in thm_axioms {
178        env.add(Declaration::Axiom {
179            name: Name::str(*name),
180            univ_params: vec![],
181            ty: ty.clone(),
182        })
183        .ok();
184    }
185    Ok(())
186}
187pub const TRIE_ALPHABET: usize = 256;
188pub fn avl_height<T: Ord>(node: &Option<Box<AvlNode<T>>>) -> usize {
189    node.as_ref().map_or(0, |n| n.height)
190}
191pub fn avl_update_height<T: Ord>(node: &mut Box<AvlNode<T>>) {
192    node.height = 1 + avl_height(&node.left).max(avl_height(&node.right));
193}
194pub fn avl_balance_factor<T: Ord>(node: &Box<AvlNode<T>>) -> i64 {
195    avl_height(&node.left) as i64 - avl_height(&node.right) as i64
196}
197pub fn avl_rotate_right<T: Ord>(mut y: Box<AvlNode<T>>) -> Box<AvlNode<T>> {
198    let mut x = y
199        .left
200        .take()
201        .expect("avl_rotate_right called only when left child exists (bf > 1)");
202    y.left = x.right.take();
203    avl_update_height(&mut y);
204    x.right = Some(y);
205    avl_update_height(&mut x);
206    x
207}
208pub fn avl_rotate_left<T: Ord>(mut x: Box<AvlNode<T>>) -> Box<AvlNode<T>> {
209    let mut y = x
210        .right
211        .take()
212        .expect("avl_rotate_left called only when right child exists (bf < -1)");
213    x.right = y.left.take();
214    avl_update_height(&mut x);
215    y.left = Some(x);
216    avl_update_height(&mut y);
217    y
218}
219pub fn avl_rebalance<T: Ord>(mut node: Box<AvlNode<T>>) -> Box<AvlNode<T>> {
220    avl_update_height(&mut node);
221    let bf = avl_balance_factor(&node);
222    if bf > 1 {
223        if avl_balance_factor(node.left.as_ref().expect("left child exists when bf > 1")) < 0 {
224            let left = node.left.take().expect("left child exists when bf > 1");
225            node.left = Some(avl_rotate_left(left));
226        }
227        return avl_rotate_right(node);
228    }
229    if bf < -1 {
230        if avl_balance_factor(
231            node.right
232                .as_ref()
233                .expect("right child exists when bf < -1"),
234        ) > 0
235        {
236            let right = node.right.take().expect("right child exists when bf < -1");
237            node.right = Some(avl_rotate_right(right));
238        }
239        return avl_rotate_left(node);
240    }
241    node
242}
243pub fn avl_insert<T: Ord>(node: Option<Box<AvlNode<T>>>, value: T) -> Box<AvlNode<T>> {
244    match node {
245        None => AvlNode::new(value),
246        Some(mut n) => {
247            match value.cmp(&n.value) {
248                std::cmp::Ordering::Less => {
249                    n.left = Some(avl_insert(n.left.take(), value));
250                }
251                std::cmp::Ordering::Greater => {
252                    n.right = Some(avl_insert(n.right.take(), value));
253                }
254                std::cmp::Ordering::Equal => {}
255            }
256            avl_rebalance(n)
257        }
258    }
259}
260pub fn avl_contains<T: Ord>(node: &Option<Box<AvlNode<T>>>, value: &T) -> bool {
261    match node {
262        None => false,
263        Some(n) => match value.cmp(&n.value) {
264            std::cmp::Ordering::Less => avl_contains(&n.left, value),
265            std::cmp::Ordering::Greater => avl_contains(&n.right, value),
266            std::cmp::Ordering::Equal => true,
267        },
268    }
269}
270#[cfg(test)]
271mod tests {
272    use super::*;
273    #[test]
274    fn test_binary_heap() {
275        let mut heap = BinaryHeap::new();
276        assert!(heap.is_empty());
277        heap.push(5);
278        heap.push(3);
279        heap.push(8);
280        heap.push(1);
281        heap.push(9);
282        assert_eq!(heap.peek(), Some(&1));
283        assert_eq!(heap.len(), 5);
284        assert_eq!(heap.pop(), Some(1));
285        assert_eq!(heap.pop(), Some(3));
286        assert_eq!(heap.pop(), Some(5));
287        assert_eq!(heap.pop(), Some(8));
288        assert_eq!(heap.pop(), Some(9));
289        assert_eq!(heap.pop(), None);
290        assert!(heap.is_empty());
291    }
292    #[test]
293    fn test_segment_tree() {
294        let values = vec![1i64, 3, 5, 7, 9, 11];
295        let mut st = SegmentTree::new(&values);
296        assert_eq!(st.query(0, 5), 36);
297        assert_eq!(st.query(1, 3), 15);
298        assert_eq!(st.query(4, 4), 9);
299        st.update(2, 10);
300        assert_eq!(st.query(0, 5), 41);
301        assert_eq!(st.query(1, 3), 20);
302        assert_eq!(st.query(10, 20), 0);
303        assert_eq!(st.len(), 6);
304        assert!(!st.is_empty());
305    }
306    #[test]
307    fn test_trie() {
308        let mut trie = Trie::new();
309        assert!(!trie.search("hello"));
310        trie.insert("hello");
311        trie.insert("world");
312        trie.insert("help");
313        assert!(trie.search("hello"));
314        assert!(trie.search("world"));
315        assert!(trie.search("help"));
316        assert!(!trie.search("hel"));
317        assert!(!trie.search("worlds"));
318        assert!(!trie.search(""));
319        assert!(trie.starts_with("hel"));
320        assert!(trie.starts_with("wor"));
321        assert!(!trie.starts_with("xyz"));
322    }
323    #[test]
324    fn test_disjoint_set() {
325        let mut ds = DisjointSet::new(6);
326        assert_eq!(ds.num_sets(), 6);
327        assert!(!ds.connected(0, 1));
328        assert!(ds.union(0, 1));
329        assert!(ds.union(2, 3));
330        assert!(ds.union(4, 5));
331        assert_eq!(ds.num_sets(), 3);
332        assert!(ds.connected(0, 1));
333        assert!(ds.connected(2, 3));
334        assert!(!ds.connected(0, 2));
335        assert!(ds.union(1, 2));
336        assert_eq!(ds.num_sets(), 2);
337        assert!(ds.connected(0, 3));
338        assert!(!ds.union(0, 3));
339        assert_eq!(ds.num_sets(), 2);
340    }
341    #[test]
342    fn test_avl_tree() {
343        let mut tree = AvlTree::new();
344        assert!(tree.is_empty());
345        for i in 1..=10 {
346            tree.insert(i);
347        }
348        for i in 1..=10 {
349            assert!(tree.contains(&i));
350        }
351        assert!(!tree.contains(&0));
352        assert!(!tree.contains(&11));
353        let n = 10usize;
354        let max_height = (2.0 * ((n + 1) as f64).log2()).ceil() as usize + 1;
355        assert!(
356            tree.height() <= max_height,
357            "AVL height {} exceeds bound {}",
358            tree.height(),
359            max_height
360        );
361    }
362    #[test]
363    fn test_deque() {
364        let mut dq: Deque<i32> = Deque::new();
365        assert!(dq.is_empty());
366        dq.push_back(1);
367        dq.push_back(2);
368        dq.push_back(3);
369        dq.push_front(0);
370        dq.push_front(-1);
371        assert_eq!(dq.len(), 5);
372        assert_eq!(dq.pop_front(), Some(-1));
373        assert_eq!(dq.pop_front(), Some(0));
374        assert_eq!(dq.pop_back(), Some(3));
375        assert_eq!(dq.pop_back(), Some(2));
376        assert_eq!(dq.pop_front(), Some(1));
377        assert_eq!(dq.pop_front(), None);
378        assert!(dq.is_empty());
379        dq.push_back(10);
380        dq.push_back(20);
381        assert_eq!(dq.front(), Some(&10));
382        assert_eq!(dq.back(), Some(&20));
383    }
384    #[test]
385    fn test_build_env() {
386        let mut env = Environment::new();
387        let result = build_data_structures_env(&mut env);
388        assert!(
389            result.is_ok(),
390            "build_data_structures_env failed: {:?}",
391            result
392        );
393    }
394}
395/// `PersistentArray α n : Type 0` — persistent immutable array.
396///
397/// Every update produces a new version while the old version remains accessible.
398/// Implemented via fat-node method or path copying.
399pub fn persistent_array_ty() -> Expr {
400    arrow(type0(), arrow(nat_ty(), type0()))
401}
402/// `PersistenceTheorem : Prop` — all versions of a persistent structure coexist.
403pub fn persistence_theorem_ty() -> Expr {
404    prop()
405}
406/// `FatNodeMethod : Nat → Prop` — the fat node method overhead is O(1) per update.
407pub fn fat_node_method_ty() -> Expr {
408    arrow(nat_ty(), prop())
409}
410/// `PathCopying : Nat → Prop` — path copying persistence for BSTs.
411pub fn path_copying_ty() -> Expr {
412    arrow(nat_ty(), prop())
413}
414/// `PersistentStack α : Type 0` — persistent (immutable-spine) stack.
415pub fn persistent_stack_ty() -> Expr {
416    arrow(type0(), type0())
417}
418/// `PersistentQueue α : Type 0` — persistent queue (Hood-Melville or banker).
419pub fn persistent_queue_ty() -> Expr {
420    arrow(type0(), type0())
421}
422/// `VanEmdeBoasTree n : Type 0` — van Emde Boas tree over universe [0,n).
423///
424/// Supports predecessor, successor, insert, delete in O(log log n) time.
425pub fn van_emde_boas_ty() -> Expr {
426    arrow(nat_ty(), type0())
427}
428/// `FractionalCascading : Nat → Prop` — fractional cascading speedup for range queries.
429pub fn fractional_cascading_ty() -> Expr {
430    arrow(nat_ty(), prop())
431}
432/// `CacheObliviousBTree : Nat → Type 0` — cache-oblivious B-tree.
433pub fn cache_oblivious_btree_ty() -> Expr {
434    arrow(nat_ty(), type0())
435}
436/// `CacheObliviousMatrix : Nat → Type 0` — cache-oblivious matrix layout (Z-curve).
437pub fn cache_oblivious_matrix_ty() -> Expr {
438    arrow(nat_ty(), type0())
439}
440/// `SuccinctBitVectorTy : Nat → Type 0` — compact bit vector with rank/select.
441///
442/// Stores n bits in n + o(n) bits and answers rank/select in O(1).
443pub fn succinct_bit_vector_ty() -> Expr {
444    arrow(nat_ty(), type0())
445}
446/// `WaveletTreeTy : Nat → Type 0` — wavelet tree for range queries on sequences.
447///
448/// Answers range frequency, range median, range quantile in O(log σ) time.
449pub fn wavelet_tree_ty() -> Expr {
450    arrow(nat_ty(), type0())
451}
452/// `CompressedSuffixArray : Nat → Type 0` — compressed suffix array (CSA/FM-index).
453pub fn compressed_suffix_array_ty() -> Expr {
454    arrow(nat_ty(), type0())
455}
456/// `RankSelectAxiom : Prop` — rank(i) + select(rank(i)) = i on succinct bit vectors.
457pub fn rank_select_axiom_ty() -> Expr {
458    prop()
459}
460/// `DistributedHashTable : Nat → Type 0` — distributed hash table (DHT).
461pub fn distributed_hash_table_ty() -> Expr {
462    arrow(nat_ty(), type0())
463}
464/// `ConsistentHashing : Nat → Prop` — consistent hashing with O(1/n) key redistribution.
465pub fn consistent_hashing_ty() -> Expr {
466    arrow(nat_ty(), prop())
467}
468/// `CRDT : Type 0` — conflict-free replicated data type.
469///
470/// A CRDT is a data structure that can be replicated across multiple nodes
471/// with guaranteed eventual consistency via lattice-based merge operations.
472pub fn crdt_ty() -> Expr {
473    type0()
474}
475/// `ReplicationConsistency : Prop` — eventual consistency of CRDT merges.
476pub fn replication_consistency_ty() -> Expr {
477    prop()
478}
479/// `BloomFilterTy : Nat → Nat → Type 0` — Bloom filter with m bits and k hash functions.
480pub fn bloom_filter_ds_ty() -> Expr {
481    arrow(nat_ty(), arrow(nat_ty(), type0()))
482}
483/// `HyperLogLogTy : Nat → Type 0` — HyperLogLog cardinality estimator with b-bit registers.
484pub fn hyperloglog_ty() -> Expr {
485    arrow(nat_ty(), type0())
486}
487/// `CountMinSketchTy : Nat → Nat → Type 0` — count-min sketch with w columns, d rows.
488pub fn count_min_sketch_ty() -> Expr {
489    arrow(nat_ty(), arrow(nat_ty(), type0()))
490}
491/// `BloomFilterFPR : Prop` — false positive rate of Bloom filter is (1-e^{-kn/m})^k.
492pub fn bloom_filter_fpr_ty() -> Expr {
493    prop()
494}
495/// `HyperLogLogError : Prop` — HyperLogLog relative error is 1.04/sqrt(m).
496pub fn hyperloglog_error_ty() -> Expr {
497    prop()
498}
499/// `BTree : Nat → Type 0` — B-tree of order t (min t-1 keys, max 2t-1 keys per node).
500pub fn btree_ty() -> Expr {
501    arrow(nat_ty(), type0())
502}
503/// `BufferTree : Nat → Type 0` — buffer tree for batched external-memory operations.
504pub fn buffer_tree_ty() -> Expr {
505    arrow(nat_ty(), type0())
506}
507/// `BTreeSearchComplexity : Prop` — B-tree search runs in O(log_t n) I/Os.
508pub fn btree_search_complexity_ty() -> Expr {
509    prop()
510}
511/// `BTreeInsertComplexity : Prop` — B-tree insert runs in O(log_t n) I/Os.
512pub fn btree_insert_complexity_ty() -> Expr {
513    prop()
514}
515/// `LockFreeStack α : Type 0` — lock-free Treiber stack.
516pub fn lock_free_stack_ty() -> Expr {
517    arrow(type0(), type0())
518}
519/// `WaitFreeQueue α : Type 0` — wait-free queue (Kogan-Petrank).
520pub fn wait_free_queue_ty() -> Expr {
521    arrow(type0(), type0())
522}
523/// `Linearizability : Prop` — concurrent operations are linearizable.
524pub fn linearizability_ty() -> Expr {
525    prop()
526}
527/// `WaitFreedom : Prop` — every thread finishes in a bounded number of steps.
528pub fn wait_freedom_ty() -> Expr {
529    prop()
530}
531/// `RedBlackTree α : Type 0` — red-black BST (Okasaki functional formulation).
532pub fn red_black_tree_ty() -> Expr {
533    arrow(type0(), type0())
534}
535/// `RealTimeQueue α : Type 0` — Hood-Melville real-time O(1) worst-case queue.
536pub fn real_time_queue_ty() -> Expr {
537    arrow(type0(), type0())
538}
539/// `BootstrappedHeap α : Type 0` — bootstrapped priority queue (Kaplan-Tarjan).
540pub fn bootstrapped_heap_ty() -> Expr {
541    arrow(type0(), type0())
542}
543/// `FunctionalBSTInvariant : Prop` — a functional BST satisfies the BST ordering.
544pub fn functional_bst_invariant_ty() -> Expr {
545    prop()
546}
547/// `SuffixTree : Nat → Type 0` — compressed suffix tree (Ukkonen's linear construction).
548pub fn suffix_tree_ty() -> Expr {
549    arrow(nat_ty(), type0())
550}
551/// `SuffixAutomaton : Nat → Type 0` — suffix automaton (DAWG).
552pub fn suffix_automaton_ty() -> Expr {
553    arrow(nat_ty(), type0())
554}
555/// `FMIndex : Nat → Type 0` — FM-index for compressed string matching.
556pub fn fm_index_ty() -> Expr {
557    arrow(nat_ty(), type0())
558}
559/// `SuffixTreeLinearTime : Prop` — suffix tree can be built in O(n) time.
560pub fn suffix_tree_linear_time_ty() -> Expr {
561    prop()
562}
563/// `AdjacencyList : Nat → Type 0` — adjacency list graph representation.
564pub fn adjacency_list_ty() -> Expr {
565    arrow(nat_ty(), type0())
566}
567/// `AdjacencyMatrix : Nat → Type 0` — adjacency matrix graph representation.
568pub fn adjacency_matrix_ty() -> Expr {
569    arrow(nat_ty(), type0())
570}
571/// `DynamicGraph : Nat → Type 0` — dynamic graph supporting edge insertions/deletions.
572pub fn dynamic_graph_ty() -> Expr {
573    arrow(nat_ty(), type0())
574}
575/// `EdgeWeightedGraph : Nat → Type 0` — edge-weighted graph.
576pub fn edge_weighted_graph_ty() -> Expr {
577    arrow(nat_ty(), type0())
578}
579/// `KDTree : Nat → Type 0` — k-d tree for k-dimensional range queries.
580pub fn kd_tree_ty() -> Expr {
581    arrow(nat_ty(), type0())
582}
583/// `RangeTree : Nat → Type 0` — range tree for orthogonal range queries.
584pub fn range_tree_ty() -> Expr {
585    arrow(nat_ty(), type0())
586}
587/// `KDTreeNNComplexity : Prop` — k-d tree nearest neighbor runs in O(sqrt(n)) expected.
588pub fn kd_tree_nn_complexity_ty() -> Expr {
589    prop()
590}
591/// `RangeTreeQueryComplexity : Prop` — range tree answers queries in O(log^d n + k).
592pub fn range_tree_query_complexity_ty() -> Expr {
593    prop()
594}
595/// `SplayTree α : Type 0` — splay tree with amortized O(log n) per operation.
596pub fn splay_tree_ty() -> Expr {
597    arrow(type0(), type0())
598}
599/// `PairingHeap α : Type 0` — pairing heap with O(log n) amortized delete-min.
600pub fn pairing_heap_ty() -> Expr {
601    arrow(type0(), type0())
602}
603/// `FibonacciHeap α : Type 0` — Fibonacci heap with O(1) amortized decrease-key.
604pub fn fibonacci_heap_ty() -> Expr {
605    arrow(type0(), type0())
606}
607/// `SplayTreeAmortized : Prop` — splay tree access lemma and amortized O(log n).
608pub fn splay_tree_amortized_ty() -> Expr {
609    prop()
610}
611/// `FibonacciHeapDecreaseKey : Prop` — decrease-key in Fibonacci heap is O(1) amortized.
612pub fn fibonacci_heap_decrease_key_ty() -> Expr {
613    prop()
614}
615/// Register extended data structure axioms into the given kernel environment.
616pub fn build_extended_ds_env(env: &mut Environment) -> Result<(), String> {
617    let axioms: &[(&str, Expr)] = &[
618        ("PersistentArray", persistent_array_ty()),
619        ("PersistenceTheorem", persistence_theorem_ty()),
620        ("FatNodeMethod", fat_node_method_ty()),
621        ("PathCopying", path_copying_ty()),
622        ("PersistentStack", persistent_stack_ty()),
623        ("PersistentQueue", persistent_queue_ty()),
624        ("VanEmdeBoasTree", van_emde_boas_ty()),
625        ("FractionalCascading", fractional_cascading_ty()),
626        ("CacheObliviousBTree", cache_oblivious_btree_ty()),
627        ("CacheObliviousMatrix", cache_oblivious_matrix_ty()),
628        ("SuccinctBitVector", succinct_bit_vector_ty()),
629        ("WaveletTree", wavelet_tree_ty()),
630        ("CompressedSuffixArray", compressed_suffix_array_ty()),
631        ("RankSelectAxiom", rank_select_axiom_ty()),
632        ("DistributedHashTable", distributed_hash_table_ty()),
633        ("ConsistentHashing", consistent_hashing_ty()),
634        ("CRDT", crdt_ty()),
635        ("ReplicationConsistency", replication_consistency_ty()),
636        ("BloomFilterDs", bloom_filter_ds_ty()),
637        ("HyperLogLog", hyperloglog_ty()),
638        ("CountMinSketch", count_min_sketch_ty()),
639        ("BloomFilterFPR", bloom_filter_fpr_ty()),
640        ("HyperLogLogError", hyperloglog_error_ty()),
641        ("BTree", btree_ty()),
642        ("BufferTree", buffer_tree_ty()),
643        ("BTreeSearchComplexity", btree_search_complexity_ty()),
644        ("BTreeInsertComplexity", btree_insert_complexity_ty()),
645        ("LockFreeStack", lock_free_stack_ty()),
646        ("WaitFreeQueue", wait_free_queue_ty()),
647        ("Linearizability", linearizability_ty()),
648        ("WaitFreedom", wait_freedom_ty()),
649        ("RedBlackTree", red_black_tree_ty()),
650        ("RealTimeQueue", real_time_queue_ty()),
651        ("BootstrappedHeap", bootstrapped_heap_ty()),
652        ("FunctionalBSTInvariant", functional_bst_invariant_ty()),
653        ("SuffixTree", suffix_tree_ty()),
654        ("SuffixAutomaton", suffix_automaton_ty()),
655        ("FMIndex", fm_index_ty()),
656        ("SuffixTreeLinearTime", suffix_tree_linear_time_ty()),
657        ("AdjacencyList", adjacency_list_ty()),
658        ("AdjacencyMatrix", adjacency_matrix_ty()),
659        ("DynamicGraph", dynamic_graph_ty()),
660        ("EdgeWeightedGraph", edge_weighted_graph_ty()),
661        ("KDTree", kd_tree_ty()),
662        ("RangeTree", range_tree_ty()),
663        ("KDTreeNNComplexity", kd_tree_nn_complexity_ty()),
664        ("RangeTreeQueryComplexity", range_tree_query_complexity_ty()),
665        ("SplayTree", splay_tree_ty()),
666        ("PairingHeap", pairing_heap_ty()),
667        ("FibonacciHeap", fibonacci_heap_ty()),
668        ("SplayTreeAmortized", splay_tree_amortized_ty()),
669        ("FibonacciHeapDecreaseKey", fibonacci_heap_decrease_key_ty()),
670    ];
671    for (name, ty) in axioms {
672        env.add(Declaration::Axiom {
673            name: Name::str(*name),
674            univ_params: vec![],
675            ty: ty.clone(),
676        })
677        .ok();
678    }
679    Ok(())
680}
681#[cfg(test)]
682mod extended_tests {
683    use super::*;
684    #[test]
685    fn test_bloom_filter_ds() {
686        let mut bf = BloomFilterDs::new(1024, 3);
687        assert!(bf.is_empty());
688        bf.insert(42);
689        bf.insert(100);
690        bf.insert(999);
691        assert_eq!(bf.len(), 3);
692        assert!(bf.might_contain(42));
693        assert!(bf.might_contain(100));
694        assert!(bf.might_contain(999));
695        let fpr = bf.false_positive_rate();
696        assert!(fpr < 0.1, "FPR {} is too high", fpr);
697    }
698    #[test]
699    fn test_hyperloglog() {
700        let mut hll = HyperLogLog::new(10);
701        assert_eq!(hll.num_registers(), 1024);
702        for i in 0u64..1000 {
703            hll.add(i);
704        }
705        let est = hll.estimate();
706        assert!(
707            est > 800.0 && est < 1200.0,
708            "HLL estimate {} out of range [800, 1200]",
709            est
710        );
711        let err = hll.relative_error_bound();
712        assert!(err < 0.04, "Error bound {} too large", err);
713    }
714    #[test]
715    fn test_wavelet_tree() {
716        let data = vec![3u64, 1, 4, 1, 5, 9, 2, 6, 5, 3];
717        let wt = WaveletTree::new(&data, 0, 10);
718        assert_eq!(wt.len(), 10);
719        assert!(!wt.is_empty());
720        assert!(wt.num_levels() > 0);
721        let freq = wt.range_freq(&data, 0, 3, 1);
722        assert_eq!(freq, 2);
723        let freq5 = wt.range_freq(&data, 4, 8, 5);
724        assert_eq!(freq5, 2);
725    }
726    #[test]
727    fn test_succinct_bit_vector() {
728        let bits = vec![true, false, true, true, false, false, true, false];
729        let sbv = SuccinctBitVector::new(&bits);
730        assert_eq!(sbv.len(), 8);
731        assert!(!sbv.is_empty());
732        assert!(sbv.get(0));
733        assert!(!sbv.get(1));
734        assert!(sbv.get(2));
735        assert!(sbv.get(3));
736        assert!(!sbv.get(4));
737        assert!(!sbv.get(5));
738        assert!(sbv.get(6));
739        assert!(!sbv.get(7));
740        assert_eq!(sbv.rank1(3), 3);
741        assert_eq!(sbv.rank1(0), 1);
742        assert_eq!(sbv.rank1(1), 1);
743        assert_eq!(sbv.rank0(1), 1);
744        assert_eq!(sbv.popcount_total(), 4);
745        assert_eq!(sbv.select1(1), Some(0));
746        assert_eq!(sbv.select1(2), Some(2));
747        assert_eq!(sbv.select1(3), Some(3));
748        assert_eq!(sbv.select1(4), Some(6));
749        assert_eq!(sbv.select1(5), None);
750    }
751    #[test]
752    fn test_bloom_filter_no_false_negatives() {
753        let mut bf = BloomFilterDs::new(2048, 5);
754        let inserted: Vec<u64> = (0..100).collect();
755        for &k in &inserted {
756            bf.insert(k);
757        }
758        for &k in &inserted {
759            assert!(bf.might_contain(k), "False negative for key {}", k);
760        }
761    }
762    #[test]
763    fn test_succinct_bit_vector_large() {
764        let bits: Vec<bool> = (0..200).map(|i| i % 3 == 0).collect();
765        let sbv = SuccinctBitVector::new(&bits);
766        assert_eq!(sbv.len(), 200);
767        let expected_ones = bits.iter().filter(|&&b| b).count();
768        assert_eq!(sbv.popcount_total(), expected_ones);
769    }
770    #[test]
771    fn test_wavelet_tree_empty() {
772        let wt = WaveletTree::new(&[], 0, 10);
773        assert_eq!(wt.len(), 0);
774        assert!(wt.is_empty());
775    }
776    #[test]
777    fn test_hyperloglog_small() {
778        let mut hll = HyperLogLog::new(8);
779        assert_eq!(hll.num_registers(), 256);
780        hll.add(12345);
781        let est = hll.estimate();
782        assert!(est >= 0.5, "HLL estimate {} too small", est);
783    }
784    #[test]
785    fn test_extended_axiom_registration() {
786        let mut env = Environment::new();
787        build_extended_ds_env(&mut env).expect("build_extended_ds_env should succeed");
788        assert!(env.get(&Name::str("BloomFilterDs")).is_some());
789        assert!(env.get(&Name::str("HyperLogLog")).is_some());
790        assert!(env.get(&Name::str("WaveletTree")).is_some());
791        assert!(env.get(&Name::str("SuccinctBitVector")).is_some());
792        assert!(env.get(&Name::str("FibonacciHeap")).is_some());
793        assert!(env.get(&Name::str("SuffixTree")).is_some());
794        assert!(env.get(&Name::str("KDTree")).is_some());
795        assert!(env.get(&Name::str("CRDT")).is_some());
796        assert!(env.get(&Name::str("VanEmdeBoasTree")).is_some());
797        assert!(env.get(&Name::str("FMIndex")).is_some());
798    }
799}
800#[cfg(test)]
801mod ds_ext_tests {
802    use super::*;
803    #[test]
804    fn test_union_find() {
805        let mut uf = UnionFind::new(5);
806        assert_eq!(uf.num_components(), 5);
807        uf.union(0, 1);
808        uf.union(2, 3);
809        assert_eq!(uf.num_components(), 3);
810        assert!(uf.connected(0, 1));
811        assert!(!uf.connected(0, 2));
812    }
813    #[test]
814    fn test_segment_tree() {
815        let arr = vec![1i64, 3, 5, 7, 9, 11];
816        let st = SegmentTreeNew::from_slice(&arr);
817        assert_eq!(st.query_sum(0, 5), 36);
818        assert_eq!(st.query_sum(1, 3), 15);
819    }
820    #[test]
821    fn test_fenwick_tree() {
822        let mut ft = FenwickTree::new(6);
823        for (i, &v) in [1i64, 3, 5, 7, 9, 11].iter().enumerate() {
824            ft.update(i + 1, v);
825        }
826        assert_eq!(ft.range_sum(1, 6), 36);
827        assert_eq!(ft.range_sum(2, 4), 15);
828    }
829    #[test]
830    fn test_persistent_array() {
831        let mut pa: PersistArrayExt<i32> = PersistArrayExt::new(vec![1, 2, 3]);
832        let v1 = pa.update(0, 1, 99);
833        assert_eq!(pa.get(0, 1), Some(&2));
834        assert_eq!(pa.get(v1, 1), Some(&99));
835    }
836    #[test]
837    fn test_btree() {
838        let bt = BTree::new(3);
839        assert_eq!(bt.max_keys_per_node(), 5);
840        assert_eq!(bt.min_keys_per_node(), 2);
841    }
842}
843#[cfg(test)]
844mod heap_hash_tests {
845    use super::*;
846    #[test]
847    fn test_binary_min_heap() {
848        let mut heap = BinaryMinHeap::new();
849        heap.push(5);
850        heap.push(1);
851        heap.push(3);
852        assert_eq!(heap.pop(), Some(1));
853        assert_eq!(heap.pop(), Some(3));
854        assert_eq!(heap.pop(), Some(5));
855    }
856    #[test]
857    fn test_simple_hashmap() {
858        let mut hm = SimpleHashMap::new(16);
859        hm.insert(1, 100);
860        hm.insert(2, 200);
861        assert_eq!(hm.get(1), Some(100));
862        assert_eq!(hm.get(2), Some(200));
863        assert_eq!(hm.get(3), None);
864    }
865}
866#[cfg(test)]
867mod tests_data_structures_ext {
868    use super::*;
869    #[test]
870    fn test_van_emde_boas() {
871        let veb = VanEmdeBoasTree::new(16);
872        assert!(veb.is_empty());
873        assert_eq!(veb.upper_sqrt(), 4);
874        assert_eq!(veb.lower_sqrt(), 4);
875        assert_eq!(veb.high(10), 2);
876        assert_eq!(veb.low(10), 2);
877        let desc = veb.complexity_description();
878        assert!(desc.contains("van Emde Boas"));
879    }
880    #[test]
881    fn test_xfast_trie() {
882        let xf = XFastTrie::new(32);
883        let desc = xf.complexity_description();
884        assert!(desc.contains("X-Fast Trie"));
885        let pred = xf.predecessor_time();
886        assert!(pred.contains("O(log W)"));
887    }
888    #[test]
889    fn test_persistent_array() {
890        let mut pa: PersistArrayV2<i32> = PersistArrayV2::new(5);
891        let v1 = pa.update(2, 42);
892        assert_eq!(v1, 1);
893        assert_eq!(pa.data[2], 42);
894        pa.rollback();
895        assert_eq!(pa.data[2], 0);
896    }
897    #[test]
898    fn test_persistent_segment_tree() {
899        let pst = PersistentSegmentTree::new(100);
900        let space = pst.space_complexity();
901        assert!(space.contains("Persistent"));
902        let time = pst.time_complexity();
903        assert!(time.contains("historical"));
904    }
905    #[test]
906    fn test_skip_list() {
907        let mut sl = SkipListData::new(20, 0.5);
908        sl.insert();
909        sl.insert();
910        let t = sl.expected_search_time();
911        assert!(t > 0.0);
912        let space = sl.space_usage();
913        assert!(space.contains("Skip list"));
914        let pugh = sl.pugh_analysis();
915        assert!(pugh.contains("Pugh"));
916    }
917    #[test]
918    fn test_treap() {
919        let mut treap = TreapData::new();
920        treap.size = 1000;
921        let h = treap.expected_height();
922        assert!(h > 0.0);
923        let split = treap.split_at(500);
924        assert!(split.contains("O(log n)"));
925        let merge = treap.merge_description();
926        assert!(merge.contains("Merge"));
927        let it = TreapData::implicit_treap();
928        assert!(it.is_implicitly_keyed);
929    }
930}