1use crate::{Expr, FVarId, Level, Name};
6
7use std::collections::HashMap;
8
9use super::functions::{instantiate_many, named_subst_apply};
10
11#[derive(Clone, Debug, Default)]
17pub struct Telescope {
18 pub binders: Vec<(Name, Expr)>,
20}
21impl Telescope {
22 pub fn new() -> Self {
24 Self::default()
25 }
26 pub fn push(&mut self, name: Name, ty: Expr) {
28 self.binders.push((name, ty));
29 }
30 pub fn len(&self) -> usize {
32 self.binders.len()
33 }
34 pub fn is_empty(&self) -> bool {
36 self.binders.is_empty()
37 }
38 pub fn from_pi(expr: &Expr) -> (Self, Expr) {
42 let mut tel = Telescope::new();
43 let mut cur = expr;
44 while let Expr::Pi(_, name, ty, body) = cur {
45 tel.push(name.clone(), *ty.clone());
46 cur = body;
47 }
48 (tel, cur.clone())
49 }
50 pub fn to_pi(&self, body: Expr) -> Expr {
52 self.binders.iter().rev().fold(body, |acc, (name, ty)| {
53 Expr::Pi(
54 crate::BinderInfo::Default,
55 name.clone(),
56 Box::new(ty.clone()),
57 Box::new(acc),
58 )
59 })
60 }
61 pub fn to_lam(&self, body: Expr) -> Expr {
63 self.binders.iter().rev().fold(body, |acc, (name, ty)| {
64 Expr::Lam(
65 crate::BinderInfo::Default,
66 name.clone(),
67 Box::new(ty.clone()),
68 Box::new(acc),
69 )
70 })
71 }
72 pub fn instantiate(&self, args: &[Expr]) -> Vec<Expr> {
76 let mut result = Vec::new();
77 for (i, (_, ty)) in self.binders.iter().enumerate() {
78 let subst = &args[..i.min(args.len())];
79 let inst = instantiate_many(ty, subst);
80 result.push(inst);
81 }
82 result
83 }
84}
85#[allow(dead_code)]
87pub struct SparseVec<T: Default + Clone + PartialEq> {
88 entries: std::collections::HashMap<usize, T>,
89 default_: T,
90 logical_len: usize,
91}
92#[allow(dead_code)]
93impl<T: Default + Clone + PartialEq> SparseVec<T> {
94 pub fn new(len: usize) -> Self {
96 Self {
97 entries: std::collections::HashMap::new(),
98 default_: T::default(),
99 logical_len: len,
100 }
101 }
102 pub fn set(&mut self, idx: usize, val: T) {
104 if val == self.default_ {
105 self.entries.remove(&idx);
106 } else {
107 self.entries.insert(idx, val);
108 }
109 }
110 pub fn get(&self, idx: usize) -> &T {
112 self.entries.get(&idx).unwrap_or(&self.default_)
113 }
114 pub fn len(&self) -> usize {
116 self.logical_len
117 }
118 pub fn is_empty(&self) -> bool {
120 self.len() == 0
121 }
122 pub fn nnz(&self) -> usize {
124 self.entries.len()
125 }
126}
127#[allow(dead_code)]
129pub struct Fixture {
130 data: std::collections::HashMap<String, String>,
131}
132#[allow(dead_code)]
133impl Fixture {
134 pub fn new() -> Self {
136 Self {
137 data: std::collections::HashMap::new(),
138 }
139 }
140 pub fn set(&mut self, key: impl Into<String>, val: impl Into<String>) {
142 self.data.insert(key.into(), val.into());
143 }
144 pub fn get(&self, key: &str) -> Option<&str> {
146 self.data.get(key).map(|s| s.as_str())
147 }
148 pub fn len(&self) -> usize {
150 self.data.len()
151 }
152 pub fn is_empty(&self) -> bool {
154 self.len() == 0
155 }
156}
157#[allow(dead_code)]
159pub struct RewriteRuleSet {
160 rules: Vec<RewriteRule>,
161}
162#[allow(dead_code)]
163impl RewriteRuleSet {
164 pub fn new() -> Self {
166 Self { rules: Vec::new() }
167 }
168 pub fn add(&mut self, rule: RewriteRule) {
170 self.rules.push(rule);
171 }
172 pub fn len(&self) -> usize {
174 self.rules.len()
175 }
176 pub fn is_empty(&self) -> bool {
178 self.rules.is_empty()
179 }
180 pub fn conditional_rules(&self) -> Vec<&RewriteRule> {
182 self.rules.iter().filter(|r| r.conditional).collect()
183 }
184 pub fn unconditional_rules(&self) -> Vec<&RewriteRule> {
186 self.rules.iter().filter(|r| !r.conditional).collect()
187 }
188 pub fn get(&self, name: &str) -> Option<&RewriteRule> {
190 self.rules.iter().find(|r| r.name == name)
191 }
192}
193#[allow(dead_code)]
195pub struct LabelSet {
196 labels: Vec<String>,
197}
198#[allow(dead_code)]
199impl LabelSet {
200 pub fn new() -> Self {
202 Self { labels: Vec::new() }
203 }
204 pub fn add(&mut self, label: impl Into<String>) {
206 let s = label.into();
207 if !self.labels.contains(&s) {
208 self.labels.push(s);
209 }
210 }
211 pub fn has(&self, label: &str) -> bool {
213 self.labels.iter().any(|l| l == label)
214 }
215 pub fn count(&self) -> usize {
217 self.labels.len()
218 }
219 pub fn all(&self) -> &[String] {
221 &self.labels
222 }
223}
224#[allow(dead_code)]
226pub struct WindowIterator<'a, T> {
227 pub(super) data: &'a [T],
228 pub(super) pos: usize,
229 pub(super) window: usize,
230}
231#[allow(dead_code)]
232impl<'a, T> WindowIterator<'a, T> {
233 pub fn new(data: &'a [T], window: usize) -> Self {
235 Self {
236 data,
237 pos: 0,
238 window,
239 }
240 }
241}
242#[allow(dead_code)]
244pub struct FlatSubstitution {
245 pairs: Vec<(String, String)>,
246}
247#[allow(dead_code)]
248impl FlatSubstitution {
249 pub fn new() -> Self {
251 Self { pairs: Vec::new() }
252 }
253 pub fn add(&mut self, from: impl Into<String>, to: impl Into<String>) {
255 self.pairs.push((from.into(), to.into()));
256 }
257 pub fn apply(&self, s: &str) -> String {
259 let mut result = s.to_string();
260 for (from, to) in &self.pairs {
261 result = result.replace(from.as_str(), to.as_str());
262 }
263 result
264 }
265 pub fn len(&self) -> usize {
267 self.pairs.len()
268 }
269 pub fn is_empty(&self) -> bool {
271 self.pairs.is_empty()
272 }
273}
274#[allow(dead_code)]
276pub struct StringPool {
277 free: Vec<String>,
278}
279#[allow(dead_code)]
280impl StringPool {
281 pub fn new() -> Self {
283 Self { free: Vec::new() }
284 }
285 pub fn take(&mut self) -> String {
287 self.free.pop().unwrap_or_default()
288 }
289 pub fn give(&mut self, mut s: String) {
291 s.clear();
292 self.free.push(s);
293 }
294 pub fn free_count(&self) -> usize {
296 self.free.len()
297 }
298}
299#[allow(dead_code)]
301pub struct NonEmptyVec<T> {
302 head: T,
303 tail: Vec<T>,
304}
305#[allow(dead_code)]
306impl<T> NonEmptyVec<T> {
307 pub fn singleton(val: T) -> Self {
309 Self {
310 head: val,
311 tail: Vec::new(),
312 }
313 }
314 pub fn push(&mut self, val: T) {
316 self.tail.push(val);
317 }
318 pub fn first(&self) -> &T {
320 &self.head
321 }
322 pub fn last(&self) -> &T {
324 self.tail.last().unwrap_or(&self.head)
325 }
326 pub fn len(&self) -> usize {
328 1 + self.tail.len()
329 }
330 pub fn is_empty(&self) -> bool {
332 self.len() == 0
333 }
334 pub fn to_vec(&self) -> Vec<&T> {
336 let mut v = vec![&self.head];
337 v.extend(self.tail.iter());
338 v
339 }
340}
341#[allow(dead_code)]
343pub struct SmallMap<K: Ord + Clone, V: Clone> {
344 entries: Vec<(K, V)>,
345}
346#[allow(dead_code)]
347impl<K: Ord + Clone, V: Clone> SmallMap<K, V> {
348 pub fn new() -> Self {
350 Self {
351 entries: Vec::new(),
352 }
353 }
354 pub fn insert(&mut self, key: K, val: V) {
356 match self.entries.binary_search_by_key(&&key, |(k, _)| k) {
357 Ok(i) => self.entries[i].1 = val,
358 Err(i) => self.entries.insert(i, (key, val)),
359 }
360 }
361 pub fn get(&self, key: &K) -> Option<&V> {
363 self.entries
364 .binary_search_by_key(&key, |(k, _)| k)
365 .ok()
366 .map(|i| &self.entries[i].1)
367 }
368 pub fn len(&self) -> usize {
370 self.entries.len()
371 }
372 pub fn is_empty(&self) -> bool {
374 self.entries.is_empty()
375 }
376 pub fn keys(&self) -> Vec<&K> {
378 self.entries.iter().map(|(k, _)| k).collect()
379 }
380 pub fn values(&self) -> Vec<&V> {
382 self.entries.iter().map(|(_, v)| v).collect()
383 }
384}
385#[allow(dead_code)]
387pub struct StatSummary {
388 count: u64,
389 sum: f64,
390 min: f64,
391 max: f64,
392}
393#[allow(dead_code)]
394impl StatSummary {
395 pub fn new() -> Self {
397 Self {
398 count: 0,
399 sum: 0.0,
400 min: f64::INFINITY,
401 max: f64::NEG_INFINITY,
402 }
403 }
404 pub fn record(&mut self, val: f64) {
406 self.count += 1;
407 self.sum += val;
408 if val < self.min {
409 self.min = val;
410 }
411 if val > self.max {
412 self.max = val;
413 }
414 }
415 pub fn mean(&self) -> Option<f64> {
417 if self.count == 0 {
418 None
419 } else {
420 Some(self.sum / self.count as f64)
421 }
422 }
423 pub fn min(&self) -> Option<f64> {
425 if self.count == 0 {
426 None
427 } else {
428 Some(self.min)
429 }
430 }
431 pub fn max(&self) -> Option<f64> {
433 if self.count == 0 {
434 None
435 } else {
436 Some(self.max)
437 }
438 }
439 pub fn count(&self) -> u64 {
441 self.count
442 }
443}
444#[allow(dead_code)]
446pub struct MinHeap<T: Ord> {
447 data: Vec<T>,
448}
449#[allow(dead_code)]
450impl<T: Ord> MinHeap<T> {
451 pub fn new() -> Self {
453 Self { data: Vec::new() }
454 }
455 pub fn push(&mut self, val: T) {
457 self.data.push(val);
458 self.sift_up(self.data.len() - 1);
459 }
460 pub fn pop(&mut self) -> Option<T> {
462 if self.data.is_empty() {
463 return None;
464 }
465 let n = self.data.len();
466 self.data.swap(0, n - 1);
467 let min = self.data.pop();
468 if !self.data.is_empty() {
469 self.sift_down(0);
470 }
471 min
472 }
473 pub fn peek(&self) -> Option<&T> {
475 self.data.first()
476 }
477 pub fn len(&self) -> usize {
479 self.data.len()
480 }
481 pub fn is_empty(&self) -> bool {
483 self.data.is_empty()
484 }
485 fn sift_up(&mut self, mut i: usize) {
486 while i > 0 {
487 let parent = (i - 1) / 2;
488 if self.data[i] < self.data[parent] {
489 self.data.swap(i, parent);
490 i = parent;
491 } else {
492 break;
493 }
494 }
495 }
496 fn sift_down(&mut self, mut i: usize) {
497 let n = self.data.len();
498 loop {
499 let left = 2 * i + 1;
500 let right = 2 * i + 2;
501 let mut smallest = i;
502 if left < n && self.data[left] < self.data[smallest] {
503 smallest = left;
504 }
505 if right < n && self.data[right] < self.data[smallest] {
506 smallest = right;
507 }
508 if smallest == i {
509 break;
510 }
511 self.data.swap(i, smallest);
512 i = smallest;
513 }
514 }
515}
516#[allow(dead_code)]
518#[allow(missing_docs)]
519pub struct RewriteRule {
520 pub name: String,
522 pub lhs: String,
524 pub rhs: String,
526 pub conditional: bool,
528}
529#[allow(dead_code)]
530impl RewriteRule {
531 pub fn unconditional(
533 name: impl Into<String>,
534 lhs: impl Into<String>,
535 rhs: impl Into<String>,
536 ) -> Self {
537 Self {
538 name: name.into(),
539 lhs: lhs.into(),
540 rhs: rhs.into(),
541 conditional: false,
542 }
543 }
544 pub fn conditional(
546 name: impl Into<String>,
547 lhs: impl Into<String>,
548 rhs: impl Into<String>,
549 ) -> Self {
550 Self {
551 name: name.into(),
552 lhs: lhs.into(),
553 rhs: rhs.into(),
554 conditional: true,
555 }
556 }
557 pub fn display(&self) -> String {
559 format!("{}: {} → {}", self.name, self.lhs, self.rhs)
560 }
561}
562#[allow(dead_code)]
564pub struct TransitiveClosure {
565 adj: Vec<Vec<usize>>,
566 n: usize,
567}
568#[allow(dead_code)]
569impl TransitiveClosure {
570 pub fn new(n: usize) -> Self {
572 Self {
573 adj: vec![Vec::new(); n],
574 n,
575 }
576 }
577 pub fn add_edge(&mut self, from: usize, to: usize) {
579 if from < self.n {
580 self.adj[from].push(to);
581 }
582 }
583 pub fn reachable_from(&self, start: usize) -> Vec<usize> {
585 let mut visited = vec![false; self.n];
586 let mut queue = std::collections::VecDeque::new();
587 queue.push_back(start);
588 while let Some(node) = queue.pop_front() {
589 if node >= self.n || visited[node] {
590 continue;
591 }
592 visited[node] = true;
593 for &next in &self.adj[node] {
594 queue.push_back(next);
595 }
596 }
597 (0..self.n).filter(|&i| visited[i]).collect()
598 }
599 pub fn can_reach(&self, from: usize, to: usize) -> bool {
601 self.reachable_from(from).contains(&to)
602 }
603}
604#[allow(dead_code)]
606pub struct PathBuf {
607 components: Vec<String>,
608}
609#[allow(dead_code)]
610impl PathBuf {
611 pub fn new() -> Self {
613 Self {
614 components: Vec::new(),
615 }
616 }
617 pub fn push(&mut self, comp: impl Into<String>) {
619 self.components.push(comp.into());
620 }
621 pub fn pop(&mut self) {
623 self.components.pop();
624 }
625 pub fn as_str(&self) -> String {
627 self.components.join("/")
628 }
629 pub fn depth(&self) -> usize {
631 self.components.len()
632 }
633 pub fn clear(&mut self) {
635 self.components.clear();
636 }
637}
638#[allow(dead_code)]
640pub struct RawFnPtr {
641 ptr: usize,
643 arity: usize,
644 name: String,
645}
646#[allow(dead_code)]
647impl RawFnPtr {
648 pub fn new(ptr: usize, arity: usize, name: impl Into<String>) -> Self {
650 Self {
651 ptr,
652 arity,
653 name: name.into(),
654 }
655 }
656 pub fn arity(&self) -> usize {
658 self.arity
659 }
660 pub fn name(&self) -> &str {
662 &self.name
663 }
664 pub fn raw(&self) -> usize {
666 self.ptr
667 }
668}
669#[allow(dead_code)]
671pub struct Stopwatch {
672 start: std::time::Instant,
673 splits: Vec<f64>,
674}
675#[allow(dead_code)]
676impl Stopwatch {
677 pub fn start() -> Self {
679 Self {
680 start: std::time::Instant::now(),
681 splits: Vec::new(),
682 }
683 }
684 pub fn split(&mut self) {
686 self.splits.push(self.elapsed_ms());
687 }
688 pub fn elapsed_ms(&self) -> f64 {
690 self.start.elapsed().as_secs_f64() * 1000.0
691 }
692 pub fn splits(&self) -> &[f64] {
694 &self.splits
695 }
696 pub fn num_splits(&self) -> usize {
698 self.splits.len()
699 }
700}
701#[allow(dead_code)]
703#[allow(missing_docs)]
704pub enum DecisionNode {
705 Leaf(String),
707 Branch {
709 key: String,
710 val: String,
711 yes_branch: Box<DecisionNode>,
712 no_branch: Box<DecisionNode>,
713 },
714}
715#[allow(dead_code)]
716impl DecisionNode {
717 pub fn evaluate(&self, ctx: &std::collections::HashMap<String, String>) -> &str {
719 match self {
720 DecisionNode::Leaf(action) => action.as_str(),
721 DecisionNode::Branch {
722 key,
723 val,
724 yes_branch,
725 no_branch,
726 } => {
727 let actual = ctx.get(key).map(|s| s.as_str()).unwrap_or("");
728 if actual == val.as_str() {
729 yes_branch.evaluate(ctx)
730 } else {
731 no_branch.evaluate(ctx)
732 }
733 }
734 }
735 }
736 pub fn depth(&self) -> usize {
738 match self {
739 DecisionNode::Leaf(_) => 0,
740 DecisionNode::Branch {
741 yes_branch,
742 no_branch,
743 ..
744 } => 1 + yes_branch.depth().max(no_branch.depth()),
745 }
746 }
747}
748#[allow(dead_code)]
750pub struct ConfigNode {
751 key: String,
752 value: Option<String>,
753 children: Vec<ConfigNode>,
754}
755#[allow(dead_code)]
756impl ConfigNode {
757 pub fn leaf(key: impl Into<String>, value: impl Into<String>) -> Self {
759 Self {
760 key: key.into(),
761 value: Some(value.into()),
762 children: Vec::new(),
763 }
764 }
765 pub fn section(key: impl Into<String>) -> Self {
767 Self {
768 key: key.into(),
769 value: None,
770 children: Vec::new(),
771 }
772 }
773 pub fn add_child(&mut self, child: ConfigNode) {
775 self.children.push(child);
776 }
777 pub fn key(&self) -> &str {
779 &self.key
780 }
781 pub fn value(&self) -> Option<&str> {
783 self.value.as_deref()
784 }
785 pub fn num_children(&self) -> usize {
787 self.children.len()
788 }
789 pub fn lookup(&self, path: &str) -> Option<&str> {
791 let mut parts = path.splitn(2, '.');
792 let head = parts.next()?;
793 let tail = parts.next();
794 if head != self.key {
795 return None;
796 }
797 match tail {
798 None => self.value.as_deref(),
799 Some(rest) => self.children.iter().find_map(|c| c.lookup_relative(rest)),
800 }
801 }
802 fn lookup_relative(&self, path: &str) -> Option<&str> {
803 let mut parts = path.splitn(2, '.');
804 let head = parts.next()?;
805 let tail = parts.next();
806 if head != self.key {
807 return None;
808 }
809 match tail {
810 None => self.value.as_deref(),
811 Some(rest) => self.children.iter().find_map(|c| c.lookup_relative(rest)),
812 }
813 }
814}
815#[allow(dead_code)]
817pub struct VersionedRecord<T: Clone> {
818 history: Vec<T>,
819}
820#[allow(dead_code)]
821impl<T: Clone> VersionedRecord<T> {
822 pub fn new(initial: T) -> Self {
824 Self {
825 history: vec![initial],
826 }
827 }
828 pub fn update(&mut self, val: T) {
830 self.history.push(val);
831 }
832 pub fn current(&self) -> &T {
834 self.history
835 .last()
836 .expect("VersionedRecord history is always non-empty after construction")
837 }
838 pub fn at_version(&self, n: usize) -> Option<&T> {
840 self.history.get(n)
841 }
842 pub fn version(&self) -> usize {
844 self.history.len() - 1
845 }
846 pub fn has_history(&self) -> bool {
848 self.history.len() > 1
849 }
850}
851#[allow(dead_code)]
853pub enum Either2<A, B> {
854 First(A),
856 Second(B),
858}
859#[allow(dead_code)]
860impl<A, B> Either2<A, B> {
861 pub fn is_first(&self) -> bool {
863 matches!(self, Either2::First(_))
864 }
865 pub fn is_second(&self) -> bool {
867 matches!(self, Either2::Second(_))
868 }
869 pub fn first(self) -> Option<A> {
871 match self {
872 Either2::First(a) => Some(a),
873 _ => None,
874 }
875 }
876 pub fn second(self) -> Option<B> {
878 match self {
879 Either2::Second(b) => Some(b),
880 _ => None,
881 }
882 }
883 pub fn map_first<C, F: FnOnce(A) -> C>(self, f: F) -> Either2<C, B> {
885 match self {
886 Either2::First(a) => Either2::First(f(a)),
887 Either2::Second(b) => Either2::Second(b),
888 }
889 }
890}
891#[allow(dead_code)]
893pub struct FocusStack<T> {
894 items: Vec<T>,
895}
896#[allow(dead_code)]
897impl<T> FocusStack<T> {
898 pub fn new() -> Self {
900 Self { items: Vec::new() }
901 }
902 pub fn focus(&mut self, item: T) {
904 self.items.push(item);
905 }
906 pub fn blur(&mut self) -> Option<T> {
908 self.items.pop()
909 }
910 pub fn current(&self) -> Option<&T> {
912 self.items.last()
913 }
914 pub fn depth(&self) -> usize {
916 self.items.len()
917 }
918 pub fn is_empty(&self) -> bool {
920 self.items.is_empty()
921 }
922}
923#[allow(dead_code)]
925pub struct PrefixCounter {
926 children: std::collections::HashMap<char, PrefixCounter>,
927 count: usize,
928}
929#[allow(dead_code)]
930impl PrefixCounter {
931 pub fn new() -> Self {
933 Self {
934 children: std::collections::HashMap::new(),
935 count: 0,
936 }
937 }
938 pub fn record(&mut self, s: &str) {
940 self.count += 1;
941 let mut node = self;
942 for c in s.chars() {
943 node = node.children.entry(c).or_default();
944 node.count += 1;
945 }
946 }
947 pub fn count_with_prefix(&self, prefix: &str) -> usize {
949 let mut node = self;
950 for c in prefix.chars() {
951 match node.children.get(&c) {
952 Some(n) => node = n,
953 None => return 0,
954 }
955 }
956 node.count
957 }
958}
959#[allow(dead_code)]
961pub struct SlidingSum {
962 window: Vec<f64>,
963 capacity: usize,
964 pos: usize,
965 sum: f64,
966 count: usize,
967}
968#[allow(dead_code)]
969impl SlidingSum {
970 pub fn new(capacity: usize) -> Self {
972 Self {
973 window: vec![0.0; capacity],
974 capacity,
975 pos: 0,
976 sum: 0.0,
977 count: 0,
978 }
979 }
980 pub fn push(&mut self, val: f64) {
982 let oldest = self.window[self.pos];
983 self.sum -= oldest;
984 self.sum += val;
985 self.window[self.pos] = val;
986 self.pos = (self.pos + 1) % self.capacity;
987 if self.count < self.capacity {
988 self.count += 1;
989 }
990 }
991 pub fn sum(&self) -> f64 {
993 self.sum
994 }
995 pub fn mean(&self) -> Option<f64> {
997 if self.count == 0 {
998 None
999 } else {
1000 Some(self.sum / self.count as f64)
1001 }
1002 }
1003 pub fn count(&self) -> usize {
1005 self.count
1006 }
1007}
1008#[allow(dead_code)]
1010pub struct StackCalc {
1011 stack: Vec<i64>,
1012}
1013#[allow(dead_code)]
1014impl StackCalc {
1015 pub fn new() -> Self {
1017 Self { stack: Vec::new() }
1018 }
1019 pub fn push(&mut self, n: i64) {
1021 self.stack.push(n);
1022 }
1023 pub fn add(&mut self) {
1025 let b = self
1026 .stack
1027 .pop()
1028 .expect("stack must have at least two values for add");
1029 let a = self
1030 .stack
1031 .pop()
1032 .expect("stack must have at least two values for add");
1033 self.stack.push(a + b);
1034 }
1035 pub fn sub(&mut self) {
1037 let b = self
1038 .stack
1039 .pop()
1040 .expect("stack must have at least two values for sub");
1041 let a = self
1042 .stack
1043 .pop()
1044 .expect("stack must have at least two values for sub");
1045 self.stack.push(a - b);
1046 }
1047 pub fn mul(&mut self) {
1049 let b = self
1050 .stack
1051 .pop()
1052 .expect("stack must have at least two values for mul");
1053 let a = self
1054 .stack
1055 .pop()
1056 .expect("stack must have at least two values for mul");
1057 self.stack.push(a * b);
1058 }
1059 pub fn peek(&self) -> Option<i64> {
1061 self.stack.last().copied()
1062 }
1063 pub fn depth(&self) -> usize {
1065 self.stack.len()
1066 }
1067}
1068#[allow(dead_code)]
1070pub struct SimpleDag {
1071 edges: Vec<Vec<usize>>,
1073}
1074#[allow(dead_code)]
1075impl SimpleDag {
1076 pub fn new(n: usize) -> Self {
1078 Self {
1079 edges: vec![Vec::new(); n],
1080 }
1081 }
1082 pub fn add_edge(&mut self, from: usize, to: usize) {
1084 if from < self.edges.len() {
1085 self.edges[from].push(to);
1086 }
1087 }
1088 pub fn successors(&self, node: usize) -> &[usize] {
1090 self.edges.get(node).map(|v| v.as_slice()).unwrap_or(&[])
1091 }
1092 pub fn can_reach(&self, from: usize, to: usize) -> bool {
1094 let mut visited = vec![false; self.edges.len()];
1095 self.dfs(from, to, &mut visited)
1096 }
1097 fn dfs(&self, cur: usize, target: usize, visited: &mut Vec<bool>) -> bool {
1098 if cur == target {
1099 return true;
1100 }
1101 if cur >= visited.len() || visited[cur] {
1102 return false;
1103 }
1104 visited[cur] = true;
1105 for &next in self.successors(cur) {
1106 if self.dfs(next, target, visited) {
1107 return true;
1108 }
1109 }
1110 false
1111 }
1112 pub fn topological_sort(&self) -> Option<Vec<usize>> {
1114 let n = self.edges.len();
1115 let mut in_degree = vec![0usize; n];
1116 for succs in &self.edges {
1117 for &s in succs {
1118 if s < n {
1119 in_degree[s] += 1;
1120 }
1121 }
1122 }
1123 let mut queue: std::collections::VecDeque<usize> =
1124 (0..n).filter(|&i| in_degree[i] == 0).collect();
1125 let mut order = Vec::new();
1126 while let Some(node) = queue.pop_front() {
1127 order.push(node);
1128 for &s in self.successors(node) {
1129 if s < n {
1130 in_degree[s] -= 1;
1131 if in_degree[s] == 0 {
1132 queue.push_back(s);
1133 }
1134 }
1135 }
1136 }
1137 if order.len() == n {
1138 Some(order)
1139 } else {
1140 None
1141 }
1142 }
1143 pub fn num_nodes(&self) -> usize {
1145 self.edges.len()
1146 }
1147}
1148#[allow(dead_code)]
1150pub struct WriteOnce<T> {
1151 value: std::cell::Cell<Option<T>>,
1152}
1153#[allow(dead_code)]
1154impl<T: Copy> WriteOnce<T> {
1155 pub fn new() -> Self {
1157 Self {
1158 value: std::cell::Cell::new(None),
1159 }
1160 }
1161 pub fn write(&self, val: T) -> bool {
1163 if self.value.get().is_some() {
1164 return false;
1165 }
1166 self.value.set(Some(val));
1167 true
1168 }
1169 pub fn read(&self) -> Option<T> {
1171 self.value.get()
1172 }
1173 pub fn is_written(&self) -> bool {
1175 self.value.get().is_some()
1176 }
1177}
1178#[derive(Clone, Debug, Default)]
1180pub struct NamedSubst {
1181 map: std::collections::HashMap<Name, Expr>,
1182}
1183impl NamedSubst {
1184 pub fn new() -> Self {
1186 Self::default()
1187 }
1188 pub fn insert(&mut self, name: Name, val: Expr) {
1190 self.map.insert(name, val);
1191 }
1192 pub fn get(&self, name: &Name) -> Option<&Expr> {
1194 self.map.get(name)
1195 }
1196 pub fn len(&self) -> usize {
1198 self.map.len()
1199 }
1200 pub fn is_empty(&self) -> bool {
1202 self.map.is_empty()
1203 }
1204 pub fn apply(&self, expr: &Expr) -> Expr {
1208 named_subst_apply(expr, self)
1209 }
1210}
1211#[allow(dead_code)]
1213pub struct TransformStat {
1214 before: StatSummary,
1215 after: StatSummary,
1216}
1217#[allow(dead_code)]
1218impl TransformStat {
1219 pub fn new() -> Self {
1221 Self {
1222 before: StatSummary::new(),
1223 after: StatSummary::new(),
1224 }
1225 }
1226 pub fn record_before(&mut self, v: f64) {
1228 self.before.record(v);
1229 }
1230 pub fn record_after(&mut self, v: f64) {
1232 self.after.record(v);
1233 }
1234 pub fn mean_ratio(&self) -> Option<f64> {
1236 let b = self.before.mean()?;
1237 let a = self.after.mean()?;
1238 if b.abs() < f64::EPSILON {
1239 return None;
1240 }
1241 Some(a / b)
1242 }
1243}
1244#[allow(dead_code)]
1246pub struct TokenBucket {
1247 capacity: u64,
1248 tokens: u64,
1249 refill_per_ms: u64,
1250 last_refill: std::time::Instant,
1251}
1252#[allow(dead_code)]
1253impl TokenBucket {
1254 pub fn new(capacity: u64, refill_per_ms: u64) -> Self {
1256 Self {
1257 capacity,
1258 tokens: capacity,
1259 refill_per_ms,
1260 last_refill: std::time::Instant::now(),
1261 }
1262 }
1263 pub fn try_consume(&mut self, n: u64) -> bool {
1265 self.refill();
1266 if self.tokens >= n {
1267 self.tokens -= n;
1268 true
1269 } else {
1270 false
1271 }
1272 }
1273 fn refill(&mut self) {
1274 let now = std::time::Instant::now();
1275 let elapsed_ms = now.duration_since(self.last_refill).as_millis() as u64;
1276 if elapsed_ms > 0 {
1277 let new_tokens = elapsed_ms * self.refill_per_ms;
1278 self.tokens = (self.tokens + new_tokens).min(self.capacity);
1279 self.last_refill = now;
1280 }
1281 }
1282 pub fn available(&self) -> u64 {
1284 self.tokens
1285 }
1286 pub fn capacity(&self) -> u64 {
1288 self.capacity
1289 }
1290}