Skip to main content

oxilean_kernel/env/
functions.rs

1//! Auto-generated module
2//!
3//! 🤖 Generated with [SplitRS](https://github.com/cool-japan/splitrs)
4
5use crate::declaration::{ConstantInfo, ConstantVal, DefinitionSafety, DefinitionVal};
6use crate::reduce::ReducibilityHint;
7use crate::{Expr, Level, Name};
8use std::collections::HashMap;
9
10use super::types::{
11    ConfigNode, DecisionNode, Declaration, Either2, EnvError, EnvKindCounts, EnvStats, Environment,
12    EnvironmentBuilder, EnvironmentSnapshot, EnvironmentView, Fixture, FlatSubstitution,
13    FocusStack, LabelSet, MinHeap, NonEmptyVec, PathBuf, PrefixCounter, RewriteRule,
14    RewriteRuleSet, SimpleDag, SlidingSum, SmallMap, SparseVec, StackCalc, StatSummary, Stopwatch,
15    StringPool, TokenBucket, TransformStat, TransitiveClosure, VersionedRecord, WindowIterator,
16    WriteOnce,
17};
18
19#[cfg(test)]
20mod tests {
21    use super::*;
22    use crate::{Level, Literal};
23    #[test]
24    fn test_add_and_get() {
25        let mut env = Environment::new();
26        let nat_ty = Expr::Sort(Level::zero());
27        let zero_decl = Declaration::Axiom {
28            name: Name::str("Nat.zero"),
29            univ_params: vec![],
30            ty: nat_ty,
31        };
32        env.add(zero_decl).expect("value should be present");
33        assert!(env.contains(&Name::str("Nat.zero")));
34        assert_eq!(env.len(), 1);
35        let retrieved = env
36            .get(&Name::str("Nat.zero"))
37            .expect("retrieved should be present");
38        assert_eq!(retrieved.name(), &Name::str("Nat.zero"));
39    }
40    #[test]
41    fn test_duplicate_declaration() {
42        let mut env = Environment::new();
43        let ty = Expr::Sort(Level::zero());
44        let decl1 = Declaration::Axiom {
45            name: Name::str("foo"),
46            univ_params: vec![],
47            ty: ty.clone(),
48        };
49        let decl2 = Declaration::Axiom {
50            name: Name::str("foo"),
51            univ_params: vec![],
52            ty,
53        };
54        env.add(decl1).expect("value should be present");
55        let result = env.add(decl2);
56        assert!(matches!(result, Err(EnvError::DuplicateDeclaration(_))));
57    }
58    #[test]
59    fn test_definition_with_value() {
60        let mut env = Environment::new();
61        let nat_ty = Expr::Sort(Level::zero());
62        let val = Expr::Lit(Literal::Nat(42));
63        let decl = Declaration::Definition {
64            name: Name::str("answer"),
65            univ_params: vec![],
66            ty: nat_ty,
67            val: val.clone(),
68            hint: ReducibilityHint::Regular(1),
69        };
70        env.add(decl).expect("value should be present");
71        let (defn_val, hint) = env
72            .get_defn(&Name::str("answer"))
73            .expect("value should be present");
74        assert_eq!(defn_val, val);
75        assert_eq!(hint, ReducibilityHint::Regular(1));
76    }
77    #[test]
78    fn test_constant_info_lookup() {
79        let mut env = Environment::new();
80        let ci = ConstantInfo::Axiom(crate::declaration::AxiomVal {
81            common: ConstantVal {
82                name: Name::str("propext"),
83                level_params: vec![],
84                ty: Expr::Sort(Level::zero()),
85            },
86            is_unsafe: false,
87        });
88        env.add_constant(ci).expect("value should be present");
89        assert!(env.contains(&Name::str("propext")));
90        let found = env
91            .find(&Name::str("propext"))
92            .expect("found should be present");
93        assert!(found.is_axiom());
94    }
95    #[test]
96    fn test_inductive_queries() {
97        let mut env = Environment::new();
98        let ind = ConstantInfo::Inductive(crate::declaration::InductiveVal {
99            common: ConstantVal {
100                name: Name::str("Nat"),
101                level_params: vec![],
102                ty: Expr::Sort(Level::succ(Level::zero())),
103            },
104            num_params: 0,
105            num_indices: 0,
106            all: vec![Name::str("Nat")],
107            ctors: vec![Name::str("Nat.zero"), Name::str("Nat.succ")],
108            num_nested: 0,
109            is_rec: true,
110            is_unsafe: false,
111            is_reflexive: false,
112            is_prop: false,
113        });
114        env.add_constant(ind).expect("value should be present");
115        assert!(env.is_inductive(&Name::str("Nat")));
116        assert!(!env.is_constructor(&Name::str("Nat")));
117        let iv = env
118            .get_inductive_val(&Name::str("Nat"))
119            .expect("iv should be present");
120        assert_eq!(iv.ctors.len(), 2);
121    }
122    #[test]
123    fn test_instantiate_const_type() {
124        let mut env = Environment::new();
125        let ci = ConstantInfo::Axiom(crate::declaration::AxiomVal {
126            common: ConstantVal {
127                name: Name::str("List"),
128                level_params: vec![Name::str("u")],
129                ty: Expr::Sort(Level::param(Name::str("u"))),
130            },
131            is_unsafe: false,
132        });
133        env.add_constant(ci).expect("value should be present");
134        let result = env
135            .instantiate_const_type(&Name::str("List"), &[Level::succ(Level::zero())])
136            .expect("value should be present");
137        assert_eq!(result, Expr::Sort(Level::succ(Level::zero())));
138    }
139}
140/// Merge two environments into one.
141#[allow(dead_code)]
142pub fn merge_environments(
143    base: Environment,
144    extension: Environment,
145) -> Result<Environment, EnvError> {
146    let mut result = base;
147    for (_, ci) in extension.constant_infos() {
148        result.add_constant(ci.clone())?;
149    }
150    Ok(result)
151}
152/// Filter an environment to only include declarations satisfying a predicate.
153#[allow(dead_code)]
154pub fn filter_environment<F>(env: &Environment, predicate: F) -> Environment
155where
156    F: Fn(&Name) -> bool,
157{
158    let mut result = Environment::new();
159    for (name, ci) in env.constant_infos() {
160        if predicate(name) {
161            let _ = result.add_constant(ci.clone());
162        }
163    }
164    result
165}
166#[cfg(test)]
167mod extended_env_tests {
168    use super::*;
169    use crate::{
170        declaration::{AxiomVal, ConstantVal},
171        Level, Literal, ReducibilityHint,
172    };
173    fn mk_axiom(name: &str) -> crate::declaration::ConstantInfo {
174        crate::declaration::ConstantInfo::Axiom(AxiomVal {
175            common: ConstantVal {
176                name: Name::str(name),
177                level_params: vec![],
178                ty: Expr::Sort(Level::zero()),
179            },
180            is_unsafe: false,
181        })
182    }
183    #[test]
184    fn test_environment_view_axiom_names() {
185        let mut env = Environment::new();
186        env.add_constant(mk_axiom("ax1"))
187            .expect("value should be present");
188        env.add_constant(mk_axiom("ax2"))
189            .expect("value should be present");
190        let view = EnvironmentView::new(&env);
191        let names = view.axiom_names();
192        assert_eq!(names.len(), 2);
193    }
194    #[test]
195    fn test_environment_view_counts() {
196        let mut env = Environment::new();
197        env.add_constant(mk_axiom("a"))
198            .expect("value should be present");
199        let view = EnvironmentView::new(&env);
200        let counts = view.count_by_kind();
201        assert_eq!(counts.axioms, 1);
202        assert_eq!(counts.total(), 1);
203    }
204    #[test]
205    fn test_env_builder_empty() {
206        let builder = EnvironmentBuilder::new();
207        assert!(builder.is_empty());
208        let env = builder.build().expect("env should be present");
209        assert!(env.is_empty());
210    }
211    #[test]
212    fn test_env_builder_with_decls() {
213        let decl = Declaration::Axiom {
214            name: Name::str("foo"),
215            univ_params: vec![],
216            ty: Expr::Sort(Level::zero()),
217        };
218        let env = EnvironmentBuilder::new()
219            .add_decl(decl)
220            .build()
221            .expect("env should be present");
222        assert!(env.contains(&Name::str("foo")));
223    }
224    #[test]
225    fn test_env_builder_duplicate_error() {
226        let decl1 = Declaration::Axiom {
227            name: Name::str("dup"),
228            univ_params: vec![],
229            ty: Expr::Sort(Level::zero()),
230        };
231        let decl2 = Declaration::Axiom {
232            name: Name::str("dup"),
233            univ_params: vec![],
234            ty: Expr::Sort(Level::zero()),
235        };
236        let result = EnvironmentBuilder::new()
237            .add_decl(decl1)
238            .add_decl(decl2)
239            .build();
240        assert!(result.is_err());
241    }
242    #[test]
243    fn test_env_builder_with_constant() {
244        let env = EnvironmentBuilder::new()
245            .add_constant(mk_axiom("myax"))
246            .build()
247            .expect("value should be present");
248        assert!(env.contains(&Name::str("myax")));
249    }
250    #[test]
251    fn test_filter_environment() {
252        let mut env = Environment::new();
253        env.add_constant(mk_axiom("Nat.zero"))
254            .expect("value should be present");
255        env.add_constant(mk_axiom("Bool.true"))
256            .expect("value should be present");
257        let nat_only = filter_environment(&env, |name| name.to_string().starts_with("Nat"));
258        assert!(nat_only.contains(&Name::str("Nat.zero")));
259        assert!(!nat_only.contains(&Name::str("Bool.true")));
260    }
261    #[test]
262    fn test_env_error_display() {
263        let e = EnvError::DuplicateDeclaration(Name::str("foo"));
264        assert!(format!("{}", e).contains("foo"));
265        let e2 = EnvError::NotFound(Name::str("bar"));
266        assert!(format!("{}", e2).contains("bar"));
267    }
268    #[test]
269    fn test_env_kind_counts_total() {
270        let counts = EnvKindCounts {
271            axioms: 2,
272            inductives: 1,
273            constructors: 3,
274            recursors: 1,
275            definitions: 5,
276            theorems: 4,
277            other: 0,
278        };
279        assert_eq!(counts.total(), 16);
280    }
281    #[test]
282    fn test_merge_environments_disjoint() {
283        let mut env1 = Environment::new();
284        env1.add_constant(mk_axiom("a"))
285            .expect("value should be present");
286        let mut env2 = Environment::new();
287        env2.add_constant(mk_axiom("b"))
288            .expect("value should be present");
289        let merged = merge_environments(env1, env2).expect("merged should be present");
290        assert!(merged.contains(&Name::str("a")));
291        assert!(merged.contains(&Name::str("b")));
292    }
293    #[test]
294    fn test_merge_environments_conflict() {
295        let mut env1 = Environment::new();
296        env1.add_constant(mk_axiom("shared"))
297            .expect("value should be present");
298        let mut env2 = Environment::new();
299        env2.add_constant(mk_axiom("shared"))
300            .expect("value should be present");
301        let result = merge_environments(env1, env2);
302        assert!(result.is_err());
303    }
304    #[test]
305    fn test_env_builder_len() {
306        let b = EnvironmentBuilder::new()
307            .add_constant(mk_axiom("a"))
308            .add_constant(mk_axiom("b"));
309        assert_eq!(b.len(), 2);
310        assert!(!b.is_empty());
311    }
312    #[test]
313    fn test_definition_value_retrieval() {
314        let mut env = Environment::new();
315        let val = Expr::Lit(Literal::Nat(99));
316        env.add(Declaration::Definition {
317            name: Name::str("myval"),
318            univ_params: vec![],
319            ty: Expr::Sort(Level::zero()),
320            val: val.clone(),
321            hint: ReducibilityHint::Regular(1),
322        })
323        .expect("value should be present");
324        let (v, _) = env
325            .get_defn(&Name::str("myval"))
326            .expect("value should be present");
327        assert_eq!(v, val);
328    }
329}
330/// Compute detailed statistics about an environment.
331pub fn env_stats(env: &Environment) -> EnvStats {
332    let mut stats = EnvStats::default();
333    for (_, ci) in env.constant_infos() {
334        stats.total += 1;
335        if ci.is_axiom() {
336            stats.axioms += 1;
337        }
338        if ci.is_definition() {
339            stats.definitions += 1;
340        }
341        if ci.is_theorem() {
342            stats.theorems += 1;
343        }
344        if ci.is_inductive() {
345            stats.inductives += 1;
346        }
347        if ci.is_constructor() {
348            stats.constructors += 1;
349        }
350        if ci.is_recursor() {
351            stats.recursors += 1;
352        }
353    }
354    stats
355}
356/// Return all constants whose names start with `prefix`.
357pub fn constants_with_prefix<'a>(env: &'a Environment, prefix: &str) -> Vec<&'a Name> {
358    env.constant_names()
359        .filter(|n| n.to_string().starts_with(prefix))
360        .collect()
361}
362/// Check if the environment contains any constant from a given set of names.
363pub fn contains_any(env: &Environment, names: &[Name]) -> bool {
364    names.iter().any(|n| env.contains(n))
365}
366/// Return the subset of `names` that are present in `env`.
367pub fn present_names<'a>(env: &'a Environment, names: &[Name]) -> Vec<&'a Name> {
368    env.constant_names().filter(|n| names.contains(n)).collect()
369}
370/// Return the subset of `names` that are NOT present in `env`.
371pub fn missing_names(env: &Environment, names: &[Name]) -> Vec<Name> {
372    names.iter().filter(|n| !env.contains(n)).cloned().collect()
373}
374#[cfg(test)]
375mod env_new_tests {
376    use super::*;
377    use crate::{
378        declaration::{AxiomVal, ConstantVal},
379        Level,
380    };
381    fn mk_axiom_ci(name: &str) -> crate::declaration::ConstantInfo {
382        crate::declaration::ConstantInfo::Axiom(AxiomVal {
383            common: ConstantVal {
384                name: Name::str(name),
385                level_params: vec![],
386                ty: Expr::Sort(Level::zero()),
387            },
388            is_unsafe: false,
389        })
390    }
391    #[test]
392    fn test_env_snapshot_basic() {
393        let mut env = Environment::new();
394        env.add_constant(mk_axiom_ci("a"))
395            .expect("value should be present");
396        env.add_constant(mk_axiom_ci("b"))
397            .expect("value should be present");
398        let snap = EnvironmentSnapshot::from_env(&env);
399        assert_eq!(snap.len(), 2);
400        assert!(!snap.is_empty());
401    }
402    #[test]
403    fn test_env_snapshot_diff() {
404        let mut env = Environment::new();
405        env.add_constant(mk_axiom_ci("a"))
406            .expect("value should be present");
407        let snap1 = EnvironmentSnapshot::from_env(&env);
408        env.add_constant(mk_axiom_ci("b"))
409            .expect("value should be present");
410        let snap2 = EnvironmentSnapshot::from_env(&env);
411        let added = snap1.diff(&snap2);
412        assert_eq!(added.len(), 1);
413        assert_eq!(added[0], &Name::str("b"));
414    }
415    #[test]
416    fn test_env_stats_empty() {
417        let env = Environment::new();
418        let stats = env_stats(&env);
419        assert_eq!(stats.total, 0);
420    }
421    #[test]
422    fn test_env_stats_with_axioms() {
423        let mut env = Environment::new();
424        env.add_constant(mk_axiom_ci("x"))
425            .expect("value should be present");
426        env.add_constant(mk_axiom_ci("y"))
427            .expect("value should be present");
428        let stats = env_stats(&env);
429        assert_eq!(stats.total, 2);
430        assert_eq!(stats.axioms, 2);
431    }
432    #[test]
433    fn test_env_stats_display() {
434        let env = Environment::new();
435        let stats = env_stats(&env);
436        let s = format!("{}", stats);
437        assert!(s.contains("total=0"));
438    }
439    #[test]
440    fn test_constants_with_prefix() {
441        let mut env = Environment::new();
442        env.add_constant(mk_axiom_ci("Nat.zero"))
443            .expect("value should be present");
444        env.add_constant(mk_axiom_ci("Nat.succ"))
445            .expect("value should be present");
446        env.add_constant(mk_axiom_ci("Bool.true"))
447            .expect("value should be present");
448        let nat_consts = constants_with_prefix(&env, "Nat");
449        assert_eq!(nat_consts.len(), 2);
450    }
451    #[test]
452    fn test_contains_any() {
453        let mut env = Environment::new();
454        env.add_constant(mk_axiom_ci("foo"))
455            .expect("value should be present");
456        assert!(contains_any(&env, &[Name::str("foo"), Name::str("bar")]));
457        assert!(!contains_any(&env, &[Name::str("baz")]));
458    }
459    #[test]
460    fn test_missing_names() {
461        let mut env = Environment::new();
462        env.add_constant(mk_axiom_ci("a"))
463            .expect("value should be present");
464        let missing = missing_names(&env, &[Name::str("a"), Name::str("b"), Name::str("c")]);
465        assert_eq!(missing.len(), 2);
466        assert!(missing.contains(&Name::str("b")));
467        assert!(missing.contains(&Name::str("c")));
468    }
469    #[test]
470    fn test_present_names() {
471        let mut env = Environment::new();
472        env.add_constant(mk_axiom_ci("x"))
473            .expect("value should be present");
474        env.add_constant(mk_axiom_ci("y"))
475            .expect("value should be present");
476        let present = present_names(&env, &[Name::str("x"), Name::str("z")]);
477        assert_eq!(present.len(), 1);
478    }
479    #[test]
480    fn test_env_snapshot_empty() {
481        let env = Environment::new();
482        let snap = EnvironmentSnapshot::from_env(&env);
483        assert!(snap.is_empty());
484        assert_eq!(snap.len(), 0);
485    }
486    #[test]
487    fn test_env_snapshot_diff_no_change() {
488        let env = Environment::new();
489        let snap1 = EnvironmentSnapshot::from_env(&env);
490        let snap2 = EnvironmentSnapshot::from_env(&env);
491        let added = snap1.diff(&snap2);
492        assert!(added.is_empty());
493    }
494}
495#[cfg(test)]
496mod tests_padding_infra {
497    use super::*;
498    #[test]
499    fn test_stat_summary() {
500        let mut ss = StatSummary::new();
501        ss.record(10.0);
502        ss.record(20.0);
503        ss.record(30.0);
504        assert_eq!(ss.count(), 3);
505        assert!((ss.mean().expect("mean should succeed") - 20.0).abs() < 1e-9);
506        assert_eq!(ss.min().expect("min should succeed") as i64, 10);
507        assert_eq!(ss.max().expect("max should succeed") as i64, 30);
508    }
509    #[test]
510    fn test_transform_stat() {
511        let mut ts = TransformStat::new();
512        ts.record_before(100.0);
513        ts.record_after(80.0);
514        let ratio = ts.mean_ratio().expect("ratio should be present");
515        assert!((ratio - 0.8).abs() < 1e-9);
516    }
517    #[test]
518    fn test_small_map() {
519        let mut m: SmallMap<u32, &str> = SmallMap::new();
520        m.insert(3, "three");
521        m.insert(1, "one");
522        m.insert(2, "two");
523        assert_eq!(m.get(&2), Some(&"two"));
524        assert_eq!(m.len(), 3);
525        let keys = m.keys();
526        assert_eq!(*keys[0], 1);
527        assert_eq!(*keys[2], 3);
528    }
529    #[test]
530    fn test_label_set() {
531        let mut ls = LabelSet::new();
532        ls.add("foo");
533        ls.add("bar");
534        ls.add("foo");
535        assert_eq!(ls.count(), 2);
536        assert!(ls.has("bar"));
537        assert!(!ls.has("baz"));
538    }
539    #[test]
540    fn test_config_node() {
541        let mut root = ConfigNode::section("root");
542        let child = ConfigNode::leaf("key", "value");
543        root.add_child(child);
544        assert_eq!(root.num_children(), 1);
545    }
546    #[test]
547    fn test_versioned_record() {
548        let mut vr = VersionedRecord::new(0u32);
549        vr.update(1);
550        vr.update(2);
551        assert_eq!(*vr.current(), 2);
552        assert_eq!(vr.version(), 2);
553        assert!(vr.has_history());
554        assert_eq!(*vr.at_version(0).expect("value should be present"), 0);
555    }
556    #[test]
557    fn test_simple_dag() {
558        let mut dag = SimpleDag::new(4);
559        dag.add_edge(0, 1);
560        dag.add_edge(1, 2);
561        dag.add_edge(2, 3);
562        assert!(dag.can_reach(0, 3));
563        assert!(!dag.can_reach(3, 0));
564        let order = dag.topological_sort().expect("order should be present");
565        assert_eq!(order, vec![0, 1, 2, 3]);
566    }
567    #[test]
568    fn test_focus_stack() {
569        let mut fs: FocusStack<&str> = FocusStack::new();
570        fs.focus("a");
571        fs.focus("b");
572        assert_eq!(fs.current(), Some(&"b"));
573        assert_eq!(fs.depth(), 2);
574        fs.blur();
575        assert_eq!(fs.current(), Some(&"a"));
576    }
577}
578#[cfg(test)]
579mod tests_extra_iterators {
580    use super::*;
581    #[test]
582    fn test_window_iterator() {
583        let data = vec![1u32, 2, 3, 4, 5];
584        let windows: Vec<_> = WindowIterator::new(&data, 3).collect();
585        assert_eq!(windows.len(), 3);
586        assert_eq!(windows[0], &[1, 2, 3]);
587        assert_eq!(windows[2], &[3, 4, 5]);
588    }
589    #[test]
590    fn test_non_empty_vec() {
591        let mut nev = NonEmptyVec::singleton(10u32);
592        nev.push(20);
593        nev.push(30);
594        assert_eq!(nev.len(), 3);
595        assert_eq!(*nev.first(), 10);
596        assert_eq!(*nev.last(), 30);
597    }
598}
599#[cfg(test)]
600mod tests_padding2 {
601    use super::*;
602    #[test]
603    fn test_sliding_sum() {
604        let mut ss = SlidingSum::new(3);
605        ss.push(1.0);
606        ss.push(2.0);
607        ss.push(3.0);
608        assert!((ss.sum() - 6.0).abs() < 1e-9);
609        ss.push(4.0);
610        assert!((ss.sum() - 9.0).abs() < 1e-9);
611        assert_eq!(ss.count(), 3);
612    }
613    #[test]
614    fn test_path_buf() {
615        let mut pb = PathBuf::new();
616        pb.push("src");
617        pb.push("main");
618        assert_eq!(pb.as_str(), "src/main");
619        assert_eq!(pb.depth(), 2);
620        pb.pop();
621        assert_eq!(pb.as_str(), "src");
622    }
623    #[test]
624    fn test_string_pool() {
625        let mut pool = StringPool::new();
626        let s = pool.take();
627        assert!(s.is_empty());
628        pool.give("hello".to_string());
629        let s2 = pool.take();
630        assert!(s2.is_empty());
631        assert_eq!(pool.free_count(), 0);
632    }
633    #[test]
634    fn test_transitive_closure() {
635        let mut tc = TransitiveClosure::new(4);
636        tc.add_edge(0, 1);
637        tc.add_edge(1, 2);
638        tc.add_edge(2, 3);
639        assert!(tc.can_reach(0, 3));
640        assert!(!tc.can_reach(3, 0));
641        let r = tc.reachable_from(0);
642        assert_eq!(r.len(), 4);
643    }
644    #[test]
645    fn test_token_bucket() {
646        let mut tb = TokenBucket::new(100, 10);
647        assert_eq!(tb.available(), 100);
648        assert!(tb.try_consume(50));
649        assert_eq!(tb.available(), 50);
650        assert!(!tb.try_consume(60));
651        assert_eq!(tb.capacity(), 100);
652    }
653    #[test]
654    fn test_rewrite_rule_set() {
655        let mut rrs = RewriteRuleSet::new();
656        rrs.add(RewriteRule::unconditional(
657            "beta",
658            "App(Lam(x, b), v)",
659            "b[x:=v]",
660        ));
661        rrs.add(RewriteRule::conditional("comm", "a + b", "b + a"));
662        assert_eq!(rrs.len(), 2);
663        assert_eq!(rrs.unconditional_rules().len(), 1);
664        assert_eq!(rrs.conditional_rules().len(), 1);
665        assert!(rrs.get("beta").is_some());
666        let disp = rrs
667            .get("beta")
668            .expect("element at \'beta\' should exist")
669            .display();
670        assert!(disp.contains("→"));
671    }
672}
673#[cfg(test)]
674mod tests_padding3 {
675    use super::*;
676    #[test]
677    fn test_decision_node() {
678        let tree = DecisionNode::Branch {
679            key: "x".into(),
680            val: "1".into(),
681            yes_branch: Box::new(DecisionNode::Leaf("yes".into())),
682            no_branch: Box::new(DecisionNode::Leaf("no".into())),
683        };
684        let mut ctx = std::collections::HashMap::new();
685        ctx.insert("x".into(), "1".into());
686        assert_eq!(tree.evaluate(&ctx), "yes");
687        ctx.insert("x".into(), "2".into());
688        assert_eq!(tree.evaluate(&ctx), "no");
689        assert_eq!(tree.depth(), 1);
690    }
691    #[test]
692    fn test_flat_substitution() {
693        let mut sub = FlatSubstitution::new();
694        sub.add("foo", "bar");
695        sub.add("baz", "qux");
696        assert_eq!(sub.apply("foo and baz"), "bar and qux");
697        assert_eq!(sub.len(), 2);
698    }
699    #[test]
700    fn test_stopwatch() {
701        let mut sw = Stopwatch::start();
702        sw.split();
703        sw.split();
704        assert_eq!(sw.num_splits(), 2);
705        assert!(sw.elapsed_ms() >= 0.0);
706        for &s in sw.splits() {
707            assert!(s >= 0.0);
708        }
709    }
710    #[test]
711    fn test_either2() {
712        let e: Either2<i32, &str> = Either2::First(42);
713        assert!(e.is_first());
714        let mapped = e.map_first(|x| x * 2);
715        assert_eq!(mapped.first(), Some(84));
716        let e2: Either2<i32, &str> = Either2::Second("hello");
717        assert!(e2.is_second());
718        assert_eq!(e2.second(), Some("hello"));
719    }
720    #[test]
721    fn test_write_once() {
722        let wo: WriteOnce<u32> = WriteOnce::new();
723        assert!(!wo.is_written());
724        assert!(wo.write(42));
725        assert!(!wo.write(99));
726        assert_eq!(wo.read(), Some(42));
727    }
728    #[test]
729    fn test_sparse_vec() {
730        let mut sv: SparseVec<i32> = SparseVec::new(100);
731        sv.set(5, 10);
732        sv.set(50, 20);
733        assert_eq!(*sv.get(5), 10);
734        assert_eq!(*sv.get(50), 20);
735        assert_eq!(*sv.get(0), 0);
736        assert_eq!(sv.nnz(), 2);
737        sv.set(5, 0);
738        assert_eq!(sv.nnz(), 1);
739    }
740    #[test]
741    fn test_stack_calc() {
742        let mut calc = StackCalc::new();
743        calc.push(3);
744        calc.push(4);
745        calc.add();
746        assert_eq!(calc.peek(), Some(7));
747        calc.push(2);
748        calc.mul();
749        assert_eq!(calc.peek(), Some(14));
750    }
751}
752#[cfg(test)]
753mod tests_final_padding {
754    use super::*;
755    #[test]
756    fn test_min_heap() {
757        let mut h = MinHeap::new();
758        h.push(5u32);
759        h.push(1u32);
760        h.push(3u32);
761        assert_eq!(h.peek(), Some(&1));
762        assert_eq!(h.pop(), Some(1));
763        assert_eq!(h.pop(), Some(3));
764        assert_eq!(h.pop(), Some(5));
765        assert!(h.is_empty());
766    }
767    #[test]
768    fn test_prefix_counter() {
769        let mut pc = PrefixCounter::new();
770        pc.record("hello");
771        pc.record("help");
772        pc.record("world");
773        assert_eq!(pc.count_with_prefix("hel"), 2);
774        assert_eq!(pc.count_with_prefix("wor"), 1);
775        assert_eq!(pc.count_with_prefix("xyz"), 0);
776    }
777    #[test]
778    fn test_fixture() {
779        let mut f = Fixture::new();
780        f.set("key1", "val1");
781        f.set("key2", "val2");
782        assert_eq!(f.get("key1"), Some("val1"));
783        assert_eq!(f.get("key3"), None);
784        assert_eq!(f.len(), 2);
785    }
786}