1use 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}
50pub fn heap_ty() -> Expr {
54 arrow(type0(), type0())
55}
56pub fn trie_ty() -> Expr {
60 arrow(type0(), type0())
61}
62pub fn segment_tree_ty() -> Expr {
66 arrow(type0(), arrow(nat_ty(), type0()))
67}
68pub fn finger_tree_ty() -> Expr {
72 arrow(type0(), type0())
73}
74pub fn avl_tree_ty() -> Expr {
78 arrow(type0(), type0())
79}
80pub fn skip_list_ty() -> Expr {
84 arrow(type0(), type0())
85}
86pub fn priority_queue_ty() -> Expr {
88 arrow(type0(), type0())
89}
90pub fn disjoint_set_ty() -> Expr {
95 arrow(nat_ty(), type0())
96}
97pub fn deque_ty() -> Expr {
101 arrow(type0(), type0())
102}
103pub fn interval_tree_ty() -> Expr {
107 arrow(type0(), type0())
108}
109pub fn heap_push_ty() -> Expr {
113 impl_pi(
114 "α",
115 type0(),
116 arrow(app(cst("Heap"), bvar(0)), arrow(bvar(1), prop())),
117 )
118}
119pub fn heap_pop_ty() -> Expr {
123 impl_pi("α", type0(), arrow(app(cst("Heap"), bvar(0)), prop()))
124}
125pub fn segment_tree_query_ty() -> Expr {
129 arrow(nat_ty(), prop())
130}
131pub fn avl_balance_ty() -> Expr {
135 impl_pi("α", type0(), arrow(app(cst("AVLTree"), bvar(0)), prop()))
136}
137pub fn union_find_amortized_ty() -> Expr {
142 arrow(nat_ty(), arrow(nat_ty(), prop()))
143}
144pub 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}
395pub fn persistent_array_ty() -> Expr {
400 arrow(type0(), arrow(nat_ty(), type0()))
401}
402pub fn persistence_theorem_ty() -> Expr {
404 prop()
405}
406pub fn fat_node_method_ty() -> Expr {
408 arrow(nat_ty(), prop())
409}
410pub fn path_copying_ty() -> Expr {
412 arrow(nat_ty(), prop())
413}
414pub fn persistent_stack_ty() -> Expr {
416 arrow(type0(), type0())
417}
418pub fn persistent_queue_ty() -> Expr {
420 arrow(type0(), type0())
421}
422pub fn van_emde_boas_ty() -> Expr {
426 arrow(nat_ty(), type0())
427}
428pub fn fractional_cascading_ty() -> Expr {
430 arrow(nat_ty(), prop())
431}
432pub fn cache_oblivious_btree_ty() -> Expr {
434 arrow(nat_ty(), type0())
435}
436pub fn cache_oblivious_matrix_ty() -> Expr {
438 arrow(nat_ty(), type0())
439}
440pub fn succinct_bit_vector_ty() -> Expr {
444 arrow(nat_ty(), type0())
445}
446pub fn wavelet_tree_ty() -> Expr {
450 arrow(nat_ty(), type0())
451}
452pub fn compressed_suffix_array_ty() -> Expr {
454 arrow(nat_ty(), type0())
455}
456pub fn rank_select_axiom_ty() -> Expr {
458 prop()
459}
460pub fn distributed_hash_table_ty() -> Expr {
462 arrow(nat_ty(), type0())
463}
464pub fn consistent_hashing_ty() -> Expr {
466 arrow(nat_ty(), prop())
467}
468pub fn crdt_ty() -> Expr {
473 type0()
474}
475pub fn replication_consistency_ty() -> Expr {
477 prop()
478}
479pub fn bloom_filter_ds_ty() -> Expr {
481 arrow(nat_ty(), arrow(nat_ty(), type0()))
482}
483pub fn hyperloglog_ty() -> Expr {
485 arrow(nat_ty(), type0())
486}
487pub fn count_min_sketch_ty() -> Expr {
489 arrow(nat_ty(), arrow(nat_ty(), type0()))
490}
491pub fn bloom_filter_fpr_ty() -> Expr {
493 prop()
494}
495pub fn hyperloglog_error_ty() -> Expr {
497 prop()
498}
499pub fn btree_ty() -> Expr {
501 arrow(nat_ty(), type0())
502}
503pub fn buffer_tree_ty() -> Expr {
505 arrow(nat_ty(), type0())
506}
507pub fn btree_search_complexity_ty() -> Expr {
509 prop()
510}
511pub fn btree_insert_complexity_ty() -> Expr {
513 prop()
514}
515pub fn lock_free_stack_ty() -> Expr {
517 arrow(type0(), type0())
518}
519pub fn wait_free_queue_ty() -> Expr {
521 arrow(type0(), type0())
522}
523pub fn linearizability_ty() -> Expr {
525 prop()
526}
527pub fn wait_freedom_ty() -> Expr {
529 prop()
530}
531pub fn red_black_tree_ty() -> Expr {
533 arrow(type0(), type0())
534}
535pub fn real_time_queue_ty() -> Expr {
537 arrow(type0(), type0())
538}
539pub fn bootstrapped_heap_ty() -> Expr {
541 arrow(type0(), type0())
542}
543pub fn functional_bst_invariant_ty() -> Expr {
545 prop()
546}
547pub fn suffix_tree_ty() -> Expr {
549 arrow(nat_ty(), type0())
550}
551pub fn suffix_automaton_ty() -> Expr {
553 arrow(nat_ty(), type0())
554}
555pub fn fm_index_ty() -> Expr {
557 arrow(nat_ty(), type0())
558}
559pub fn suffix_tree_linear_time_ty() -> Expr {
561 prop()
562}
563pub fn adjacency_list_ty() -> Expr {
565 arrow(nat_ty(), type0())
566}
567pub fn adjacency_matrix_ty() -> Expr {
569 arrow(nat_ty(), type0())
570}
571pub fn dynamic_graph_ty() -> Expr {
573 arrow(nat_ty(), type0())
574}
575pub fn edge_weighted_graph_ty() -> Expr {
577 arrow(nat_ty(), type0())
578}
579pub fn kd_tree_ty() -> Expr {
581 arrow(nat_ty(), type0())
582}
583pub fn range_tree_ty() -> Expr {
585 arrow(nat_ty(), type0())
586}
587pub fn kd_tree_nn_complexity_ty() -> Expr {
589 prop()
590}
591pub fn range_tree_query_complexity_ty() -> Expr {
593 prop()
594}
595pub fn splay_tree_ty() -> Expr {
597 arrow(type0(), type0())
598}
599pub fn pairing_heap_ty() -> Expr {
601 arrow(type0(), type0())
602}
603pub fn fibonacci_heap_ty() -> Expr {
605 arrow(type0(), type0())
606}
607pub fn splay_tree_amortized_ty() -> Expr {
609 prop()
610}
611pub fn fibonacci_heap_decrease_key_ty() -> Expr {
613 prop()
614}
615pub 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}