1use oxilean_kernel::{
6 BinderInfo, Declaration, Environment, Expr, InductiveEnv, InductiveType, IntroRule, Level, Name,
7};
8
9use super::types::{CircularBuffer, DList, FenwickTree, FixedVec, PrefixScan, SparseVec};
10
11pub fn build_vec_env(env: &mut Environment, ind_env: &mut InductiveEnv) -> Result<(), String> {
15 let type1 = Expr::Sort(Level::succ(Level::zero()));
16 let vec_ty = Expr::Pi(
17 BinderInfo::Default,
18 Name::str("α"),
19 Box::new(type1.clone()),
20 Box::new(Expr::Pi(
21 BinderInfo::Default,
22 Name::str("n"),
23 Box::new(Expr::Const(Name::str("Nat"), vec![])),
24 Box::new(type1.clone()),
25 )),
26 );
27 let nil_ty = Expr::Pi(
28 BinderInfo::Implicit,
29 Name::str("α"),
30 Box::new(type1.clone()),
31 Box::new(Expr::App(
32 Box::new(Expr::App(
33 Box::new(Expr::Const(Name::str("Vec"), vec![])),
34 Box::new(Expr::BVar(0)),
35 )),
36 Box::new(Expr::Const(Name::str("Nat.zero"), vec![])),
37 )),
38 );
39 let cons_ty = Expr::Pi(
40 BinderInfo::Implicit,
41 Name::str("α"),
42 Box::new(type1.clone()),
43 Box::new(Expr::Pi(
44 BinderInfo::Implicit,
45 Name::str("n"),
46 Box::new(Expr::Const(Name::str("Nat"), vec![])),
47 Box::new(Expr::Pi(
48 BinderInfo::Default,
49 Name::str("head"),
50 Box::new(Expr::BVar(1)),
51 Box::new(Expr::Pi(
52 BinderInfo::Default,
53 Name::str("tail"),
54 Box::new(Expr::App(
55 Box::new(Expr::App(
56 Box::new(Expr::Const(Name::str("Vec"), vec![])),
57 Box::new(Expr::BVar(2)),
58 )),
59 Box::new(Expr::BVar(1)),
60 )),
61 Box::new(Expr::App(
62 Box::new(Expr::App(
63 Box::new(Expr::Const(Name::str("Vec"), vec![])),
64 Box::new(Expr::BVar(3)),
65 )),
66 Box::new(Expr::App(
67 Box::new(Expr::Const(Name::str("Nat.succ"), vec![])),
68 Box::new(Expr::BVar(2)),
69 )),
70 )),
71 )),
72 )),
73 )),
74 );
75 let vec_ind = InductiveType::new(
76 Name::str("Vec"),
77 vec![],
78 1,
79 1,
80 vec_ty.clone(),
81 vec![
82 IntroRule {
83 name: Name::str("Vec.nil"),
84 ty: nil_ty.clone(),
85 },
86 IntroRule {
87 name: Name::str("Vec.cons"),
88 ty: cons_ty.clone(),
89 },
90 ],
91 );
92 ind_env.add(vec_ind).map_err(|e| format!("{}", e))?;
93 env.add(Declaration::Axiom {
94 name: Name::str("Vec"),
95 univ_params: vec![],
96 ty: vec_ty,
97 })
98 .map_err(|e| e.to_string())?;
99 env.add(Declaration::Axiom {
100 name: Name::str("Vec.nil"),
101 univ_params: vec![],
102 ty: nil_ty,
103 })
104 .map_err(|e| e.to_string())?;
105 env.add(Declaration::Axiom {
106 name: Name::str("Vec.cons"),
107 univ_params: vec![],
108 ty: cons_ty,
109 })
110 .map_err(|e| e.to_string())?;
111 Ok(())
112}
113#[cfg(test)]
114mod tests {
115 use super::*;
116 #[test]
117 fn test_build_vec_env() {
118 let mut env = Environment::new();
119 let mut ind_env = InductiveEnv::new();
120 let type1 = Expr::Sort(Level::succ(Level::zero()));
121 env.add(Declaration::Axiom {
122 name: Name::str("Nat"),
123 univ_params: vec![],
124 ty: type1.clone(),
125 })
126 .expect("operation should succeed");
127 env.add(Declaration::Axiom {
128 name: Name::str("Nat.zero"),
129 univ_params: vec![],
130 ty: Expr::Const(Name::str("Nat"), vec![]),
131 })
132 .expect("operation should succeed");
133 env.add(Declaration::Axiom {
134 name: Name::str("Nat.succ"),
135 univ_params: vec![],
136 ty: Expr::Pi(
137 BinderInfo::Default,
138 Name::str("n"),
139 Box::new(Expr::Const(Name::str("Nat"), vec![])),
140 Box::new(Expr::Const(Name::str("Nat"), vec![])),
141 ),
142 })
143 .expect("operation should succeed");
144 assert!(build_vec_env(&mut env, &mut ind_env).is_ok());
145 assert!(env.get(&Name::str("Vec")).is_some());
146 assert!(env.get(&Name::str("Vec.nil")).is_some());
147 assert!(env.get(&Name::str("Vec.cons")).is_some());
148 }
149}
150#[allow(dead_code)]
152pub fn vec_append<T: Clone>(a: &[T], b: &[T]) -> Vec<T> {
153 let mut result = a.to_vec();
154 result.extend_from_slice(b);
155 result
156}
157#[allow(dead_code)]
159pub fn vec_contains<T: PartialEq>(v: &[T], elem: &T) -> bool {
160 v.contains(elem)
161}
162#[allow(dead_code)]
164pub fn vec_index_of<T: PartialEq>(v: &[T], elem: &T) -> Option<usize> {
165 v.iter().position(|x| x == elem)
166}
167#[allow(dead_code)]
169pub fn vec_remove_all<T: PartialEq>(v: Vec<T>, elem: &T) -> Vec<T> {
170 v.into_iter().filter(|x| x != elem).collect()
171}
172#[allow(dead_code)]
174pub fn vec_dedup_stable<T: PartialEq + Clone>(v: &[T]) -> Vec<T> {
175 let mut seen = Vec::new();
176 for item in v {
177 if !seen.contains(item) {
178 seen.push(item.clone());
179 }
180 }
181 seen
182}
183#[allow(dead_code)]
185pub fn vec_flatten<T>(v: Vec<Vec<T>>) -> Vec<T> {
186 v.into_iter().flatten().collect()
187}
188#[allow(dead_code)]
190pub fn vec_last<T>(v: &[T]) -> Option<&T> {
191 v.last()
192}
193#[allow(dead_code)]
195pub fn vec_head<T>(v: &[T]) -> Option<&T> {
196 v.first()
197}
198#[allow(dead_code)]
200pub fn vec_init<T: Clone>(v: &[T]) -> Vec<T> {
201 if v.is_empty() {
202 vec![]
203 } else {
204 v[..v.len() - 1].to_vec()
205 }
206}
207#[allow(dead_code)]
209pub fn vec_tail<T: Clone>(v: &[T]) -> Vec<T> {
210 if v.is_empty() {
211 vec![]
212 } else {
213 v[1..].to_vec()
214 }
215}
216#[allow(dead_code)]
218pub fn vec_split_at<T: Clone>(v: &[T], index: usize) -> (Vec<T>, Vec<T>) {
219 let idx = index.min(v.len());
220 (v[..idx].to_vec(), v[idx..].to_vec())
221}
222#[allow(dead_code)]
224pub fn vec_zip<A: Clone, B: Clone>(a: &[A], b: &[B]) -> Vec<(A, B)> {
225 a.iter()
226 .zip(b.iter())
227 .map(|(x, y)| (x.clone(), y.clone()))
228 .collect()
229}
230#[allow(dead_code)]
232pub fn vec_unzip<A, B>(v: Vec<(A, B)>) -> (Vec<A>, Vec<B>) {
233 v.into_iter().unzip()
234}
235#[allow(dead_code)]
237pub fn vec_remove_at<T: Clone>(v: &[T], index: usize) -> Vec<T> {
238 let mut result = v.to_vec();
239 if index < result.len() {
240 result.remove(index);
241 }
242 result
243}
244#[allow(dead_code)]
246pub fn vec_insert_at<T: Clone>(v: &[T], index: usize, elem: T) -> Vec<T> {
247 let mut result = v.to_vec();
248 let idx = index.min(result.len());
249 result.insert(idx, elem);
250 result
251}
252#[allow(dead_code)]
254pub fn vec_set<T: Clone>(v: &[T], index: usize, new_val: T) -> Vec<T> {
255 let mut result = v.to_vec();
256 if index < result.len() {
257 result[index] = new_val;
258 }
259 result
260}
261#[allow(dead_code)]
263pub fn vec_reverse<T: Clone>(v: &[T]) -> Vec<T> {
264 let mut result = v.to_vec();
265 result.reverse();
266 result
267}
268#[allow(dead_code)]
270pub fn vec_rotate_left<T: Clone>(v: &[T], n: usize) -> Vec<T> {
271 if v.is_empty() {
272 return vec![];
273 }
274 let n = n % v.len();
275 let mut result = v[n..].to_vec();
276 result.extend_from_slice(&v[..n]);
277 result
278}
279#[allow(dead_code)]
281pub fn vec_rotate_right<T: Clone>(v: &[T], n: usize) -> Vec<T> {
282 if v.is_empty() {
283 return vec![];
284 }
285 let n = n % v.len();
286 vec_rotate_left(v, v.len() - n)
287}
288#[allow(dead_code)]
290pub fn vec_step_by<T: Clone>(v: &[T], start: usize, step: usize) -> Vec<T> {
291 if step == 0 {
292 return vec![];
293 }
294 v.iter()
295 .enumerate()
296 .filter(|(i, _)| i >= &start && (i - start) % step == 0)
297 .map(|(_, x)| x.clone())
298 .collect()
299}
300#[allow(dead_code)]
302pub fn vec_count_where<T, F: Fn(&T) -> bool>(v: &[T], pred: F) -> usize {
303 v.iter().filter(|x| pred(x)).count()
304}
305#[allow(dead_code)]
307pub fn vec_partition<T, F: Fn(&T) -> bool>(v: Vec<T>, pred: F) -> (Vec<T>, Vec<T>) {
308 v.into_iter().partition(|x| pred(x))
309}
310#[allow(dead_code)]
312pub fn vec_try_map<T, U, E, F: Fn(T) -> Result<U, E>>(v: Vec<T>, f: F) -> Result<Vec<U>, E> {
313 v.into_iter().map(f).collect()
314}
315#[allow(dead_code)]
317pub fn vec_intersperse<T: Clone>(v: &[T], sep: T) -> Vec<T> {
318 if v.is_empty() {
319 return vec![];
320 }
321 let mut result = Vec::with_capacity(v.len() * 2 - 1);
322 for (i, x) in v.iter().enumerate() {
323 if i > 0 {
324 result.push(sep.clone());
325 }
326 result.push(x.clone());
327 }
328 result
329}
330#[allow(dead_code)]
334pub fn vec_transpose<T: Clone>(matrix: &[Vec<T>]) -> Vec<Vec<T>> {
335 if matrix.is_empty() || matrix[0].is_empty() {
336 return vec![];
337 }
338 let rows = matrix.len();
339 let cols = matrix[0].len();
340 (0..cols)
341 .map(|c| (0..rows).map(|r| matrix[r][c].clone()).collect())
342 .collect()
343}
344#[allow(dead_code)]
348pub fn vec_cartesian_product<T: Clone>(vecs: &[Vec<T>]) -> Vec<Vec<T>> {
349 if vecs.is_empty() {
350 return vec![vec![]];
351 }
352 let mut result = vec![vec![]];
353 for row in vecs {
354 let mut new_result = Vec::new();
355 for prefix in &result {
356 for item in row {
357 let mut new_prefix = prefix.clone();
358 new_prefix.push(item.clone());
359 new_result.push(new_prefix);
360 }
361 }
362 result = new_result;
363 }
364 result
365}
366#[allow(dead_code)]
368pub fn vec_max<T: Ord + Clone>(v: &[T]) -> Option<T> {
369 v.iter().max().cloned()
370}
371#[allow(dead_code)]
373pub fn vec_min<T: Ord + Clone>(v: &[T]) -> Option<T> {
374 v.iter().min().cloned()
375}
376#[allow(dead_code)]
378pub fn vec_sum_u64(v: &[u64]) -> u64 {
379 v.iter().sum()
380}
381#[allow(dead_code)]
383pub fn vec_product_u64(v: &[u64]) -> u64 {
384 v.iter().product()
385}
386#[cfg(test)]
387mod vec_extra_tests {
388 use super::*;
389 #[test]
390 fn test_vec_append() {
391 let a = vec![1, 2];
392 let b = vec![3, 4];
393 assert_eq!(vec_append(&a, &b), vec![1, 2, 3, 4]);
394 }
395 #[test]
396 fn test_vec_dedup_stable() {
397 let v = vec![1, 2, 1, 3, 2, 4];
398 assert_eq!(vec_dedup_stable(&v), vec![1, 2, 3, 4]);
399 }
400 #[test]
401 fn test_vec_flatten() {
402 let v = vec![vec![1, 2], vec![3], vec![4, 5]];
403 assert_eq!(vec_flatten(v), vec![1, 2, 3, 4, 5]);
404 }
405 #[test]
406 fn test_vec_head_tail() {
407 let v = vec![10, 20, 30];
408 assert_eq!(vec_head(&v), Some(&10));
409 assert_eq!(vec_tail(&v), vec![20, 30]);
410 assert_eq!(vec_init(&v), vec![10, 20]);
411 }
412 #[test]
413 fn test_vec_zip_unzip() {
414 let a = vec![1, 2, 3];
415 let b = vec!["a", "b", "c"];
416 let zipped = vec_zip(&a, &b);
417 assert_eq!(zipped, vec![(1, "a"), (2, "b"), (3, "c")]);
418 let (a2, b2): (Vec<_>, Vec<_>) = vec_unzip(zipped);
419 assert_eq!(a2, a);
420 assert_eq!(b2, b);
421 }
422 #[test]
423 fn test_vec_rotate() {
424 let v = vec![1, 2, 3, 4, 5];
425 assert_eq!(vec_rotate_left(&v, 2), vec![3, 4, 5, 1, 2]);
426 assert_eq!(vec_rotate_right(&v, 2), vec![4, 5, 1, 2, 3]);
427 }
428 #[test]
429 fn test_vec_intersperse() {
430 let v = vec![1, 2, 3];
431 assert_eq!(vec_intersperse(&v, 0), vec![1, 0, 2, 0, 3]);
432 }
433 #[test]
434 fn test_vec_transpose() {
435 let m = vec![vec![1, 2, 3], vec![4, 5, 6]];
436 let t = vec_transpose(&m);
437 assert_eq!(t, vec![vec![1, 4], vec![2, 5], vec![3, 6]]);
438 }
439 #[test]
440 fn test_vec_cartesian_product() {
441 let vecs = vec![vec![1, 2], vec![3, 4]];
442 let product = vec_cartesian_product(&vecs);
443 assert_eq!(product.len(), 4);
444 assert!(product.contains(&vec![1, 3]));
445 assert!(product.contains(&vec![2, 4]));
446 }
447 #[test]
448 fn test_vec_partition() {
449 let v = vec![1, 2, 3, 4, 5, 6];
450 let (even, odd) = vec_partition(v, |x| x % 2 == 0);
451 assert_eq!(even, vec![2, 4, 6]);
452 assert_eq!(odd, vec![1, 3, 5]);
453 }
454 #[test]
455 fn test_fixed_vec() {
456 let fv = FixedVec::from_vec(vec![10, 20, 30]);
457 assert_eq!(fv.len(), 3);
458 assert_eq!(fv.get(1), Some(&20));
459 assert_eq!(fv.get(5), None);
460 }
461 #[test]
462 fn test_vec_step_by() {
463 let v = vec![0, 1, 2, 3, 4, 5, 6];
464 assert_eq!(vec_step_by(&v, 0, 2), vec![0, 2, 4, 6]);
465 }
466 #[test]
467 fn test_vec_count_where() {
468 let v = vec![1, 2, 3, 4, 5];
469 assert_eq!(vec_count_where(&v, |x| *x > 3), 2);
470 }
471 #[test]
472 fn test_vec_min_max() {
473 let v = vec![3, 1, 4, 1, 5, 9];
474 assert_eq!(vec_min(&v), Some(1));
475 assert_eq!(vec_max(&v), Some(9));
476 }
477 #[test]
478 fn test_vec_remove_at_insert_at() {
479 let v = vec![1, 2, 3, 4];
480 let removed = vec_remove_at(&v, 1);
481 assert_eq!(removed, vec![1, 3, 4]);
482 let inserted = vec_insert_at(&v, 2, 99);
483 assert_eq!(inserted, vec![1, 2, 99, 3, 4]);
484 }
485 #[test]
486 fn test_vec_try_map() {
487 let v = vec!["1", "2", "3"];
488 let result: Result<Vec<u32>, _> = vec_try_map(v, |s| s.parse::<u32>());
489 assert_eq!(result.expect("result should be valid"), vec![1, 2, 3]);
490 }
491}
492#[allow(dead_code)]
494pub fn same_length_check<A, B>(a: &[A], b: &[B]) -> Result<(), String> {
495 if a.len() == b.len() {
496 Ok(())
497 } else {
498 Err(format!("length mismatch: {} vs {}", a.len(), b.len()))
499 }
500}
501#[allow(dead_code)]
503pub fn zip_exact<A: Clone, B: Clone>(a: &[A], b: &[B]) -> Result<Vec<(A, B)>, String> {
504 same_length_check(a, b)?;
505 Ok(vec_zip(a, b))
506}
507#[allow(dead_code)]
509pub fn indexed_map<T, U, F: Fn(usize, &T) -> U>(v: &[T], f: F) -> Vec<(usize, U)> {
510 v.iter().enumerate().map(|(i, x)| (i, f(i, x))).collect()
511}
512#[allow(dead_code)]
514pub fn argmax<T: PartialOrd>(v: &[T]) -> Option<usize> {
515 if v.is_empty() {
516 return None;
517 }
518 let mut best = 0;
519 for (i, x) in v.iter().enumerate() {
520 if *x > v[best] {
521 best = i;
522 }
523 }
524 Some(best)
525}
526#[allow(dead_code)]
528pub fn argmin<T: PartialOrd>(v: &[T]) -> Option<usize> {
529 if v.is_empty() {
530 return None;
531 }
532 let mut best = 0;
533 for (i, x) in v.iter().enumerate() {
534 if *x < v[best] {
535 best = i;
536 }
537 }
538 Some(best)
539}
540#[allow(dead_code)]
542pub fn run_length_encode<T: PartialEq + Clone>(v: &[T]) -> Vec<(T, usize)> {
543 if v.is_empty() {
544 return vec![];
545 }
546 let mut result = Vec::new();
547 let mut current = v[0].clone();
548 let mut count = 1;
549 for item in &v[1..] {
550 if *item == current {
551 count += 1;
552 } else {
553 result.push((current.clone(), count));
554 current = item.clone();
555 count = 1;
556 }
557 }
558 result.push((current, count));
559 result
560}
561#[allow(dead_code)]
563pub fn run_length_decode<T: Clone>(encoded: &[(T, usize)]) -> Vec<T> {
564 let mut result = Vec::new();
565 for (item, count) in encoded {
566 for _ in 0..*count {
567 result.push(item.clone());
568 }
569 }
570 result
571}
572#[allow(dead_code)]
574pub fn windows_collect<T: Clone>(v: &[T], window: usize) -> Vec<Vec<T>> {
575 if window == 0 || window > v.len() {
576 return vec![];
577 }
578 v.windows(window).map(|w| w.to_vec()).collect()
579}
580#[allow(dead_code)]
582pub fn is_palindrome<T: PartialEq>(v: &[T]) -> bool {
583 let n = v.len();
584 for i in 0..n / 2 {
585 if v[i] != v[n - 1 - i] {
586 return false;
587 }
588 }
589 true
590}
591#[allow(dead_code)]
593pub fn flatten_once<T: Clone>(v: &[Vec<T>]) -> Vec<T> {
594 v.iter().flat_map(|inner| inner.iter().cloned()).collect()
595}
596#[allow(dead_code)]
598pub fn group_by<T: Clone, K: PartialEq, F: Fn(&T) -> K>(v: &[T], key: F) -> Vec<Vec<T>> {
599 if v.is_empty() {
600 return vec![];
601 }
602 let mut groups: Vec<Vec<T>> = Vec::new();
603 let mut current_group = vec![v[0].clone()];
604 let mut current_key = key(&v[0]);
605 for item in &v[1..] {
606 let k = key(item);
607 if k == current_key {
608 current_group.push(item.clone());
609 } else {
610 groups.push(current_group.clone());
611 current_group = vec![item.clone()];
612 current_key = k;
613 }
614 }
615 groups.push(current_group);
616 groups
617}
618#[cfg(test)]
619mod vec_extra_tests2 {
620 use super::*;
621 #[test]
622 fn test_same_length_check() {
623 assert!(same_length_check(&[1, 2], &[3, 4]).is_ok());
624 assert!(same_length_check(&[1], &[3, 4]).is_err());
625 }
626 #[test]
627 fn test_zip_exact() {
628 let a = vec![1, 2, 3];
629 let b = vec!["a", "b", "c"];
630 let z = zip_exact(&a, &b).expect("operation should succeed");
631 assert_eq!(z.len(), 3);
632 assert!(zip_exact(&[1], &[2, 3]).is_err());
633 }
634 #[test]
635 fn test_argmax_argmin() {
636 let v = vec![3.0f64, 1.0, 4.0, 1.0, 5.0, 9.0, 2.0, 6.0];
637 assert_eq!(argmax(&v), Some(5));
638 assert_eq!(argmin(&v), Some(1));
639 let empty: Vec<f64> = vec![];
640 assert!(argmax(&empty).is_none());
641 }
642 #[test]
643 fn test_run_length_encode_decode() {
644 let v = vec![1, 1, 2, 3, 3, 3, 1];
645 let enc = run_length_encode(&v);
646 assert_eq!(enc, vec![(1, 2), (2, 1), (3, 3), (1, 1)]);
647 let dec = run_length_decode(&enc);
648 assert_eq!(dec, v);
649 }
650 #[test]
651 fn test_windows_collect() {
652 let v = vec![1, 2, 3, 4];
653 let wins = windows_collect(&v, 2);
654 assert_eq!(wins, vec![vec![1, 2], vec![2, 3], vec![3, 4]]);
655 }
656 #[test]
657 fn test_is_palindrome() {
658 assert!(is_palindrome(&[1, 2, 1]));
659 assert!(is_palindrome(&[1, 2, 2, 1]));
660 assert!(!is_palindrome(&[1, 2, 3]));
661 assert!(is_palindrome::<i32>(&[]));
662 }
663 #[test]
664 fn test_flatten_once() {
665 let v = vec![vec![1, 2], vec![3], vec![4, 5]];
666 assert_eq!(flatten_once(&v), vec![1, 2, 3, 4, 5]);
667 }
668 #[test]
669 fn test_group_by() {
670 let v = vec![1, 1, 2, 3, 3, 1];
671 let groups = group_by(&v, |x| *x);
672 assert_eq!(groups.len(), 4);
673 assert_eq!(groups[0], vec![1, 1]);
674 assert_eq!(groups[2], vec![3, 3]);
675 }
676 #[test]
677 fn test_indexed_map() {
678 let v = vec![10, 20, 30];
679 let result = indexed_map(&v, |i, x| i + x);
680 assert_eq!(result, vec![(0, 10), (1, 21), (2, 32)]);
681 }
682}
683#[allow(dead_code)]
685pub fn vec_difference<T: PartialEq + Clone>(a: &[T], b: &[T]) -> Vec<T> {
686 a.iter().filter(|x| !b.contains(x)).cloned().collect()
687}
688#[allow(dead_code)]
690pub fn vec_intersection<T: PartialEq + Clone>(a: &[T], b: &[T]) -> Vec<T> {
691 a.iter().filter(|x| b.contains(x)).cloned().collect()
692}
693#[allow(dead_code)]
695pub fn vec_symmetric_difference<T: PartialEq + Clone>(a: &[T], b: &[T]) -> Vec<T> {
696 let mut result = vec_difference(a, b);
697 result.extend(vec_difference(b, a));
698 result
699}
700#[allow(dead_code)]
702pub fn vec_set_eq<T: PartialEq>(a: &[T], b: &[T]) -> bool {
703 if a.len() != b.len() {
704 return false;
705 }
706 a.iter().all(|x| b.contains(x))
707}
708#[allow(dead_code)]
710pub fn vec_is_subset<T: PartialEq>(a: &[T], b: &[T]) -> bool {
711 a.iter().all(|x| b.contains(x))
712}
713#[allow(dead_code)]
717pub fn vec_mean_f64(v: &[f64]) -> f64 {
718 if v.is_empty() {
719 return f64::NAN;
720 }
721 v.iter().sum::<f64>() / v.len() as f64
722}
723#[allow(dead_code)]
725pub fn vec_variance_f64(v: &[f64]) -> f64 {
726 if v.is_empty() {
727 return f64::NAN;
728 }
729 let mean = vec_mean_f64(v);
730 v.iter().map(|x| (x - mean).powi(2)).sum::<f64>() / v.len() as f64
731}
732#[allow(dead_code)]
734pub fn vec_std_dev_f64(v: &[f64]) -> f64 {
735 vec_variance_f64(v).sqrt()
736}
737#[allow(dead_code)]
742pub fn vec_median_f64(v: &[f64]) -> f64 {
743 if v.is_empty() {
744 return f64::NAN;
745 }
746 let mut sorted = v.to_vec();
747 sorted.sort_by(|a, b| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal));
748 let n = sorted.len();
749 if n % 2 == 1 {
750 sorted[n / 2]
751 } else {
752 (sorted[n / 2 - 1] + sorted[n / 2]) / 2.0
753 }
754}
755#[allow(dead_code)]
759pub fn vec_normalize_f64(v: &[f64]) -> Vec<f64> {
760 let total: f64 = v.iter().sum();
761 if total == 0.0 {
762 return v.to_vec();
763 }
764 v.iter().map(|x| x / total).collect()
765}
766#[allow(dead_code)]
770pub fn vec_chunks<T: Clone>(v: &[T], size: usize) -> Vec<Vec<T>> {
771 if size == 0 {
772 return vec![];
773 }
774 v.chunks(size).map(|c| c.to_vec()).collect()
775}
776#[allow(dead_code)]
778pub fn vec_take<T: Clone>(v: &[T], n: usize) -> Vec<T> {
779 v.iter().take(n).cloned().collect()
780}
781#[allow(dead_code)]
783pub fn vec_drop<T: Clone>(v: &[T], n: usize) -> Vec<T> {
784 v.iter().skip(n).cloned().collect()
785}
786#[allow(dead_code)]
788pub fn vec_take_while<T: Clone, F: Fn(&T) -> bool>(v: &[T], pred: F) -> Vec<T> {
789 v.iter().take_while(|x| pred(x)).cloned().collect()
790}
791#[allow(dead_code)]
793pub fn vec_drop_while<T: Clone, F: Fn(&T) -> bool>(v: &[T], pred: F) -> Vec<T> {
794 v.iter().skip_while(|x| pred(x)).cloned().collect()
795}
796#[cfg(test)]
797mod vec_set_op_tests {
798 use super::*;
799 #[test]
800 fn test_vec_difference() {
801 assert_eq!(vec_difference(&[1, 2, 3], &[2, 4]), vec![1, 3]);
802 }
803 #[test]
804 fn test_vec_intersection() {
805 assert_eq!(vec_intersection(&[1, 2, 3, 4], &[2, 4, 6]), vec![2, 4]);
806 }
807 #[test]
808 fn test_vec_symmetric_difference() {
809 let r = vec_symmetric_difference(&[1, 2, 3], &[2, 3, 4]);
810 assert!(r.contains(&1) && r.contains(&4));
811 assert!(!r.contains(&2));
812 }
813 #[test]
814 fn test_vec_set_eq() {
815 assert!(vec_set_eq(&[1, 2, 3], &[3, 1, 2]));
816 assert!(!vec_set_eq(&[1, 2], &[1, 2, 3]));
817 }
818 #[test]
819 fn test_vec_is_subset() {
820 assert!(vec_is_subset(&[1, 2], &[1, 2, 3]));
821 assert!(!vec_is_subset(&[1, 4], &[1, 2, 3]));
822 }
823 #[test]
824 fn test_vec_mean_f64() {
825 assert!((vec_mean_f64(&[1.0, 2.0, 3.0]) - 2.0).abs() < 1e-9);
826 assert!(vec_mean_f64(&[]).is_nan());
827 }
828 #[test]
829 fn test_vec_variance_f64() {
830 let v = vec![2.0, 4.0, 4.0, 4.0, 5.0, 5.0, 7.0, 9.0];
831 let var = vec_variance_f64(&v);
832 assert!((var - 4.0).abs() < 1e-9);
833 }
834 #[test]
835 fn test_vec_std_dev_f64() {
836 let v = vec![2.0, 4.0, 4.0, 4.0, 5.0, 5.0, 7.0, 9.0];
837 let std = vec_std_dev_f64(&v);
838 assert!((std - 2.0).abs() < 1e-9);
839 }
840 #[test]
841 fn test_vec_median_f64_odd() {
842 assert!((vec_median_f64(&[3.0, 1.0, 2.0]) - 2.0).abs() < 1e-9);
843 }
844 #[test]
845 fn test_vec_median_f64_even() {
846 assert!((vec_median_f64(&[1.0, 3.0, 5.0, 7.0]) - 4.0).abs() < 1e-9);
847 }
848 #[test]
849 fn test_vec_normalize_f64() {
850 let v = vec![1.0, 2.0, 3.0, 4.0];
851 let n = vec_normalize_f64(&v);
852 let sum: f64 = n.iter().sum();
853 assert!((sum - 1.0).abs() < 1e-9);
854 }
855 #[test]
856 fn test_vec_chunks() {
857 let v = vec![1, 2, 3, 4, 5];
858 let chunks = vec_chunks(&v, 2);
859 assert_eq!(chunks.len(), 3);
860 assert_eq!(chunks[2], vec![5]);
861 }
862 #[test]
863 fn test_vec_take_drop() {
864 let v = vec![1, 2, 3, 4, 5];
865 assert_eq!(vec_take(&v, 3), vec![1, 2, 3]);
866 assert_eq!(vec_drop(&v, 3), vec![4, 5]);
867 }
868 #[test]
869 fn test_vec_take_while_drop_while() {
870 let v = vec![1, 2, 3, 4, 5];
871 let tw = vec_take_while(&v, |x| *x < 4);
872 assert_eq!(tw, vec![1, 2, 3]);
873 let dw = vec_drop_while(&v, |x| *x < 4);
874 assert_eq!(dw, vec![4, 5]);
875 }
876 #[test]
877 fn test_vec_normalize_zero_sum() {
878 let v = vec![0.0, 0.0, 0.0];
879 let n = vec_normalize_f64(&v);
880 assert_eq!(n, v);
881 }
882 #[test]
883 fn test_vec_chunks_zero_size() {
884 let v = vec![1, 2, 3];
885 let chunks = vec_chunks(&v, 0);
886 assert!(chunks.is_empty());
887 }
888}
889pub fn vec_ext_prop_axiom(name: &str, env: &mut Environment) -> std::result::Result<(), String> {
890 let prop = Expr::Sort(Level::zero());
891 env.add(Declaration::Axiom {
892 name: Name::str(name),
893 univ_params: vec![],
894 ty: prop,
895 })
896 .map_err(|e| e.to_string())
897}
898pub fn vec_ext_forall1_axiom(name: &str, env: &mut Environment) -> std::result::Result<(), String> {
900 let prop = Expr::Sort(Level::zero());
901 let type1 = Expr::Sort(Level::succ(Level::zero()));
902 let ty = Expr::Pi(
903 BinderInfo::Implicit,
904 Name::str("α"),
905 Box::new(type1),
906 Box::new(prop),
907 );
908 env.add(Declaration::Axiom {
909 name: Name::str(name),
910 univ_params: vec![],
911 ty,
912 })
913 .map_err(|e| e.to_string())
914}
915pub fn vec_ext_forall2_axiom(name: &str, env: &mut Environment) -> std::result::Result<(), String> {
917 let prop = Expr::Sort(Level::zero());
918 let type1 = Expr::Sort(Level::succ(Level::zero()));
919 let ty = Expr::Pi(
920 BinderInfo::Implicit,
921 Name::str("α"),
922 Box::new(type1.clone()),
923 Box::new(Expr::Pi(
924 BinderInfo::Implicit,
925 Name::str("β"),
926 Box::new(type1),
927 Box::new(prop),
928 )),
929 );
930 env.add(Declaration::Axiom {
931 name: Name::str(name),
932 univ_params: vec![],
933 ty,
934 })
935 .map_err(|e| e.to_string())
936}
937pub fn vec_ext_forall3_axiom(name: &str, env: &mut Environment) -> std::result::Result<(), String> {
939 let prop = Expr::Sort(Level::zero());
940 let type1 = Expr::Sort(Level::succ(Level::zero()));
941 let ty = Expr::Pi(
942 BinderInfo::Implicit,
943 Name::str("α"),
944 Box::new(type1.clone()),
945 Box::new(Expr::Pi(
946 BinderInfo::Implicit,
947 Name::str("β"),
948 Box::new(type1.clone()),
949 Box::new(Expr::Pi(
950 BinderInfo::Implicit,
951 Name::str("γ"),
952 Box::new(type1),
953 Box::new(prop),
954 )),
955 )),
956 );
957 env.add(Declaration::Axiom {
958 name: Name::str(name),
959 univ_params: vec![],
960 ty,
961 })
962 .map_err(|e| e.to_string())
963}
964pub fn vec_ext_build_functor_map_id(env: &mut Environment) -> std::result::Result<(), String> {
966 vec_ext_forall1_axiom("Vec.functor_map_id", env)
967}
968pub fn vec_ext_build_functor_map_comp(env: &mut Environment) -> std::result::Result<(), String> {
970 vec_ext_forall3_axiom("Vec.functor_map_comp", env)
971}
972pub fn vec_ext_build_monad_left_id(env: &mut Environment) -> std::result::Result<(), String> {
974 vec_ext_forall2_axiom("Vec.monad_left_id", env)
975}
976pub fn vec_ext_build_monad_right_id(env: &mut Environment) -> std::result::Result<(), String> {
978 vec_ext_forall1_axiom("Vec.monad_right_id", env)
979}
980pub fn vec_ext_build_monad_assoc(env: &mut Environment) -> std::result::Result<(), String> {
982 vec_ext_forall3_axiom("Vec.monad_assoc", env)
983}
984pub fn vec_ext_build_ap_identity(env: &mut Environment) -> std::result::Result<(), String> {
986 vec_ext_forall1_axiom("Vec.ap_identity", env)
987}
988pub fn vec_ext_build_ap_homomorphism(env: &mut Environment) -> std::result::Result<(), String> {
990 vec_ext_forall2_axiom("Vec.ap_homomorphism", env)
991}
992pub fn vec_ext_build_ap_interchange(env: &mut Environment) -> std::result::Result<(), String> {
994 vec_ext_forall2_axiom("Vec.ap_interchange", env)
995}
996pub fn vec_ext_build_ap_composition(env: &mut Environment) -> std::result::Result<(), String> {
998 vec_ext_forall3_axiom("Vec.ap_composition", env)
999}
1000pub fn vec_ext_build_foldr_nil(env: &mut Environment) -> std::result::Result<(), String> {
1002 vec_ext_forall2_axiom("Vec.foldr_nil", env)
1003}
1004pub fn vec_ext_build_foldr_cons(env: &mut Environment) -> std::result::Result<(), String> {
1006 vec_ext_forall2_axiom("Vec.foldr_cons", env)
1007}
1008pub fn vec_ext_build_foldl_nil(env: &mut Environment) -> std::result::Result<(), String> {
1010 vec_ext_forall2_axiom("Vec.foldl_nil", env)
1011}
1012pub fn vec_ext_build_foldl_cons(env: &mut Environment) -> std::result::Result<(), String> {
1014 vec_ext_forall2_axiom("Vec.foldl_cons", env)
1015}
1016pub fn vec_ext_build_foldl_foldr_duality(env: &mut Environment) -> std::result::Result<(), String> {
1018 vec_ext_forall2_axiom("Vec.foldl_foldr_duality", env)
1019}
1020pub fn vec_ext_build_scanl_nil(env: &mut Environment) -> std::result::Result<(), String> {
1022 vec_ext_forall2_axiom("Vec.scanl_nil", env)
1023}
1024pub fn vec_ext_build_scanl_cons(env: &mut Environment) -> std::result::Result<(), String> {
1026 vec_ext_forall2_axiom("Vec.scanl_cons", env)
1027}
1028pub fn vec_ext_build_scanr_nil(env: &mut Environment) -> std::result::Result<(), String> {
1030 vec_ext_forall2_axiom("Vec.scanr_nil", env)
1031}
1032pub fn vec_ext_build_scanr_cons(env: &mut Environment) -> std::result::Result<(), String> {
1034 vec_ext_forall2_axiom("Vec.scanr_cons", env)
1035}
1036pub fn vec_ext_build_scanl_last(env: &mut Environment) -> std::result::Result<(), String> {
1038 vec_ext_forall2_axiom("Vec.scanl_last", env)
1039}
1040pub fn vec_ext_build_sort_is_permutation(env: &mut Environment) -> std::result::Result<(), String> {
1042 vec_ext_forall1_axiom("Vec.sort_is_permutation", env)
1043}
1044pub fn vec_ext_build_sort_is_sorted(env: &mut Environment) -> std::result::Result<(), String> {
1046 vec_ext_forall1_axiom("Vec.sort_is_sorted", env)
1047}
1048pub fn vec_ext_build_stable_sort(env: &mut Environment) -> std::result::Result<(), String> {
1050 vec_ext_forall1_axiom("Vec.stable_sort_preserves_order", env)
1051}
1052pub fn vec_ext_build_sort_idempotent(env: &mut Environment) -> std::result::Result<(), String> {
1054 vec_ext_forall1_axiom("Vec.sort_idempotent", env)
1055}
1056pub fn vec_ext_build_map_fusion(env: &mut Environment) -> std::result::Result<(), String> {
1058 vec_ext_forall3_axiom("Vec.map_fusion", env)
1059}
1060pub fn vec_ext_build_filter_fusion(env: &mut Environment) -> std::result::Result<(), String> {
1062 vec_ext_forall1_axiom("Vec.filter_fusion", env)
1063}
1064pub fn vec_ext_build_map_filter_fusion(env: &mut Environment) -> std::result::Result<(), String> {
1066 vec_ext_forall2_axiom("Vec.map_filter_fusion", env)
1067}
1068pub fn vec_ext_build_fold_build_duality(env: &mut Environment) -> std::result::Result<(), String> {
1070 vec_ext_forall2_axiom("Vec.fold_build_duality", env)
1071}
1072pub fn vec_ext_build_fin_index_get(env: &mut Environment) -> std::result::Result<(), String> {
1074 vec_ext_forall2_axiom("Vec.fin_index_get", env)
1075}
1076pub fn vec_ext_build_fin_index_set(env: &mut Environment) -> std::result::Result<(), String> {
1078 vec_ext_forall2_axiom("Vec.fin_index_set", env)
1079}
1080pub fn vec_ext_build_fin_map_length(env: &mut Environment) -> std::result::Result<(), String> {
1082 vec_ext_forall2_axiom("Vec.fin_map_preserves_length", env)
1083}
1084pub fn vec_ext_build_reverse_involutive(env: &mut Environment) -> std::result::Result<(), String> {
1086 vec_ext_forall1_axiom("Vec.reverse_involutive", env)
1087}
1088pub fn vec_ext_build_reverse_append(env: &mut Environment) -> std::result::Result<(), String> {
1090 vec_ext_forall1_axiom("Vec.reverse_append", env)
1091}
1092pub fn vec_ext_build_reverse_map(env: &mut Environment) -> std::result::Result<(), String> {
1094 vec_ext_forall2_axiom("Vec.reverse_map", env)
1095}
1096pub fn vec_ext_build_take_drop_reconstruct(
1098 env: &mut Environment,
1099) -> std::result::Result<(), String> {
1100 vec_ext_forall1_axiom("Vec.take_drop_reconstruct", env)
1101}
1102pub fn vec_ext_build_take_length(env: &mut Environment) -> std::result::Result<(), String> {
1104 vec_ext_forall1_axiom("Vec.take_length", env)
1105}
1106pub fn vec_ext_build_drop_length(env: &mut Environment) -> std::result::Result<(), String> {
1108 vec_ext_forall1_axiom("Vec.drop_length", env)
1109}
1110pub fn vec_ext_build_zip_length(env: &mut Environment) -> std::result::Result<(), String> {
1112 vec_ext_forall2_axiom("Vec.zip_length", env)
1113}
1114pub fn vec_ext_build_unzip_zip(env: &mut Environment) -> std::result::Result<(), String> {
1116 vec_ext_forall2_axiom("Vec.unzip_zip", env)
1117}
1118pub fn vec_ext_build_zip_map(env: &mut Environment) -> std::result::Result<(), String> {
1120 vec_ext_forall3_axiom("Vec.zip_map", env)
1121}
1122pub fn vec_ext_build_chunks_flatten(env: &mut Environment) -> std::result::Result<(), String> {
1124 vec_ext_forall1_axiom("Vec.chunks_flatten", env)
1125}
1126pub fn vec_ext_build_chunks_all_size(env: &mut Environment) -> std::result::Result<(), String> {
1128 vec_ext_forall1_axiom("Vec.chunks_all_size", env)
1129}
1130pub fn vec_ext_build_chunks_count(env: &mut Environment) -> std::result::Result<(), String> {
1132 vec_ext_forall1_axiom("Vec.chunks_count", env)
1133}
1134pub fn vec_ext_build_append_nil_left(env: &mut Environment) -> std::result::Result<(), String> {
1136 vec_ext_forall1_axiom("Vec.append_nil_left", env)
1137}
1138pub fn vec_ext_build_append_nil_right(env: &mut Environment) -> std::result::Result<(), String> {
1140 vec_ext_forall1_axiom("Vec.append_nil_right", env)
1141}
1142pub fn vec_ext_build_append_assoc(env: &mut Environment) -> std::result::Result<(), String> {
1144 vec_ext_forall1_axiom("Vec.append_assoc", env)
1145}
1146pub fn vec_ext_build_length_append(env: &mut Environment) -> std::result::Result<(), String> {
1148 vec_ext_forall1_axiom("Vec.length_append", env)
1149}
1150pub fn vec_ext_build_rotate_left_right_inv(
1152 env: &mut Environment,
1153) -> std::result::Result<(), String> {
1154 vec_ext_forall1_axiom("Vec.rotate_left_right_inverse", env)
1155}
1156pub fn vec_ext_build_rotate_length(env: &mut Environment) -> std::result::Result<(), String> {
1158 vec_ext_forall1_axiom("Vec.rotate_length", env)
1159}
1160pub fn vec_ext_build_rotate_zero(env: &mut Environment) -> std::result::Result<(), String> {
1162 vec_ext_forall1_axiom("Vec.rotate_zero", env)
1163}
1164pub fn vec_ext_build_dlist_append_assoc(env: &mut Environment) -> std::result::Result<(), String> {
1166 vec_ext_forall1_axiom("Vec.dlist_append_assoc", env)
1167}
1168pub fn vec_ext_build_dlist_to_list(env: &mut Environment) -> std::result::Result<(), String> {
1170 vec_ext_forall1_axiom("Vec.dlist_to_list_preserves", env)
1171}
1172pub fn vec_ext_build_concat_map_id(env: &mut Environment) -> std::result::Result<(), String> {
1174 vec_ext_forall1_axiom("Vec.concat_map_id", env)
1175}
1176pub fn vec_ext_build_concat_map_assoc(env: &mut Environment) -> std::result::Result<(), String> {
1178 vec_ext_forall3_axiom("Vec.concat_map_assoc", env)
1179}
1180pub fn vec_ext_build_flatten_singleton(env: &mut Environment) -> std::result::Result<(), String> {
1182 vec_ext_forall1_axiom("Vec.flatten_singleton", env)
1183}
1184pub fn vec_ext_build_flatten_map(env: &mut Environment) -> std::result::Result<(), String> {
1186 vec_ext_forall2_axiom("Vec.flatten_map", env)
1187}
1188pub fn vec_ext_build_span_reconstruct(env: &mut Environment) -> std::result::Result<(), String> {
1190 vec_ext_forall1_axiom("Vec.span_reconstruct", env)
1191}
1192pub fn vec_ext_build_partition_reconstruct(
1194 env: &mut Environment,
1195) -> std::result::Result<(), String> {
1196 vec_ext_forall1_axiom("Vec.partition_reconstruct", env)
1197}
1198pub fn vec_ext_build_groupby_flatten(env: &mut Environment) -> std::result::Result<(), String> {
1200 vec_ext_forall1_axiom("Vec.groupBy_flatten", env)
1201}
1202pub fn vec_ext_build_prefix_sum_correct(env: &mut Environment) -> std::result::Result<(), String> {
1204 vec_ext_prop_axiom("Vec.prefix_sum_correct", env)
1205}
1206pub fn vec_ext_build_parallel_prefix_equiv(
1208 env: &mut Environment,
1209) -> std::result::Result<(), String> {
1210 vec_ext_forall2_axiom("Vec.parallel_prefix_sequential_equiv", env)
1211}
1212pub fn vec_ext_build_fenwick_correct(env: &mut Environment) -> std::result::Result<(), String> {
1214 vec_ext_prop_axiom("Vec.fenwick_prefix_sum_correct", env)
1215}
1216pub fn vec_ext_build_rle_roundtrip(env: &mut Environment) -> std::result::Result<(), String> {
1218 vec_ext_forall1_axiom("Vec.rle_decode_encode", env)
1219}
1220pub fn vec_ext_build_rle_length(env: &mut Environment) -> std::result::Result<(), String> {
1222 vec_ext_forall1_axiom("Vec.rle_length", env)
1223}
1224pub fn vec_ext_build_matrix_transpose_invol(
1226 env: &mut Environment,
1227) -> std::result::Result<(), String> {
1228 vec_ext_forall1_axiom("Vec.matrix_transpose_involutive", env)
1229}
1230pub fn vec_ext_build_matrix_row_count(env: &mut Environment) -> std::result::Result<(), String> {
1232 vec_ext_forall1_axiom("Vec.matrix_row_count", env)
1233}
1234pub fn vec_ext_build_matrix_col_count(env: &mut Environment) -> std::result::Result<(), String> {
1236 vec_ext_forall1_axiom("Vec.matrix_col_count", env)
1237}
1238pub fn register_vec_extended_axioms(env: &mut Environment) {
1258 let builders: &[fn(&mut Environment) -> std::result::Result<(), String>] = &[
1259 vec_ext_build_functor_map_id,
1260 vec_ext_build_functor_map_comp,
1261 vec_ext_build_monad_left_id,
1262 vec_ext_build_monad_right_id,
1263 vec_ext_build_monad_assoc,
1264 vec_ext_build_ap_identity,
1265 vec_ext_build_ap_homomorphism,
1266 vec_ext_build_ap_interchange,
1267 vec_ext_build_ap_composition,
1268 vec_ext_build_foldr_nil,
1269 vec_ext_build_foldr_cons,
1270 vec_ext_build_foldl_nil,
1271 vec_ext_build_foldl_cons,
1272 vec_ext_build_foldl_foldr_duality,
1273 vec_ext_build_scanl_nil,
1274 vec_ext_build_scanl_cons,
1275 vec_ext_build_scanr_nil,
1276 vec_ext_build_scanr_cons,
1277 vec_ext_build_scanl_last,
1278 vec_ext_build_sort_is_permutation,
1279 vec_ext_build_sort_is_sorted,
1280 vec_ext_build_stable_sort,
1281 vec_ext_build_sort_idempotent,
1282 vec_ext_build_map_fusion,
1283 vec_ext_build_filter_fusion,
1284 vec_ext_build_map_filter_fusion,
1285 vec_ext_build_fold_build_duality,
1286 vec_ext_build_fin_index_get,
1287 vec_ext_build_fin_index_set,
1288 vec_ext_build_fin_map_length,
1289 vec_ext_build_reverse_involutive,
1290 vec_ext_build_reverse_append,
1291 vec_ext_build_reverse_map,
1292 vec_ext_build_take_drop_reconstruct,
1293 vec_ext_build_take_length,
1294 vec_ext_build_drop_length,
1295 vec_ext_build_zip_length,
1296 vec_ext_build_unzip_zip,
1297 vec_ext_build_zip_map,
1298 vec_ext_build_chunks_flatten,
1299 vec_ext_build_chunks_all_size,
1300 vec_ext_build_chunks_count,
1301 vec_ext_build_append_nil_left,
1302 vec_ext_build_append_nil_right,
1303 vec_ext_build_append_assoc,
1304 vec_ext_build_length_append,
1305 vec_ext_build_rotate_left_right_inv,
1306 vec_ext_build_rotate_length,
1307 vec_ext_build_rotate_zero,
1308 vec_ext_build_dlist_append_assoc,
1309 vec_ext_build_dlist_to_list,
1310 vec_ext_build_concat_map_id,
1311 vec_ext_build_concat_map_assoc,
1312 vec_ext_build_flatten_singleton,
1313 vec_ext_build_flatten_map,
1314 vec_ext_build_span_reconstruct,
1315 vec_ext_build_partition_reconstruct,
1316 vec_ext_build_groupby_flatten,
1317 vec_ext_build_prefix_sum_correct,
1318 vec_ext_build_parallel_prefix_equiv,
1319 vec_ext_build_fenwick_correct,
1320 vec_ext_build_rle_roundtrip,
1321 vec_ext_build_rle_length,
1322 vec_ext_build_matrix_transpose_invol,
1323 vec_ext_build_matrix_row_count,
1324 vec_ext_build_matrix_col_count,
1325 ];
1326 for builder in builders {
1327 let _ = builder(env);
1328 }
1329}
1330#[cfg(test)]
1331mod vec_extended_axiom_tests {
1332 use super::*;
1333 fn make_env() -> Environment {
1334 let mut env = Environment::new();
1335 let type1 = Expr::Sort(Level::succ(Level::zero()));
1336 env.add(Declaration::Axiom {
1337 name: Name::str("Nat"),
1338 univ_params: vec![],
1339 ty: type1.clone(),
1340 })
1341 .expect("operation should succeed");
1342 env.add(Declaration::Axiom {
1343 name: Name::str("Nat.zero"),
1344 univ_params: vec![],
1345 ty: Expr::Const(Name::str("Nat"), vec![]),
1346 })
1347 .expect("operation should succeed");
1348 env.add(Declaration::Axiom {
1349 name: Name::str("Nat.succ"),
1350 univ_params: vec![],
1351 ty: Expr::Pi(
1352 BinderInfo::Default,
1353 Name::str("n"),
1354 Box::new(Expr::Const(Name::str("Nat"), vec![])),
1355 Box::new(Expr::Const(Name::str("Nat"), vec![])),
1356 ),
1357 })
1358 .expect("operation should succeed");
1359 env
1360 }
1361 #[test]
1362 fn test_register_vec_extended_axioms_runs() {
1363 let mut env = make_env();
1364 register_vec_extended_axioms(&mut env);
1365 assert!(env.get(&Name::str("Vec.functor_map_id")).is_some());
1366 assert!(env.get(&Name::str("Vec.monad_left_id")).is_some());
1367 assert!(env.get(&Name::str("Vec.append_assoc")).is_some());
1368 }
1369 #[test]
1370 fn test_functor_laws_present() {
1371 let mut env = make_env();
1372 register_vec_extended_axioms(&mut env);
1373 assert!(env.get(&Name::str("Vec.functor_map_id")).is_some());
1374 assert!(env.get(&Name::str("Vec.functor_map_comp")).is_some());
1375 }
1376 #[test]
1377 fn test_monad_laws_present() {
1378 let mut env = make_env();
1379 register_vec_extended_axioms(&mut env);
1380 assert!(env.get(&Name::str("Vec.monad_left_id")).is_some());
1381 assert!(env.get(&Name::str("Vec.monad_right_id")).is_some());
1382 assert!(env.get(&Name::str("Vec.monad_assoc")).is_some());
1383 }
1384 #[test]
1385 fn test_applicative_laws_present() {
1386 let mut env = make_env();
1387 register_vec_extended_axioms(&mut env);
1388 assert!(env.get(&Name::str("Vec.ap_identity")).is_some());
1389 assert!(env.get(&Name::str("Vec.ap_homomorphism")).is_some());
1390 assert!(env.get(&Name::str("Vec.ap_interchange")).is_some());
1391 assert!(env.get(&Name::str("Vec.ap_composition")).is_some());
1392 }
1393 #[test]
1394 fn test_fold_laws_present() {
1395 let mut env = make_env();
1396 register_vec_extended_axioms(&mut env);
1397 assert!(env.get(&Name::str("Vec.foldr_nil")).is_some());
1398 assert!(env.get(&Name::str("Vec.foldr_cons")).is_some());
1399 assert!(env.get(&Name::str("Vec.foldl_nil")).is_some());
1400 assert!(env.get(&Name::str("Vec.foldl_cons")).is_some());
1401 assert!(env.get(&Name::str("Vec.foldl_foldr_duality")).is_some());
1402 }
1403 #[test]
1404 fn test_scan_laws_present() {
1405 let mut env = make_env();
1406 register_vec_extended_axioms(&mut env);
1407 assert!(env.get(&Name::str("Vec.scanl_nil")).is_some());
1408 assert!(env.get(&Name::str("Vec.scanl_cons")).is_some());
1409 assert!(env.get(&Name::str("Vec.scanr_nil")).is_some());
1410 assert!(env.get(&Name::str("Vec.scanr_cons")).is_some());
1411 assert!(env.get(&Name::str("Vec.scanl_last")).is_some());
1412 }
1413 #[test]
1414 fn test_sort_laws_present() {
1415 let mut env = make_env();
1416 register_vec_extended_axioms(&mut env);
1417 assert!(env.get(&Name::str("Vec.sort_is_permutation")).is_some());
1418 assert!(env.get(&Name::str("Vec.sort_is_sorted")).is_some());
1419 assert!(env
1420 .get(&Name::str("Vec.stable_sort_preserves_order"))
1421 .is_some());
1422 assert!(env.get(&Name::str("Vec.sort_idempotent")).is_some());
1423 }
1424 #[test]
1425 fn test_fusion_laws_present() {
1426 let mut env = make_env();
1427 register_vec_extended_axioms(&mut env);
1428 assert!(env.get(&Name::str("Vec.map_fusion")).is_some());
1429 assert!(env.get(&Name::str("Vec.filter_fusion")).is_some());
1430 assert!(env.get(&Name::str("Vec.map_filter_fusion")).is_some());
1431 assert!(env.get(&Name::str("Vec.fold_build_duality")).is_some());
1432 }
1433 #[test]
1434 fn test_fin_indexed_laws_present() {
1435 let mut env = make_env();
1436 register_vec_extended_axioms(&mut env);
1437 assert!(env.get(&Name::str("Vec.fin_index_get")).is_some());
1438 assert!(env.get(&Name::str("Vec.fin_index_set")).is_some());
1439 assert!(env
1440 .get(&Name::str("Vec.fin_map_preserves_length"))
1441 .is_some());
1442 }
1443 #[test]
1444 fn test_reverse_laws_present() {
1445 let mut env = make_env();
1446 register_vec_extended_axioms(&mut env);
1447 assert!(env.get(&Name::str("Vec.reverse_involutive")).is_some());
1448 assert!(env.get(&Name::str("Vec.reverse_append")).is_some());
1449 assert!(env.get(&Name::str("Vec.reverse_map")).is_some());
1450 }
1451 #[test]
1452 fn test_take_drop_laws_present() {
1453 let mut env = make_env();
1454 register_vec_extended_axioms(&mut env);
1455 assert!(env.get(&Name::str("Vec.take_drop_reconstruct")).is_some());
1456 assert!(env.get(&Name::str("Vec.take_length")).is_some());
1457 assert!(env.get(&Name::str("Vec.drop_length")).is_some());
1458 }
1459 #[test]
1460 fn test_zip_laws_present() {
1461 let mut env = make_env();
1462 register_vec_extended_axioms(&mut env);
1463 assert!(env.get(&Name::str("Vec.zip_length")).is_some());
1464 assert!(env.get(&Name::str("Vec.unzip_zip")).is_some());
1465 assert!(env.get(&Name::str("Vec.zip_map")).is_some());
1466 }
1467 #[test]
1468 fn test_chunking_laws_present() {
1469 let mut env = make_env();
1470 register_vec_extended_axioms(&mut env);
1471 assert!(env.get(&Name::str("Vec.chunks_flatten")).is_some());
1472 assert!(env.get(&Name::str("Vec.chunks_all_size")).is_some());
1473 assert!(env.get(&Name::str("Vec.chunks_count")).is_some());
1474 }
1475 #[test]
1476 fn test_free_monoid_laws_present() {
1477 let mut env = make_env();
1478 register_vec_extended_axioms(&mut env);
1479 assert!(env.get(&Name::str("Vec.append_nil_left")).is_some());
1480 assert!(env.get(&Name::str("Vec.append_nil_right")).is_some());
1481 assert!(env.get(&Name::str("Vec.append_assoc")).is_some());
1482 assert!(env.get(&Name::str("Vec.length_append")).is_some());
1483 }
1484 #[test]
1485 fn test_rotation_laws_present() {
1486 let mut env = make_env();
1487 register_vec_extended_axioms(&mut env);
1488 assert!(env
1489 .get(&Name::str("Vec.rotate_left_right_inverse"))
1490 .is_some());
1491 assert!(env.get(&Name::str("Vec.rotate_length")).is_some());
1492 assert!(env.get(&Name::str("Vec.rotate_zero")).is_some());
1493 }
1494 #[test]
1495 fn test_dlist_laws_present() {
1496 let mut env = make_env();
1497 register_vec_extended_axioms(&mut env);
1498 assert!(env.get(&Name::str("Vec.dlist_append_assoc")).is_some());
1499 assert!(env.get(&Name::str("Vec.dlist_to_list_preserves")).is_some());
1500 }
1501 #[test]
1502 fn test_concat_map_laws_present() {
1503 let mut env = make_env();
1504 register_vec_extended_axioms(&mut env);
1505 assert!(env.get(&Name::str("Vec.concat_map_id")).is_some());
1506 assert!(env.get(&Name::str("Vec.concat_map_assoc")).is_some());
1507 assert!(env.get(&Name::str("Vec.flatten_singleton")).is_some());
1508 assert!(env.get(&Name::str("Vec.flatten_map")).is_some());
1509 }
1510 #[test]
1511 fn test_span_partition_laws_present() {
1512 let mut env = make_env();
1513 register_vec_extended_axioms(&mut env);
1514 assert!(env.get(&Name::str("Vec.span_reconstruct")).is_some());
1515 assert!(env.get(&Name::str("Vec.partition_reconstruct")).is_some());
1516 assert!(env.get(&Name::str("Vec.groupBy_flatten")).is_some());
1517 }
1518 #[test]
1519 fn test_parallel_prefix_laws_present() {
1520 let mut env = make_env();
1521 register_vec_extended_axioms(&mut env);
1522 assert!(env.get(&Name::str("Vec.prefix_sum_correct")).is_some());
1523 assert!(env
1524 .get(&Name::str("Vec.parallel_prefix_sequential_equiv"))
1525 .is_some());
1526 assert!(env
1527 .get(&Name::str("Vec.fenwick_prefix_sum_correct"))
1528 .is_some());
1529 }
1530 #[test]
1531 fn test_rle_laws_present() {
1532 let mut env = make_env();
1533 register_vec_extended_axioms(&mut env);
1534 assert!(env.get(&Name::str("Vec.rle_decode_encode")).is_some());
1535 assert!(env.get(&Name::str("Vec.rle_length")).is_some());
1536 }
1537 #[test]
1538 fn test_matrix_laws_present() {
1539 let mut env = make_env();
1540 register_vec_extended_axioms(&mut env);
1541 assert!(env
1542 .get(&Name::str("Vec.matrix_transpose_involutive"))
1543 .is_some());
1544 assert!(env.get(&Name::str("Vec.matrix_row_count")).is_some());
1545 assert!(env.get(&Name::str("Vec.matrix_col_count")).is_some());
1546 }
1547 #[test]
1548 fn test_circular_buffer_basic() {
1549 let buf: CircularBuffer<i32> = CircularBuffer::new(8);
1550 assert_eq!(buf.capacity(), 8);
1551 assert!(buf.is_empty());
1552 assert!(!buf.is_full());
1553 }
1554 #[test]
1555 fn test_dlist_singleton_to_vec() {
1556 let d = DList::singleton(42i32);
1557 assert_eq!(d.to_vec(), vec![42]);
1558 }
1559 #[test]
1560 fn test_prefix_scan_inclusive() {
1561 let ps = PrefixScan::inclusive(vec![1, 3, 6, 10]);
1562 assert_eq!(ps.values(), &[1, 3, 6, 10]);
1563 assert!(ps.inclusive);
1564 assert_eq!(ps.len(), 4);
1565 }
1566 #[test]
1567 fn test_fenwick_tree_basic() {
1568 let mut ft = FenwickTree::new(5);
1569 ft.update(1, 3);
1570 ft.update(2, 2);
1571 ft.update(3, 7);
1572 assert_eq!(ft.query(1), 3);
1573 assert_eq!(ft.query(2), 5);
1574 assert_eq!(ft.query(3), 12);
1575 }
1576 #[test]
1577 fn test_sparse_vec_get_set() {
1578 let mut sv: SparseVec<i32> = SparseVec::new(10, 0);
1579 assert_eq!(*sv.get(5), 0);
1580 sv.set(5, 42);
1581 assert_eq!(*sv.get(5), 42);
1582 assert_eq!(*sv.get(3), 0);
1583 assert_eq!(sv.nnz(), 1);
1584 }
1585 #[test]
1586 fn test_all_35_plus_vec_axioms_registered() {
1587 let mut env = make_env();
1588 register_vec_extended_axioms(&mut env);
1589 let axiom_names = [
1590 "Vec.functor_map_id",
1591 "Vec.functor_map_comp",
1592 "Vec.monad_left_id",
1593 "Vec.monad_right_id",
1594 "Vec.monad_assoc",
1595 "Vec.ap_identity",
1596 "Vec.ap_homomorphism",
1597 "Vec.ap_interchange",
1598 "Vec.ap_composition",
1599 "Vec.foldr_nil",
1600 "Vec.foldr_cons",
1601 "Vec.foldl_nil",
1602 "Vec.foldl_cons",
1603 "Vec.foldl_foldr_duality",
1604 "Vec.scanl_nil",
1605 "Vec.scanl_cons",
1606 "Vec.scanr_nil",
1607 "Vec.scanr_cons",
1608 "Vec.scanl_last",
1609 "Vec.sort_is_permutation",
1610 "Vec.sort_is_sorted",
1611 "Vec.stable_sort_preserves_order",
1612 "Vec.sort_idempotent",
1613 "Vec.map_fusion",
1614 "Vec.filter_fusion",
1615 "Vec.map_filter_fusion",
1616 "Vec.fold_build_duality",
1617 "Vec.fin_index_get",
1618 "Vec.fin_index_set",
1619 "Vec.fin_map_preserves_length",
1620 "Vec.reverse_involutive",
1621 "Vec.reverse_append",
1622 "Vec.reverse_map",
1623 "Vec.take_drop_reconstruct",
1624 "Vec.take_length",
1625 ];
1626 let mut found = 0usize;
1627 for name in &axiom_names {
1628 if env.get(&Name::str(*name)).is_some() {
1629 found += 1;
1630 }
1631 }
1632 assert!(found >= 35, "Expected at least 35 axioms, found {}", found);
1633 }
1634}