1use crate::declaration::{ConstantInfo, ConstantVal, DefinitionSafety, DefinitionVal};
6use crate::reduce::ReducibilityHint;
7use crate::{Expr, Level, Name};
8use std::collections::HashMap;
9
10#[allow(dead_code)]
12#[allow(missing_docs)]
13pub struct RewriteRule {
14 pub name: String,
16 pub lhs: String,
18 pub rhs: String,
20 pub conditional: bool,
22}
23#[allow(dead_code)]
24impl RewriteRule {
25 pub fn unconditional(
27 name: impl Into<String>,
28 lhs: impl Into<String>,
29 rhs: impl Into<String>,
30 ) -> Self {
31 Self {
32 name: name.into(),
33 lhs: lhs.into(),
34 rhs: rhs.into(),
35 conditional: false,
36 }
37 }
38 pub fn conditional(
40 name: impl Into<String>,
41 lhs: impl Into<String>,
42 rhs: impl Into<String>,
43 ) -> Self {
44 Self {
45 name: name.into(),
46 lhs: lhs.into(),
47 rhs: rhs.into(),
48 conditional: true,
49 }
50 }
51 pub fn display(&self) -> String {
53 format!("{}: {} → {}", self.name, self.lhs, self.rhs)
54 }
55}
56#[allow(dead_code)]
58pub struct RewriteRuleSet {
59 rules: Vec<RewriteRule>,
60}
61#[allow(dead_code)]
62impl RewriteRuleSet {
63 pub fn new() -> Self {
65 Self { rules: Vec::new() }
66 }
67 pub fn add(&mut self, rule: RewriteRule) {
69 self.rules.push(rule);
70 }
71 pub fn len(&self) -> usize {
73 self.rules.len()
74 }
75 pub fn is_empty(&self) -> bool {
77 self.rules.is_empty()
78 }
79 pub fn conditional_rules(&self) -> Vec<&RewriteRule> {
81 self.rules.iter().filter(|r| r.conditional).collect()
82 }
83 pub fn unconditional_rules(&self) -> Vec<&RewriteRule> {
85 self.rules.iter().filter(|r| !r.conditional).collect()
86 }
87 pub fn get(&self, name: &str) -> Option<&RewriteRule> {
89 self.rules.iter().find(|r| r.name == name)
90 }
91}
92#[allow(dead_code)]
94pub struct VersionedRecord<T: Clone> {
95 earlier: Vec<T>,
97 current: T,
99}
100#[allow(dead_code)]
101impl<T: Clone> VersionedRecord<T> {
102 pub fn new(initial: T) -> Self {
104 Self {
105 earlier: Vec::new(),
106 current: initial,
107 }
108 }
109 pub fn update(&mut self, val: T) {
111 let previous = std::mem::replace(&mut self.current, val);
112 self.earlier.push(previous);
113 }
114 pub fn current(&self) -> &T {
116 &self.current
117 }
118 pub fn at_version(&self, n: usize) -> Option<&T> {
120 match self.earlier.get(n) {
121 Some(value) => Some(value),
122 None if n == self.earlier.len() => Some(&self.current),
123 None => None,
124 }
125 }
126 pub fn version(&self) -> usize {
128 self.earlier.len()
129 }
130 pub fn has_history(&self) -> bool {
132 !self.earlier.is_empty()
133 }
134}
135#[allow(dead_code)]
137pub struct FocusStack<T> {
138 items: Vec<T>,
139}
140#[allow(dead_code)]
141impl<T> FocusStack<T> {
142 pub fn new() -> Self {
144 Self { items: Vec::new() }
145 }
146 pub fn focus(&mut self, item: T) {
148 self.items.push(item);
149 }
150 pub fn blur(&mut self) -> Option<T> {
152 self.items.pop()
153 }
154 pub fn current(&self) -> Option<&T> {
156 self.items.last()
157 }
158 pub fn depth(&self) -> usize {
160 self.items.len()
161 }
162 pub fn is_empty(&self) -> bool {
164 self.items.is_empty()
165 }
166}
167#[allow(dead_code)]
169pub struct SparseVec<T: Default + Clone + PartialEq> {
170 entries: std::collections::HashMap<usize, T>,
171 default_: T,
172 logical_len: usize,
173}
174#[allow(dead_code)]
175impl<T: Default + Clone + PartialEq> SparseVec<T> {
176 pub fn new(len: usize) -> Self {
178 Self {
179 entries: std::collections::HashMap::new(),
180 default_: T::default(),
181 logical_len: len,
182 }
183 }
184 pub fn set(&mut self, idx: usize, val: T) {
186 if val == self.default_ {
187 self.entries.remove(&idx);
188 } else {
189 self.entries.insert(idx, val);
190 }
191 }
192 pub fn get(&self, idx: usize) -> &T {
194 self.entries.get(&idx).unwrap_or(&self.default_)
195 }
196 pub fn len(&self) -> usize {
198 self.logical_len
199 }
200 pub fn is_empty(&self) -> bool {
202 self.len() == 0
203 }
204 pub fn nnz(&self) -> usize {
206 self.entries.len()
207 }
208}
209#[allow(dead_code)]
211pub struct WindowIterator<'a, T> {
212 pub(super) data: &'a [T],
213 pub(super) pos: usize,
214 pub(super) window: usize,
215}
216#[allow(dead_code)]
217impl<'a, T> WindowIterator<'a, T> {
218 pub fn new(data: &'a [T], window: usize) -> Self {
220 Self {
221 data,
222 pos: 0,
223 window,
224 }
225 }
226}
227#[derive(Clone, Debug, Default)]
229pub struct Environment {
230 declarations: HashMap<Name, Declaration>,
232 constants: HashMap<Name, ConstantInfo>,
234 quot_initialized: bool,
238 literal_primitives: bool,
241}
242impl Environment {
243 pub fn new() -> Self {
245 Self {
246 declarations: HashMap::new(),
247 constants: HashMap::new(),
248 quot_initialized: false,
249 literal_primitives: false,
250 }
251 }
252 pub fn add(&mut self, decl: Declaration) -> Result<(), EnvError> {
256 let name = decl.name().clone();
257 if self.declarations.contains_key(&name) || self.constants.contains_key(&name) {
258 return Err(EnvError::DuplicateDeclaration(name));
259 }
260 let ci = decl.to_constant_info();
261 self.constants.insert(name.clone(), ci);
262 self.declarations.insert(name, decl);
263 Ok(())
264 }
265 pub fn add_constant(&mut self, ci: ConstantInfo) -> Result<(), EnvError> {
273 if ci.is_quotient() {
274 return Err(EnvError::InvalidQuotient(
275 "quotient constants may only be added via Environment::add_quot".to_string(),
276 ));
277 }
278 let name = ci.name().clone();
279 if self.declarations.contains_key(&name) || self.constants.contains_key(&name) {
280 return Err(EnvError::DuplicateDeclaration(name));
281 }
282 self.constants.insert(name, ci);
283 Ok(())
284 }
285 pub fn add_constants(&mut self, cis: Vec<ConstantInfo>) -> Result<(), EnvError> {
296 for (i, ci) in cis.iter().enumerate() {
297 if ci.is_quotient() {
298 return Err(EnvError::InvalidQuotient(
299 "quotient constants may only be added via Environment::add_quot".to_string(),
300 ));
301 }
302 let name = ci.name();
303 if self.contains(name) || cis[..i].iter().any(|earlier| earlier.name() == name) {
304 return Err(EnvError::DuplicateDeclaration(name.clone()));
305 }
306 }
307 for ci in cis {
308 self.constants.insert(ci.name().clone(), ci);
309 }
310 Ok(())
311 }
312 pub(crate) fn remove_constants(&mut self, names: &[Name]) {
319 for name in names {
320 self.constants.remove(name);
321 }
322 }
323 pub fn quot_initialized(&self) -> bool {
325 self.quot_initialized
326 }
327 pub fn has_literal_primitives(&self) -> bool {
339 self.literal_primitives
340 }
341 pub(crate) fn declare_literal_primitives(&mut self) {
347 self.literal_primitives = true;
348 }
349 pub(crate) fn insert_quotient(&mut self, ci: ConstantInfo) {
355 debug_assert!(ci.is_quotient());
356 let name = ci.name().clone();
357 self.constants.insert(name, ci);
358 }
359 pub(crate) fn set_quot_initialized(&mut self) {
361 self.quot_initialized = true;
362 }
363 pub fn get(&self, name: &Name) -> Option<&Declaration> {
365 self.declarations.get(name)
366 }
367 pub fn find(&self, name: &Name) -> Option<&ConstantInfo> {
369 self.constants.get(name)
370 }
371 pub fn contains(&self, name: &Name) -> bool {
373 self.declarations.contains_key(name) || self.constants.contains_key(name)
374 }
375 pub fn len(&self) -> usize {
377 self.constants.len().max(self.declarations.len())
378 }
379 pub fn is_empty(&self) -> bool {
381 self.declarations.is_empty() && self.constants.is_empty()
382 }
383 pub fn get_defn(&self, name: &Name) -> Option<(Expr, ReducibilityHint)> {
385 if let Some(ci) = self.constants.get(name) {
386 if let Some(val) = ci.value() {
387 return Some((val.clone(), ci.reducibility_hint()));
388 }
389 }
390 self.declarations.get(name).and_then(|decl| {
391 decl.value()
392 .map(|val| (val.clone(), decl.reducibility_hint()))
393 })
394 }
395 pub fn is_inductive(&self, name: &Name) -> bool {
397 self.constants.get(name).is_some_and(|ci| ci.is_inductive())
398 }
399 pub fn is_constructor(&self, name: &Name) -> bool {
401 self.constants
402 .get(name)
403 .is_some_and(|ci| ci.is_constructor())
404 }
405 pub fn is_recursor(&self, name: &Name) -> bool {
407 self.constants.get(name).is_some_and(|ci| ci.is_recursor())
408 }
409 pub fn is_quotient(&self, name: &Name) -> bool {
411 self.constants.get(name).is_some_and(|ci| ci.is_quotient())
412 }
413 pub fn is_structure_like(&self, name: &Name) -> bool {
415 self.constants
416 .get(name)
417 .is_some_and(|ci| ci.is_structure_like())
418 }
419 pub fn get_inductive_val(&self, name: &Name) -> Option<&crate::declaration::InductiveVal> {
421 self.constants
422 .get(name)
423 .and_then(|ci| ci.to_inductive_val())
424 }
425 pub fn get_constructor_val(&self, name: &Name) -> Option<&crate::declaration::ConstructorVal> {
427 self.constants
428 .get(name)
429 .and_then(|ci| ci.to_constructor_val())
430 }
431 pub fn get_recursor_val(&self, name: &Name) -> Option<&crate::declaration::RecursorVal> {
433 self.constants.get(name).and_then(|ci| ci.to_recursor_val())
434 }
435 pub fn get_quotient_val(&self, name: &Name) -> Option<&crate::declaration::QuotVal> {
437 self.constants.get(name).and_then(|ci| ci.to_quotient_val())
438 }
439 pub fn get_type(&self, name: &Name) -> Option<&Expr> {
441 self.constants.get(name).map(|ci| ci.ty())
442 }
443 pub fn get_level_params(&self, name: &Name) -> Option<&[Name]> {
445 self.constants.get(name).map(|ci| ci.level_params())
446 }
447 pub fn instantiate_const_type(&self, name: &Name, levels: &[Level]) -> Option<Expr> {
449 let ci = self.constants.get(name)?;
450 let params = ci.level_params();
451 if params.is_empty() || levels.is_empty() {
452 return Some(ci.ty().clone());
453 }
454 Some(crate::declaration::instantiate_level_params(
455 ci.ty(),
456 params,
457 levels,
458 ))
459 }
460 pub fn constant_names(&self) -> impl Iterator<Item = &Name> {
462 self.constants.keys()
463 }
464 pub fn constant_infos(&self) -> impl Iterator<Item = (&Name, &ConstantInfo)> {
466 self.constants.iter()
467 }
468}
469#[allow(dead_code)]
471#[derive(Debug, Clone, Default)]
472pub struct EnvKindCounts {
473 pub axioms: usize,
475 pub inductives: usize,
477 pub constructors: usize,
479 pub recursors: usize,
481 pub definitions: usize,
483 pub theorems: usize,
485 pub other: usize,
487}
488impl EnvKindCounts {
489 #[allow(dead_code)]
491 pub fn total(&self) -> usize {
492 self.axioms
493 + self.inductives
494 + self.constructors
495 + self.recursors
496 + self.definitions
497 + self.theorems
498 + self.other
499 }
500}
501#[derive(Clone, Debug)]
503pub enum Declaration {
504 Axiom {
506 name: Name,
508 univ_params: Vec<Name>,
510 ty: Expr,
512 },
513 Definition {
515 name: Name,
517 univ_params: Vec<Name>,
519 ty: Expr,
521 val: Expr,
523 hint: ReducibilityHint,
525 },
526 Theorem {
528 name: Name,
530 univ_params: Vec<Name>,
532 ty: Expr,
534 val: Expr,
536 },
537 Opaque {
539 name: Name,
541 univ_params: Vec<Name>,
543 ty: Expr,
545 val: Expr,
547 },
548}
549impl Declaration {
550 pub fn name(&self) -> &Name {
552 match self {
553 Declaration::Axiom { name, .. }
554 | Declaration::Definition { name, .. }
555 | Declaration::Theorem { name, .. }
556 | Declaration::Opaque { name, .. } => name,
557 }
558 }
559 pub fn ty(&self) -> &Expr {
561 match self {
562 Declaration::Axiom { ty, .. }
563 | Declaration::Definition { ty, .. }
564 | Declaration::Theorem { ty, .. }
565 | Declaration::Opaque { ty, .. } => ty,
566 }
567 }
568 pub fn univ_params(&self) -> &[Name] {
570 match self {
571 Declaration::Axiom { univ_params, .. }
572 | Declaration::Definition { univ_params, .. }
573 | Declaration::Theorem { univ_params, .. }
574 | Declaration::Opaque { univ_params, .. } => univ_params,
575 }
576 }
577 pub fn value(&self) -> Option<&Expr> {
579 match self {
580 Declaration::Axiom { .. } => None,
581 Declaration::Definition { val, .. }
582 | Declaration::Theorem { val, .. }
583 | Declaration::Opaque { val, .. } => Some(val),
584 }
585 }
586 pub fn reducibility_hint(&self) -> ReducibilityHint {
588 match self {
589 Declaration::Axiom { .. } => ReducibilityHint::Opaque,
590 Declaration::Definition { hint, .. } => *hint,
591 Declaration::Theorem { .. } | Declaration::Opaque { .. } => ReducibilityHint::Opaque,
592 }
593 }
594 pub fn to_constant_info(&self) -> ConstantInfo {
596 match self {
597 Declaration::Axiom {
598 name,
599 univ_params,
600 ty,
601 } => ConstantInfo::Axiom(crate::declaration::AxiomVal {
602 common: ConstantVal {
603 name: name.clone(),
604 level_params: univ_params.clone(),
605 ty: ty.clone(),
606 },
607 is_unsafe: false,
608 }),
609 Declaration::Definition {
610 name,
611 univ_params,
612 ty,
613 val,
614 hint,
615 } => ConstantInfo::Definition(DefinitionVal {
616 common: ConstantVal {
617 name: name.clone(),
618 level_params: univ_params.clone(),
619 ty: ty.clone(),
620 },
621 value: val.clone(),
622 hints: *hint,
623 safety: DefinitionSafety::Safe,
624 all: vec![name.clone()],
625 }),
626 Declaration::Theorem {
627 name,
628 univ_params,
629 ty,
630 val,
631 } => ConstantInfo::Theorem(crate::declaration::TheoremVal {
632 common: ConstantVal {
633 name: name.clone(),
634 level_params: univ_params.clone(),
635 ty: ty.clone(),
636 },
637 value: val.clone(),
638 all: vec![name.clone()],
639 }),
640 Declaration::Opaque {
641 name,
642 univ_params,
643 ty,
644 val,
645 } => ConstantInfo::Opaque(crate::declaration::OpaqueVal {
646 common: ConstantVal {
647 name: name.clone(),
648 level_params: univ_params.clone(),
649 ty: ty.clone(),
650 },
651 value: val.clone(),
652 is_unsafe: false,
653 all: vec![name.clone()],
654 }),
655 }
656 }
657}
658#[allow(dead_code)]
660pub struct RawFnPtr {
661 ptr: usize,
663 arity: usize,
664 name: String,
665}
666#[allow(dead_code)]
667impl RawFnPtr {
668 pub fn new(ptr: usize, arity: usize, name: impl Into<String>) -> Self {
670 Self {
671 ptr,
672 arity,
673 name: name.into(),
674 }
675 }
676 pub fn arity(&self) -> usize {
678 self.arity
679 }
680 pub fn name(&self) -> &str {
682 &self.name
683 }
684 pub fn raw(&self) -> usize {
686 self.ptr
687 }
688}
689#[allow(dead_code)]
691pub struct PrefixCounter {
692 children: std::collections::HashMap<char, PrefixCounter>,
693 count: usize,
694}
695#[allow(dead_code)]
696impl PrefixCounter {
697 pub fn new() -> Self {
699 Self {
700 children: std::collections::HashMap::new(),
701 count: 0,
702 }
703 }
704 pub fn record(&mut self, s: &str) {
706 self.count += 1;
707 let mut node = self;
708 for c in s.chars() {
709 node = node.children.entry(c).or_default();
710 node.count += 1;
711 }
712 }
713 pub fn count_with_prefix(&self, prefix: &str) -> usize {
715 let mut node = self;
716 for c in prefix.chars() {
717 match node.children.get(&c) {
718 Some(n) => node = n,
719 None => return 0,
720 }
721 }
722 node.count
723 }
724}
725#[allow(dead_code)]
727pub struct Fixture {
728 data: std::collections::HashMap<String, String>,
729}
730#[allow(dead_code)]
731impl Fixture {
732 pub fn new() -> Self {
734 Self {
735 data: std::collections::HashMap::new(),
736 }
737 }
738 pub fn set(&mut self, key: impl Into<String>, val: impl Into<String>) {
740 self.data.insert(key.into(), val.into());
741 }
742 pub fn get(&self, key: &str) -> Option<&str> {
744 self.data.get(key).map(|s| s.as_str())
745 }
746 pub fn len(&self) -> usize {
748 self.data.len()
749 }
750 pub fn is_empty(&self) -> bool {
752 self.len() == 0
753 }
754}
755#[allow(dead_code)]
757pub struct EnvironmentView<'a> {
758 env: &'a Environment,
759}
760impl<'a> EnvironmentView<'a> {
761 #[allow(dead_code)]
763 pub fn new(env: &'a Environment) -> Self {
764 Self { env }
765 }
766 #[allow(dead_code)]
768 pub fn axiom_names(&self) -> Vec<&Name> {
769 self.env
770 .constant_infos()
771 .filter_map(|(name, ci)| if ci.is_axiom() { Some(name) } else { None })
772 .collect()
773 }
774 #[allow(dead_code)]
776 pub fn inductive_names(&self) -> Vec<&Name> {
777 self.env
778 .constant_infos()
779 .filter_map(|(name, ci)| if ci.is_inductive() { Some(name) } else { None })
780 .collect()
781 }
782 #[allow(dead_code)]
784 pub fn constructor_names(&self) -> Vec<&Name> {
785 self.env
786 .constant_infos()
787 .filter_map(|(name, ci)| {
788 if ci.is_constructor() {
789 Some(name)
790 } else {
791 None
792 }
793 })
794 .collect()
795 }
796 #[allow(dead_code)]
798 pub fn definition_names(&self) -> Vec<&Name> {
799 self.env
800 .constant_infos()
801 .filter_map(|(name, ci)| if ci.is_definition() { Some(name) } else { None })
802 .collect()
803 }
804 #[allow(dead_code)]
806 pub fn count_by_kind(&self) -> EnvKindCounts {
807 let mut counts = EnvKindCounts::default();
808 for (_, ci) in self.env.constant_infos() {
809 if ci.is_axiom() {
810 counts.axioms += 1;
811 } else if ci.is_inductive() {
812 counts.inductives += 1;
813 } else if ci.is_constructor() {
814 counts.constructors += 1;
815 } else if ci.is_recursor() {
816 counts.recursors += 1;
817 } else if ci.is_definition() {
818 counts.definitions += 1;
819 } else if ci.is_theorem() {
820 counts.theorems += 1;
821 } else {
822 counts.other += 1;
823 }
824 }
825 counts
826 }
827}
828#[allow(dead_code)]
830pub struct LabelSet {
831 labels: Vec<String>,
832}
833#[allow(dead_code)]
834impl LabelSet {
835 pub fn new() -> Self {
837 Self { labels: Vec::new() }
838 }
839 pub fn add(&mut self, label: impl Into<String>) {
841 let s = label.into();
842 if !self.labels.contains(&s) {
843 self.labels.push(s);
844 }
845 }
846 pub fn has(&self, label: &str) -> bool {
848 self.labels.iter().any(|l| l == label)
849 }
850 pub fn count(&self) -> usize {
852 self.labels.len()
853 }
854 pub fn all(&self) -> &[String] {
856 &self.labels
857 }
858}
859#[derive(Clone, Debug, Default)]
861pub struct EnvStats {
862 pub total: usize,
864 pub axioms: usize,
866 pub definitions: usize,
868 pub theorems: usize,
870 pub inductives: usize,
872 pub constructors: usize,
874 pub recursors: usize,
876}
877#[allow(dead_code)]
879pub struct StatSummary {
880 count: u64,
881 sum: f64,
882 min: f64,
883 max: f64,
884}
885#[allow(dead_code)]
886impl StatSummary {
887 pub fn new() -> Self {
889 Self {
890 count: 0,
891 sum: 0.0,
892 min: f64::INFINITY,
893 max: f64::NEG_INFINITY,
894 }
895 }
896 pub fn record(&mut self, val: f64) {
898 self.count += 1;
899 self.sum += val;
900 if val < self.min {
901 self.min = val;
902 }
903 if val > self.max {
904 self.max = val;
905 }
906 }
907 pub fn mean(&self) -> Option<f64> {
909 if self.count == 0 {
910 None
911 } else {
912 Some(self.sum / self.count as f64)
913 }
914 }
915 pub fn min(&self) -> Option<f64> {
917 if self.count == 0 {
918 None
919 } else {
920 Some(self.min)
921 }
922 }
923 pub fn max(&self) -> Option<f64> {
925 if self.count == 0 {
926 None
927 } else {
928 Some(self.max)
929 }
930 }
931 pub fn count(&self) -> u64 {
933 self.count
934 }
935}
936#[allow(dead_code)]
938pub struct NonEmptyVec<T> {
939 head: T,
940 tail: Vec<T>,
941}
942#[allow(dead_code)]
943impl<T> NonEmptyVec<T> {
944 pub fn singleton(val: T) -> Self {
946 Self {
947 head: val,
948 tail: Vec::new(),
949 }
950 }
951 pub fn push(&mut self, val: T) {
953 self.tail.push(val);
954 }
955 pub fn first(&self) -> &T {
957 &self.head
958 }
959 pub fn last(&self) -> &T {
961 self.tail.last().unwrap_or(&self.head)
962 }
963 pub fn len(&self) -> usize {
965 1 + self.tail.len()
966 }
967 pub fn is_empty(&self) -> bool {
969 self.len() == 0
970 }
971 pub fn to_vec(&self) -> Vec<&T> {
973 let mut v = vec![&self.head];
974 v.extend(self.tail.iter());
975 v
976 }
977}
978#[allow(dead_code)]
980pub struct Stopwatch {
981 start: crate::wall_clock::Instant,
982 splits: Vec<f64>,
983}
984#[allow(dead_code)]
985impl Stopwatch {
986 pub fn start() -> Self {
988 Self {
989 start: crate::wall_clock::Instant::now(),
990 splits: Vec::new(),
991 }
992 }
993 pub fn split(&mut self) {
995 self.splits.push(self.elapsed_ms());
996 }
997 pub fn elapsed_ms(&self) -> f64 {
999 self.start.elapsed().as_secs_f64() * 1000.0
1000 }
1001 pub fn splits(&self) -> &[f64] {
1003 &self.splits
1004 }
1005 pub fn num_splits(&self) -> usize {
1007 self.splits.len()
1008 }
1009}
1010#[allow(dead_code)]
1012pub struct TokenBucket {
1013 capacity: u64,
1014 tokens: u64,
1015 refill_per_ms: u64,
1016 last_refill: crate::wall_clock::Instant,
1017}
1018#[allow(dead_code)]
1019impl TokenBucket {
1020 pub fn new(capacity: u64, refill_per_ms: u64) -> Self {
1022 Self {
1023 capacity,
1024 tokens: capacity,
1025 refill_per_ms,
1026 last_refill: crate::wall_clock::Instant::now(),
1027 }
1028 }
1029 pub fn try_consume(&mut self, n: u64) -> bool {
1031 self.refill();
1032 if self.tokens >= n {
1033 self.tokens -= n;
1034 true
1035 } else {
1036 false
1037 }
1038 }
1039 fn refill(&mut self) {
1040 let now = crate::wall_clock::Instant::now();
1041 let elapsed_ms = now.duration_since(self.last_refill).as_millis() as u64;
1042 if elapsed_ms > 0 {
1043 let new_tokens = elapsed_ms * self.refill_per_ms;
1044 self.tokens = (self.tokens + new_tokens).min(self.capacity);
1045 self.last_refill = now;
1046 }
1047 }
1048 pub fn available(&self) -> u64 {
1050 self.tokens
1051 }
1052 pub fn capacity(&self) -> u64 {
1054 self.capacity
1055 }
1056}
1057#[allow(dead_code)]
1059#[derive(Default)]
1060pub struct EnvironmentBuilder {
1061 declarations: Vec<Declaration>,
1062 constants: Vec<crate::declaration::ConstantInfo>,
1063}
1064impl EnvironmentBuilder {
1065 #[allow(dead_code)]
1067 pub fn new() -> Self {
1068 Self::default()
1069 }
1070 #[allow(dead_code)]
1072 pub fn add_decl(mut self, decl: Declaration) -> Self {
1073 self.declarations.push(decl);
1074 self
1075 }
1076 #[allow(dead_code)]
1078 pub fn add_constant(mut self, ci: crate::declaration::ConstantInfo) -> Self {
1079 self.constants.push(ci);
1080 self
1081 }
1082 #[allow(dead_code)]
1084 pub fn build(self) -> Result<Environment, EnvError> {
1085 let mut env = Environment::new();
1086 for decl in self.declarations {
1087 env.add(decl)?;
1088 }
1089 for ci in self.constants {
1090 env.add_constant(ci)?;
1091 }
1092 Ok(env)
1093 }
1094 #[allow(dead_code)]
1096 pub fn len(&self) -> usize {
1097 self.declarations.len() + self.constants.len()
1098 }
1099 #[allow(dead_code)]
1101 pub fn is_empty(&self) -> bool {
1102 self.declarations.is_empty() && self.constants.is_empty()
1103 }
1104}
1105#[allow(dead_code)]
1107#[allow(missing_docs)]
1108pub enum DecisionNode {
1109 Leaf(String),
1111 Branch {
1113 key: String,
1114 val: String,
1115 yes_branch: Box<DecisionNode>,
1116 no_branch: Box<DecisionNode>,
1117 },
1118}
1119#[allow(dead_code)]
1120impl DecisionNode {
1121 pub fn evaluate(&self, ctx: &std::collections::HashMap<String, String>) -> &str {
1123 match self {
1124 DecisionNode::Leaf(action) => action.as_str(),
1125 DecisionNode::Branch {
1126 key,
1127 val,
1128 yes_branch,
1129 no_branch,
1130 } => {
1131 let actual = ctx.get(key).map(|s| s.as_str()).unwrap_or("");
1132 if actual == val.as_str() {
1133 yes_branch.evaluate(ctx)
1134 } else {
1135 no_branch.evaluate(ctx)
1136 }
1137 }
1138 }
1139 }
1140 pub fn depth(&self) -> usize {
1142 match self {
1143 DecisionNode::Leaf(_) => 0,
1144 DecisionNode::Branch {
1145 yes_branch,
1146 no_branch,
1147 ..
1148 } => 1 + yes_branch.depth().max(no_branch.depth()),
1149 }
1150 }
1151}
1152#[allow(dead_code)]
1154pub struct StringPool {
1155 free: Vec<String>,
1156}
1157#[allow(dead_code)]
1158impl StringPool {
1159 pub fn new() -> Self {
1161 Self { free: Vec::new() }
1162 }
1163 pub fn take(&mut self) -> String {
1165 self.free.pop().unwrap_or_default()
1166 }
1167 pub fn give(&mut self, mut s: String) {
1169 s.clear();
1170 self.free.push(s);
1171 }
1172 pub fn free_count(&self) -> usize {
1174 self.free.len()
1175 }
1176}
1177#[allow(dead_code)]
1179pub enum Either2<A, B> {
1180 First(A),
1182 Second(B),
1184}
1185#[allow(dead_code)]
1186impl<A, B> Either2<A, B> {
1187 pub fn is_first(&self) -> bool {
1189 matches!(self, Either2::First(_))
1190 }
1191 pub fn is_second(&self) -> bool {
1193 matches!(self, Either2::Second(_))
1194 }
1195 pub fn first(self) -> Option<A> {
1197 match self {
1198 Either2::First(a) => Some(a),
1199 _ => None,
1200 }
1201 }
1202 pub fn second(self) -> Option<B> {
1204 match self {
1205 Either2::Second(b) => Some(b),
1206 _ => None,
1207 }
1208 }
1209 pub fn map_first<C, F: FnOnce(A) -> C>(self, f: F) -> Either2<C, B> {
1211 match self {
1212 Either2::First(a) => Either2::First(f(a)),
1213 Either2::Second(b) => Either2::Second(b),
1214 }
1215 }
1216}
1217#[allow(dead_code)]
1219pub struct StackCalc {
1220 stack: Vec<i64>,
1221}
1222#[allow(dead_code)]
1223impl StackCalc {
1224 pub fn new() -> Self {
1226 Self { stack: Vec::new() }
1227 }
1228 pub fn push(&mut self, n: i64) {
1230 self.stack.push(n);
1231 }
1232 fn apply_binary(&mut self, op: impl FnOnce(i64, i64) -> i64) -> Option<i64> {
1236 let (rest_len, a, b) = match self.stack[..] {
1237 [ref rest @ .., a, b] => (rest.len(), a, b),
1238 _ => return None,
1239 };
1240 let value = op(a, b);
1241 self.stack.truncate(rest_len);
1242 self.stack.push(value);
1243 Some(value)
1244 }
1245 pub fn add(&mut self) -> Option<i64> {
1249 self.apply_binary(|a, b| a + b)
1250 }
1251 pub fn sub(&mut self) -> Option<i64> {
1255 self.apply_binary(|a, b| a - b)
1256 }
1257 pub fn mul(&mut self) -> Option<i64> {
1261 self.apply_binary(|a, b| a * b)
1262 }
1263 pub fn peek(&self) -> Option<i64> {
1265 self.stack.last().copied()
1266 }
1267 pub fn depth(&self) -> usize {
1269 self.stack.len()
1270 }
1271}
1272#[allow(dead_code)]
1274pub struct SlidingSum {
1275 window: Vec<f64>,
1276 capacity: usize,
1277 pos: usize,
1278 sum: f64,
1279 count: usize,
1280}
1281#[allow(dead_code)]
1282impl SlidingSum {
1283 pub fn new(capacity: usize) -> Self {
1285 Self {
1286 window: vec![0.0; capacity],
1287 capacity,
1288 pos: 0,
1289 sum: 0.0,
1290 count: 0,
1291 }
1292 }
1293 pub fn push(&mut self, val: f64) {
1295 let oldest = self.window[self.pos];
1296 self.sum -= oldest;
1297 self.sum += val;
1298 self.window[self.pos] = val;
1299 self.pos = (self.pos + 1) % self.capacity;
1300 if self.count < self.capacity {
1301 self.count += 1;
1302 }
1303 }
1304 pub fn sum(&self) -> f64 {
1306 self.sum
1307 }
1308 pub fn mean(&self) -> Option<f64> {
1310 if self.count == 0 {
1311 None
1312 } else {
1313 Some(self.sum / self.count as f64)
1314 }
1315 }
1316 pub fn count(&self) -> usize {
1318 self.count
1319 }
1320}
1321#[allow(dead_code)]
1323pub struct PathBuf {
1324 components: Vec<String>,
1325}
1326#[allow(dead_code)]
1327impl PathBuf {
1328 pub fn new() -> Self {
1330 Self {
1331 components: Vec::new(),
1332 }
1333 }
1334 pub fn push(&mut self, comp: impl Into<String>) {
1336 self.components.push(comp.into());
1337 }
1338 pub fn pop(&mut self) {
1340 self.components.pop();
1341 }
1342 pub fn as_str(&self) -> String {
1344 self.components.join("/")
1345 }
1346 pub fn depth(&self) -> usize {
1348 self.components.len()
1349 }
1350 pub fn clear(&mut self) {
1352 self.components.clear();
1353 }
1354}
1355#[allow(dead_code)]
1357pub struct FlatSubstitution {
1358 pairs: Vec<(String, String)>,
1359}
1360#[allow(dead_code)]
1361impl FlatSubstitution {
1362 pub fn new() -> Self {
1364 Self { pairs: Vec::new() }
1365 }
1366 pub fn add(&mut self, from: impl Into<String>, to: impl Into<String>) {
1368 self.pairs.push((from.into(), to.into()));
1369 }
1370 pub fn apply(&self, s: &str) -> String {
1372 let mut result = s.to_string();
1373 for (from, to) in &self.pairs {
1374 result = result.replace(from.as_str(), to.as_str());
1375 }
1376 result
1377 }
1378 pub fn len(&self) -> usize {
1380 self.pairs.len()
1381 }
1382 pub fn is_empty(&self) -> bool {
1384 self.pairs.is_empty()
1385 }
1386}
1387#[derive(Clone, Debug)]
1389pub enum EnvError {
1390 DuplicateDeclaration(Name),
1392 NotFound(Name),
1394 InvalidQuotient(String),
1398}
1399#[allow(dead_code)]
1401pub struct TransformStat {
1402 before: StatSummary,
1403 after: StatSummary,
1404}
1405#[allow(dead_code)]
1406impl TransformStat {
1407 pub fn new() -> Self {
1409 Self {
1410 before: StatSummary::new(),
1411 after: StatSummary::new(),
1412 }
1413 }
1414 pub fn record_before(&mut self, v: f64) {
1416 self.before.record(v);
1417 }
1418 pub fn record_after(&mut self, v: f64) {
1420 self.after.record(v);
1421 }
1422 pub fn mean_ratio(&self) -> Option<f64> {
1424 let b = self.before.mean()?;
1425 let a = self.after.mean()?;
1426 if b.abs() < f64::EPSILON {
1427 return None;
1428 }
1429 Some(a / b)
1430 }
1431}
1432#[allow(dead_code)]
1434pub struct TransitiveClosure {
1435 adj: Vec<Vec<usize>>,
1436 n: usize,
1437}
1438#[allow(dead_code)]
1439impl TransitiveClosure {
1440 pub fn new(n: usize) -> Self {
1442 Self {
1443 adj: vec![Vec::new(); n],
1444 n,
1445 }
1446 }
1447 pub fn add_edge(&mut self, from: usize, to: usize) {
1449 if from < self.n {
1450 self.adj[from].push(to);
1451 }
1452 }
1453 pub fn reachable_from(&self, start: usize) -> Vec<usize> {
1455 let mut visited = vec![false; self.n];
1456 let mut queue = std::collections::VecDeque::new();
1457 queue.push_back(start);
1458 while let Some(node) = queue.pop_front() {
1459 if node >= self.n || visited[node] {
1460 continue;
1461 }
1462 visited[node] = true;
1463 for &next in &self.adj[node] {
1464 queue.push_back(next);
1465 }
1466 }
1467 (0..self.n).filter(|&i| visited[i]).collect()
1468 }
1469 pub fn can_reach(&self, from: usize, to: usize) -> bool {
1471 self.reachable_from(from).contains(&to)
1472 }
1473}
1474#[allow(dead_code)]
1476pub struct MinHeap<T: Ord> {
1477 data: Vec<T>,
1478}
1479#[allow(dead_code)]
1480impl<T: Ord> MinHeap<T> {
1481 pub fn new() -> Self {
1483 Self { data: Vec::new() }
1484 }
1485 pub fn push(&mut self, val: T) {
1487 self.data.push(val);
1488 self.sift_up(self.data.len() - 1);
1489 }
1490 pub fn pop(&mut self) -> Option<T> {
1492 if self.data.is_empty() {
1493 return None;
1494 }
1495 let n = self.data.len();
1496 self.data.swap(0, n - 1);
1497 let min = self.data.pop();
1498 if !self.data.is_empty() {
1499 self.sift_down(0);
1500 }
1501 min
1502 }
1503 pub fn peek(&self) -> Option<&T> {
1505 self.data.first()
1506 }
1507 pub fn len(&self) -> usize {
1509 self.data.len()
1510 }
1511 pub fn is_empty(&self) -> bool {
1513 self.data.is_empty()
1514 }
1515 fn sift_up(&mut self, mut i: usize) {
1516 while i > 0 {
1517 let parent = (i - 1) / 2;
1518 if self.data[i] < self.data[parent] {
1519 self.data.swap(i, parent);
1520 i = parent;
1521 } else {
1522 break;
1523 }
1524 }
1525 }
1526 fn sift_down(&mut self, mut i: usize) {
1527 let n = self.data.len();
1528 loop {
1529 let left = 2 * i + 1;
1530 let right = 2 * i + 2;
1531 let mut smallest = i;
1532 if left < n && self.data[left] < self.data[smallest] {
1533 smallest = left;
1534 }
1535 if right < n && self.data[right] < self.data[smallest] {
1536 smallest = right;
1537 }
1538 if smallest == i {
1539 break;
1540 }
1541 self.data.swap(i, smallest);
1542 i = smallest;
1543 }
1544 }
1545}
1546#[allow(dead_code)]
1548pub struct ConfigNode {
1549 key: String,
1550 value: Option<String>,
1551 children: Vec<ConfigNode>,
1552}
1553#[allow(dead_code)]
1554impl ConfigNode {
1555 pub fn leaf(key: impl Into<String>, value: impl Into<String>) -> Self {
1557 Self {
1558 key: key.into(),
1559 value: Some(value.into()),
1560 children: Vec::new(),
1561 }
1562 }
1563 pub fn section(key: impl Into<String>) -> Self {
1565 Self {
1566 key: key.into(),
1567 value: None,
1568 children: Vec::new(),
1569 }
1570 }
1571 pub fn add_child(&mut self, child: ConfigNode) {
1573 self.children.push(child);
1574 }
1575 pub fn key(&self) -> &str {
1577 &self.key
1578 }
1579 pub fn value(&self) -> Option<&str> {
1581 self.value.as_deref()
1582 }
1583 pub fn num_children(&self) -> usize {
1585 self.children.len()
1586 }
1587 pub fn lookup(&self, path: &str) -> Option<&str> {
1589 let mut parts = path.splitn(2, '.');
1590 let head = parts.next()?;
1591 let tail = parts.next();
1592 if head != self.key {
1593 return None;
1594 }
1595 match tail {
1596 None => self.value.as_deref(),
1597 Some(rest) => self.children.iter().find_map(|c| c.lookup_relative(rest)),
1598 }
1599 }
1600 fn lookup_relative(&self, path: &str) -> Option<&str> {
1601 let mut parts = path.splitn(2, '.');
1602 let head = parts.next()?;
1603 let tail = parts.next();
1604 if head != self.key {
1605 return None;
1606 }
1607 match tail {
1608 None => self.value.as_deref(),
1609 Some(rest) => self.children.iter().find_map(|c| c.lookup_relative(rest)),
1610 }
1611 }
1612}
1613#[derive(Clone, Debug)]
1617pub struct EnvironmentSnapshot {
1618 pub names: Vec<Name>,
1620}
1621impl EnvironmentSnapshot {
1622 pub fn from_env(env: &Environment) -> Self {
1624 let names: Vec<Name> = env.constant_names().cloned().collect();
1625 Self { names }
1626 }
1627 pub fn len(&self) -> usize {
1629 self.names.len()
1630 }
1631 pub fn is_empty(&self) -> bool {
1633 self.names.is_empty()
1634 }
1635 pub fn diff<'a>(&self, new: &'a EnvironmentSnapshot) -> Vec<&'a Name> {
1637 new.names
1638 .iter()
1639 .filter(|n| !self.names.contains(n))
1640 .collect()
1641 }
1642}
1643#[allow(dead_code)]
1645pub struct SmallMap<K: Ord + Clone, V: Clone> {
1646 entries: Vec<(K, V)>,
1647}
1648#[allow(dead_code)]
1649impl<K: Ord + Clone, V: Clone> SmallMap<K, V> {
1650 pub fn new() -> Self {
1652 Self {
1653 entries: Vec::new(),
1654 }
1655 }
1656 pub fn insert(&mut self, key: K, val: V) {
1658 match self.entries.binary_search_by_key(&&key, |(k, _)| k) {
1659 Ok(i) => self.entries[i].1 = val,
1660 Err(i) => self.entries.insert(i, (key, val)),
1661 }
1662 }
1663 pub fn get(&self, key: &K) -> Option<&V> {
1665 self.entries
1666 .binary_search_by_key(&key, |(k, _)| k)
1667 .ok()
1668 .map(|i| &self.entries[i].1)
1669 }
1670 pub fn len(&self) -> usize {
1672 self.entries.len()
1673 }
1674 pub fn is_empty(&self) -> bool {
1676 self.entries.is_empty()
1677 }
1678 pub fn keys(&self) -> Vec<&K> {
1680 self.entries.iter().map(|(k, _)| k).collect()
1681 }
1682 pub fn values(&self) -> Vec<&V> {
1684 self.entries.iter().map(|(_, v)| v).collect()
1685 }
1686}
1687#[allow(dead_code)]
1689pub struct SimpleDag {
1690 edges: Vec<Vec<usize>>,
1692}
1693#[allow(dead_code)]
1694impl SimpleDag {
1695 pub fn new(n: usize) -> Self {
1697 Self {
1698 edges: vec![Vec::new(); n],
1699 }
1700 }
1701 pub fn add_edge(&mut self, from: usize, to: usize) {
1703 if from < self.edges.len() {
1704 self.edges[from].push(to);
1705 }
1706 }
1707 pub fn successors(&self, node: usize) -> &[usize] {
1709 self.edges.get(node).map(|v| v.as_slice()).unwrap_or(&[])
1710 }
1711 pub fn can_reach(&self, from: usize, to: usize) -> bool {
1713 let mut visited = vec![false; self.edges.len()];
1714 self.dfs(from, to, &mut visited)
1715 }
1716 fn dfs(&self, cur: usize, target: usize, visited: &mut Vec<bool>) -> bool {
1717 if cur == target {
1718 return true;
1719 }
1720 if cur >= visited.len() || visited[cur] {
1721 return false;
1722 }
1723 visited[cur] = true;
1724 for &next in self.successors(cur) {
1725 if self.dfs(next, target, visited) {
1726 return true;
1727 }
1728 }
1729 false
1730 }
1731 pub fn topological_sort(&self) -> Option<Vec<usize>> {
1733 let n = self.edges.len();
1734 let mut in_degree = vec![0usize; n];
1735 for succs in &self.edges {
1736 for &s in succs {
1737 if s < n {
1738 in_degree[s] += 1;
1739 }
1740 }
1741 }
1742 let mut queue: std::collections::VecDeque<usize> =
1743 (0..n).filter(|&i| in_degree[i] == 0).collect();
1744 let mut order = Vec::new();
1745 while let Some(node) = queue.pop_front() {
1746 order.push(node);
1747 for &s in self.successors(node) {
1748 if s < n {
1749 in_degree[s] -= 1;
1750 if in_degree[s] == 0 {
1751 queue.push_back(s);
1752 }
1753 }
1754 }
1755 }
1756 if order.len() == n {
1757 Some(order)
1758 } else {
1759 None
1760 }
1761 }
1762 pub fn num_nodes(&self) -> usize {
1764 self.edges.len()
1765 }
1766}
1767#[allow(dead_code)]
1769pub struct WriteOnce<T> {
1770 value: std::cell::Cell<Option<T>>,
1771}
1772#[allow(dead_code)]
1773impl<T: Copy> WriteOnce<T> {
1774 pub fn new() -> Self {
1776 Self {
1777 value: std::cell::Cell::new(None),
1778 }
1779 }
1780 pub fn write(&self, val: T) -> bool {
1782 if self.value.get().is_some() {
1783 return false;
1784 }
1785 self.value.set(Some(val));
1786 true
1787 }
1788 pub fn read(&self) -> Option<T> {
1790 self.value.get()
1791 }
1792 pub fn is_written(&self) -> bool {
1794 self.value.get().is_some()
1795 }
1796}