1use crate::Name;
6
7use super::types::{
8 ConfigNode, ConstraintSet, DecisionNode, Either2, Fixture, FlatSubstitution, FocusStack,
9 LabelSet, Level, LevelConstraint, LevelMVarId, LevelView, MinHeap, NonEmptyVec, PathBuf,
10 PrefixCounter, RewriteRule, RewriteRuleSet, SimpleDag, SlidingSum, SmallMap, SparseVec,
11 StackCalc, StatSummary, Stopwatch, StringPool, TokenBucket, TransformStat, TransitiveClosure,
12 VersionedRecord, WindowIterator, WriteOnce,
13};
14
15pub fn to_offset(l: &Level) -> (&Level, u32) {
19 match l.view() {
20 LevelView::Succ(inner) => {
21 let (base, k) = to_offset(inner);
22 (base, k + 1)
23 }
24 _ => (l, 0),
25 }
26}
27pub(super) fn from_offset(base: Level, offset: u32) -> Level {
29 let mut result = base;
30 for _ in 0..offset {
31 result = Level::succ(result);
32 }
33 result
34}
35pub(super) fn push_max_args(l: &Level, args: &mut Vec<Level>) {
37 match l.view() {
38 LevelView::Max(l1, l2) => {
39 push_max_args(l1, args);
40 push_max_args(l2, args);
41 }
42 _ => args.push(l.clone()),
43 }
44}
45pub(super) fn is_norm_lt(l1: &Level, l2: &Level) -> bool {
49 let (b1, k1) = to_offset(l1);
50 let (b2, k2) = to_offset(l2);
51 fn kind_ord(l: &Level) -> u8 {
52 match l.view() {
53 LevelView::Zero => 0,
54 LevelView::Param(_) => 1,
55 LevelView::MVar(_) => 2,
56 LevelView::Max(_, _) => 3,
57 LevelView::IMax(_, _) => 4,
58 LevelView::Succ(_) => 5,
59 }
60 }
61 let k1_ord = kind_ord(b1);
62 let k2_ord = kind_ord(b2);
63 if k1_ord != k2_ord {
64 return k1_ord < k2_ord;
65 }
66 match (b1.view(), b2.view()) {
67 (LevelView::Param(n1), LevelView::Param(n2)) => {
68 match super::order::name_cmp(n1, n2) {
72 std::cmp::Ordering::Less => return true,
73 std::cmp::Ordering::Greater => return false,
74 std::cmp::Ordering::Equal => {}
75 }
76 }
77 (LevelView::MVar(m1), LevelView::MVar(m2)) if m1.0 != m2.0 => {
78 return m1.0 < m2.0;
79 }
80 (LevelView::MVar(_), LevelView::MVar(_)) => {}
81 (LevelView::Max(a1, a2), LevelView::Max(b1_inner, b2_inner))
82 | (LevelView::IMax(a1, a2), LevelView::IMax(b1_inner, b2_inner)) => {
83 if a1 != b1_inner {
84 return is_norm_lt(a1, b1_inner);
85 }
86 if a2 != b2_inner {
87 return is_norm_lt(a2, b2_inner);
88 }
89 }
90 _ => {}
91 }
92 k1 < k2
93}
94pub fn normalize(l: &Level) -> Level {
103 let (base, k) = to_offset(l);
104 match base.view() {
105 LevelView::Zero | LevelView::Param(_) | LevelView::MVar(_) => l.clone(),
106 LevelView::Succ(_) => l.clone(),
107 LevelView::IMax(l1, l2) => {
108 let l1_norm = normalize(l1);
109 let l2_norm = normalize(l2);
110 if l2_norm.is_zero() {
111 return from_offset(Level::zero(), k);
113 }
114 if l2_norm.is_not_zero() {
115 return normalize(&Level::max(
120 from_offset(l1_norm, k),
121 from_offset(l2_norm, k),
122 ));
123 }
124 if l1_norm.is_zero() {
125 let with_offset = from_offset(l2_norm, k);
130 return if k == 0 {
131 with_offset
132 } else {
133 normalize(&with_offset)
134 };
135 }
136 if l1_norm == l2_norm {
137 return from_offset(l1_norm, k);
143 }
144 from_offset(Level::imax(l1_norm, l2_norm), k)
145 }
146 LevelView::Max(_, _) => {
147 let mut args = Vec::new();
148 push_max_args(base, &mut args);
149 let mut normed: Vec<Level> = Vec::new();
153 for a in args {
154 let normalized_a = normalize(&from_offset(a, k));
155 push_max_args(&normalized_a, &mut normed);
157 }
158 normed.sort_by(|a, b| {
159 if is_norm_lt(a, b) {
160 std::cmp::Ordering::Less
161 } else if a == b {
162 std::cmp::Ordering::Equal
163 } else {
164 std::cmp::Ordering::Greater
165 }
166 });
167 let mut merged: Vec<Level> = Vec::new();
168 for arg in normed {
169 let dominated = if let Some(last) = merged.last() {
170 let (base_last, k_last) = to_offset(last);
171 let (base_arg, k_arg) = to_offset(&arg);
172 if base_last == base_arg {
173 if k_arg > k_last {
174 merged.pop();
175 false
176 } else {
177 true
178 }
179 } else {
180 false
181 }
182 } else {
183 false
184 };
185 if !dominated {
186 merged.push(arg);
187 }
188 }
189 if merged.len() > 1 {
190 let max_nonnumeral_offset = merged
200 .iter()
201 .filter_map(|a| {
202 let (b, k) = to_offset(a);
203 if matches!(b.view(), LevelView::Zero) {
204 None
205 } else {
206 Some(k)
207 }
208 })
209 .max();
210 if let Some(bound) = max_nonnumeral_offset {
211 merged.retain(|a| {
212 let (b, k) = to_offset(a);
213 !(matches!(b.view(), LevelView::Zero) && k <= bound)
216 });
217 }
218 }
219 match merged.pop() {
220 None => Level::zero(),
221 Some(last) => {
222 let mut result = last;
223 while let Some(arg) = merged.pop() {
224 result = Level::max(arg, result);
225 }
226 result
227 }
228 }
229 }
230 }
231}
232pub fn is_equivalent(l1: &Level, l2: &Level) -> bool {
241 l1 == l2 || (is_leq(l1, l2) && is_leq(l2, l1))
242}
243pub fn is_geq(l1: &Level, l2: &Level) -> bool {
248 is_leq(l2, l1)
249}
250pub fn is_leq(l1: &Level, l2: &Level) -> bool {
257 super::order::is_leq_core(l1, l2, 0)
258}
259pub fn instantiate_level(level: &Level, param_names: &[Name], levels: &[Level]) -> Level {
264 if param_names.is_empty() {
265 return level.clone();
266 }
267 match level.view() {
268 LevelView::Param(name) => {
269 for (i, pn) in param_names.iter().enumerate() {
270 if pn == name {
271 if let Some(l) = levels.get(i) {
272 return l.clone();
273 }
274 }
275 }
276 level.clone()
277 }
278 LevelView::Succ(l) => Level::succ(instantiate_level(l, param_names, levels)),
279 LevelView::Max(l1, l2) => Level::max(
280 instantiate_level(l1, param_names, levels),
281 instantiate_level(l2, param_names, levels),
282 ),
283 LevelView::IMax(l1, l2) => Level::imax(
284 instantiate_level(l1, param_names, levels),
285 instantiate_level(l2, param_names, levels),
286 ),
287 LevelView::Zero | LevelView::MVar(_) => level.clone(),
288 }
289}
290pub fn collect_level_params(l: &Level, params: &mut Vec<Name>) {
292 match l.view() {
293 LevelView::Param(name) => {
294 if !params.contains(name) {
295 params.push(name.clone());
296 }
297 }
298 LevelView::Succ(l) => collect_level_params(l, params),
299 LevelView::Max(l1, l2) | LevelView::IMax(l1, l2) => {
300 collect_level_params(l1, params);
301 collect_level_params(l2, params);
302 }
303 LevelView::Zero | LevelView::MVar(_) => {}
304 }
305}
306pub fn collect_level_mvars(l: &Level, mvars: &mut Vec<LevelMVarId>) {
308 match l.view() {
309 LevelView::MVar(id) => {
310 if !mvars.contains(&id) {
311 mvars.push(id);
312 }
313 }
314 LevelView::Succ(l) => collect_level_mvars(l, mvars),
315 LevelView::Max(l1, l2) | LevelView::IMax(l1, l2) => {
316 collect_level_mvars(l1, mvars);
317 collect_level_mvars(l2, mvars);
318 }
319 LevelView::Zero | LevelView::Param(_) => {}
320 }
321}
322pub fn instantiate_level_mvars(
324 level: &Level,
325 subst: &dyn Fn(LevelMVarId) -> Option<Level>,
326) -> Level {
327 match level.view() {
328 LevelView::MVar(id) => {
329 if let Some(l) = subst(id) {
330 instantiate_level_mvars(&l, subst)
331 } else {
332 level.clone()
333 }
334 }
335 LevelView::Succ(l) => Level::succ(instantiate_level_mvars(l, subst)),
336 LevelView::Max(l1, l2) => Level::max(
337 instantiate_level_mvars(l1, subst),
338 instantiate_level_mvars(l2, subst),
339 ),
340 LevelView::IMax(l1, l2) => Level::imax(
341 instantiate_level_mvars(l1, subst),
342 instantiate_level_mvars(l2, subst),
343 ),
344 LevelView::Zero | LevelView::Param(_) => level.clone(),
345 }
346}
347#[cfg(test)]
348mod tests {
349 use super::*;
350 #[test]
351 fn test_level_construction() {
352 let l0 = Level::zero();
353 let l1 = Level::succ(Level::zero());
354 let l_param = Level::param(Name::str("u"));
355 let l_max = Level::max(l1.clone(), l_param.clone());
356 assert!(l0.is_zero());
357 assert!(l_param.is_param());
358 assert!(!l_max.is_zero());
359 }
360 #[test]
361 fn test_level_display() {
362 let l0 = Level::zero();
363 let l1 = Level::succ(Level::zero());
364 let l_max = Level::max(l0.clone(), l1.clone());
365 let l_imax = Level::imax(l0, l1);
366 assert_eq!(l_max.to_string(), "max(0, 1)");
367 assert_eq!(l_imax.to_string(), "imax(0, 1)");
368 }
369 #[test]
370 fn test_level_mvar() {
371 let mv = Level::mvar(LevelMVarId(42));
372 assert!(mv.is_mvar());
373 assert!(mv.has_mvar());
374 assert!(!mv.has_param());
375 assert_eq!(mv.to_string(), "?u_42");
376 }
377 #[test]
378 fn test_is_not_zero() {
379 assert!(!Level::zero().is_not_zero());
380 assert!(Level::succ(Level::zero()).is_not_zero());
381 assert!(Level::succ(Level::param(Name::str("u"))).is_not_zero());
382 assert!(!Level::param(Name::str("u")).is_not_zero());
383 let m = Level::max(Level::zero(), Level::succ(Level::param(Name::str("u"))));
384 assert!(m.is_not_zero());
385 }
386 #[test]
387 fn test_to_offset() {
388 let l = Level::succ(Level::succ(Level::param(Name::str("u"))));
389 let (base, k) = to_offset(&l);
390 assert_eq!(*base, Level::param(Name::str("u")));
391 assert_eq!(k, 2);
392 let zero = Level::zero();
393 let (base0, k0) = to_offset(&zero);
394 assert_eq!(*base0, Level::zero());
395 assert_eq!(k0, 0);
396 }
397 #[test]
398 fn test_from_nat_to_nat() {
399 for n in 0..5 {
400 let l = Level::from_nat(n);
401 assert_eq!(l.to_nat(), Some(n));
402 }
403 assert_eq!(Level::param(Name::str("u")).to_nat(), None);
404 }
405 #[test]
406 fn test_normalize_zero() {
407 assert_eq!(normalize(&Level::zero()), Level::zero());
408 }
409 #[test]
410 fn test_normalize_succ() {
411 let l = Level::succ(Level::succ(Level::zero()));
412 assert_eq!(normalize(&l), l);
413 }
414 #[test]
415 fn test_normalize_max_same() {
416 let u = Level::param(Name::str("u"));
417 let m = Level::max(u.clone(), u.clone());
418 assert_eq!(normalize(&m), u);
419 }
420 #[test]
421 fn test_normalize_max_zero() {
422 let u = Level::param(Name::str("u"));
423 let m = Level::max(u.clone(), Level::zero());
424 let n = normalize(&m);
425 assert!(is_equivalent(&n, &u) || is_equivalent(&n, &m));
426 }
427 #[test]
428 fn test_normalize_max_ordering() {
429 let u = Level::param(Name::str("u"));
430 let v = Level::param(Name::str("v"));
431 let m1 = Level::max(u.clone(), v.clone());
432 let m2 = Level::max(v, u);
433 assert_eq!(normalize(&m1), normalize(&m2));
434 }
435 #[test]
436 fn test_normalize_imax_zero() {
437 let u = Level::param(Name::str("u"));
438 let im = Level::imax(u, Level::zero());
439 assert_eq!(normalize(&im), Level::zero());
440 }
441 #[test]
442 fn test_normalize_imax_succ() {
443 let u = Level::param(Name::str("u"));
444 let v = Level::param(Name::str("v"));
445 let im = Level::imax(u.clone(), Level::succ(v.clone()));
446 let expected = normalize(&Level::max(u, Level::succ(v)));
447 assert_eq!(normalize(&im), expected);
448 }
449 #[test]
450 fn test_is_equivalent() {
451 let u = Level::param(Name::str("u"));
452 let v = Level::param(Name::str("v"));
453 assert!(is_equivalent(
454 &Level::max(u.clone(), v.clone()),
455 &Level::max(v, u),
456 ));
457 assert!(!is_equivalent(
458 &Level::param(Name::str("u")),
459 &Level::param(Name::str("v")),
460 ));
461 assert!(is_equivalent(
462 &Level::succ(Level::zero()),
463 &Level::succ(Level::zero()),
464 ));
465 }
466 #[test]
467 fn test_is_geq() {
468 let u = Level::param(Name::str("u"));
469 let l0 = Level::zero();
470 let l1 = Level::succ(Level::zero());
471 let l2 = Level::succ(Level::succ(Level::zero()));
472 assert!(is_geq(&u, &l0));
473 assert!(is_geq(&l2, &l1));
474 assert!(!is_geq(&l1, &l2));
475 assert!(is_geq(&Level::succ(u.clone()), &u));
476 let v = Level::param(Name::str("v"));
477 assert!(is_geq(&Level::max(u.clone(), v.clone()), &u));
478 assert!(is_geq(&Level::max(u.clone(), v.clone()), &v));
479 }
480 #[test]
481 fn test_instantiate_level() {
482 let l = Level::max(
483 Level::param(Name::str("u")),
484 Level::succ(Level::param(Name::str("v"))),
485 );
486 let result = instantiate_level(
487 &l,
488 &[Name::str("u"), Name::str("v")],
489 &[Level::zero(), Level::succ(Level::zero())],
490 );
491 let expected = Level::max(Level::zero(), Level::succ(Level::succ(Level::zero())));
492 assert_eq!(result, expected);
493 }
494 #[test]
495 fn test_collect_level_params() {
496 let l = Level::max(
497 Level::param(Name::str("u")),
498 Level::succ(Level::param(Name::str("v"))),
499 );
500 let mut params = Vec::new();
501 collect_level_params(&l, &mut params);
502 assert_eq!(params.len(), 2);
503 assert!(params.contains(&Name::str("u")));
504 assert!(params.contains(&Name::str("v")));
505 }
506 #[test]
507 fn test_instantiate_level_mvars() {
508 let l = Level::max(
509 Level::mvar(LevelMVarId(0)),
510 Level::succ(Level::mvar(LevelMVarId(1))),
511 );
512 let result = instantiate_level_mvars(&l, &|id| {
513 if id.0 == 0 {
514 Some(Level::zero())
515 } else if id.0 == 1 {
516 Some(Level::param(Name::str("u")))
517 } else {
518 None
519 }
520 });
521 let expected = Level::max(Level::zero(), Level::succ(Level::param(Name::str("u"))));
522 assert_eq!(result, expected);
523 }
524 #[test]
525 fn test_depth() {
526 assert_eq!(Level::zero().depth(), 0);
527 assert_eq!(Level::succ(Level::zero()).depth(), 1);
528 assert_eq!(
529 Level::max(Level::param(Name::str("u")), Level::succ(Level::zero())).depth(),
530 2
531 );
532 }
533}
534#[allow(dead_code)]
540pub fn level_min(l1: &Level, l2: &Level) -> Level {
541 if l1.is_zero() || l2.is_zero() {
542 return Level::zero();
543 }
544 if is_leq(l1, l2) {
545 return l1.clone();
546 }
547 if is_leq(l2, l1) {
548 return l2.clone();
549 }
550 Level::zero()
551}
552#[allow(dead_code)]
554pub fn level_max3(l1: Level, l2: Level, l3: Level) -> Level {
555 normalize(&Level::max(Level::max(l1, l2), l3))
556}
557#[allow(dead_code)]
561pub fn level_add(l: Level, n: u32) -> Level {
562 let mut result = l;
563 for _ in 0..n {
564 result = Level::succ(result);
565 }
566 result
567}
568#[allow(dead_code)]
570pub fn type_level(n: u32) -> Level {
571 Level::from_nat(n + 1)
572}
573#[allow(dead_code)]
576pub fn is_definitely_succ(l: &Level) -> bool {
577 matches!(l.view(), LevelView::Succ(_))
578}
579#[allow(dead_code)]
581pub fn dedup_levels(levels: Vec<Level>) -> Vec<Level> {
582 let mut seen: Vec<Level> = Vec::new();
583 for l in levels {
584 if !seen.contains(&l) {
585 seen.push(l);
586 }
587 }
588 seen
589}
590#[cfg(test)]
591mod extra_level_tests {
592 use super::*;
593 #[test]
594 fn test_level_min_zeros() {
595 assert_eq!(
596 level_min(&Level::zero(), &Level::succ(Level::zero())),
597 Level::zero()
598 );
599 }
600 #[test]
601 fn test_level_min_equal() {
602 let l1 = Level::succ(Level::zero());
603 let l2 = Level::succ(Level::zero());
604 assert_eq!(level_min(&l1, &l2), l1);
605 }
606 #[test]
607 fn test_level_max3() {
608 let l0 = Level::zero();
609 let l1 = Level::succ(Level::zero());
610 let l2 = Level::succ(Level::succ(Level::zero()));
611 let result = level_max3(l0, l1, l2.clone());
612 assert!(is_equivalent(&result, &l2));
613 }
614 #[test]
615 fn test_level_add_zero_times() {
616 let l = Level::param(Name::str("u"));
617 assert_eq!(level_add(l.clone(), 0), l);
618 }
619 #[test]
620 fn test_level_add_two_times() {
621 let l = Level::zero();
622 let result = level_add(l, 2);
623 assert_eq!(result.to_nat(), Some(2));
624 }
625 #[test]
626 fn test_type_level_zero() {
627 assert_eq!(type_level(0), Level::succ(Level::zero()));
628 }
629 #[test]
630 fn test_type_level_two() {
631 assert_eq!(type_level(2).to_nat(), Some(3));
632 }
633 #[test]
634 fn test_is_definitely_succ_true() {
635 assert!(is_definitely_succ(&Level::succ(Level::zero())));
636 }
637 #[test]
638 fn test_is_definitely_succ_false() {
639 assert!(!is_definitely_succ(&Level::zero()));
640 assert!(!is_definitely_succ(&Level::param(Name::str("u"))));
641 }
642 #[test]
643 fn test_dedup_levels() {
644 let l0 = Level::zero();
645 let l1 = Level::succ(Level::zero());
646 let levels = vec![l0.clone(), l0.clone(), l1.clone(), l1.clone()];
647 let deduped = dedup_levels(levels);
648 assert_eq!(deduped.len(), 2);
649 }
650 #[test]
651 fn test_collect_level_mvars_multiple() {
652 let l = Level::max(Level::mvar(LevelMVarId(0)), Level::mvar(LevelMVarId(1)));
653 let mut mvars = Vec::new();
654 collect_level_mvars(&l, &mut mvars);
655 assert_eq!(mvars.len(), 2);
656 }
657 #[test]
658 fn test_level_is_leq() {
659 let l0 = Level::zero();
660 let l1 = Level::succ(Level::zero());
661 assert!(is_leq(&l0, &l1));
662 assert!(!is_leq(&l1, &l0));
663 assert!(is_leq(&l0, &l0));
664 }
665}
666#[allow(dead_code)]
670pub fn flatten_max(l: &Level) -> Vec<(Level, u32)> {
671 let norm = normalize(l);
672 let mut result = Vec::new();
673 push_flat(&norm, &mut result);
674 result
675}
676pub(super) fn push_flat(l: &Level, acc: &mut Vec<(Level, u32)>) {
677 match l.view() {
678 LevelView::Max(l1, l2) => {
679 push_flat(l1, acc);
680 push_flat(l2, acc);
681 }
682 _ => {
683 let (base, k) = to_offset(l);
684 acc.push((base.clone(), k));
685 }
686 }
687}
688#[allow(dead_code)]
690pub fn is_numeral(l: &Level) -> bool {
691 l.to_nat().is_some()
692}
693#[allow(dead_code)]
695pub fn is_ground(l: &Level) -> bool {
696 !l.has_param() && !l.has_mvar()
697}
698#[allow(dead_code)]
702pub fn eval_ground_level(l: &Level) -> Option<u32> {
703 if !is_ground(l) {
704 return None;
705 }
706 let norm = normalize(l);
707 norm.to_nat()
708}
709#[allow(dead_code)]
713pub fn max_of_slice(levels: &[Level]) -> Level {
714 let mut iter = levels.iter();
715 match iter.next() {
716 None => Level::zero(),
717 Some(first) => iter.fold(first.clone(), |acc, l| Level::max(acc, l.clone())),
718 }
719}
720#[allow(dead_code)]
724pub fn imax_fold(levels: &[Level]) -> Level {
725 let mut iter = levels.iter();
726 match iter.next() {
727 None => Level::zero(),
728 Some(first) => iter.fold(first.clone(), |acc, l| Level::imax(acc, l.clone())),
729 }
730}
731#[allow(dead_code)]
736pub fn prop_level() -> Level {
737 Level::zero()
738}
739#[allow(dead_code)]
741pub fn type0_level() -> Level {
742 Level::succ(Level::zero())
743}
744#[allow(dead_code)]
746pub fn type1_level() -> Level {
747 Level::succ(Level::succ(Level::zero()))
748}
749#[cfg(test)]
750mod extra2_level_tests {
751 use super::*;
752 #[test]
753 fn test_level_constraint_leq_satisfied() {
754 let l0 = Level::zero();
755 let l1 = Level::succ(Level::zero());
756 let c = LevelConstraint::Leq(l0, l1);
757 assert!(c.is_satisfied());
758 }
759 #[test]
760 fn test_level_constraint_leq_violated() {
761 let l1 = Level::succ(Level::zero());
762 let l0 = Level::zero();
763 let c = LevelConstraint::Leq(l1, l0);
764 assert!(!c.is_satisfied());
765 }
766 #[test]
767 fn test_level_constraint_eq_satisfied() {
768 let l = Level::succ(Level::zero());
769 let c = LevelConstraint::Eq(l.clone(), l);
770 assert!(c.is_satisfied());
771 }
772 #[test]
773 fn test_constraint_set_all_satisfied() {
774 let mut cs = ConstraintSet::new();
775 cs.add_leq(Level::zero(), Level::succ(Level::zero()));
776 cs.add_eq(Level::zero(), Level::zero());
777 assert!(cs.all_satisfied());
778 }
779 #[test]
780 fn test_constraint_set_unsatisfied() {
781 let mut cs = ConstraintSet::new();
782 cs.add_leq(Level::succ(Level::zero()), Level::zero());
783 assert!(!cs.all_satisfied());
784 assert_eq!(cs.unsatisfied().len(), 1);
785 }
786 #[test]
787 fn test_flatten_max_single() {
788 let l = Level::param(Name::str("u"));
789 let flat = flatten_max(&l);
790 assert_eq!(flat.len(), 1);
791 }
792 #[test]
793 fn test_flatten_max_binary() {
794 let u = Level::param(Name::str("u"));
795 let v = Level::param(Name::str("v"));
796 let m = Level::max(u, v);
797 let flat = flatten_max(&m);
798 assert_eq!(flat.len(), 2);
799 }
800 #[test]
801 fn test_is_numeral_true() {
802 assert!(is_numeral(&Level::zero()));
803 assert!(is_numeral(&Level::succ(Level::zero())));
804 assert!(is_numeral(&Level::from_nat(5)));
805 }
806 #[test]
807 fn test_is_numeral_false() {
808 assert!(!is_numeral(&Level::param(Name::str("u"))));
809 }
810 #[test]
811 fn test_is_ground_zero() {
812 assert!(is_ground(&Level::zero()));
813 }
814 #[test]
815 fn test_is_ground_param() {
816 assert!(!is_ground(&Level::param(Name::str("u"))));
817 }
818 #[test]
819 fn test_eval_ground_level_numeral() {
820 let l = Level::from_nat(3);
821 assert_eq!(eval_ground_level(&l), Some(3));
822 }
823 #[test]
824 fn test_eval_ground_level_param() {
825 let l = Level::param(Name::str("u"));
826 assert_eq!(eval_ground_level(&l), None);
827 }
828 #[test]
829 fn test_max_of_slice_empty() {
830 let result = max_of_slice(&[]);
831 assert_eq!(result, Level::zero());
832 }
833 #[test]
834 fn test_max_of_slice_single() {
835 let l = Level::succ(Level::zero());
836 let result = max_of_slice(std::slice::from_ref(&l));
837 assert_eq!(result, l);
838 }
839 #[test]
840 fn test_max_of_slice_multiple() {
841 let l0 = Level::zero();
842 let l1 = Level::succ(Level::zero());
843 let l2 = Level::succ(Level::succ(Level::zero()));
844 let result = max_of_slice(&[l0, l1, l2.clone()]);
845 assert!(is_equivalent(&normalize(&result), &l2));
846 }
847 #[test]
848 fn test_imax_fold_empty() {
849 assert_eq!(imax_fold(&[]), Level::zero());
850 }
851 #[test]
852 fn test_type0_level() {
853 assert_eq!(type0_level().to_nat(), Some(1));
854 }
855 #[test]
856 fn test_type1_level() {
857 assert_eq!(type1_level().to_nat(), Some(2));
858 }
859 #[test]
860 fn test_constraint_set_len() {
861 let mut cs = ConstraintSet::new();
862 cs.add_leq(Level::zero(), Level::succ(Level::zero()));
863 assert_eq!(cs.len(), 1);
864 assert!(!cs.is_empty());
865 }
866}
867#[cfg(test)]
868mod tests_padding_infra {
869 use super::*;
870 #[test]
871 fn test_stat_summary() {
872 let mut ss = StatSummary::new();
873 ss.record(10.0);
874 ss.record(20.0);
875 ss.record(30.0);
876 assert_eq!(ss.count(), 3);
877 assert!((ss.mean().expect("mean should succeed") - 20.0).abs() < 1e-9);
878 assert_eq!(ss.min().expect("min should succeed") as i64, 10);
879 assert_eq!(ss.max().expect("max should succeed") as i64, 30);
880 }
881 #[test]
882 fn test_transform_stat() {
883 let mut ts = TransformStat::new();
884 ts.record_before(100.0);
885 ts.record_after(80.0);
886 let ratio = ts.mean_ratio().expect("ratio should be present");
887 assert!((ratio - 0.8).abs() < 1e-9);
888 }
889 #[test]
890 fn test_small_map() {
891 let mut m: SmallMap<u32, &str> = SmallMap::new();
892 m.insert(3, "three");
893 m.insert(1, "one");
894 m.insert(2, "two");
895 assert_eq!(m.get(&2), Some(&"two"));
896 assert_eq!(m.len(), 3);
897 let keys = m.keys();
898 assert_eq!(*keys[0], 1);
899 assert_eq!(*keys[2], 3);
900 }
901 #[test]
902 fn test_label_set() {
903 let mut ls = LabelSet::new();
904 ls.add("foo");
905 ls.add("bar");
906 ls.add("foo");
907 assert_eq!(ls.count(), 2);
908 assert!(ls.has("bar"));
909 assert!(!ls.has("baz"));
910 }
911 #[test]
912 fn test_config_node() {
913 let mut root = ConfigNode::section("root");
914 let child = ConfigNode::leaf("key", "value");
915 root.add_child(child);
916 assert_eq!(root.num_children(), 1);
917 }
918 #[test]
919 fn test_versioned_record() {
920 let mut vr = VersionedRecord::new(0u32);
921 vr.update(1);
922 vr.update(2);
923 assert_eq!(*vr.current(), 2);
924 assert_eq!(vr.version(), 2);
925 assert!(vr.has_history());
926 assert_eq!(*vr.at_version(0).expect("value should be present"), 0);
927 }
928 #[test]
929 fn test_simple_dag() {
930 let mut dag = SimpleDag::new(4);
931 dag.add_edge(0, 1);
932 dag.add_edge(1, 2);
933 dag.add_edge(2, 3);
934 assert!(dag.can_reach(0, 3));
935 assert!(!dag.can_reach(3, 0));
936 let order = dag.topological_sort().expect("order should be present");
937 assert_eq!(order, vec![0, 1, 2, 3]);
938 }
939 #[test]
940 fn test_focus_stack() {
941 let mut fs: FocusStack<&str> = FocusStack::new();
942 fs.focus("a");
943 fs.focus("b");
944 assert_eq!(fs.current(), Some(&"b"));
945 assert_eq!(fs.depth(), 2);
946 fs.blur();
947 assert_eq!(fs.current(), Some(&"a"));
948 }
949}
950#[cfg(test)]
951mod tests_extra_iterators {
952 use super::*;
953 #[test]
954 fn test_window_iterator() {
955 let data = vec![1u32, 2, 3, 4, 5];
956 let windows: Vec<_> = WindowIterator::new(&data, 3).collect();
957 assert_eq!(windows.len(), 3);
958 assert_eq!(windows[0], &[1, 2, 3]);
959 assert_eq!(windows[2], &[3, 4, 5]);
960 }
961 #[test]
962 fn test_non_empty_vec() {
963 let mut nev = NonEmptyVec::singleton(10u32);
964 nev.push(20);
965 nev.push(30);
966 assert_eq!(nev.len(), 3);
967 assert_eq!(*nev.first(), 10);
968 assert_eq!(*nev.last(), 30);
969 }
970}
971#[cfg(test)]
972mod tests_padding2 {
973 use super::*;
974 #[test]
975 fn test_sliding_sum() {
976 let mut ss = SlidingSum::new(3);
977 ss.push(1.0);
978 ss.push(2.0);
979 ss.push(3.0);
980 assert!((ss.sum() - 6.0).abs() < 1e-9);
981 ss.push(4.0);
982 assert!((ss.sum() - 9.0).abs() < 1e-9);
983 assert_eq!(ss.count(), 3);
984 }
985 #[test]
986 fn test_path_buf() {
987 let mut pb = PathBuf::new();
988 pb.push("src");
989 pb.push("main");
990 assert_eq!(pb.as_str(), "src/main");
991 assert_eq!(pb.depth(), 2);
992 pb.pop();
993 assert_eq!(pb.as_str(), "src");
994 }
995 #[test]
996 fn test_string_pool() {
997 let mut pool = StringPool::new();
998 let s = pool.take();
999 assert!(s.is_empty());
1000 pool.give("hello".to_string());
1001 let s2 = pool.take();
1002 assert!(s2.is_empty());
1003 assert_eq!(pool.free_count(), 0);
1004 }
1005 #[test]
1006 fn test_transitive_closure() {
1007 let mut tc = TransitiveClosure::new(4);
1008 tc.add_edge(0, 1);
1009 tc.add_edge(1, 2);
1010 tc.add_edge(2, 3);
1011 assert!(tc.can_reach(0, 3));
1012 assert!(!tc.can_reach(3, 0));
1013 let r = tc.reachable_from(0);
1014 assert_eq!(r.len(), 4);
1015 }
1016 #[test]
1017 fn test_token_bucket() {
1018 let mut tb = TokenBucket::new(100, 0);
1019 assert_eq!(tb.available(), 100);
1020 assert!(tb.try_consume(50));
1021 assert_eq!(tb.available(), 50);
1022 assert!(!tb.try_consume(60));
1023 assert_eq!(tb.capacity(), 100);
1024 }
1025 #[test]
1026 fn test_rewrite_rule_set() {
1027 let mut rrs = RewriteRuleSet::new();
1028 rrs.add(RewriteRule::unconditional(
1029 "beta",
1030 "App(Lam(x, b), v)",
1031 "b[x:=v]",
1032 ));
1033 rrs.add(RewriteRule::conditional("comm", "a + b", "b + a"));
1034 assert_eq!(rrs.len(), 2);
1035 assert_eq!(rrs.unconditional_rules().len(), 1);
1036 assert_eq!(rrs.conditional_rules().len(), 1);
1037 assert!(rrs.get("beta").is_some());
1038 let disp = rrs
1039 .get("beta")
1040 .expect("element at \'beta\' should exist")
1041 .display();
1042 assert!(disp.contains("→"));
1043 }
1044}
1045#[cfg(test)]
1046mod tests_padding3 {
1047 use super::*;
1048 #[test]
1049 fn test_decision_node() {
1050 let tree = DecisionNode::Branch {
1051 key: "x".into(),
1052 val: "1".into(),
1053 yes_branch: Box::new(DecisionNode::Leaf("yes".into())),
1054 no_branch: Box::new(DecisionNode::Leaf("no".into())),
1055 };
1056 let mut ctx = std::collections::HashMap::new();
1057 ctx.insert("x".into(), "1".into());
1058 assert_eq!(tree.evaluate(&ctx), "yes");
1059 ctx.insert("x".into(), "2".into());
1060 assert_eq!(tree.evaluate(&ctx), "no");
1061 assert_eq!(tree.depth(), 1);
1062 }
1063 #[test]
1064 fn test_flat_substitution() {
1065 let mut sub = FlatSubstitution::new();
1066 sub.add("foo", "bar");
1067 sub.add("baz", "qux");
1068 assert_eq!(sub.apply("foo and baz"), "bar and qux");
1069 assert_eq!(sub.len(), 2);
1070 }
1071 #[test]
1072 fn test_stopwatch() {
1073 let mut sw = Stopwatch::start();
1074 sw.split();
1075 sw.split();
1076 assert_eq!(sw.num_splits(), 2);
1077 assert!(sw.elapsed_ms() >= 0.0);
1078 for &s in sw.splits() {
1079 assert!(s >= 0.0);
1080 }
1081 }
1082 #[test]
1083 fn test_either2() {
1084 let e: Either2<i32, &str> = Either2::First(42);
1085 assert!(e.is_first());
1086 let mapped = e.map_first(|x| x * 2);
1087 assert_eq!(mapped.first(), Some(84));
1088 let e2: Either2<i32, &str> = Either2::Second("hello");
1089 assert!(e2.is_second());
1090 assert_eq!(e2.second(), Some("hello"));
1091 }
1092 #[test]
1093 fn test_write_once() {
1094 let wo: WriteOnce<u32> = WriteOnce::new();
1095 assert!(!wo.is_written());
1096 assert!(wo.write(42));
1097 assert!(!wo.write(99));
1098 assert_eq!(wo.read(), Some(42));
1099 }
1100 #[test]
1101 fn test_sparse_vec() {
1102 let mut sv: SparseVec<i32> = SparseVec::new(100);
1103 sv.set(5, 10);
1104 sv.set(50, 20);
1105 assert_eq!(*sv.get(5), 10);
1106 assert_eq!(*sv.get(50), 20);
1107 assert_eq!(*sv.get(0), 0);
1108 assert_eq!(sv.nnz(), 2);
1109 sv.set(5, 0);
1110 assert_eq!(sv.nnz(), 1);
1111 }
1112 #[test]
1113 fn test_stack_calc() {
1114 let mut calc = StackCalc::new();
1115 calc.push(3);
1116 calc.push(4);
1117 assert_eq!(calc.add(), Some(7));
1118 assert_eq!(calc.peek(), Some(7));
1119 calc.push(2);
1120 assert_eq!(calc.mul(), Some(14));
1121 assert_eq!(calc.peek(), Some(14));
1122 }
1123}
1124#[cfg(test)]
1125mod tests_final_padding {
1126 use super::*;
1127 #[test]
1128 fn test_min_heap() {
1129 let mut h = MinHeap::new();
1130 h.push(5u32);
1131 h.push(1u32);
1132 h.push(3u32);
1133 assert_eq!(h.peek(), Some(&1));
1134 assert_eq!(h.pop(), Some(1));
1135 assert_eq!(h.pop(), Some(3));
1136 assert_eq!(h.pop(), Some(5));
1137 assert!(h.is_empty());
1138 }
1139 #[test]
1140 fn test_prefix_counter() {
1141 let mut pc = PrefixCounter::new();
1142 pc.record("hello");
1143 pc.record("help");
1144 pc.record("world");
1145 assert_eq!(pc.count_with_prefix("hel"), 2);
1146 assert_eq!(pc.count_with_prefix("wor"), 1);
1147 assert_eq!(pc.count_with_prefix("xyz"), 0);
1148 }
1149 #[test]
1150 fn test_fixture() {
1151 let mut f = Fixture::new();
1152 f.set("key1", "val1");
1153 f.set("key2", "val2");
1154 assert_eq!(f.get("key1"), Some("val1"));
1155 assert_eq!(f.get("key3"), None);
1156 assert_eq!(f.len(), 2);
1157 }
1158}
1159#[cfg(test)]
1160mod normalize_merge_tests;