1use crate::Name;
6
7use std::collections::HashMap;
8
9use super::functions::{is_equivalent, is_leq};
10
11#[allow(dead_code)]
13#[allow(missing_docs)]
14pub enum DecisionNode {
15 Leaf(String),
17 Branch {
19 key: String,
20 val: String,
21 yes_branch: Box<DecisionNode>,
22 no_branch: Box<DecisionNode>,
23 },
24}
25#[allow(dead_code)]
26impl DecisionNode {
27 pub fn evaluate(&self, ctx: &std::collections::HashMap<String, String>) -> &str {
29 match self {
30 DecisionNode::Leaf(action) => action.as_str(),
31 DecisionNode::Branch {
32 key,
33 val,
34 yes_branch,
35 no_branch,
36 } => {
37 let actual = ctx.get(key).map(|s| s.as_str()).unwrap_or("");
38 if actual == val.as_str() {
39 yes_branch.evaluate(ctx)
40 } else {
41 no_branch.evaluate(ctx)
42 }
43 }
44 }
45 }
46 pub fn depth(&self) -> usize {
48 match self {
49 DecisionNode::Leaf(_) => 0,
50 DecisionNode::Branch {
51 yes_branch,
52 no_branch,
53 ..
54 } => 1 + yes_branch.depth().max(no_branch.depth()),
55 }
56 }
57}
58#[allow(dead_code)]
60pub struct FlatSubstitution {
61 pairs: Vec<(String, String)>,
62}
63#[allow(dead_code)]
64impl FlatSubstitution {
65 pub fn new() -> Self {
67 Self { pairs: Vec::new() }
68 }
69 pub fn add(&mut self, from: impl Into<String>, to: impl Into<String>) {
71 self.pairs.push((from.into(), to.into()));
72 }
73 pub fn apply(&self, s: &str) -> String {
75 let mut result = s.to_string();
76 for (from, to) in &self.pairs {
77 result = result.replace(from.as_str(), to.as_str());
78 }
79 result
80 }
81 pub fn len(&self) -> usize {
83 self.pairs.len()
84 }
85 pub fn is_empty(&self) -> bool {
87 self.pairs.is_empty()
88 }
89}
90#[allow(dead_code)]
92#[derive(Debug, Clone, PartialEq)]
93pub enum LevelConstraint {
94 Leq(Level, Level),
96 Eq(Level, Level),
98}
99impl LevelConstraint {
100 #[allow(dead_code)]
104 pub fn is_satisfied(&self) -> bool {
105 match self {
106 LevelConstraint::Leq(l1, l2) => is_leq(l1, l2),
107 LevelConstraint::Eq(l1, l2) => is_equivalent(l1, l2),
108 }
109 }
110 #[allow(dead_code)]
112 pub fn levels(&self) -> (&Level, &Level) {
113 match self {
114 LevelConstraint::Leq(l1, l2) | LevelConstraint::Eq(l1, l2) => (l1, l2),
115 }
116 }
117}
118#[allow(dead_code)]
120pub struct ConfigNode {
121 key: String,
122 value: Option<String>,
123 children: Vec<ConfigNode>,
124}
125#[allow(dead_code)]
126impl ConfigNode {
127 pub fn leaf(key: impl Into<String>, value: impl Into<String>) -> Self {
129 Self {
130 key: key.into(),
131 value: Some(value.into()),
132 children: Vec::new(),
133 }
134 }
135 pub fn section(key: impl Into<String>) -> Self {
137 Self {
138 key: key.into(),
139 value: None,
140 children: Vec::new(),
141 }
142 }
143 pub fn add_child(&mut self, child: ConfigNode) {
145 self.children.push(child);
146 }
147 pub fn key(&self) -> &str {
149 &self.key
150 }
151 pub fn value(&self) -> Option<&str> {
153 self.value.as_deref()
154 }
155 pub fn num_children(&self) -> usize {
157 self.children.len()
158 }
159 pub fn lookup(&self, path: &str) -> Option<&str> {
161 let mut parts = path.splitn(2, '.');
162 let head = parts.next()?;
163 let tail = parts.next();
164 if head != self.key {
165 return None;
166 }
167 match tail {
168 None => self.value.as_deref(),
169 Some(rest) => self.children.iter().find_map(|c| c.lookup_relative(rest)),
170 }
171 }
172 fn lookup_relative(&self, path: &str) -> Option<&str> {
173 let mut parts = path.splitn(2, '.');
174 let head = parts.next()?;
175 let tail = parts.next();
176 if head != self.key {
177 return None;
178 }
179 match tail {
180 None => self.value.as_deref(),
181 Some(rest) => self.children.iter().find_map(|c| c.lookup_relative(rest)),
182 }
183 }
184}
185#[allow(dead_code)]
187pub struct WindowIterator<'a, T> {
188 pub(super) data: &'a [T],
189 pub(super) pos: usize,
190 pub(super) window: usize,
191}
192#[allow(dead_code)]
193impl<'a, T> WindowIterator<'a, T> {
194 pub fn new(data: &'a [T], window: usize) -> Self {
196 Self {
197 data,
198 pos: 0,
199 window,
200 }
201 }
202}
203#[allow(dead_code)]
205pub struct Stopwatch {
206 start: std::time::Instant,
207 splits: Vec<f64>,
208}
209#[allow(dead_code)]
210impl Stopwatch {
211 pub fn start() -> Self {
213 Self {
214 start: std::time::Instant::now(),
215 splits: Vec::new(),
216 }
217 }
218 pub fn split(&mut self) {
220 self.splits.push(self.elapsed_ms());
221 }
222 pub fn elapsed_ms(&self) -> f64 {
224 self.start.elapsed().as_secs_f64() * 1000.0
225 }
226 pub fn splits(&self) -> &[f64] {
228 &self.splits
229 }
230 pub fn num_splits(&self) -> usize {
232 self.splits.len()
233 }
234}
235#[allow(dead_code)]
237pub struct WriteOnce<T> {
238 value: std::cell::Cell<Option<T>>,
239}
240#[allow(dead_code)]
241impl<T: Copy> WriteOnce<T> {
242 pub fn new() -> Self {
244 Self {
245 value: std::cell::Cell::new(None),
246 }
247 }
248 pub fn write(&self, val: T) -> bool {
250 if self.value.get().is_some() {
251 return false;
252 }
253 self.value.set(Some(val));
254 true
255 }
256 pub fn read(&self) -> Option<T> {
258 self.value.get()
259 }
260 pub fn is_written(&self) -> bool {
262 self.value.get().is_some()
263 }
264}
265#[allow(dead_code)]
267pub enum Either2<A, B> {
268 First(A),
270 Second(B),
272}
273#[allow(dead_code)]
274impl<A, B> Either2<A, B> {
275 pub fn is_first(&self) -> bool {
277 matches!(self, Either2::First(_))
278 }
279 pub fn is_second(&self) -> bool {
281 matches!(self, Either2::Second(_))
282 }
283 pub fn first(self) -> Option<A> {
285 match self {
286 Either2::First(a) => Some(a),
287 _ => None,
288 }
289 }
290 pub fn second(self) -> Option<B> {
292 match self {
293 Either2::Second(b) => Some(b),
294 _ => None,
295 }
296 }
297 pub fn map_first<C, F: FnOnce(A) -> C>(self, f: F) -> Either2<C, B> {
299 match self {
300 Either2::First(a) => Either2::First(f(a)),
301 Either2::Second(b) => Either2::Second(b),
302 }
303 }
304}
305#[allow(dead_code)]
307pub struct VersionedRecord<T: Clone> {
308 history: Vec<T>,
309}
310#[allow(dead_code)]
311impl<T: Clone> VersionedRecord<T> {
312 pub fn new(initial: T) -> Self {
314 Self {
315 history: vec![initial],
316 }
317 }
318 pub fn update(&mut self, val: T) {
320 self.history.push(val);
321 }
322 pub fn current(&self) -> &T {
324 self.history
325 .last()
326 .expect("VersionedRecord history is always non-empty after construction")
327 }
328 pub fn at_version(&self, n: usize) -> Option<&T> {
330 self.history.get(n)
331 }
332 pub fn version(&self) -> usize {
334 self.history.len() - 1
335 }
336 pub fn has_history(&self) -> bool {
338 self.history.len() > 1
339 }
340}
341#[allow(dead_code)]
343pub struct Fixture {
344 data: std::collections::HashMap<String, String>,
345}
346#[allow(dead_code)]
347impl Fixture {
348 pub fn new() -> Self {
350 Self {
351 data: std::collections::HashMap::new(),
352 }
353 }
354 pub fn set(&mut self, key: impl Into<String>, val: impl Into<String>) {
356 self.data.insert(key.into(), val.into());
357 }
358 pub fn get(&self, key: &str) -> Option<&str> {
360 self.data.get(key).map(|s| s.as_str())
361 }
362 pub fn len(&self) -> usize {
364 self.data.len()
365 }
366 pub fn is_empty(&self) -> bool {
368 self.len() == 0
369 }
370}
371#[allow(dead_code)]
373pub struct RawFnPtr {
374 ptr: usize,
376 arity: usize,
377 name: String,
378}
379#[allow(dead_code)]
380impl RawFnPtr {
381 pub fn new(ptr: usize, arity: usize, name: impl Into<String>) -> Self {
383 Self {
384 ptr,
385 arity,
386 name: name.into(),
387 }
388 }
389 pub fn arity(&self) -> usize {
391 self.arity
392 }
393 pub fn name(&self) -> &str {
395 &self.name
396 }
397 pub fn raw(&self) -> usize {
399 self.ptr
400 }
401}
402#[allow(dead_code)]
404pub struct FocusStack<T> {
405 items: Vec<T>,
406}
407#[allow(dead_code)]
408impl<T> FocusStack<T> {
409 pub fn new() -> Self {
411 Self { items: Vec::new() }
412 }
413 pub fn focus(&mut self, item: T) {
415 self.items.push(item);
416 }
417 pub fn blur(&mut self) -> Option<T> {
419 self.items.pop()
420 }
421 pub fn current(&self) -> Option<&T> {
423 self.items.last()
424 }
425 pub fn depth(&self) -> usize {
427 self.items.len()
428 }
429 pub fn is_empty(&self) -> bool {
431 self.items.is_empty()
432 }
433}
434#[allow(dead_code)]
436pub struct TransitiveClosure {
437 adj: Vec<Vec<usize>>,
438 n: usize,
439}
440#[allow(dead_code)]
441impl TransitiveClosure {
442 pub fn new(n: usize) -> Self {
444 Self {
445 adj: vec![Vec::new(); n],
446 n,
447 }
448 }
449 pub fn add_edge(&mut self, from: usize, to: usize) {
451 if from < self.n {
452 self.adj[from].push(to);
453 }
454 }
455 pub fn reachable_from(&self, start: usize) -> Vec<usize> {
457 let mut visited = vec![false; self.n];
458 let mut queue = std::collections::VecDeque::new();
459 queue.push_back(start);
460 while let Some(node) = queue.pop_front() {
461 if node >= self.n || visited[node] {
462 continue;
463 }
464 visited[node] = true;
465 for &next in &self.adj[node] {
466 queue.push_back(next);
467 }
468 }
469 (0..self.n).filter(|&i| visited[i]).collect()
470 }
471 pub fn can_reach(&self, from: usize, to: usize) -> bool {
473 self.reachable_from(from).contains(&to)
474 }
475}
476#[allow(dead_code)]
478pub struct LabelSet {
479 labels: Vec<String>,
480}
481#[allow(dead_code)]
482impl LabelSet {
483 pub fn new() -> Self {
485 Self { labels: Vec::new() }
486 }
487 pub fn add(&mut self, label: impl Into<String>) {
489 let s = label.into();
490 if !self.labels.contains(&s) {
491 self.labels.push(s);
492 }
493 }
494 pub fn has(&self, label: &str) -> bool {
496 self.labels.iter().any(|l| l == label)
497 }
498 pub fn count(&self) -> usize {
500 self.labels.len()
501 }
502 pub fn all(&self) -> &[String] {
504 &self.labels
505 }
506}
507#[allow(dead_code)]
509pub struct RewriteRuleSet {
510 rules: Vec<RewriteRule>,
511}
512#[allow(dead_code)]
513impl RewriteRuleSet {
514 pub fn new() -> Self {
516 Self { rules: Vec::new() }
517 }
518 pub fn add(&mut self, rule: RewriteRule) {
520 self.rules.push(rule);
521 }
522 pub fn len(&self) -> usize {
524 self.rules.len()
525 }
526 pub fn is_empty(&self) -> bool {
528 self.rules.is_empty()
529 }
530 pub fn conditional_rules(&self) -> Vec<&RewriteRule> {
532 self.rules.iter().filter(|r| r.conditional).collect()
533 }
534 pub fn unconditional_rules(&self) -> Vec<&RewriteRule> {
536 self.rules.iter().filter(|r| !r.conditional).collect()
537 }
538 pub fn get(&self, name: &str) -> Option<&RewriteRule> {
540 self.rules.iter().find(|r| r.name == name)
541 }
542}
543#[allow(dead_code)]
545pub struct SmallMap<K: Ord + Clone, V: Clone> {
546 entries: Vec<(K, V)>,
547}
548#[allow(dead_code)]
549impl<K: Ord + Clone, V: Clone> SmallMap<K, V> {
550 pub fn new() -> Self {
552 Self {
553 entries: Vec::new(),
554 }
555 }
556 pub fn insert(&mut self, key: K, val: V) {
558 match self.entries.binary_search_by_key(&&key, |(k, _)| k) {
559 Ok(i) => self.entries[i].1 = val,
560 Err(i) => self.entries.insert(i, (key, val)),
561 }
562 }
563 pub fn get(&self, key: &K) -> Option<&V> {
565 self.entries
566 .binary_search_by_key(&key, |(k, _)| k)
567 .ok()
568 .map(|i| &self.entries[i].1)
569 }
570 pub fn len(&self) -> usize {
572 self.entries.len()
573 }
574 pub fn is_empty(&self) -> bool {
576 self.entries.is_empty()
577 }
578 pub fn keys(&self) -> Vec<&K> {
580 self.entries.iter().map(|(k, _)| k).collect()
581 }
582 pub fn values(&self) -> Vec<&V> {
584 self.entries.iter().map(|(_, v)| v).collect()
585 }
586}
587#[allow(dead_code)]
589pub struct TokenBucket {
590 capacity: u64,
591 tokens: u64,
592 refill_per_ms: u64,
593 last_refill: std::time::Instant,
594}
595#[allow(dead_code)]
596impl TokenBucket {
597 pub fn new(capacity: u64, refill_per_ms: u64) -> Self {
599 Self {
600 capacity,
601 tokens: capacity,
602 refill_per_ms,
603 last_refill: std::time::Instant::now(),
604 }
605 }
606 pub fn try_consume(&mut self, n: u64) -> bool {
608 self.refill();
609 if self.tokens >= n {
610 self.tokens -= n;
611 true
612 } else {
613 false
614 }
615 }
616 fn refill(&mut self) {
617 let now = std::time::Instant::now();
618 let elapsed_ms = now.duration_since(self.last_refill).as_millis() as u64;
619 if elapsed_ms > 0 {
620 let new_tokens = elapsed_ms * self.refill_per_ms;
621 self.tokens = (self.tokens + new_tokens).min(self.capacity);
622 self.last_refill = now;
623 }
624 }
625 pub fn available(&self) -> u64 {
627 self.tokens
628 }
629 pub fn capacity(&self) -> u64 {
631 self.capacity
632 }
633}
634#[allow(dead_code)]
636pub struct StackCalc {
637 stack: Vec<i64>,
638}
639#[allow(dead_code)]
640impl StackCalc {
641 pub fn new() -> Self {
643 Self { stack: Vec::new() }
644 }
645 pub fn push(&mut self, n: i64) {
647 self.stack.push(n);
648 }
649 pub fn add(&mut self) {
651 let b = self
652 .stack
653 .pop()
654 .expect("stack must have at least two values for add");
655 let a = self
656 .stack
657 .pop()
658 .expect("stack must have at least two values for add");
659 self.stack.push(a + b);
660 }
661 pub fn sub(&mut self) {
663 let b = self
664 .stack
665 .pop()
666 .expect("stack must have at least two values for sub");
667 let a = self
668 .stack
669 .pop()
670 .expect("stack must have at least two values for sub");
671 self.stack.push(a - b);
672 }
673 pub fn mul(&mut self) {
675 let b = self
676 .stack
677 .pop()
678 .expect("stack must have at least two values for mul");
679 let a = self
680 .stack
681 .pop()
682 .expect("stack must have at least two values for mul");
683 self.stack.push(a * b);
684 }
685 pub fn peek(&self) -> Option<i64> {
687 self.stack.last().copied()
688 }
689 pub fn depth(&self) -> usize {
691 self.stack.len()
692 }
693}
694#[allow(dead_code)]
696#[allow(missing_docs)]
697pub struct RewriteRule {
698 pub name: String,
700 pub lhs: String,
702 pub rhs: String,
704 pub conditional: bool,
706}
707#[allow(dead_code)]
708impl RewriteRule {
709 pub fn unconditional(
711 name: impl Into<String>,
712 lhs: impl Into<String>,
713 rhs: impl Into<String>,
714 ) -> Self {
715 Self {
716 name: name.into(),
717 lhs: lhs.into(),
718 rhs: rhs.into(),
719 conditional: false,
720 }
721 }
722 pub fn conditional(
724 name: impl Into<String>,
725 lhs: impl Into<String>,
726 rhs: impl Into<String>,
727 ) -> Self {
728 Self {
729 name: name.into(),
730 lhs: lhs.into(),
731 rhs: rhs.into(),
732 conditional: true,
733 }
734 }
735 pub fn display(&self) -> String {
737 format!("{}: {} → {}", self.name, self.lhs, self.rhs)
738 }
739}
740#[allow(dead_code)]
742#[derive(Debug, Default, Clone)]
743pub struct ConstraintSet {
744 constraints: Vec<LevelConstraint>,
745}
746impl ConstraintSet {
747 #[allow(dead_code)]
749 pub fn new() -> Self {
750 Self::default()
751 }
752 #[allow(dead_code)]
754 pub fn add(&mut self, c: LevelConstraint) {
755 self.constraints.push(c);
756 }
757 #[allow(dead_code)]
759 pub fn add_leq(&mut self, l1: Level, l2: Level) {
760 self.add(LevelConstraint::Leq(l1, l2));
761 }
762 #[allow(dead_code)]
764 pub fn add_eq(&mut self, l1: Level, l2: Level) {
765 self.add(LevelConstraint::Eq(l1, l2));
766 }
767 #[allow(dead_code)]
769 pub fn all_satisfied(&self) -> bool {
770 self.constraints.iter().all(|c| c.is_satisfied())
771 }
772 #[allow(dead_code)]
774 pub fn unsatisfied(&self) -> Vec<&LevelConstraint> {
775 self.constraints
776 .iter()
777 .filter(|c| !c.is_satisfied())
778 .collect()
779 }
780 #[allow(dead_code)]
782 pub fn len(&self) -> usize {
783 self.constraints.len()
784 }
785 #[allow(dead_code)]
787 pub fn is_empty(&self) -> bool {
788 self.constraints.is_empty()
789 }
790}
791#[allow(dead_code)]
793pub struct SlidingSum {
794 window: Vec<f64>,
795 capacity: usize,
796 pos: usize,
797 sum: f64,
798 count: usize,
799}
800#[allow(dead_code)]
801impl SlidingSum {
802 pub fn new(capacity: usize) -> Self {
804 Self {
805 window: vec![0.0; capacity],
806 capacity,
807 pos: 0,
808 sum: 0.0,
809 count: 0,
810 }
811 }
812 pub fn push(&mut self, val: f64) {
814 let oldest = self.window[self.pos];
815 self.sum -= oldest;
816 self.sum += val;
817 self.window[self.pos] = val;
818 self.pos = (self.pos + 1) % self.capacity;
819 if self.count < self.capacity {
820 self.count += 1;
821 }
822 }
823 pub fn sum(&self) -> f64 {
825 self.sum
826 }
827 pub fn mean(&self) -> Option<f64> {
829 if self.count == 0 {
830 None
831 } else {
832 Some(self.sum / self.count as f64)
833 }
834 }
835 pub fn count(&self) -> usize {
837 self.count
838 }
839}
840#[allow(dead_code)]
842pub struct PathBuf {
843 components: Vec<String>,
844}
845#[allow(dead_code)]
846impl PathBuf {
847 pub fn new() -> Self {
849 Self {
850 components: Vec::new(),
851 }
852 }
853 pub fn push(&mut self, comp: impl Into<String>) {
855 self.components.push(comp.into());
856 }
857 pub fn pop(&mut self) {
859 self.components.pop();
860 }
861 pub fn as_str(&self) -> String {
863 self.components.join("/")
864 }
865 pub fn depth(&self) -> usize {
867 self.components.len()
868 }
869 pub fn clear(&mut self) {
871 self.components.clear();
872 }
873}
874#[allow(dead_code)]
876pub struct NonEmptyVec<T> {
877 head: T,
878 tail: Vec<T>,
879}
880#[allow(dead_code)]
881impl<T> NonEmptyVec<T> {
882 pub fn singleton(val: T) -> Self {
884 Self {
885 head: val,
886 tail: Vec::new(),
887 }
888 }
889 pub fn push(&mut self, val: T) {
891 self.tail.push(val);
892 }
893 pub fn first(&self) -> &T {
895 &self.head
896 }
897 pub fn last(&self) -> &T {
899 self.tail.last().unwrap_or(&self.head)
900 }
901 pub fn len(&self) -> usize {
903 1 + self.tail.len()
904 }
905 pub fn is_empty(&self) -> bool {
907 self.len() == 0
908 }
909 pub fn to_vec(&self) -> Vec<&T> {
911 let mut v = vec![&self.head];
912 v.extend(self.tail.iter());
913 v
914 }
915}
916#[allow(dead_code)]
918pub struct StringPool {
919 free: Vec<String>,
920}
921#[allow(dead_code)]
922impl StringPool {
923 pub fn new() -> Self {
925 Self { free: Vec::new() }
926 }
927 pub fn take(&mut self) -> String {
929 self.free.pop().unwrap_or_default()
930 }
931 pub fn give(&mut self, mut s: String) {
933 s.clear();
934 self.free.push(s);
935 }
936 pub fn free_count(&self) -> usize {
938 self.free.len()
939 }
940}
941#[allow(dead_code)]
943pub struct StatSummary {
944 count: u64,
945 sum: f64,
946 min: f64,
947 max: f64,
948}
949#[allow(dead_code)]
950impl StatSummary {
951 pub fn new() -> Self {
953 Self {
954 count: 0,
955 sum: 0.0,
956 min: f64::INFINITY,
957 max: f64::NEG_INFINITY,
958 }
959 }
960 pub fn record(&mut self, val: f64) {
962 self.count += 1;
963 self.sum += val;
964 if val < self.min {
965 self.min = val;
966 }
967 if val > self.max {
968 self.max = val;
969 }
970 }
971 pub fn mean(&self) -> Option<f64> {
973 if self.count == 0 {
974 None
975 } else {
976 Some(self.sum / self.count as f64)
977 }
978 }
979 pub fn min(&self) -> Option<f64> {
981 if self.count == 0 {
982 None
983 } else {
984 Some(self.min)
985 }
986 }
987 pub fn max(&self) -> Option<f64> {
989 if self.count == 0 {
990 None
991 } else {
992 Some(self.max)
993 }
994 }
995 pub fn count(&self) -> u64 {
997 self.count
998 }
999}
1000#[allow(dead_code)]
1002pub struct SimpleDag {
1003 edges: Vec<Vec<usize>>,
1005}
1006#[allow(dead_code)]
1007impl SimpleDag {
1008 pub fn new(n: usize) -> Self {
1010 Self {
1011 edges: vec![Vec::new(); n],
1012 }
1013 }
1014 pub fn add_edge(&mut self, from: usize, to: usize) {
1016 if from < self.edges.len() {
1017 self.edges[from].push(to);
1018 }
1019 }
1020 pub fn successors(&self, node: usize) -> &[usize] {
1022 self.edges.get(node).map(|v| v.as_slice()).unwrap_or(&[])
1023 }
1024 pub fn can_reach(&self, from: usize, to: usize) -> bool {
1026 let mut visited = vec![false; self.edges.len()];
1027 self.dfs(from, to, &mut visited)
1028 }
1029 fn dfs(&self, cur: usize, target: usize, visited: &mut Vec<bool>) -> bool {
1030 if cur == target {
1031 return true;
1032 }
1033 if cur >= visited.len() || visited[cur] {
1034 return false;
1035 }
1036 visited[cur] = true;
1037 for &next in self.successors(cur) {
1038 if self.dfs(next, target, visited) {
1039 return true;
1040 }
1041 }
1042 false
1043 }
1044 pub fn topological_sort(&self) -> Option<Vec<usize>> {
1046 let n = self.edges.len();
1047 let mut in_degree = vec![0usize; n];
1048 for succs in &self.edges {
1049 for &s in succs {
1050 if s < n {
1051 in_degree[s] += 1;
1052 }
1053 }
1054 }
1055 let mut queue: std::collections::VecDeque<usize> =
1056 (0..n).filter(|&i| in_degree[i] == 0).collect();
1057 let mut order = Vec::new();
1058 while let Some(node) = queue.pop_front() {
1059 order.push(node);
1060 for &s in self.successors(node) {
1061 if s < n {
1062 in_degree[s] -= 1;
1063 if in_degree[s] == 0 {
1064 queue.push_back(s);
1065 }
1066 }
1067 }
1068 }
1069 if order.len() == n {
1070 Some(order)
1071 } else {
1072 None
1073 }
1074 }
1075 pub fn num_nodes(&self) -> usize {
1077 self.edges.len()
1078 }
1079}
1080#[derive(Clone, PartialEq, Eq, Hash, Debug)]
1085pub enum Level {
1086 Zero,
1088 Succ(Box<Level>),
1090 Max(Box<Level>, Box<Level>),
1092 IMax(Box<Level>, Box<Level>),
1097 Param(Name),
1099 MVar(LevelMVarId),
1101}
1102impl Level {
1103 pub fn zero() -> Self {
1105 Level::Zero
1106 }
1107 pub fn succ(l: Level) -> Self {
1109 Level::Succ(Box::new(l))
1110 }
1111 pub fn max(l1: Level, l2: Level) -> Self {
1113 Level::Max(Box::new(l1), Box::new(l2))
1114 }
1115 pub fn imax(l1: Level, l2: Level) -> Self {
1117 Level::IMax(Box::new(l1), Box::new(l2))
1118 }
1119 pub fn param(name: Name) -> Self {
1121 Level::Param(name)
1122 }
1123 pub fn mvar(id: LevelMVarId) -> Self {
1125 Level::MVar(id)
1126 }
1127 pub fn is_zero(&self) -> bool {
1129 matches!(self, Level::Zero)
1130 }
1131 pub fn is_param(&self) -> bool {
1133 matches!(self, Level::Param(_))
1134 }
1135 pub fn is_mvar(&self) -> bool {
1137 matches!(self, Level::MVar(_))
1138 }
1139 pub fn is_succ(&self) -> bool {
1141 matches!(self, Level::Succ(_))
1142 }
1143 pub fn is_max(&self) -> bool {
1145 matches!(self, Level::Max(_, _))
1146 }
1147 pub fn is_imax(&self) -> bool {
1149 matches!(self, Level::IMax(_, _))
1150 }
1151 pub fn is_not_zero(&self) -> bool {
1155 match self {
1156 Level::Zero => false,
1157 Level::Succ(_) => true,
1158 Level::Max(l1, l2) => l1.is_not_zero() || l2.is_not_zero(),
1159 Level::IMax(_, l2) => l2.is_not_zero(),
1160 Level::Param(_) | Level::MVar(_) => false,
1161 }
1162 }
1163 pub fn has_mvar(&self) -> bool {
1165 match self {
1166 Level::MVar(_) => true,
1167 Level::Succ(l) => l.has_mvar(),
1168 Level::Max(l1, l2) | Level::IMax(l1, l2) => l1.has_mvar() || l2.has_mvar(),
1169 Level::Zero | Level::Param(_) => false,
1170 }
1171 }
1172 pub fn has_param(&self) -> bool {
1174 match self {
1175 Level::Param(_) => true,
1176 Level::Succ(l) => l.has_param(),
1177 Level::Max(l1, l2) | Level::IMax(l1, l2) => l1.has_param() || l2.has_param(),
1178 Level::Zero | Level::MVar(_) => false,
1179 }
1180 }
1181 pub fn depth(&self) -> usize {
1183 match self {
1184 Level::Zero | Level::Param(_) | Level::MVar(_) => 0,
1185 Level::Succ(l) => 1 + l.depth(),
1186 Level::Max(l1, l2) | Level::IMax(l1, l2) => 1 + l1.depth().max(l2.depth()),
1187 }
1188 }
1189 pub fn from_nat(n: u32) -> Self {
1191 let mut l = Level::Zero;
1192 for _ in 0..n {
1193 l = Level::succ(l);
1194 }
1195 l
1196 }
1197 pub fn to_nat(&self) -> Option<u32> {
1201 match self {
1202 Level::Zero => Some(0),
1203 Level::Succ(l) => l.to_nat().map(|n| n + 1),
1204 _ => None,
1205 }
1206 }
1207}
1208#[allow(dead_code)]
1210pub struct MinHeap<T: Ord> {
1211 data: Vec<T>,
1212}
1213#[allow(dead_code)]
1214impl<T: Ord> MinHeap<T> {
1215 pub fn new() -> Self {
1217 Self { data: Vec::new() }
1218 }
1219 pub fn push(&mut self, val: T) {
1221 self.data.push(val);
1222 self.sift_up(self.data.len() - 1);
1223 }
1224 pub fn pop(&mut self) -> Option<T> {
1226 if self.data.is_empty() {
1227 return None;
1228 }
1229 let n = self.data.len();
1230 self.data.swap(0, n - 1);
1231 let min = self.data.pop();
1232 if !self.data.is_empty() {
1233 self.sift_down(0);
1234 }
1235 min
1236 }
1237 pub fn peek(&self) -> Option<&T> {
1239 self.data.first()
1240 }
1241 pub fn len(&self) -> usize {
1243 self.data.len()
1244 }
1245 pub fn is_empty(&self) -> bool {
1247 self.data.is_empty()
1248 }
1249 fn sift_up(&mut self, mut i: usize) {
1250 while i > 0 {
1251 let parent = (i - 1) / 2;
1252 if self.data[i] < self.data[parent] {
1253 self.data.swap(i, parent);
1254 i = parent;
1255 } else {
1256 break;
1257 }
1258 }
1259 }
1260 fn sift_down(&mut self, mut i: usize) {
1261 let n = self.data.len();
1262 loop {
1263 let left = 2 * i + 1;
1264 let right = 2 * i + 2;
1265 let mut smallest = i;
1266 if left < n && self.data[left] < self.data[smallest] {
1267 smallest = left;
1268 }
1269 if right < n && self.data[right] < self.data[smallest] {
1270 smallest = right;
1271 }
1272 if smallest == i {
1273 break;
1274 }
1275 self.data.swap(i, smallest);
1276 i = smallest;
1277 }
1278 }
1279}
1280#[allow(dead_code)]
1282pub struct TransformStat {
1283 before: StatSummary,
1284 after: StatSummary,
1285}
1286#[allow(dead_code)]
1287impl TransformStat {
1288 pub fn new() -> Self {
1290 Self {
1291 before: StatSummary::new(),
1292 after: StatSummary::new(),
1293 }
1294 }
1295 pub fn record_before(&mut self, v: f64) {
1297 self.before.record(v);
1298 }
1299 pub fn record_after(&mut self, v: f64) {
1301 self.after.record(v);
1302 }
1303 pub fn mean_ratio(&self) -> Option<f64> {
1305 let b = self.before.mean()?;
1306 let a = self.after.mean()?;
1307 if b.abs() < f64::EPSILON {
1308 return None;
1309 }
1310 Some(a / b)
1311 }
1312}
1313#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
1315pub struct LevelMVarId(pub u64);
1316#[allow(dead_code)]
1318pub struct SparseVec<T: Default + Clone + PartialEq> {
1319 entries: std::collections::HashMap<usize, T>,
1320 default_: T,
1321 logical_len: usize,
1322}
1323#[allow(dead_code)]
1324impl<T: Default + Clone + PartialEq> SparseVec<T> {
1325 pub fn new(len: usize) -> Self {
1327 Self {
1328 entries: std::collections::HashMap::new(),
1329 default_: T::default(),
1330 logical_len: len,
1331 }
1332 }
1333 pub fn set(&mut self, idx: usize, val: T) {
1335 if val == self.default_ {
1336 self.entries.remove(&idx);
1337 } else {
1338 self.entries.insert(idx, val);
1339 }
1340 }
1341 pub fn get(&self, idx: usize) -> &T {
1343 self.entries.get(&idx).unwrap_or(&self.default_)
1344 }
1345 pub fn len(&self) -> usize {
1347 self.logical_len
1348 }
1349 pub fn is_empty(&self) -> bool {
1351 self.len() == 0
1352 }
1353 pub fn nnz(&self) -> usize {
1355 self.entries.len()
1356 }
1357}
1358#[allow(dead_code)]
1360pub struct PrefixCounter {
1361 children: std::collections::HashMap<char, PrefixCounter>,
1362 count: usize,
1363}
1364#[allow(dead_code)]
1365impl PrefixCounter {
1366 pub fn new() -> Self {
1368 Self {
1369 children: std::collections::HashMap::new(),
1370 count: 0,
1371 }
1372 }
1373 pub fn record(&mut self, s: &str) {
1375 self.count += 1;
1376 let mut node = self;
1377 for c in s.chars() {
1378 node = node.children.entry(c).or_default();
1379 node.count += 1;
1380 }
1381 }
1382 pub fn count_with_prefix(&self, prefix: &str) -> usize {
1384 let mut node = self;
1385 for c in prefix.chars() {
1386 match node.children.get(&c) {
1387 Some(n) => node = n,
1388 None => return 0,
1389 }
1390 }
1391 node.count
1392 }
1393}