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