1use crate::Node;
6use crate::{Expr, FVarId, Level, Name};
7use std::rc::Rc;
8
9use std::collections::HashMap;
10
11use super::functions::{instantiate_many, named_subst_apply};
12
13#[derive(Clone, Debug, Default)]
19pub struct Telescope {
20 pub binders: Vec<(Name, Expr)>,
22}
23impl Telescope {
24 pub fn new() -> Self {
26 Self::default()
27 }
28 pub fn push(&mut self, name: Name, ty: Expr) {
30 self.binders.push((name, ty));
31 }
32 pub fn len(&self) -> usize {
34 self.binders.len()
35 }
36 pub fn is_empty(&self) -> bool {
38 self.binders.is_empty()
39 }
40 pub fn from_pi(expr: &Expr) -> (Self, Expr) {
44 let mut tel = Telescope::new();
45 let mut cur = expr;
46 while let Expr::Pi(_, name, ty, body) = cur {
47 tel.push(name.clone(), (**ty).clone());
48 cur = body;
49 }
50 (tel, cur.clone())
51 }
52 pub fn to_pi(&self, body: Expr) -> Expr {
54 self.binders.iter().rev().fold(body, |acc, (name, ty)| {
55 Expr::Pi(
56 crate::BinderInfo::Default,
57 name.clone(),
58 Node::new(ty.clone()),
59 Node::new(acc),
60 )
61 })
62 }
63 pub fn to_lam(&self, body: Expr) -> Expr {
65 self.binders.iter().rev().fold(body, |acc, (name, ty)| {
66 Expr::Lam(
67 crate::BinderInfo::Default,
68 name.clone(),
69 Node::new(ty.clone()),
70 Node::new(acc),
71 )
72 })
73 }
74 pub fn instantiate(&self, args: &[Expr]) -> Vec<Expr> {
78 let mut result = Vec::new();
79 for (i, (_, ty)) in self.binders.iter().enumerate() {
80 let subst = &args[..i.min(args.len())];
81 let inst = instantiate_many(ty, subst);
82 result.push(inst);
83 }
84 result
85 }
86}
87#[allow(dead_code)]
89pub struct SparseVec<T: Default + Clone + PartialEq> {
90 entries: std::collections::HashMap<usize, T>,
91 default_: T,
92 logical_len: usize,
93}
94#[allow(dead_code)]
95impl<T: Default + Clone + PartialEq> SparseVec<T> {
96 pub fn new(len: usize) -> Self {
98 Self {
99 entries: std::collections::HashMap::new(),
100 default_: T::default(),
101 logical_len: len,
102 }
103 }
104 pub fn set(&mut self, idx: usize, val: T) {
106 if val == self.default_ {
107 self.entries.remove(&idx);
108 } else {
109 self.entries.insert(idx, val);
110 }
111 }
112 pub fn get(&self, idx: usize) -> &T {
114 self.entries.get(&idx).unwrap_or(&self.default_)
115 }
116 pub fn len(&self) -> usize {
118 self.logical_len
119 }
120 pub fn is_empty(&self) -> bool {
122 self.len() == 0
123 }
124 pub fn nnz(&self) -> usize {
126 self.entries.len()
127 }
128}
129#[allow(dead_code)]
131pub struct Fixture {
132 data: std::collections::HashMap<String, String>,
133}
134#[allow(dead_code)]
135impl Fixture {
136 pub fn new() -> Self {
138 Self {
139 data: std::collections::HashMap::new(),
140 }
141 }
142 pub fn set(&mut self, key: impl Into<String>, val: impl Into<String>) {
144 self.data.insert(key.into(), val.into());
145 }
146 pub fn get(&self, key: &str) -> Option<&str> {
148 self.data.get(key).map(|s| s.as_str())
149 }
150 pub fn len(&self) -> usize {
152 self.data.len()
153 }
154 pub fn is_empty(&self) -> bool {
156 self.len() == 0
157 }
158}
159#[allow(dead_code)]
161pub struct RewriteRuleSet {
162 rules: Vec<RewriteRule>,
163}
164#[allow(dead_code)]
165impl RewriteRuleSet {
166 pub fn new() -> Self {
168 Self { rules: Vec::new() }
169 }
170 pub fn add(&mut self, rule: RewriteRule) {
172 self.rules.push(rule);
173 }
174 pub fn len(&self) -> usize {
176 self.rules.len()
177 }
178 pub fn is_empty(&self) -> bool {
180 self.rules.is_empty()
181 }
182 pub fn conditional_rules(&self) -> Vec<&RewriteRule> {
184 self.rules.iter().filter(|r| r.conditional).collect()
185 }
186 pub fn unconditional_rules(&self) -> Vec<&RewriteRule> {
188 self.rules.iter().filter(|r| !r.conditional).collect()
189 }
190 pub fn get(&self, name: &str) -> Option<&RewriteRule> {
192 self.rules.iter().find(|r| r.name == name)
193 }
194}
195#[allow(dead_code)]
197pub struct LabelSet {
198 labels: Vec<String>,
199}
200#[allow(dead_code)]
201impl LabelSet {
202 pub fn new() -> Self {
204 Self { labels: Vec::new() }
205 }
206 pub fn add(&mut self, label: impl Into<String>) {
208 let s = label.into();
209 if !self.labels.contains(&s) {
210 self.labels.push(s);
211 }
212 }
213 pub fn has(&self, label: &str) -> bool {
215 self.labels.iter().any(|l| l == label)
216 }
217 pub fn count(&self) -> usize {
219 self.labels.len()
220 }
221 pub fn all(&self) -> &[String] {
223 &self.labels
224 }
225}
226#[allow(dead_code)]
228pub struct WindowIterator<'a, T> {
229 pub(super) data: &'a [T],
230 pub(super) pos: usize,
231 pub(super) window: usize,
232}
233#[allow(dead_code)]
234impl<'a, T> WindowIterator<'a, T> {
235 pub fn new(data: &'a [T], window: usize) -> Self {
237 Self {
238 data,
239 pos: 0,
240 window,
241 }
242 }
243}
244#[allow(dead_code)]
246pub struct FlatSubstitution {
247 pairs: Vec<(String, String)>,
248}
249#[allow(dead_code)]
250impl FlatSubstitution {
251 pub fn new() -> Self {
253 Self { pairs: Vec::new() }
254 }
255 pub fn add(&mut self, from: impl Into<String>, to: impl Into<String>) {
257 self.pairs.push((from.into(), to.into()));
258 }
259 pub fn apply(&self, s: &str) -> String {
261 let mut result = s.to_string();
262 for (from, to) in &self.pairs {
263 result = result.replace(from.as_str(), to.as_str());
264 }
265 result
266 }
267 pub fn len(&self) -> usize {
269 self.pairs.len()
270 }
271 pub fn is_empty(&self) -> bool {
273 self.pairs.is_empty()
274 }
275}
276#[allow(dead_code)]
278pub struct StringPool {
279 free: Vec<String>,
280}
281#[allow(dead_code)]
282impl StringPool {
283 pub fn new() -> Self {
285 Self { free: Vec::new() }
286 }
287 pub fn take(&mut self) -> String {
289 self.free.pop().unwrap_or_default()
290 }
291 pub fn give(&mut self, mut s: String) {
293 s.clear();
294 self.free.push(s);
295 }
296 pub fn free_count(&self) -> usize {
298 self.free.len()
299 }
300}
301#[allow(dead_code)]
303pub struct NonEmptyVec<T> {
304 head: T,
305 tail: Vec<T>,
306}
307#[allow(dead_code)]
308impl<T> NonEmptyVec<T> {
309 pub fn singleton(val: T) -> Self {
311 Self {
312 head: val,
313 tail: Vec::new(),
314 }
315 }
316 pub fn push(&mut self, val: T) {
318 self.tail.push(val);
319 }
320 pub fn first(&self) -> &T {
322 &self.head
323 }
324 pub fn last(&self) -> &T {
326 self.tail.last().unwrap_or(&self.head)
327 }
328 pub fn len(&self) -> usize {
330 1 + self.tail.len()
331 }
332 pub fn is_empty(&self) -> bool {
334 self.len() == 0
335 }
336 pub fn to_vec(&self) -> Vec<&T> {
338 let mut v = vec![&self.head];
339 v.extend(self.tail.iter());
340 v
341 }
342}
343#[allow(dead_code)]
345pub struct SmallMap<K: Ord + Clone, V: Clone> {
346 entries: Vec<(K, V)>,
347}
348#[allow(dead_code)]
349impl<K: Ord + Clone, V: Clone> SmallMap<K, V> {
350 pub fn new() -> Self {
352 Self {
353 entries: Vec::new(),
354 }
355 }
356 pub fn insert(&mut self, key: K, val: V) {
358 match self.entries.binary_search_by_key(&&key, |(k, _)| k) {
359 Ok(i) => self.entries[i].1 = val,
360 Err(i) => self.entries.insert(i, (key, val)),
361 }
362 }
363 pub fn get(&self, key: &K) -> Option<&V> {
365 self.entries
366 .binary_search_by_key(&key, |(k, _)| k)
367 .ok()
368 .map(|i| &self.entries[i].1)
369 }
370 pub fn len(&self) -> usize {
372 self.entries.len()
373 }
374 pub fn is_empty(&self) -> bool {
376 self.entries.is_empty()
377 }
378 pub fn keys(&self) -> Vec<&K> {
380 self.entries.iter().map(|(k, _)| k).collect()
381 }
382 pub fn values(&self) -> Vec<&V> {
384 self.entries.iter().map(|(_, v)| v).collect()
385 }
386}
387#[allow(dead_code)]
389pub struct StatSummary {
390 count: u64,
391 sum: f64,
392 min: f64,
393 max: f64,
394}
395#[allow(dead_code)]
396impl StatSummary {
397 pub fn new() -> Self {
399 Self {
400 count: 0,
401 sum: 0.0,
402 min: f64::INFINITY,
403 max: f64::NEG_INFINITY,
404 }
405 }
406 pub fn record(&mut self, val: f64) {
408 self.count += 1;
409 self.sum += val;
410 if val < self.min {
411 self.min = val;
412 }
413 if val > self.max {
414 self.max = val;
415 }
416 }
417 pub fn mean(&self) -> Option<f64> {
419 if self.count == 0 {
420 None
421 } else {
422 Some(self.sum / self.count as f64)
423 }
424 }
425 pub fn min(&self) -> Option<f64> {
427 if self.count == 0 {
428 None
429 } else {
430 Some(self.min)
431 }
432 }
433 pub fn max(&self) -> Option<f64> {
435 if self.count == 0 {
436 None
437 } else {
438 Some(self.max)
439 }
440 }
441 pub fn count(&self) -> u64 {
443 self.count
444 }
445}
446#[allow(dead_code)]
448pub struct MinHeap<T: Ord> {
449 data: Vec<T>,
450}
451#[allow(dead_code)]
452impl<T: Ord> MinHeap<T> {
453 pub fn new() -> Self {
455 Self { data: Vec::new() }
456 }
457 pub fn push(&mut self, val: T) {
459 self.data.push(val);
460 self.sift_up(self.data.len() - 1);
461 }
462 pub fn pop(&mut self) -> Option<T> {
464 if self.data.is_empty() {
465 return None;
466 }
467 let n = self.data.len();
468 self.data.swap(0, n - 1);
469 let min = self.data.pop();
470 if !self.data.is_empty() {
471 self.sift_down(0);
472 }
473 min
474 }
475 pub fn peek(&self) -> Option<&T> {
477 self.data.first()
478 }
479 pub fn len(&self) -> usize {
481 self.data.len()
482 }
483 pub fn is_empty(&self) -> bool {
485 self.data.is_empty()
486 }
487 fn sift_up(&mut self, mut i: usize) {
488 while i > 0 {
489 let parent = (i - 1) / 2;
490 if self.data[i] < self.data[parent] {
491 self.data.swap(i, parent);
492 i = parent;
493 } else {
494 break;
495 }
496 }
497 }
498 fn sift_down(&mut self, mut i: usize) {
499 let n = self.data.len();
500 loop {
501 let left = 2 * i + 1;
502 let right = 2 * i + 2;
503 let mut smallest = i;
504 if left < n && self.data[left] < self.data[smallest] {
505 smallest = left;
506 }
507 if right < n && self.data[right] < self.data[smallest] {
508 smallest = right;
509 }
510 if smallest == i {
511 break;
512 }
513 self.data.swap(i, smallest);
514 i = smallest;
515 }
516 }
517}
518#[allow(dead_code)]
520#[allow(missing_docs)]
521pub struct RewriteRule {
522 pub name: String,
524 pub lhs: String,
526 pub rhs: String,
528 pub conditional: bool,
530}
531#[allow(dead_code)]
532impl RewriteRule {
533 pub fn unconditional(
535 name: impl Into<String>,
536 lhs: impl Into<String>,
537 rhs: impl Into<String>,
538 ) -> Self {
539 Self {
540 name: name.into(),
541 lhs: lhs.into(),
542 rhs: rhs.into(),
543 conditional: false,
544 }
545 }
546 pub fn conditional(
548 name: impl Into<String>,
549 lhs: impl Into<String>,
550 rhs: impl Into<String>,
551 ) -> Self {
552 Self {
553 name: name.into(),
554 lhs: lhs.into(),
555 rhs: rhs.into(),
556 conditional: true,
557 }
558 }
559 pub fn display(&self) -> String {
561 format!("{}: {} → {}", self.name, self.lhs, self.rhs)
562 }
563}
564#[allow(dead_code)]
566pub struct TransitiveClosure {
567 adj: Vec<Vec<usize>>,
568 n: usize,
569}
570#[allow(dead_code)]
571impl TransitiveClosure {
572 pub fn new(n: usize) -> Self {
574 Self {
575 adj: vec![Vec::new(); n],
576 n,
577 }
578 }
579 pub fn add_edge(&mut self, from: usize, to: usize) {
581 if from < self.n {
582 self.adj[from].push(to);
583 }
584 }
585 pub fn reachable_from(&self, start: usize) -> Vec<usize> {
587 let mut visited = vec![false; self.n];
588 let mut queue = std::collections::VecDeque::new();
589 queue.push_back(start);
590 while let Some(node) = queue.pop_front() {
591 if node >= self.n || visited[node] {
592 continue;
593 }
594 visited[node] = true;
595 for &next in &self.adj[node] {
596 queue.push_back(next);
597 }
598 }
599 (0..self.n).filter(|&i| visited[i]).collect()
600 }
601 pub fn can_reach(&self, from: usize, to: usize) -> bool {
603 self.reachable_from(from).contains(&to)
604 }
605}
606#[allow(dead_code)]
608pub struct PathBuf {
609 components: Vec<String>,
610}
611#[allow(dead_code)]
612impl PathBuf {
613 pub fn new() -> Self {
615 Self {
616 components: Vec::new(),
617 }
618 }
619 pub fn push(&mut self, comp: impl Into<String>) {
621 self.components.push(comp.into());
622 }
623 pub fn pop(&mut self) {
625 self.components.pop();
626 }
627 pub fn as_str(&self) -> String {
629 self.components.join("/")
630 }
631 pub fn depth(&self) -> usize {
633 self.components.len()
634 }
635 pub fn clear(&mut self) {
637 self.components.clear();
638 }
639}
640#[allow(dead_code)]
642pub struct RawFnPtr {
643 ptr: usize,
645 arity: usize,
646 name: String,
647}
648#[allow(dead_code)]
649impl RawFnPtr {
650 pub fn new(ptr: usize, arity: usize, name: impl Into<String>) -> Self {
652 Self {
653 ptr,
654 arity,
655 name: name.into(),
656 }
657 }
658 pub fn arity(&self) -> usize {
660 self.arity
661 }
662 pub fn name(&self) -> &str {
664 &self.name
665 }
666 pub fn raw(&self) -> usize {
668 self.ptr
669 }
670}
671#[allow(dead_code)]
673pub struct Stopwatch {
674 start: crate::wall_clock::Instant,
675 splits: Vec<f64>,
676}
677#[allow(dead_code)]
678impl Stopwatch {
679 pub fn start() -> Self {
681 Self {
682 start: crate::wall_clock::Instant::now(),
683 splits: Vec::new(),
684 }
685 }
686 pub fn split(&mut self) {
688 self.splits.push(self.elapsed_ms());
689 }
690 pub fn elapsed_ms(&self) -> f64 {
692 self.start.elapsed().as_secs_f64() * 1000.0
693 }
694 pub fn splits(&self) -> &[f64] {
696 &self.splits
697 }
698 pub fn num_splits(&self) -> usize {
700 self.splits.len()
701 }
702}
703#[allow(dead_code)]
705#[allow(missing_docs)]
706pub enum DecisionNode {
707 Leaf(String),
709 Branch {
711 key: String,
712 val: String,
713 yes_branch: Box<DecisionNode>,
714 no_branch: Box<DecisionNode>,
715 },
716}
717#[allow(dead_code)]
718impl DecisionNode {
719 pub fn evaluate(&self, ctx: &std::collections::HashMap<String, String>) -> &str {
721 match self {
722 DecisionNode::Leaf(action) => action.as_str(),
723 DecisionNode::Branch {
724 key,
725 val,
726 yes_branch,
727 no_branch,
728 } => {
729 let actual = ctx.get(key).map(|s| s.as_str()).unwrap_or("");
730 if actual == val.as_str() {
731 yes_branch.evaluate(ctx)
732 } else {
733 no_branch.evaluate(ctx)
734 }
735 }
736 }
737 }
738 pub fn depth(&self) -> usize {
740 match self {
741 DecisionNode::Leaf(_) => 0,
742 DecisionNode::Branch {
743 yes_branch,
744 no_branch,
745 ..
746 } => 1 + yes_branch.depth().max(no_branch.depth()),
747 }
748 }
749}
750#[allow(dead_code)]
752pub struct ConfigNode {
753 key: String,
754 value: Option<String>,
755 children: Vec<ConfigNode>,
756}
757#[allow(dead_code)]
758impl ConfigNode {
759 pub fn leaf(key: impl Into<String>, value: impl Into<String>) -> Self {
761 Self {
762 key: key.into(),
763 value: Some(value.into()),
764 children: Vec::new(),
765 }
766 }
767 pub fn section(key: impl Into<String>) -> Self {
769 Self {
770 key: key.into(),
771 value: None,
772 children: Vec::new(),
773 }
774 }
775 pub fn add_child(&mut self, child: ConfigNode) {
777 self.children.push(child);
778 }
779 pub fn key(&self) -> &str {
781 &self.key
782 }
783 pub fn value(&self) -> Option<&str> {
785 self.value.as_deref()
786 }
787 pub fn num_children(&self) -> usize {
789 self.children.len()
790 }
791 pub fn lookup(&self, path: &str) -> Option<&str> {
793 let mut parts = path.splitn(2, '.');
794 let head = parts.next()?;
795 let tail = parts.next();
796 if head != self.key {
797 return None;
798 }
799 match tail {
800 None => self.value.as_deref(),
801 Some(rest) => self.children.iter().find_map(|c| c.lookup_relative(rest)),
802 }
803 }
804 fn lookup_relative(&self, path: &str) -> Option<&str> {
805 let mut parts = path.splitn(2, '.');
806 let head = parts.next()?;
807 let tail = parts.next();
808 if head != self.key {
809 return None;
810 }
811 match tail {
812 None => self.value.as_deref(),
813 Some(rest) => self.children.iter().find_map(|c| c.lookup_relative(rest)),
814 }
815 }
816}
817#[allow(dead_code)]
819pub struct VersionedRecord<T: Clone> {
820 earlier: Vec<T>,
822 current: T,
824}
825#[allow(dead_code)]
826impl<T: Clone> VersionedRecord<T> {
827 pub fn new(initial: T) -> Self {
829 Self {
830 earlier: Vec::new(),
831 current: initial,
832 }
833 }
834 pub fn update(&mut self, val: T) {
836 let previous = std::mem::replace(&mut self.current, val);
837 self.earlier.push(previous);
838 }
839 pub fn current(&self) -> &T {
841 &self.current
842 }
843 pub fn at_version(&self, n: usize) -> Option<&T> {
845 match self.earlier.get(n) {
846 Some(value) => Some(value),
847 None if n == self.earlier.len() => Some(&self.current),
848 None => None,
849 }
850 }
851 pub fn version(&self) -> usize {
853 self.earlier.len()
854 }
855 pub fn has_history(&self) -> bool {
857 !self.earlier.is_empty()
858 }
859}
860#[allow(dead_code)]
862pub enum Either2<A, B> {
863 First(A),
865 Second(B),
867}
868#[allow(dead_code)]
869impl<A, B> Either2<A, B> {
870 pub fn is_first(&self) -> bool {
872 matches!(self, Either2::First(_))
873 }
874 pub fn is_second(&self) -> bool {
876 matches!(self, Either2::Second(_))
877 }
878 pub fn first(self) -> Option<A> {
880 match self {
881 Either2::First(a) => Some(a),
882 _ => None,
883 }
884 }
885 pub fn second(self) -> Option<B> {
887 match self {
888 Either2::Second(b) => Some(b),
889 _ => None,
890 }
891 }
892 pub fn map_first<C, F: FnOnce(A) -> C>(self, f: F) -> Either2<C, B> {
894 match self {
895 Either2::First(a) => Either2::First(f(a)),
896 Either2::Second(b) => Either2::Second(b),
897 }
898 }
899}
900#[allow(dead_code)]
902pub struct FocusStack<T> {
903 items: Vec<T>,
904}
905#[allow(dead_code)]
906impl<T> FocusStack<T> {
907 pub fn new() -> Self {
909 Self { items: Vec::new() }
910 }
911 pub fn focus(&mut self, item: T) {
913 self.items.push(item);
914 }
915 pub fn blur(&mut self) -> Option<T> {
917 self.items.pop()
918 }
919 pub fn current(&self) -> Option<&T> {
921 self.items.last()
922 }
923 pub fn depth(&self) -> usize {
925 self.items.len()
926 }
927 pub fn is_empty(&self) -> bool {
929 self.items.is_empty()
930 }
931}
932#[allow(dead_code)]
934pub struct PrefixCounter {
935 children: std::collections::HashMap<char, PrefixCounter>,
936 count: usize,
937}
938#[allow(dead_code)]
939impl PrefixCounter {
940 pub fn new() -> Self {
942 Self {
943 children: std::collections::HashMap::new(),
944 count: 0,
945 }
946 }
947 pub fn record(&mut self, s: &str) {
949 self.count += 1;
950 let mut node = self;
951 for c in s.chars() {
952 node = node.children.entry(c).or_default();
953 node.count += 1;
954 }
955 }
956 pub fn count_with_prefix(&self, prefix: &str) -> usize {
958 let mut node = self;
959 for c in prefix.chars() {
960 match node.children.get(&c) {
961 Some(n) => node = n,
962 None => return 0,
963 }
964 }
965 node.count
966 }
967}
968#[allow(dead_code)]
970pub struct SlidingSum {
971 window: Vec<f64>,
972 capacity: usize,
973 pos: usize,
974 sum: f64,
975 count: usize,
976}
977#[allow(dead_code)]
978impl SlidingSum {
979 pub fn new(capacity: usize) -> Self {
981 Self {
982 window: vec![0.0; capacity],
983 capacity,
984 pos: 0,
985 sum: 0.0,
986 count: 0,
987 }
988 }
989 pub fn push(&mut self, val: f64) {
991 let oldest = self.window[self.pos];
992 self.sum -= oldest;
993 self.sum += val;
994 self.window[self.pos] = val;
995 self.pos = (self.pos + 1) % self.capacity;
996 if self.count < self.capacity {
997 self.count += 1;
998 }
999 }
1000 pub fn sum(&self) -> f64 {
1002 self.sum
1003 }
1004 pub fn mean(&self) -> Option<f64> {
1006 if self.count == 0 {
1007 None
1008 } else {
1009 Some(self.sum / self.count as f64)
1010 }
1011 }
1012 pub fn count(&self) -> usize {
1014 self.count
1015 }
1016}
1017#[allow(dead_code)]
1019pub struct StackCalc {
1020 stack: Vec<i64>,
1021}
1022#[allow(dead_code)]
1023impl StackCalc {
1024 pub fn new() -> Self {
1026 Self { stack: Vec::new() }
1027 }
1028 pub fn push(&mut self, n: i64) {
1030 self.stack.push(n);
1031 }
1032 fn apply_binary(&mut self, op: impl FnOnce(i64, i64) -> i64) -> Option<i64> {
1036 let (rest_len, a, b) = match self.stack[..] {
1037 [ref rest @ .., a, b] => (rest.len(), a, b),
1038 _ => return None,
1039 };
1040 let value = op(a, b);
1041 self.stack.truncate(rest_len);
1042 self.stack.push(value);
1043 Some(value)
1044 }
1045 pub fn add(&mut self) -> Option<i64> {
1049 self.apply_binary(|a, b| a + b)
1050 }
1051 pub fn sub(&mut self) -> Option<i64> {
1055 self.apply_binary(|a, b| a - b)
1056 }
1057 pub fn mul(&mut self) -> Option<i64> {
1061 self.apply_binary(|a, b| a * b)
1062 }
1063 pub fn peek(&self) -> Option<i64> {
1065 self.stack.last().copied()
1066 }
1067 pub fn depth(&self) -> usize {
1069 self.stack.len()
1070 }
1071}
1072#[allow(dead_code)]
1074pub struct SimpleDag {
1075 edges: Vec<Vec<usize>>,
1077}
1078#[allow(dead_code)]
1079impl SimpleDag {
1080 pub fn new(n: usize) -> Self {
1082 Self {
1083 edges: vec![Vec::new(); n],
1084 }
1085 }
1086 pub fn add_edge(&mut self, from: usize, to: usize) {
1088 if from < self.edges.len() {
1089 self.edges[from].push(to);
1090 }
1091 }
1092 pub fn successors(&self, node: usize) -> &[usize] {
1094 self.edges.get(node).map(|v| v.as_slice()).unwrap_or(&[])
1095 }
1096 pub fn can_reach(&self, from: usize, to: usize) -> bool {
1098 let mut visited = vec![false; self.edges.len()];
1099 self.dfs(from, to, &mut visited)
1100 }
1101 fn dfs(&self, cur: usize, target: usize, visited: &mut Vec<bool>) -> bool {
1102 if cur == target {
1103 return true;
1104 }
1105 if cur >= visited.len() || visited[cur] {
1106 return false;
1107 }
1108 visited[cur] = true;
1109 for &next in self.successors(cur) {
1110 if self.dfs(next, target, visited) {
1111 return true;
1112 }
1113 }
1114 false
1115 }
1116 pub fn topological_sort(&self) -> Option<Vec<usize>> {
1118 let n = self.edges.len();
1119 let mut in_degree = vec![0usize; n];
1120 for succs in &self.edges {
1121 for &s in succs {
1122 if s < n {
1123 in_degree[s] += 1;
1124 }
1125 }
1126 }
1127 let mut queue: std::collections::VecDeque<usize> =
1128 (0..n).filter(|&i| in_degree[i] == 0).collect();
1129 let mut order = Vec::new();
1130 while let Some(node) = queue.pop_front() {
1131 order.push(node);
1132 for &s in self.successors(node) {
1133 if s < n {
1134 in_degree[s] -= 1;
1135 if in_degree[s] == 0 {
1136 queue.push_back(s);
1137 }
1138 }
1139 }
1140 }
1141 if order.len() == n {
1142 Some(order)
1143 } else {
1144 None
1145 }
1146 }
1147 pub fn num_nodes(&self) -> usize {
1149 self.edges.len()
1150 }
1151}
1152#[allow(dead_code)]
1154pub struct WriteOnce<T> {
1155 value: std::cell::Cell<Option<T>>,
1156}
1157#[allow(dead_code)]
1158impl<T: Copy> WriteOnce<T> {
1159 pub fn new() -> Self {
1161 Self {
1162 value: std::cell::Cell::new(None),
1163 }
1164 }
1165 pub fn write(&self, val: T) -> bool {
1167 if self.value.get().is_some() {
1168 return false;
1169 }
1170 self.value.set(Some(val));
1171 true
1172 }
1173 pub fn read(&self) -> Option<T> {
1175 self.value.get()
1176 }
1177 pub fn is_written(&self) -> bool {
1179 self.value.get().is_some()
1180 }
1181}
1182#[derive(Clone, Debug, Default)]
1184pub struct NamedSubst {
1185 map: std::collections::HashMap<Name, Expr>,
1186}
1187impl NamedSubst {
1188 pub fn new() -> Self {
1190 Self::default()
1191 }
1192 pub fn insert(&mut self, name: Name, val: Expr) {
1194 self.map.insert(name, val);
1195 }
1196 pub fn get(&self, name: &Name) -> Option<&Expr> {
1198 self.map.get(name)
1199 }
1200 pub fn len(&self) -> usize {
1202 self.map.len()
1203 }
1204 pub fn is_empty(&self) -> bool {
1206 self.map.is_empty()
1207 }
1208 pub fn apply(&self, expr: &Expr) -> Expr {
1212 named_subst_apply(expr, self)
1213 }
1214}
1215#[allow(dead_code)]
1217pub struct TransformStat {
1218 before: StatSummary,
1219 after: StatSummary,
1220}
1221#[allow(dead_code)]
1222impl TransformStat {
1223 pub fn new() -> Self {
1225 Self {
1226 before: StatSummary::new(),
1227 after: StatSummary::new(),
1228 }
1229 }
1230 pub fn record_before(&mut self, v: f64) {
1232 self.before.record(v);
1233 }
1234 pub fn record_after(&mut self, v: f64) {
1236 self.after.record(v);
1237 }
1238 pub fn mean_ratio(&self) -> Option<f64> {
1240 let b = self.before.mean()?;
1241 let a = self.after.mean()?;
1242 if b.abs() < f64::EPSILON {
1243 return None;
1244 }
1245 Some(a / b)
1246 }
1247}
1248#[allow(dead_code)]
1250pub struct TokenBucket {
1251 capacity: u64,
1252 tokens: u64,
1253 refill_per_ms: u64,
1254 last_refill: crate::wall_clock::Instant,
1255}
1256#[allow(dead_code)]
1257impl TokenBucket {
1258 pub fn new(capacity: u64, refill_per_ms: u64) -> Self {
1260 Self {
1261 capacity,
1262 tokens: capacity,
1263 refill_per_ms,
1264 last_refill: crate::wall_clock::Instant::now(),
1265 }
1266 }
1267 pub fn try_consume(&mut self, n: u64) -> bool {
1269 self.refill();
1270 if self.tokens >= n {
1271 self.tokens -= n;
1272 true
1273 } else {
1274 false
1275 }
1276 }
1277 fn refill(&mut self) {
1278 let now = crate::wall_clock::Instant::now();
1279 let elapsed_ms = now.duration_since(self.last_refill).as_millis() as u64;
1280 if elapsed_ms > 0 {
1281 let new_tokens = elapsed_ms * self.refill_per_ms;
1282 self.tokens = (self.tokens + new_tokens).min(self.capacity);
1283 self.last_refill = now;
1284 }
1285 }
1286 pub fn available(&self) -> u64 {
1288 self.tokens
1289 }
1290 pub fn capacity(&self) -> u64 {
1292 self.capacity
1293 }
1294}