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