1use crate::level;
6use crate::{Level, Name};
7use std::collections::{HashMap, HashSet};
8
9use super::types::{
10 ConfigNode, DecisionNode, Either2, FlatSubstitution, FocusStack, LabelSet,
11 LevelComparisonTable, LevelNormalForm, NonEmptyVec, PathBuf, RewriteRule, RewriteRuleSet,
12 SimpleDag, SlidingSum, SmallMap, SparseVec, StackCalc, StatSummary, Stopwatch, StringPool,
13 TokenBucket, TransformStat, TransitiveClosure, UnivChecker, UnivConstraint, UnivConstraintSet,
14 UnivPolySignature, UnivSatChecker, UniverseInstantiation, VersionedRecord, WindowIterator,
15 WriteOnce,
16};
17
18#[cfg(test)]
19mod tests {
20 use super::*;
21 #[test]
22 fn test_create_checker() {
23 let checker = UnivChecker::new();
24 assert_eq!(checker.all_constraints().len(), 0);
25 assert_eq!(checker.all_univ_vars().len(), 0);
26 }
27 #[test]
28 fn test_add_univ_var() {
29 let mut checker = UnivChecker::new();
30 checker.add_univ_var(Name::str("u"));
31 assert_eq!(checker.all_univ_vars().len(), 1);
32 }
33 #[test]
34 fn test_satisfiable_lt() {
35 let mut checker = UnivChecker::new();
36 checker.add_constraint(UnivConstraint::Lt(
37 Level::zero(),
38 Level::succ(Level::zero()),
39 ));
40 assert!(checker.check().is_ok());
41 }
42 #[test]
43 fn test_unsatisfiable_lt() {
44 let mut checker = UnivChecker::new();
45 let u = Level::succ(Level::zero());
46 checker.add_constraint(UnivConstraint::Lt(u.clone(), u));
47 assert!(checker.check().is_err());
48 }
49 #[test]
50 fn test_satisfiable_eq() {
51 let mut checker = UnivChecker::new();
52 let u = Level::zero();
53 checker.add_constraint(UnivConstraint::Eq(u.clone(), u));
54 assert!(checker.check().is_ok());
55 }
56 #[test]
57 fn test_le_constraint() {
58 let mut checker = UnivChecker::new();
59 checker.add_constraint(UnivConstraint::Le(
60 Level::zero(),
61 Level::succ(Level::zero()),
62 ));
63 assert!(checker.check().is_ok());
64 }
65 #[test]
66 fn test_le_equal() {
67 let mut checker = UnivChecker::new();
68 let l = Level::succ(Level::zero());
69 checker.add_constraint(UnivConstraint::Le(l.clone(), l));
70 assert!(checker.check().is_ok());
71 }
72 #[test]
73 fn test_le_violation() {
74 let mut checker = UnivChecker::new();
75 checker.add_constraint(UnivConstraint::Le(
76 Level::succ(Level::succ(Level::zero())),
77 Level::succ(Level::zero()),
78 ));
79 assert!(checker.check().is_err());
80 }
81 #[test]
82 fn test_level_def_eq_normalized() {
83 let checker = UnivChecker::new();
84 let l1 = Level::max(Level::param(Name::str("u")), Level::param(Name::str("v")));
85 let l2 = Level::max(Level::param(Name::str("v")), Level::param(Name::str("u")));
86 assert!(checker.is_level_def_eq(&l1, &l2));
87 }
88 #[test]
89 fn test_level_mvar_assignment() {
90 let mut checker = UnivChecker::new();
91 let m = checker.fresh_level_mvar();
92 let one = Level::succ(Level::zero());
93 if let Level::MVar(id) = &m {
94 checker.assign_mvar(*id, one.clone());
95 }
96 checker.add_constraint(UnivConstraint::Eq(m, one));
97 assert!(checker.check().is_ok());
98 }
99 #[test]
100 fn test_solve_simple() {
101 let mut checker = UnivChecker::new();
102 let m = checker.fresh_level_mvar();
103 let two = Level::succ(Level::succ(Level::zero()));
104 checker.add_constraint(UnivConstraint::Eq(m.clone(), two.clone()));
105 assert!(checker.solve_simple());
106 if let Level::MVar(id) = &m {
107 assert_eq!(checker.get_mvar_assignment(id), Some(&two));
108 }
109 }
110 #[test]
111 fn test_is_geq() {
112 let checker = UnivChecker::new();
113 assert!(checker.is_geq(&Level::succ(Level::zero()), &Level::zero()));
114 assert!(checker.is_geq(&Level::zero(), &Level::zero()));
115 assert!(!checker.is_geq(&Level::zero(), &Level::succ(Level::zero())));
116 }
117 #[test]
118 fn test_is_gt() {
119 let checker = UnivChecker::new();
120 assert!(checker.is_gt(&Level::succ(Level::zero()), &Level::zero()));
121 assert!(!checker.is_gt(&Level::zero(), &Level::zero()));
122 }
123 #[test]
124 fn test_clear() {
125 let mut checker = UnivChecker::new();
126 checker.add_constraint(UnivConstraint::Eq(Level::zero(), Level::zero()));
127 let m = checker.fresh_level_mvar();
128 if let Level::MVar(id) = &m {
129 checker.assign_mvar(*id, Level::zero());
130 }
131 checker.clear();
132 assert_eq!(checker.all_constraints().len(), 0);
133 }
134}
135pub fn level_max(l1: Level, l2: Level) -> Level {
137 Level::max(l1, l2)
138}
139pub fn level_succ(l: Level) -> Level {
141 Level::succ(l)
142}
143pub fn level_imax(l1: Level, l2: Level) -> Level {
145 Level::imax(l1, l2)
146}
147pub fn sort_type_level(l: &Level) -> Level {
149 Level::succ(l.clone())
150}
151pub fn pi_type_level(domain: &Level, codomain: &Level) -> Level {
153 Level::imax(domain.clone(), codomain.clone())
154}
155pub fn level_to_nat(l: &Level) -> Option<u32> {
157 match l {
158 Level::Zero => Some(0),
159 Level::Succ(inner) => level_to_nat(inner).map(|n| n + 1),
160 Level::Max(a, b) => {
161 let a_n = level_to_nat(a)?;
162 let b_n = level_to_nat(b)?;
163 Some(a_n.max(b_n))
164 }
165 Level::IMax(a, b) => {
166 let b_n = level_to_nat(b)?;
167 if b_n == 0 {
168 Some(0)
169 } else {
170 let a_n = level_to_nat(a)?;
171 Some(a_n.max(b_n))
172 }
173 }
174 Level::Param(_) | Level::MVar(_) => None,
175 }
176}
177pub fn prop_level() -> Level {
179 Level::zero()
180}
181pub fn type0_level() -> Level {
183 Level::succ(Level::zero())
184}
185pub fn type1_level() -> Level {
187 Level::succ(Level::succ(Level::zero()))
188}
189pub fn is_prop_level(l: &Level) -> bool {
191 level::is_equivalent(l, &Level::zero())
192}
193pub fn count_succs(l: &Level) -> Option<u32> {
195 match l {
196 Level::Zero => Some(0),
197 Level::Succ(inner) => count_succs(inner).map(|n| n + 1),
198 _ => None,
199 }
200}
201pub fn peel_succs(l: &Level, n: u32) -> Option<Level> {
203 if n == 0 {
204 return Some(l.clone());
205 }
206 match l {
207 Level::Succ(inner) => peel_succs(inner, n - 1),
208 _ => None,
209 }
210}
211pub fn add_succs(l: Level, n: u32) -> Level {
213 let mut r = l;
214 for _ in 0..n {
215 r = Level::succ(r);
216 }
217 r
218}
219pub fn collect_level_params(l: &Level) -> Vec<Name> {
221 let mut params = std::collections::HashSet::new();
222 collect_level_params_impl(l, &mut params);
223 let mut result: Vec<Name> = params.into_iter().collect();
224 result.sort_by(|a, b| format!("{}", a).cmp(&format!("{}", b)));
225 result
226}
227fn collect_level_params_impl(l: &Level, params: &mut std::collections::HashSet<Name>) {
228 match l {
229 Level::Param(name) => {
230 params.insert(name.clone());
231 }
232 Level::Succ(inner) => collect_level_params_impl(inner, params),
233 Level::Max(a, b) | Level::IMax(a, b) => {
234 collect_level_params_impl(a, params);
235 collect_level_params_impl(b, params);
236 }
237 Level::Zero | Level::MVar(_) => {}
238 }
239}
240pub fn substitute_level_param(l: &Level, param_name: &Name, replacement: &Level) -> Level {
242 match l {
243 Level::Param(name) if name == param_name => replacement.clone(),
244 Level::Succ(inner) => Level::succ(substitute_level_param(inner, param_name, replacement)),
245 Level::Max(a, b) => Level::max(
246 substitute_level_param(a, param_name, replacement),
247 substitute_level_param(b, param_name, replacement),
248 ),
249 Level::IMax(a, b) => Level::imax(
250 substitute_level_param(a, param_name, replacement),
251 substitute_level_param(b, param_name, replacement),
252 ),
253 Level::Zero | Level::Param(_) | Level::MVar(_) => l.clone(),
254 }
255}
256pub fn format_level(l: &Level) -> String {
258 match l {
259 Level::Zero => "0".to_string(),
260 Level::Succ(_) => {
261 if let Some(n) = count_succs(l) {
262 if n <= 4 {
263 return n.to_string();
264 }
265 }
266 if let Level::Succ(inner) = l {
267 format!("succ({})", format_level(inner))
268 } else {
269 "?".to_string()
270 }
271 }
272 Level::Max(a, b) => format!("max({}, {})", format_level(a), format_level(b)),
273 Level::IMax(a, b) => format!("imax({}, {})", format_level(a), format_level(b)),
274 Level::Param(name) => format!("{}", name),
275 Level::MVar(id) => format!("?u{}", id.0),
276 }
277}
278pub fn parse_level_str(s: &str) -> Option<Level> {
280 match s.trim() {
281 "0" => Some(Level::zero()),
282 "1" => Some(Level::succ(Level::zero())),
283 "2" => Some(Level::succ(Level::succ(Level::zero()))),
284 "Prop" => Some(Level::zero()),
285 "Type" => Some(Level::succ(Level::zero())),
286 s if s.starts_with("succ(") && s.ends_with(')') => {
287 parse_level_str(&s[5..s.len() - 1]).map(Level::succ)
288 }
289 s if s
290 .chars()
291 .all(|c| c.is_alphanumeric() || c == '_' || c == '.') =>
292 {
293 Some(Level::param(Name::str(s)))
294 }
295 _ => None,
296 }
297}
298pub(super) fn collect_nf_comps(l: &Level, offset: u32, comps: &mut Vec<(Option<Name>, u32)>) {
299 match l {
300 Level::Zero => comps.push((None, offset)),
301 Level::Param(name) => comps.push((Some(name.clone()), offset)),
302 Level::Succ(inner) => collect_nf_comps(inner, offset + 1, comps),
303 Level::Max(a, b) => {
304 collect_nf_comps(a, offset, comps);
305 collect_nf_comps(b, offset, comps);
306 }
307 Level::IMax(a, b) => {
308 collect_nf_comps(a, offset, comps);
309 collect_nf_comps(b, offset, comps);
310 }
311 Level::MVar(_) => {}
312 }
313}
314#[cfg(test)]
315mod universe_arith_tests {
316 use super::*;
317 #[test]
318 fn test_level_to_nat_zero() {
319 assert_eq!(level_to_nat(&Level::zero()), Some(0));
320 }
321 #[test]
322 fn test_level_to_nat_succ() {
323 assert_eq!(level_to_nat(&Level::succ(Level::zero())), Some(1));
324 assert_eq!(
325 level_to_nat(&Level::succ(Level::succ(Level::zero()))),
326 Some(2)
327 );
328 }
329 #[test]
330 fn test_level_to_nat_param() {
331 assert_eq!(level_to_nat(&Level::param(Name::str("u"))), None);
332 }
333 #[test]
334 fn test_is_prop_level() {
335 assert!(is_prop_level(&Level::zero()));
336 assert!(!is_prop_level(&Level::succ(Level::zero())));
337 }
338 #[test]
339 fn test_pi_type_level() {
340 let pi_l = pi_type_level(&Level::zero(), &Level::succ(Level::zero()));
341 assert!(level::is_equivalent(&pi_l, &Level::succ(Level::zero())));
342 }
343 #[test]
344 fn test_collect_level_params() {
345 let l = Level::max(
346 Level::param(Name::str("u")),
347 Level::succ(Level::param(Name::str("v"))),
348 );
349 let params = collect_level_params(&l);
350 assert!(params.contains(&Name::str("u")));
351 assert!(params.contains(&Name::str("v")));
352 }
353 #[test]
354 fn test_substitute_level_param() {
355 let l = Level::succ(Level::param(Name::str("u")));
356 let result = substitute_level_param(&l, &Name::str("u"), &Level::zero());
357 assert_eq!(result, Level::succ(Level::zero()));
358 }
359 #[test]
360 fn test_add_succs() {
361 let result = add_succs(Level::zero(), 3);
362 assert_eq!(level_to_nat(&result), Some(3));
363 }
364 #[test]
365 fn test_peel_succs() {
366 let l = Level::succ(Level::succ(Level::succ(Level::zero())));
367 assert_eq!(peel_succs(&l, 3), Some(Level::zero()));
368 assert_eq!(peel_succs(&l, 4), None);
369 }
370 #[test]
371 fn test_parse_level_str() {
372 assert_eq!(parse_level_str("0"), Some(Level::zero()));
373 assert_eq!(parse_level_str("1"), Some(Level::succ(Level::zero())));
374 assert_eq!(parse_level_str("u"), Some(Level::param(Name::str("u"))));
375 }
376 #[test]
377 fn test_format_level() {
378 assert_eq!(format_level(&Level::zero()), "0");
379 assert_eq!(format_level(&Level::succ(Level::zero())), "1");
380 }
381 #[test]
382 fn test_sat_checker() {
383 let mut checker = UnivSatChecker::new();
384 checker.add_lower_bound(Name::str("u"), 1);
385 checker.add_upper_bound(Name::str("u"), 3);
386 assert!(checker.is_satisfiable());
387 }
388 #[test]
389 fn test_sat_checker_unsat() {
390 let mut checker = UnivSatChecker::new();
391 checker.add_lower_bound(Name::str("u"), 5);
392 checker.add_upper_bound(Name::str("u"), 3);
393 assert!(!checker.is_satisfiable());
394 }
395 #[test]
396 fn test_sort_type_level() {
397 assert_eq!(sort_type_level(&Level::zero()), Level::succ(Level::zero()));
398 }
399 #[test]
400 fn test_prop_level() {
401 assert_eq!(prop_level(), Level::zero());
402 }
403 #[test]
404 fn test_count_succs() {
405 assert_eq!(count_succs(&Level::zero()), Some(0));
406 assert_eq!(count_succs(&Level::succ(Level::zero())), Some(1));
407 }
408 #[test]
409 fn test_level_normal_form() {
410 let l = Level::max(Level::succ(Level::zero()), Level::zero());
411 let nf = LevelNormalForm::from_level(&l);
412 assert!(!nf.components.is_empty());
413 }
414 #[test]
415 fn test_type0_type1() {
416 assert_eq!(level_to_nat(&type0_level()), Some(1));
417 assert_eq!(level_to_nat(&type1_level()), Some(2));
418 }
419 #[test]
420 fn test_level_max_fn() {
421 let l = level_max(Level::zero(), Level::succ(Level::zero()));
422 assert!(level::is_equivalent(&l, &Level::succ(Level::zero())));
423 }
424 #[test]
425 fn test_level_succ_fn() {
426 assert_eq!(level_succ(Level::zero()), Level::succ(Level::zero()));
427 }
428}
429#[allow(dead_code)]
433pub fn level_max_many(levels: &[Level]) -> Level {
434 levels
435 .iter()
436 .fold(Level::zero(), |acc, l| level_max(acc, l.clone()))
437}
438#[allow(dead_code)]
440pub fn is_max_level(l: &Level) -> bool {
441 matches!(l, Level::Max(_, _))
442}
443#[allow(dead_code)]
445pub fn is_imax_level(l: &Level) -> bool {
446 matches!(l, Level::IMax(_, _))
447}
448#[allow(dead_code)]
452pub fn count_succ_depth(l: &Level) -> u32 {
453 let mut depth = 0u32;
454 let mut cur = l;
455 while let Level::Succ(inner) = cur {
456 depth += 1;
457 cur = inner;
458 }
459 depth
460}
461#[allow(dead_code)]
465pub fn add_succ_n(l: Level, n: u32) -> Level {
466 (0..n).fold(l, |acc, _| Level::succ(acc))
467}
468#[allow(dead_code)]
472pub fn eval_closed_level(l: &Level) -> Option<u32> {
473 level_to_nat(l)
474}
475#[allow(dead_code)]
477pub fn same_level_shape(l1: &Level, l2: &Level) -> bool {
478 match (l1, l2) {
479 (Level::Zero, Level::Zero) => true,
480 (Level::Succ(a), Level::Succ(b)) => same_level_shape(a, b),
481 (Level::Max(a1, b1), Level::Max(a2, b2)) => {
482 same_level_shape(a1, a2) && same_level_shape(b1, b2)
483 }
484 (Level::IMax(a1, b1), Level::IMax(a2, b2)) => {
485 same_level_shape(a1, a2) && same_level_shape(b1, b2)
486 }
487 (Level::Param(_), Level::Param(_)) => true,
488 (Level::MVar(_), Level::MVar(_)) => true,
489 _ => false,
490 }
491}
492pub fn is_valid_instantiation(params: &[Name], inst: &UniverseInstantiation) -> bool {
494 params.iter().all(|p| inst.subst.contains_key(p))
495}
496pub fn instantiate_levels(levels: &[Level], params: &[Name], args: &[Level]) -> Vec<Level> {
498 let mut inst = UniverseInstantiation::new();
499 for (p, l) in params.iter().zip(args.iter()) {
500 inst.add(p.clone(), l.clone());
501 }
502 levels.iter().map(|l| inst.apply(l)).collect()
503}
504#[cfg(test)]
505mod poly_tests {
506 use super::*;
507 #[test]
508 fn test_universe_instantiation_apply() {
509 let mut inst = UniverseInstantiation::new();
510 inst.add(Name::str("u"), Level::succ(Level::zero()));
511 let l = Level::param(Name::str("u"));
512 let result = inst.apply(&l);
513 assert_eq!(result, Level::succ(Level::zero()));
514 }
515 #[test]
516 fn test_universe_instantiation_compose() {
517 let mut inst1 = UniverseInstantiation::new();
518 inst1.add(Name::str("v"), Level::zero());
519 let mut inst2 = UniverseInstantiation::new();
520 inst2.add(Name::str("u"), Level::param(Name::str("v")));
521 let composed = inst1.compose(&inst2);
522 let l = Level::param(Name::str("u"));
523 let result = composed.apply(&l);
524 assert_eq!(result, Level::zero());
525 }
526 #[test]
527 fn test_is_valid_instantiation() {
528 let mut inst = UniverseInstantiation::new();
529 inst.add(Name::str("u"), Level::zero());
530 let params = vec![Name::str("u")];
531 assert!(is_valid_instantiation(¶ms, &inst));
532 let params2 = vec![Name::str("u"), Name::str("v")];
533 assert!(!is_valid_instantiation(¶ms2, &inst));
534 }
535 #[test]
536 fn test_instantiate_levels() {
537 let levels = vec![
538 Level::param(Name::str("u")),
539 Level::succ(Level::param(Name::str("u"))),
540 ];
541 let params = vec![Name::str("u")];
542 let args = vec![Level::zero()];
543 let result = instantiate_levels(&levels, ¶ms, &args);
544 assert_eq!(result[0], Level::zero());
545 assert_eq!(result[1], Level::succ(Level::zero()));
546 }
547 #[test]
548 fn test_univ_constraint_set_dedup() {
549 let mut s = UnivConstraintSet::new();
550 s.add(UnivConstraint::Eq(Level::zero(), Level::zero()));
551 s.add(UnivConstraint::Eq(Level::zero(), Level::zero()));
552 s.dedup();
553 assert_eq!(s.len(), 1);
554 }
555 #[test]
556 fn test_univ_constraint_set_merge() {
557 let mut s1 = UnivConstraintSet::new();
558 s1.add(UnivConstraint::Le(
559 Level::zero(),
560 Level::succ(Level::zero()),
561 ));
562 let mut s2 = UnivConstraintSet::new();
563 s2.add(UnivConstraint::Eq(Level::zero(), Level::zero()));
564 s1.merge(&s2);
565 assert_eq!(s1.len(), 2);
566 }
567 #[test]
568 fn test_univ_poly_signature_instantiate() {
569 let sig = UnivPolySignature::new(vec![Name::str("u"), Name::str("v")]);
570 let args = vec![Level::zero(), Level::succ(Level::zero())];
571 let inst = sig.instantiate(&args).expect("inst should be present");
572 assert_eq!(inst.apply(&Level::param(Name::str("u"))), Level::zero());
573 assert_eq!(
574 inst.apply(&Level::param(Name::str("v"))),
575 Level::succ(Level::zero())
576 );
577 }
578 #[test]
579 fn test_univ_poly_signature_wrong_arity() {
580 let sig = UnivPolySignature::new(vec![Name::str("u")]);
581 assert!(sig.instantiate(&[]).is_none());
582 }
583 #[test]
584 fn test_univ_poly_signature_check_ok() {
585 let mut sig = UnivPolySignature::new(vec![Name::str("u")]);
586 sig.add_constraint(UnivConstraint::Le(
587 Level::param(Name::str("u")),
588 Level::succ(Level::param(Name::str("u"))),
589 ));
590 let args = vec![Level::zero()];
591 let inst = sig.instantiate(&args).expect("inst should be present");
592 assert!(sig.check_instantiation(&inst).is_ok());
593 }
594 #[test]
595 fn test_univ_constraint_display() {
596 let c = UnivConstraint::Lt(Level::zero(), Level::succ(Level::zero()));
597 let s = format!("{}", c);
598 assert!(s.contains('<'));
599 }
600 #[test]
601 fn test_level_comparison_table() {
602 let levels = vec![
603 Level::zero(),
604 Level::succ(Level::zero()),
605 Level::succ(Level::succ(Level::zero())),
606 ];
607 let table = LevelComparisonTable::new(levels);
608 assert_eq!(table.len(), 3);
609 assert_eq!(table.geq(1, 0), Some(true));
610 assert_eq!(table.geq(0, 1), Some(false));
611 }
612 #[test]
613 fn test_level_comparison_table_max() {
614 let levels = vec![Level::zero(), Level::succ(Level::zero())];
615 let table = LevelComparisonTable::new(levels);
616 let max = table.max_idx();
617 assert_eq!(max, Some(1));
618 }
619 #[test]
620 fn test_same_level_shape_max() {
621 let l1 = Level::max(Level::param(Name::str("u")), Level::param(Name::str("v")));
622 let l2 = Level::max(Level::param(Name::str("a")), Level::param(Name::str("b")));
623 assert!(same_level_shape(&l1, &l2));
624 }
625 #[test]
626 fn test_count_succ_depth() {
627 assert_eq!(count_succ_depth(&Level::zero()), 0);
628 assert_eq!(
629 count_succ_depth(&Level::succ(Level::succ(Level::zero()))),
630 2
631 );
632 }
633 #[test]
634 fn test_add_succ_n() {
635 let result = add_succ_n(Level::zero(), 4);
636 assert_eq!(level_to_nat(&result), Some(4));
637 }
638 #[test]
639 fn test_eval_closed_level_param() {
640 let l = Level::param(Name::str("u"));
641 assert!(eval_closed_level(&l).is_none());
642 }
643 #[test]
644 fn test_is_max_level() {
645 let l = Level::max(Level::zero(), Level::zero());
646 assert!(is_max_level(&l));
647 assert!(!is_imax_level(&l));
648 }
649 #[test]
650 fn test_is_imax_level() {
651 let l = Level::imax(Level::zero(), Level::zero());
652 assert!(is_imax_level(&l));
653 assert!(!is_max_level(&l));
654 }
655 #[test]
656 fn test_level_max_many_empty() {
657 let result = level_max_many(&[]);
658 assert_eq!(result, Level::zero());
659 }
660 #[test]
661 fn test_level_max_many_one() {
662 let l = Level::succ(Level::zero());
663 let result = level_max_many(std::slice::from_ref(&l));
664 assert!(crate::level::is_equivalent(&result, &l));
665 }
666 #[test]
667 fn test_univ_instantiation_len() {
668 let mut inst = UniverseInstantiation::new();
669 assert_eq!(inst.len(), 0);
670 inst.add(Name::str("u"), Level::zero());
671 assert_eq!(inst.len(), 1);
672 }
673}
674#[cfg(test)]
675mod tests_padding_infra {
676 use super::*;
677 #[test]
678 fn test_stat_summary() {
679 let mut ss = StatSummary::new();
680 ss.record(10.0);
681 ss.record(20.0);
682 ss.record(30.0);
683 assert_eq!(ss.count(), 3);
684 assert!((ss.mean().expect("mean should succeed") - 20.0).abs() < 1e-9);
685 assert_eq!(ss.min().expect("min should succeed") as i64, 10);
686 assert_eq!(ss.max().expect("max should succeed") as i64, 30);
687 }
688 #[test]
689 fn test_transform_stat() {
690 let mut ts = TransformStat::new();
691 ts.record_before(100.0);
692 ts.record_after(80.0);
693 let ratio = ts.mean_ratio().expect("ratio should be present");
694 assert!((ratio - 0.8).abs() < 1e-9);
695 }
696 #[test]
697 fn test_small_map() {
698 let mut m: SmallMap<u32, &str> = SmallMap::new();
699 m.insert(3, "three");
700 m.insert(1, "one");
701 m.insert(2, "two");
702 assert_eq!(m.get(&2), Some(&"two"));
703 assert_eq!(m.len(), 3);
704 let keys = m.keys();
705 assert_eq!(*keys[0], 1);
706 assert_eq!(*keys[2], 3);
707 }
708 #[test]
709 fn test_label_set() {
710 let mut ls = LabelSet::new();
711 ls.add("foo");
712 ls.add("bar");
713 ls.add("foo");
714 assert_eq!(ls.count(), 2);
715 assert!(ls.has("bar"));
716 assert!(!ls.has("baz"));
717 }
718 #[test]
719 fn test_config_node() {
720 let mut root = ConfigNode::section("root");
721 let child = ConfigNode::leaf("key", "value");
722 root.add_child(child);
723 assert_eq!(root.num_children(), 1);
724 }
725 #[test]
726 fn test_versioned_record() {
727 let mut vr = VersionedRecord::new(0u32);
728 vr.update(1);
729 vr.update(2);
730 assert_eq!(*vr.current(), 2);
731 assert_eq!(vr.version(), 2);
732 assert!(vr.has_history());
733 assert_eq!(*vr.at_version(0).expect("value should be present"), 0);
734 }
735 #[test]
736 fn test_simple_dag() {
737 let mut dag = SimpleDag::new(4);
738 dag.add_edge(0, 1);
739 dag.add_edge(1, 2);
740 dag.add_edge(2, 3);
741 assert!(dag.can_reach(0, 3));
742 assert!(!dag.can_reach(3, 0));
743 let order = dag.topological_sort().expect("order should be present");
744 assert_eq!(order, vec![0, 1, 2, 3]);
745 }
746 #[test]
747 fn test_focus_stack() {
748 let mut fs: FocusStack<&str> = FocusStack::new();
749 fs.focus("a");
750 fs.focus("b");
751 assert_eq!(fs.current(), Some(&"b"));
752 assert_eq!(fs.depth(), 2);
753 fs.blur();
754 assert_eq!(fs.current(), Some(&"a"));
755 }
756}
757#[cfg(test)]
758mod tests_extra_iterators {
759 use super::*;
760 #[test]
761 fn test_window_iterator() {
762 let data = vec![1u32, 2, 3, 4, 5];
763 let windows: Vec<_> = WindowIterator::new(&data, 3).collect();
764 assert_eq!(windows.len(), 3);
765 assert_eq!(windows[0], &[1, 2, 3]);
766 assert_eq!(windows[2], &[3, 4, 5]);
767 }
768 #[test]
769 fn test_non_empty_vec() {
770 let mut nev = NonEmptyVec::singleton(10u32);
771 nev.push(20);
772 nev.push(30);
773 assert_eq!(nev.len(), 3);
774 assert_eq!(*nev.first(), 10);
775 assert_eq!(*nev.last(), 30);
776 }
777}
778#[cfg(test)]
779mod tests_padding2 {
780 use super::*;
781 #[test]
782 fn test_sliding_sum() {
783 let mut ss = SlidingSum::new(3);
784 ss.push(1.0);
785 ss.push(2.0);
786 ss.push(3.0);
787 assert!((ss.sum() - 6.0).abs() < 1e-9);
788 ss.push(4.0);
789 assert!((ss.sum() - 9.0).abs() < 1e-9);
790 assert_eq!(ss.count(), 3);
791 }
792 #[test]
793 fn test_path_buf() {
794 let mut pb = PathBuf::new();
795 pb.push("src");
796 pb.push("main");
797 assert_eq!(pb.as_str(), "src/main");
798 assert_eq!(pb.depth(), 2);
799 pb.pop();
800 assert_eq!(pb.as_str(), "src");
801 }
802 #[test]
803 fn test_string_pool() {
804 let mut pool = StringPool::new();
805 let s = pool.take();
806 assert!(s.is_empty());
807 pool.give("hello".to_string());
808 let s2 = pool.take();
809 assert!(s2.is_empty());
810 assert_eq!(pool.free_count(), 0);
811 }
812 #[test]
813 fn test_transitive_closure() {
814 let mut tc = TransitiveClosure::new(4);
815 tc.add_edge(0, 1);
816 tc.add_edge(1, 2);
817 tc.add_edge(2, 3);
818 assert!(tc.can_reach(0, 3));
819 assert!(!tc.can_reach(3, 0));
820 let r = tc.reachable_from(0);
821 assert_eq!(r.len(), 4);
822 }
823 #[test]
824 fn test_token_bucket() {
825 let mut tb = TokenBucket::new(100, 10);
826 assert_eq!(tb.available(), 100);
827 assert!(tb.try_consume(50));
828 assert_eq!(tb.available(), 50);
829 assert!(!tb.try_consume(60));
830 assert_eq!(tb.capacity(), 100);
831 }
832 #[test]
833 fn test_rewrite_rule_set() {
834 let mut rrs = RewriteRuleSet::new();
835 rrs.add(RewriteRule::unconditional(
836 "beta",
837 "App(Lam(x, b), v)",
838 "b[x:=v]",
839 ));
840 rrs.add(RewriteRule::conditional("comm", "a + b", "b + a"));
841 assert_eq!(rrs.len(), 2);
842 assert_eq!(rrs.unconditional_rules().len(), 1);
843 assert_eq!(rrs.conditional_rules().len(), 1);
844 assert!(rrs.get("beta").is_some());
845 let disp = rrs
846 .get("beta")
847 .expect("element at \'beta\' should exist")
848 .display();
849 assert!(disp.contains("→"));
850 }
851}
852#[cfg(test)]
853mod tests_padding3 {
854 use super::*;
855 #[test]
856 fn test_decision_node() {
857 let tree = DecisionNode::Branch {
858 key: "x".into(),
859 val: "1".into(),
860 yes_branch: Box::new(DecisionNode::Leaf("yes".into())),
861 no_branch: Box::new(DecisionNode::Leaf("no".into())),
862 };
863 let mut ctx = std::collections::HashMap::new();
864 ctx.insert("x".into(), "1".into());
865 assert_eq!(tree.evaluate(&ctx), "yes");
866 ctx.insert("x".into(), "2".into());
867 assert_eq!(tree.evaluate(&ctx), "no");
868 assert_eq!(tree.depth(), 1);
869 }
870 #[test]
871 fn test_flat_substitution() {
872 let mut sub = FlatSubstitution::new();
873 sub.add("foo", "bar");
874 sub.add("baz", "qux");
875 assert_eq!(sub.apply("foo and baz"), "bar and qux");
876 assert_eq!(sub.len(), 2);
877 }
878 #[test]
879 fn test_stopwatch() {
880 let mut sw = Stopwatch::start();
881 sw.split();
882 sw.split();
883 assert_eq!(sw.num_splits(), 2);
884 assert!(sw.elapsed_ms() >= 0.0);
885 for &s in sw.splits() {
886 assert!(s >= 0.0);
887 }
888 }
889 #[test]
890 fn test_either2() {
891 let e: Either2<i32, &str> = Either2::First(42);
892 assert!(e.is_first());
893 let mapped = e.map_first(|x| x * 2);
894 assert_eq!(mapped.first(), Some(84));
895 let e2: Either2<i32, &str> = Either2::Second("hello");
896 assert!(e2.is_second());
897 assert_eq!(e2.second(), Some("hello"));
898 }
899 #[test]
900 fn test_write_once() {
901 let wo: WriteOnce<u32> = WriteOnce::new();
902 assert!(!wo.is_written());
903 assert!(wo.write(42));
904 assert!(!wo.write(99));
905 assert_eq!(wo.read(), Some(42));
906 }
907 #[test]
908 fn test_sparse_vec() {
909 let mut sv: SparseVec<i32> = SparseVec::new(100);
910 sv.set(5, 10);
911 sv.set(50, 20);
912 assert_eq!(*sv.get(5), 10);
913 assert_eq!(*sv.get(50), 20);
914 assert_eq!(*sv.get(0), 0);
915 assert_eq!(sv.nnz(), 2);
916 sv.set(5, 0);
917 assert_eq!(sv.nnz(), 1);
918 }
919 #[test]
920 fn test_stack_calc() {
921 let mut calc = StackCalc::new();
922 calc.push(3);
923 calc.push(4);
924 calc.add();
925 assert_eq!(calc.peek(), Some(7));
926 calc.push(2);
927 calc.mul();
928 assert_eq!(calc.peek(), Some(14));
929 }
930}