1use crate::Name;
6
7use std::collections::HashMap;
8use std::rc::Rc;
9
10use super::functions::{is_equivalent, is_leq};
11
12#[allow(dead_code)]
14#[allow(missing_docs)]
15pub enum DecisionNode {
16 Leaf(String),
18 Branch {
20 key: String,
21 val: String,
22 yes_branch: Box<DecisionNode>,
23 no_branch: Box<DecisionNode>,
24 },
25}
26#[allow(dead_code)]
27impl DecisionNode {
28 pub fn evaluate(&self, ctx: &std::collections::HashMap<String, String>) -> &str {
30 match self {
31 DecisionNode::Leaf(action) => action.as_str(),
32 DecisionNode::Branch {
33 key,
34 val,
35 yes_branch,
36 no_branch,
37 } => {
38 let actual = ctx.get(key).map(|s| s.as_str()).unwrap_or("");
39 if actual == val.as_str() {
40 yes_branch.evaluate(ctx)
41 } else {
42 no_branch.evaluate(ctx)
43 }
44 }
45 }
46 }
47 pub fn depth(&self) -> usize {
49 match self {
50 DecisionNode::Leaf(_) => 0,
51 DecisionNode::Branch {
52 yes_branch,
53 no_branch,
54 ..
55 } => 1 + yes_branch.depth().max(no_branch.depth()),
56 }
57 }
58}
59#[allow(dead_code)]
61pub struct FlatSubstitution {
62 pairs: Vec<(String, String)>,
63}
64#[allow(dead_code)]
65impl FlatSubstitution {
66 pub fn new() -> Self {
68 Self { pairs: Vec::new() }
69 }
70 pub fn add(&mut self, from: impl Into<String>, to: impl Into<String>) {
72 self.pairs.push((from.into(), to.into()));
73 }
74 pub fn apply(&self, s: &str) -> String {
76 let mut result = s.to_string();
77 for (from, to) in &self.pairs {
78 result = result.replace(from.as_str(), to.as_str());
79 }
80 result
81 }
82 pub fn len(&self) -> usize {
84 self.pairs.len()
85 }
86 pub fn is_empty(&self) -> bool {
88 self.pairs.is_empty()
89 }
90}
91#[allow(dead_code)]
93#[derive(Debug, Clone, PartialEq)]
94pub enum LevelConstraint {
95 Leq(Level, Level),
97 Eq(Level, Level),
99}
100impl LevelConstraint {
101 #[allow(dead_code)]
105 pub fn is_satisfied(&self) -> bool {
106 match self {
107 LevelConstraint::Leq(l1, l2) => is_leq(l1, l2),
108 LevelConstraint::Eq(l1, l2) => is_equivalent(l1, l2),
109 }
110 }
111 #[allow(dead_code)]
113 pub fn levels(&self) -> (&Level, &Level) {
114 match self {
115 LevelConstraint::Leq(l1, l2) | LevelConstraint::Eq(l1, l2) => (l1, l2),
116 }
117 }
118}
119#[allow(dead_code)]
121pub struct ConfigNode {
122 key: String,
123 value: Option<String>,
124 children: Vec<ConfigNode>,
125}
126#[allow(dead_code)]
127impl ConfigNode {
128 pub fn leaf(key: impl Into<String>, value: impl Into<String>) -> Self {
130 Self {
131 key: key.into(),
132 value: Some(value.into()),
133 children: Vec::new(),
134 }
135 }
136 pub fn section(key: impl Into<String>) -> Self {
138 Self {
139 key: key.into(),
140 value: None,
141 children: Vec::new(),
142 }
143 }
144 pub fn add_child(&mut self, child: ConfigNode) {
146 self.children.push(child);
147 }
148 pub fn key(&self) -> &str {
150 &self.key
151 }
152 pub fn value(&self) -> Option<&str> {
154 self.value.as_deref()
155 }
156 pub fn num_children(&self) -> usize {
158 self.children.len()
159 }
160 pub fn lookup(&self, path: &str) -> Option<&str> {
162 let mut parts = path.splitn(2, '.');
163 let head = parts.next()?;
164 let tail = parts.next();
165 if head != self.key {
166 return None;
167 }
168 match tail {
169 None => self.value.as_deref(),
170 Some(rest) => self.children.iter().find_map(|c| c.lookup_relative(rest)),
171 }
172 }
173 fn lookup_relative(&self, path: &str) -> Option<&str> {
174 let mut parts = path.splitn(2, '.');
175 let head = parts.next()?;
176 let tail = parts.next();
177 if head != self.key {
178 return None;
179 }
180 match tail {
181 None => self.value.as_deref(),
182 Some(rest) => self.children.iter().find_map(|c| c.lookup_relative(rest)),
183 }
184 }
185}
186#[allow(dead_code)]
188pub struct WindowIterator<'a, T> {
189 pub(super) data: &'a [T],
190 pub(super) pos: usize,
191 pub(super) window: usize,
192}
193#[allow(dead_code)]
194impl<'a, T> WindowIterator<'a, T> {
195 pub fn new(data: &'a [T], window: usize) -> Self {
197 Self {
198 data,
199 pos: 0,
200 window,
201 }
202 }
203}
204#[allow(dead_code)]
206pub struct Stopwatch {
207 start: crate::wall_clock::Instant,
208 splits: Vec<f64>,
209}
210#[allow(dead_code)]
211impl Stopwatch {
212 pub fn start() -> Self {
214 Self {
215 start: crate::wall_clock::Instant::now(),
216 splits: Vec::new(),
217 }
218 }
219 pub fn split(&mut self) {
221 self.splits.push(self.elapsed_ms());
222 }
223 pub fn elapsed_ms(&self) -> f64 {
225 self.start.elapsed().as_secs_f64() * 1000.0
226 }
227 pub fn splits(&self) -> &[f64] {
229 &self.splits
230 }
231 pub fn num_splits(&self) -> usize {
233 self.splits.len()
234 }
235}
236#[allow(dead_code)]
238pub struct WriteOnce<T> {
239 value: std::cell::Cell<Option<T>>,
240}
241#[allow(dead_code)]
242impl<T: Copy> WriteOnce<T> {
243 pub fn new() -> Self {
245 Self {
246 value: std::cell::Cell::new(None),
247 }
248 }
249 pub fn write(&self, val: T) -> bool {
251 if self.value.get().is_some() {
252 return false;
253 }
254 self.value.set(Some(val));
255 true
256 }
257 pub fn read(&self) -> Option<T> {
259 self.value.get()
260 }
261 pub fn is_written(&self) -> bool {
263 self.value.get().is_some()
264 }
265}
266#[allow(dead_code)]
268pub enum Either2<A, B> {
269 First(A),
271 Second(B),
273}
274#[allow(dead_code)]
275impl<A, B> Either2<A, B> {
276 pub fn is_first(&self) -> bool {
278 matches!(self, Either2::First(_))
279 }
280 pub fn is_second(&self) -> bool {
282 matches!(self, Either2::Second(_))
283 }
284 pub fn first(self) -> Option<A> {
286 match self {
287 Either2::First(a) => Some(a),
288 _ => None,
289 }
290 }
291 pub fn second(self) -> Option<B> {
293 match self {
294 Either2::Second(b) => Some(b),
295 _ => None,
296 }
297 }
298 pub fn map_first<C, F: FnOnce(A) -> C>(self, f: F) -> Either2<C, B> {
300 match self {
301 Either2::First(a) => Either2::First(f(a)),
302 Either2::Second(b) => Either2::Second(b),
303 }
304 }
305}
306#[allow(dead_code)]
308pub struct VersionedRecord<T: Clone> {
309 earlier: Vec<T>,
311 current: T,
313}
314#[allow(dead_code)]
315impl<T: Clone> VersionedRecord<T> {
316 pub fn new(initial: T) -> Self {
318 Self {
319 earlier: Vec::new(),
320 current: initial,
321 }
322 }
323 pub fn update(&mut self, val: T) {
325 let previous = std::mem::replace(&mut self.current, val);
326 self.earlier.push(previous);
327 }
328 pub fn current(&self) -> &T {
330 &self.current
331 }
332 pub fn at_version(&self, n: usize) -> Option<&T> {
334 match self.earlier.get(n) {
335 Some(value) => Some(value),
336 None if n == self.earlier.len() => Some(&self.current),
337 None => None,
338 }
339 }
340 pub fn version(&self) -> usize {
342 self.earlier.len()
343 }
344 pub fn has_history(&self) -> bool {
346 !self.earlier.is_empty()
347 }
348}
349#[allow(dead_code)]
351pub struct Fixture {
352 data: std::collections::HashMap<String, String>,
353}
354#[allow(dead_code)]
355impl Fixture {
356 pub fn new() -> Self {
358 Self {
359 data: std::collections::HashMap::new(),
360 }
361 }
362 pub fn set(&mut self, key: impl Into<String>, val: impl Into<String>) {
364 self.data.insert(key.into(), val.into());
365 }
366 pub fn get(&self, key: &str) -> Option<&str> {
368 self.data.get(key).map(|s| s.as_str())
369 }
370 pub fn len(&self) -> usize {
372 self.data.len()
373 }
374 pub fn is_empty(&self) -> bool {
376 self.len() == 0
377 }
378}
379#[allow(dead_code)]
381pub struct RawFnPtr {
382 ptr: usize,
384 arity: usize,
385 name: String,
386}
387#[allow(dead_code)]
388impl RawFnPtr {
389 pub fn new(ptr: usize, arity: usize, name: impl Into<String>) -> Self {
391 Self {
392 ptr,
393 arity,
394 name: name.into(),
395 }
396 }
397 pub fn arity(&self) -> usize {
399 self.arity
400 }
401 pub fn name(&self) -> &str {
403 &self.name
404 }
405 pub fn raw(&self) -> usize {
407 self.ptr
408 }
409}
410#[allow(dead_code)]
412pub struct FocusStack<T> {
413 items: Vec<T>,
414}
415#[allow(dead_code)]
416impl<T> FocusStack<T> {
417 pub fn new() -> Self {
419 Self { items: Vec::new() }
420 }
421 pub fn focus(&mut self, item: T) {
423 self.items.push(item);
424 }
425 pub fn blur(&mut self) -> Option<T> {
427 self.items.pop()
428 }
429 pub fn current(&self) -> Option<&T> {
431 self.items.last()
432 }
433 pub fn depth(&self) -> usize {
435 self.items.len()
436 }
437 pub fn is_empty(&self) -> bool {
439 self.items.is_empty()
440 }
441}
442#[allow(dead_code)]
444pub struct TransitiveClosure {
445 adj: Vec<Vec<usize>>,
446 n: usize,
447}
448#[allow(dead_code)]
449impl TransitiveClosure {
450 pub fn new(n: usize) -> Self {
452 Self {
453 adj: vec![Vec::new(); n],
454 n,
455 }
456 }
457 pub fn add_edge(&mut self, from: usize, to: usize) {
459 if from < self.n {
460 self.adj[from].push(to);
461 }
462 }
463 pub fn reachable_from(&self, start: usize) -> Vec<usize> {
465 let mut visited = vec![false; self.n];
466 let mut queue = std::collections::VecDeque::new();
467 queue.push_back(start);
468 while let Some(node) = queue.pop_front() {
469 if node >= self.n || visited[node] {
470 continue;
471 }
472 visited[node] = true;
473 for &next in &self.adj[node] {
474 queue.push_back(next);
475 }
476 }
477 (0..self.n).filter(|&i| visited[i]).collect()
478 }
479 pub fn can_reach(&self, from: usize, to: usize) -> bool {
481 self.reachable_from(from).contains(&to)
482 }
483}
484#[allow(dead_code)]
486pub struct LabelSet {
487 labels: Vec<String>,
488}
489#[allow(dead_code)]
490impl LabelSet {
491 pub fn new() -> Self {
493 Self { labels: Vec::new() }
494 }
495 pub fn add(&mut self, label: impl Into<String>) {
497 let s = label.into();
498 if !self.labels.contains(&s) {
499 self.labels.push(s);
500 }
501 }
502 pub fn has(&self, label: &str) -> bool {
504 self.labels.iter().any(|l| l == label)
505 }
506 pub fn count(&self) -> usize {
508 self.labels.len()
509 }
510 pub fn all(&self) -> &[String] {
512 &self.labels
513 }
514}
515#[allow(dead_code)]
517pub struct RewriteRuleSet {
518 rules: Vec<RewriteRule>,
519}
520#[allow(dead_code)]
521impl RewriteRuleSet {
522 pub fn new() -> Self {
524 Self { rules: Vec::new() }
525 }
526 pub fn add(&mut self, rule: RewriteRule) {
528 self.rules.push(rule);
529 }
530 pub fn len(&self) -> usize {
532 self.rules.len()
533 }
534 pub fn is_empty(&self) -> bool {
536 self.rules.is_empty()
537 }
538 pub fn conditional_rules(&self) -> Vec<&RewriteRule> {
540 self.rules.iter().filter(|r| r.conditional).collect()
541 }
542 pub fn unconditional_rules(&self) -> Vec<&RewriteRule> {
544 self.rules.iter().filter(|r| !r.conditional).collect()
545 }
546 pub fn get(&self, name: &str) -> Option<&RewriteRule> {
548 self.rules.iter().find(|r| r.name == name)
549 }
550}
551#[allow(dead_code)]
553pub struct SmallMap<K: Ord + Clone, V: Clone> {
554 entries: Vec<(K, V)>,
555}
556#[allow(dead_code)]
557impl<K: Ord + Clone, V: Clone> SmallMap<K, V> {
558 pub fn new() -> Self {
560 Self {
561 entries: Vec::new(),
562 }
563 }
564 pub fn insert(&mut self, key: K, val: V) {
566 match self.entries.binary_search_by_key(&&key, |(k, _)| k) {
567 Ok(i) => self.entries[i].1 = val,
568 Err(i) => self.entries.insert(i, (key, val)),
569 }
570 }
571 pub fn get(&self, key: &K) -> Option<&V> {
573 self.entries
574 .binary_search_by_key(&key, |(k, _)| k)
575 .ok()
576 .map(|i| &self.entries[i].1)
577 }
578 pub fn len(&self) -> usize {
580 self.entries.len()
581 }
582 pub fn is_empty(&self) -> bool {
584 self.entries.is_empty()
585 }
586 pub fn keys(&self) -> Vec<&K> {
588 self.entries.iter().map(|(k, _)| k).collect()
589 }
590 pub fn values(&self) -> Vec<&V> {
592 self.entries.iter().map(|(_, v)| v).collect()
593 }
594}
595#[allow(dead_code)]
597pub struct TokenBucket {
598 capacity: u64,
599 tokens: u64,
600 refill_per_ms: u64,
601 last_refill: crate::wall_clock::Instant,
602}
603#[allow(dead_code)]
604impl TokenBucket {
605 pub fn new(capacity: u64, refill_per_ms: u64) -> Self {
607 Self {
608 capacity,
609 tokens: capacity,
610 refill_per_ms,
611 last_refill: crate::wall_clock::Instant::now(),
612 }
613 }
614 pub fn try_consume(&mut self, n: u64) -> bool {
616 self.refill();
617 if self.tokens >= n {
618 self.tokens -= n;
619 true
620 } else {
621 false
622 }
623 }
624 fn refill(&mut self) {
625 let now = crate::wall_clock::Instant::now();
626 let elapsed_ms = now.duration_since(self.last_refill).as_millis() as u64;
627 if elapsed_ms > 0 {
628 let new_tokens = elapsed_ms * self.refill_per_ms;
629 self.tokens = (self.tokens + new_tokens).min(self.capacity);
630 self.last_refill = now;
631 }
632 }
633 pub fn available(&self) -> u64 {
635 self.tokens
636 }
637 pub fn capacity(&self) -> u64 {
639 self.capacity
640 }
641}
642#[allow(dead_code)]
644pub struct StackCalc {
645 stack: Vec<i64>,
646}
647#[allow(dead_code)]
648impl StackCalc {
649 pub fn new() -> Self {
651 Self { stack: Vec::new() }
652 }
653 pub fn push(&mut self, n: i64) {
655 self.stack.push(n);
656 }
657 fn apply_binary(&mut self, op: impl FnOnce(i64, i64) -> i64) -> Option<i64> {
661 let (rest_len, a, b) = match self.stack[..] {
662 [ref rest @ .., a, b] => (rest.len(), a, b),
663 _ => return None,
664 };
665 let value = op(a, b);
666 self.stack.truncate(rest_len);
667 self.stack.push(value);
668 Some(value)
669 }
670 pub fn add(&mut self) -> Option<i64> {
674 self.apply_binary(|a, b| a + b)
675 }
676 pub fn sub(&mut self) -> Option<i64> {
680 self.apply_binary(|a, b| a - b)
681 }
682 pub fn mul(&mut self) -> Option<i64> {
686 self.apply_binary(|a, b| a * b)
687 }
688 pub fn peek(&self) -> Option<i64> {
690 self.stack.last().copied()
691 }
692 pub fn depth(&self) -> usize {
694 self.stack.len()
695 }
696}
697#[allow(dead_code)]
699#[allow(missing_docs)]
700pub struct RewriteRule {
701 pub name: String,
703 pub lhs: String,
705 pub rhs: String,
707 pub conditional: bool,
709}
710#[allow(dead_code)]
711impl RewriteRule {
712 pub fn unconditional(
714 name: impl Into<String>,
715 lhs: impl Into<String>,
716 rhs: impl Into<String>,
717 ) -> Self {
718 Self {
719 name: name.into(),
720 lhs: lhs.into(),
721 rhs: rhs.into(),
722 conditional: false,
723 }
724 }
725 pub fn conditional(
727 name: impl Into<String>,
728 lhs: impl Into<String>,
729 rhs: impl Into<String>,
730 ) -> Self {
731 Self {
732 name: name.into(),
733 lhs: lhs.into(),
734 rhs: rhs.into(),
735 conditional: true,
736 }
737 }
738 pub fn display(&self) -> String {
740 format!("{}: {} → {}", self.name, self.lhs, self.rhs)
741 }
742}
743#[allow(dead_code)]
745#[derive(Debug, Default, Clone)]
746pub struct ConstraintSet {
747 constraints: Vec<LevelConstraint>,
748}
749impl ConstraintSet {
750 #[allow(dead_code)]
752 pub fn new() -> Self {
753 Self::default()
754 }
755 #[allow(dead_code)]
757 pub fn add(&mut self, c: LevelConstraint) {
758 self.constraints.push(c);
759 }
760 #[allow(dead_code)]
762 pub fn add_leq(&mut self, l1: Level, l2: Level) {
763 self.add(LevelConstraint::Leq(l1, l2));
764 }
765 #[allow(dead_code)]
767 pub fn add_eq(&mut self, l1: Level, l2: Level) {
768 self.add(LevelConstraint::Eq(l1, l2));
769 }
770 #[allow(dead_code)]
772 pub fn all_satisfied(&self) -> bool {
773 self.constraints.iter().all(|c| c.is_satisfied())
774 }
775 #[allow(dead_code)]
777 pub fn unsatisfied(&self) -> Vec<&LevelConstraint> {
778 self.constraints
779 .iter()
780 .filter(|c| !c.is_satisfied())
781 .collect()
782 }
783 #[allow(dead_code)]
785 pub fn len(&self) -> usize {
786 self.constraints.len()
787 }
788 #[allow(dead_code)]
790 pub fn is_empty(&self) -> bool {
791 self.constraints.is_empty()
792 }
793}
794#[allow(dead_code)]
796pub struct SlidingSum {
797 window: Vec<f64>,
798 capacity: usize,
799 pos: usize,
800 sum: f64,
801 count: usize,
802}
803#[allow(dead_code)]
804impl SlidingSum {
805 pub fn new(capacity: usize) -> Self {
807 Self {
808 window: vec![0.0; capacity],
809 capacity,
810 pos: 0,
811 sum: 0.0,
812 count: 0,
813 }
814 }
815 pub fn push(&mut self, val: f64) {
817 let oldest = self.window[self.pos];
818 self.sum -= oldest;
819 self.sum += val;
820 self.window[self.pos] = val;
821 self.pos = (self.pos + 1) % self.capacity;
822 if self.count < self.capacity {
823 self.count += 1;
824 }
825 }
826 pub fn sum(&self) -> f64 {
828 self.sum
829 }
830 pub fn mean(&self) -> Option<f64> {
832 if self.count == 0 {
833 None
834 } else {
835 Some(self.sum / self.count as f64)
836 }
837 }
838 pub fn count(&self) -> usize {
840 self.count
841 }
842}
843#[allow(dead_code)]
845pub struct PathBuf {
846 components: Vec<String>,
847}
848#[allow(dead_code)]
849impl PathBuf {
850 pub fn new() -> Self {
852 Self {
853 components: Vec::new(),
854 }
855 }
856 pub fn push(&mut self, comp: impl Into<String>) {
858 self.components.push(comp.into());
859 }
860 pub fn pop(&mut self) {
862 self.components.pop();
863 }
864 pub fn as_str(&self) -> String {
866 self.components.join("/")
867 }
868 pub fn depth(&self) -> usize {
870 self.components.len()
871 }
872 pub fn clear(&mut self) {
874 self.components.clear();
875 }
876}
877#[allow(dead_code)]
879pub struct NonEmptyVec<T> {
880 head: T,
881 tail: Vec<T>,
882}
883#[allow(dead_code)]
884impl<T> NonEmptyVec<T> {
885 pub fn singleton(val: T) -> Self {
887 Self {
888 head: val,
889 tail: Vec::new(),
890 }
891 }
892 pub fn push(&mut self, val: T) {
894 self.tail.push(val);
895 }
896 pub fn first(&self) -> &T {
898 &self.head
899 }
900 pub fn last(&self) -> &T {
902 self.tail.last().unwrap_or(&self.head)
903 }
904 pub fn len(&self) -> usize {
906 1 + self.tail.len()
907 }
908 pub fn is_empty(&self) -> bool {
910 self.len() == 0
911 }
912 pub fn to_vec(&self) -> Vec<&T> {
914 let mut v = vec![&self.head];
915 v.extend(self.tail.iter());
916 v
917 }
918}
919#[allow(dead_code)]
921pub struct StringPool {
922 free: Vec<String>,
923}
924#[allow(dead_code)]
925impl StringPool {
926 pub fn new() -> Self {
928 Self { free: Vec::new() }
929 }
930 pub fn take(&mut self) -> String {
932 self.free.pop().unwrap_or_default()
933 }
934 pub fn give(&mut self, mut s: String) {
936 s.clear();
937 self.free.push(s);
938 }
939 pub fn free_count(&self) -> usize {
941 self.free.len()
942 }
943}
944#[allow(dead_code)]
946pub struct StatSummary {
947 count: u64,
948 sum: f64,
949 min: f64,
950 max: f64,
951}
952#[allow(dead_code)]
953impl StatSummary {
954 pub fn new() -> Self {
956 Self {
957 count: 0,
958 sum: 0.0,
959 min: f64::INFINITY,
960 max: f64::NEG_INFINITY,
961 }
962 }
963 pub fn record(&mut self, val: f64) {
965 self.count += 1;
966 self.sum += val;
967 if val < self.min {
968 self.min = val;
969 }
970 if val > self.max {
971 self.max = val;
972 }
973 }
974 pub fn mean(&self) -> Option<f64> {
976 if self.count == 0 {
977 None
978 } else {
979 Some(self.sum / self.count as f64)
980 }
981 }
982 pub fn min(&self) -> Option<f64> {
984 if self.count == 0 {
985 None
986 } else {
987 Some(self.min)
988 }
989 }
990 pub fn max(&self) -> Option<f64> {
992 if self.count == 0 {
993 None
994 } else {
995 Some(self.max)
996 }
997 }
998 pub fn count(&self) -> u64 {
1000 self.count
1001 }
1002}
1003#[allow(dead_code)]
1005pub struct SimpleDag {
1006 edges: Vec<Vec<usize>>,
1008}
1009#[allow(dead_code)]
1010impl SimpleDag {
1011 pub fn new(n: usize) -> Self {
1013 Self {
1014 edges: vec![Vec::new(); n],
1015 }
1016 }
1017 pub fn add_edge(&mut self, from: usize, to: usize) {
1019 if from < self.edges.len() {
1020 self.edges[from].push(to);
1021 }
1022 }
1023 pub fn successors(&self, node: usize) -> &[usize] {
1025 self.edges.get(node).map(|v| v.as_slice()).unwrap_or(&[])
1026 }
1027 pub fn can_reach(&self, from: usize, to: usize) -> bool {
1029 let mut visited = vec![false; self.edges.len()];
1030 self.dfs(from, to, &mut visited)
1031 }
1032 fn dfs(&self, cur: usize, target: usize, visited: &mut Vec<bool>) -> bool {
1033 if cur == target {
1034 return true;
1035 }
1036 if cur >= visited.len() || visited[cur] {
1037 return false;
1038 }
1039 visited[cur] = true;
1040 for &next in self.successors(cur) {
1041 if self.dfs(next, target, visited) {
1042 return true;
1043 }
1044 }
1045 false
1046 }
1047 pub fn topological_sort(&self) -> Option<Vec<usize>> {
1049 let n = self.edges.len();
1050 let mut in_degree = vec![0usize; n];
1051 for succs in &self.edges {
1052 for &s in succs {
1053 if s < n {
1054 in_degree[s] += 1;
1055 }
1056 }
1057 }
1058 let mut queue: std::collections::VecDeque<usize> =
1059 (0..n).filter(|&i| in_degree[i] == 0).collect();
1060 let mut order = Vec::new();
1061 while let Some(node) = queue.pop_front() {
1062 order.push(node);
1063 for &s in self.successors(node) {
1064 if s < n {
1065 in_degree[s] -= 1;
1066 if in_degree[s] == 0 {
1067 queue.push_back(s);
1068 }
1069 }
1070 }
1071 }
1072 if order.len() == n {
1073 Some(order)
1074 } else {
1075 None
1076 }
1077 }
1078 pub fn num_nodes(&self) -> usize {
1080 self.edges.len()
1081 }
1082}
1083#[derive(Clone)]
1104pub struct Level(Rc<LevelCell>);
1105
1106struct LevelCell {
1113 hash: u64,
1114 kind: LevelKind,
1115}
1116
1117impl PartialEq for Level {
1118 #[inline]
1119 fn eq(&self, other: &Level) -> bool {
1120 Rc::ptr_eq(&self.0, &other.0)
1121 || (self.0.hash == other.0.hash && self.0.kind == other.0.kind)
1122 }
1123}
1124impl Eq for Level {}
1125impl std::hash::Hash for Level {
1126 #[inline]
1129 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
1130 self.0.kind.hash(state);
1131 }
1132}
1133impl std::fmt::Debug for Level {
1134 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1138 f.debug_tuple("Level").field(&self.0.kind).finish()
1139 }
1140}
1141
1142#[derive(PartialEq, Eq, Hash, Debug)]
1145enum LevelKind {
1146 Zero,
1148 Succ(Level),
1150 Max(Level, Level),
1152 IMax(Level, Level),
1157 Param(Name),
1159 MVar(LevelMVarId),
1161}
1162
1163pub enum LevelView<'a> {
1167 Zero,
1169 Succ(&'a Level),
1171 Max(&'a Level, &'a Level),
1173 IMax(&'a Level, &'a Level),
1175 Param(&'a Name),
1177 MVar(LevelMVarId),
1179}
1180
1181impl Level {
1182 #[inline]
1184 pub fn view(&self) -> LevelView<'_> {
1185 match &self.0.kind {
1186 LevelKind::Zero => LevelView::Zero,
1187 LevelKind::Succ(l) => LevelView::Succ(l),
1188 LevelKind::Max(a, b) => LevelView::Max(a, b),
1189 LevelKind::IMax(a, b) => LevelView::IMax(a, b),
1190 LevelKind::Param(n) => LevelView::Param(n),
1191 LevelKind::MVar(id) => LevelView::MVar(*id),
1192 }
1193 }
1194 #[inline]
1197 #[must_use]
1198 pub(crate) fn structural_hash(&self) -> u64 {
1199 self.0.hash
1200 }
1201 #[inline]
1204 fn from_kind(kind: LevelKind) -> Self {
1205 use crate::structural_hash::{
1206 mix, LEVEL_IMAX, LEVEL_MAX, LEVEL_MVAR, LEVEL_PARAM, LEVEL_SUCC, LEVEL_ZERO,
1207 };
1208 let hash = match &kind {
1209 LevelKind::Zero => LEVEL_ZERO,
1210 LevelKind::Succ(l) => mix(LEVEL_SUCC, l.0.hash),
1211 LevelKind::Max(l1, l2) => mix(mix(LEVEL_MAX, l1.0.hash), l2.0.hash),
1212 LevelKind::IMax(l1, l2) => mix(mix(LEVEL_IMAX, l1.0.hash), l2.0.hash),
1213 LevelKind::Param(name) => mix(LEVEL_PARAM, name.structural_hash()),
1214 LevelKind::MVar(id) => mix(LEVEL_MVAR, id.0),
1215 };
1216 Level(Rc::new(LevelCell { hash, kind }))
1217 }
1218 pub fn zero() -> Self {
1220 Level::from_kind(LevelKind::Zero)
1221 }
1222 pub fn succ(l: Level) -> Self {
1224 Level::from_kind(LevelKind::Succ(l))
1225 }
1226 pub fn max(l1: Level, l2: Level) -> Self {
1228 Level::from_kind(LevelKind::Max(l1, l2))
1229 }
1230 pub fn imax(l1: Level, l2: Level) -> Self {
1232 Level::from_kind(LevelKind::IMax(l1, l2))
1233 }
1234 pub fn param(name: Name) -> Self {
1236 Level::from_kind(LevelKind::Param(name))
1237 }
1238 pub fn mvar(id: LevelMVarId) -> Self {
1240 Level::from_kind(LevelKind::MVar(id))
1241 }
1242 pub fn is_zero(&self) -> bool {
1244 matches!(&self.0.kind, LevelKind::Zero)
1245 }
1246 pub fn is_param(&self) -> bool {
1248 matches!(&self.0.kind, LevelKind::Param(_))
1249 }
1250 pub fn is_mvar(&self) -> bool {
1252 matches!(&self.0.kind, LevelKind::MVar(_))
1253 }
1254 pub fn is_succ(&self) -> bool {
1256 matches!(&self.0.kind, LevelKind::Succ(_))
1257 }
1258 pub fn is_max(&self) -> bool {
1260 matches!(&self.0.kind, LevelKind::Max(_, _))
1261 }
1262 pub fn is_imax(&self) -> bool {
1264 matches!(&self.0.kind, LevelKind::IMax(_, _))
1265 }
1266 pub fn is_not_zero(&self) -> bool {
1270 match &self.0.kind {
1271 LevelKind::Zero => false,
1272 LevelKind::Succ(_) => true,
1273 LevelKind::Max(l1, l2) => l1.is_not_zero() || l2.is_not_zero(),
1274 LevelKind::IMax(_, l2) => l2.is_not_zero(),
1275 LevelKind::Param(_) | LevelKind::MVar(_) => false,
1276 }
1277 }
1278 pub fn has_mvar(&self) -> bool {
1280 match &self.0.kind {
1281 LevelKind::MVar(_) => true,
1282 LevelKind::Succ(l) => l.has_mvar(),
1283 LevelKind::Max(l1, l2) | LevelKind::IMax(l1, l2) => l1.has_mvar() || l2.has_mvar(),
1284 LevelKind::Zero | LevelKind::Param(_) => false,
1285 }
1286 }
1287 pub fn has_param(&self) -> bool {
1289 match &self.0.kind {
1290 LevelKind::Param(_) => true,
1291 LevelKind::Succ(l) => l.has_param(),
1292 LevelKind::Max(l1, l2) | LevelKind::IMax(l1, l2) => l1.has_param() || l2.has_param(),
1293 LevelKind::Zero | LevelKind::MVar(_) => false,
1294 }
1295 }
1296 pub fn depth(&self) -> usize {
1298 match &self.0.kind {
1299 LevelKind::Zero | LevelKind::Param(_) | LevelKind::MVar(_) => 0,
1300 LevelKind::Succ(l) => 1 + l.depth(),
1301 LevelKind::Max(l1, l2) | LevelKind::IMax(l1, l2) => 1 + l1.depth().max(l2.depth()),
1302 }
1303 }
1304 pub fn from_nat(n: u32) -> Self {
1306 let mut l = Level::zero();
1307 for _ in 0..n {
1308 l = Level::succ(l);
1309 }
1310 l
1311 }
1312 pub fn to_nat(&self) -> Option<u32> {
1316 match &self.0.kind {
1317 LevelKind::Zero => Some(0),
1318 LevelKind::Succ(l) => l.to_nat().map(|n| n + 1),
1319 _ => None,
1320 }
1321 }
1322}
1323#[allow(dead_code)]
1325pub struct MinHeap<T: Ord> {
1326 data: Vec<T>,
1327}
1328#[allow(dead_code)]
1329impl<T: Ord> MinHeap<T> {
1330 pub fn new() -> Self {
1332 Self { data: Vec::new() }
1333 }
1334 pub fn push(&mut self, val: T) {
1336 self.data.push(val);
1337 self.sift_up(self.data.len() - 1);
1338 }
1339 pub fn pop(&mut self) -> Option<T> {
1341 if self.data.is_empty() {
1342 return None;
1343 }
1344 let n = self.data.len();
1345 self.data.swap(0, n - 1);
1346 let min = self.data.pop();
1347 if !self.data.is_empty() {
1348 self.sift_down(0);
1349 }
1350 min
1351 }
1352 pub fn peek(&self) -> Option<&T> {
1354 self.data.first()
1355 }
1356 pub fn len(&self) -> usize {
1358 self.data.len()
1359 }
1360 pub fn is_empty(&self) -> bool {
1362 self.data.is_empty()
1363 }
1364 fn sift_up(&mut self, mut i: usize) {
1365 while i > 0 {
1366 let parent = (i - 1) / 2;
1367 if self.data[i] < self.data[parent] {
1368 self.data.swap(i, parent);
1369 i = parent;
1370 } else {
1371 break;
1372 }
1373 }
1374 }
1375 fn sift_down(&mut self, mut i: usize) {
1376 let n = self.data.len();
1377 loop {
1378 let left = 2 * i + 1;
1379 let right = 2 * i + 2;
1380 let mut smallest = i;
1381 if left < n && self.data[left] < self.data[smallest] {
1382 smallest = left;
1383 }
1384 if right < n && self.data[right] < self.data[smallest] {
1385 smallest = right;
1386 }
1387 if smallest == i {
1388 break;
1389 }
1390 self.data.swap(i, smallest);
1391 i = smallest;
1392 }
1393 }
1394}
1395#[allow(dead_code)]
1397pub struct TransformStat {
1398 before: StatSummary,
1399 after: StatSummary,
1400}
1401#[allow(dead_code)]
1402impl TransformStat {
1403 pub fn new() -> Self {
1405 Self {
1406 before: StatSummary::new(),
1407 after: StatSummary::new(),
1408 }
1409 }
1410 pub fn record_before(&mut self, v: f64) {
1412 self.before.record(v);
1413 }
1414 pub fn record_after(&mut self, v: f64) {
1416 self.after.record(v);
1417 }
1418 pub fn mean_ratio(&self) -> Option<f64> {
1420 let b = self.before.mean()?;
1421 let a = self.after.mean()?;
1422 if b.abs() < f64::EPSILON {
1423 return None;
1424 }
1425 Some(a / b)
1426 }
1427}
1428#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
1430pub struct LevelMVarId(pub u64);
1431#[allow(dead_code)]
1433pub struct SparseVec<T: Default + Clone + PartialEq> {
1434 entries: std::collections::HashMap<usize, T>,
1435 default_: T,
1436 logical_len: usize,
1437}
1438#[allow(dead_code)]
1439impl<T: Default + Clone + PartialEq> SparseVec<T> {
1440 pub fn new(len: usize) -> Self {
1442 Self {
1443 entries: std::collections::HashMap::new(),
1444 default_: T::default(),
1445 logical_len: len,
1446 }
1447 }
1448 pub fn set(&mut self, idx: usize, val: T) {
1450 if val == self.default_ {
1451 self.entries.remove(&idx);
1452 } else {
1453 self.entries.insert(idx, val);
1454 }
1455 }
1456 pub fn get(&self, idx: usize) -> &T {
1458 self.entries.get(&idx).unwrap_or(&self.default_)
1459 }
1460 pub fn len(&self) -> usize {
1462 self.logical_len
1463 }
1464 pub fn is_empty(&self) -> bool {
1466 self.len() == 0
1467 }
1468 pub fn nnz(&self) -> usize {
1470 self.entries.len()
1471 }
1472}
1473#[allow(dead_code)]
1475pub struct PrefixCounter {
1476 children: std::collections::HashMap<char, PrefixCounter>,
1477 count: usize,
1478}
1479#[allow(dead_code)]
1480impl PrefixCounter {
1481 pub fn new() -> Self {
1483 Self {
1484 children: std::collections::HashMap::new(),
1485 count: 0,
1486 }
1487 }
1488 pub fn record(&mut self, s: &str) {
1490 self.count += 1;
1491 let mut node = self;
1492 for c in s.chars() {
1493 node = node.children.entry(c).or_default();
1494 node.count += 1;
1495 }
1496 }
1497 pub fn count_with_prefix(&self, prefix: &str) -> usize {
1499 let mut node = self;
1500 for c in prefix.chars() {
1501 match node.children.get(&c) {
1502 Some(n) => node = n,
1503 None => return 0,
1504 }
1505 }
1506 node.count
1507 }
1508}